diff --git a/examples/studiMain.cpp b/examples/studiMain.cpp index 9040968028892decce7b78dc6a8096b4e1f80f3d..6e8bf3fa4c214344b7d59c028586ffdea43dabb8 100644 --- a/examples/studiMain.cpp +++ b/examples/studiMain.cpp @@ -37,6 +37,7 @@ void setup() void superDummy() { + cute::setAxisRange(0, 0, 42, 0, 69); int prog = 0; while (cute::ok()) { @@ -92,7 +93,8 @@ std::string point2str(cute::Point p) void advancedDummy() { cute::resetPlot(0); - cute::setPlotScale(0, cute::logarithmic, cute::logarithmic); + //cute::setPlotScale(0, cute::logarithmic, cute::logarithmic); + cute::setAxisRange(0, -100, 200, -100, 200); std::vector<float> problem1D = cute::getProblemData1D(); cute::logMessage(fvec2str(problem1D)); cute::setPlotTheme(problem1D.size() - 1); diff --git a/include/cute.h b/include/cute.h index 64151fd567d06cb8d08a53a53798da0c9882feed..f66ca6aae9aaa0331f40908cfb623f6a27f7b110 100644 --- a/include/cute.h +++ b/include/cute.h @@ -112,6 +112,7 @@ namespace cute void DYNAMIC setLegendVisible(int plot, bool visible = true); void DYNAMIC setAxisTitles(int plot, const std::string& x, const std::string& y); void DYNAMIC setAxisVisible(int plot, bool x, bool y); + void DYNAMIC setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max); void DYNAMIC registerAlgorithm(void (*func)(), const std::string& name, void (*localSetup)() = nullptr); @@ -128,7 +129,7 @@ namespace cute bool loop = false, const PlotProperties& properties = {}); void DYNAMIC undo(int plot); - void DYNAMIC resetPlot(int plot); + void DYNAMIC resetPlot(int plot, bool keepRanges = false); void DYNAMIC logMessage(const std::string& message); void DYNAMIC setStatusMessage(const std::string& message, int duration_s = 5); diff --git a/src/chartMenu.cpp b/src/chartMenu.cpp index 88e5f82f46f5d1be9e0b0ef94ebcb18fc051dbfd..4846bd6677b8abf7be585933874d47b0f7ee9c20 100644 --- a/src/chartMenu.cpp +++ b/src/chartMenu.cpp @@ -156,7 +156,7 @@ void ChartMenu::onReset() // modal execution int result = dialog.exec(); if (result == QDialog::Accepted) - emit s_resetPlot(i); + emit s_resetPlot(i, true); } } } diff --git a/src/chartMenu.h b/src/chartMenu.h index 8f1ffcefce3400f080f2a9db80aca5e5d482bef0..f095623223b5c38cfc6c197775af2f6cc5cc87d2 100644 --- a/src/chartMenu.h +++ b/src/chartMenu.h @@ -48,7 +48,7 @@ public slots: signals: void s_setPlotScale(int plot, int x, int y); - void s_resetPlot(int plot); + void s_resetPlot(int plot, bool keepRanges); }; diff --git a/src/control.cpp b/src/control.cpp index 9dc3d5906c102b370d691c7af80cade1ffe19c0f..81ab09d0ba835f9f93f20006bca2c5a2ac25773b 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -38,6 +38,7 @@ void Control::makeConnections() connect(cc, &CuteControl::s_setPlotTheme, this, &Control::setPlotTheme); connect(cc, &CuteControl::s_setLegendVisible, this, &Control::setLegendVisible); connect(cc, &CuteControl::s_setAxisVisible, this, &Control::setAxisVisible); + connect(cc, &CuteControl::s_setAxisRange, this, &Control::setAxisRange); connect(cc, &CuteControl::s_setAxisTitles, this, &Control::setAxisTitles); connect(cc, &CuteControl::s_enableAutorun, this, &Control::enableAutorun); connect(cc, &CuteControl::s_setProblemSize, this, &Control::setProblemSize); @@ -116,6 +117,7 @@ void Control::addPlot(int type) { onTopSeries.emplace_back(); plotHistory.emplace_back(); + axisRanges.emplace_back(); if (type == cute::PlotType::chart) { addChart(); @@ -532,7 +534,7 @@ void Control::onPreviewButton() auto ptr = dynamic_cast<QtCharts::QChartView*>(w->graphingWidgets[i]); if (ptr) { - resetPlot(i); + resetPlot(i, true); problemPreviewed = false; CuteControl::get().plotPoints(getProblem(), i, {}); problemPreviewed = true; @@ -723,6 +725,24 @@ void Control::resizeAxes(int plot) return; QChart* chart = chartView->chart(); + if (axisRanges[plot].set) + { + QList<QAbstractAxis*> axes = chart->axes(); + AxisRanges& r = axisRanges[plot]; + for (auto axis : axes) + { + if (axis->orientation() == Qt::Orientation::Horizontal) + { + axis->setRange(r.x_min, r.x_max); + } + else + { + axis->setRange(r.y_min, r.y_max); + } + } + return; + } + double maxX = std::numeric_limits<double>::min(); double maxY = std::numeric_limits<double>::min(); double minX = std::numeric_limits<double>::max(); @@ -814,7 +834,7 @@ void Control::resizeAxes(int plot) * This currently only works with QCharts. * @param plot The plot to be reset. */ -void Control::resetPlot(int plot) +void Control::resetPlot(int plot, bool keepRanges) { using namespace QtCharts; if (plot < (int)w->graphingWidgets.size() && plot >= 0) @@ -826,6 +846,8 @@ void Control::resetPlot(int plot) } plotHistory[plot].clear(); onTopSeries[plot].clear(); + if (!keepRanges) + axisRanges[plot] = AxisRanges(); } } @@ -975,3 +997,16 @@ void Control::saveProblem() setStatusMessage("Error writing File " + path, 5000); } } + +void Control::setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max) +{ + if (plot < (int)w->graphingWidgets.size() && plot >= 0) + { + axisRanges[plot].x_min = x_min; + axisRanges[plot].x_max = x_max; + axisRanges[plot].y_min = y_min; + axisRanges[plot].y_max = y_max; + axisRanges[plot].set = x_min != x_max && y_min != y_max; + resizeAxes(plot); + } +} diff --git a/src/control.h b/src/control.h index c40ae689d4ed72a75689437095da26a32623678e..0b2aed85d81423b688c050cd2cfde9339224d873 100644 --- a/src/control.h +++ b/src/control.h @@ -13,6 +13,14 @@ class Control : public QObject { Q_OBJECT private: + struct AxisRanges + { + float x_min = 0; + float x_max = 0; + float y_min = 0; + float y_max = 0; + bool set = false; + }; struct Algorithm { void (*algorithm)(); @@ -38,6 +46,7 @@ private: std::vector<cute::Point> getProblem(); void resizeAxes(int plot); std::vector<std::vector<QtCharts::QAbstractSeries*>> onTopSeries; + std::vector<AxisRanges> axisRanges; void redrawOnTopSeries(int plot); std::vector<std::vector<std::variant<QtCharts::QAbstractSeries*, QGraphicsItem*>>> plotHistory; @@ -65,6 +74,7 @@ public slots: void setLegendVisible(int plot, bool visible); void setAxisTitles(int plot, QString x, QString y); void setAxisVisible(int plot, bool x, bool y); + void setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max); void onRunButton(); void onSetupButton(); void onAlgoSelected(int index); @@ -75,7 +85,7 @@ public slots: void plotXYSeries(QtCharts::QXYSeries* s, int plot, bool onTop, bool legend, QString tooltip = ""); void plotBarSeries(QtCharts::QBarSeries* series, int plot, bool onTop, bool legend); void highlightValue(float value, int plot, QColor c); - void resetPlot(int plot); + void resetPlot(int plot, bool keepRanges); void undo(int plot); void saveProblem(); void addPlot(int type); diff --git a/src/cute.cpp b/src/cute.cpp index 084eb1861a7e618ac4ae46a6b6663eac34cf3c3b..d188170d4994b612d7c7e8403a529abdeb19fa30 100644 --- a/src/cute.cpp +++ b/src/cute.cpp @@ -138,6 +138,10 @@ void cute::setAxisVisible(int plot, bool x, bool y) CuteControl::get().setAxisVisible(plot, x, y); } +void cute::setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max) +{ + CuteControl::get().setAxisRange(plot, x_min, x_max, y_min, y_max); +} void cute::registerAlgorithm(void (*func)(), const std::string& name, void (*localSetup)()) { @@ -201,10 +205,10 @@ void cute::undo(int plot) timerResumeInternal(); } -void cute::resetPlot(int plot) +void cute::resetPlot(int plot, bool keepRanges) { timerPauseInternal(); - CuteControl::get().resetPlot(plot); + CuteControl::get().resetPlot(plot, keepRanges); timerResumeInternal(); } diff --git a/src/cuteControl.h b/src/cuteControl.h index d9a31697b2c7912e69f535459b58244a0329b083..48fcbf605c5da6b4db4bdd67c89d9a3add60d6d0 100644 --- a/src/cuteControl.h +++ b/src/cuteControl.h @@ -39,10 +39,11 @@ signals: void s_setLegendVisible(int plot, bool visible); void s_setAxisTitles(int plot, QString x, QString y); void s_setAxisVisible(int plot, bool x, bool y); + void s_setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max); void s_plotXYSeries(QtCharts::QXYSeries* series, int plot, bool onTop, bool legend, QString tooltip = ""); void s_plotBarSeries(QtCharts::QBarSeries* series, int plot, bool onTop, bool legend); void s_highlightValue(float value, int plot, QColor c); - void s_resetPlot(int plot); + void s_resetPlot(int plot, bool keepRanges); void s_undo(int plot); void s_verbosityChanged(int level); @@ -86,6 +87,10 @@ public: void setPlotVisible(int plot, bool visible) { emit s_setPlotVisible(plot, visible); } + void setAxisRange(int plot, float x_min, float x_max, float y_min, float y_max) { + emit s_setAxisRange(plot, x_min, x_max, y_min, y_max); + } + void enableAutorun(bool run) { emit s_enableAutorun(run); } void setProblemSize(int n) { emit s_setProblemSize(n); } @@ -230,7 +235,7 @@ public: emit s_plotXYSeries(s, plot, properties.onTop, legend); } - void resetPlot(int plot) { emit s_resetPlot(plot); } + void resetPlot(int plot, bool keepRanges) { emit s_resetPlot(plot, keepRanges); } void undo(int plot) { emit s_undo(plot); } void setPlotScale(int plot, cute::Scale x, cute::Scale y) { emit s_setPlotScale(plot, (int)x, (int)y); } void setLegendVisible(int plot, bool visible) { emit s_setLegendVisible(plot, visible); }