Skip to content

Commit a47192d

Browse files
committed
Add PlotShadedClip
1 parent d875123 commit a47192d

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

implot.h

+6
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,12 @@ IMPLOT_TMP void PlotShaded(const char* label_id, const T* xs, const T* ys, int c
871871
IMPLOT_TMP void PlotShaded(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
872872
IMPLOT_API void PlotShadedG(const char* label_id, ImPlotGetter getter1, void* data1, ImPlotGetter getter2, void* data2, int count, ImPlotShadedFlags flags=0);
873873

874+
// Plots a shaded (filled) region between two lines, only if the second line is higher than the first one
875+
IMPLOT_TMP void PlotShadedClip(const char* label_id, const T* values, int count, double yref=0, double xscale=1, double xstart=0, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
876+
IMPLOT_TMP void PlotShadedClip(const char* label_id, const T* xs, const T* ys, int count, double yref=0, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
877+
IMPLOT_TMP void PlotShadedClip(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
878+
IMPLOT_API void PlotShadedClipG(const char* label_id, ImPlotGetter getter1, void* data1, ImPlotGetter getter2, void* data2, int count, ImPlotShadedFlags flags=0);
879+
874880
// Plots a bar graph. Vertical by default. #bar_size and #shift are in plot units.
875881
IMPLOT_TMP void PlotBars(const char* label_id, const T* values, int count, double bar_size=0.67, double shift=0, ImPlotBarsFlags flags=0, int offset=0, int stride=sizeof(T));
876882
IMPLOT_TMP void PlotBars(const char* label_id, const T* xs, const T* ys, int count, double bar_size, ImPlotBarsFlags flags=0, int offset=0, int stride=sizeof(T));

implot_demo.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,22 @@ void Demo_ShadedPlots() {
384384
ImPlot::PopStyleVar();
385385
ImPlot::EndPlot();
386386
}
387+
if (ImPlot::BeginPlot("Shaded Clip Plots")) {
388+
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, alpha);
389+
390+
ImPlot::SetNextLineStyle(ImVec4(0.0f,1.0f,0.0f,0.25f));
391+
ImPlot::SetNextFillStyle(ImVec4(0.0f,1.0f,0.0f,0.25f));
392+
ImPlot::PlotLine("Overlapping",xs,ys4,1001);
393+
ImPlot::PlotShadedClip("Overlapping",xs,ys3,ys4,1001);
394+
395+
ImPlot::SetNextLineStyle(ImVec4(1.0f,0.0f,0.0f,0.25f));
396+
ImPlot::SetNextFillStyle(ImVec4(1.0f,0.0f,0.0f,0.25f));
397+
ImPlot::PlotLine("Overlapping",xs,ys3,1001);
398+
ImPlot::PlotShadedClip("Overlapping",xs,ys4,ys3,1001);
399+
400+
ImPlot::PopStyleVar();
401+
ImPlot::EndPlot();
402+
}
387403
}
388404

389405
//-----------------------------------------------------------------------------

implot_items.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,53 @@ struct RendererRectC : RendererBase {
13511351
mutable ImVec2 UV;
13521352
};
13531353

1354+
template <class _Getter1, class _Getter2>
1355+
struct RendererShadedClip : RendererShaded<_Getter1, _Getter2> {
1356+
RendererShadedClip(const _Getter1& getter1, const _Getter2& getter2, ImU32 col) :
1357+
RendererShaded<_Getter1, _Getter2>(getter1, getter2, col)
1358+
{}
1359+
1360+
IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const {
1361+
ImVec2 P21 = this->Transformer(this->Getter1(prim+1));
1362+
ImVec2 P22 = this->Transformer(this->Getter2(prim+1));
1363+
ImRect rect(ImMin(ImMin(ImMin(this->P11,this->P12),P21),P22), ImMax(ImMax(ImMax(this->P11,this->P12),P21),P22));
1364+
if (!cull_rect.Overlaps(rect)) {
1365+
this->P11 = P21;
1366+
this->P12 = P22;
1367+
return false;
1368+
}
1369+
const int intersect = (this->P11.y > this->P12.y && P22.y > P21.y) || (this->P12.y > this->P11.y && P21.y > P22.y);
1370+
ImVec2 intersection = Intersection(this->P11,P21,this->P12,P22);
1371+
draw_list._VtxWritePtr[0].pos = this->P11;
1372+
draw_list._VtxWritePtr[0].uv = this->UV;
1373+
draw_list._VtxWritePtr[0].col = this->Col;
1374+
draw_list._VtxWritePtr[1].pos = P21;
1375+
draw_list._VtxWritePtr[1].uv = this->UV;
1376+
draw_list._VtxWritePtr[1].col = this->Col;
1377+
draw_list._VtxWritePtr[2].pos = intersection;
1378+
draw_list._VtxWritePtr[2].uv = this->UV;
1379+
draw_list._VtxWritePtr[2].col = this->Col;
1380+
draw_list._VtxWritePtr[3].pos = this->P12;
1381+
draw_list._VtxWritePtr[3].uv = this->UV;
1382+
draw_list._VtxWritePtr[3].col = this->Col;
1383+
draw_list._VtxWritePtr[4].pos = P22;
1384+
draw_list._VtxWritePtr[4].uv = this->UV;
1385+
draw_list._VtxWritePtr[4].col = this->Col;
1386+
draw_list._VtxWritePtr += 5;
1387+
draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx);
1388+
draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1 + intersect);
1389+
draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 0 + 3 * (this->P11.y >= this->P12.y) );
1390+
draw_list._IdxWritePtr[3] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1);
1391+
draw_list._IdxWritePtr[4] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3 - intersect);
1392+
draw_list._IdxWritePtr[5] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1 + 3 * (P21.y >= P22.y) );
1393+
draw_list._IdxWritePtr += 6;
1394+
draw_list._VtxCurrentIdx += 5;
1395+
this->P11 = P21;
1396+
this->P12 = P22;
1397+
return true;
1398+
}
1399+
};
1400+
13541401
//-----------------------------------------------------------------------------
13551402
// [SECTION] RenderPrimitives
13561403
//-----------------------------------------------------------------------------
@@ -1798,6 +1845,67 @@ void PlotShadedG(const char* label_id, ImPlotGetter getter_func1, void* data1, I
17981845
PlotShadedEx(label_id, getter1, getter2, flags);
17991846
}
18001847

1848+
//-----------------------------------------------------------------------------
1849+
// [SECTION] PlotShadedClip
1850+
//-----------------------------------------------------------------------------
1851+
1852+
// NEW
1853+
template <typename Getter1, typename Getter2>
1854+
void PlotShadedClipEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, ImPlotShadedFlags flags) {
1855+
if (BeginItemEx(label_id, Fitter2<Getter1,Getter2>(getter1,getter2), flags, ImPlotCol_Fill)) {
1856+
const ImPlotNextItemData& s = GetItemData();
1857+
if (s.RenderFill) {
1858+
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
1859+
RenderPrimitives2<RendererShadedClip>(getter1,getter2,col);
1860+
}
1861+
EndItem();
1862+
}
1863+
}
1864+
1865+
template <typename T>
1866+
void PlotShadedClip(const char* label_id, const T* values, int count, double y_ref, double xscale, double x0, ImPlotShadedFlags flags, int offset, int stride) {
1867+
if (!(y_ref > -DBL_MAX))
1868+
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Min;
1869+
if (!(y_ref < DBL_MAX))
1870+
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Max;
1871+
GetterXY<IndexerLin,IndexerIdx<T>> getter1(IndexerLin(xscale,x0),IndexerIdx<T>(values,count,offset,stride),count);
1872+
GetterXY<IndexerLin,IndexerConst> getter2(IndexerLin(xscale,x0),IndexerConst(y_ref),count);
1873+
PlotShadedClipEx(label_id, getter1, getter2, flags);
1874+
}
1875+
1876+
template <typename T>
1877+
void PlotShadedClip(const char* label_id, const T* xs, const T* ys, int count, double y_ref, ImPlotShadedFlags flags, int offset, int stride) {
1878+
if (y_ref == -HUGE_VAL)
1879+
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Min;
1880+
if (y_ref == HUGE_VAL)
1881+
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Max;
1882+
GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter1(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys,count,offset,stride),count);
1883+
GetterXY<IndexerIdx<T>,IndexerConst> getter2(IndexerIdx<T>(xs,count,offset,stride),IndexerConst(y_ref),count);
1884+
PlotShadedClipEx(label_id, getter1, getter2, flags);
1885+
}
1886+
1887+
1888+
template <typename T>
1889+
void PlotShadedClip(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, ImPlotShadedFlags flags, int offset, int stride) {
1890+
GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter1(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys1,count,offset,stride),count);
1891+
GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter2(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys2,count,offset,stride),count);
1892+
PlotShadedClipEx(label_id, getter1, getter2, flags);
1893+
}
1894+
1895+
#define INSTANTIATE_MACRO(T) \
1896+
template IMPLOT_API void PlotShadedClip<T>(const char* label_id, const T* values, int count, double y_ref, double xscale, double x0, ImPlotShadedFlags flags, int offset, int stride); \
1897+
template IMPLOT_API void PlotShadedClip<T>(const char* label_id, const T* xs, const T* ys, int count, double y_ref, ImPlotShadedFlags flags, int offset, int stride); \
1898+
template IMPLOT_API void PlotShadedClip<T>(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, ImPlotShadedFlags flags, int offset, int stride);
1899+
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
1900+
#undef INSTANTIATE_MACRO
1901+
1902+
// custom
1903+
void PlotShadedClipG(const char* label_id, ImPlotGetter getter_func1, void* data1, ImPlotGetter getter_func2, void* data2, int count, ImPlotShadedFlags flags) {
1904+
GetterFuncPtr getter1(getter_func1, data1, count);
1905+
GetterFuncPtr getter2(getter_func2, data2, count);
1906+
PlotShadedClipEx(label_id, getter1, getter2, flags);
1907+
}
1908+
18011909
//-----------------------------------------------------------------------------
18021910
// [SECTION] PlotBars
18031911
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)