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

overhaul styling

This commit is contained in:
epezent 2020-08-23 23:45:42 -05:00
parent db16011e73
commit 1884d3d7d5
5 changed files with 879 additions and 464 deletions

View File

@ -77,35 +77,6 @@ ImPlotRange::ImPlotRange() {
Max = NAN; Max = NAN;
} }
ImPlotStyle::ImPlotStyle() {
LineWeight = 1;
Marker = ImPlotMarker_None;
MarkerSize = 4;
MarkerWeight = 1;
FillAlpha = 1;
ErrorBarSize = 5;
ErrorBarWeight = 1.5f;
DigitalBitHeight = 8;
DigitalBitGap = 4;
PlotPadding = ImVec2(8,8);
Colors[ImPlotCol_Line] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Fill] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_MarkerOutline] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_MarkerFill] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_ErrorBar] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_FrameBg] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_PlotBg] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_PlotBorder] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_XAxis] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis2] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis3] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Selection] = ImVec4(1,1,0,1);
Colors[ImPlotCol_Query] = ImVec4(0,1,0,1);
}
ImPlotInputMap::ImPlotInputMap() { ImPlotInputMap::ImPlotInputMap() {
PanButton = ImGuiMouseButton_Left; PanButton = ImGuiMouseButton_Left;
PanMod = ImGuiKeyModFlags_None; PanMod = ImGuiKeyModFlags_None;
@ -121,8 +92,162 @@ ImPlotInputMap::ImPlotInputMap() {
VerticalMod = ImGuiKeyModFlags_Shift; VerticalMod = ImGuiKeyModFlags_Shift;
} }
ImPlotStyle::ImPlotStyle() {
LineWeight = 1;
Marker = ImPlotMarker_None;
MarkerSize = 4;
MarkerWeight = 1;
FillAlpha = 1;
ErrorBarSize = 5;
ErrorBarWeight = 1.5f;
DigitalBitHeight = 8;
DigitalBitGap = 4;
PlotBorderSize = 1;
MinorAlpha = 0.25f;
MajorTickLen = ImVec2(10,10);
MinorTickLen = ImVec2(5,5);
MajorTickSize = ImVec2(1,1);
MinorTickSize = ImVec2(1,1);
MajorGridSize = ImVec2(1,1);
MinorGridSize = ImVec2(1,1);
PlotPadding = ImVec2(8,8);
LabelPadding = ImVec2(5,5);
LegendPadding = ImVec2(10,10);
InfoPadding = ImVec2(10,10);
PlotMinSize = ImVec2(300,225);
Colors[ImPlotCol_Line] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Fill] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_MarkerOutline] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_MarkerFill] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_ErrorBar] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_FrameBg] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_PlotBg] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_PlotBorder] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_LegendBg] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_LegendBorder] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_LegendText] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_TitleText] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_InlayText] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_PlotBorder] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_XAxis] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_XAxisGrid] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxisGrid] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis2] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxisGrid2] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxis3] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_YAxisGrid3] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Selection] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Query] = IMPLOT_COL_AUTO;
Colors[ImPlotCol_Crosshairs] = IMPLOT_COL_AUTO;
}
namespace ImPlot { namespace ImPlot {
const char* GetStyleColorName(ImPlotCol col) {
static const char* col_names[] = {
"Line",
"Fill",
"MarkerOutline",
"MarkerFill",
"ErrorBar",
"FrameBg",
"PlotBg",
"PlotBorder",
"LegendBg",
"LegendBorder",
"LegendText",
"TitleText",
"InlayText",
"XAxis",
"XAxisGrid",
"YAxis",
"YAxisGrid",
"YAxis2",
"YAxisGrid2",
"YAxis3",
"YAxisGrid3",
"Selection",
"Query",
"Crosshairs"
};
return col_names[col];
}
ImVec4 GetAutoColor(ImPlotCol idx) {
ImVec4 col(0,0,0,1);
switch(idx) {
case ImPlotCol_Line: return col; // these are plot dependent!
case ImPlotCol_Fill: return col; // these are plot dependent!
case ImPlotCol_MarkerOutline: return col; // these are plot dependent!
case ImPlotCol_MarkerFill: return col; // these are plot dependent!
case ImPlotCol_ErrorBar: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_FrameBg: return ImGui::GetStyleColorVec4(ImGuiCol_FrameBg);
case ImPlotCol_PlotBg: return ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
case ImPlotCol_PlotBorder: return ImGui::GetStyleColorVec4(ImGuiCol_Text) * ImVec4(1,1,1,0.50f);
case ImPlotCol_LegendBg: return ImGui::GetStyleColorVec4(ImGuiCol_PopupBg);
case ImPlotCol_LegendBorder: return GetStyleColorVec4(ImPlotCol_PlotBorder);
case ImPlotCol_LegendText: return GetStyleColorVec4(ImPlotCol_InlayText);
case ImPlotCol_TitleText: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_InlayText: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_XAxis: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_XAxisGrid: return GetStyleColorVec4(ImPlotCol_XAxis) * ImVec4(1,1,1,0.25f);
case ImPlotCol_YAxis: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_YAxisGrid: return GetStyleColorVec4(ImPlotCol_YAxis) * ImVec4(1,1,1,0.25f);
case ImPlotCol_YAxis2: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_YAxisGrid2: return GetStyleColorVec4(ImPlotCol_YAxis2) * ImVec4(1,1,1,0.25f);
case ImPlotCol_YAxis3: return ImGui::GetStyleColorVec4(ImGuiCol_Text);
case ImPlotCol_YAxisGrid3: return GetStyleColorVec4(ImPlotCol_YAxis3) * ImVec4(1,1,1,0.25f);
case ImPlotCol_Selection: return ImVec4(1,1,0,1);
case ImPlotCol_Query: return ImVec4(0,1,0,1);
case ImPlotCol_Crosshairs: return GetStyleColorVec4(ImPlotCol_PlotBorder);
default: return col;
}
}
struct ImPlotStyleVarInfo {
ImGuiDataType Type;
ImU32 Count;
ImU32 Offset;
void* GetVarPtr(ImPlotStyle* style) const { return (void*)((unsigned char*)style + Offset); }
};
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, FillAlpha) }, // ImPlotStyleVar_FillAlpha
{ 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, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorAlpha) }, // ImPlotStyleVar_MinorAlpha
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickLen) }, // ImPlotStyleVar_MajorTickLen
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickSize) }, // ImPlotStyleVar_MajorTickSize
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickSize) }, // ImPlotStyleVar_MinorTickSize
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorGridSize) }, // ImPlotStyleVar_MinorGridSize
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendPadding) }, // ImPlotStyleVar_LegendPadding
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, InfoPadding) }, // ImPlotStyleVar_InfoPadding
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
};
static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) {
IM_ASSERT(idx >= 0 && idx < ImPlotStyleVar_COUNT);
IM_ASSERT(IM_ARRAYSIZE(GPlotStyleVarInfo) == ImPlotStyleVar_COUNT);
return &GPlotStyleVarInfo[idx];
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Generic Helpers // Generic Helpers
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -259,6 +384,10 @@ ImPlotState* GetCurrentPlot() {
return GImPlot->CurrentPlot; return GImPlot->CurrentPlot;
} }
void BustPlotCache() {
GImPlot->Plots.Clear();
}
void FitPoint(const ImPlotPoint& p) { void FitPoint(const ImPlotPoint& p) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
const int y_axis = gp.CurrentPlot->CurrentYAxis; const int y_axis = gp.CurrentPlot->CurrentYAxis;
@ -390,14 +519,12 @@ ImPlotItem* GetItem(const char* plot_title, const char* item_label_id) {
return NULL; return NULL;
} }
void BustItemColorCache() { void BustItemCache() {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
for (int p = 0; p < gp.Plots.GetSize(); ++p) { for (int p = 0; p < gp.Plots.GetSize(); ++p) {
ImPlotState& plot = *gp.Plots.GetByIndex(p); ImPlotState& plot = *gp.Plots.GetByIndex(p);
for (int i = 0; i < plot.Items.GetSize(); ++i) { plot.ColormapIdx = 0;
ImPlotItem& item = *plot.Items.GetByIndex(i); plot.Items.Clear();
item.Color = IMPLOT_COL_AUTO;
}
} }
} }
@ -523,15 +650,16 @@ float SumTickLabelHeight(const ImVector<ImPlotTick>& ticks) {
// Axis Utils // Axis Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void UpdateAxisColor(int axis_flag, ImPlotAxisColor* col) { void UpdateAxisColors(int axis_flag, ImPlotAxisColor* col) {
ImPlotContext& gp = *GImPlot; const ImVec4 col_label = GetStyleColorVec4(axis_flag);
const ImVec4 col_axis = gp.Style.Colors[axis_flag].w == -1 ? ImGui::GetStyle().Colors[ImGuiCol_Text] * ImVec4(1, 1, 1, 0.25f) : gp.Style.Colors[axis_flag]; const ImVec4 col_grid = GetStyleColorVec4(axis_flag + 1);
col->Major = ImGui::GetColorU32(col_axis); col->Major = ImGui::GetColorU32(col_grid);
col->Minor = ImGui::GetColorU32(col_axis * ImVec4(1, 1, 1, 0.25f)); col->Minor = ImGui::GetColorU32(col_grid*ImVec4(1,1,1,GImPlot->Style.MinorAlpha));
col->MajTxt = ImGui::GetColorU32(ImVec4(col_axis.x, col_axis.y, col_axis.z, 1)); col->MajTxt = ImGui::GetColorU32(col_label);
col->MinTxt = ImGui::GetColorU32(ImVec4(col_axis.x, col_axis.y, col_axis.z, 0.8f)); col->MinTxt = ImGui::GetColorU32(col_label);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// BeginPlot() // BeginPlot()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -650,32 +778,21 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
plot.YAxis[i].Range.Max = plot.YAxis[i].Range.Min + DBL_EPSILON; plot.YAxis[i].Range.Max = plot.YAxis[i].Range.Min + DBL_EPSILON;
} }
// COLORS ----------------------------------------------------------------- // AXIS COLORS -----------------------------------------------------------------
gp.Col_Frame = gp.Style.Colors[ImPlotCol_FrameBg].w == -1 ? ImGui::GetColorU32(ImGuiCol_FrameBg) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_FrameBg]); UpdateAxisColors(ImPlotCol_XAxis, &gp.Col_X);
gp.Col_Bg = gp.Style.Colors[ImPlotCol_PlotBg].w == -1 ? ImGui::GetColorU32(ImGuiCol_WindowBg) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_PlotBg]); UpdateAxisColors(ImPlotCol_YAxis, &gp.Col_Y[0]);
gp.Col_Border = gp.Style.Colors[ImPlotCol_PlotBorder].w == -1 ? ImGui::GetColorU32(ImGuiCol_Text, 0.5f) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_PlotBorder]); UpdateAxisColors(ImPlotCol_YAxis2, &gp.Col_Y[1]);
UpdateAxisColors(ImPlotCol_YAxis3, &gp.Col_Y[2]);
UpdateAxisColor(ImPlotCol_XAxis, &gp.Col_X);
UpdateAxisColor(ImPlotCol_YAxis, &gp.Col_Y[0]);
UpdateAxisColor(ImPlotCol_YAxis2, &gp.Col_Y[1]);
UpdateAxisColor(ImPlotCol_YAxis3, &gp.Col_Y[2]);
gp.Col_Txt = ImGui::GetColorU32(ImGuiCol_Text);
gp.Col_TxtDis = ImGui::GetColorU32(ImGuiCol_TextDisabled);
gp.Col_SlctBg = ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_Selection] * ImVec4(1,1,1,0.25f));
gp.Col_SlctBd = ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_Selection]);
gp.Col_QryBg = ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_Query] * ImVec4(1,1,1,0.25f));
gp.Col_QryBd = ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_Query]);
// BB AND HOVER ----------------------------------------------------------- // BB AND HOVER -----------------------------------------------------------
// frame // frame
ImVec2 frame_size = ImGui::CalcItemSize(size, IMPLOT_DEFAULT_W, IMPLOT_DEFAULT_H); ImVec2 frame_size = ImGui::CalcItemSize(size, IMPLOT_DEFAULT_W, IMPLOT_DEFAULT_H);
if (frame_size.x < IMPLOT_MIN_W && size.x < 0.0f) if (frame_size.x < gp.Style.PlotMinSize.x && size.x < 0.0f)
frame_size.x = IMPLOT_MIN_W; frame_size.x = gp.Style.PlotMinSize.x;
if (frame_size.y < IMPLOT_MIN_H && size.y < 0.0f) if (frame_size.y < gp.Style.PlotMinSize.y && size.y < 0.0f)
frame_size.y = IMPLOT_MIN_H; frame_size.y = gp.Style.PlotMinSize.y;
gp.BB_Frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + frame_size); gp.BB_Frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + frame_size);
ImGui::ItemSize(gp.BB_Frame); ImGui::ItemSize(gp.BB_Frame);
if (!ImGui::ItemAdd(gp.BB_Frame, 0, &gp.BB_Frame)) { if (!ImGui::ItemAdd(gp.BB_Frame, 0, &gp.BB_Frame)) {
@ -683,7 +800,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
return false; return false;
} }
gp.Hov_Frame = ImGui::ItemHoverable(gp.BB_Frame, ID); gp.Hov_Frame = ImGui::ItemHoverable(gp.BB_Frame, ID);
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, GetStyleColorU32(ImPlotCol_FrameBg), true, Style.FrameRounding);
// canvas bb // canvas bb
gp.BB_Canvas = ImRect(gp.BB_Frame.Min + gp.Style.PlotPadding, gp.BB_Frame.Max - gp.Style.PlotPadding); gp.BB_Canvas = ImRect(gp.BB_Frame.Min + gp.Style.PlotPadding, gp.BB_Frame.Max - gp.Style.PlotPadding);
@ -732,13 +849,13 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// plot bb // plot bb
const ImVec2 title_size = ImGui::CalcTextSize(title, NULL, true); const ImVec2 title_size = ImGui::CalcTextSize(title, NULL, true);
const float txt_height = ImGui::GetTextLineHeight(); const float txt_height = ImGui::GetTextLineHeight();
const float pad_top = title_size.x > 0.0f ? txt_height + IMPLOT_LABEL_PAD : 0; const float pad_top = title_size.x > 0.0f ? txt_height + gp.Style.LabelPadding.y : 0;
const float pad_bot = (gp.X.HasLabels ? txt_height + IMPLOT_LABEL_PAD : 0) + (x_label ? txt_height + IMPLOT_LABEL_PAD : 0); const float pad_bot = (gp.X.HasLabels ? txt_height + gp.Style.LabelPadding.y : 0) + (x_label ? txt_height + gp.Style.LabelPadding.y : 0);
const float pad_left = (y_label ? txt_height + IMPLOT_LABEL_PAD : 0) const float pad_left = (y_label ? txt_height + gp.Style.LabelPadding.x : 0)
+ (gp.Y[0].HasLabels ? max_label_widths[0] + IMPLOT_LABEL_PAD : 0); + (gp.Y[0].HasLabels ? max_label_widths[0] + gp.Style.LabelPadding.x : 0);
const float pad_right = ((gp.Y[1].Present && gp.Y[1].HasLabels) ? max_label_widths[1] + IMPLOT_LABEL_PAD : 0) const float pad_right = ((gp.Y[1].Present && gp.Y[1].HasLabels) ? max_label_widths[1] + gp.Style.LabelPadding.x : 0)
+ ((gp.Y[1].Present && gp.Y[2].Present) ? IMPLOT_LABEL_PAD + IMPLOT_MINOR_SIZE : 0) + ((gp.Y[1].Present && gp.Y[2].Present) ? gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y : 0)
+ ((gp.Y[2].Present && gp.Y[2].HasLabels) ? max_label_widths[2] + IMPLOT_LABEL_PAD : 0); + ((gp.Y[2].Present && gp.Y[2].HasLabels) ? max_label_widths[2] + gp.Style.LabelPadding.x : 0);
gp.BB_Plot = ImRect(gp.BB_Canvas.Min + ImVec2(pad_left, pad_top), gp.BB_Canvas.Max - ImVec2(pad_right, pad_bot)); gp.BB_Plot = ImRect(gp.BB_Canvas.Min + ImVec2(pad_left, pad_top), gp.BB_Canvas.Max - ImVec2(pad_right, pad_bot));
@ -752,7 +869,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// axis label reference // axis label reference
gp.YAxisReference[0] = gp.BB_Plot.Min.x; gp.YAxisReference[0] = gp.BB_Plot.Min.x;
gp.YAxisReference[1] = gp.BB_Plot.Max.x; gp.YAxisReference[1] = gp.BB_Plot.Max.x;
gp.YAxisReference[2] = !gp.Y[1].Present ? gp.BB_Plot.Max.x : (gp.YAxisReference[1] + (gp.Y[1].HasLabels ? IMPLOT_LABEL_PAD + max_label_widths[1] : 0) + IMPLOT_LABEL_PAD + IMPLOT_MINOR_SIZE); gp.YAxisReference[2] = !gp.Y[1].Present ? gp.BB_Plot.Max.x : (gp.YAxisReference[1] + (gp.Y[1].HasLabels ? gp.Style.LabelPadding.x + max_label_widths[1] : 0) + gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y);
// y axis regions bb and hover // y axis regions bb and hover
ImRect yAxisRegion_bb[IMPLOT_Y_AXES]; ImRect yAxisRegion_bb[IMPLOT_Y_AXES];
@ -1035,7 +1152,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// RENDER ----------------------------------------------------------------- // RENDER -----------------------------------------------------------------
// grid bg // grid bg
DrawList.AddRectFilled(gp.BB_Plot.Min, gp.BB_Plot.Max, gp.Col_Bg); DrawList.AddRectFilled(gp.BB_Plot.Min, gp.BB_Plot.Max, GetStyleColorU32(ImPlotCol_PlotBg));
// render axes // render axes
PushPlotClipRect(); PushPlotClipRect();
@ -1065,9 +1182,9 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImPlotTick& xt = gp.XTicks[t]; ImPlotTick& xt = gp.XTicks[t];
if (xt.Major) if (xt.Major)
DrawList.AddLine(ImVec2(xt.PixelPos, gp.BB_Plot.Min.y), ImVec2(xt.PixelPos, gp.BB_Plot.Max.y), gp.Col_X.Major, 1); DrawList.AddLine(ImVec2(xt.PixelPos, gp.BB_Plot.Min.y), ImVec2(xt.PixelPos, gp.BB_Plot.Max.y), gp.Col_X.Major, gp.Style.MajorGridSize.x);
else if (density < 0.2f) else if (density < 0.2f)
DrawList.AddLine(ImVec2(xt.PixelPos, gp.BB_Plot.Min.y), ImVec2(xt.PixelPos, gp.BB_Plot.Max.y), col_min32, 1); DrawList.AddLine(ImVec2(xt.PixelPos, gp.BB_Plot.Min.y), ImVec2(xt.PixelPos, gp.BB_Plot.Max.y), col_min32, gp.Style.MinorGridSize.x);
} }
} }
@ -1080,9 +1197,9 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
for (int t = 0; t < gp.YTicks[i].Size; t++) { for (int t = 0; t < gp.YTicks[i].Size; t++) {
ImPlotTick& yt = gp.YTicks[i][t]; ImPlotTick& yt = gp.YTicks[i][t];
if (yt.Major) if (yt.Major)
DrawList.AddLine(ImVec2(gp.BB_Plot.Min.x, yt.PixelPos), ImVec2(gp.BB_Plot.Max.x, yt.PixelPos), gp.Col_Y[i].Major, 1); DrawList.AddLine(ImVec2(gp.BB_Plot.Min.x, yt.PixelPos), ImVec2(gp.BB_Plot.Max.x, yt.PixelPos), gp.Col_Y[i].Major, gp.Style.MajorGridSize.y);
else if (density < 0.2f) else if (density < 0.2f)
DrawList.AddLine(ImVec2(gp.BB_Plot.Min.x, yt.PixelPos), ImVec2(gp.BB_Plot.Max.x, yt.PixelPos), col_min32, 1); DrawList.AddLine(ImVec2(gp.BB_Plot.Min.x, yt.PixelPos), ImVec2(gp.BB_Plot.Max.x, yt.PixelPos), col_min32, gp.Style.MinorGridSize.y);
} }
} }
} }
@ -1091,7 +1208,9 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// render title // render title
if (title_size.x > 0.0f) { if (title_size.x > 0.0f) {
ImGui::RenderText(ImVec2(gp.BB_Canvas.GetCenter().x - title_size.x * 0.5f, gp.BB_Canvas.Min.y), title, NULL, true); ImU32 col = GetStyleColorU32(ImPlotCol_TitleText);
const char* title_end = ImGui::FindRenderedTextEnd(title, NULL);
DrawList.AddText(ImVec2(gp.BB_Canvas.GetCenter().x - title_size.x * 0.5f, gp.BB_Canvas.Min.y),col,title,title_end);
} }
// render axis labels // render axis labels
@ -1112,13 +1231,13 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImPlotTick *xt = &gp.XTicks[t]; ImPlotTick *xt = &gp.XTicks[t];
if (xt->ShowLabel && xt->PixelPos >= gp.BB_Plot.Min.x - 1 && xt->PixelPos <= gp.BB_Plot.Max.x + 1) if (xt->ShowLabel && xt->PixelPos >= gp.BB_Plot.Min.x - 1 && xt->PixelPos <= gp.BB_Plot.Max.x + 1)
DrawList.AddText(ImVec2(xt->PixelPos - xt->LabelSize.x * 0.5f, gp.BB_Plot.Max.y + IMPLOT_LABEL_PAD), xt->Major ? gp.Col_X.MajTxt : gp.Col_X.MinTxt, gp.XTickLabels.Buf.Data + xt->BufferOffset); DrawList.AddText(ImVec2(xt->PixelPos - xt->LabelSize.x * 0.5f, gp.BB_Plot.Max.y + gp.Style.LabelPadding.y), xt->Major ? gp.Col_X.MajTxt : gp.Col_X.MinTxt, gp.XTickLabels.Buf.Data + xt->BufferOffset);
} }
} }
for (int i = 0; i < IMPLOT_Y_AXES; i++) { for (int i = 0; i < IMPLOT_Y_AXES; i++) {
if (gp.Y[i].Present && ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) { if (gp.Y[i].Present && ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) {
for (int t = 0; t < gp.YTicks[i].Size; t++) { for (int t = 0; t < gp.YTicks[i].Size; t++) {
const float x_start = gp.YAxisReference[i] + (i == 0 ? (-IMPLOT_LABEL_PAD - gp.YTicks[i][t].LabelSize.x) : IMPLOT_LABEL_PAD); const float x_start = gp.YAxisReference[i] + (i == 0 ? (-gp.Style.LabelPadding.x - gp.YTicks[i][t].LabelSize.x) : gp.Style.LabelPadding.x);
ImPlotTick *yt = &gp.YTicks[i][t]; ImPlotTick *yt = &gp.YTicks[i][t];
if (yt->ShowLabel && yt->PixelPos >= gp.BB_Plot.Min.y - 1 && yt->PixelPos <= gp.BB_Plot.Max.y + 1) { if (yt->ShowLabel && yt->PixelPos >= gp.BB_Plot.Min.y - 1 && yt->PixelPos <= gp.BB_Plot.Max.y + 1) {
ImVec2 start(x_start, yt->PixelPos - 0.5f * yt->LabelSize.y); ImVec2 start(x_start, yt->PixelPos - 0.5f * yt->LabelSize.y);
@ -1302,7 +1421,10 @@ void EndPlot() {
if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks)) { if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks)) {
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImPlotTick *xt = &gp.XTicks[t]; ImPlotTick *xt = &gp.XTicks[t];
DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Plot.Max.y),ImVec2(xt->PixelPos, gp.BB_Plot.Max.y - (xt->Major ? IMPLOT_MAJOR_SIZE : IMPLOT_MINOR_SIZE)), gp.Col_Border, 1); DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Plot.Max.y),
ImVec2(xt->PixelPos, gp.BB_Plot.Max.y - (xt->Major ? gp.Style.MajorTickLen.x : gp.Style.MinorTickLen.x)),
gp.Col_X.Major,
xt->Major ? gp.Style.MajorTickSize.x : gp.Style.MinorTickSize.x);
} }
} }
PopPlotClipRect(); PopPlotClipRect();
@ -1320,10 +1442,10 @@ void EndPlot() {
for (int t = 0; t < gp.YTicks[i].Size; t++) { for (int t = 0; t < gp.YTicks[i].Size; t++) {
ImPlotTick *yt = &gp.YTicks[i][t]; ImPlotTick *yt = &gp.YTicks[i][t];
ImVec2 start = ImVec2(x_start, yt->PixelPos); ImVec2 start = ImVec2(x_start, yt->PixelPos);
DrawList.AddLine( DrawList.AddLine(start,
start, start + ImVec2(direction * ((!no_major && yt->Major) ? gp.Style.MajorTickLen.y : gp.Style.MinorTickLen.y), 0),
start + ImVec2(direction * ((!no_major && yt->Major) ? IMPLOT_MAJOR_SIZE : IMPLOT_MINOR_SIZE), 0), gp.Col_Y[i].Major,
gp.Col_Border, 1); (!no_major && yt->Major) ? gp.Style.MajorTickSize.y : gp.Style.MinorTickSize.y);
} }
} }
@ -1332,7 +1454,7 @@ void EndPlot() {
DrawList.AddLine( DrawList.AddLine(
ImVec2(x_start, gp.BB_Plot.Min.y), ImVec2(x_start, gp.BB_Plot.Min.y),
ImVec2(x_start, gp.BB_Plot.Max.y), ImVec2(x_start, gp.BB_Plot.Max.y),
gp.Col_Border, 1); GetStyleColorU32(ImPlotCol_PlotBorder), 1);
} }
} }
ImGui::PopClipRect(); ImGui::PopClipRect();
@ -1353,50 +1475,54 @@ void EndPlot() {
// render selection/query // render selection/query
if (plot.Selecting) { if (plot.Selecting) {
ImRect select_bb(ImMin(IO.MousePos, plot.SelectStart), ImMax(IO.MousePos, plot.SelectStart)); ImRect select_bb(ImMin(IO.MousePos, plot.SelectStart), ImMax(IO.MousePos, plot.SelectStart));
bool select_big_enough = ImLengthSqr(select_bb.GetSize()) > 4; const bool select_big_enough = ImLengthSqr(select_bb.GetSize()) > 4;
if (plot.Selecting && !gp.LockPlot && ImHasFlag(plot.Flags, ImPlotFlags_BoxSelect) && select_big_enough) { if (plot.Selecting && !gp.LockPlot && ImHasFlag(plot.Flags, ImPlotFlags_BoxSelect) && select_big_enough) {
const ImVec4 col = GetStyleColorVec4(ImPlotCol_Selection);
const ImU32 col_bg = ImGui::GetColorU32(col * ImVec4(1,1,1,0.25f));
const ImU32 col_bd = ImGui::GetColorU32(col);
if (IO.KeyAlt && IO.KeyShift) { if (IO.KeyAlt && IO.KeyShift) {
DrawList.AddRectFilled(gp.BB_Plot.Min, gp.BB_Plot.Max, gp.Col_SlctBg); DrawList.AddRectFilled(gp.BB_Plot.Min, gp.BB_Plot.Max, col_bg);
DrawList.AddRect( gp.BB_Plot.Min, gp.BB_Plot.Max, gp.Col_SlctBd); DrawList.AddRect( gp.BB_Plot.Min, gp.BB_Plot.Max, col_bd);
} }
else if ((gp.X.Lock || IO.KeyAlt)) { else if ((gp.X.Lock || IO.KeyAlt)) {
DrawList.AddRectFilled(ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), gp.Col_SlctBg); DrawList.AddRectFilled(ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), col_bg);
DrawList.AddRect( ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), gp.Col_SlctBd); DrawList.AddRect( ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), col_bd);
} }
else if ((any_y_locked || IO.KeyShift)) { else if ((any_y_locked || IO.KeyShift)) {
DrawList.AddRectFilled(ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), gp.Col_SlctBg); DrawList.AddRectFilled(ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), col_bg);
DrawList.AddRect( ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), gp.Col_SlctBd); DrawList.AddRect( ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), col_bd);
} }
else { else {
DrawList.AddRectFilled(select_bb.Min, select_bb.Max, gp.Col_SlctBg); DrawList.AddRectFilled(select_bb.Min, select_bb.Max, col_bg);
DrawList.AddRect( select_bb.Min, select_bb.Max, gp.Col_SlctBd); DrawList.AddRect( select_bb.Min, select_bb.Max, col_bd);
} }
} }
} }
if (ImHasFlag(plot.Flags, ImPlotFlags_Query)) // draw query rect only when query enabled. if (ImHasFlag(plot.Flags, ImPlotFlags_Query)) // draw query rect only when query enabled.
{ {
const ImVec4 col = GetStyleColorVec4(ImPlotCol_Query);
const ImU32 col_bd = ImGui::GetColorU32(col * ImVec4(1,1,1,0.25f));
const ImU32 col_bg = ImGui::GetColorU32(col);
if (plot.Querying || plot.Queried) { if (plot.Querying || plot.Queried) {
if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2) { if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2) {
DrawList.AddRectFilled(plot.QueryRect.Min + gp.BB_Plot.Min, plot.QueryRect.Max + gp.BB_Plot.Min, gp.Col_QryBg); DrawList.AddRectFilled(plot.QueryRect.Min + gp.BB_Plot.Min, plot.QueryRect.Max + gp.BB_Plot.Min, col_bd);
DrawList.AddRect( plot.QueryRect.Min + gp.BB_Plot.Min, plot.QueryRect.Max + gp.BB_Plot.Min, gp.Col_QryBd); DrawList.AddRect( plot.QueryRect.Min + gp.BB_Plot.Min, plot.QueryRect.Max + gp.BB_Plot.Min, col_bg);
} }
} }
else if (plot.Queried) { else if (plot.Queried) {
ImRect bb_query = plot.QueryRect; ImRect bb_query = plot.QueryRect;
bb_query.Min += gp.BB_Plot.Min; bb_query.Min += gp.BB_Plot.Min;
bb_query.Max += gp.BB_Plot.Min; bb_query.Max += gp.BB_Plot.Min;
DrawList.AddRectFilled(bb_query.Min, bb_query.Max, col_bd);
DrawList.AddRectFilled(bb_query.Min, bb_query.Max, gp.Col_QryBg); DrawList.AddRect( bb_query.Min, bb_query.Max, col_bg);
DrawList.AddRect( bb_query.Min, bb_query.Max, gp.Col_QryBd);
} }
} }
// render legend // render legend
const float txt_ht = ImGui::GetTextLineHeight(); const float txt_ht = ImGui::GetTextLineHeight();
const ImVec2 legend_offset(10, 10); const ImVec2 legend_offset = gp.Style.LegendPadding;
const ImVec2 legend_padding(5, 5); const ImVec2 legend_spacing(5, 5);
const float legend_icon_size = txt_ht; const float legend_icon_size = txt_ht;
ImRect legend_content_bb; ImRect legend_content_bb;
int nItems = GetLegendCount(); int nItems = GetLegendCount();
@ -1410,29 +1536,33 @@ void EndPlot() {
max_label_width = labelWidth.x > max_label_width ? labelWidth.x : max_label_width; max_label_width = labelWidth.x > max_label_width ? labelWidth.x : max_label_width;
} }
legend_content_bb = ImRect(gp.BB_Plot.Min + legend_offset, gp.BB_Plot.Min + legend_offset + ImVec2(max_label_width, nItems * txt_ht)); legend_content_bb = ImRect(gp.BB_Plot.Min + legend_offset, gp.BB_Plot.Min + legend_offset + ImVec2(max_label_width, nItems * txt_ht));
plot.BB_Legend = ImRect(legend_content_bb.Min, legend_content_bb.Max + legend_padding * 2 + ImVec2(legend_icon_size, 0)); plot.BB_Legend = ImRect(legend_content_bb.Min, legend_content_bb.Max + legend_spacing * 2 + ImVec2(legend_icon_size, 0));
hov_legend = ImHasFlag(plot.Flags, ImPlotFlags_Legend) ? gp.Hov_Frame && plot.BB_Legend.Contains(IO.MousePos) : false; hov_legend = ImHasFlag(plot.Flags, ImPlotFlags_Legend) ? gp.Hov_Frame && plot.BB_Legend.Contains(IO.MousePos) : false;
// render legend box // render legend box
DrawList.AddRectFilled(plot.BB_Legend.Min, plot.BB_Legend.Max, ImGui::GetColorU32(ImGuiCol_PopupBg)); ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
DrawList.AddRect(plot.BB_Legend.Min, plot.BB_Legend.Max, gp.Col_Border); ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
ImVec4 col_txt = GetStyleColorVec4(ImPlotCol_LegendText);
ImU32 col_txt_dis = ImGui::GetColorU32(col_txt * ImVec4(1,1,1,0.25f));
DrawList.AddRectFilled(plot.BB_Legend.Min, plot.BB_Legend.Max, col_bg);
DrawList.AddRect(plot.BB_Legend.Min, plot.BB_Legend.Max, col_bd);
// render each legend item // render each legend item
for (int i = 0; i < nItems; ++i) { for (int i = 0; i < nItems; ++i) {
ImPlotItem* item = GetItem(i); ImPlotItem* item = GetItem(i);
ImRect icon_bb; ImRect icon_bb;
icon_bb.Min = legend_content_bb.Min + legend_padding + ImVec2(0, i * txt_ht) + ImVec2(2, 2); icon_bb.Min = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(2, 2);
icon_bb.Max = legend_content_bb.Min + legend_padding + ImVec2(0, i * txt_ht) + ImVec2(legend_icon_size - 2, legend_icon_size - 2); icon_bb.Max = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(legend_icon_size - 2, legend_icon_size - 2);
ImRect label_bb; ImRect label_bb;
label_bb.Min = legend_content_bb.Min + legend_padding + ImVec2(0, i * txt_ht) + ImVec2(2, 2); label_bb.Min = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(2, 2);
label_bb.Max = legend_content_bb.Min + legend_padding + ImVec2(0, i * txt_ht) + ImVec2(legend_content_bb.Max.x, legend_icon_size - 2); label_bb.Max = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(legend_content_bb.Max.x, legend_icon_size - 2);
ImU32 col_hl_txt; ImU32 col_hl_txt;
if (ImHasFlag(plot.Flags, ImPlotFlags_Highlight) && hov_legend && (icon_bb.Contains(IO.MousePos) || label_bb.Contains(IO.MousePos))) { if (ImHasFlag(plot.Flags, ImPlotFlags_Highlight) && hov_legend && (icon_bb.Contains(IO.MousePos) || label_bb.Contains(IO.MousePos))) {
item->Highlight = true; item->Highlight = true;
col_hl_txt = ImGui::GetColorU32(ImLerp(G.Style.Colors[ImGuiCol_Text], item->Color, 0.25f)); col_hl_txt = ImGui::GetColorU32(ImLerp(col_txt, item->Color, 0.25f));
} }
else else
{ {
item->Highlight = false; item->Highlight = false;
col_hl_txt = gp.Col_Txt; col_hl_txt = ImGui::GetColorU32(col_txt);
} }
ImU32 iconColor; ImU32 iconColor;
if (hov_legend && icon_bb.Contains(IO.MousePos)) { if (hov_legend && icon_bb.Contains(IO.MousePos)) {
@ -1443,13 +1573,13 @@ void EndPlot() {
if (IO.MouseClicked[0]) if (IO.MouseClicked[0])
item->Show = !item->Show; item->Show = !item->Show;
} else { } else {
iconColor = item->Show ? ImGui::GetColorU32(item->Color) : gp.Col_TxtDis; iconColor = item->Show ? ImGui::GetColorU32(item->Color) : col_txt_dis;
} }
DrawList.AddRectFilled(icon_bb.Min, icon_bb.Max, iconColor, 1); DrawList.AddRectFilled(icon_bb.Min, icon_bb.Max, iconColor, 1);
const char* label = GetLegendLabel(i); const char* label = GetLegendLabel(i);
const char* text_display_end = ImGui::FindRenderedTextEnd(label, NULL); const char* text_display_end = ImGui::FindRenderedTextEnd(label, NULL);
if (label != text_display_end) if (label != text_display_end)
DrawList.AddText(legend_content_bb.Min + legend_padding + ImVec2(legend_icon_size, i * txt_ht), item->Show ? col_hl_txt : gp.Col_TxtDis, label, text_display_end); DrawList.AddText(legend_content_bb.Min + legend_spacing + ImVec2(legend_icon_size, i * txt_ht), item->Show ? col_hl_txt : col_txt_dis, label, text_display_end);
} }
} }
@ -1466,10 +1596,11 @@ void EndPlot() {
ImVec2 v2(xy.x, xy.y - 5); ImVec2 v2(xy.x, xy.y - 5);
ImVec2 v3(xy.x, xy.y + 5); ImVec2 v3(xy.x, xy.y + 5);
ImVec2 v4(xy.x, gp.BB_Plot.Max.y); ImVec2 v4(xy.x, gp.BB_Plot.Max.y);
DrawList.AddLine(h1, h2, gp.Col_Border); ImU32 col = GetStyleColorU32(ImPlotCol_Crosshairs);
DrawList.AddLine(h3, h4, gp.Col_Border); DrawList.AddLine(h1, h2, col);
DrawList.AddLine(v1, v2, gp.Col_Border); DrawList.AddLine(h3, h4, col);
DrawList.AddLine(v3, v4, gp.Col_Border); DrawList.AddLine(v1, v2, col);
DrawList.AddLine(v3, v4, col);
} }
// render mouse pos // render mouse pos
@ -1514,14 +1645,15 @@ void EndPlot() {
} }
} }
ImVec2 size = ImGui::CalcTextSize(buffer); ImVec2 size = ImGui::CalcTextSize(buffer);
ImVec2 pos = gp.BB_Plot.Max - size - ImVec2(5, 5); ImVec2 pos = gp.BB_Plot.Max - size - gp.Style.InfoPadding;
DrawList.AddText(pos, gp.Col_Txt, buffer); DrawList.AddText(pos, GetStyleColorU32(ImPlotCol_InlayText), buffer);
} }
PopPlotClipRect(); PopPlotClipRect();
// render border // render border
DrawList.AddRect(gp.BB_Plot.Min, gp.BB_Plot.Max, gp.Col_Border); if (gp.Style.PlotBorderSize > 0)
DrawList.AddRect(gp.BB_Plot.Min, gp.BB_Plot.Max, GetStyleColorU32(ImPlotCol_PlotBorder), 0, ImDrawCornerFlags_All, gp.Style.PlotBorderSize);
// FIT DATA -------------------------------------------------------------- // FIT DATA --------------------------------------------------------------
@ -1773,34 +1905,6 @@ bool IsLegendEntryHovered(const char* label_id) {
// STYLING // STYLING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct ImPlotStyleVarInfo {
ImGuiDataType Type;
ImU32 Count;
ImU32 Offset;
void* GetVarPtr(ImPlotStyle* style) const { return (void*)((unsigned char*)style + Offset); }
};
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, FillAlpha) }, // ImPlotStyleVar_FillAlpha
{ 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, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
{ 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)
{
IM_ASSERT(idx >= 0 && idx < ImPlotStyleVar_COUNT);
IM_ASSERT(IM_ARRAYSIZE(GPlotStyleVarInfo) == ImPlotStyleVar_COUNT);
return &GPlotStyleVarInfo[idx];
}
ImPlotStyle& GetStyle() { ImPlotStyle& GetStyle() {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
return gp.Style; return gp.Style;
@ -1942,7 +2046,8 @@ void SetColormap(ImPlotColormap colormap, int samples) {
void SetColormap(const ImVec4* colors, int size) { void SetColormap(const ImVec4* colors, int size) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(size > 1, "The number of colors must be greater than 1!"); IM_ASSERT_USER_ERROR(colors != NULL, "You can't set the colors to NULL!");
IM_ASSERT_USER_ERROR(size > 0, "The number of colors must be greater than 0!");
static ImVector<ImVec4> user_colormap; static ImVector<ImVec4> user_colormap;
user_colormap.shrink(0); user_colormap.shrink(0);
user_colormap.reserve(size); user_colormap.reserve(size);
@ -1953,9 +2058,9 @@ void SetColormap(const ImVec4* colors, int size) {
} }
const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out) { const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out) {
static const int csizes[ImPlotColormap_COUNT] = {10,9,9,12,11,11,11,11,11,11}; static const int csizes[ImPlotColormap_COUNT] = {10,9,9,12,10,11,11,11,11,11,11};
static const ImOffsetCalculator<ImPlotColormap_COUNT> coffs(csizes); static const ImOffsetCalculator<ImPlotColormap_COUNT> coffs(csizes);
static const ImVec4 cdata[] = { static ImVec4 cdata[] = {
// ImPlotColormap_Default // X11 Named Colors // ImPlotColormap_Default // X11 Named Colors
ImVec4(0.0f, 0.7490196228f, 1.0f, 1.0f), // Blues::DeepSkyBlue, ImVec4(0.0f, 0.7490196228f, 1.0f, 1.0f), // Blues::DeepSkyBlue,
ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // Reds::Red, ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // Reds::Red,
@ -2000,6 +2105,17 @@ const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out) {
ImVec4(0.415686f, 0.239216f, 0.603922f, 1.0f), ImVec4(0.415686f, 0.239216f, 0.603922f, 1.0f),
ImVec4(1.000000f, 1.000000f, 0.600000f, 1.0f), ImVec4(1.000000f, 1.000000f, 0.600000f, 1.0f),
ImVec4(0.694118f, 0.349020f, 0.156863f, 1.0f), ImVec4(0.694118f, 0.349020f, 0.156863f, 1.0f),
// ImPlotColormap_Deep
ImVec4(0.298f, 0.447f, 0.690f, 1.000f),
ImVec4(0.867f, 0.518f, 0.322f, 1.000f),
ImVec4(0.333f, 0.659f, 0.408f, 1.000f),
ImVec4(0.769f, 0.306f, 0.322f, 1.000f),
ImVec4(0.506f, 0.446f, 0.702f, 1.000f),
ImVec4(0.576f, 0.471f, 0.376f, 1.000f),
ImVec4(0.855f, 0.545f, 0.765f, 1.000f),
ImVec4(0.549f, 0.549f, 0.549f, 1.000f),
ImVec4(0.800f, 0.725f, 0.455f, 1.000f),
ImVec4(0.392f, 0.710f, 0.804f, 1.000f),
// ImPlotColormap_Viridis // ImPlotColormap_Viridis
ImVec4(0.267004f, 0.004874f, 0.329415f, 1.0f), ImVec4(0.267004f, 0.004874f, 0.329415f, 1.0f),
ImVec4(0.282623f, 0.140926f, 0.457517f, 1.0f), ImVec4(0.282623f, 0.140926f, 0.457517f, 1.0f),
@ -2078,7 +2194,7 @@ const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out) {
} }
const char* GetColormapName(ImPlotColormap colormap) { const char* GetColormapName(ImPlotColormap colormap) {
static const char* cmap_names[] = {"Default","Dark","Pastel","Paired","Viridis","Plasma","Hot","Cool","Pink","Jet"}; static const char* cmap_names[] = {"Default","Dark","Pastel","Paired","Deep","Viridis","Plasma","Hot","Cool","Pink","Jet"};
return cmap_names[colormap]; return cmap_names[colormap];
} }
@ -2104,7 +2220,7 @@ ImVec4 LerpColormap(const ImVec4* colormap, int size, float t) {
float tc = ImClamp(t,0.0f,1.0f); float tc = ImClamp(t,0.0f,1.0f);
int i1 = (int)((size -1 ) * tc); int i1 = (int)((size -1 ) * tc);
int i2 = i1 + 1; int i2 = i1 + 1;
if (i2 == size) if (i2 == size || size == 1)
return colormap[i1]; return colormap[i1];
float t1 = (float)i1 / (float)(size - 1); float t1 = (float)i1 / (float)(size - 1);
float t2 = (float)i2 / (float)(size - 1); float t2 = (float)i2 / (float)(size - 1);
@ -2179,4 +2295,269 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
} }
//-----------------------------------------------------------------------------
// Style Editor etc.
//-----------------------------------------------------------------------------
static void HelpMarker(const char* desc) {
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
void ShowStyleEditor(ImPlotStyle* ref) {
ImPlotContext& gp = *GImPlot;
ImPlotStyle& style = GetStyle();
static ImPlotStyle ref_saved_style;
// Default to using internal storage as reference
static bool init = true;
if (init && ref == NULL)
ref_saved_style = style;
init = false;
if (ref == NULL)
ref = &ref_saved_style;
// Save/Revert button
if (ImGui::Button("Save Ref"))
*ref = ref_saved_style = style;
ImGui::SameLine();
if (ImGui::Button("Revert Ref"))
style = *ref;
ImGui::SameLine();
HelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. "
"Use \"Export\" below to save them somewhere.");
if (ImGui::BeginTabBar("##StyleEditor")) {
if (ImGui::BeginTabItem("Variables")) {
ImGui::Text("Item Styling");
ImGui::SliderFloat("LineWeight", &style.LineWeight, 0.0f, 5.0f, "%.1f");
ImGui::SliderFloat("MarkerSize", &style.MarkerSize, 2.0f, 10.0f, "%.1f");
ImGui::SliderFloat("MarkerWeight", &style.MarkerWeight, 0.0f, 5.0f, "%.1f");
ImGui::SliderFloat("FillAlpha", &style.FillAlpha, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat("ErrorBarSize", &style.ErrorBarSize, 0.0f, 10.0f, "%.1f");
ImGui::SliderFloat("ErrorBarWeight", &style.ErrorBarWeight, 0.0f, 5.0f, "%.1f");
ImGui::SliderFloat("DigitalBitHeight", &style.DigitalBitHeight, 0.0f, 20.0f, "%.1f");
ImGui::SliderFloat("DigitalBitGap", &style.DigitalBitGap, 0.0f, 20.0f, "%.1f");
ImGui::Text("Plot Styling");
ImGui::SliderFloat("PlotBorderSize", &style.PlotBorderSize, 0.0f, 2.0f, "%.0f");
ImGui::SliderFloat("MinorAlpha", &style.MinorAlpha, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat2("MajorTickLen", (float*)&style.MajorTickLen, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("MinorTickLen", (float*)&style.MinorTickLen, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("MajorTickSize", (float*)&style.MajorTickSize, 0.0f, 2.0f, "%.1f");
ImGui::SliderFloat2("MinorTickSize", (float*)&style.MinorTickSize, 0.0f, 2.0f, "%.1f");
ImGui::SliderFloat2("MajorGridSize", (float*)&style.MajorGridSize, 0.0f, 2.0f, "%.1f");
ImGui::SliderFloat2("MinorGridSize", (float*)&style.MinorGridSize, 0.0f, 2.0f, "%.1f");
ImGui::Text("Plot Padding");
ImGui::SliderFloat2("PlotPadding", (float*)&style.PlotPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("LabelPadding", (float*)&style.LabelPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("LegendPadding", (float*)&style.LegendPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("InfoPadding", (float*)&style.InfoPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("PlotMinSize", (float*)&style.PlotMinSize, 0.0f, 300, "%.0f");
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Colors")) {
static int output_dest = 0;
static bool output_only_modified = false;
if (ImGui::Button("Export", ImVec2(75,0))) {
if (output_dest == 0)
ImGui::LogToClipboard();
else
ImGui::LogToTTY();
ImGui::LogText("ImVec4* colors = ImPlot::GetStyle().Colors;\n");
for (int i = 0; i < ImPlotCol_COUNT; i++) {
const ImVec4& col = style.Colors[i];
const char* name = ImPlot::GetStyleColorName(i);
if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) {
if (IsColorAuto(i))
ImGui::LogText("colors[ImPlotCol_%s]%*s= IMPLOT_COL_AUTO;\n",name,14 - (int)strlen(name), "");
else
ImGui::LogText("colors[ImPlotCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);\n",
name, 14 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
}
}
ImGui::LogFinish();
}
ImGui::SameLine(); ImGui::SetNextItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified);
static ImGuiTextFilter filter;
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
static ImGuiColorEditFlags alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
HelpMarker(
"In the color list:\n"
"Left-click on colored square to open color picker,\n"
"Right-click to open edit options menu.");
ImGui::Separator();
ImGui::PushItemWidth(-160);
for (int i = 0; i < ImPlotCol_COUNT; i++) {
const char* name = ImPlot::GetStyleColorName(i);
if (!filter.PassFilter(name))
continue;
ImGui::PushID(i);
ImVec4 temp = GetStyleColorVec4(i);
const bool is_auto = IsColorAuto(i);
if (!is_auto)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.25f);
if (ImGui::Button("Auto")) {
if (is_auto)
style.Colors[i] = temp;
else
style.Colors[i] = IMPLOT_COL_AUTO;
BustItemCache();
}
if (!is_auto)
ImGui::PopStyleVar();
ImGui::SameLine();
if (ImGui::ColorEdit4(name, &temp.x, ImGuiColorEditFlags_NoInputs | alpha_flags)) {
style.Colors[i] = temp;
BustItemCache();
}
if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
ImGui::SameLine(175); if (ImGui::Button("Save")) { ref->Colors[i] = style.Colors[i]; }
ImGui::SameLine(); if (ImGui::Button("Revert")) {
style.Colors[i] = ref->Colors[i];
BustItemCache();
}
}
ImGui::PopID();
}
ImGui::PopItemWidth();
ImGui::Separator();
ImGui::Text("Colors that are set to Auto (i.e. IMPLOT_COL_AUTO) will\n"
"be automatically deduced from your ImGui style or the\n"
"current ImPlot Colormap. If you want to style individual\n"
"plot items, use Push/PopStyleColor around its function.");
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Colormaps")) {
static int output_dest = 0;
if (ImGui::Button("Export", ImVec2(75,0))) {
if (output_dest == 0)
ImGui::LogToClipboard();
else
ImGui::LogToTTY();
ImGui::LogText("static const ImVec4 colormap[%d] = {\n", gp.ColormapSize);
for (int i = 0; i < gp.ColormapSize; ++i) {
const ImVec4& col = gp.Colormap[i];
ImGui::LogText(" ImVec4(%.2ff, %.2ff, %.2ff, %.2ff)%s\n", col.x, col.y, col.z, col.w, i == gp.ColormapSize - 1 ? "" : ",");
}
ImGui::LogText("};");
ImGui::LogFinish();
}
ImGui::SameLine(); ImGui::SetNextItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
ImGui::SameLine(); HelpMarker("Export code for selected Colormap\n(built in or custom).");
ImGui::Separator();
static ImVector<ImVec4> custom;
static bool custom_set = false;
for (int i = 0; i < ImPlotColormap_COUNT; ++i) {
ImGui::PushID(i);
int size;
const ImVec4* cmap = GetColormap(i, &size);
bool selected = cmap == gp.Colormap;
if (!selected)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.25f);
if (ImGui::Button(GetColormapName(i), ImVec2(75,0))) {
SetColormap(i);
BustItemCache();
custom_set = false;
}
if (!selected)
ImGui::PopStyleVar();
ImGui::SameLine();
for (int c = 0; c < size; ++c) {
ImGui::PushID(c);
ImGui::ColorButton("",cmap[c]);
if (c != size -1)
ImGui::SameLine();
ImGui::PopID();
}
ImGui::PopID();
}
if (custom.Size == 0) {
custom.push_back(ImVec4(1,1,1,1));
custom.push_back(ImVec4(0.5f,0.5f,0.5f,1));
}
ImGui::Separator();
ImGui::BeginGroup();
bool custom_set_now = custom_set;
if (!custom_set_now)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.25f);
if (ImGui::Button("Custom", ImVec2(75, 0))) {
SetColormap(&custom[0], custom.Size);
BustItemCache();
custom_set = true;
}
if (!custom_set_now)
ImGui::PopStyleVar();
if (ImGui::Button("+", ImVec2((75 - ImGui::GetStyle().ItemSpacing.x)/2,0))) {
custom.push_back(ImVec4(0,0,0,1));
if (custom_set) {
SetColormap(&custom[0], custom.Size);
BustItemCache();
}
}
ImGui::SameLine();
if (ImGui::Button("-", ImVec2((75 - ImGui::GetStyle().ItemSpacing.x)/2,0)) && custom.Size > 1) {
custom.pop_back();
if (custom_set) {
SetColormap(&custom[0], custom.Size);
BustItemCache();
}
}
ImGui::EndGroup();
ImGui::SameLine();
ImGui::BeginGroup();
for (int c = 0; c < custom.Size; ++c) {
ImGui::PushID(c);
if (ImGui::ColorEdit4("##Col1", &custom[c].x, ImGuiColorEditFlags_NoInputs) && custom_set) {
SetColormap(&custom[0], custom.Size);
BustItemCache();
}
if ((c + 1) % 12 != 0)
ImGui::SameLine();
ImGui::PopID();
}
ImGui::EndGroup();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
void ShowUserGuide() {
ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes.");
ImGui::Indent();
ImGui::BulletText("Left click and drag on an axis to pan an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Scroll in the plot area to zoom both X any Y axes.");
ImGui::Indent();
ImGui::BulletText("Scroll on an axis to zoom an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Right click and drag to box select data.");
ImGui::Indent();
ImGui::BulletText("Hold Alt to expand box selection horizontally.");
ImGui::BulletText("Hold Shift to expand box selection vertically.");
ImGui::BulletText("Left click while box selecting to cancel the selection.");
ImGui::Unindent();
ImGui::BulletText("Double left click to fit all visible data.");
ImGui::Indent();
ImGui::BulletText("Double left click on an axis to fit the individual axis.");
ImGui::Unindent();
ImGui::BulletText("Double right click to open the full plot context menu.");
ImGui::Indent();
ImGui::BulletText("Double right click on an axis to open the axis context menu.");
ImGui::Unindent();
ImGui::BulletText("Click legend label icons to show/hide plot items.");
}
} // namespace ImPlot } // namespace ImPlot

View File

@ -74,25 +74,38 @@ enum ImPlotAxisFlags_ {
// Plot styling colors. // Plot styling colors.
enum ImPlotCol_ { enum ImPlotCol_ {
// item related colors
ImPlotCol_Line, // plot line/outline color (defaults to next unused color in current colormap) ImPlotCol_Line, // plot line/outline color (defaults to next unused color in current colormap)
ImPlotCol_Fill, // plot fill color for bars (defaults to the current line color) ImPlotCol_Fill, // plot fill color for bars (defaults to the current line color)
ImPlotCol_MarkerOutline, // marker outline color (defaults to the current line color) ImPlotCol_MarkerOutline, // marker outline color (defaults to the current line color)
ImPlotCol_MarkerFill, // marker fill color (defaults to the current line color) ImPlotCol_MarkerFill, // marker fill color (defaults to the current line color)
ImPlotCol_ErrorBar, // error bar color (defaults to ImGuiCol_Text) ImPlotCol_ErrorBar, // error bar color (defaults to ImGuiCol_Text)
// plot related colors
ImPlotCol_FrameBg, // plot frame background color (defaults to ImGuiCol_FrameBg) ImPlotCol_FrameBg, // plot frame background color (defaults to ImGuiCol_FrameBg)
ImPlotCol_PlotBg, // plot area background color (defaults to ImGuiCol_WindowBg) ImPlotCol_PlotBg, // plot area background color (defaults to ImGuiCol_WindowBg)
ImPlotCol_PlotBorder, // plot area border color (defaults to ImGuiCol_Text) ImPlotCol_PlotBorder, // plot area border color (defaults to 50% ImGuiCol_Text)
ImPlotCol_XAxis, // x-axis grid/label color (defaults to ImGuiCol_Text) ImPlotCol_LegendBg, // legend background color (defaults to ImGuiCol_PopupBg)
ImPlotCol_YAxis, // y-axis grid/label color (defaults to ImGuiCol_Text) ImPlotCol_LegendBorder, // legend border color (defaults to ImPlotCol_PlotBorder)
ImPlotCol_YAxis2, // 2nd y-axis grid/label color (defaults to ImGuiCol_Text) ImPlotCol_LegendText, // legend text color (defaults to ImPlotCol_InlayText)
ImPlotCol_YAxis3, // 3rd y-axis grid/label color (defaults to ImGuiCol_Text) ImPlotCol_TitleText, // plot title text color (defaults to ImGuiCol_Text)
ImPlotCol_InlayText, // color of text appearing inside of plots (defaults to ImGuiCol_Text)
ImPlotCol_XAxis, // x-axis label and tick lables color (defaults to ImGuiCol_Text)
ImPlotCol_XAxisGrid, // x-axis grid color (defaults to 25% ImPlotCol_XAxis)
ImPlotCol_YAxis, // y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid, // y-axis grid color (defaults to 25% ImPlotCol_YAxis)
ImPlotCol_YAxis2, // 2nd y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid2, // 2nd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis2)
ImPlotCol_YAxis3, // 3rd y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid3, // 3rd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis3)
ImPlotCol_Selection, // box-selection color (defaults to yellow) ImPlotCol_Selection, // box-selection color (defaults to yellow)
ImPlotCol_Query, // box-query color (defaults to green) ImPlotCol_Query, // box-query color (defaults to green)
ImPlotCol_Crosshairs, // crosshairs color (defaults to ImPlotCol_PlotBorder)
ImPlotCol_COUNT ImPlotCol_COUNT
}; };
// Plot styling variables. // Plot styling variables.
enum ImPlotStyleVar_ { enum ImPlotStyleVar_ {
// item styling variables
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
ImPlotStyleVar_Marker, // int, marker specification ImPlotStyleVar_Marker, // int, marker specification
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius") ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
@ -102,11 +115,24 @@ 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
// plot styling variables
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
ImPlotStyleVar_MajorTickLen, // ImVec2, major tick lengths for X and Y axes
ImPlotStyleVar_MinorTickLen, // ImVec2, minor tick lengths for X and Y axes
ImPlotStyleVar_MajorTickSize, // ImVec2, line thickness of major ticks
ImPlotStyleVar_MinorTickSize, // ImVec2, line thickness of minor ticks
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major grid lines
ImPlotStyleVar_MinorGridSize, // ImVec2, line thickness of minor grid lines
ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area and/or labels ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area and/or labels
ImPlotStyleVar_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from top-left of plot
ImPlotStyleVar_InfoPadding, // ImVec2, padding between plot edge and interior info text
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
ImPlotStyleVar_COUNT ImPlotStyleVar_COUNT
}; };
// Marker specifications. You can combine this with binary OR, e.g. ImPlotMarker_Circle | ImPlotMarker_Cross. // Marker specifications. You can combine these with binary OR, e.g. ImPlotMarker_Circle | ImPlotMarker_Cross.
enum ImPlotMarker_ { enum ImPlotMarker_ {
ImPlotMarker_None = 1 << 0, // no marker ImPlotMarker_None = 1 << 0, // no marker
ImPlotMarker_Circle = 1 << 1, // a circle marker ImPlotMarker_Circle = 1 << 1, // a circle marker
@ -127,12 +153,13 @@ enum ImPlotColormap_ {
ImPlotColormap_Dark = 1, // a.k.a. matplotlib "Set1" (n=9) ImPlotColormap_Dark = 1, // a.k.a. matplotlib "Set1" (n=9)
ImPlotColormap_Pastel = 2, // a.k.a. matplotlib "Pastel1" (n=9) ImPlotColormap_Pastel = 2, // a.k.a. matplotlib "Pastel1" (n=9)
ImPlotColormap_Paired = 3, // a.k.a. matplotlib "Paired" (n=12) ImPlotColormap_Paired = 3, // a.k.a. matplotlib "Paired" (n=12)
ImPlotColormap_Viridis = 4, // a.k.a. matplotlib "viridis" (n=11) ImPlotColormap_Deep = 4, // a.k.a. seaborn deep (n=10)
ImPlotColormap_Plasma = 5, // a.k.a. matplotlib "plasma" (n=11) ImPlotColormap_Viridis = 5, // a.k.a. matplotlib "viridis" (n=11)
ImPlotColormap_Hot = 6, // a.k.a. matplotlib/MATLAB "hot" (n=11) ImPlotColormap_Plasma = 6, // a.k.a. matplotlib "plasma" (n=11)
ImPlotColormap_Cool = 7, // a.k.a. matplotlib/MATLAB "cool" (n=11) ImPlotColormap_Hot = 7, // a.k.a. matplotlib/MATLAB "hot" (n=11)
ImPlotColormap_Pink = 8, // a.k.a. matplotlib/MATLAB "pink" (n=11) ImPlotColormap_Cool = 8, // a.k.a. matplotlib/MATLAB "cool" (n=11)
ImPlotColormap_Jet = 9, // a.k.a. MATLAB "jet" (n=11) ImPlotColormap_Pink = 9, // a.k.a. matplotlib/MATLAB "pink" (n=11)
ImPlotColormap_Jet = 10, // a.k.a. MATLAB "jet" (n=11)
ImPlotColormap_COUNT ImPlotColormap_COUNT
}; };
@ -166,7 +193,8 @@ struct ImPlotLimits {
// Plot style structure // Plot style structure
struct ImPlotStyle { struct ImPlotStyle {
float LineWeight; // = 1, line weight in pixels // item styling variables
float LineWeight; // = 1, item line weight in pixels
ImPlotMarker Marker; // = ImPlotMarker_None, marker specification ImPlotMarker Marker; // = ImPlotMarker_None, marker specification
float MarkerSize; // = 4, marker size in pixels (roughly the marker's "radius") float MarkerSize; // = 4, marker size in pixels (roughly the marker's "radius")
float MarkerWeight; // = 1, outline weight of markers in pixels float MarkerWeight; // = 1, outline weight of markers in pixels
@ -175,7 +203,20 @@ 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 // plot styling variables
float PlotBorderSize; // = 1, line thickness of border around plot area
float MinorAlpha; // = 0.25 alpha multiplier applied to minor axis grid lines
ImVec2 MajorTickLen; // = 10,10 major tick lengths for X and Y axes
ImVec2 MinorTickLen; // = 5,5 minor tick lengths for X and Y axes
ImVec2 MajorTickSize; // = 1,1 line thickness of major ticks
ImVec2 MinorTickSize; // = 1,1 line thickness of minor ticks
ImVec2 MajorGridSize; // = 1,1 line thickness of major grid lines
ImVec2 MinorGridSize; // = 1,1 line thickness of minor grid lines
ImVec2 PlotPadding; // = 8,8 padding between widget frame and plot area and/or labels
ImVec2 LabelPadding; // = 5,5 padding between axes labels, tick labels, and plot edge
ImVec2 LegendPadding; // = 10,10 legend padding from top-left of plot
ImVec2 InfoPadding; // = 10,10 padding between plot edge and interior info text
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
ImPlotStyle(); ImPlotStyle();
}; };
@ -317,9 +358,6 @@ void PlotText(const char* text, double x, double y, bool vertical = false, const
// Plot Utils // Plot Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Select which Y axis will be used for subsequent plot elements. The default is '0', or the first (left) Y axis.
void SetPlotYAxis(int y_axis);
// Set the axes range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the axes limits will be locked. // Set the axes range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the axes limits will be locked.
void SetNextPlotLimits(double x_min, double x_max, double y_min, double y_max, ImGuiCond cond = ImGuiCond_Once); void SetNextPlotLimits(double x_min, double x_max, double y_min, double y_max, ImGuiCond cond = ImGuiCond_Once);
// Set the X axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the X axis limits will be locked. // Set the X axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the X axis limits will be locked.
@ -337,6 +375,9 @@ void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** lab
void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0); void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0);
void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0); void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0);
// Select which Y axis will be used for subsequent plot elements. The default is '0', or the first (left) Y axis. Enable 2nd and 3rd axes with ImPlotFlags_YAxisX.
void SetPlotYAxis(int y_axis);
// Convert pixels to a position in the current plot's coordinate system. A negative y_axis uses the current value of SetPlotYAxis (0 initially). // Convert pixels to a position in the current plot's coordinate system. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
ImPlotPoint PixelsToPlot(const ImVec2& pix, int y_axis = -1); ImPlotPoint PixelsToPlot(const ImVec2& pix, int y_axis = -1);
ImPlotPoint PixelsToPlot(float x, float y, int y_axis = -1); ImPlotPoint PixelsToPlot(float x, float y, int y_axis = -1);
@ -371,7 +412,7 @@ ImPlotLimits GetPlotQuery(int y_axis = -1);
bool IsLegendEntryHovered(const char* label_id); bool IsLegendEntryHovered(const char* label_id);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Styling and Colormaps // Plot and Item Styling and Colormaps
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Provides access to plot style structure for permanant modifications to colors, sizes, etc. // Provides access to plot style structure for permanant modifications to colors, sizes, etc.
@ -415,6 +456,8 @@ ImVec4 GetColormapColor(int index);
ImVec4 LerpColormap(float t); ImVec4 LerpColormap(float t);
// Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired. Call between BeginPlot/EndPlot. // Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired. Call between BeginPlot/EndPlot.
ImVec4 NextColormapColor(); ImVec4 NextColormapColor();
const char* GetStyleColorName(ImPlotCol color);
// Returns a null terminated string name for a built-in colormap // Returns a null terminated string name for a built-in colormap
const char* GetColormapName(ImPlotColormap colormap); const char* GetColormapName(ImPlotColormap colormap);
@ -428,16 +471,21 @@ void ShowColormapScale(double scale_min, double scale_max, float height);
// Allows changing how keyboard/mouse interaction works. // Allows changing how keyboard/mouse interaction works.
ImPlotInputMap& GetInputMap(); ImPlotInputMap& GetInputMap();
// Shows ImPlot style editor block (not a window)
void ShowStyleEditor(ImPlotStyle* ref = NULL);
// Add basic help/info block (not a window): how to manipulate ImPlot as a end-user
void ShowUserGuide();
// Push clip rect for rendering to current plot area. // Push clip rect for rendering to current plot area.
void PushPlotClipRect(); void PushPlotClipRect();
// Pop plot clip rect. // Pop plot clip rect.
void PopPlotClipRect(); void PopPlotClipRect();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Demo // Demo (add implot_demo.cpp to your sources!)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Shows the ImPlot demo. Add implot_demo.cpp to your sources! // Shows the ImPlot demo.
void ShowDemoWindow(bool* p_open = NULL); void ShowDemoWindow(bool* p_open = NULL);
} // namespace ImPlot } // namespace ImPlot

View File

@ -45,6 +45,8 @@ ImPlotPoint Spiral(void*, int idx);
void Sparkline(const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col, const ImVec2& size); void Sparkline(const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col, const ImVec2& size);
// Example for Custom Plotters and Tooltips section. Plots a candlestick chart for financial data. See implementation 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));
// Sets style to mimic Seaborn
void StyleSeaborn();
} // namespace MyImPlot } // namespace MyImPlot
@ -54,7 +56,7 @@ namespace ImPlot {
/// NB: You don't ever need to typdef of define values for ImPlot. This /// NB: You don't ever need to typdef of define values for ImPlot. This
/// is only being done here for the sake of demoing both precision types. /// is only being done here for the sake of demoing both precision types.
// #define IMPLOT_DEMO_USE_DOUBLE #define IMPLOT_DEMO_USE_DOUBLE
#ifdef IMPLOT_DEMO_USE_DOUBLE #ifdef IMPLOT_DEMO_USE_DOUBLE
typedef double t_float; typedef double t_float;
typedef ImPlotPoint t_float2; typedef ImPlotPoint t_float2;
@ -73,17 +75,17 @@ typedef ImVec2 t_float2;
#define Fmod fmodf #define Fmod fmodf
#endif #endif
t_float RandomRange(t_float min, t_float max) { inline t_float RandomRange(t_float min, t_float max) {
t_float scale = rand() / (t_float) RAND_MAX; t_float scale = rand() / (t_float) RAND_MAX;
return min + scale * ( max - min ); return min + scale * ( max - min );
} }
// utility structure for realtime plot // utility structure for realtime plot
struct ScrollingData { struct ScrollingBuffer {
int MaxSize; int MaxSize;
int Offset; int Offset;
ImVector<t_float2> Data; ImVector<t_float2> Data;
ScrollingData() { ScrollingBuffer() {
MaxSize = 2000; MaxSize = 2000;
Offset = 0; Offset = 0;
Data.reserve(MaxSize); Data.reserve(MaxSize);
@ -105,10 +107,10 @@ struct ScrollingData {
}; };
// utility structure for realtime plot // utility structure for realtime plot
struct RollingData { struct RollingBuffer {
t_float Span; t_float Span;
ImVector<t_float2> Data; ImVector<t_float2> Data;
RollingData() { RollingBuffer() {
Span = 10.0f; Span = 10.0f;
Data.reserve(2000); Data.reserve(2000);
} }
@ -139,47 +141,46 @@ struct BenchmarkItem {
void ShowDemoWindow(bool* p_open) { void ShowDemoWindow(bool* p_open) {
static bool show_imgui_metrics = false; static bool show_imgui_metrics = false;
static bool show_imgui_style_editor = false; static bool show_imgui_style_editor = false;
if (show_imgui_metrics) { ImGui::ShowMetricsWindow(&show_imgui_metrics); } static bool show_implot_style_editor = false;
if (show_imgui_style_editor) { ImGui::Begin("Style Editor", &show_imgui_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } if (show_imgui_metrics) {
ImGui::ShowMetricsWindow(&show_imgui_metrics);
}
if (show_imgui_style_editor) {
ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor);
ImGui::ShowStyleEditor();
ImGui::End();
}
if (show_implot_style_editor) {
ImGui::SetNextWindowSize(ImVec2(415,762), ImGuiCond_Appearing);
ImGui::Begin("Style Editor (ImPlot)", &show_implot_style_editor);
ImPlot::ShowStyleEditor();
ImGui::End();
}
ImGui::SetNextWindowPos(ImVec2(50, 50), ImGuiCond_FirstUseEver); ImGui::SetNextWindowPos(ImVec2(50, 50), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(530, 750), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(530, 750), ImGuiCond_FirstUseEver);
ImGui::Begin("ImPlot Demo", p_open, ImGuiWindowFlags_MenuBar); ImGui::Begin("ImPlot Demo", p_open, ImGuiWindowFlags_MenuBar);
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("Tools")) { if (ImGui::BeginMenu("Tools")) {
ImGui::MenuItem("Metrics", NULL, &show_imgui_metrics); ImGui::MenuItem("Metrics (ImGui)", NULL, &show_imgui_metrics);
ImGui::MenuItem("Style Editor (ImGui)", NULL, &show_imgui_style_editor); ImGui::MenuItem("Style Editor (ImGui)", NULL, &show_imgui_style_editor);
ImGui::MenuItem("Style Editor (ImPlot)", NULL, &show_implot_style_editor);
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
ImGui::Text("ImPlot says hello. (%s)", IMPLOT_VERSION); ImGui::Text("ImPlot says hello. (%s)", IMPLOT_VERSION);
ImGui::Spacing();
if (ImGui::CollapsingHeader("Help")) { if (ImGui::CollapsingHeader("Help")) {
ImGui::Text("USER GUIDE:"); ImGui::Text("ABOUT THIS DEMO:");
ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes."); ImGui::BulletText("Sections below are demonstrating many aspects of the library.");
ImGui::Indent(); ImGui::BulletText("The \"Tools\" menu above gives access to: Style Editors (ImPlot/ImGui)\n"
ImGui::BulletText("Left click and drag on an axis to pan an individual axis."); "and Metrics (general purpose Dear ImGui debugging tool).");
ImGui::Unindent(); ImGui::Separator();
ImGui::BulletText("Scroll in the plot area to zoom both X any Y axes."); ImGui::Text("PROGRAMMER GUIDE:");
ImGui::Indent(); ImGui::BulletText("See the ShowDemoWindow() code in implot_demo.cpp. <- you are here!");
ImGui::BulletText("Scroll on an axis to zoom an individual axis."); ImGui::BulletText("By default, anti-aliased lines are turned OFF.");
ImGui::Unindent();
ImGui::BulletText("Right click and drag to box select data.");
ImGui::Indent();
ImGui::BulletText("Hold Alt to expand box selection horizontally.");
ImGui::BulletText("Hold Shift to expand box selection vertically.");
ImGui::BulletText("Left click while box selecting to cancel the selection.");
ImGui::Unindent();
ImGui::BulletText("Double left click to fit all visible data.");
ImGui::Indent();
ImGui::BulletText("Double left click on an axis to fit the individual axis.");
ImGui::Unindent();
ImGui::BulletText("Double right click to open the full plot context menu.");
ImGui::Indent();
ImGui::BulletText("Double right click on an axis to open the axis context menu.");
ImGui::Unindent();
ImGui::BulletText("Click legend label icons to show/hide plot items.");
ImGui::BulletText("IMPORTANT: By default, anti-aliased lines are turned OFF.");
ImGui::Indent(); ImGui::Indent();
ImGui::BulletText("Software AA can be enabled per plot with ImPlotFlags_AntiAliased."); ImGui::BulletText("Software AA can be enabled per plot with ImPlotFlags_AntiAliased.");
ImGui::BulletText("AA for demo plots can be enabled from the plot's context menu."); ImGui::BulletText("AA for demo plots can be enabled from the plot's context menu.");
@ -190,13 +191,17 @@ void ShowDemoWindow(bool* p_open) {
#else #else
ImGui::BulletText("The demo data precision is: float"); ImGui::BulletText("The demo data precision is: float");
#endif #endif
ImGui::Separator();
ImGui::Text("USER GUIDE:");
ShowUserGuide();
} }
t_float DEMO_TIME = (t_float)ImGui::GetTime();
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Line Plots")) { if (ImGui::CollapsingHeader("Line Plots")) {
static t_float xs1[1001], ys1[1001]; static t_float xs1[1001], ys1[1001];
for (int i = 0; i < 1001; ++i) { for (int i = 0; i < 1001; ++i) {
xs1[i] = i * 0.001f; xs1[i] = i * 0.001f;
ys1[i] = 0.5f + 0.5f * Sin(50 * xs1[i]); ys1[i] = 0.5f + 0.5f * Sin(50 * (xs1[i] + DEMO_TIME / 10));
} }
static t_float xs2[11], ys2[11]; static t_float xs2[11], ys2[11];
for (int i = 0; i < 11; ++i) { for (int i = 0; i < 11; ++i) {
@ -206,9 +211,10 @@ void ShowDemoWindow(bool* p_open) {
static float weight = ImPlot::GetStyle().LineWeight; static float weight = ImPlot::GetStyle().LineWeight;
ImGui::BulletText("Anti-aliasing can be enabled from the plot's context menu (see Help)."); ImGui::BulletText("Anti-aliasing can be enabled from the plot's context menu (see Help).");
ImGui::DragFloat("Line Weight", &weight, 0.05f, 1.0f, 5.0f, "%.2f px"); ImGui::DragFloat("Line Weight", &weight, 0.05f, 1.0f, 5.0f, "%.2f px");
if (ImPlot::BeginPlot("Line Plot", "x", "f(x)")) { if (ImPlot::BeginPlot("Line Plot", "x", "f(x)")) {
ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, weight); ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, weight);
ImPlot::PlotLine("0.5 + 0.5*sin(50*x)", xs1, ys1, 1001); ImPlot::PlotLine("sin(x)", xs1, ys1, 1001);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle);
ImPlot::PlotLine("x^2", xs2, ys2, 11); ImPlot::PlotLine("x^2", xs2, ys2, 11);
ImPlot::PopStyleVar(2); ImPlot::PopStyleVar(2);
@ -231,6 +237,7 @@ void ShowDemoWindow(bool* p_open) {
ImGui::Checkbox("Lines",&show_lines); ImGui::SameLine(); ImGui::Checkbox("Lines",&show_lines); ImGui::SameLine();
ImGui::Checkbox("Fills",&show_fills); ImGui::Checkbox("Fills",&show_fills);
ImGui::DragFloat("Reference",&fill_ref, 1, -100, 500); ImGui::DragFloat("Reference",&fill_ref, 1, -100, 500);
ImPlot::SetNextPlotLimits(0,100,0,500); ImPlot::SetNextPlotLimits(0,100,0,500);
if (ImPlot::BeginPlot("Stock Prices", "Days", "Price")) { if (ImPlot::BeginPlot("Stock Prices", "Days", "Price")) {
if (show_fills) { if (show_fills) {
@ -262,6 +269,7 @@ void ShowDemoWindow(bool* p_open) {
} }
static float alpha = 0.25f; static float alpha = 0.25f;
ImGui::DragFloat("Alpha",&alpha,0.01f,0,1); ImGui::DragFloat("Alpha",&alpha,0.01f,0,1);
if (ImPlot::BeginPlot("Shaded Plots")) { if (ImPlot::BeginPlot("Shaded Plots")) {
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, alpha); ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, alpha);
ImPlot::PlotShaded("Uncertain Data",xs,ys1,ys2,1001); ImPlot::PlotShaded("Uncertain Data",xs,ys1,ys2,1001);
@ -286,6 +294,7 @@ void ShowDemoWindow(bool* p_open) {
xs2[i] = 0.25f + 0.2f * ((t_float)rand() / (t_float)RAND_MAX); xs2[i] = 0.25f + 0.2f * ((t_float)rand() / (t_float)RAND_MAX);
ys2[i] = 0.75f + 0.2f * ((t_float)rand() / (t_float)RAND_MAX); ys2[i] = 0.75f + 0.2f * ((t_float)rand() / (t_float)RAND_MAX);
} }
if (ImPlot::BeginPlot("Scatter Plot", NULL, NULL)) { if (ImPlot::BeginPlot("Scatter Plot", NULL, NULL)) {
ImPlot::PlotScatter("Data 1", xs1, ys1, 100); ImPlot::PlotScatter("Data 1", xs1, ys1, 100);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 6); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 6);
@ -301,7 +310,11 @@ void ShowDemoWindow(bool* p_open) {
static const char* labels[] = {"S1","S2","S3","S4","S5","S6","S7","S8","S9","S10"}; static const char* labels[] = {"S1","S2","S3","S4","S5","S6","S7","S8","S9","S10"};
static const double positions[] = {0,1,2,3,4,5,6,7,8,9}; static const double positions[] = {0,1,2,3,4,5,6,7,8,9};
static bool horz = false; static bool horz = false;
static t_float midtm[10] = {83, 67, 23, 89, 83, 78, 91, 82, 85, 90};
static t_float final[10] = {80, 62, 56, 99, 55, 78, 88, 78, 90, 100};
static t_float grade[10] = {80, 69, 52, 92, 72, 78, 75, 76, 89, 95};
ImGui::Checkbox("Horizontal",&horz); ImGui::Checkbox("Horizontal",&horz);
if (horz) { if (horz) {
ImPlot::SetNextPlotLimits(0, 110, -0.5, 9.5, ImGuiCond_Always); ImPlot::SetNextPlotLimits(0, 110, -0.5, 9.5, ImGuiCond_Always);
ImPlot::SetNextPlotTicksY(positions, 10, labels); ImPlot::SetNextPlotTicksY(positions, 10, labels);
@ -310,10 +323,10 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::SetNextPlotLimits(-0.5, 9.5, 0, 110, ImGuiCond_Always); ImPlot::SetNextPlotLimits(-0.5, 9.5, 0, 110, ImGuiCond_Always);
ImPlot::SetNextPlotTicksX(positions, 10, labels); ImPlot::SetNextPlotTicksX(positions, 10, labels);
} }
if (ImPlot::BeginPlot("Bar Plot", horz ? "Score": "Student", horz ? "Student" : "Score")) { if (ImPlot::BeginPlot("Bar Plot", horz ? "Score": "Student", horz ? "Student" : "Score",
static t_float midtm[10] = {83, 67, 23, 89, 83, 78, 91, 82, 85, 90}; ImVec2(-1,0), ImPlotFlags_Default, ImPlotAxisFlags_Default,
static t_float final[10] = {80, 62, 56, 99, 55, 78, 88, 78, 90, 100}; horz ? ImPlotAxisFlags_Default | ImPlotAxisFlags_Invert : ImPlotAxisFlags_Default))
static t_float grade[10] = {80, 69, 52, 92, 72, 78, 75, 76, 89, 95}; {
if (horz) { if (horz) {
ImPlot::PlotBarsH("Midterm Exam", midtm, 10, 0.2f, -0.2f); ImPlot::PlotBarsH("Midterm Exam", midtm, 10, 0.2f, -0.2f);
ImPlot::PlotBarsH("Final Exam", final, 10, 0.2f, 0); ImPlot::PlotBarsH("Final Exam", final, 10, 0.2f, 0);
@ -329,18 +342,19 @@ void ShowDemoWindow(bool* p_open) {
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Error Bars")) { if (ImGui::CollapsingHeader("Error Bars")) {
t_float xs[5] = {1,2,3,4,5}; static t_float xs[5] = {1,2,3,4,5};
t_float bar[5] = {1,2,5,3,4}; static t_float bar[5] = {1,2,5,3,4};
t_float lin1[5] = {8,8,9,7,8}; static t_float lin1[5] = {8,8,9,7,8};
t_float lin2[5] = {6,7,6,9,6}; static t_float lin2[5] = {6,7,6,9,6};
t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; static t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f};
t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; static t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f};
t_float err3[5] = {0.09f, 0.14f, 0.09f, 0.12f, 0.16f}; static t_float err3[5] = {0.09f, 0.14f, 0.09f, 0.12f, 0.16f};
t_float err4[5] = {0.02f, 0.08f, 0.15f, 0.05f, 0.2f}; static t_float err4[5] = {0.02f, 0.08f, 0.15f, 0.05f, 0.2f};
static float size = ImPlot::GetStyle().ErrorBarSize; static float size = ImPlot::GetStyle().ErrorBarSize;
static float weight = ImPlot::GetStyle().ErrorBarWeight; static float weight = ImPlot::GetStyle().ErrorBarWeight;
ImGui::DragFloat("Error Bar Size", &size, 0.1f, 0, 10,"%.2f px"); ImGui::DragFloat("Error Bar Size", &size, 0.1f, 0, 10,"%.2f px");
ImGui::DragFloat("Error Bar Weight",&weight,0.01f,1,3,"%.2f px"); ImGui::DragFloat("Error Bar Weight",&weight,0.01f,1,3,"%.2f px");
ImPlot::SetNextPlotLimits(0, 6, 0, 10); ImPlot::SetNextPlotLimits(0, 6, 0, 10);
if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) { if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) {
ImPlot::PushStyleVar(ImPlotStyleVar_ErrorBarSize, size); ImPlot::PushStyleVar(ImPlotStyleVar_ErrorBarSize, size);
@ -349,17 +363,15 @@ void ShowDemoWindow(bool* p_open) {
// error bars can be grouped with the associated item by using the same label ID // error bars can be grouped with the associated item by using the same label ID
ImPlot::PlotErrorBars("Bar", xs, bar, err1, 5); ImPlot::PlotErrorBars("Bar", xs, bar, err1, 5);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3);
ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(1)); ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(1));
ImPlot::PlotErrorBars("Line1", xs, lin1, err1, err2, 5); ImPlot::PlotErrorBars("Line", xs, lin1, err1, err2, 5);
ImPlot::PlotLine("Line1", xs, lin1, 5); ImPlot::PlotLine("Line", xs, lin1, 5);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3);
ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(2)); ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(2));
ImPlot::PlotErrorBars("Line2", xs, lin2, err2, 5); ImPlot::PlotErrorBars("Scatter", xs, lin2, err2, 5);
ImPlot::PlotErrorBarsH("Line2", xs, lin2, err3, err4, 5); ImPlot::PlotErrorBarsH("Scatter", xs, lin2, err3, err4, 5);
ImPlot::PlotLine("Line2", xs, lin2, 5); ImPlot::PlotScatter("Scatter", xs, lin2, 5);
ImPlot::PopStyleVar(6); ImPlot::PopStyleVar(4);
ImPlot::PopStyleColor(2); ImPlot::PopStyleColor(2);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
@ -375,16 +387,20 @@ void ShowDemoWindow(bool* p_open) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox("Normalize", &normalize); ImGui::Checkbox("Normalize", &normalize);
} }
SetNextPlotLimits(0,1,0,1,ImGuiCond_Always);
ImPlot::SetNextPlotLimits(0,1,0,1,ImGuiCond_Always);
if (ImPlot::BeginPlot("##Pie1", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) { if (ImPlot::BeginPlot("##Pie1", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) {
ImPlot::PlotPieChart(labels1, data1, 4, 0.5f, 0.5f, 0.4f, normalize, "%.2f"); ImPlot::PlotPieChart(labels1, data1, 4, 0.5f, 0.5f, 0.4f, normalize, "%.2f");
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImGui::SameLine(); ImGui::SameLine();
ImPlot::PushColormap(ImPlotColormap_Pastel);
SetNextPlotLimits(0,1,0,1,ImGuiCond_Always);
static const char* labels2[] = {"A","B","C","D","E"}; static const char* labels2[] = {"A","B","C","D","E"};
static t_float data2[] = {1,1,2,3,5}; static t_float data2[] = {1,1,2,3,5};
ImPlot::PushColormap(ImPlotColormap_Pastel);
ImPlot::SetNextPlotLimits(0,1,0,1,ImGuiCond_Always);
if (ImPlot::BeginPlot("##Pie2", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) { if (ImPlot::BeginPlot("##Pie2", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) {
ImPlot::PlotPieChart(labels2, data2, 5, 0.5f, 0.5f, 0.4f, true, "%.0f", 180); ImPlot::PlotPieChart(labels2, data2, 5, 0.5f, 0.5f, 0.4f, true, "%.0f", 180);
ImPlot::EndPlot(); ImPlot::EndPlot();
@ -403,24 +419,25 @@ void ShowDemoWindow(bool* p_open) {
static float scale_min = 0; static float scale_min = 0;
static float scale_max = 6.3f; static float scale_max = 6.3f;
static t_float values2[100*100]; static t_float values2[100*100];
for (int i = 0; i < 100*100; ++i) { srand((unsigned int)(DEMO_TIME*1000000));
for (int i = 0; i < 100*100; ++i)
values2[i] = RandomRange(0,1); values2[i] = RandomRange(0,1);
} static const char* xlabels[] = {"C1","C2","C3","C4","C5","C6","C7"};
static const char* ylabels[] = {"R1","R2","R3","R4","R5","R6","R7"};
static ImPlotColormap map = ImPlotColormap_Viridis; static ImPlotColormap map = ImPlotColormap_Viridis;
if (ImGui::Button("Change Colormap",ImVec2(225,0))) if (ImGui::Button("Change Colormap",ImVec2(225,0)))
map = (map + 1) % ImPlotColormap_COUNT; map = (map + 1) % ImPlotColormap_COUNT;
ImPlot::PushColormap(map);
ImGui::SameLine(); ImGui::SameLine();
ImGui::LabelText("##Colormap Index", "%s", ImPlot::GetColormapName(map)); ImGui::LabelText("##Colormap Index", "%s", ImPlot::GetColormapName(map));
ImGui::SetNextItemWidth(225); ImGui::SetNextItemWidth(225);
ImGui::DragFloatRange2("Min / Max",&scale_min, &scale_max, 0.01f, -20, 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* ylabels[] = {"R1","R2","R3","R4","R5","R6","R7"};
ImPlot::PushColormap(map);
SetNextPlotTicksX(0 + 1.0/14.0, 1 - 1.0/14.0, 7, xlabels); SetNextPlotTicksX(0 + 1.0/14.0, 1 - 1.0/14.0, 7, xlabels);
SetNextPlotTicksY(1- 1.0/14.0, 0 + 1.0/14.0, 7, ylabels); SetNextPlotTicksY(1- 1.0/14.0, 0 + 1.0/14.0, 7, ylabels);
if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(225,225),0,axes_flags,axes_flags)) { if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(225,225),0,axes_flags,axes_flags)) {
ImPlot::PlotHeatmap("heat",values1[0],7,7,scale_min,scale_max); ImPlot::PlotHeatmap("heat",values1[0],7,7,scale_min,scale_max);
ImPlot::EndPlot(); ImPlot::EndPlot();
@ -428,9 +445,11 @@ void ShowDemoWindow(bool* p_open) {
ImGui::SameLine(); ImGui::SameLine();
ImPlot::ShowColormapScale(scale_min, scale_max, 225); ImPlot::ShowColormapScale(scale_min, scale_max, 225);
ImPlot::PopColormap(); ImPlot::PopColormap();
ImGui::SameLine(); ImGui::SameLine();
static ImVec4 gray[2] = {ImVec4(0,0,0,1), ImVec4(1,1,1,1)}; static ImVec4 gray[2] = {ImVec4(0,0,0,1), ImVec4(1,1,1,1)};
ImPlot::PushColormap(&gray[0], 2); ImPlot::PushColormap(gray, 2);
ImPlot::SetNextPlotLimits(-1,1,-1,1); ImPlot::SetNextPlotLimits(-1,1,-1,1);
if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(225,225),ImPlotFlags_ContextMenu,0,0)) { if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(225,225),ImPlotFlags_ContextMenu,0,0)) {
ImPlot::PlotHeatmap("heat1",values2,100,100,0,1,NULL); ImPlot::PlotHeatmap("heat1",values2,100,100,0,1,NULL);
@ -443,29 +462,26 @@ void ShowDemoWindow(bool* p_open) {
if (ImGui::CollapsingHeader("Realtime Plots")) { if (ImGui::CollapsingHeader("Realtime Plots")) {
ImGui::BulletText("Move your mouse to change the data!"); ImGui::BulletText("Move your mouse to change the data!");
ImGui::BulletText("This example assumes 60 FPS. Higher FPS requires larger buffer size."); ImGui::BulletText("This example assumes 60 FPS. Higher FPS requires larger buffer size.");
static bool paused = false; static ScrollingBuffer sdata1, sdata2;
static ScrollingData sdata1, sdata2; static RollingBuffer rdata1, rdata2;
static RollingData rdata1, rdata2;
ImVec2 mouse = ImGui::GetMousePos(); ImVec2 mouse = ImGui::GetMousePos();
static t_float t = 0; static t_float t = 0;
if (!paused) {
t += ImGui::GetIO().DeltaTime; t += ImGui::GetIO().DeltaTime;
sdata1.AddPoint(t, mouse.x * 0.0005f); sdata1.AddPoint(t, mouse.x * 0.0005f);
rdata1.AddPoint(t, mouse.x * 0.0005f); rdata1.AddPoint(t, mouse.x * 0.0005f);
sdata2.AddPoint(t, mouse.y * 0.0005f); sdata2.AddPoint(t, mouse.y * 0.0005f);
rdata2.AddPoint(t, mouse.y * 0.0005f); rdata2.AddPoint(t, mouse.y * 0.0005f);
}
static float history = 10.0f; static float history = 10.0f;
ImGui::SliderFloat("History",&history,1,30,"%.1f s"); ImGui::SliderFloat("History",&history,1,30,"%.1f s");
rdata1.Span = history; rdata1.Span = history;
rdata2.Span = history; rdata2.Span = history;
ImPlot::SetNextPlotLimitsX(t - history, t, paused ? ImGuiCond_Once : ImGuiCond_Always);
static int rt_axis = ImPlotAxisFlags_Default & ~ImPlotAxisFlags_TickLabels; static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_Default & ~ImPlotAxisFlags_TickLabels;
ImPlot::SetNextPlotLimitsX(t - history, t, ImGuiCond_Always);
if (ImPlot::BeginPlot("##Scrolling", NULL, NULL, ImVec2(-1,150), ImPlotFlags_Default, rt_axis, rt_axis | ImPlotAxisFlags_LockMin)) { if (ImPlot::BeginPlot("##Scrolling", NULL, NULL, ImVec2(-1,150), ImPlotFlags_Default, rt_axis, rt_axis | ImPlotAxisFlags_LockMin)) {
ImPlot::PlotLine("Data 1", &sdata1.Data[0], sdata1.Data.size(), sdata1.Offset); ImPlot::PlotShaded("Data 1", &sdata1.Data[0].x, &sdata1.Data[0].y, sdata1.Data.size(), 0, sdata1.Offset, 2 * sizeof(t_float));
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f); ImPlot::PlotLine("Data 2", &sdata2.Data[0], sdata2.Data.size(), sdata2.Offset);
ImPlot::PlotShaded("Data 2", &sdata2.Data[0].x, &sdata2.Data[0].y, sdata2.Data.size(), 0, sdata2.Offset, 2 * sizeof(t_float));
ImPlot::PopStyleVar();
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::SetNextPlotLimitsX(0, history, ImGuiCond_Always); ImPlot::SetNextPlotLimitsX(0, history, ImGuiCond_Always);
@ -479,76 +495,45 @@ void ShowDemoWindow(bool* p_open) {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Colormaps, Markers, and Text")) { if (ImGui::CollapsingHeader("Markers and Text")) {
static ImPlotColormap map = ImPlotColormap_Default;
if (ImGui::Button("Change Colormap##2"))
map = (map + 1) % ImPlotColormap_COUNT;
ImGui::SameLine();
ImGui::LabelText("##Colormap Index", "%s", ImPlot::GetColormapName(map));
static float mk_size = ImPlot::GetStyle().MarkerSize; static float mk_size = ImPlot::GetStyle().MarkerSize;
static float mk_weight = ImPlot::GetStyle().MarkerWeight; static float mk_weight = ImPlot::GetStyle().MarkerWeight;
ImGui::DragFloat("Marker Size",&mk_size,0.1f,2.0f,10.0f,"%.2f px"); ImGui::DragFloat("Marker Size",&mk_size,0.1f,2.0f,10.0f,"%.2f px");
ImGui::DragFloat("Marker Weight", &mk_weight,0.05f,0.5f,3.0f,"%.2f px"); ImGui::DragFloat("Marker Weight", &mk_weight,0.05f,0.5f,3.0f,"%.2f px");
ImGui::PushID(map); // NB: This is merely a workaround so that the demo can cycle color maps. You wouldn't need to do this in your own code!
ImPlot::SetNextPlotLimits(0, 10, 0, 12); ImPlot::SetNextPlotLimits(0, 10, 0, 12);
if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) { if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) {
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, mk_size);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, mk_weight);
ImPlot::PushColormap(map);
t_float xs[2] = {1,4}; t_float xs[2] = {1,4};
t_float ys[2] = {10,11}; t_float ys[2] = {10,11};
// filled
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle);
ImPlot::PlotLine("Circle##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ys[0]--; ys[1]--;
ImPlot::PlotLine("Square##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Diamond); ys[0]--; ys[1]--;
ImPlot::PlotLine("Diamond##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Up); ys[0]--; ys[1]--;
ImPlot::PlotLine("Up##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Down); ys[0]--; ys[1]--;
ImPlot::PlotLine("Down##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Left); ys[0]--; ys[1]--;
ImPlot::PlotLine("Left##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Right); ys[0]--; ys[1]--;
ImPlot::PlotLine("Right##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Cross); ys[0]--; ys[1]--;
ImPlot::PlotLine("Cross##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Plus); ys[0]--; ys[1]--;
ImPlot::PlotLine("Plus##Fill", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Asterisk); ys[0]--; ys[1]--;
ImPlot::PlotLine("Asterisk##Fill", xs, ys, 2);
ImPlot::PopStyleVar(10);
xs[0] = 6; xs[1] = 9; ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, mk_size);
ys[0] = 10; ys[1] = 11; ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, mk_weight);
// filled markers
for (int i = 1; i < 11; ++i) {
ImPlotMarker marker = 1 << i; // e.g. ImPlotMarkerCircle = 1 << 1 (see implot.h)
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, marker);
ImGui::PushID(i);
ImPlot::PlotLine("##Filled", xs, ys, 2);
ImGui::PopID();
ImPlot::PopStyleVar();
ys[0]--; ys[1]--;
}
xs[0] = 6; xs[1] = 9; ys[0] = 10; ys[1] = 11;
// open markers
ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(0,0,0,0)); ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(0,0,0,0));
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle); for (int i = 1; i < 11; ++i) {
ImPlot::PlotLine("Circle", xs, ys, 2); ImPlotMarker marker = 1 << i; // e.g. ImPlotMarkerCircle = 1 << 1 (see implot.h)
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ys[0]--; ys[1]--; ImPlot::PushStyleVar(ImPlotStyleVar_Marker, marker);
ImPlot::PlotLine("Square", xs, ys, 2); ImGui::PushID(i);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Diamond); ys[0]--; ys[1]--; ImPlot::PlotLine("##Open", xs, ys, 2);
ImPlot::PlotLine("Diamond", xs, ys, 2); ImGui::PopID();
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Up); ys[0]--; ys[1]--; ImPlot::PopStyleVar();
ImPlot::PlotLine("Up", xs, ys, 2); ys[0]--; ys[1]--;
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Down); ys[0]--; ys[1]--; }
ImPlot::PlotLine("Down", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Left); ys[0]--; ys[1]--;
ImPlot::PlotLine("Left", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Right); ys[0]--; ys[1]--;
ImPlot::PlotLine("Right", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Cross); ys[0]--; ys[1]--;
ImPlot::PlotLine("Cross", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Plus); ys[0]--; ys[1]--;
ImPlot::PlotLine("Plus", xs, ys, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Asterisk); ys[0]--; ys[1]--;
ImPlot::PlotLine("Asterisk", xs, ys, 2);
ImPlot::PopStyleColor(); ImPlot::PopStyleColor();
ImPlot::PopStyleVar(10); ImPlot::PopStyleVar(2);
xs[0] = 5; xs[1] = 5;
ys[0] = 1; ys[1] = 11;
xs[0] = 5; xs[1] = 5; ys[0] = 1; ys[1] = 11;
ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 2); ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 2);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 8); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 8);
ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, 2); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, 2);
@ -557,7 +542,7 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(1,1,1,1)); ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(1,1,1,1));
ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0,0,0,1)); ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0,0,0,1));
ImPlot::PlotLine("Circle|Cross", xs, ys, 2); ImPlot::PlotLine("Circle|Cross", xs, ys, 2);
ImPlot::PopStyleVar(6); ImPlot::PopStyleVar(4);
ImPlot::PopStyleColor(3); ImPlot::PopStyleColor(3);
ImPlot::PlotText("Filled Markers", 2.5f, 6.0f); ImPlot::PlotText("Filled Markers", 2.5f, 6.0f);
@ -567,15 +552,11 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::PlotText("Fancy Markers", 5.0f, 6.0f, true); ImPlot::PlotText("Fancy Markers", 5.0f, 6.0f, true);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImPlot::PopColormap();
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImGui::PopID();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Log Scale")) { if (ImGui::CollapsingHeader("Log Scale")) {
ImGui::BulletText("Open the plot context menu (double right click) to change scales.");
static t_float xs[1001], ys1[1001], ys2[1001], ys3[1001]; static t_float xs[1001], ys1[1001], ys2[1001], ys3[1001];
for (int i = 0; i < 1001; ++i) { for (int i = 0; i < 1001; ++i) {
xs[i] = i*0.1f; xs[i] = i*0.1f;
@ -583,6 +564,8 @@ void ShowDemoWindow(bool* p_open) {
ys2[i] = Log(xs[i]); ys2[i] = Log(xs[i]);
ys3[i] = Pow(10.0f, xs[i]); ys3[i] = Pow(10.0f, xs[i]);
} }
ImGui::BulletText("Open the plot context menu (double right click) to change scales.");
ImPlot::SetNextPlotLimits(0.1, 100, 0, 10); ImPlot::SetNextPlotLimits(0.1, 100, 0, 10);
if (ImPlot::BeginPlot("Log Plot", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Default, ImPlotAxisFlags_Default | ImPlotAxisFlags_LogScale )) { if (ImPlot::BeginPlot("Log Plot", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Default, ImPlotAxisFlags_Default | ImPlotAxisFlags_LogScale )) {
ImPlot::PlotLine("f(x) = x", xs, xs, 1001); ImPlot::PlotLine("f(x) = x", xs, xs, 1001);
@ -594,29 +577,9 @@ void ShowDemoWindow(bool* p_open) {
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Multiple Y-Axes")) { if (ImGui::CollapsingHeader("Multiple Y-Axes")) {
static ImVec4 txt_col = ImGui::GetStyle().Colors[ImGuiCol_Text];
txt_col.w = 0.25f;
static ImVec4 y1_col = txt_col;
static ImVec4 y2_col = txt_col;
static ImVec4 y3_col = txt_col;
static t_float xs[1001], xs2[1001], ys1[1001], ys2[1001], ys3[1001]; static t_float xs[1001], xs2[1001], ys1[1001], ys2[1001], ys3[1001];
static bool y2_axis = true;
static bool y3_axis = true;
ImGui::Checkbox("Y-Axis 2", &y2_axis);
ImGui::SameLine();
ImGui::Checkbox("Y-Axis 3", &y3_axis);
ImGui::SameLine();
ImGui::ColorEdit4("##Col1", &y1_col.x, ImGuiColorEditFlags_NoInputs);
ImGui::SameLine();
ImGui::ColorEdit4("##Col2", &y2_col.x, ImGuiColorEditFlags_NoInputs);
ImGui::SameLine();
ImGui::ColorEdit4("##Col3", &y3_col.x, ImGuiColorEditFlags_NoInputs);
// you can fit axes programatically
ImGui::SameLine(); if (ImGui::Button("Fit X")) ImPlot::FitNextPlotAxes(true, false, false, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y")) ImPlot::FitNextPlotAxes(false, true, false, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y2")) ImPlot::FitNextPlotAxes(false, false, true, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y3")) ImPlot::FitNextPlotAxes(false, false, false, true);
for (int i = 0; i < 1001; ++i) { for (int i = 0; i < 1001; ++i) {
xs[i] = (i*0.1f); xs[i] = (i*0.1f);
ys1[i] = Sin(xs[i]) * 3 + 1; ys1[i] = Sin(xs[i]) * 3 + 1;
@ -624,36 +587,44 @@ void ShowDemoWindow(bool* p_open) {
ys3[i] = Sin(xs[i]+0.5f) * 100 + 200; ys3[i] = Sin(xs[i]+0.5f) * 100 + 200;
xs2[i] = xs[i] + 10.0f; xs2[i] = xs[i] + 10.0f;
} }
static bool y2_axis = true;
static bool y3_axis = true;
ImGui::Checkbox("Y-Axis 2", &y2_axis);
ImGui::SameLine();
ImGui::Checkbox("Y-Axis 3", &y3_axis);
ImGui::SameLine();
// you can fit axes programatically
ImGui::SameLine(); if (ImGui::Button("Fit X")) ImPlot::FitNextPlotAxes(true, false, false, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y")) ImPlot::FitNextPlotAxes(false, true, false, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y2")) ImPlot::FitNextPlotAxes(false, false, true, false);
ImGui::SameLine(); if (ImGui::Button("Fit Y3")) ImPlot::FitNextPlotAxes(false, false, false, true);
ImPlot::SetNextPlotLimits(0.1, 100, 0, 10); ImPlot::SetNextPlotLimits(0.1, 100, 0, 10);
ImPlot::SetNextPlotLimitsY(0, 1, ImGuiCond_Once, 1); ImPlot::SetNextPlotLimitsY(0, 1, ImGuiCond_Once, 1);
ImPlot::SetNextPlotLimitsY(0, 300, ImGuiCond_Once, 2); ImPlot::SetNextPlotLimitsY(0, 300, ImGuiCond_Once, 2);
ImPlot::PushStyleColor(ImPlotCol_YAxis, y1_col);
ImPlot::PushStyleColor(ImPlotCol_YAxis2, y2_col);
ImPlot::PushStyleColor(ImPlotCol_YAxis3, y3_col);
if (ImPlot::BeginPlot("Multi-Axis Plot", NULL, NULL, ImVec2(-1,0), if (ImPlot::BeginPlot("Multi-Axis Plot", NULL, NULL, ImVec2(-1,0),
ImPlotFlags_Default | ImPlotFlags_Default |
(y2_axis ? ImPlotFlags_YAxis2 : 0) | (y2_axis ? ImPlotFlags_YAxis2 : 0) |
(y3_axis ? ImPlotFlags_YAxis3 : 0))) { (y3_axis ? ImPlotFlags_YAxis3 : 0))) {
ImPlot::PlotLine("f(x) = x", xs, xs, 1001); ImPlot::PlotLine("f(x) = x", xs, xs, 1001);
ImPlot::PlotLine("f(x) = sin(x)*3+1", xs, ys1, 1001); ImPlot::PlotLine("f(x) = sin(x)*3+1", xs, ys1, 1001);
if (y2_axis) { if (y2_axis) {
ImPlot::SetPlotYAxis(1); ImPlot::SetPlotYAxis(1);
ImPlot::PlotLine("f(x) = cos(x)*.2+.5 (Y2)", xs, ys2, 1001); ImPlot::PlotLine("f(x) = cos(x)*.2+.5 (Y2)", xs, ys2, 1001);
} }
if (y3_axis) { if (y3_axis) {
ImPlot::SetPlotYAxis(2); ImPlot::SetPlotYAxis(2);
ImPlot::PlotLine("f(x) = sin(x+.5)*100+200 (Y3)", xs2, ys3, 1001); ImPlot::PlotLine("f(x) = sin(x+.5)*100+200 (Y3)", xs2, ys3, 1001);
} }
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::PopStyleColor(3);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Querying")) { if (ImGui::CollapsingHeader("Querying")) {
static ImVector<t_float2> data;
static ImPlotLimits range, query;
ImGui::BulletText("Ctrl + click in the plot area to draw points."); ImGui::BulletText("Ctrl + click in the plot area to draw points.");
ImGui::BulletText("Middle click (or Ctrl + right click) and drag to create a query rect."); ImGui::BulletText("Middle click (or Ctrl + right click) and drag to create a query rect.");
ImGui::Indent(); ImGui::Indent();
@ -661,12 +632,10 @@ void ShowDemoWindow(bool* p_open) {
ImGui::BulletText("Hold Shift to expand query vertically."); ImGui::BulletText("Hold Shift to expand query vertically.");
ImGui::BulletText("The query rect can be dragged after it's created."); ImGui::BulletText("The query rect can be dragged after it's created.");
ImGui::Unindent(); ImGui::Unindent();
static ImVector<t_float2> data;
ImPlotLimits range, query;
if (ImPlot::BeginPlot("##Drawing", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Default | ImPlotFlags_Query, ImPlotAxisFlags_GridLines, ImPlotAxisFlags_GridLines)) { if (ImPlot::BeginPlot("##Drawing", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Default | ImPlotFlags_Query, ImPlotAxisFlags_GridLines, ImPlotAxisFlags_GridLines)) {
if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyCtrl) { if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyCtrl) {
ImPlotPoint pt = ImPlot::GetPlotMousePos(); ImPlotPoint pt = ImPlot::GetPlotMousePos();
data.push_back(t_float2((t_float)pt.x, (t_float)pt.y)); data.push_back(t_float2((t_float)pt.x, (t_float)pt.y));
} }
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Diamond); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Diamond);
@ -716,9 +685,9 @@ void ShowDemoWindow(bool* p_open) {
} }
ImGui::BulletText("Query the first plot to render a subview in the second plot (see above for controls)."); ImGui::BulletText("Query the first plot to render a subview in the second plot (see above for controls).");
ImPlot::SetNextPlotLimits(0,0.01,-1,1); ImPlot::SetNextPlotLimits(0,0.01,-1,1);
ImPlotAxisFlags flgs = ImPlotAxisFlags_Default & ~ImPlotAxisFlags_TickLabels; ImPlotAxisFlags flags = ImPlotAxisFlags_Default & ~ImPlotAxisFlags_TickLabels;
ImPlotLimits query; ImPlotLimits query;
if (ImPlot::BeginPlot("##View1",NULL,NULL,ImVec2(-1,150), ImPlotFlags_Default | ImPlotFlags_Query, flgs, flgs)) { if (ImPlot::BeginPlot("##View1",NULL,NULL,ImVec2(-1,150), ImPlotFlags_Default | ImPlotFlags_Query, flags, flags)) {
ImPlot::PlotLine("Signal 1", x_data, y_data1, 512); ImPlot::PlotLine("Signal 1", x_data, y_data1, 512);
ImPlot::PlotLine("Signal 2", x_data, y_data2, 512); ImPlot::PlotLine("Signal 2", x_data, y_data2, 512);
ImPlot::PlotLine("Signal 3", x_data, y_data3, 512); ImPlot::PlotLine("Signal 3", x_data, y_data3, 512);
@ -736,10 +705,10 @@ void ShowDemoWindow(bool* p_open) {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Drag and Drop")) { if (ImGui::CollapsingHeader("Drag and Drop")) {
const int K_CHANNELS = 9; const int K_CHANNELS = 9;
srand((int)(10000000 * ImGui::GetTime())); srand((int)(10000000 * DEMO_TIME));
static bool paused = false; static bool paused = false;
static bool init = true; static bool init = true;
static ScrollingData data[K_CHANNELS]; static ScrollingBuffer data[K_CHANNELS];
static bool show[K_CHANNELS]; static bool show[K_CHANNELS];
static int yAxis[K_CHANNELS]; static int yAxis[K_CHANNELS];
if (init) { if (init) {
@ -772,7 +741,7 @@ void ShowDemoWindow(bool* p_open) {
} }
ImGui::EndGroup(); ImGui::EndGroup();
ImGui::SameLine(); ImGui::SameLine();
srand((unsigned int)ImGui::GetTime()*10000000); srand((unsigned int)DEMO_TIME*10000000);
static t_float t = 0; static t_float t = 0;
if (!paused) { if (!paused) {
t += ImGui::GetIO().DeltaTime; t += ImGui::GetIO().DeltaTime;
@ -810,8 +779,8 @@ void ShowDemoWindow(bool* p_open) {
static bool paused = false; static bool paused = false;
#define K_PLOT_DIGITAL_CH_COUNT 4 #define K_PLOT_DIGITAL_CH_COUNT 4
#define K_PLOT_ANALOG_CH_COUNT 4 #define K_PLOT_ANALOG_CH_COUNT 4
static ScrollingData dataDigital[K_PLOT_DIGITAL_CH_COUNT]; static ScrollingBuffer dataDigital[K_PLOT_DIGITAL_CH_COUNT];
static ScrollingData dataAnalog[K_PLOT_ANALOG_CH_COUNT]; static ScrollingBuffer dataAnalog[K_PLOT_ANALOG_CH_COUNT];
static bool showDigital[K_PLOT_DIGITAL_CH_COUNT]; static bool showDigital[K_PLOT_DIGITAL_CH_COUNT];
static bool showAnalog[K_PLOT_ANALOG_CH_COUNT]; static bool showAnalog[K_PLOT_ANALOG_CH_COUNT];
@ -829,12 +798,6 @@ void ShowDemoWindow(bool* p_open) {
} }
if (ImGui::Button(paused ? "Resume" : "Pause", ImVec2(100,0))) if (ImGui::Button(paused ? "Resume" : "Pause", ImVec2(100,0)))
paused = !paused; paused = !paused;
ImGui::SetNextItemWidth(100);
static float bitHeight = 8;
ImGui::DragFloat("##Bit Height", &bitHeight, 1, 5, 25, "%.0f px");
ImGui::SetNextItemWidth(100);
static float bitGap = 4;
ImGui::DragFloat("##Bit Gap", &bitGap, 1, 2, 20, "%.0f px");
for (int i = 0; i < K_PLOT_DIGITAL_CH_COUNT; ++i) { for (int i = 0; i < K_PLOT_DIGITAL_CH_COUNT; ++i) {
char label[32]; char label[32];
sprintf(label, "digital_%d", i); sprintf(label, "digital_%d", i);
@ -894,10 +857,7 @@ void ShowDemoWindow(bool* p_open) {
if (showDigital[i] && dataDigital[i].Data.size() > 0) { if (showDigital[i] && dataDigital[i].Data.size() > 0) {
char label[32]; char label[32];
sprintf(label, "digital_%d", i); sprintf(label, "digital_%d", i);
ImPlot::PushStyleVar(ImPlotStyleVar_DigitalBitHeight, bitHeight);
ImPlot::PushStyleVar(ImPlotStyleVar_DigitalBitGap, bitGap);
ImPlot::PlotDigital(label, &dataDigital[i].Data[0].x, &dataDigital[i].Data[0].y, dataDigital[i].Data.size(), dataDigital[i].Offset, 2 * sizeof(t_float)); ImPlot::PlotDigital(label, &dataDigital[i].Data[0].x, &dataDigital[i].Data[0].y, dataDigital[i].Data.size(), dataDigital[i].Offset, 2 * sizeof(t_float));
ImPlot::PopStyleVar(2);
} }
} }
for (int i = 0; i < K_PLOT_ANALOG_CH_COUNT; ++i) { for (int i = 0; i < K_PLOT_ANALOG_CH_COUNT; ++i) {
@ -942,9 +902,7 @@ void ShowDemoWindow(bool* p_open) {
ImGui::TableSetupColumn("EMG Signal"); ImGui::TableSetupColumn("EMG Signal");
ImGui::TableAutoHeaders(); ImGui::TableAutoHeaders();
ImPlot::PushColormap(ImPlotColormap_Cool); ImPlot::PushColormap(ImPlotColormap_Cool);
for (int row = 0; row < 10; row++) {
for (int row = 0; row < 10; row++)
{
ImGui::TableNextRow(); ImGui::TableNextRow();
static float data[100]; static float data[100];
srand(row); srand(row);
@ -1048,33 +1006,22 @@ void ShowDemoWindow(bool* p_open) {
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Custom Styles")) { if (ImGui::CollapsingHeader("Custom Styles")) {
static ImVec4 my_map[3] = { ImPlot::PushColormap(ImPlotColormap_Deep);
ImVec4(0.000f, 0.980f, 0.604f, 1.0f), // normally you wouldn't change the entire style each frame
ImVec4(0.996f, 0.278f, 0.380f, 1.0f), ImPlotStyle backup = ImPlot::GetStyle();
ImVec4(0.1176470593f, 0.5647059083f, 1.0f, 1.0f), MyImPlot::StyleSeaborn();
}; ImPlot::SetNextPlotLimits(-0.5f, 9.5f, 0, 10);
ImPlot::PushColormap(my_map, 3); if (ImPlot::BeginPlot("seaborn style", "x-axis", "y-axis")) {
ImPlot::PushStyleColor(ImPlotCol_FrameBg, IM_COL32(32,51,77,255));
ImPlot::PushStyleColor(ImPlotCol_PlotBg, ImVec4(0,0,0,0));
ImPlot::PushStyleColor(ImPlotCol_PlotBorder, ImVec4(0,0,0,0));
ImPlot::PushStyleColor(ImPlotCol_XAxis, IM_COL32(192, 192, 192, 192));
ImPlot::PushStyleColor(ImPlotCol_YAxis, IM_COL32(192, 192, 192, 192));
ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 2);
ImPlot::SetNextPlotLimits(-0.5f, 9.5f, -0.5f, 9.5f);
if (ImPlot::BeginPlot("##Custom", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Default & ~ImPlotFlags_Legend, 0)) {
t_float lin[10] = {8,8,9,7,8,8,8,9,7,8}; t_float lin[10] = {8,8,9,7,8,8,8,9,7,8};
t_float bar[10] = {1,2,5,3,4,1,2,5,3,4}; t_float bar[10] = {1,2,5,3,4,1,2,5,3,4};
t_float dot[10] = {7,6,6,7,8,5,6,5,8,7}; t_float dot[10] = {7,6,6,7,8,5,6,5,8,7};
ImPlot::PlotBars("Bar", bar, 10, 0.5f); ImPlot::PlotBars("Bars", bar, 10, 0.5f);
ImPlot::PlotLine("Line", lin, 10); ImPlot::PlotLine("Line", lin, 10);
ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 0); ImPlot::NextColormapColor(); // skip green
ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ImPlot::PlotScatter("Scatter", dot, 10);
ImPlot::PlotLine("Dot", dot, 10);
ImPlot::PopStyleVar(2);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::PopStyleColor(5); ImPlot::GetStyle() = backup;
ImPlot::PopStyleVar();
ImPlot::PopColormap(); ImPlot::PopColormap();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1183,6 +1130,60 @@ void Sparkline(const char* id, const float* values, int count, float min_v, floa
ImPlot::PopStyleVar(); ImPlot::PopStyleVar();
} }
void StyleSeaborn() {
ImPlotStyle& style = ImPlot::GetStyle();
ImVec4* colors = style.Colors;
colors[ImPlotCol_Line] = IMPLOT_COL_AUTO;
colors[ImPlotCol_Fill] = IMPLOT_COL_AUTO;
colors[ImPlotCol_MarkerOutline] = IMPLOT_COL_AUTO;
colors[ImPlotCol_MarkerFill] = IMPLOT_COL_AUTO;
colors[ImPlotCol_ErrorBar] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImPlotCol_PlotBg] = ImVec4(0.93f, 0.93f, 0.98f, 1.00f);
colors[ImPlotCol_PlotBorder] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImPlotCol_LegendBg] = ImVec4(0.93f, 0.93f, 0.98f, 1.00f);
colors[ImPlotCol_LegendBorder] = ImVec4(0.80f, 0.81f, 0.85f, 1.00f);
colors[ImPlotCol_LegendText] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_TitleText] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_InlayText] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_XAxis] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_XAxisGrid] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImPlotCol_YAxis] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_YAxisGrid] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImPlotCol_YAxis2] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_YAxisGrid2] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImPlotCol_YAxis3] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImPlotCol_YAxisGrid3] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImPlotCol_Selection] = ImVec4(1.00f, 0.65f, 0.00f, 1.00f);
colors[ImPlotCol_Query] = ImVec4(0.23f, 0.10f, 0.64f, 1.00f);
colors[ImPlotCol_Crosshairs] = ImVec4(0.23f, 0.10f, 0.64f, 0.50f);
style.LineWeight = 1.5;
style.Marker = ImPlotMarker_None;
style.MarkerSize = 4;
style.MarkerWeight = 1;
style.FillAlpha = 1.0f;
style.ErrorBarSize = 5;
style.ErrorBarWeight = 1.5f;
style.DigitalBitHeight = 8;
style.DigitalBitGap = 4;
style.PlotBorderSize = 0;
style.MinorAlpha = 1.0f;
style.MajorTickLen = ImVec2(0,0);
style.MinorTickLen = ImVec2(0,0);
style.MajorTickSize = ImVec2(0,0);
style.MinorTickSize = ImVec2(0,0);
style.MajorGridSize = ImVec2(1.2f,1.2f);
style.MinorGridSize = ImVec2(1.2f,1.2f);
style.PlotPadding = ImVec2(12,12);
style.LabelPadding = ImVec2(5,5);
style.LegendPadding = ImVec2(5,5);
style.InfoPadding = ImVec2(5,5);
style.PlotMinSize = ImVec2(300,225);
}
} // namespaece MyImPlot } // namespaece MyImPlot
// WARNING: // WARNING:
@ -1271,4 +1272,3 @@ void PlotCandlestick(const char* label_id, const double* xs, const double* opens
} }
} // namespace MyImplot } // namespace MyImplot

View File

@ -70,20 +70,10 @@ extern ImPlotContext* GImPlot; // Current implicit context pointer
#define IMPLOT_DEFAULT_W 400 #define IMPLOT_DEFAULT_W 400
// Default plot frame height when requested height is auto (i.e. 0). This is not the plot area height! // Default plot frame height when requested height is auto (i.e. 0). This is not the plot area height!
#define IMPLOT_DEFAULT_H 300 #define IMPLOT_DEFAULT_H 300
// Minimum plot frame width when requested width is to edge (i.e. -1). This is not the plot area width!
#define IMPLOT_MIN_W 300
// Minimum plot frame height when requested height is to edge (i.e. -1). This is not the plot area height!
#define IMPLOT_MIN_H 225
// The maximum number of supported y-axes (DO NOT CHANGE THIS) // The maximum number of supported y-axes (DO NOT CHANGE THIS)
#define IMPLOT_Y_AXES 3 #define IMPLOT_Y_AXES 3
// The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5) // The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5)
#define IMPLOT_SUB_DIV 10 #define IMPLOT_SUB_DIV 10
// Pixel padding used for labels/titles
#define IMPLOT_LABEL_PAD 5
// Major tick size in pixels
#define IMPLOT_MAJOR_SIZE 10
// Minor tick size in pixels
#define IMPLOT_MINOR_SIZE 5
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click) // Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
#define IMPLOT_ZOOM_RATE 0.1f #define IMPLOT_ZOOM_RATE 0.1f
@ -340,17 +330,6 @@ struct ImPlotContext {
ImRect BB_Canvas; ImRect BB_Canvas;
ImRect BB_Plot; ImRect BB_Plot;
// Cached Colors
ImU32 Col_Frame;
ImU32 Col_Bg;
ImU32 Col_Border;
ImU32 Col_Txt;
ImU32 Col_TxtDis;
ImU32 Col_SlctBg;
ImU32 Col_SlctBd;
ImU32 Col_QryBg;
ImU32 Col_QryBd;
// Axis States // Axis States
ImPlotAxisColor Col_X; ImPlotAxisColor Col_X;
ImPlotAxisColor Col_Y[IMPLOT_Y_AXES]; ImPlotAxisColor Col_Y[IMPLOT_Y_AXES];
@ -434,6 +413,8 @@ void Reset(ImPlotContext* ctx);
ImPlotState* GetPlot(const char* title); ImPlotState* GetPlot(const char* title);
// Gets the current plot from the current ImPlotContext // Gets the current plot from the current ImPlotContext
ImPlotState* GetCurrentPlot(); ImPlotState* GetCurrentPlot();
// Busts the cache for every plot in the current context
void BustPlotCache();
// Updates plot-to-pixel space transformation variables for the current plot. // Updates plot-to-pixel space transformation variables for the current plot.
void UpdateTransformCache(); void UpdateTransformCache();
@ -448,8 +429,8 @@ ImPlotItem* GetItem(int i);
ImPlotItem* GetItem(const char* label_id); ImPlotItem* GetItem(const char* label_id);
// Gets a plot item from a specific plot // Gets a plot item from a specific plot
ImPlotItem* GetItem(const char* plot_title, const char* item_label_id); ImPlotItem* GetItem(const char* plot_title, const char* item_label_id);
// Busts the cached color for the every item (i.e. sets ImPlotItem.Color to IMPLOT_COL_AUTO) for every plot in the current context // Busts the cache for every item for every plot in the current context.
void BustItemColorCache(); void BustItemCache();
// Returns the number of entries in the current legend // Returns the number of entries in the current legend
int GetLegendCount(); int GetLegendCount();
@ -474,7 +455,7 @@ float SumTickLabelHeight(const ImVector<ImPlotTick>& ticks);
// Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2) // Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
double NiceNum(double x, bool round); double NiceNum(double x, bool round);
// Updates axis ticks, lins, and label colors // Updates axis ticks, lins, and label colors
void UpdateAxisColor(int axis_flag, ImPlotAxisColor* col); void UpdateAxisColors(int axis_flag, ImPlotAxisColor* col);
// Draws vertical text. The position is the bottom left of the text rect. // Draws vertical text. The position is the bottom left of the text rect.
void AddTextVertical(ImDrawList *DrawList, const char *text, ImVec2 pos, ImU32 text_color); void AddTextVertical(ImDrawList *DrawList, const char *text, ImVec2 pos, ImU32 text_color);
// Calculates the size of vertical text // Calculates the size of vertical text
@ -531,7 +512,12 @@ ImVec4 LerpColormap(const ImVec4* colormap, int size, float t);
void ResampleColormap(const ImVec4* colormap_in, int size_in, ImVec4* colormap_out, int size_out); void ResampleColormap(const ImVec4* colormap_in, int size_in, ImVec4* colormap_out, int size_out);
// Returns true if a style color is set to be automaticaly determined // Returns true if a style color is set to be automaticaly determined
inline bool ColorIsAuto(ImPlotCol idx) { return GImPlot->Style.Colors[idx].w == -1; } inline bool IsColorAuto(ImPlotCol idx) { return GImPlot->Style.Colors[idx].w == -1; }
// Returns the automatically deduced style color
ImVec4 GetAutoColor(ImPlotCol idx);
// Returns the style color whether it is automatic or custom set
inline ImVec4 GetStyleColorVec4(ImPlotCol idx) {return IsColorAuto(idx) ? GetAutoColor(idx) : GImPlot->Style.Colors[idx]; }
inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConvertFloat4ToU32(GetStyleColorVec4(idx)); }
// Recolors an item legend icon from an the current ImPlotCol if it is not automatic (i.e. alpha != -1) // Recolors an item legend icon from an the current ImPlotCol if it is not automatic (i.e. alpha != -1)
inline void TryRecolorItem(ImPlotItem* item, ImPlotCol idx) { inline void TryRecolorItem(ImPlotItem* item, ImPlotCol idx) {
@ -561,31 +547,31 @@ inline bool WillMarkerFillRender() {
// Gets the line color for an item // Gets the line color for an item
inline ImVec4 GetLineColor(ImPlotItem* item) { inline ImVec4 GetLineColor(ImPlotItem* item) {
return ColorIsAuto(ImPlotCol_Line) ? item->Color : GImPlot->Style.Colors[ImPlotCol_Line]; return IsColorAuto(ImPlotCol_Line) ? item->Color : GImPlot->Style.Colors[ImPlotCol_Line];
} }
// Gets the fill color for an item // Gets the fill color for an item
inline ImVec4 GetItemFillColor(ImPlotItem* item) { inline ImVec4 GetItemFillColor(ImPlotItem* item) {
ImVec4 col = ColorIsAuto(ImPlotCol_Fill) ? item->Color : GImPlot->Style.Colors[ImPlotCol_Fill]; ImVec4 col = IsColorAuto(ImPlotCol_Fill) ? item->Color : GImPlot->Style.Colors[ImPlotCol_Fill];
col.w *= GImPlot->Style.FillAlpha; col.w *= GImPlot->Style.FillAlpha;
return col; return col;
} }
// Gets the marker outline color for an item // Gets the marker outline color for an item
inline ImVec4 GetMarkerOutlineColor(ImPlotItem* item) { inline ImVec4 GetMarkerOutlineColor(ImPlotItem* item) {
return ColorIsAuto(ImPlotCol_MarkerOutline) ? GetLineColor(item) : GImPlot->Style.Colors[ImPlotCol_MarkerOutline]; return IsColorAuto(ImPlotCol_MarkerOutline) ? GetLineColor(item) : GImPlot->Style.Colors[ImPlotCol_MarkerOutline];
} }
// Gets the marker fill color for an item // Gets the marker fill color for an item
inline ImVec4 GetMarkerFillColor(ImPlotItem* item) { inline ImVec4 GetMarkerFillColor(ImPlotItem* item) {
ImVec4 col = ColorIsAuto(ImPlotCol_MarkerFill) ? GetLineColor(item) :GImPlot->Style.Colors[ImPlotCol_MarkerFill]; ImVec4 col = IsColorAuto(ImPlotCol_MarkerFill) ? GetLineColor(item) :GImPlot->Style.Colors[ImPlotCol_MarkerFill];
col.w *= GImPlot->Style.FillAlpha; col.w *= GImPlot->Style.FillAlpha;
return col; return col;
} }
// Gets the error bar color // Gets the error bar color
inline ImVec4 GetErrorBarColor() { inline ImVec4 GetErrorBarColor() {
return ColorIsAuto(ImPlotCol_ErrorBar) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : GImPlot->Style.Colors[ImPlotCol_ErrorBar]; return GetStyleColorVec4(ImPlotCol_ErrorBar);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -905,7 +905,7 @@ void PlotBarsEx(const char* label_id, Getter getter, TWidth width) {
if (rend_fill) if (rend_fill)
DrawList.AddRectFilled(a, b, col_fill); DrawList.AddRectFilled(a, b, col_fill);
if (rend_line) if (rend_line)
DrawList.AddRect(a, b, col_line); DrawList.AddRect(a, b, col_line, 0, ImDrawCornerFlags_All, gp.Style.LineWeight);
} }
PopPlotClipRect(); PopPlotClipRect();
} }
@ -982,7 +982,7 @@ void PlotBarsHEx(const char* label_id, Getter getter, THeight height) {
if (rend_fill) if (rend_fill)
DrawList.AddRectFilled(a, b, col_fill); DrawList.AddRectFilled(a, b, col_fill);
if (rend_line) if (rend_line)
DrawList.AddRect(a, b, col_line); DrawList.AddRect(a, b, col_line, 0, ImDrawCornerFlags_All, gp.Style.LineWeight);
} }
PopPlotClipRect(); PopPlotClipRect();
} }