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

make plots initially fit to plotted data on first frame

This commit is contained in:
epezent 2021-03-20 22:56:47 -06:00
parent 7aab224742
commit 5db2ba3b22
4 changed files with 52 additions and 40 deletions

View File

@ -1369,14 +1369,25 @@ bool BeginPlot(const char* title, const char* x_label, const char* y1_label, con
} }
if (gp.NextPlotData.HasXRange) { if (gp.NextPlotData.HasXRange) {
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always) if (!plot.Initialized || gp.NextPlotData.XRangeCond == ImGuiCond_Always)
plot.XAxis.SetRange(gp.NextPlotData.X); plot.XAxis.SetRange(gp.NextPlotData.XRange);
} }
for (int i = 0; i < IMPLOT_Y_AXES; i++) { for (int i = 0; i < IMPLOT_Y_AXES; i++) {
if (gp.NextPlotData.HasYRange[i]) { if (gp.NextPlotData.HasYRange[i]) {
if (just_created || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always) if (!plot.Initialized || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always)
plot.YAxis[i].SetRange(gp.NextPlotData.Y[i]); plot.YAxis[i].SetRange(gp.NextPlotData.YRange[i]);
}
}
// Initialization ------------------------------------------------------------
if (!plot.Initialized) {
if (!ImHasFlag(plot.XAxis.Flags,ImPlotAxisFlags_NoInitialFit) && !gp.NextPlotData.HasXRange)
gp.FitThisFrame = gp.FitX = true;
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
if (!ImHasFlag(plot.YAxis[i].Flags,ImPlotAxisFlags_NoInitialFit) && !gp.NextPlotData.HasYRange[i])
gp.FitThisFrame = gp.FitY[i] = true;
} }
} }
@ -2570,10 +2581,13 @@ void EndPlot() {
// reset the plot items for the next frame // reset the plot items for the next frame
for (int i = 0; i < gp.CurrentPlot->Items.GetSize(); ++i) { for (int i = 0; i < plot.Items.GetSize(); ++i) {
gp.CurrentPlot->Items.GetByIndex(i)->SeenThisFrame = false; plot.Items.GetByIndex(i)->SeenThisFrame = false;
} }
// mark the plot as initialized, i.e. having made it through one frame completely
plot.Initialized = true;
// Pop ImGui::PushID at the end of BeginPlot // Pop ImGui::PushID at the end of BeginPlot
ImGui::PopID(); ImGui::PopID();
// Reset context for next plot // Reset context for next plot
@ -2600,8 +2614,8 @@ void SetNextPlotLimitsX(double x_min, double x_max, ImGuiCond cond) {
IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
gp.NextPlotData.HasXRange = true; gp.NextPlotData.HasXRange = true;
gp.NextPlotData.XRangeCond = cond; gp.NextPlotData.XRangeCond = cond;
gp.NextPlotData.X.Min = x_min; gp.NextPlotData.XRange.Min = x_min;
gp.NextPlotData.X.Max = x_max; gp.NextPlotData.XRange.Max = x_max;
} }
void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, ImPlotYAxis y_axis) { void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, ImPlotYAxis y_axis) {
@ -2611,8 +2625,8 @@ void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, ImPlotYAxis
IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
gp.NextPlotData.HasYRange[y_axis] = true; gp.NextPlotData.HasYRange[y_axis] = true;
gp.NextPlotData.YRangeCond[y_axis] = cond; gp.NextPlotData.YRangeCond[y_axis] = cond;
gp.NextPlotData.Y[y_axis].Min = y_min; gp.NextPlotData.YRange[y_axis].Min = y_min;
gp.NextPlotData.Y[y_axis].Max = y_max; gp.NextPlotData.YRange[y_axis].Max = y_max;
} }
void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2, double* ymax2, double* ymin3, double* ymax3) { void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2, double* ymax2, double* ymin3, double* ymax3) {
@ -3130,10 +3144,6 @@ bool IsLegendEntryHovered(const char* label_id) {
return item && item->LegendHovered; return item && item->LegendHovered;
} }
bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button) { bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "BeginLegendPopup() needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "BeginLegendPopup() needs to be called between BeginPlot() and EndPlot()!");
@ -3973,12 +3983,13 @@ void ShowMetricsWindow(bool* p_popen) {
ShowAxisMetrics(&plot->YAxis[2], show_axes_rects); ShowAxisMetrics(&plot->YAxis[2], show_axes_rects);
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::Bullet(); ImGui::Text("Flags: %d", plot->Flags); ImGui::Bullet(); ImGui::Text("Flags: %d", plot->Flags);
ImGui::Bullet(); ImGui::Text("Selecting: %s", plot->Selecting ? "true" : "false"); ImGui::Bullet(); ImGui::Text("Initialized: %s", plot->Initialized ? "true" : "false");
ImGui::Bullet(); ImGui::Text("Querying: %s", plot->Querying ? "true" : "false"); ImGui::Bullet(); ImGui::Text("Selecting: %s", plot->Selecting ? "true" : "false");
ImGui::Bullet(); ImGui::Text("Queried: %s", plot->Queried ? "true" : "false"); ImGui::Bullet(); ImGui::Text("Querying: %s", plot->Querying ? "true" : "false");
ImGui::Bullet(); ImGui::Text("FrameHovered: %s", plot->FrameHovered ? "true" : "false"); ImGui::Bullet(); ImGui::Text("Queried: %s", plot->Queried ? "true" : "false");
ImGui::Bullet(); ImGui::Text("PlotHovered: %s", plot->PlotHovered ? "true" : "false"); ImGui::Bullet(); ImGui::Text("FrameHovered: %s", plot->FrameHovered ? "true" : "false");
ImGui::Bullet(); ImGui::Text("PlotHovered: %s", plot->PlotHovered ? "true" : "false");
ImGui::Bullet(); ImGui::Text("LegendHovered: %s", plot->LegendHovered ? "true" : "false"); ImGui::Bullet(); ImGui::Text("LegendHovered: %s", plot->LegendHovered ? "true" : "false");
ImGui::TreePop(); ImGui::TreePop();
if (show_plot_rects) if (show_plot_rects)

View File

@ -84,17 +84,18 @@ 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_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL) ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL)
ImPlotAxisFlags_NoGridLines = 1 << 1, // no grid lines will be displayed ImPlotAxisFlags_NoGridLines = 1 << 1, // no grid lines will be displayed
ImPlotAxisFlags_NoTickMarks = 1 << 2, // no tick marks will be displayed ImPlotAxisFlags_NoTickMarks = 1 << 2, // no tick marks will be displayed
ImPlotAxisFlags_NoTickLabels = 1 << 3, // no text labels will be displayed ImPlotAxisFlags_NoTickLabels = 1 << 3, // no text labels will be displayed
ImPlotAxisFlags_LogScale = 1 << 4, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time) 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_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_Invert = 1 << 6, // the axis will be inverted
ImPlotAxisFlags_AutoFit = 1 << 7, // axis will be auto-fitting to data extents ImPlotAxisFlags_NoInitialFit = 1 << 7, // axis will not be initially fit to data extents on the first rendered frame (also the case if SetNextPlotLimits explicitly called)
ImPlotAxisFlags_LockMin = 1 << 8, // the axis minimum value will be locked when panning/zooming ImPlotAxisFlags_AutoFit = 1 << 8, // axis will be auto-fitting to data extents
ImPlotAxisFlags_LockMax = 1 << 9, // the axis maximum value will be locked when panning/zooming ImPlotAxisFlags_LockMin = 1 << 9, // the axis minimum value will be locked when panning/zooming
ImPlotAxisFlags_LockMax = 1 << 10, // 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_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
}; };

View File

@ -483,20 +483,17 @@ void ShowDemoWindow(bool* p_open) {
} }
ImPlot::SetNextPlotLimits(0,1,0,1.6); ImPlot::SetNextPlotLimits(0,1,0,1.6);
if (ImPlot::BeginPlot("Stem Plots")) { if (ImPlot::BeginPlot("Stem Plots")) {
ImPlot::PlotStems("Stems 1",xs,ys1,51); ImPlot::PlotStems("Stems 1",xs,ys1,51);
ImPlot::SetNextLineStyle(ImVec4(1,0.5f,0,0.75f)); ImPlot::SetNextLineStyle(ImVec4(1,0.5f,0,0.75f));
ImPlot::SetNextMarkerStyle(ImPlotMarker_Square,5,ImVec4(1,0.5f,0,0.25f)); ImPlot::SetNextMarkerStyle(ImPlotMarker_Square,5,ImVec4(1,0.5f,0,0.25f));
ImPlot::PlotStems("Stems 2", xs, ys2,51); ImPlot::PlotStems("Stems 2", xs, ys2,51);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Infinite Lines")) { if (ImGui::CollapsingHeader("Infinite Lines")) {
static double vals[] = {0.25, 0.5, 0.75}; static double vals[] = {0.25, 0.5, 0.75};
if (ImPlot::BeginPlot("##Infinite")) { if (ImPlot::BeginPlot("##Infinite",0,0,ImVec2(-1,0),0,ImPlotAxisFlags_NoInitialFit,ImPlotAxisFlags_NoInitialFit)) {
ImPlot::PlotVLines("VLines",vals,3); ImPlot::PlotVLines("VLines",vals,3);
ImPlot::PlotHLines("HLines",vals,3); ImPlot::PlotHLines("HLines",vals,3);
ImPlot::EndPlot(); ImPlot::EndPlot();
@ -639,7 +636,6 @@ void ShowDemoWindow(bool* p_open) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox("Outliers",&outliers); ImGui::Checkbox("Outliers",&outliers);
} }
ImPlot::SetNextPlotLimits(-3, 13, 0, 0.25);
if (ImPlot::BeginPlot("##Histograms")) { if (ImPlot::BeginPlot("##Histograms")) {
ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.5f); ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.5f);
ImPlot::PlotHistogram("Empirical", dist.Data, 10000, bins, cumulative, density, range ? ImPlotRange(rmin,rmax) : ImPlotRange(), outliers); ImPlot::PlotHistogram("Empirical", dist.Data, 10000, bins, cumulative, density, range ? ImPlotRange(rmin,rmax) : ImPlotRange(), outliers);
@ -760,12 +756,14 @@ void ShowDemoWindow(bool* p_open) {
static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_NoTickLabels; static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_NoTickLabels;
ImPlot::SetNextPlotLimitsX(t - history, t, ImGuiCond_Always); ImPlot::SetNextPlotLimitsX(t - history, t, ImGuiCond_Always);
ImPlot::SetNextPlotLimitsY(0,1);
if (ImPlot::BeginPlot("##Scrolling", NULL, NULL, ImVec2(-1,150), 0, rt_axis, rt_axis | ImPlotAxisFlags_LockMin)) { if (ImPlot::BeginPlot("##Scrolling", NULL, NULL, ImVec2(-1,150), 0, rt_axis, rt_axis | ImPlotAxisFlags_LockMin)) {
ImPlot::PlotShaded("Data 1", &sdata1.Data[0].x, &sdata1.Data[0].y, sdata1.Data.size(), 0, sdata1.Offset, 2 * sizeof(float)); ImPlot::PlotShaded("Data 1", &sdata1.Data[0].x, &sdata1.Data[0].y, sdata1.Data.size(), 0, sdata1.Offset, 2 * sizeof(float));
ImPlot::PlotLine("Data 2", &sdata2.Data[0].x, &sdata2.Data[0].y, sdata2.Data.size(), sdata2.Offset, 2*sizeof(float)); ImPlot::PlotLine("Data 2", &sdata2.Data[0].x, &sdata2.Data[0].y, sdata2.Data.size(), sdata2.Offset, 2*sizeof(float));
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::SetNextPlotLimitsX(0, history, ImGuiCond_Always); ImPlot::SetNextPlotLimitsX(0, history, ImGuiCond_Always);
ImPlot::SetNextPlotLimitsY(0,1);
if (ImPlot::BeginPlot("##Rolling", NULL, NULL, ImVec2(-1,150), 0, rt_axis, rt_axis)) { if (ImPlot::BeginPlot("##Rolling", NULL, NULL, ImVec2(-1,150), 0, rt_axis, rt_axis)) {
ImPlot::PlotLine("Data 1", &rdata1.Data[0].x, &rdata1.Data[0].y, rdata1.Data.size(), 0, 2 * sizeof(float)); ImPlot::PlotLine("Data 1", &rdata1.Data[0].x, &rdata1.Data[0].y, rdata1.Data.size(), 0, 2 * sizeof(float));
ImPlot::PlotLine("Data 2", &rdata2.Data[0].x, &rdata2.Data[0].y, rdata2.Data.size(), 0, 2 * sizeof(float)); ImPlot::PlotLine("Data 2", &rdata2.Data[0].x, &rdata2.Data[0].y, rdata2.Data.size(), 0, 2 * sizeof(float));
@ -947,7 +945,6 @@ void ShowDemoWindow(bool* p_open) {
double angle = i * 2 * PI / 999.0; double angle = i * 2 * PI / 999.0;
xs[i] = cos(angle); ys[i] = sin(angle); xs[i] = cos(angle); ys[i] = sin(angle);
} }
ImPlot::SetNextPlotLimits(-1,1,-1,1);
if (ImPlot::BeginPlot("",0,0,ImVec2(-1,0),ImPlotFlags_Equal)) { if (ImPlot::BeginPlot("",0,0,ImVec2(-1,0),ImPlotFlags_Equal)) {
ImPlot::PlotLine("Circle",xs,ys,1000); ImPlot::PlotLine("Circle",xs,ys,1000);
ImPlot::EndPlot(); ImPlot::EndPlot();
@ -1072,6 +1069,7 @@ void ShowDemoWindow(bool* p_open) {
static double f = 0.1; static double f = 0.1;
static bool show_labels = true; static bool show_labels = true;
ImGui::Checkbox("Show Labels##1",&show_labels); ImGui::Checkbox("Show Labels##1",&show_labels);
ImPlot::SetNextPlotLimits(0,1,0,1);
if (ImPlot::BeginPlot("##guides",0,0,ImVec2(-1,0),ImPlotFlags_YAxis2)) { if (ImPlot::BeginPlot("##guides",0,0,ImVec2(-1,0),ImPlotFlags_YAxis2)) {
ImPlot::DragLineX("x1",&x1,show_labels); ImPlot::DragLineX("x1",&x1,show_labels);
ImPlot::DragLineX("x2",&x2,show_labels); ImPlot::DragLineX("x2",&x2,show_labels);
@ -1090,6 +1088,7 @@ void ShowDemoWindow(bool* p_open) {
ImGui::BulletText("Click and drag any point."); ImGui::BulletText("Click and drag any point.");
ImGui::Checkbox("Show Labels##2",&show_labels); ImGui::Checkbox("Show Labels##2",&show_labels);
ImPlotAxisFlags flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoTickMarks; ImPlotAxisFlags flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoTickMarks;
ImPlot::SetNextPlotLimits(0,1,0,1);
if (ImPlot::BeginPlot("##Bezier",0,0,ImVec2(-1,0),ImPlotFlags_CanvasOnly,flags,flags)) { if (ImPlot::BeginPlot("##Bezier",0,0,ImVec2(-1,0),ImPlotFlags_CanvasOnly,flags,flags)) {
static ImPlotPoint P[] = {ImPlotPoint(.05f,.05f), ImPlotPoint(0.2,0.4), ImPlotPoint(0.8,0.6), ImPlotPoint(.95f,.95f)}; static ImPlotPoint P[] = {ImPlotPoint(.05f,.05f), ImPlotPoint(0.2,0.4), ImPlotPoint(0.8,0.6), ImPlotPoint(.95f,.95f)};
static ImPlotPoint B[100]; static ImPlotPoint B[100];

View File

@ -722,6 +722,7 @@ struct ImPlotPlot
ImVec2 SelectStart; ImVec2 SelectStart;
ImVec2 QueryStart; ImVec2 QueryStart;
ImRect QueryRect; ImRect QueryRect;
bool Initialized;
bool Selecting; bool Selecting;
bool ContextLocked; bool ContextLocked;
bool Querying; bool Querying;
@ -749,7 +750,7 @@ struct ImPlotPlot
for (int i = 0; i < IMPLOT_Y_AXES; ++i) for (int i = 0; i < IMPLOT_Y_AXES; ++i)
YAxis[i].Orientation = ImPlotOrientation_Vertical; YAxis[i].Orientation = ImPlotOrientation_Vertical;
SelectStart = QueryStart = ImVec2(0,0); SelectStart = QueryStart = ImVec2(0,0);
Selecting = ContextLocked = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSideNextFrame = false; Initialized = Selecting = ContextLocked = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSideNextFrame = false;
ColormapIdx = CurrentYAxis = 0; ColormapIdx = CurrentYAxis = 0;
LegendLocation = ImPlotLocation_North | ImPlotLocation_West; LegendLocation = ImPlotLocation_North | ImPlotLocation_West;
LegendOrientation = ImPlotOrientation_Vertical; LegendOrientation = ImPlotOrientation_Vertical;
@ -768,8 +769,8 @@ struct ImPlotNextPlotData
{ {
ImGuiCond XRangeCond; ImGuiCond XRangeCond;
ImGuiCond YRangeCond[IMPLOT_Y_AXES]; ImGuiCond YRangeCond[IMPLOT_Y_AXES];
ImPlotRange X; ImPlotRange XRange;
ImPlotRange Y[IMPLOT_Y_AXES]; ImPlotRange YRange[IMPLOT_Y_AXES];
bool HasXRange; bool HasXRange;
bool HasYRange[IMPLOT_Y_AXES]; bool HasYRange[IMPLOT_Y_AXES];
bool ShowDefaultTicksX; bool ShowDefaultTicksX;