mirror of
https://github.com/gwm17/implot.git
synced 2024-11-22 18:28:53 -05:00
add stairstep plots (#136)
This commit is contained in:
parent
587c8b6221
commit
42d93bcdbc
7
implot.h
7
implot.h
|
@ -394,6 +394,11 @@ template <typename T> IMPLOT_API void PlotScatter(const char* label_id, const T
|
|||
template <typename T> IMPLOT_API void PlotScatter(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
|
||||
IMPLOT_API void PlotScatterG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
|
||||
|
||||
// Plots a a stairstep graph. The y value is continued constantly from every x position, i.e. the interval [x[i], x[i+1]) has the value y[i].
|
||||
template <typename T> IMPLOT_API void PlotStairs(const char* label_id, const T* values, int count, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
|
||||
template <typename T> IMPLOT_API void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
|
||||
IMPLOT_API void PlotStairsG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
|
||||
|
||||
// Plots a shaded (filled) region between two lines, or a line and a horizontal reference.
|
||||
template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T* values, int count, double y_ref=0, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
|
||||
template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, double y_ref=0, int offset=0, int stride=sizeof(T));
|
||||
|
@ -532,7 +537,7 @@ IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label
|
|||
|
||||
// Set the location of the current plot's legend.
|
||||
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
|
||||
// Set the locaton of the current plot's mouse position text (default = South|East).
|
||||
// Set the location of the current plot's mouse position text (default = South|East).
|
||||
IMPLOT_API void SetMousePosLocation(ImPlotLocation location);
|
||||
// Returns true if a plot item legend entry is hovered.
|
||||
IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
|
||||
|
|
|
@ -326,6 +326,20 @@ void ShowDemoWindow(bool* p_open) {
|
|||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
if (ImGui::CollapsingHeader("Stairstep Plots")) {
|
||||
static float ys1[101], ys2[101];
|
||||
for (int i = 0; i < 101; ++i) {
|
||||
ys1[i] = 0.5f + 0.4f * sinf(50 * i * 0.01f);
|
||||
ys2[i] = 0.5f + 0.2f * sinf(25 * i * 0.01f);
|
||||
}
|
||||
if (ImPlot::BeginPlot("Stairstep Plot", "x", "f(x)")) {
|
||||
ImPlot::PlotStairs("Signal 1", ys1, 101, 0.01f);
|
||||
ImPlot::SetNextMarkerStyle(ImPlotMarker_Square, 2.0f);
|
||||
ImPlot::PlotStairs("Signal 2", ys2, 101, 0.01f);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
if (ImGui::CollapsingHeader("Bar Plots")) {
|
||||
|
||||
static bool horz = false;
|
||||
|
|
160
implot_items.cpp
160
implot_items.cpp
|
@ -455,6 +455,32 @@ inline void AddLine(const ImVec2& P1, const ImVec2& P2, float weight, ImU32 col,
|
|||
DrawList._VtxCurrentIdx += 4;
|
||||
}
|
||||
|
||||
inline void AddRectFilled(const ImVec2& Pmin, const ImVec2& Pmax, ImU32 col, ImDrawList& DrawList, ImVec2 uv) {
|
||||
DrawList._VtxWritePtr[0].pos = Pmin;
|
||||
DrawList._VtxWritePtr[0].uv = uv;
|
||||
DrawList._VtxWritePtr[0].col = col;
|
||||
DrawList._VtxWritePtr[1].pos = Pmax;
|
||||
DrawList._VtxWritePtr[1].uv = uv;
|
||||
DrawList._VtxWritePtr[1].col = col;
|
||||
DrawList._VtxWritePtr[2].pos.x = Pmin.x;
|
||||
DrawList._VtxWritePtr[2].pos.y = Pmax.y;
|
||||
DrawList._VtxWritePtr[2].uv = uv;
|
||||
DrawList._VtxWritePtr[2].col = col;
|
||||
DrawList._VtxWritePtr[3].pos.x = Pmax.x;
|
||||
DrawList._VtxWritePtr[3].pos.y = Pmin.y;
|
||||
DrawList._VtxWritePtr[3].uv = uv;
|
||||
DrawList._VtxWritePtr[3].col = col;
|
||||
DrawList._VtxWritePtr += 4;
|
||||
DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
|
||||
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
|
||||
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 2);
|
||||
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
|
||||
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
|
||||
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3);
|
||||
DrawList._IdxWritePtr += 6;
|
||||
DrawList._VtxCurrentIdx += 4;
|
||||
}
|
||||
|
||||
template <typename TGetter, typename TTransformer>
|
||||
struct LineStripRenderer {
|
||||
inline LineStripRenderer(const TGetter& getter, const TTransformer& transformer, ImU32 col, float weight) :
|
||||
|
@ -486,6 +512,41 @@ struct LineStripRenderer {
|
|||
static const int VtxConsumed = 4;
|
||||
};
|
||||
|
||||
template <typename TGetter, typename TTransformer>
|
||||
struct StairsRenderer {
|
||||
inline StairsRenderer(const TGetter& getter, const TTransformer& transformer, ImU32 col, float weight) :
|
||||
Getter(getter),
|
||||
Transformer(transformer),
|
||||
Prims(Getter.Count - 1),
|
||||
Col(col),
|
||||
HalfWeight(weight * 0.5f)
|
||||
{
|
||||
P1 = Transformer(Getter(0));
|
||||
}
|
||||
inline bool operator()(ImDrawList& DrawList, const ImRect& cull_rect, const ImVec2& uv, int prim) const {
|
||||
ImVec2 P2 = Transformer(Getter(prim + 1));
|
||||
if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) {
|
||||
P1 = P2;
|
||||
return false;
|
||||
}
|
||||
AddRectFilled(ImVec2(P1.x, P1.y + HalfWeight), ImVec2(P2.x, P1.y - HalfWeight), Col, DrawList, uv);
|
||||
AddRectFilled(ImVec2(P2.x - HalfWeight, P2.y), ImVec2(P2.x + HalfWeight, P1.y), Col, DrawList, uv);
|
||||
|
||||
// AddLine(P1, P12, Weight, Col, DrawList, uv);
|
||||
// AddLine(P12, P2, Weight, Col, DrawList, uv);
|
||||
P1 = P2;
|
||||
return true;
|
||||
}
|
||||
const TGetter& Getter;
|
||||
const TTransformer& Transformer;
|
||||
const int Prims;
|
||||
const ImU32 Col;
|
||||
const float HalfWeight;
|
||||
mutable ImVec2 P1;
|
||||
static const int IdxConsumed = 12;
|
||||
static const int VtxConsumed = 8;
|
||||
};
|
||||
|
||||
template <typename TGetter1, typename TGetter2, typename TTransformer>
|
||||
struct LineSegmentsRenderer {
|
||||
inline LineSegmentsRenderer(const TGetter1& getter1, const TGetter2& getter2, const TTransformer& transformer, ImU32 col, float weight) :
|
||||
|
@ -695,6 +756,26 @@ inline void RenderLineSegments(const Getter1& getter1, const Getter2& getter2, c
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Getter, typename Transformer>
|
||||
inline void RenderStairs(const Getter& getter, const Transformer& transformer, ImDrawList& DrawList, float line_weight, ImU32 col) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
if (ImHasFlag(gp.CurrentPlot->Flags, ImPlotFlags_AntiAliased) || gp.Style.AntiAliasedLines) {
|
||||
ImVec2 p1 = transformer(getter(0));
|
||||
for (int i = 1; i < getter.Count; ++i) {
|
||||
ImVec2 p2 = transformer(getter(i));
|
||||
if (gp.BB_Plot.Overlaps(ImRect(ImMin(p1, p2), ImMax(p1, p2)))) {
|
||||
ImVec2 p12(p2.x, p1.y);
|
||||
DrawList.AddLine(p1, p12, col, line_weight);
|
||||
DrawList.AddLine(p12, p2, col, line_weight);
|
||||
}
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RenderPrimitives(StairsRenderer<Getter,Transformer>(getter, transformer, col, line_weight), DrawList, gp.BB_Plot);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MARKER RENDERERS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -954,6 +1035,85 @@ void PlotScatterG(const char* label_id, ImPlotPoint (*getter_func)(void* data, i
|
|||
return PlotScatterEx(label_id, getter);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PLOT STAIRS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename Getter>
|
||||
inline void PlotStairsEx(const char* label_id, const Getter& getter) {
|
||||
if (BeginItem(label_id, ImPlotCol_Line)) {
|
||||
if (FitThisFrame()) {
|
||||
for (int i = 0; i < getter.Count; ++i) {
|
||||
ImPlotPoint p = getter(i);
|
||||
FitPoint(p);
|
||||
}
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImDrawList& DrawList = *GetPlotDrawList();
|
||||
if (getter.Count > 1 && s.RenderLine) {
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
switch (GetCurrentScale()) {
|
||||
case ImPlotScale_LinLin: RenderStairs(getter, TransformerLinLin(), DrawList, s.LineWeight, col_line); break;
|
||||
case ImPlotScale_LogLin: RenderStairs(getter, TransformerLogLin(), DrawList, s.LineWeight, col_line); break;
|
||||
case ImPlotScale_LinLog: RenderStairs(getter, TransformerLinLog(), DrawList, s.LineWeight, col_line); break;
|
||||
case ImPlotScale_LogLog: RenderStairs(getter, TransformerLogLog(), DrawList, s.LineWeight, col_line); break;
|
||||
}
|
||||
}
|
||||
// render markers
|
||||
if (s.Marker != ImPlotMarker_None) {
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerOutline]);
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerFill]);
|
||||
switch (GetCurrentScale()) {
|
||||
case ImPlotScale_LinLin: RenderMarkers(getter, TransformerLinLin(), DrawList, s.Marker, s.MarkerSize, s.RenderMarkerLine, col_line, s.MarkerWeight, s.RenderMarkerFill, col_fill); break;
|
||||
case ImPlotScale_LogLin: RenderMarkers(getter, TransformerLogLin(), DrawList, s.Marker, s.MarkerSize, s.RenderMarkerLine, col_line, s.MarkerWeight, s.RenderMarkerFill, col_fill); break;
|
||||
case ImPlotScale_LinLog: RenderMarkers(getter, TransformerLinLog(), DrawList, s.Marker, s.MarkerSize, s.RenderMarkerLine, col_line, s.MarkerWeight, s.RenderMarkerFill, col_fill); break;
|
||||
case ImPlotScale_LogLog: RenderMarkers(getter, TransformerLogLog(), DrawList, s.Marker, s.MarkerSize, s.RenderMarkerLine, col_line, s.MarkerWeight, s.RenderMarkerFill, col_fill); break;
|
||||
}
|
||||
}
|
||||
EndItem();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PlotStairs(const char* label_id, const T* values, int count, double xscale, double x0, int offset, int stride) {
|
||||
GetterYs<T> getter(values,count,xscale,x0,offset,stride);
|
||||
PlotStairsEx(label_id, getter);
|
||||
}
|
||||
|
||||
template IMPLOT_API void PlotStairs<ImS8> (const char* label_id, const ImS8* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU8> (const char* label_id, const ImU8* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS16>(const char* label_id, const ImS16* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU16>(const char* label_id, const ImU16* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS32>(const char* label_id, const ImS32* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU32>(const char* label_id, const ImU32* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS64>(const char* label_id, const ImS64* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU64>(const char* label_id, const ImU64* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<float>(const char* label_id, const float* values, int count, double xscale, double x0, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<double>(const char* label_id, const double* values, int count, double xscale, double x0, int offset, int stride);
|
||||
|
||||
template <typename T>
|
||||
void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, int offset, int stride) {
|
||||
GetterXsYs<T> getter(xs,ys,count,offset,stride);
|
||||
return PlotStairsEx(label_id, getter);
|
||||
}
|
||||
|
||||
template IMPLOT_API void PlotStairs<ImS8>(const char* label_id, const ImS8* xs, const ImS8* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU8>(const char* label_id, const ImU8* xs, const ImU8* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS16>(const char* label_id, const ImS16* xs, const ImS16* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU16>(const char* label_id, const ImU16* xs, const ImU16* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS32>(const char* label_id, const ImS32* xs, const ImS32* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU32>(const char* label_id, const ImU32* xs, const ImU32* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImS64>(const char* label_id, const ImS64* xs, const ImS64* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<ImU64>(const char* label_id, const ImU64* xs, const ImU64* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<float>(const char* label_id, const float* xs, const float* ys, int count, int offset, int stride);
|
||||
template IMPLOT_API void PlotStairs<double>(const char* label_id, const double* xs, const double* ys, int count, int offset, int stride);
|
||||
|
||||
// custom
|
||||
void PlotStairsG(const char* label_id, ImPlotPoint (*getter_func)(void* data, int idx), void* data, int count, int offset) {
|
||||
GetterFuncPtr getter(getter_func,data, count, offset);
|
||||
return PlotStairsEx(label_id, getter);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PLOT SHADED
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue
Block a user