mirror of
https://github.com/gwm17/implot.git
synced 2025-02-16 19:08:50 -05:00
Allow second and third axes to have labels (#163)
* Allow second and third axes to have labels * Handle both axes in one loop * fix compiler warnings, add ImPlotAxisFlags_NoLabel * fix bug when y2 label hidden Co-authored-by: epezent <epezent@rice.edu>
This commit is contained in:
parent
a9d3347915
commit
5b59b47bae
52
implot.cpp
52
implot.cpp
|
@ -1219,8 +1219,9 @@ void UpdateAxisColors(int axis_flag, ImPlotAxis* axis) {
|
||||||
// BeginPlot()
|
// BeginPlot()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool BeginPlot(const char* title, const char* x_label, const char* y_label, const ImVec2& size,
|
bool BeginPlot(const char* title, const char* x_label, const char* y1_label, const ImVec2& size,
|
||||||
ImPlotFlags flags, ImPlotAxisFlags x_flags, ImPlotAxisFlags y1_flags, ImPlotAxisFlags y2_flags, ImPlotAxisFlags y3_flags)
|
ImPlotFlags flags, ImPlotAxisFlags x_flags, ImPlotAxisFlags y1_flags, ImPlotAxisFlags y2_flags, ImPlotAxisFlags y3_flags,
|
||||||
|
const char* y2_label, const char* y3_label)
|
||||||
{
|
{
|
||||||
IM_ASSERT_USER_ERROR(GImPlot != NULL, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
|
IM_ASSERT_USER_ERROR(GImPlot != NULL, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
|
||||||
ImPlotContext& gp = *GImPlot;
|
ImPlotContext& gp = *GImPlot;
|
||||||
|
@ -1420,9 +1421,11 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
title_size = ImGui::CalcTextSize(title, NULL, true);
|
title_size = ImGui::CalcTextSize(title, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool show_x_label = x_label && !ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_NoLabel);
|
||||||
|
|
||||||
const float pad_top = title_size.x > 0.0f ? txt_height + gp.Style.LabelPadding.y : 0;
|
const float pad_top = title_size.x > 0.0f ? txt_height + gp.Style.LabelPadding.y : 0;
|
||||||
const float pad_bot = (plot.XAxis.IsLabeled() ? txt_height + gp.Style.LabelPadding.y + (plot.XAxis.IsTime() ? txt_height + gp.Style.LabelPadding.y : 0) : 0)
|
const float pad_bot = (plot.XAxis.IsLabeled() ? txt_height + gp.Style.LabelPadding.y + (plot.XAxis.IsTime() ? txt_height + gp.Style.LabelPadding.y : 0) : 0)
|
||||||
+ (x_label ? txt_height + gp.Style.LabelPadding.y : 0);
|
+ (show_x_label ? txt_height + gp.Style.LabelPadding.y : 0);
|
||||||
|
|
||||||
const float plot_height = plot.CanvasRect.GetHeight() - pad_top - pad_bot;
|
const float plot_height = plot.CanvasRect.GetHeight() - pad_top - pad_bot;
|
||||||
|
|
||||||
|
@ -1437,11 +1440,17 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// (3) calc left/right pad
|
// (3) calc left/right pad
|
||||||
const float pad_left = (y_label ? txt_height + gp.Style.LabelPadding.x : 0)
|
const bool show_y1_label = y1_label && !ImHasFlag(plot.YAxis[0].Flags, ImPlotAxisFlags_NoLabel);
|
||||||
|
const bool show_y2_label = y2_label && !ImHasFlag(plot.YAxis[1].Flags, ImPlotAxisFlags_NoLabel);
|
||||||
|
const bool show_y3_label = y3_label && !ImHasFlag(plot.YAxis[2].Flags, ImPlotAxisFlags_NoLabel);
|
||||||
|
|
||||||
|
const float pad_left = (show_y1_label ? txt_height + gp.Style.LabelPadding.x : 0)
|
||||||
+ (plot.YAxis[0].IsLabeled() ? gp.YTicks[0].MaxWidth + gp.Style.LabelPadding.x : 0);
|
+ (plot.YAxis[0].IsLabeled() ? gp.YTicks[0].MaxWidth + gp.Style.LabelPadding.x : 0);
|
||||||
const float pad_right = ((plot.YAxis[1].Present && plot.YAxis[1].IsLabeled()) ? gp.YTicks[1].MaxWidth + gp.Style.LabelPadding.x : 0)
|
const float pad_right = ((plot.YAxis[1].Present && plot.YAxis[1].IsLabeled()) ? gp.YTicks[1].MaxWidth + gp.Style.LabelPadding.x : 0)
|
||||||
|
+ ((plot.YAxis[1].Present && show_y2_label) ? txt_height + gp.Style.LabelPadding.x : 0)
|
||||||
+ ((plot.YAxis[1].Present && plot.YAxis[2].Present) ? gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y : 0)
|
+ ((plot.YAxis[1].Present && plot.YAxis[2].Present) ? gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y : 0)
|
||||||
+ ((plot.YAxis[2].Present && plot.YAxis[2].IsLabeled()) ? gp.YTicks[2].MaxWidth + gp.Style.LabelPadding.x : 0);
|
+ ((plot.YAxis[2].Present && plot.YAxis[2].IsLabeled()) ? gp.YTicks[2].MaxWidth + gp.Style.LabelPadding.x : 0)
|
||||||
|
+ ((plot.YAxis[2].Present && show_y3_label) ? txt_height + gp.Style.LabelPadding.x : 0);
|
||||||
|
|
||||||
const float plot_width = plot.CanvasRect.GetWidth() - pad_left - pad_right;
|
const float plot_width = plot.CanvasRect.GetWidth() - pad_left - pad_right;
|
||||||
|
|
||||||
|
@ -1467,7 +1476,12 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
// axis label reference
|
// axis label reference
|
||||||
gp.YAxisReference[0] = plot.PlotRect.Min.x;
|
gp.YAxisReference[0] = plot.PlotRect.Min.x;
|
||||||
gp.YAxisReference[1] = plot.PlotRect.Max.x;
|
gp.YAxisReference[1] = plot.PlotRect.Max.x;
|
||||||
gp.YAxisReference[2] = !plot.YAxis[1].Present ? plot.PlotRect.Max.x : (gp.YAxisReference[1] + (plot.YAxis[1].IsLabeled() ? gp.Style.LabelPadding.x + gp.YTicks[1].MaxWidth : 0) + gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y);
|
gp.YAxisReference[2] = !plot.YAxis[1].Present
|
||||||
|
? plot.PlotRect.Max.x
|
||||||
|
: gp.YAxisReference[1]
|
||||||
|
+ (plot.YAxis[1].IsLabeled() ? gp.Style.LabelPadding.x + gp.YTicks[1].MaxWidth : 0)
|
||||||
|
+ (show_y2_label ? txt_height + gp.Style.LabelPadding.x : 0)
|
||||||
|
+ gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y;
|
||||||
|
|
||||||
// y axis regions bb and hover
|
// y axis regions bb and hover
|
||||||
plot.YAxis[0].HoverRect = ImRect(ImVec2(plot.AxesRect.Min.x, plot.PlotRect.Min.y), ImVec2(plot.PlotRect.Min.x, plot.PlotRect.Max.y));
|
plot.YAxis[0].HoverRect = ImRect(ImVec2(plot.AxesRect.Min.x, plot.PlotRect.Min.y), ImVec2(plot.PlotRect.Min.x, plot.PlotRect.Max.y));
|
||||||
|
@ -1849,15 +1863,27 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// render axis labels
|
// render axis labels
|
||||||
if (x_label) {
|
if (show_x_label) {
|
||||||
const ImVec2 xLabel_size = ImGui::CalcTextSize(x_label);
|
const ImVec2 xLabel_size = ImGui::CalcTextSize(x_label);
|
||||||
const ImVec2 xLabel_pos(plot.PlotRect.GetCenter().x - xLabel_size.x * 0.5f, plot.CanvasRect.Max.y - txt_height);
|
const ImVec2 xLabel_pos(plot.PlotRect.GetCenter().x - xLabel_size.x * 0.5f, plot.CanvasRect.Max.y - txt_height);
|
||||||
DrawList.AddText(xLabel_pos, plot.XAxis.ColorTxt, x_label);
|
DrawList.AddText(xLabel_pos, plot.XAxis.ColorTxt, x_label);
|
||||||
}
|
}
|
||||||
if (y_label) {
|
|
||||||
const ImVec2 yLabel_size = CalcTextSizeVertical(y_label);
|
if (show_y1_label) {
|
||||||
|
const ImVec2 yLabel_size = CalcTextSizeVertical(y1_label);
|
||||||
const ImVec2 yLabel_pos(plot.CanvasRect.Min.x, plot.PlotRect.GetCenter().y + yLabel_size.y * 0.5f);
|
const ImVec2 yLabel_pos(plot.CanvasRect.Min.x, plot.PlotRect.GetCenter().y + yLabel_size.y * 0.5f);
|
||||||
AddTextVertical(&DrawList, yLabel_pos, plot.YAxis[0].ColorTxt, y_label);
|
AddTextVertical(&DrawList, yLabel_pos, plot.YAxis[0].ColorTxt, y1_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* y_labels[] = {y2_label, y3_label};
|
||||||
|
for (int i = 1; i < IMPLOT_Y_AXES; i++) {
|
||||||
|
const char* current_label = y_labels[i-1];
|
||||||
|
if (plot.YAxis[i].Present && current_label && !ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_NoLabel)) {
|
||||||
|
const ImVec2 yLabel_size = CalcTextSizeVertical(current_label);
|
||||||
|
float label_offset = (plot.YAxis[i].IsLabeled() ? gp.YTicks[i].MaxWidth + gp.Style.LabelPadding.x : 0.0f) + gp.Style.LabelPadding.x;
|
||||||
|
const ImVec2 yLabel_pos(gp.YAxisReference[i] + label_offset, plot.PlotRect.GetCenter().y + yLabel_size.y * 0.5f);
|
||||||
|
AddTextVertical(&DrawList, yLabel_pos, plot.YAxis[i].ColorTxt, current_label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// render tick labels
|
// render tick labels
|
||||||
|
@ -1883,6 +1909,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
|
|
||||||
// clear legend
|
// clear legend
|
||||||
plot.LegendData.Reset();
|
plot.LegendData.Reset();
|
||||||
// push plot ID into stack
|
// push plot ID into stack
|
||||||
|
@ -1927,6 +1954,7 @@ void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_all
|
||||||
|
|
||||||
ImGui::PushItemWidth(75);
|
ImGui::PushItemWidth(75);
|
||||||
bool always_locked = axis.IsAlwaysLocked();
|
bool always_locked = axis.IsAlwaysLocked();
|
||||||
|
bool label = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoLabel);
|
||||||
bool grid = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
|
bool grid = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
|
||||||
bool ticks = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
|
bool ticks = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
|
||||||
bool labels = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
|
bool labels = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
|
||||||
|
@ -2023,11 +2051,13 @@ void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_all
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
if (ImGui::Checkbox("Label", &label))
|
||||||
|
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoLabel);
|
||||||
if (ImGui::Checkbox("Grid Lines", &grid))
|
if (ImGui::Checkbox("Grid Lines", &grid))
|
||||||
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
|
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
|
||||||
if (ImGui::Checkbox("Tick Marks", &ticks))
|
if (ImGui::Checkbox("Tick Marks", &ticks))
|
||||||
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
|
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
|
||||||
if (ImGui::Checkbox("Labels", &labels))
|
if (ImGui::Checkbox("Tick Labels", &labels))
|
||||||
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
|
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
implot.h
23
implot.h
|
@ -84,16 +84,17 @@ enum ImPlotFlags_ {
|
||||||
// Options for plot axes (X and Y).
|
// Options for plot axes (X and Y).
|
||||||
enum ImPlotAxisFlags_ {
|
enum ImPlotAxisFlags_ {
|
||||||
ImPlotAxisFlags_None = 0, // default
|
ImPlotAxisFlags_None = 0, // default
|
||||||
ImPlotAxisFlags_NoGridLines = 1 << 0, // no grid lines will be displayed
|
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if string is NULL)
|
||||||
ImPlotAxisFlags_NoTickMarks = 1 << 1, // no tick marks will be displayed
|
ImPlotAxisFlags_NoGridLines = 1 << 1, // the axis grid lines will not be displayed
|
||||||
ImPlotAxisFlags_NoTickLabels = 1 << 2, // no text labels will be displayed
|
ImPlotAxisFlags_NoTickMarks = 1 << 2, // the axis tick marks will not be displayed
|
||||||
ImPlotAxisFlags_LogScale = 1 << 3, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time)
|
ImPlotAxisFlags_NoTickLabels = 1 << 3, // the axis tick labels will not be displayed
|
||||||
ImPlotAxisFlags_Time = 1 << 4, // axis will display date/time formatted labels (mutually exclusive with ImPlotAxisFlags_LogScale)
|
ImPlotAxisFlags_LogScale = 1 << 4, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time)
|
||||||
ImPlotAxisFlags_Invert = 1 << 5, // the axis will be inverted
|
ImPlotAxisFlags_Time = 1 << 5, // axis will display date/time formatted labels (mutually exclusive with ImPlotAxisFlags_LogScale)
|
||||||
ImPlotAxisFlags_LockMin = 1 << 6, // the axis minimum value will be locked when panning/zooming
|
ImPlotAxisFlags_Invert = 1 << 6, // the axis will be inverted
|
||||||
ImPlotAxisFlags_LockMax = 1 << 7, // the axis maximum value will be locked when panning/zooming
|
ImPlotAxisFlags_LockMin = 1 << 7, // the axis minimum value will be locked when panning/zooming
|
||||||
|
ImPlotAxisFlags_LockMax = 1 << 8, // the axis maximum value will be locked when panning/zooming
|
||||||
ImPlotAxisFlags_Lock = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax,
|
ImPlotAxisFlags_Lock = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax,
|
||||||
ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
|
ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
|
||||||
};
|
};
|
||||||
|
|
||||||
// Plot styling colors.
|
// Plot styling colors.
|
||||||
|
@ -343,7 +344,9 @@ IMPLOT_API bool BeginPlot(const char* title_id,
|
||||||
ImPlotAxisFlags x_flags = ImPlotAxisFlags_None,
|
ImPlotAxisFlags x_flags = ImPlotAxisFlags_None,
|
||||||
ImPlotAxisFlags y_flags = ImPlotAxisFlags_None,
|
ImPlotAxisFlags y_flags = ImPlotAxisFlags_None,
|
||||||
ImPlotAxisFlags y2_flags = ImPlotAxisFlags_NoGridLines,
|
ImPlotAxisFlags y2_flags = ImPlotAxisFlags_NoGridLines,
|
||||||
ImPlotAxisFlags y3_flags = ImPlotAxisFlags_NoGridLines);
|
ImPlotAxisFlags y3_flags = ImPlotAxisFlags_NoGridLines,
|
||||||
|
const char* y2_label = NULL,
|
||||||
|
const char* y3_label = NULL);
|
||||||
|
|
||||||
// Only call EndPlot() if BeginPlot() returns true! Typically called at the end
|
// Only call EndPlot() if BeginPlot() returns true! Typically called at the end
|
||||||
// of an if statement conditioned on BeginPlot().
|
// of an if statement conditioned on BeginPlot().
|
||||||
|
|
|
@ -705,9 +705,11 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
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);
|
||||||
if (ImPlot::BeginPlot("Multi-Axis Plot", NULL, NULL, ImVec2(-1,0),
|
if (ImPlot::BeginPlot("Multi-Axis Plot", NULL, "Y-Axis 1", ImVec2(-1,0),
|
||||||
(y2_axis ? ImPlotFlags_YAxis2 : 0) |
|
(y2_axis ? ImPlotFlags_YAxis2 : 0) |
|
||||||
(y3_axis ? ImPlotFlags_YAxis3 : 0))) {
|
(y3_axis ? ImPlotFlags_YAxis3 : 0),
|
||||||
|
ImPlotAxisFlags_None, ImPlotAxisFlags_None, ImPlotAxisFlags_NoGridLines, ImPlotAxisFlags_NoGridLines,
|
||||||
|
"Y-Axis 2", "Y-Axis 3")) {
|
||||||
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) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user