1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-22 18:28:53 -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:
Yan 2021-01-06 10:34:03 -05:00 committed by GitHub
parent a9d3347915
commit 5b59b47bae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 23 deletions

View File

@ -1219,8 +1219,9 @@ void UpdateAxisColors(int axis_flag, ImPlotAxis* axis) {
// BeginPlot()
//-----------------------------------------------------------------------------
bool BeginPlot(const char* title, const char* x_label, const char* y_label, const ImVec2& size,
ImPlotFlags flags, ImPlotAxisFlags x_flags, ImPlotAxisFlags y1_flags, ImPlotAxisFlags y2_flags, ImPlotAxisFlags y3_flags)
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,
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()?");
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);
}
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_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;
@ -1437,11 +1440,17 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
}
// (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);
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[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;
@ -1467,7 +1476,12 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// axis label reference
gp.YAxisReference[0] = plot.PlotRect.Min.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
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
if (x_label) {
if (show_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);
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);
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
@ -1883,6 +1909,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
}
}
ImGui::PopClipRect();
// clear legend
plot.LegendData.Reset();
// push plot ID into stack
@ -1927,6 +1954,7 @@ void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_all
ImGui::PushItemWidth(75);
bool always_locked = axis.IsAlwaysLocked();
bool label = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoLabel);
bool grid = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
bool ticks = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
bool labels = !ImHasFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
@ -2023,11 +2051,13 @@ void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_all
}
ImGui::Separator();
if (ImGui::Checkbox("Label", &label))
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoLabel);
if (ImGui::Checkbox("Grid Lines", &grid))
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoGridLines);
if (ImGui::Checkbox("Tick Marks", &ticks))
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickMarks);
if (ImGui::Checkbox("Labels", &labels))
if (ImGui::Checkbox("Tick Labels", &labels))
ImFlipFlag(axis.Flags, ImPlotAxisFlags_NoTickLabels);
}

View File

@ -84,16 +84,17 @@ enum ImPlotFlags_ {
// Options for plot axes (X and Y).
enum ImPlotAxisFlags_ {
ImPlotAxisFlags_None = 0, // default
ImPlotAxisFlags_NoGridLines = 1 << 0, // no grid lines will be displayed
ImPlotAxisFlags_NoTickMarks = 1 << 1, // no tick marks will be displayed
ImPlotAxisFlags_NoTickLabels = 1 << 2, // no text labels will be displayed
ImPlotAxisFlags_LogScale = 1 << 3, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time)
ImPlotAxisFlags_Time = 1 << 4, // axis will display date/time formatted labels (mutually exclusive with ImPlotAxisFlags_LogScale)
ImPlotAxisFlags_Invert = 1 << 5, // the axis will be inverted
ImPlotAxisFlags_LockMin = 1 << 6, // the axis minimum value will be locked when panning/zooming
ImPlotAxisFlags_LockMax = 1 << 7, // the axis maximum value will be locked when panning/zooming
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if string is NULL)
ImPlotAxisFlags_NoGridLines = 1 << 1, // the axis grid lines will not be displayed
ImPlotAxisFlags_NoTickMarks = 1 << 2, // the axis tick marks will not be displayed
ImPlotAxisFlags_NoTickLabels = 1 << 3, // the axis tick labels will not be displayed
ImPlotAxisFlags_LogScale = 1 << 4, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time)
ImPlotAxisFlags_Time = 1 << 5, // axis will display date/time formatted labels (mutually exclusive with ImPlotAxisFlags_LogScale)
ImPlotAxisFlags_Invert = 1 << 6, // the axis will be inverted
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_NoDecorations = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
};
// Plot styling colors.
@ -343,7 +344,9 @@ IMPLOT_API bool BeginPlot(const char* title_id,
ImPlotAxisFlags x_flags = ImPlotAxisFlags_None,
ImPlotAxisFlags y_flags = ImPlotAxisFlags_None,
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
// of an if statement conditioned on BeginPlot().

View File

@ -705,9 +705,11 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::SetNextPlotLimits(0.1, 100, 0, 10);
ImPlot::SetNextPlotLimitsY(0, 1, ImGuiCond_Once, 1);
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) |
(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) = sin(x)*3+1", xs, ys1, 1001);
if (y2_axis) {