1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-10-09 23:57:26 -04:00

add overloads for PlotShaded, ImPlotStyleVar_PlotPadding, and ImGui Tables API demo section

This commit is contained in:
epezent 2020-08-20 23:01:21 -05:00
parent a41d413790
commit 9deca4e422
5 changed files with 124 additions and 20 deletions

View File

@ -88,6 +88,7 @@ ImPlotStyle::ImPlotStyle() {
ErrorBarWeight = 1.5f; ErrorBarWeight = 1.5f;
DigitalBitHeight = 8; DigitalBitHeight = 8;
DigitalBitGap = 4; DigitalBitGap = 4;
PlotPadding = ImVec2(8,8);
Colors[ImPlotCol_Line] = IMPLOT_COL_AUTO; Colors[ImPlotCol_Line] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Fill] = IMPLOT_COL_AUTO; Colors[ImPlotCol_Fill] = IMPLOT_COL_AUTO;
@ -660,7 +661,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
ImGui::RenderFrame(gp.BB_Frame.Min, gp.BB_Frame.Max, gp.Col_Frame, true, Style.FrameRounding); ImGui::RenderFrame(gp.BB_Frame.Min, gp.BB_Frame.Max, gp.Col_Frame, true, Style.FrameRounding);
// canvas bb // canvas bb
gp.BB_Canvas = ImRect(gp.BB_Frame.Min + Style.WindowPadding, gp.BB_Frame.Max - Style.WindowPadding); gp.BB_Canvas = ImRect(gp.BB_Frame.Min + gp.Style.PlotPadding, gp.BB_Frame.Max - gp.Style.PlotPadding);
// adaptive divisions // adaptive divisions
int x_divisions = ImMax(2, (int)IM_ROUND(0.003 * gp.BB_Canvas.GetWidth())); int x_divisions = ImMax(2, (int)IM_ROUND(0.003 * gp.BB_Canvas.GetWidth()));
@ -1719,15 +1720,16 @@ struct ImPlotStyleVarInfo {
static const ImPlotStyleVarInfo GPlotStyleVarInfo[] = static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
{ {
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
{ ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker { 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, MarkerSize) }, // ImPlotStyleVar_MarkerSize
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize { 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, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) } // ImPlotStyleVar_DigitalBitGap { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
}; };
static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx)
@ -1801,6 +1803,20 @@ void PushStyleVar(ImPlotStyleVar idx, int val) {
IM_ASSERT(0 && "Called PushStyleVar() int variant but variable is not a int!"); IM_ASSERT(0 && "Called PushStyleVar() int variant but variable is not a int!");
} }
void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
{
ImPlotContext& gp = *GImPlot;
const ImPlotStyleVarInfo* var_info = GetPlotStyleVarInfo(idx);
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
{
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&gp.Style);
gp.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
*pvar = val;
return;
}
IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!");
}
void PopStyleVar(int count) { void PopStyleVar(int count) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
while (count > 0) { while (count > 0) {
@ -1883,16 +1899,16 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
const float bar_w = 20; const float bar_w = 20;
ImDrawList &DrawList = *Window->DrawList; ImDrawList &DrawList = *Window->DrawList;
ImVec2 size(bar_w + txt_off + max_width + 2 * Style.WindowPadding.x, height); ImVec2 size(bar_w + txt_off + max_width + 2 * gp.Style.PlotPadding.x, height);
ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + size); ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + size);
ImGui::ItemSize(bb_frame); ImGui::ItemSize(bb_frame);
if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame)) if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame))
return; return;
ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, ImGui::GetColorU32(ImGuiCol_FrameBg)); ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, ImGui::GetColorU32(ImGuiCol_FrameBg));
ImRect bb_grad(bb_frame.Min + Style.WindowPadding, bb_frame.Min + ImVec2(bar_w + Style.WindowPadding.x, height - Style.WindowPadding.y)); ImRect bb_grad(bb_frame.Min + gp.Style.PlotPadding, bb_frame.Min + ImVec2(bar_w + gp.Style.PlotPadding.x, height - gp.Style.PlotPadding.y));
int num_cols = GetColormapSize(); int num_cols = GetColormapSize();
float h_step = (height - 2 * Style.WindowPadding.y) / (num_cols - 1); float h_step = (height - 2 * gp.Style.PlotPadding.y) / (num_cols - 1);
for (int i = 0; i < num_cols-1; ++i) { for (int i = 0; i < num_cols-1; ++i) {
ImRect rect(bb_grad.Min.x, bb_grad.Min.y + h_step * i, bb_grad.Max.x, bb_grad.Min.y + h_step * (i + 1)); ImRect rect(bb_grad.Min.x, bb_grad.Min.y + h_step * i, bb_grad.Max.x, bb_grad.Min.y + h_step * (i + 1));
ImU32 col1 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - i)); ImU32 col1 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - i));

View File

@ -102,6 +102,7 @@ enum ImPlotStyleVar_ {
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area and/or labels
ImPlotStyleVar_COUNT ImPlotStyleVar_COUNT
}; };
@ -174,6 +175,7 @@ struct ImPlotStyle {
float ErrorBarWeight; // = 1.5, error bar whisker weight in pixels float ErrorBarWeight; // = 1.5, error bar whisker weight in pixels
float DigitalBitHeight; // = 8, digital channels bit height (at y = 1.0f) in pixels float DigitalBitHeight; // = 8, digital channels bit height (at y = 1.0f) in pixels
float DigitalBitGap; // = 4, digital channels bit padding gap in pixels float DigitalBitGap; // = 4, digital channels bit padding gap in pixels
ImVec2 PlotPadding; // = (8,8), padding between widget frame and plot area and/or labels
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
ImPlotStyle(); ImPlotStyle();
}; };
@ -259,10 +261,12 @@ void PlotScatter(const char* label_id, const ImPlotPoint* data, int count, int o
void PlotScatter(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset = 0); void PlotScatter(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. // Plots a shaded (filled) region between two lines, or a line and a horizontal reference.
void PlotShaded(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset = 0, int stride = sizeof(float)); void PlotShaded(const char* label_id, const float* values, int count, float y_ref = 0, int offset = 0, int stride = sizeof(float));
void PlotShaded(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset = 0, int stride = sizeof(double)); void PlotShaded(const char* label_id, const double* values, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double));
void PlotShaded(const char* label_id, const float* xs, const float* ys, int count, float y_ref = 0, int offset = 0, int stride = sizeof(float)); void PlotShaded(const char* label_id, const float* xs, const float* ys, int count, float y_ref = 0, int offset = 0, int stride = sizeof(float));
void PlotShaded(const char* label_id, const double* xs, const double* ys, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double)); void PlotShaded(const char* label_id, const double* xs, const double* ys, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double));
void PlotShaded(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset = 0, int stride = sizeof(float));
void PlotShaded(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset = 0, int stride = sizeof(double));
// Plots a vertical bar graph. #width and #shift are in X units. // Plots a vertical bar graph. #width and #shift are in X units.
void PlotBars(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float)); void PlotBars(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float));
@ -356,6 +360,8 @@ void PopStyleColor(int count = 1);
void PushStyleVar(ImPlotStyleVar idx, float val); void PushStyleVar(ImPlotStyleVar idx, float val);
// Temporarily modify a style variable of int type. Don't forget to call PopStyleVar! // Temporarily modify a style variable of int type. Don't forget to call PopStyleVar!
void PushStyleVar(ImPlotStyleVar idx, int val); void PushStyleVar(ImPlotStyleVar idx, int val);
// Temporarily modify a style variable of ImVec2 type. Don't forget to call PopStyleVar!
void PushStyleVar(ImPlotStyleVar idx, const ImVec2& val);
// Undo temporary style modification. // Undo temporary style modification.
void PopStyleVar(int count = 1); void PopStyleVar(int count = 1);

View File

@ -33,9 +33,12 @@
namespace MyImPlot { namespace MyImPlot {
// Example for Custom Plotters and Tooltips section. Plots a candlestick chart for financial data. See implementatoin at bottom. // Example for Custom Plotters and Tooltips section. Plots a candlestick chart for financial data. See implementation at bottom.
void PlotCandlestick(const char* label_id, const double* xs, const double* opens, const double* closes, const double* lows, const double* highs, int count, bool tooltip = true, float width_percent = 0.25f, ImVec4 bullCol = ImVec4(0,1,0,1), ImVec4 bearCol = ImVec4(1,0,0,1)); void PlotCandlestick(const char* label_id, const double* xs, const double* opens, const double* closes, const double* lows, const double* highs, int count, bool tooltip = true, float width_percent = 0.25f, ImVec4 bullCol = ImVec4(0,1,0,1), ImVec4 bearCol = ImVec4(1,0,0,1));
// Example for Tables section. Generates a quick and simple shaded line plot. See implementation at bottom.
void Sparkline(const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col, const ImVec2& size);
} }
namespace ImPlot { namespace ImPlot {
@ -404,7 +407,7 @@ void ShowDemoWindow(bool* p_open) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::LabelText("##Colormap Index", "%s", cmap_names[map]); ImGui::LabelText("##Colormap Index", "%s", cmap_names[map]);
ImGui::SetNextItemWidth(225); ImGui::SetNextItemWidth(225);
ImGui::DragFloat("Max",&scale_max,0.01f,0.1f,20); ImGui::DragFloatRange2("Min / Max",&scale_min, &scale_max, 0.01f, -20, 20);
static ImPlotAxisFlags axes_flags = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax | ImPlotAxisFlags_TickLabels; static ImPlotAxisFlags axes_flags = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax | ImPlotAxisFlags_TickLabels;
static const char* xlabels[] = {"C1","C2","C3","C4","C5","C6","C7"}; static const char* xlabels[] = {"C1","C2","C3","C4","C5","C6","C7"};
static const char* ylabels[] = {"R1","R2","R3","R4","R5","R6","R7"}; static const char* ylabels[] = {"R1","R2","R3","R4","R5","R6","R7"};
@ -915,6 +918,45 @@ void ShowDemoWindow(bool* p_open) {
ImGui::EndDragDropTarget(); ImGui::EndDragDropTarget();
} }
} }
if (ImGui::CollapsingHeader("Tables")) {
#ifdef IMGUI_HAS_TABLE
static ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_RowBg;
static bool anim = true;
static int offset = 0;
ImGui::BulletText("Plots can be used inside of ImGui tables.");
ImGui::Checkbox("Animate",&anim);
if (anim)
offset = (offset + 1) % 100;
if (ImGui::BeginTable("##table", 3, flags, ImVec2(-1,0))) {
ImGui::TableSetupColumn("Electrode", ImGuiTableColumnFlags_WidthFixed, 75.0f);
ImGui::TableSetupColumn("Voltage", ImGuiTableColumnFlags_WidthFixed, 75.0f);
ImGui::TableSetupColumn("EMG Signal");
ImGui::TableAutoHeaders();
ImPlot::SetColormap(ImPlotColormap_Cool, 10);
for (int row = 0; row < 10; row++)
{
ImGui::TableNextRow();
static float data[100];
srand(row);
for (int i = 0; i < 100; ++i)
data[i] = RandomRange(0,10);
ImGui::TableSetColumnIndex(0);
ImGui::Text("EMG %d", row);
ImGui::TableSetColumnIndex(1);
ImGui::Text("%.3f V", data[offset]);
ImGui::TableSetColumnIndex(2);
ImGui::PushID(row);
MyImPlot::Sparkline("##spark",data,100,0,11.0f,offset,ImPlot::GetColormapColor(row),ImVec2(-1, 35));
ImGui::PopID();
}
ImPlot::SetColormap(ImPlotColormap_Default);
ImGui::EndTable();
}
#else
ImGui::BulletText("You need to merge the ImGui 'tables' branch for this section.");
#endif
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Offset and Stride")) { if (ImGui::CollapsingHeader("Offset and Stride")) {
static const int k_circles = 11; static const int k_circles = 11;
@ -1142,4 +1184,20 @@ void PlotCandlestick(const char* label_id, const double* xs, const double* opens
} }
} }
// Example for Tables section. Generates a quick and simple shaded line plot. See implementation at bottom.
void Sparkline(const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col, const ImVec2& size) {
ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, ImVec2(0,0));
ImPlot::SetNextPlotLimits(0, count - 1, min_v, max_v, ImGuiCond_Always);
if (ImPlot::BeginPlot(id,0,0,size,ImPlotFlags_NoChild,0,0,0,0)) {
ImPlot::PushStyleColor(ImPlotCol_Line, col);
ImPlot::PlotLine(id, values, count, offset);
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
ImPlot::PlotShaded(id, values, count, 0, offset);
ImPlot::PopStyleVar();
ImPlot::PopStyleColor();
ImPlot::EndPlot();
}
ImPlot::PopStyleVar();
}
} }

View File

@ -63,7 +63,8 @@ extern ImPlotContext* GImPlot; // Current implicit context pointer
// [SECTION] Macros and Constants // [SECTION] Macros and Constants
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Constants can be changed unless stated otherwise // Constants can be changed unless stated otherwise. We may move some of these
// to ImPlotStyleVar_ over time.
// Default plot frame width when requested width is auto (i.e. 0). This is not the plot area width! // Default plot frame width when requested width is auto (i.e. 0). This is not the plot area width!
#define IMPLOT_DEFAULT_W 400 #define IMPLOT_DEFAULT_W 400

View File

@ -88,7 +88,18 @@ struct GetterXsYs {
} }
}; };
/// Interprets an array of X points as ImPlotPoints where the Y value is a constant reference value // Always returns a constant Y reference value where the X value is the index
template <typename T>
struct GetterYRef {
GetterYRef(T y_ref, int count) { YRef = y_ref; Count = count; }
inline ImPlotPoint operator()(int idx) {
return ImPlotPoint((T)idx, YRef);
}
T YRef;
int Count;
};
// Interprets an array of X points as ImPlotPoints where the Y value is a constant reference value
template <typename T> template <typename T>
struct GetterXsYRef { struct GetterXsYRef {
GetterXsYRef(const T* xs, T y_ref, int count, int offset, int stride) { GetterXsYRef(const T* xs, T y_ref, int count, int offset, int stride) {
@ -799,6 +810,12 @@ inline void PlotShadedEx(const char* label_id, Getter1 getter1, Getter2 getter2)
} }
// float // float
void PlotShaded(const char* label_id, const float* values, int count, float y_ref, int offset, int stride) {
GetterYs<float> getter1(values,count,offset,stride);
GetterYRef<float> getter2(y_ref, count);
PlotShadedEx(label_id, getter1, getter2);}
void PlotShaded(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset, int stride) { void PlotShaded(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset, int stride) {
GetterXsYs<float> getter1(xs, ys1, count, offset, stride); GetterXsYs<float> getter1(xs, ys1, count, offset, stride);
GetterXsYs<float> getter2(xs, ys2, count, offset, stride); GetterXsYs<float> getter2(xs, ys2, count, offset, stride);
@ -812,6 +829,12 @@ void PlotShaded(const char* label_id, const float* xs, const float* ys, int coun
} }
// double // double
void PlotShaded(const char* label_id, const double* values, int count, double y_ref, int offset, int stride) {
GetterYs<double> getter1(values,count,offset,stride);
GetterYRef<double> getter2(y_ref, count);
PlotShadedEx(label_id, getter1, getter2);
}
void PlotShaded(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset, int stride) { void PlotShaded(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset, int stride) {
GetterXsYs<double> getter1(xs, ys1, count, offset, stride); GetterXsYs<double> getter1(xs, ys1, count, offset, stride);
GetterXsYs<double> getter2(xs, ys2, count, offset, stride); GetterXsYs<double> getter2(xs, ys2, count, offset, stride);