From 7da6ed69f3458db6af85c3215f4e06676bcf2a4f Mon Sep 17 00:00:00 2001 From: epezent Date: Wed, 19 Aug 2020 23:50:12 -0500 Subject: [PATCH] add FitNextPlotAxes --- implot.cpp | 32 ++++++++++++++++++++++++-------- implot.h | 2 ++ implot_demo.cpp | 5 +++++ implot_internal.h | 4 ++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/implot.cpp b/implot.cpp index 3ed29b6..5ea473f 100644 --- a/implot.cpp +++ b/implot.cpp @@ -227,7 +227,8 @@ void Reset(ImPlotContext* ctx) { ctx->YTicks[i].shrink(0); ctx->YTickLabels[i].Buf.shrink(0); } - // reset extents + // reset extents/fit + ctx->FitThisFrame = false; ctx->FitX = false; ctx->ExtentsX.Min = HUGE_VAL; ctx->ExtentsX.Max = -HUGE_VAL; @@ -971,19 +972,25 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons plot.QueryRect = ImRect(0,0,0,0); } - // DOUBLE CLICK ----------------------------------------------------------- + // FIT ----------------------------------------------------------- - if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (plot.XAxis.HoveredTot || any_hov_y_axis_region) && !hov_legend && !hov_query) { + // fit from double click + if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (plot.XAxis.HoveredTot || any_hov_y_axis_region) && !hov_legend && !hov_query ) { gp.FitThisFrame = true; gp.FitX = plot.XAxis.HoveredTot; for (int i = 0; i < IMPLOT_Y_AXES; i++) gp.FitY[i] = plot.YAxis[i].HoveredTot; } - else { - gp.FitThisFrame = false; - gp.FitX = false; - for (int i = 0; i < IMPLOT_Y_AXES; i++) - gp.FitY[i] = false; + // fit from FitNextPlotAxes + if (gp.NextPlotData.FitX) { + gp.FitThisFrame = true; + gp.FitX = true; + } + for (int i = 0; i < IMPLOT_Y_AXES; ++i) { + if (gp.NextPlotData.FitY[i]) { + gp.FitThisFrame = true; + gp.FitY[i] = true; + } } // FOCUS ------------------------------------------------------------------ @@ -1554,6 +1561,15 @@ void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, int y_axis) gp.NextPlotData.Y[y_axis].Max = y_max; } +void FitNextPlotAxes(bool x, bool y, bool y2, bool y3) { + ImPlotContext& gp = *GImPlot; + IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "FitNextPlotAxes() needs to be called before BeginPlot()!"); + gp.NextPlotData.FitX = x; + gp.NextPlotData.FitY[0] = y; + gp.NextPlotData.FitY[1] = y2; + gp.NextPlotData.FitY[2] = y3; +} + void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels, bool show_default) { ImPlotContext& gp = *GImPlot; IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "SetNextPlotTicksX() needs to be called before BeginPlot()!"); diff --git a/implot.h b/implot.h index 971f79e..9f2025d 100644 --- a/implot.h +++ b/implot.h @@ -382,6 +382,8 @@ void SetNextPlotLimits(double x_min, double x_max, double y_min, double y_max, I void SetNextPlotLimitsX(double x_min, double x_max, ImGuiCond cond = ImGuiCond_Once); // Set the Y axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the Y axis limits will be locked. void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond = ImGuiCond_Once, int y_axis = 0); +// Fits the next plot axes if they are unlocked. +void FitNextPlotAxes(bool x = true, bool y = true, bool y2 = true, bool y3 = true); // Set the X axis ticks and optionally the labels for the next plot. void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false); diff --git a/implot_demo.cpp b/implot_demo.cpp index 2735747..7e5339d 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -600,6 +600,11 @@ void ShowDemoWindow(bool* p_open) { ImGui::ColorEdit4("##Col2", &y2_col.x, ImGuiColorEditFlags_NoInputs); ImGui::SameLine(); ImGui::ColorEdit4("##Col3", &y3_col.x, ImGuiColorEditFlags_NoInputs); + // you can fit axes programatically + ImGui::SameLine(); if (ImGui::Button("Fit X")) ImPlot::FitNextPlotAxes(true, false, false, false); + ImGui::SameLine(); if (ImGui::Button("Fit Y")) ImPlot::FitNextPlotAxes(false, true, false, false); + ImGui::SameLine(); if (ImGui::Button("Fit Y2")) ImPlot::FitNextPlotAxes(false, false, true, false); + ImGui::SameLine(); if (ImGui::Button("Fit Y3")) ImPlot::FitNextPlotAxes(false, false, false, true); for (int i = 0; i < 1001; ++i) { xs[i] = (i*0.1f); ys1[i] = Sin(xs[i]) * 3 + 1; diff --git a/implot_internal.h b/implot_internal.h index 2baaf6b..1fd8cd1 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -299,13 +299,17 @@ struct ImPlotNextPlotData bool HasYRange[IMPLOT_Y_AXES]; bool ShowDefaultTicksX; bool ShowDefaultTicksY[IMPLOT_Y_AXES]; + bool FitX; + bool FitY[IMPLOT_Y_AXES]; ImPlotNextPlotData() { HasXRange = false; ShowDefaultTicksX = true; + FitX = false; for (int i = 0; i < IMPLOT_Y_AXES; ++i) { HasYRange[i] = false; ShowDefaultTicksY[i] = true; + FitY[i] = false; } } };