diff --git a/implot.cpp b/implot.cpp index 181ca11..f0f0174 100644 --- a/implot.cpp +++ b/implot.cpp @@ -83,11 +83,6 @@ You can read releases logs https://github.com/epezent/implot/releases for more d #define ImDrawFlags_RoundCornersAll ImDrawCornerFlags_All #endif -// Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize() -#if (IMGUI_VERSION_NUM < 18303) -#define GetBufSize GetSize // A little bit ugly since 'GetBufSize' could technically be used elsewhere (but currently isn't). Could use a proxy define if needed. -#endif - // Global plot context ImPlotContext* GImPlot = NULL; @@ -703,6 +698,9 @@ bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool hov // Tick Utils //----------------------------------------------------------------------------- +static const float TICK_FILL_X = 0.8f; +static const float TICK_FILL_Y = 1.0f; + void AddTicksDefault(const ImPlotRange& range, float pix, ImPlotOrientation orn, ImPlotTickCollection& ticks, const char* fmt) { const int idx0 = ticks.Size; const int nMinor = 10; @@ -713,12 +711,7 @@ void AddTicksDefault(const ImPlotRange& range, float pix, ImPlotOrientation orn, const double graphmax = ceil(range.Max / interval) * interval; bool first_major_set = false; int first_major_idx = 0; - - char dummy[32]; - sprintf(dummy,fmt,-ImAbs(interval / nMinor)); - ImVec2 dummy_size = ImGui::CalcTextSize(dummy); ImVec2 total_size(0,0); - for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) { // is this zero? combat zero formatting issues if (major-interval < 0 && major+interval > 0) @@ -728,19 +721,17 @@ void AddTicksDefault(const ImPlotRange& range, float pix, ImPlotOrientation orn, first_major_idx = ticks.Size; first_major_set = true; } - ticks.Append(major, true, true, fmt); - total_size += dummy_size; + total_size += ticks.Append(major, true, true, fmt).LabelSize; } for (int i = 1; i < nMinor; ++i) { double minor = major + i * interval / nMinor; if (range.Contains(minor)) { - ticks.Append(minor, false, true, fmt); - total_size += dummy_size; + total_size += ticks.Append(minor, false, true, fmt).LabelSize; } } } // prune if necessary - if ((orn == ImPlotOrientation_Horizontal && total_size.x > pix) || (orn == ImPlotOrientation_Vertical && total_size.y > pix)) { + if ((orn == ImPlotOrientation_Horizontal && total_size.x > pix*TICK_FILL_X) || (orn == ImPlotOrientation_Vertical && total_size.y > pix*TICK_FILL_Y)) { for (int i = first_major_idx-1; i >= idx0; i -= 2) ticks.Ticks[i].ShowLabel = false; for (int i = first_major_idx+1; i < ticks.Size; i += 2) @@ -2071,22 +2062,6 @@ bool BeginPlot(const char* title, const char* x_label, const char* y1_label, con for (int i = 0; i < IMPLOT_Y_AXES; ++i) plot.YAxis[i].Constrain(); - // constrain equal axes for primary x and y if not approximately equal - // constrains x to y since x pixel size depends on y labels width, and causes feedback loops in opposite case - if (ImHasFlag(plot.Flags, ImPlotFlags_Equal)) { - double xar = plot.XAxis.GetAspect(); - double yar = plot.YAxis[0].GetAspect(); - // edge case: user has set x range this frame, so fit y to x so that we honor their request for x range - // NB: because of feedback across several frames, the user's x request may not be perfectly honored - if (gp.NextPlotData.HasXRange) { - plot.YAxis[0].SetAspect(xar); - } - else { - if (!ImAlmostEqual(xar,yar) && !plot.YAxis[0].IsInputLocked()) - plot.XAxis.SetAspect(yar); - } - } - // AXIS COLORS ----------------------------------------------------------------- UpdateAxisColors(ImPlotCol_XAxis, &plot.XAxis); @@ -2253,6 +2228,23 @@ bool BeginPlot(const char* title, const char* x_label, const char* y1_label, con for (int i = 0; i < IMPLOT_Y_AXES; ++i) plot.YAxis[i].Pixels = plot.PlotRect.GetHeight(); + // Equal axis constraint. Must happen after we set Pixels + // constrain equal axes for primary x and y if not approximately equal + // constrains x to y since x pixel size depends on y labels width, and causes feedback loops in opposite case + if (ImHasFlag(plot.Flags, ImPlotFlags_Equal)) { + double xar = plot.XAxis.GetAspect(); + double yar = plot.YAxis[0].GetAspect(); + // edge case: user has set x range this frame, so fit y to x so that we honor their request for x range + // NB: because of feedback across several frames, the user's x request may not be perfectly honored + if (gp.NextPlotData.HasXRange) { + plot.YAxis[0].SetAspect(xar); + } + else { + if (!ImAlmostEqual(xar,yar) && !plot.YAxis[0].IsInputLocked()) + plot.XAxis.SetAspect(yar); + } + } + // INPUT ------------------------------------------------------------------ HandlePlotInput(plot); @@ -4494,7 +4486,7 @@ void ShowMetricsWindow(bool* p_popen) { if (ImHasFlag(plot->Flags, ImPlotFlags_YAxis2)) fg.AddRect(plot->YAxis[1].HoverRect.Min, plot->YAxis[1].HoverRect.Max, IM_COL32(0,255,0,255)); if (ImHasFlag(plot->Flags, ImPlotFlags_YAxis3)) - fg.AddRect(plot->YAxis[3].HoverRect.Min, plot->YAxis[2].HoverRect.Max, IM_COL32(0,255,0,255)); + fg.AddRect(plot->YAxis[2].HoverRect.Min, plot->YAxis[2].HoverRect.Max, IM_COL32(0,255,0,255)); } } for (int p = 0; p < n_subplots; ++p) { diff --git a/implot_demo.cpp b/implot_demo.cpp index 46e7269..a1ef3e2 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -2063,9 +2063,10 @@ struct BenchData { enum BenchMode { Line = 0, - Shaded = 1, - Scatter = 2, - Bars = 3 + LineG = 1, + Shaded = 2, + Scatter = 3, + Bars = 4 }; struct BenchRecord { @@ -2074,6 +2075,11 @@ struct BenchRecord { ImVector Data; }; +ImPlotPoint BenchmarkGetter(void* data, int idx) { + float* values = (float*)data; + return ImPlotPoint(idx, values[idx]); +} + void ShowBenchmarkTool() { static const int max_items = 500; static BenchData items[max_items]; @@ -2083,7 +2089,7 @@ void ShowBenchmarkTool() { static int F = 0; static double t1, t2; static int mode = BenchMode::Line; - const char* names[] = {"Line","Shaded","Scatter","Bars"}; + const char* names[] = {"Line","LineG","Shaded","Scatter","Bars"}; static ImVector records; @@ -2143,6 +2149,14 @@ void ShowBenchmarkTool() { ImGui::PopID(); } } + else if (mode == BenchMode::LineG) { + for (int i = 0; i < L; ++i) { + ImGui::PushID(i); + ImPlot::SetNextLineStyle(items[i].Col); + ImPlot::PlotLineG("##item",BenchmarkGetter,items[i].Data,1000); + ImGui::PopID(); + } + } else if (mode == BenchMode::Shaded) { for (int i = 0; i < L; ++i) { ImGui::PushID(i); diff --git a/implot_internal.h b/implot_internal.h index c17b2fb..63aa1fc 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -43,6 +43,11 @@ #error Must include implot.h before implot_internal.h #endif +// Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize() +#if (IMGUI_VERSION_NUM < 18303) +#define GetBufSize GetSize +#endif + //----------------------------------------------------------------------------- // [SECTION] Constants //----------------------------------------------------------------------------- @@ -1272,7 +1277,6 @@ static inline T OffsetAndStride(const T* data, int idx, int count, int offset, i idx = ImPosMod(offset + idx, count); return *(const T*)(const void*)((const unsigned char*)data + (size_t)idx * stride); } - // Calculate histogram bin counts and widths template static inline void CalculateBins(const T* values, int count, ImPlotBin meth, const ImPlotRange& range, int& bins_out, double& width_out) { diff --git a/implot_items.cpp b/implot_items.cpp index 44ed253..676852e 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -48,12 +48,6 @@ #define ImDrawFlags_RoundCornersAll ImDrawCornerFlags_All #endif -// Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize() -#if (IMGUI_VERSION_NUM < 18303) -#define GetBufSize GetSize // A little bit ugly since 'GetBufSize' could technically be used elsewhere (but currently isn't). Could use a proxy define if needed. -#endif - - namespace ImPlot { // Calculates maximum index size of ImDrawIdx without integer overflow issues