From bce306bd65a36e213a1471adc247b694b9d28c58 Mon Sep 17 00:00:00 2001 From: ozlb Date: Wed, 29 Apr 2020 16:32:35 +0200 Subject: [PATCH] PlotDigital --- implot.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++------ implot.h | 17 ++++++---- 2 files changed, 99 insertions(+), 16 deletions(-) diff --git a/implot.cpp b/implot.cpp index ffa5208..31092b8 100644 --- a/implot.cpp +++ b/implot.cpp @@ -49,6 +49,7 @@ ImPlotStyle::ImPlotStyle() { MarkerWeight = 1; ErrorBarSize = 5; ErrorBarWeight = 1.5; + DigitalBitHeight = 7; Colors[ImPlotCol_Line] = IM_COL_AUTO; Colors[ImPlotCol_Fill] = IM_COL_AUTO; @@ -397,9 +398,9 @@ struct ImPlotContext { ImPlotStyle Style; ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() - ImNextPlotData NextPlotData; - - + ImNextPlotData NextPlotData; + // Digital plot item count + int DigitalPlotItemCnt; }; /// Global plot context @@ -907,6 +908,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons gp.Extents.Max.y = -INFINITY; // clear item names gp._LegendLabels.Buf.resize(0); + // reset digital plot items count + gp.DigitalPlotItemCnt = 0; return true; } @@ -1296,12 +1299,13 @@ struct ImPlotStyleVarInfo { static const ImPlotStyleVarInfo GPlotStyleVarInfo[] = { - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight - { ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarWeight) } // ImPlotStyleVar_ErrorBarWeight + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight + { ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight + { ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) } // ImPlotStyleVar_DigitalBitHeight }; static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) @@ -1690,6 +1694,80 @@ void Plot(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* dat ImGui::PopClipRect(); } +//////////////////////////////////////////////////////////////// + +void PlotDigital(const char* label_id, const float* xs, const float* ys, int count, int offset, int stride) { + ImPlotGetterData data(xs,ys,stride); + PlotDigital(label_id, &ImPlotGetter2D, (void*)&data, count, offset); +} + +void PlotDigital(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* data, int count, int offset) +{ + IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotDigital() Needs to be called between BeginPlot() and EndPlot()!"); + + ImPlotItem* item = gp.RegisterItem(label_id); + if (!item->Show) + return; + + ImDrawList & DrawList = *ImGui::GetWindowDrawList(); + + const bool rend_line = gp.Style.Colors[ImPlotCol_Line].w != 0 && gp.Style.LineWeight > 0; + + ImU32 col_line = gp.Style.Colors[ImPlotCol_Line].w == -1 ? GetColorU32(item->Color) : GetColorU32(gp.Style.Colors[ImPlotCol_Line]); + + if (gp.Style.Colors[ImPlotCol_Line].w != -1) + item->Color = gp.Style.Colors[ImPlotCol_Line]; + + // find data extents + if (gp.FitThisFrame) { + for (int i = 0; i < count; ++i) { + ImVec2 p = getter(data, i); + gp.FitPoint(p); + } + } + + ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true); + bool cull = HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_CullData); + + const float line_weight = item->Highlight ? gp.Style.LineWeight * 2 : gp.Style.LineWeight; + + // render digital signals as "pixel bases" rectangles + if (count > 1 && rend_line) { + const int segments = count - 1; + int i1 = offset; + for (int s = 0; s < segments; ++s) { + const int i2 = (i1 + 1) % count; + ImVec2 itemData1 = getter(data, i1); + ImVec2 itemData2 = getter(data, i2); + i1 = i2; + const float mx = (gp.PixelRange.Max.x - gp.PixelRange.Min.x) / (gp.CurrentPlot->XAxis.Max - gp.CurrentPlot->XAxis.Min); + int pixY_0 = line_weight; + int pixY_1 = gp.Style.DigitalBitHeight; + int pixY_Offset = 20;//20 pixel from bottom due to mouse cursor label + int pixY_chOffset = pixY_1 + 3; //3 pixels between channels + + float y1 = (gp.PixelRange.Min.y) + ((-pixY_chOffset * gp.DigitalPlotItemCnt) - ((itemData1.y == 0.0) ? pixY_0 : pixY_1) - pixY_Offset); + float y2 = (gp.PixelRange.Min.y) + ((-pixY_chOffset * gp.DigitalPlotItemCnt) - pixY_Offset); + float l = gp.PixelRange.Min.x + mx * (itemData2.x - gp.CurrentPlot->XAxis.Min); + float r = gp.PixelRange.Min.x + mx * (itemData1.x - gp.CurrentPlot->XAxis.Min); + + ImVec2 cl, cr; + cl.x = l; + cl.y = y1; + cr.x = r; + cr.y = y2; + if (!cull || gp.BB_Grid.Contains(cl) || gp.BB_Grid.Contains(cr)) { + DrawList.AddRectFilled({l, y1}, {r, y2}, col_line); + } + } + gp.DigitalPlotItemCnt++; + } + + ImGui::PopClipRect(); +} + +//////////////////////////////////////////////////////////////// + static ImVec2 ImPlotGetterBarV(void* data, int idx) { ImPlotGetterData* data_1d = (ImPlotGetterData*)data; return ImVec2((float)idx + data_1d->XShift, ImStrideIndex(data_1d->Ys, idx, data_1d->Stride)); @@ -1898,4 +1976,4 @@ void PlotLabel(const char* text, float x, float y, bool vertical, const ImVec2& PopClipRect(); } -} // namespace ImGui \ No newline at end of file +} // namespace ImGui diff --git a/implot.h b/implot.h index ec8bcb3..58cf48d 100644 --- a/implot.h +++ b/implot.h @@ -81,12 +81,13 @@ enum ImPlotCol_ { }; enum ImPlotStyleVar_ { - ImPlotStyleVar_LineWeight, // float, line weight in pixels - ImPlotStyleVar_Marker, // int, marker specification - ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius") - ImPlotStyleVar_MarkerWeight, // float, outline weight of markers in pixels - ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels - ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels + ImPlotStyleVar_LineWeight, // float, line weight in pixels + ImPlotStyleVar_Marker, // int, marker specification + ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius") + ImPlotStyleVar_MarkerWeight, // float, outline weight of markers in pixels + ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels + ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels + ImPlotStyleVar_DigitalBitHeight, // int, digital channels bit height (at 1) ImPlotStyleVar_COUNT }; @@ -120,6 +121,7 @@ struct ImPlotStyle { float MarkerWeight; // = 1, outline weight of markers in pixels float ErrorBarSize; // = 5, error bar whisker width in pixels float ErrorBarWeight; // = 1.5, error bar whisker weight in pixels + int DigitalBitHeight; // = 7, digital channels bit height (at 1) ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors ImPlotStyle(); }; @@ -177,6 +179,9 @@ ImPlotRange GetPlotQuery(); void Plot(const char* label_id, const float* values, int count, int offset = 0, int stride = sizeof(float)); void Plot(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float)); void Plot(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* data, int count, int offset = 0); +// Plots digital channels. +void PlotDigital(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float) + sizeof(bool)); +void PlotDigital(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* data, int count, int offset = 0); // Plots vertical bars. void PlotBar(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float)); void PlotBar(const char* label_id, const float* xs, const float* ys, int count, float width, int offset = 0, int stride = sizeof(float));