Skip to content

Commit 3c7ec60

Browse files
committed
Add PlotShadedClip
1 parent 555ff68 commit 3c7ec60

File tree

2 files changed

+163
-1
lines changed

2 files changed

+163
-1
lines changed

implot.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,10 @@ template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T*
449449
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));
450450
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);
451451

452+
// Plots a shaded (filled) region between two lines, only if the second line is higher than the first one
453+
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));
454+
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);
455+
452456
// Plots a vertical bar graph. #width and #shift are in X units.
453457
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));
454458
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: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,109 @@ struct ShadedRenderer {
685685
static const int VtxConsumed = 5;
686686
};
687687

688+
template <typename TGetter1, typename TGetter2, typename TTransformer>
689+
struct ShadedClipRenderer {
690+
ShadedClipRenderer(const TGetter1& getter1, const TGetter2& getter2, const TTransformer& transformer, ImU32 col) :
691+
Getter1(getter1),
692+
Getter2(getter2),
693+
Transformer(transformer),
694+
Prims(ImMin(Getter1.Count, Getter2.Count) - 1),
695+
Col(col)
696+
{
697+
P11 = Transformer(Getter1(0));
698+
P12 = Transformer(Getter2(0));
699+
}
700+
701+
inline bool operator()(ImDrawList& DrawList, const ImRect& /*cull_rect*/, const ImVec2& uv, int prim) const {
702+
// TODO: Culling
703+
ImVec2 P21 = Transformer(Getter1(prim+1));
704+
ImVec2 P22 = Transformer(Getter2(prim+1));
705+
const int intersect = (P11.y > P12.y && P22.y > P21.y) || (P12.y > P11.y && P21.y > P22.y);
706+
ImVec2 intersection = Intersection(P11,P21,P12,P22);
707+
DrawList._VtxWritePtr[0].pos = P11;
708+
DrawList._VtxWritePtr[0].uv = uv;
709+
DrawList._VtxWritePtr[0].col = Col;
710+
DrawList._VtxWritePtr[1].pos = P21;
711+
DrawList._VtxWritePtr[1].uv = uv;
712+
DrawList._VtxWritePtr[1].col = Col;
713+
DrawList._VtxWritePtr[2].pos = intersection;
714+
DrawList._VtxWritePtr[2].uv = uv;
715+
DrawList._VtxWritePtr[2].col = Col;
716+
DrawList._VtxWritePtr[3].pos = P12;
717+
DrawList._VtxWritePtr[3].uv = uv;
718+
DrawList._VtxWritePtr[3].col = Col;
719+
DrawList._VtxWritePtr[4].pos = P22;
720+
DrawList._VtxWritePtr[4].uv = uv;
721+
DrawList._VtxWritePtr[4].col = Col;
722+
DrawList._VtxWritePtr += 5;
723+
DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
724+
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + intersect);
725+
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 0 + 3 * (P11.y >= P12.y) );
726+
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
727+
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3 - intersect);
728+
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + 3 * (P21.y >= P22.y) );
729+
DrawList._IdxWritePtr += 6;
730+
DrawList._VtxCurrentIdx += 5;
731+
P11 = P21;
732+
P12 = P22;
733+
return true;
734+
}
735+
const TGetter1& Getter1;
736+
const TGetter2& Getter2;
737+
const TTransformer& Transformer;
738+
const int Prims;
739+
const ImU32 Col;
740+
mutable ImVec2 P11;
741+
mutable ImVec2 P12;
742+
static const int IdxConsumed = 6;
743+
static const int VtxConsumed = 5;
744+
};
745+
746+
template <typename TGetter, typename TTransformer>
747+
struct RectRenderer {
748+
inline RectRenderer(const TGetter& getter, const TTransformer& transformer, ImU32 col) :
749+
Getter(getter),
750+
Transformer(transformer),
751+
Prims(Getter.Count / 2),
752+
Col(col)
753+
{}
754+
inline bool operator()(ImDrawList& DrawList, const ImRect& /*cull_rect*/, const ImVec2& uv, int prim) const {
755+
// TODO: Culling
756+
ImVec2 P1 = Transformer(Getter(2*prim));
757+
ImVec2 P2 = Transformer(Getter(2*prim+1));
758+
DrawList._VtxWritePtr[0].pos = P1;
759+
DrawList._VtxWritePtr[0].uv = uv;
760+
DrawList._VtxWritePtr[0].col = Col;
761+
DrawList._VtxWritePtr[1].pos.x = P1.x;
762+
DrawList._VtxWritePtr[1].pos.y = P2.y;
763+
DrawList._VtxWritePtr[1].uv = uv;
764+
DrawList._VtxWritePtr[1].col = Col;
765+
DrawList._VtxWritePtr[2].pos = P2;
766+
DrawList._VtxWritePtr[2].uv = uv;
767+
DrawList._VtxWritePtr[2].col = Col;
768+
DrawList._VtxWritePtr[3].pos.x = P2.x;
769+
DrawList._VtxWritePtr[3].pos.y = P1.y;
770+
DrawList._VtxWritePtr[3].uv = uv;
771+
DrawList._VtxWritePtr[3].col = Col;
772+
DrawList._VtxWritePtr += 4;
773+
DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
774+
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
775+
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3);
776+
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
777+
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 2);
778+
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3);
779+
DrawList._IdxWritePtr += 6;
780+
DrawList._VtxCurrentIdx += 4;
781+
return true;
782+
}
783+
const TGetter& Getter;
784+
const TTransformer& Transformer;
785+
const int Prims;
786+
const ImU32 Col;
787+
static const int IdxConsumed = 6;
788+
static const int VtxConsumed = 4;
789+
};
790+
688791
// Stupid way of calculating maximum index size of ImDrawIdx without integer overflow issues
689792
template <typename T>
690793
struct MaxIdx { static const unsigned int Value; };
@@ -1236,6 +1339,61 @@ void PlotShadedG(const char* label_id, ImPlotPoint (*g1)(void* data, int idx), v
12361339
PlotShadedEx(label_id, getter1, getter2, true);
12371340
}
12381341

1342+
//-----------------------------------------------------------------------------
1343+
// PLOT SHADEDCLIP
1344+
//-----------------------------------------------------------------------------
1345+
1346+
template <typename Getter1, typename Getter2>
1347+
inline void PlotShadedClipEx(const char* label_id, const Getter1& getter1, const Getter2& getter2) {
1348+
if (BeginItem(label_id, ImPlotCol_Fill)) {
1349+
if (FitThisFrame()) {
1350+
for (int i = 0; i < ImMin(getter1.Count, getter2.Count); ++i) {
1351+
ImPlotPoint p1 = getter1(i);
1352+
ImPlotPoint p2 = getter2(i);
1353+
FitPoint(p1);
1354+
FitPoint(p2);
1355+
}
1356+
}
1357+
const ImPlotNextItemData& s = GetItemData();
1358+
ImDrawList & DrawList = *GetPlotDrawList();
1359+
if (s.RenderFill) {
1360+
ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
1361+
switch (GetCurrentScale()) {
1362+
case ImPlotScale_LinLin: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLinLin>(getter1,getter2,TransformerLinLin(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1363+
case ImPlotScale_LogLin: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLogLin>(getter1,getter2,TransformerLogLin(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1364+
case ImPlotScale_LinLog: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLinLog>(getter1,getter2,TransformerLinLog(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1365+
case ImPlotScale_LogLog: RenderPrimitives(ShadedClipRenderer<Getter1,Getter2,TransformerLogLog>(getter1,getter2,TransformerLogLog(), col), DrawList, GImPlot->CurrentPlot->PlotRect); break;
1366+
}
1367+
}
1368+
EndItem();
1369+
}
1370+
}
1371+
1372+
template <typename T>
1373+
void PlotShadedClip(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset, int stride) {
1374+
GetterXsYs<T> getter1(xs, ys1, count, offset, stride);
1375+
GetterXsYs<T> getter2(xs, ys2, count, offset, stride);
1376+
PlotShadedClipEx(label_id, getter1, getter2);
1377+
}
1378+
1379+
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);
1380+
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);
1381+
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);
1382+
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);
1383+
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);
1384+
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);
1385+
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);
1386+
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);
1387+
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);
1388+
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);
1389+
1390+
// custom
1391+
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) {
1392+
GetterFuncPtr getter1(g1, data1, count, offset);
1393+
GetterFuncPtr getter2(g2, data2, count, offset);
1394+
PlotShadedClipEx(label_id, getter1, getter2);
1395+
}
1396+
12391397
//-----------------------------------------------------------------------------
12401398
// PLOT BAR
12411399
//-----------------------------------------------------------------------------
@@ -2249,4 +2407,4 @@ void PlotDummy(const char* label_id) {
22492407
EndItem();
22502408
}
22512409

2252-
} // namespace ImPlot
2410+
} // namespace ImPlot

0 commit comments

Comments
 (0)