1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-26 20:28:50 -05:00

ImPlotLineFlags_Shaded and ImPlotStairsFlags_Shaded

This commit is contained in:
Evan Pezent 2022-06-22 11:00:42 -05:00
parent 6c00109636
commit fc0fd11246
4 changed files with 130 additions and 42 deletions

View File

@ -45,6 +45,8 @@ The list below represents a combination of high-priority work, nice-to-have feat
- first frame render delay might fix "fit pop" effect - first frame render delay might fix "fit pop" effect
- move some code to new `implot_tools.cpp` - move some code to new `implot_tools.cpp`
- ColormapSlider (see metrics) - ColormapSlider (see metrics)
- FillAlpha should not affect markers?
- fix mouse text for time axes
## Optimizations ## Optimizations

View File

@ -84,6 +84,7 @@ typedef int ImPlotLegendFlags; // -> enum ImPlotLegendFlags_
typedef int ImPlotMouseTextFlags; // -> enum ImPlotMouseTextFlags_ typedef int ImPlotMouseTextFlags; // -> enum ImPlotMouseTextFlags_
typedef int ImPlotDragToolFlags; // -> ImPlotDragToolFlags_ typedef int ImPlotDragToolFlags; // -> ImPlotDragToolFlags_
typedef int ImPlotColormapScaleFlags; // -> ImPlotColormapScaleFlags_ typedef int ImPlotColormapScaleFlags; // -> ImPlotColormapScaleFlags_
typedef int ImPlotItemFlags; // -> ImPlotItemFlags_ typedef int ImPlotItemFlags; // -> ImPlotItemFlags_
typedef int ImPlotLineFlags; // -> ImPlotLineFlags_ typedef int ImPlotLineFlags; // -> ImPlotLineFlags_
typedef int ImPlotScatterFlags; // -> ImPlotScatterFlags typedef int ImPlotScatterFlags; // -> ImPlotScatterFlags
@ -163,7 +164,7 @@ enum ImPlotAxisFlags_ {
ImPlotAxisFlags_AuxDefault = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_Opposite ImPlotAxisFlags_AuxDefault = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_Opposite
}; };
// Options for subplots (see BeginSubplot). // Options for subplots (see BeginSubplot)
enum ImPlotSubplotFlags_ { enum ImPlotSubplotFlags_ {
ImPlotSubplotFlags_None = 0, // default ImPlotSubplotFlags_None = 0, // default
ImPlotSubplotFlags_NoTitle = 1 << 0, // the subplot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MySubplot") ImPlotSubplotFlags_NoTitle = 1 << 0, // the subplot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MySubplot")
@ -229,6 +230,7 @@ enum ImPlotLineFlags_ {
ImPlotLineFlags_Loop = 1 << 11, // the last and first point will be connected to form a closed loop ImPlotLineFlags_Loop = 1 << 11, // the last and first point will be connected to form a closed loop
ImPlotLineFlags_SkipNaN = 1 << 12, // NaNs values will be skipped instead of rendered as missing data ImPlotLineFlags_SkipNaN = 1 << 12, // NaNs values will be skipped instead of rendered as missing data
ImPlotLineFlags_NoClip = 1 << 13, // markers (if displayed) on the edge of a plot will not be clipped ImPlotLineFlags_NoClip = 1 << 13, // markers (if displayed) on the edge of a plot will not be clipped
ImPlotLineFlags_Shaded = 1 << 14, // a filled region between the line and horizontal origin will be rendered; use PlotShaded for more advanced cases
}; };
// Flags for PlotScatter // Flags for PlotScatter
@ -240,7 +242,8 @@ enum ImPlotScatterFlags_ {
// Flags for PlotStairs // Flags for PlotStairs
enum ImPlotStairsFlags_ { enum ImPlotStairsFlags_ {
ImPlotStairsFlags_None = 0, // default ImPlotStairsFlags_None = 0, // default
ImPlotStairsFlags_PreStep = 1 << 10 // the y value is continued constantly to the left from every x position, i.e. the interval (x[i-1], x[i]] has the value y[i] ImPlotStairsFlags_PreStep = 1 << 10, // the y value is continued constantly to the left from every x position, i.e. the interval (x[i-1], x[i]] has the value y[i]
ImPlotStairsFlags_Shaded = 1 << 11 // a filled region between the stairs and horizontal origin will be rendered; use PlotShaded for more advanced cases
}; };
// Flags for PlotShaded (placeholder) // Flags for PlotShaded (placeholder)

View File

@ -295,7 +295,7 @@ void Demo_LinePlots() {
xs2[i] = i * 1/19.0f; xs2[i] = i * 1/19.0f;
ys2[i] = xs2[i] * xs2[i]; ys2[i] = xs2[i] * xs2[i];
} }
if (ImPlot::BeginPlot("Line Plot")) { if (ImPlot::BeginPlot("Line Plots")) {
ImPlot::SetupAxes("x","y"); ImPlot::SetupAxes("x","y");
ImPlot::PlotLine("f(x)", xs1, ys1, 1001); ImPlot::PlotLine("f(x)", xs1, ys1, 1001);
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle); ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
@ -419,6 +419,8 @@ void Demo_StairstepPlots() {
ys1[i] = 0.75f + 0.2f * sinf(10 * i * 0.05f); ys1[i] = 0.75f + 0.2f * sinf(10 * i * 0.05f);
ys2[i] = 0.25f + 0.2f * sinf(10 * i * 0.05f); ys2[i] = 0.25f + 0.2f * sinf(10 * i * 0.05f);
} }
static ImPlotStairsFlags flags = 0;
CHECKBOX_FLAG(flags, ImPlotStairsFlags_Shaded);
if (ImPlot::BeginPlot("Stairstep Plot")) { if (ImPlot::BeginPlot("Stairstep Plot")) {
ImPlot::SetupAxes("x","f(x)"); ImPlot::SetupAxes("x","f(x)");
ImPlot::SetupAxesLimits(0,1,0,1); ImPlot::SetupAxesLimits(0,1,0,1);
@ -429,9 +431,11 @@ void Demo_StairstepPlots() {
ImPlot::PopStyleColor(); ImPlot::PopStyleColor();
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle); ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
ImPlot::PlotStairs("Post Step (default)", ys1, 21, 0.05f); ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.25f);
ImPlot::PlotStairs("Post Step (default)", ys1, 21, 0.05f, 0, flags);
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle); ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
ImPlot::PlotStairs("Pre Step", ys2, 21, 0.05f, 0, ImPlotStairsFlags_PreStep); ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.25f);
ImPlot::PlotStairs("Pre Step", ys2, 21, 0.05f, 0, flags|ImPlotStairsFlags_PreStep);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
@ -1202,7 +1206,7 @@ void Demo_AxisConstraints() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Demo_EqualAxes() { void Demo_EqualAxes() {
ImGui::BulletText("Equal constraint applies to axis pairs (e.g ImAxis_X1/Y1, ImAxis_X2/Y2"); ImGui::BulletText("Equal constraint applies to axis pairs (e.g ImAxis_X1/Y1, ImAxis_X2/Y2)");
static double xs1[360], ys1[360]; static double xs1[360], ys1[360];
for (int i = 0; i < 360; ++i) { for (int i = 0; i < 360; ++i) {
double angle = i * 2 * PI / 359.0; double angle = i * 2 * PI / 359.0;
@ -2289,12 +2293,9 @@ void Sparkline(const char* id, const float* values, int count, float min_v, floa
if (ImPlot::BeginPlot(id,size,ImPlotFlags_CanvasOnly|ImPlotFlags_NoChild)) { if (ImPlot::BeginPlot(id,size,ImPlotFlags_CanvasOnly|ImPlotFlags_NoChild)) {
ImPlot::SetupAxes(0,0,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations); ImPlot::SetupAxes(0,0,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations);
ImPlot::SetupAxesLimits(0, count - 1, min_v, max_v, ImGuiCond_Always); ImPlot::SetupAxesLimits(0, count - 1, min_v, max_v, ImGuiCond_Always);
ImPlot::PushStyleColor(ImPlotCol_Line, col); ImPlot::SetNextLineStyle(col);
ImPlot::PlotLine(id, values, count, 1, 0, 0, offset); ImPlot::SetNextFillStyle(col, 0.25);
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f); ImPlot::PlotLine(id, values, count, 1, 0, ImPlotLineFlags_Shaded, offset);
ImPlot::PlotShaded(id, values, count, 0, 1, 0, 0, offset);
ImPlot::PopStyleVar();
ImPlot::PopStyleColor();
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::PopStyleVar(); ImPlot::PopStyleVar();

View File

@ -1159,6 +1159,72 @@ struct RendererStairsPost : RendererBase {
mutable ImVec2 UV; mutable ImVec2 UV;
}; };
template <class _Getter>
struct RendererStairsPreShaded : RendererBase {
RendererStairsPreShaded(const _Getter& getter, ImU32 col) :
RendererBase(getter.Count - 1, 6, 4),
Getter(getter),
Col(col)
{
P1 = this->Transformer(Getter(0));
Y0 = this->Transformer(ImPlotPoint(0,0)).y;
}
void Init(ImDrawList& draw_list) const {
UV = draw_list._Data->TexUvWhitePixel;
}
IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const {
ImVec2 P2 = this->Transformer(Getter(prim + 1));
ImVec2 PMin(ImMin(P1.x, P2.x), ImMin(Y0, P2.y));
ImVec2 PMax(ImMax(P1.x, P2.x), ImMax(Y0, P2.y));
if (!cull_rect.Overlaps(ImRect(PMin, PMax))) {
P1 = P2;
return false;
}
PrimRectFill(draw_list, PMin, PMax, Col, UV);
P1 = P2;
return true;
}
const _Getter& Getter;
const ImU32 Col;
float Y0;
mutable ImVec2 P1;
mutable ImVec2 UV;
};
template <class _Getter>
struct RendererStairsPostShaded : RendererBase {
RendererStairsPostShaded(const _Getter& getter, ImU32 col) :
RendererBase(getter.Count - 1, 6, 4),
Getter(getter),
Col(col)
{
P1 = this->Transformer(Getter(0));
Y0 = this->Transformer(ImPlotPoint(0,0)).y;
}
void Init(ImDrawList& draw_list) const {
UV = draw_list._Data->TexUvWhitePixel;
}
IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const {
ImVec2 P2 = this->Transformer(Getter(prim + 1));
ImVec2 PMin(ImMin(P1.x, P2.x), ImMin(P1.y, Y0));
ImVec2 PMax(ImMax(P1.x, P2.x), ImMax(P1.y, Y0));
if (!cull_rect.Overlaps(ImRect(PMin, PMax))) {
P1 = P2;
return false;
}
PrimRectFill(draw_list, PMin, PMax, Col, UV);
P1 = P2;
return true;
}
const _Getter& Getter;
const ImU32 Col;
float Y0;
mutable ImVec2 P1;
mutable ImVec2 UV;
};
template <class _Getter1, class _Getter2> template <class _Getter1, class _Getter2>
struct RendererShaded : RendererBase { struct RendererShaded : RendererBase {
RendererShaded(const _Getter1& getter1, const _Getter2& getter2, ImU32 col) : RendererShaded(const _Getter1& getter1, const _Getter2& getter2, ImU32 col) :
@ -1462,20 +1528,26 @@ void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool
// [SECTION] PlotLine // [SECTION] PlotLine
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename Getter> template <typename _Getter>
void PlotLineEx(const char* label_id, const Getter& getter, ImPlotLineFlags flags) { void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags) {
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) { if (BeginItemEx(label_id, Fitter1<_Getter>(getter), flags, ImPlotCol_Line)) {
const ImPlotNextItemData& s = GetItemData(); const ImPlotNextItemData& s = GetItemData();
if (getter.Count > 1 && s.RenderLine) { if (getter.Count > 1) {
if (ImHasFlag(flags, ImPlotLineFlags_Shaded) && s.RenderFill) {
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
GetterOverrideY<_Getter> getter2(getter, 0);
RenderPrimitives2<RendererShaded>(getter,getter2,col_fill);
}
if (s.RenderLine) {
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]); const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
if (ImHasFlag(flags,ImPlotLineFlags_Segments)) { if (ImHasFlag(flags,ImPlotLineFlags_Segments)) {
RenderPrimitives1<RendererLineSegments1>(getter,col_line,s.LineWeight); RenderPrimitives1<RendererLineSegments1>(getter,col_line,s.LineWeight);
} }
else if (ImHasFlag(flags, ImPlotLineFlags_Loop)) { else if (ImHasFlag(flags, ImPlotLineFlags_Loop)) {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN)) if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
RenderPrimitives1<RendererLineStripSkip>(GetterLoop<Getter>(getter),col_line,s.LineWeight); RenderPrimitives1<RendererLineStripSkip>(GetterLoop<_Getter>(getter),col_line,s.LineWeight);
else else
RenderPrimitives1<RendererLineStrip>(GetterLoop<Getter>(getter),col_line,s.LineWeight); RenderPrimitives1<RendererLineStrip>(GetterLoop<_Getter>(getter),col_line,s.LineWeight);
} }
else { else {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN)) if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
@ -1484,6 +1556,7 @@ void PlotLineEx(const char* label_id, const Getter& getter, ImPlotLineFlags flag
RenderPrimitives1<RendererLineStrip>(getter,col_line,s.LineWeight); RenderPrimitives1<RendererLineStrip>(getter,col_line,s.LineWeight);
} }
} }
}
// render markers // render markers
if (s.Marker != ImPlotMarker_None) { if (s.Marker != ImPlotMarker_None) {
if (ImHasFlag(flags, ImPlotLineFlags_NoClip)) { if (ImHasFlag(flags, ImPlotLineFlags_NoClip)) {
@ -1492,7 +1565,7 @@ void PlotLineEx(const char* label_id, const Getter& getter, ImPlotLineFlags flag
} }
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerOutline]); const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerOutline]);
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerFill]); const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerFill]);
RenderMarkers<Getter>(getter, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight); RenderMarkers<_Getter>(getter, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
} }
EndItem(); EndItem();
} }
@ -1518,7 +1591,7 @@ template IMPLOT_API void PlotLine<double>(const char* label_id, const double* va
template <typename T> template <typename T>
void PlotLine(const char* label_id, const T* xs, const T* ys, int count, ImPlotLineFlags flags, int offset, int stride) { void PlotLine(const char* label_id, const T* xs, const T* ys, int count, ImPlotLineFlags flags, int offset, int stride) {
GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys,count,offset,stride),count); GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys,count,offset,stride),count);
return PlotLineEx(label_id, getter, flags); PlotLineEx(label_id, getter, flags);
} }
template IMPLOT_API void PlotLine<ImS8>(const char* label_id, const ImS8* xs, const ImS8* ys, int count, ImPlotLineFlags flags, int offset, int stride); template IMPLOT_API void PlotLine<ImS8>(const char* label_id, const ImS8* xs, const ImS8* ys, int count, ImPlotLineFlags flags, int offset, int stride);
@ -1535,7 +1608,7 @@ template IMPLOT_API void PlotLine<double>(const char* label_id, const double* xs
// custom // custom
void PlotLineG(const char* label_id, ImPlotGetter getter_func, void* data, int count, ImPlotLineFlags flags) { void PlotLineG(const char* label_id, ImPlotGetter getter_func, void* data, int count, ImPlotLineFlags flags) {
GetterFuncPtr getter(getter_func,data, count); GetterFuncPtr getter(getter_func,data, count);
return PlotLineEx(label_id, getter, flags); PlotLineEx(label_id, getter, flags);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1608,13 +1681,22 @@ template <typename Getter>
void PlotStairsEx(const char* label_id, const Getter& getter, ImPlotStairsFlags flags) { void PlotStairsEx(const char* label_id, const Getter& getter, ImPlotStairsFlags flags) {
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) { if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) {
const ImPlotNextItemData& s = GetItemData(); const ImPlotNextItemData& s = GetItemData();
if (getter.Count > 1 && s.RenderLine) { if (getter.Count > 1 ) {
if (s.RenderFill && ImHasFlag(flags,ImPlotStairsFlags_Shaded)) {
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
RenderPrimitives1<RendererStairsPreShaded>(getter,col_fill);
else
RenderPrimitives1<RendererStairsPostShaded>(getter,col_fill);
}
if (s.RenderLine) {
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]); const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep)) if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
RenderPrimitives1<RendererStairsPre>(getter,col_line,s.LineWeight); RenderPrimitives1<RendererStairsPre>(getter,col_line,s.LineWeight);
else else
RenderPrimitives1<RendererStairsPost>(getter,col_line,s.LineWeight); RenderPrimitives1<RendererStairsPost>(getter,col_line,s.LineWeight);
} }
}
// render markers // render markers
if (s.Marker != ImPlotMarker_None) { if (s.Marker != ImPlotMarker_None) {
PopPlotClipRect(); PopPlotClipRect();