Skip to content

Commit 0962a21

Browse files
committed
Add PlotShadedClip
1 parent a9d3347 commit 0962a21

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

implot.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T*
409409
template <typename T> 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));
410410
IMPLOT_API void PlotShadedG(const char* label_id, ImPlotPoint (*getter1)(void* data, int idx), void* data1, ImPlotPoint (*getter2)(void* data, int idx), void* data2, int count, int offset=0);
411411

412+
// Plots a shaded (filled) region between two lines, only if the second line is higher than the first one
413+
template <typename T> IMPLOT_API void PlotShadedClip(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset=0, int stride=sizeof(T));
414+
IMPLOT_API void PlotShadedClipG(const char* label_id, ImPlotPoint (*getter1)(void* data, int idx), void* data1, ImPlotPoint (*getter2)(void* data, int idx), void* data2, int count, int offset=0);
415+
412416
// Plots a vertical bar graph. #width and #shift are in X units.
413417
template <typename T> IMPLOT_API void PlotBars(const char* label_id, const T* values, int count, double width=0.67, double shift=0, int offset=0, int stride=sizeof(T));
414418
template <typename T> IMPLOT_API void PlotBars(const char* label_id, const T* xs, const T* ys, int count, double width, int offset=0, int stride=sizeof(T));

implot_items.cpp

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,64 @@ struct ShadedRenderer {
634634
static const int VtxConsumed = 5;
635635
};
636636

637+
template <typename TGetter1, typename TGetter2, typename TTransformer>
638+
struct ShadedClipRenderer {
639+
ShadedClipRenderer(const TGetter1& getter1, const TGetter2& getter2, const TTransformer& transformer, ImU32 col) :
640+
Getter1(getter1),
641+
Getter2(getter2),
642+
Transformer(transformer),
643+
Prims(ImMin(Getter1.Count, Getter2.Count) - 1),
644+
Col(col)
645+
{
646+
P11 = Transformer(Getter1(0));
647+
P12 = Transformer(Getter2(0));
648+
}
649+
650+
inline bool operator()(ImDrawList& DrawList, const ImRect& /*cull_rect*/, const ImVec2& uv, int prim) const {
651+
// TODO: Culling
652+
ImVec2 P21 = Transformer(Getter1(prim+1));
653+
ImVec2 P22 = Transformer(Getter2(prim+1));
654+
const int intersect = (P11.y > P12.y && P22.y > P21.y) || (P12.y > P11.y && P21.y > P22.y);
655+
ImVec2 intersection = Intersection(P11,P21,P12,P22);
656+
DrawList._VtxWritePtr[0].pos = P11;
657+
DrawList._VtxWritePtr[0].uv = uv;
658+
DrawList._VtxWritePtr[0].col = Col;
659+
DrawList._VtxWritePtr[1].pos = P21;
660+
DrawList._VtxWritePtr[1].uv = uv;
661+
DrawList._VtxWritePtr[1].col = Col;
662+
DrawList._VtxWritePtr[2].pos = intersection;
663+
DrawList._VtxWritePtr[2].uv = uv;
664+
DrawList._VtxWritePtr[2].col = Col;
665+
DrawList._VtxWritePtr[3].pos = P12;
666+
DrawList._VtxWritePtr[3].uv = uv;
667+
DrawList._VtxWritePtr[3].col = Col;
668+
DrawList._VtxWritePtr[4].pos = P22;
669+
DrawList._VtxWritePtr[4].uv = uv;
670+
DrawList._VtxWritePtr[4].col = Col;
671+
DrawList._VtxWritePtr += 5;
672+
DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
673+
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + intersect);
674+
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 0 + 3 * (P11.y >= P12.y) );
675+
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
676+
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3 - intersect);
677+
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + 3 * (P21.y >= P22.y) );
678+
DrawList._IdxWritePtr += 6;
679+
DrawList._VtxCurrentIdx += 5;
680+
P11 = P21;
681+
P12 = P22;
682+
return true;
683+
}
684+
const TGetter1& Getter1;
685+
const TGetter2& Getter2;
686+
const TTransformer& Transformer;
687+
const int Prims;
688+
const ImU32 Col;
689+
mutable ImVec2 P11;
690+
mutable ImVec2 P12;
691+
static const int IdxConsumed = 6;
692+
static const int VtxConsumed = 5;
693+
};
694+
637695
template <typename TGetter, typename TTransformer>
638696
struct RectRenderer {
639697
inline RectRenderer(const TGetter& getter, const TTransformer& transformer, ImU32 col) :
@@ -1206,6 +1264,61 @@ void PlotShadedG(const char* label_id, ImPlotPoint (*g1)(void* data, int idx), v
12061264
PlotShadedEx(label_id, getter1, getter2);
12071265
}
12081266

1267+
//-----------------------------------------------------------------------------
1268+
// PLOT SHADEDCLIP
1269+
//-----------------------------------------------------------------------------
1270+
1271+
template <typename Getter1, typename Getter2>
1272+
inline void PlotShadedClipEx(const char* label_id, const Getter1& getter1, const Getter2& getter2) {
1273+
if (BeginItem(label_id, ImPlotCol_Fill)) {
1274+
if (FitThisFrame()) {
1275+
for (int i = 0; i < ImMin(getter1.Count, getter2.Count); ++i) {
1276+
ImPlotPoint p1 = getter1(i);
1277+
ImPlotPoint p2 = getter2(i);
1278+
FitPoint(p1);
1279+
FitPoint(p2);
1280+
}
1281+
}
1282+
const ImPlotNextItemData& s = GetItemData();
1283+
ImDrawList & DrawList = *GetPlotDrawList();
1284+
if (s.RenderFill) {
1285+
ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
1286+
switch (GetCurrentScale()) {
1287+
case ImPlotScale_LinLin: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLinLin>(getter1,getter2,TransformerLinLin(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1288+
case ImPlotScale_LogLin: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLogLin>(getter1,getter2,TransformerLogLin(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1289+
case ImPlotScale_LinLog: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLinLog>(getter1,getter2,TransformerLinLog(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1290+
case ImPlotScale_LogLog: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLogLog>(getter1,getter2,TransformerLogLog(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1291+
}
1292+
}
1293+
EndItem();
1294+
}
1295+
}
1296+
1297+
template <typename T>
1298+
void PlotShadedClip(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset, int stride) {
1299+
GetterXsYs<T> getter1(xs, ys1, count, offset, stride);
1300+
GetterXsYs<T> getter2(xs, ys2, count, offset, stride);
1301+
PlotShadedClipEx(label_id, getter1, getter2);
1302+
}
1303+
1304+
template IMPLOT_API void PlotShadedClip<ImS8>(const char* label_id, const ImS8* xs, const ImS8* ys1, const ImS8* ys2, int count, int offset, int stride);
1305+
template IMPLOT_API void PlotShadedClip<ImU8>(const char* label_id, const ImU8* xs, const ImU8* ys1, const ImU8* ys2, int count, int offset, int stride);
1306+
template IMPLOT_API void PlotShadedClip<ImS16>(const char* label_id, const ImS16* xs, const ImS16* ys1, const ImS16* ys2, int count, int offset, int stride);
1307+
template IMPLOT_API void PlotShadedClip<ImU16>(const char* label_id, const ImU16* xs, const ImU16* ys1, const ImU16* ys2, int count, int offset, int stride);
1308+
template IMPLOT_API void PlotShadedClip<ImS32>(const char* label_id, const ImS32* xs, const ImS32* ys1, const ImS32* ys2, int count, int offset, int stride);
1309+
template IMPLOT_API void PlotShadedClip<ImU32>(const char* label_id, const ImU32* xs, const ImU32* ys1, const ImU32* ys2, int count, int offset, int stride);
1310+
template IMPLOT_API void PlotShadedClip<ImS64>(const char* label_id, const ImS64* xs, const ImS64* ys1, const ImS64* ys2, int count, int offset, int stride);
1311+
template IMPLOT_API void PlotShadedClip<ImU64>(const char* label_id, const ImU64* xs, const ImU64* ys1, const ImU64* ys2, int count, int offset, int stride);
1312+
template IMPLOT_API void PlotShadedClip<float>(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset, int stride);
1313+
template IMPLOT_API void PlotShadedClip<double>(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset, int stride);
1314+
1315+
// custom
1316+
void PlotShadedClipG(const char* label_id, ImPlotPoint (*g1)(void* data, int idx), void* data1, ImPlotPoint (*g2)(void* data, int idx), void* data2, int count, int offset) {
1317+
GetterFuncPtr getter1(g1, data1, count, offset);
1318+
GetterFuncPtr getter2(g2, data2, count, offset);
1319+
PlotShadedClipEx(label_id, getter1, getter2);
1320+
}
1321+
12091322
//-----------------------------------------------------------------------------
12101323
// PLOT BAR
12111324
//-----------------------------------------------------------------------------
@@ -1912,4 +2025,4 @@ void PlotDummy(const char* label_id) {
19122025
EndItem();
19132026
}
19142027

1915-
} // namespace ImPlot
2028+
} // namespace ImPlot

0 commit comments

Comments
 (0)