diff --git a/implot.h b/implot.h index db4d2fb..9f0230c 100644 --- a/implot.h +++ b/implot.h @@ -406,7 +406,7 @@ template IMPLOT_API void PlotStairs(const char* label_id, const T* template IMPLOT_API void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T)); IMPLOT_API void PlotStairsG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0); -// Plots a shaded (filled) region between two lines, or a line and a horizontal reference. +// Plots a shaded (filled) region between two lines, or a line and a horizontal reference. Set y_ref to +/-INFINITY for infinite fill extents. template IMPLOT_API void PlotShaded(const char* label_id, const T* values, int count, double y_ref=0, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T)); template IMPLOT_API void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, double y_ref=0, int offset=0, int stride=sizeof(T)); template IMPLOT_API void PlotShaded(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset=0, int stride=sizeof(T)); diff --git a/implot_demo.cpp b/implot_demo.cpp index 30ac942..55e20aa 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -264,17 +264,34 @@ void ShowDemoWindow(bool* p_open) { static bool show_lines = true; static bool show_fills = true; static float fill_ref = 0; + static int shade_mode = 0; ImGui::Checkbox("Lines",&show_lines); ImGui::SameLine(); ImGui::Checkbox("Fills",&show_fills); - ImGui::DragFloat("Reference",&fill_ref, 1, -100, 500); + if (show_fills) { + ImGui::SameLine(); + if (ImGui::RadioButton("To -INF",shade_mode == 0)) + shade_mode = 0; + ImGui::SameLine(); + if (ImGui::RadioButton("To +INF",shade_mode == 1)) + shade_mode = 1; + ImGui::SameLine(); + if (ImGui::RadioButton("To Ref",shade_mode == 2)) + shade_mode = 2; + if (shade_mode == 2) { + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::DragFloat("##Ref",&fill_ref, 1, -100, 500); + } + } + ImPlot::SetNextPlotLimits(0,100,0,500); if (ImPlot::BeginPlot("Stock Prices", "Days", "Price")) { if (show_fills) { ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f); - ImPlot::PlotShaded("Stock 1", xs1, ys1, 101, fill_ref); - ImPlot::PlotShaded("Stock 2", xs1, ys2, 101, fill_ref); - ImPlot::PlotShaded("Stock 3", xs1, ys3, 101, fill_ref); + ImPlot::PlotShaded("Stock 1", xs1, ys1, 101, shade_mode == 0 ? -INFINITY : shade_mode == 1 ? INFINITY : fill_ref); + ImPlot::PlotShaded("Stock 2", xs1, ys2, 101, shade_mode == 0 ? -INFINITY : shade_mode == 1 ? INFINITY : fill_ref); + ImPlot::PlotShaded("Stock 3", xs1, ys3, 101, shade_mode == 0 ? -INFINITY : shade_mode == 1 ? INFINITY : fill_ref); ImPlot::PopStyleVar(); } if (show_lines) { diff --git a/implot_items.cpp b/implot_items.cpp index 74630e2..2e9840f 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -1120,14 +1120,14 @@ void PlotStairsG(const char* label_id, ImPlotPoint (*getter_func)(void* data, in //----------------------------------------------------------------------------- template -inline void PlotShadedEx(const char* label_id, const Getter1& getter1, const Getter2& getter2) { +inline void PlotShadedEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, bool fit2) { if (BeginItem(label_id, ImPlotCol_Fill)) { if (FitThisFrame()) { - for (int i = 0; i < ImMin(getter1.Count, getter2.Count); ++i) { - ImPlotPoint p1 = getter1(i); - ImPlotPoint p2 = getter2(i); - FitPoint(p1); - FitPoint(p2); + for (int i = 0; i < getter1.Count; ++i) + FitPoint(getter1(i)); + if (fit2) { + for (int i = 0; i < getter2.Count; ++i) + FitPoint(getter2(i)); } } const ImPlotNextItemData& s = GetItemData(); @@ -1147,9 +1147,18 @@ inline void PlotShadedEx(const char* label_id, const Getter1& getter1, const Get template void PlotShaded(const char* label_id, const T* values, int count, double y_ref, double xscale, double x0, int offset, int stride) { + bool fit2 = true; + if (y_ref == -HUGE_VAL) { + fit2 = false; + y_ref = GetPlotLimits().Y.Min; + } + if (y_ref == HUGE_VAL) { + fit2 = false; + y_ref = GetPlotLimits().Y.Max; + } GetterYs getter1(values,count,xscale,x0,offset,stride); GetterYRef getter2(y_ref,count,xscale,x0); - PlotShadedEx(label_id, getter1, getter2); + PlotShadedEx(label_id, getter1, getter2, fit2); } template IMPLOT_API void PlotShaded(const char* label_id, const ImS8* values, int count, double y_ref, double xscale, double x0, int offset, int stride); @@ -1165,9 +1174,18 @@ template IMPLOT_API void PlotShaded(const char* label_id, const double* template void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, double y_ref, int offset, int stride) { + bool fit2 = true; + if (y_ref == -HUGE_VAL) { + fit2 = false; + y_ref = GetPlotLimits().Y.Min; + } + if (y_ref == HUGE_VAL) { + fit2 = false; + y_ref = GetPlotLimits().Y.Max; + } GetterXsYs getter1(xs, ys, count, offset, stride); GetterXsYRef getter2(xs, y_ref, count, offset, stride); - PlotShadedEx(label_id, getter1, getter2); + PlotShadedEx(label_id, getter1, getter2, fit2); } template IMPLOT_API void PlotShaded(const char* label_id, const ImS8* xs, const ImS8* ys, int count, double y_ref, int offset, int stride); @@ -1185,7 +1203,7 @@ template void PlotShaded(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset, int stride) { GetterXsYs getter1(xs, ys1, count, offset, stride); GetterXsYs getter2(xs, ys2, count, offset, stride); - PlotShadedEx(label_id, getter1, getter2); + PlotShadedEx(label_id, getter1, getter2, true); } template IMPLOT_API void PlotShaded(const char* label_id, const ImS8* xs, const ImS8* ys1, const ImS8* ys2, int count, int offset, int stride); @@ -1203,7 +1221,7 @@ template IMPLOT_API void PlotShaded(const char* label_id, const double* void PlotShadedG(const char* label_id, ImPlotPoint (*g1)(void* data, int idx), void* data1, ImPlotPoint (*g2)(void* data, int idx), void* data2, int count, int offset) { GetterFuncPtr getter1(g1, data1, count, offset); GetterFuncPtr getter2(g2, data2, count, offset); - PlotShadedEx(label_id, getter1, getter2); + PlotShadedEx(label_id, getter1, getter2, true); } //-----------------------------------------------------------------------------