1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-22 18:28:53 -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
- move some code to new `implot_tools.cpp`
- ColormapSlider (see metrics)
- FillAlpha should not affect markers?
- fix mouse text for time axes
## Optimizations

View File

@ -84,6 +84,7 @@ typedef int ImPlotLegendFlags; // -> enum ImPlotLegendFlags_
typedef int ImPlotMouseTextFlags; // -> enum ImPlotMouseTextFlags_
typedef int ImPlotDragToolFlags; // -> ImPlotDragToolFlags_
typedef int ImPlotColormapScaleFlags; // -> ImPlotColormapScaleFlags_
typedef int ImPlotItemFlags; // -> ImPlotItemFlags_
typedef int ImPlotLineFlags; // -> ImPlotLineFlags_
typedef int ImPlotScatterFlags; // -> ImPlotScatterFlags
@ -163,7 +164,7 @@ enum ImPlotAxisFlags_ {
ImPlotAxisFlags_AuxDefault = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_Opposite
};
// Options for subplots (see BeginSubplot).
// Options for subplots (see BeginSubplot)
enum ImPlotSubplotFlags_ {
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")
@ -229,6 +230,7 @@ enum ImPlotLineFlags_ {
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_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
@ -239,8 +241,9 @@ enum ImPlotScatterFlags_ {
// Flags for PlotStairs
enum ImPlotStairsFlags_ {
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_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_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)

View File

@ -295,7 +295,7 @@ void Demo_LinePlots() {
xs2[i] = i * 1/19.0f;
ys2[i] = xs2[i] * xs2[i];
}
if (ImPlot::BeginPlot("Line Plot")) {
if (ImPlot::BeginPlot("Line Plots")) {
ImPlot::SetupAxes("x","y");
ImPlot::PlotLine("f(x)", xs1, ys1, 1001);
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
@ -419,6 +419,8 @@ void Demo_StairstepPlots() {
ys1[i] = 0.75f + 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")) {
ImPlot::SetupAxes("x","f(x)");
ImPlot::SetupAxesLimits(0,1,0,1);
@ -429,9 +431,11 @@ void Demo_StairstepPlots() {
ImPlot::PopStyleColor();
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::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();
}
@ -1202,7 +1206,7 @@ void Demo_AxisConstraints() {
//-----------------------------------------------------------------------------
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];
for (int i = 0; i < 360; ++i) {
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)) {
ImPlot::SetupAxes(0,0,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations);
ImPlot::SetupAxesLimits(0, count - 1, min_v, max_v, ImGuiCond_Always);
ImPlot::PushStyleColor(ImPlotCol_Line, col);
ImPlot::PlotLine(id, values, count, 1, 0, 0, offset);
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
ImPlot::PlotShaded(id, values, count, 0, 1, 0, 0, offset);
ImPlot::PopStyleVar();
ImPlot::PopStyleColor();
ImPlot::SetNextLineStyle(col);
ImPlot::SetNextFillStyle(col, 0.25);
ImPlot::PlotLine(id, values, count, 1, 0, ImPlotLineFlags_Shaded, offset);
ImPlot::EndPlot();
}
ImPlot::PopStyleVar();

View File

@ -1159,6 +1159,72 @@ struct RendererStairsPost : RendererBase {
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>
struct RendererShaded : RendererBase {
RendererShaded(const _Getter1& getter1, const _Getter2& getter2, ImU32 col) :
@ -1462,26 +1528,33 @@ void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool
// [SECTION] PlotLine
//-----------------------------------------------------------------------------
template <typename Getter>
void PlotLineEx(const char* label_id, const Getter& getter, ImPlotLineFlags flags) {
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) {
template <typename _Getter>
void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags) {
if (BeginItemEx(label_id, Fitter1<_Getter>(getter), flags, ImPlotCol_Line)) {
const ImPlotNextItemData& s = GetItemData();
if (getter.Count > 1 && s.RenderLine) {
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
if (ImHasFlag(flags,ImPlotLineFlags_Segments)) {
RenderPrimitives1<RendererLineSegments1>(getter,col_line,s.LineWeight);
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);
}
else if (ImHasFlag(flags, ImPlotLineFlags_Loop)) {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
RenderPrimitives1<RendererLineStripSkip>(GetterLoop<Getter>(getter),col_line,s.LineWeight);
else
RenderPrimitives1<RendererLineStrip>(GetterLoop<Getter>(getter),col_line,s.LineWeight);
}
else {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
RenderPrimitives1<RendererLineStripSkip>(getter,col_line,s.LineWeight);
else
RenderPrimitives1<RendererLineStrip>(getter,col_line,s.LineWeight);
if (s.RenderLine) {
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
if (ImHasFlag(flags,ImPlotLineFlags_Segments)) {
RenderPrimitives1<RendererLineSegments1>(getter,col_line,s.LineWeight);
}
else if (ImHasFlag(flags, ImPlotLineFlags_Loop)) {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
RenderPrimitives1<RendererLineStripSkip>(GetterLoop<_Getter>(getter),col_line,s.LineWeight);
else
RenderPrimitives1<RendererLineStrip>(GetterLoop<_Getter>(getter),col_line,s.LineWeight);
}
else {
if (ImHasFlag(flags, ImPlotLineFlags_SkipNaN))
RenderPrimitives1<RendererLineStripSkip>(getter,col_line,s.LineWeight);
else
RenderPrimitives1<RendererLineStrip>(getter,col_line,s.LineWeight);
}
}
}
// render markers
@ -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_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();
}
@ -1518,7 +1591,7 @@ template IMPLOT_API void PlotLine<double>(const char* label_id, const double* va
template <typename T>
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);
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);
@ -1535,7 +1608,7 @@ template IMPLOT_API void PlotLine<double>(const char* label_id, const double* xs
// custom
void PlotLineG(const char* label_id, ImPlotGetter getter_func, void* data, int count, ImPlotLineFlags flags) {
GetterFuncPtr getter(getter_func,data, count);
return PlotLineEx(label_id, getter, flags);
PlotLineEx(label_id, getter, flags);
}
//-----------------------------------------------------------------------------
@ -1608,12 +1681,21 @@ template <typename Getter>
void PlotStairsEx(const char* label_id, const Getter& getter, ImPlotStairsFlags flags) {
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) {
const ImPlotNextItemData& s = GetItemData();
if (getter.Count > 1 && s.RenderLine) {
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
RenderPrimitives1<RendererStairsPre>(getter,col_line,s.LineWeight);
else
RenderPrimitives1<RendererStairsPost>(getter,col_line,s.LineWeight);
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]);
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
RenderPrimitives1<RendererStairsPre>(getter,col_line,s.LineWeight);
else
RenderPrimitives1<RendererStairsPost>(getter,col_line,s.LineWeight);
}
}
// render markers
if (s.Marker != ImPlotMarker_None) {
@ -1690,7 +1772,7 @@ void PlotShaded(const char* label_id, const T* values, int count, double y_ref,
if (!(y_ref < DBL_MAX))
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Max;
GetterXY<IndexerLin,IndexerIdx<T>> getter1(IndexerLin(xscale,x0),IndexerIdx<T>(values,count,offset,stride),count);
GetterXY<IndexerLin,IndexerConst> getter2(IndexerLin(xscale,x0),IndexerConst(y_ref),count);
GetterXY<IndexerLin,IndexerConst> getter2(IndexerLin(xscale,x0),IndexerConst(y_ref),count);
PlotShadedEx(label_id, getter1, getter2, flags);
}
@ -1712,7 +1794,7 @@ void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, doubl
if (y_ref == HUGE_VAL)
y_ref = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO).Y.Max;
GetterXY<IndexerIdx<T>,IndexerIdx<T>> getter1(IndexerIdx<T>(xs,count,offset,stride),IndexerIdx<T>(ys,count,offset,stride),count);
GetterXY<IndexerIdx<T>,IndexerConst> getter2(IndexerIdx<T>(xs,count,offset,stride),IndexerConst(y_ref),count);
GetterXY<IndexerIdx<T>,IndexerConst> getter2(IndexerIdx<T>(xs,count,offset,stride),IndexerConst(y_ref),count);
PlotShadedEx(label_id, getter1, getter2, flags);
}