1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2025-01-30 19:08:51 -05:00

linked axes prototype

This commit is contained in:
epezent 2020-09-03 09:19:34 -05:00
parent 90693cca1b
commit fc1962cdef
4 changed files with 79 additions and 3 deletions

View File

@ -411,6 +411,16 @@ void FitPoint(const ImPlotPoint& p) {
} }
} }
void PushLinkedAxis(ImPlotAxis& axis) {
if (axis.LinkedMin) { *axis.LinkedMin = axis.Range.Min; }
if (axis.LinkedMax) { *axis.LinkedMax = axis.Range.Max; }
}
void PullLinkedAxis(ImPlotAxis& axis) {
if (axis.LinkedMin) { axis.Range.Min = *axis.LinkedMin; }
if (axis.LinkedMax) { axis.Range.Max = *axis.LinkedMax; }
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Coordinate Utils // Coordinate Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -675,6 +685,16 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// NextPlotData ----------------------------------------------------------- // NextPlotData -----------------------------------------------------------
// linked axes
plot.XAxis.LinkedMin = gp.NextPlotData.LinkedXmin;
plot.XAxis.LinkedMax = gp.NextPlotData.LinkedXmax;
PullLinkedAxis(plot.XAxis);
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
plot.YAxis[i].LinkedMin = gp.NextPlotData.LinkedYmin[i];
plot.YAxis[i].LinkedMax = gp.NextPlotData.LinkedYmax[i];
PullLinkedAxis(plot.YAxis[i]);
}
if (gp.NextPlotData.HasXRange) { if (gp.NextPlotData.HasXRange) {
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always) { if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always) {
plot.XAxis.Range = gp.NextPlotData.X; plot.XAxis.Range = gp.NextPlotData.X;
@ -1649,6 +1669,13 @@ void EndPlot() {
ImGui::PopID(); ImGui::PopID();
} }
// LINKED AXES ------------------------------------------------------------
PushLinkedAxis(plot.XAxis);
for (int i = 0; i < IMPLOT_Y_AXES; ++i)
PushLinkedAxis(plot.YAxis[i]);
// CLEANUP ---------------------------------------------------------------- // CLEANUP ----------------------------------------------------------------
// reset the plot items for the next frame // reset the plot items for the next frame
@ -1697,6 +1724,18 @@ void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, int y_axis)
gp.NextPlotData.Y[y_axis].Max = y_max; gp.NextPlotData.Y[y_axis].Max = y_max;
} }
void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2, double* ymax2, double* ymin3, double* ymax3) {
ImPlotContext& gp = *GImPlot;
gp.NextPlotData.LinkedXmin = xmin;
gp.NextPlotData.LinkedXmax = xmax;
gp.NextPlotData.LinkedYmin[0] = ymin;
gp.NextPlotData.LinkedYmax[0] = ymax;
gp.NextPlotData.LinkedYmin[1] = ymin2;
gp.NextPlotData.LinkedYmax[1] = ymax2;
gp.NextPlotData.LinkedYmin[2] = ymin3;
gp.NextPlotData.LinkedYmax[2] = ymax3;
}
void FitNextPlotAxes(bool x, bool y, bool y2, bool y3) { void FitNextPlotAxes(bool x, bool y, bool y2, bool y3) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "FitNextPlotAxes() needs to be called before BeginPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "FitNextPlotAxes() needs to be called before BeginPlot()!");

View File

@ -376,14 +376,17 @@ void PlotText(const char* text, double x, double y, bool vertical = false, const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// 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 xmin, double xmax, double ymin, double ymax, 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.
void SetNextPlotLimitsX(double x_min, double x_max, ImGuiCond cond = ImGuiCond_Once); void SetNextPlotLimitsX(double xmin, double xmax, ImGuiCond cond = ImGuiCond_Once);
// Set the Y axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the Y axis limits will be locked. // Set the Y axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the Y axis limits will be locked.
void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond = ImGuiCond_Once, int y_axis = 0); void SetNextPlotLimitsY(double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once, int y_axis = 0);
// Links the next plot axes to external range. Set to NULL for no linkage. The pointer data must remain valid until the matching call EndPlot.
void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2 = NULL, double* ymax2 = NULL, double* ymin3 = NULL, double* ymax3 = NULL);
// Fits the next plot axes to all plotted data if they are unlocked (equivalent to double-clicks). // Fits the next plot axes to all plotted data if they are unlocked (equivalent to double-clicks).
void FitNextPlotAxes(bool x = true, bool y = true, bool y2 = true, bool y3 = true); void FitNextPlotAxes(bool x = true, bool y = true, bool y2 = true, bool y3 = true);
// Set the X axis ticks and optionally the labels for the next plot. // Set the X axis ticks and optionally the labels for the next plot.
void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false); void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false);
void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** labels = NULL, bool show_default = false); void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** labels = NULL, bool show_default = false);

View File

@ -637,6 +637,25 @@ void ShowDemoWindow(bool* p_open) {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Linked Axes")) {
static double xmin = 0, xmax = 1, ymin = 0, ymax = 1;
static bool linkx = true, linky = true;
t_float data[2] = {0,1};
ImGui::Checkbox("Link X", &linkx);
ImGui::SameLine();
ImGui::Checkbox("Link Y", &linky);
ImPlot::LinkNextPlotLimits(linkx ? &xmin : NULL , linkx ? &xmax : NULL, linky ? &ymin : NULL, linky ? &ymax : NULL);
if (ImPlot::BeginPlot("Plot A")) {
ImPlot::PlotLine("Line",data,2);
ImPlot::EndPlot();
}
ImPlot::LinkNextPlotLimits(linkx ? &xmin : NULL , linkx ? &xmax : NULL, linky ? &ymin : NULL, linky ? &ymax : NULL);
if (ImPlot::BeginPlot("Plot B")) {
ImPlot::PlotLine("Line",data,2);
ImPlot::EndPlot();
}
}
//-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Querying")) { if (ImGui::CollapsingHeader("Querying")) {
static ImVector<t_float2> data; static ImVector<t_float2> data;
static ImPlotLimits range, query; static ImPlotLimits range, query;

View File

@ -249,6 +249,8 @@ struct ImPlotAxis
bool Dragging; bool Dragging;
bool HoveredExt; bool HoveredExt;
bool HoveredTot; bool HoveredTot;
double* LinkedMin;
double* LinkedMax;
ImPlotAxis() { ImPlotAxis() {
Flags = PreviousFlags = ImPlotAxisFlags_Default; Flags = PreviousFlags = ImPlotAxisFlags_Default;
@ -257,6 +259,7 @@ struct ImPlotAxis
Dragging = false; Dragging = false;
HoveredExt = false; HoveredExt = false;
HoveredTot = false; HoveredTot = false;
LinkedMin = LinkedMax = NULL;
} }
}; };
@ -356,19 +359,26 @@ struct ImPlotNextPlotData
bool ShowDefaultTicksY[IMPLOT_Y_AXES]; bool ShowDefaultTicksY[IMPLOT_Y_AXES];
bool FitX; bool FitX;
bool FitY[IMPLOT_Y_AXES]; bool FitY[IMPLOT_Y_AXES];
double* LinkedXmin;
double* LinkedXmax;
double* LinkedYmin[IMPLOT_Y_AXES];
double* LinkedYmax[IMPLOT_Y_AXES];
ImPlotNextPlotData() { ImPlotNextPlotData() {
HasXRange = false; HasXRange = false;
ShowDefaultTicksX = true; ShowDefaultTicksX = true;
FitX = false; FitX = false;
LinkedXmin = LinkedXmax = NULL;
for (int i = 0; i < IMPLOT_Y_AXES; ++i) { for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
HasYRange[i] = false; HasYRange[i] = false;
ShowDefaultTicksY[i] = true; ShowDefaultTicksY[i] = true;
FitY[i] = false; FitY[i] = false;
LinkedYmin[i] = LinkedYmax[i] = NULL;
} }
} }
}; };
// Temporary data storage for upcoming item // Temporary data storage for upcoming item
struct ImPlotItemStyle { struct ImPlotItemStyle {
ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
@ -547,6 +557,11 @@ inline bool FitThisFrame() { return GImPlot->FitThisFrame; }
// Extends the current plots axes so that it encompasses point p // Extends the current plots axes so that it encompasses point p
void FitPoint(const ImPlotPoint& p); void FitPoint(const ImPlotPoint& p);
// Updates pointers for linked axes from axis internal range
void PushLinkedAxis(ImPlotAxis& axis);
// Updates axis internal range from points for linked axes
void PullLinkedAxis(ImPlotAxis& axis);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Legend Utils // [SECTION] Legend Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------