Warning, file /education/labplot/tests/cartesianplot/CartesianPlotTest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     File                 : CartesianPlotTest.cpp
0003     Project              : LabPlot
0004     Description          : Tests for cartesian plot
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2022 Stefan Gerlach <stefan.gerlach@uni.kn>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "CartesianPlotTest.h"
0012 #include "tests/CommonTest.h"
0013 
0014 #include "backend/core/Project.h"
0015 #include "backend/core/Workbook.h"
0016 #include "backend/lib/macros.h"
0017 #include "backend/matrix/Matrix.h"
0018 #include "backend/spreadsheet/Spreadsheet.h"
0019 #include "backend/worksheet/InfoElement.h"
0020 #include "backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h"
0021 #include "backend/worksheet/plots/cartesian/CartesianPlot.h"
0022 #include "backend/worksheet/plots/cartesian/CartesianPlotPrivate.h"
0023 #include "backend/worksheet/plots/cartesian/Histogram.h"
0024 #include "backend/worksheet/plots/cartesian/XYCurve.h"
0025 #include "backend/worksheet/plots/cartesian/XYEquationCurve.h"
0026 #include "backend/worksheet/plots/cartesian/XYFitCurve.h"
0027 #include "commonfrontend/worksheet/WorksheetView.h"
0028 #include "kdefrontend/dockwidgets/XYFitCurveDock.h"
0029 
0030 #include <QAction>
0031 #include <QUndoStack>
0032 
0033 void CartesianPlotTest::initTestCase() {
0034     //  // needed in order to have the signals triggered by SignallingUndoCommand, see LabPlot.cpp
0035     //  //TODO: redesign/remove this
0036     qRegisterMetaType<const AbstractAspect*>("const AbstractAspect*");
0037     qRegisterMetaType<const AbstractColumn*>("const AbstractColumn*");
0038 }
0039 
0040 // ##############################################################################
0041 // #####################  import of LabPlot projects ############################
0042 // ##############################################################################
0043 
0044 #define LOAD_PROJECT_DATA_CHANGE                                                                                                                               \
0045     Project project;                                                                                                                                           \
0046     project.load(QFINDTESTDATA(QLatin1String("data/TestDataChange.lml")));                                                                                     \
0047                                                                                                                                                                \
0048     /* check the project tree for the imported project */                                                                                                      \
0049     /* Spreadsheet */                                                                                                                                          \
0050     auto* aspect = project.child<AbstractAspect>(0);                                                                                                           \
0051     QVERIFY(aspect != nullptr);                                                                                                                                \
0052     if (aspect)                                                                                                                                                \
0053         QCOMPARE(aspect->name(), QLatin1String("Spreadsheet"));                                                                                                \
0054     QVERIFY(aspect->type() == AspectType::Spreadsheet);                                                                                                        \
0055     auto s = dynamic_cast<Spreadsheet*>(aspect);                                                                                                               \
0056     if (!s)                                                                                                                                                    \
0057         return;                                                                                                                                                \
0058     auto* c1 = static_cast<Column*>(s->child<Column>(0));                                                                                                      \
0059     QVERIFY(c1 != nullptr);                                                                                                                                    \
0060     QCOMPARE(c1->name(), QLatin1String("1"));                                                                                                                  \
0061     QVERIFY(c1->columnMode() == AbstractColumn::ColumnMode::Double);                                                                                           \
0062     QVERIFY(c1->rowCount() == 100);                                                                                                                            \
0063     QVERIFY(c1->valueAt(0) == 1.);                                                                                                                             \
0064     QVERIFY(c1->valueAt(1) == 2.);                                                                                                                             \
0065     auto* c2 = static_cast<Column*>(s->child<Column>(1));                                                                                                      \
0066     QVERIFY(c2 != nullptr);                                                                                                                                    \
0067     QCOMPARE(c2->name(), QLatin1String("2"));                                                                                                                  \
0068     QVERIFY(c2->columnMode() == AbstractColumn::ColumnMode::Double);                                                                                           \
0069     QVERIFY(c2->rowCount() == 100);                                                                                                                            \
0070     QVERIFY(c2->valueAt(0) == 1.);                                                                                                                             \
0071     QVERIFY(c2->valueAt(1) == 2.);                                                                                                                             \
0072                                                                                                                                                                \
0073     /* Worksheet */                                                                                                                                            \
0074     aspect = project.child<AbstractAspect>(1);                                                                                                                 \
0075     QVERIFY(aspect != nullptr);                                                                                                                                \
0076     if (aspect)                                                                                                                                                \
0077         QCOMPARE(aspect->name(), QLatin1String("Worksheet - Spreadsheet"));                                                                                    \
0078     QVERIFY(aspect->type() == AspectType::Worksheet);                                                                                                          \
0079     auto* w = dynamic_cast<Worksheet*>(aspect);                                                                                                                \
0080     if (!w)                                                                                                                                                    \
0081         return;                                                                                                                                                \
0082                                                                                                                                                                \
0083     auto* plot = dynamic_cast<CartesianPlot*>(aspect->child<CartesianPlot>(0));                                                                                \
0084     QVERIFY(plot != nullptr);                                                                                                                                  \
0085     if (!plot)                                                                                                                                                 \
0086         return;                                                                                                                                                \
0087                                                                                                                                                                \
0088     /* curve */                                                                                                                                                \
0089     auto* curve = dynamic_cast<XYCurve*>(plot->child<XYCurve>(0));                                                                                             \
0090     QVERIFY(curve != nullptr);                                                                                                                                 \
0091     if (!curve)                                                                                                                                                \
0092         return;                                                                                                                                                \
0093     QCOMPARE(curve->name(), QStringLiteral("2"));                                                                                                              \
0094                                                                                                                                                                \
0095     CHECK_RANGE(plot, curve, Dimension::X, 1., 2.);                                                                                                            \
0096     CHECK_RANGE(plot, curve, Dimension::Y, 1., 2.);                                                                                                            \
0097                                                                                                                                                                \
0098     auto* xAxis = static_cast<Axis*>(plot->child<Axis>(0));                                                                                                    \
0099     QVERIFY(xAxis != nullptr);                                                                                                                                 \
0100     QCOMPARE(xAxis->orientation() == Axis::Orientation::Horizontal, true);                                                                                     \
0101                                                                                                                                                                \
0102     auto* yAxis = static_cast<Axis*>(plot->child<Axis>(2));                                                                                                    \
0103     QVERIFY(yAxis != nullptr);                                                                                                                                 \
0104     QCOMPARE(yAxis->orientation() == Axis::Orientation::Vertical, true);
0105 
0106 #define LOAD_PROJECT_HISTOGRAM_FIT_CURVE                                                                                                                       \
0107     Project project;                                                                                                                                           \
0108     project.load(QFINDTESTDATA(QLatin1String("data/histogram-fit-curve.lml")));                                                                                \
0109                                                                                                                                                                \
0110     /* TODO: check the project tree for the imported project */                                                                                                \
0111     /* Spreadsheet */                                                                                                                                          \
0112     auto* aspect = project.child<AbstractAspect>(0);                                                                                                           \
0113     QVERIFY(aspect != nullptr);                                                                                                                                \
0114     if (aspect)                                                                                                                                                \
0115         QCOMPARE(aspect->name(), QLatin1String("Spreadsheet"));                                                                                                \
0116     QVERIFY(aspect->type() == AspectType::Spreadsheet);                                                                                                        \
0117     auto s = dynamic_cast<Spreadsheet*>(aspect);                                                                                                               \
0118     if (!s)                                                                                                                                                    \
0119         return;                                                                                                                                                \
0120     auto* c1 = static_cast<Column*>(s->child<Column>(0));                                                                                                      \
0121     QVERIFY(c1 != nullptr);                                                                                                                                    \
0122     QCOMPARE(c1->name(), QLatin1String("Data"));                                                                                                               \
0123     QVERIFY(c1->columnMode() == AbstractColumn::ColumnMode::Double);                                                                                           \
0124     QVERIFY(c1->rowCount() == 10000);                                                                                                                          \
0125                                                                                                                                                                \
0126     /* Worksheet */                                                                                                                                            \
0127     aspect = project.child<AbstractAspect>(1);                                                                                                                 \
0128     QVERIFY(aspect != nullptr);                                                                                                                                \
0129     if (aspect)                                                                                                                                                \
0130         QCOMPARE(aspect->name(), QLatin1String("Worksheet - Spreadsheet"));                                                                                    \
0131     QVERIFY(aspect->type() == AspectType::Worksheet);                                                                                                          \
0132     auto* w = dynamic_cast<Worksheet*>(aspect);                                                                                                                \
0133     if (!w)                                                                                                                                                    \
0134         return;                                                                                                                                                \
0135                                                                                                                                                                \
0136     auto* plot = dynamic_cast<CartesianPlot*>(aspect->child<CartesianPlot>(0));                                                                                \
0137     QVERIFY(plot != nullptr);                                                                                                                                  \
0138     if (!plot)                                                                                                                                                 \
0139         return;                                                                                                                                                \
0140                                                                                                                                                                \
0141     auto* h = dynamic_cast<Histogram*>(plot->child<Histogram>(0));                                                                                             \
0142     QVERIFY(h != nullptr);                                                                                                                                     \
0143     if (!h)                                                                                                                                                    \
0144         return;                                                                                                                                                \
0145     QCOMPARE(h->name(), QStringLiteral("histogram"));                                                                                                          \
0146                                                                                                                                                                \
0147     /* curves */                                                                                                                                               \
0148     auto* curve1 = dynamic_cast<XYCurve*>(plot->child<XYCurve>(0));                                                                                            \
0149     QVERIFY(curve1 != nullptr);                                                                                                                                \
0150     if (!curve1)                                                                                                                                               \
0151         return;                                                                                                                                                \
0152     QCOMPARE(curve1->name(), QStringLiteral("fit"));                                                                                                           \
0153     auto* curve2 = dynamic_cast<XYCurve*>(plot->child<XYCurve>(1));                                                                                            \
0154     QVERIFY(curve2 != nullptr);                                                                                                                                \
0155     if (!curve2)                                                                                                                                               \
0156         return;                                                                                                                                                \
0157     QCOMPARE(curve2->name(), QStringLiteral("f(x)"));                                                                                                          \
0158                                                                                                                                                                \
0159     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);                                                                                                          \
0160     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 1.);
0161 
0162 #define SET_CARTESIAN_MOUSE_MODE(mode)                                                                                                                         \
0163     QAction a(nullptr);                                                                                                                                        \
0164     a.setData(static_cast<int>(mode));                                                                                                                         \
0165     view->cartesianPlotMouseModeChanged(&a);
0166 
0167 /*!
0168  * \brief CartesianPlotTest::changeData1: add data point
0169  *
0170  */
0171 
0172 void CartesianPlotTest::changeData1() {
0173     LOAD_PROJECT_DATA_CHANGE
0174 
0175     // insert data
0176     c1->setValueAt(2, 3.);
0177     c2->setValueAt(2, 3.);
0178 
0179     QVERIFY(c1->valueAt(2) == 3.);
0180     QVERIFY(c2->valueAt(2) == 3.);
0181 
0182     CHECK_RANGE(plot, curve, Dimension::X, 1., 3.);
0183     CHECK_RANGE(plot, curve, Dimension::Y, 1., 3.);
0184 }
0185 
0186 void CartesianPlotTest::changeData2() {
0187     LOAD_PROJECT_DATA_CHANGE
0188 
0189     // insert data
0190     c1->setValueAt(2, 3.);
0191     c2->setValueAt(2, 2.);
0192 
0193     QVERIFY(c1->valueAt(2) == 3.);
0194     QVERIFY(c2->valueAt(2) == 2.);
0195 
0196     CHECK_RANGE(plot, curve, Dimension::X, 1., 3.);
0197     CHECK_RANGE(plot, curve, Dimension::Y, 1., 2.);
0198 
0199     DEBUG_RANGE(plot, curve);
0200 }
0201 
0202 void CartesianPlotTest::changeData3() {
0203     LOAD_PROJECT_DATA_CHANGE
0204 
0205     // insert data
0206     c1->setValueAt(2, 2.);
0207     c2->setValueAt(2, 3.);
0208 
0209     QVERIFY(c1->valueAt(2) == 2.);
0210     QVERIFY(c2->valueAt(2) == 3.);
0211 
0212     CHECK_RANGE(plot, curve, Dimension::X, 1., 2.);
0213     CHECK_RANGE(plot, curve, Dimension::Y, 1., 3.);
0214 }
0215 
0216 void CartesianPlotTest::changeData4() {
0217     LOAD_PROJECT_DATA_CHANGE
0218 
0219     // insert data
0220     c2->setValueAt(2, 3.);
0221     c1->setValueAt(2, 3.);
0222 
0223     QVERIFY(c1->valueAt(2) == 3.);
0224     QVERIFY(c2->valueAt(2) == 3.);
0225 
0226     CHECK_RANGE(plot, curve, Dimension::X, 1., 3.);
0227     CHECK_RANGE(plot, curve, Dimension::Y, 1., 3.);
0228 }
0229 
0230 void CartesianPlotTest::changeData5() {
0231     LOAD_PROJECT_DATA_CHANGE
0232 
0233     // insert data
0234     c2->setValueAt(2, 2.);
0235     c1->setValueAt(2, 3.);
0236 
0237     QVERIFY(c1->valueAt(2) == 3.);
0238     QVERIFY(c2->valueAt(2) == 2.);
0239 
0240     CHECK_RANGE(plot, curve, Dimension::X, 1., 3.);
0241     CHECK_RANGE(plot, curve, Dimension::Y, 1., 2.);
0242 }
0243 
0244 void CartesianPlotTest::changeData6() {
0245     LOAD_PROJECT_DATA_CHANGE
0246 
0247     // insert data
0248     c2->setValueAt(2, 3.);
0249     c1->setValueAt(2, 2.);
0250 
0251     QVERIFY(c1->valueAt(2) == 2.);
0252     QVERIFY(c2->valueAt(2) == 3.);
0253 
0254     CHECK_RANGE(plot, curve, Dimension::X, 1., 2.);
0255     CHECK_RANGE(plot, curve, Dimension::Y, 1., 3.);
0256 }
0257 
0258 // check deleting curve
0259 
0260 void CartesianPlotTest::deleteCurveAutoscale() {
0261     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0262 
0263     // delete curve in plot
0264     plot->removeChild(curve2);
0265 
0266     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0267     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 0.45);
0268 }
0269 
0270 void CartesianPlotTest::deleteCurveNoAutoscale() {
0271     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0272     const auto cs = plot->coordinateSystem(curve2->coordinateSystemIndex());
0273     plot->enableAutoScale(Dimension::Y, cs->index(Dimension::Y), false, false);
0274 
0275     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0276     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 1.);
0277 
0278     // delete curve in plot
0279     plot->removeChild(curve2);
0280 
0281     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0282     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 1.);
0283 
0284     QCOMPARE(plot->autoScale(Dimension::Y, cs->index(Dimension::Y)), false);
0285 }
0286 
0287 void CartesianPlotTest::invisibleCurveAutoscale() {
0288     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0289 
0290     curve2->setVisible(false);
0291 
0292     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0293     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 0.45);
0294 }
0295 
0296 void CartesianPlotTest::invisibleCurveNoAutoscale() {
0297     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0298     const auto cs = plot->coordinateSystem(curve2->coordinateSystemIndex());
0299     plot->enableAutoScale(Dimension::Y, cs->index(Dimension::Y), false, false);
0300 
0301     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0302     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 1.);
0303 
0304     curve2->setVisible(false);
0305 
0306     CHECK_RANGE(plot, curve1, Dimension::X, -4., 4.);
0307     CHECK_RANGE(plot, curve1, Dimension::Y, 0., 1.);
0308 
0309     QCOMPARE(plot->autoScale(Dimension::Y, cs->index(Dimension::Y)), false);
0310 }
0311 
0312 void CartesianPlotTest::equationCurveEquationChangedAutoScale() {
0313     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0314     const auto cs = plot->coordinateSystem(curve2->coordinateSystemIndex());
0315 
0316     QCOMPARE(curve2->type(), AspectType::XYEquationCurve);
0317     auto eqc = static_cast<XYEquationCurve*>(curve2);
0318 
0319     auto equationData = eqc->equationData();
0320     equationData.max = QStringLiteral("10");
0321     eqc->setEquationData(equationData);
0322 
0323     CHECK_RANGE(plot, curve2, Dimension::X, -4., 10.);
0324     CHECK_RANGE(plot, curve2, Dimension::Y, 0., 10.);
0325 
0326     QCOMPARE(plot->autoScale(Dimension::Y, cs->index(Dimension::Y)), true);
0327 }
0328 
0329 void CartesianPlotTest::equationCurveEquationChangedNoAutoScale() {
0330     LOAD_PROJECT_HISTOGRAM_FIT_CURVE
0331     const auto cs = plot->coordinateSystem(curve2->coordinateSystemIndex());
0332     plot->enableAutoScale(Dimension::Y, cs->index(Dimension::Y), false, false);
0333 
0334     QCOMPARE(curve2->type(), AspectType::XYEquationCurve);
0335     auto eqc = static_cast<XYEquationCurve*>(curve2);
0336 
0337     auto equationData = eqc->equationData();
0338     equationData.max = QStringLiteral("10");
0339     eqc->setEquationData(equationData);
0340 
0341     CHECK_RANGE(plot, curve2, Dimension::X, -4., 10.);
0342     CHECK_RANGE(plot, curve2, Dimension::Y, 0., 1.);
0343 
0344     QCOMPARE(plot->autoScale(Dimension::Y, cs->index(Dimension::Y)), false);
0345 }
0346 
0347 void CartesianPlotTest::undoInfoElement() {
0348     auto* project = new Project();
0349     auto* worksheet = new Worksheet(QStringLiteral("ws"));
0350     project->addChild(worksheet);
0351 
0352     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0353     worksheet->addChild(plot);
0354 
0355     auto* curve = new XYCurve(QStringLiteral("curve"));
0356     plot->addChild(curve);
0357 
0358     auto* info = new InfoElement(QStringLiteral("info"), plot, curve, 0.);
0359     plot->addChild(info);
0360 
0361     QCOMPARE(plot->childCount<InfoElement>(), 1);
0362 
0363     // undo the last step
0364     project->undoStack()->undo();
0365     QCOMPARE(plot->childCount<InfoElement>(), 0);
0366 
0367     // redo
0368     project->undoStack()->redo();
0369     QCOMPARE(plot->childCount<InfoElement>(), 1);
0370 }
0371 
0372 void CartesianPlotTest::axisFormat() {
0373     // testing #74
0374 
0375     QString savePath;
0376     {
0377         Project project;
0378 
0379         Spreadsheet* sheet = new Spreadsheet(QStringLiteral("Spreadsheet"), false);
0380         project.addChild(sheet);
0381 
0382         sheet->setColumnCount(2);
0383         sheet->setRowCount(3);
0384 
0385         sheet->column(0)->setColumnMode(AbstractColumn::ColumnMode::DateTime);
0386         sheet->column(1)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0387 
0388         sheet->column(0)->setDateTimeAt(0, QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0389         sheet->column(0)->setDateTimeAt(1, QDateTime::fromString(QStringLiteral("2022-02-04 12:23:00"), Qt::ISODate));
0390         sheet->column(0)->setDateTimeAt(2, QDateTime::fromString(QStringLiteral("2022-02-05 12:23:00"), Qt::ISODate));
0391 
0392         QCOMPARE(sheet->column(0)->dateTimeAt(0), QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0393 
0394         sheet->column(1)->setValueAt(0, 0);
0395         sheet->column(1)->setValueAt(1, 1);
0396         sheet->column(1)->setValueAt(2, 2);
0397 
0398         auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0399         project.addChild(worksheet);
0400 
0401         auto* plot = new CartesianPlot(QStringLiteral("plot"));
0402         worksheet->addChild(plot);
0403         plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0404 
0405         auto* curve = new XYCurve(QStringLiteral("curve"));
0406         plot->addChild(curve);
0407 
0408         curve->setXColumn(sheet->column(0));
0409         curve->setYColumn(sheet->column(1));
0410 
0411         auto* xAxis = static_cast<Axis*>(plot->child<Axis>(0));
0412         QVERIFY(xAxis);
0413         QCOMPARE(xAxis->name(), QStringLiteral("x"));
0414 
0415         const auto original = xAxis->labelsDateTimeFormat();
0416         const auto newFormat = QStringLiteral("yyyy-MM-dd hh:mm");
0417         QVERIFY(original != newFormat);
0418         xAxis->setLabelsDateTimeFormat(newFormat);
0419 
0420         SAVE_PROJECT("TestAxisDateTimeFormat.lml");
0421     }
0422 
0423     {
0424         Project project;
0425         project.load(savePath);
0426 
0427         /* check the project tree for the imported project */
0428         /* Spreadsheet */
0429         auto* aspect = project.child<AbstractAspect>(0);
0430         QVERIFY(aspect);
0431         QCOMPARE(aspect->name(), QLatin1String("Spreadsheet"));
0432         QVERIFY(aspect->type() == AspectType::Spreadsheet);
0433 
0434         /* Worksheet */
0435         aspect = project.child<AbstractAspect>(1);
0436         QVERIFY(aspect);
0437         QCOMPARE(aspect->name(), QLatin1String("Worksheet"));
0438         QVERIFY(aspect->type() == AspectType::Worksheet);
0439         auto* w = dynamic_cast<Worksheet*>(aspect);
0440         QVERIFY(w);
0441 
0442         auto* plot = dynamic_cast<CartesianPlot*>(aspect->child<CartesianPlot>(0));
0443         QVERIFY(plot);
0444 
0445         auto* xAxis = static_cast<Axis*>(plot->child<Axis>(0));
0446         QVERIFY(xAxis);
0447         QCOMPARE(xAxis->name(), QStringLiteral("x"));
0448         QCOMPARE(xAxis->labelsDateTimeFormat(), QStringLiteral("yyyy-MM-dd hh:mm"));
0449     }
0450 }
0451 
0452 void CartesianPlotTest::shiftLeftAutoScale() {
0453     Project project;
0454     auto* ws = new Worksheet(QStringLiteral("worksheet"));
0455     QVERIFY(ws != nullptr);
0456     project.addChild(ws);
0457 
0458     auto* p = new CartesianPlot(QStringLiteral("plot"));
0459     p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0460     QVERIFY(p != nullptr);
0461     ws->addChild(p);
0462 
0463     auto* curve{new XYEquationCurve(QStringLiteral("f(x)"))};
0464     curve->setCoordinateSystemIndex(p->defaultCoordinateSystemIndex());
0465     p->addChild(curve);
0466 
0467     XYEquationCurve::EquationData data;
0468     data.min = QStringLiteral("1");
0469     data.max = QStringLiteral("2");
0470     data.count = 1000;
0471     data.expression1 = QStringLiteral("x");
0472     curve->setEquationData(data);
0473     curve->recalculate();
0474 
0475     CHECK_RANGE(p, curve, Dimension::X, 1., 2.);
0476     CHECK_RANGE(p, curve, Dimension::Y, 1., 2.);
0477 
0478     p->shiftLeftX();
0479 
0480     // Autoscale of the y range was done
0481     CHECK_RANGE(p, curve, Dimension::X, 1.1, 2.1);
0482     CHECK_RANGE(p, curve, Dimension::Y, 1.1, 2.); // changed range
0483 }
0484 
0485 void CartesianPlotTest::shiftRightAutoScale() {
0486     Project project;
0487     auto* ws = new Worksheet(QStringLiteral("worksheet"));
0488     QVERIFY(ws != nullptr);
0489     project.addChild(ws);
0490 
0491     auto* p = new CartesianPlot(QStringLiteral("plot"));
0492     p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0493     QVERIFY(p != nullptr);
0494     ws->addChild(p);
0495 
0496     auto* curve{new XYEquationCurve(QStringLiteral("f(x)"))};
0497     curve->setCoordinateSystemIndex(p->defaultCoordinateSystemIndex());
0498     p->addChild(curve);
0499 
0500     XYEquationCurve::EquationData data;
0501     data.min = QStringLiteral("1");
0502     data.max = QStringLiteral("2");
0503     data.count = 1000;
0504     data.expression1 = QStringLiteral("x");
0505     curve->setEquationData(data);
0506     curve->recalculate();
0507 
0508     CHECK_RANGE(p, curve, Dimension::X, 1., 2.);
0509     CHECK_RANGE(p, curve, Dimension::Y, 1., 2.);
0510 
0511     p->shiftRightX();
0512 
0513     // Autoscale of the y range was done
0514     CHECK_RANGE(p, curve, Dimension::X, 0.9, 1.9);
0515     CHECK_RANGE(p, curve, Dimension::Y, 1., 1.9); // changed range
0516 }
0517 
0518 void CartesianPlotTest::shiftUpAutoScale() {
0519     Project project;
0520     auto* ws = new Worksheet(QStringLiteral("worksheet"));
0521     QVERIFY(ws != nullptr);
0522     project.addChild(ws);
0523 
0524     auto* p = new CartesianPlot(QStringLiteral("plot"));
0525     p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0526     QVERIFY(p != nullptr);
0527     ws->addChild(p);
0528 
0529     auto* curve{new XYEquationCurve(QStringLiteral("f(x)"))};
0530     curve->setCoordinateSystemIndex(p->defaultCoordinateSystemIndex());
0531     p->addChild(curve);
0532 
0533     XYEquationCurve::EquationData data;
0534     data.min = QStringLiteral("1");
0535     data.max = QStringLiteral("2");
0536     data.count = 1000;
0537     data.expression1 = QStringLiteral("x");
0538     curve->setEquationData(data);
0539     curve->recalculate();
0540 
0541     CHECK_RANGE(p, curve, Dimension::X, 1., 2.);
0542     CHECK_RANGE(p, curve, Dimension::Y, 1., 2.);
0543 
0544     p->shiftUpY();
0545 
0546     // Autoscale of the y range was done
0547     CHECK_RANGE(p, curve, Dimension::X, 1., 1.9);
0548     CHECK_RANGE(p, curve, Dimension::Y, 0.9, 1.9); // changed range
0549 }
0550 
0551 void CartesianPlotTest::shiftDownAutoScale() {
0552     Project project;
0553     auto* ws = new Worksheet(QStringLiteral("worksheet"));
0554     QVERIFY(ws != nullptr);
0555     project.addChild(ws);
0556 
0557     auto* p = new CartesianPlot(QStringLiteral("plot"));
0558     p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0559     QVERIFY(p != nullptr);
0560     ws->addChild(p);
0561 
0562     auto* curve{new XYEquationCurve(QStringLiteral("f(x)"))};
0563     curve->setCoordinateSystemIndex(p->defaultCoordinateSystemIndex());
0564     p->addChild(curve);
0565 
0566     XYEquationCurve::EquationData data;
0567     data.min = QStringLiteral("1");
0568     data.max = QStringLiteral("2");
0569     data.count = 1000;
0570     data.expression1 = QStringLiteral("x");
0571     curve->setEquationData(data);
0572     curve->recalculate();
0573 
0574     CHECK_RANGE(p, curve, Dimension::X, 1., 2.);
0575     CHECK_RANGE(p, curve, Dimension::Y, 1., 2.);
0576 
0577     p->shiftDownY();
0578 
0579     // Autoscale of the y range was done
0580     CHECK_RANGE(p, curve, Dimension::X, 1.1, 2.);
0581     CHECK_RANGE(p, curve, Dimension::Y, 1.1, 2.1); // changed range
0582 }
0583 
0584 void CartesianPlotTest::rangeFormatYDataChanged() {
0585     Project project;
0586 
0587     Spreadsheet* sheet = new Spreadsheet(QStringLiteral("Spreadsheet"), false);
0588     project.addChild(sheet);
0589 
0590     sheet->setColumnCount(2);
0591     sheet->setRowCount(3);
0592 
0593     sheet->column(0)->setColumnMode(AbstractColumn::ColumnMode::DateTime);
0594     sheet->column(1)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0595 
0596     sheet->column(0)->setDateTimeAt(0, QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0597     sheet->column(0)->setDateTimeAt(1, QDateTime::fromString(QStringLiteral("2022-02-04 12:23:00"), Qt::ISODate));
0598     sheet->column(0)->setDateTimeAt(2, QDateTime::fromString(QStringLiteral("2022-02-05 12:23:00"), Qt::ISODate));
0599 
0600     QCOMPARE(sheet->column(0)->dateTimeAt(0), QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0601 
0602     sheet->column(1)->setValueAt(0, 0);
0603     sheet->column(1)->setValueAt(1, 1);
0604     sheet->column(1)->setValueAt(2, 2);
0605 
0606     auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0607     project.addChild(worksheet);
0608 
0609     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0610     worksheet->addChild(plot);
0611     plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0612 
0613     auto* curve = new XYCurve(QStringLiteral("curve"));
0614     plot->addChild(curve);
0615 
0616     curve->setXColumn(sheet->column(0));
0617     curve->setYColumn(sheet->column(1));
0618 
0619     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::DateTime);
0620     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0621 
0622     // simulate data change
0623     plot->dataChanged(curve, Dimension::Y);
0624 
0625     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::DateTime);
0626     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0627 }
0628 
0629 void CartesianPlotTest::rangeFormatXDataChanged() {
0630     Project project;
0631 
0632     Spreadsheet* sheet = new Spreadsheet(QStringLiteral("Spreadsheet"), false);
0633     project.addChild(sheet);
0634 
0635     sheet->setColumnCount(2);
0636     sheet->setRowCount(3);
0637 
0638     sheet->column(0)->setColumnMode(AbstractColumn::ColumnMode::DateTime);
0639     sheet->column(1)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0640 
0641     sheet->column(0)->setDateTimeAt(0, QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0642     sheet->column(0)->setDateTimeAt(1, QDateTime::fromString(QStringLiteral("2022-02-04 12:23:00"), Qt::ISODate));
0643     sheet->column(0)->setDateTimeAt(2, QDateTime::fromString(QStringLiteral("2022-02-05 12:23:00"), Qt::ISODate));
0644 
0645     QCOMPARE(sheet->column(0)->dateTimeAt(0), QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0646 
0647     sheet->column(1)->setValueAt(0, 0);
0648     sheet->column(1)->setValueAt(1, 1);
0649     sheet->column(1)->setValueAt(2, 2);
0650 
0651     auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0652     project.addChild(worksheet);
0653 
0654     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0655     worksheet->addChild(plot);
0656     plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0657 
0658     auto* curve = new XYCurve(QStringLiteral("curve"));
0659     plot->addChild(curve);
0660 
0661     curve->setXColumn(sheet->column(1));
0662     curve->setYColumn(sheet->column(0));
0663 
0664     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0665     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::DateTime);
0666 
0667     // simulate data change
0668     plot->dataChanged(curve, Dimension::X);
0669 
0670     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0671     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::DateTime);
0672 }
0673 
0674 void CartesianPlotTest::rangeFormatNonDefaultRange() {
0675     Project project;
0676 
0677     Spreadsheet* sheet = new Spreadsheet(QStringLiteral("Spreadsheet"), false);
0678     project.addChild(sheet);
0679 
0680     sheet->setColumnCount(4);
0681     sheet->setRowCount(3);
0682 
0683     sheet->column(0)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0684     sheet->column(1)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0685     sheet->column(2)->setColumnMode(AbstractColumn::ColumnMode::DateTime);
0686     sheet->column(3)->setColumnMode(AbstractColumn::ColumnMode::Integer);
0687 
0688     sheet->column(0)->setValueAt(0, 0);
0689     sheet->column(0)->setValueAt(1, 1);
0690     sheet->column(0)->setValueAt(2, 2);
0691 
0692     sheet->column(1)->setValueAt(0, 5);
0693     sheet->column(1)->setValueAt(1, 6);
0694     sheet->column(1)->setValueAt(2, 7);
0695 
0696     sheet->column(2)->setDateTimeAt(0, QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0697     sheet->column(2)->setDateTimeAt(1, QDateTime::fromString(QStringLiteral("2022-02-04 12:23:00"), Qt::ISODate));
0698     sheet->column(2)->setDateTimeAt(2, QDateTime::fromString(QStringLiteral("2022-02-05 12:23:00"), Qt::ISODate));
0699 
0700     QCOMPARE(sheet->column(2)->dateTimeAt(0), QDateTime::fromString(QStringLiteral("2022-02-03 12:23:00"), Qt::ISODate));
0701 
0702     sheet->column(3)->setValueAt(0, 8);
0703     sheet->column(3)->setValueAt(1, 10);
0704     sheet->column(3)->setValueAt(2, 9);
0705 
0706     auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0707     project.addChild(worksheet);
0708 
0709     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0710     worksheet->addChild(plot);
0711     plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0712 
0713     // Create new cSystem
0714     Range<double> xRange;
0715     xRange.setFormat(RangeT::Format::Numeric);
0716     Range<double> yRange;
0717     yRange.setFormat(RangeT::Format::Numeric);
0718     plot->addXRange(xRange);
0719     plot->addYRange(yRange);
0720     CartesianCoordinateSystem* cSystem = new CartesianCoordinateSystem(plot);
0721     cSystem->setIndex(Dimension::X, 1);
0722     cSystem->setIndex(Dimension::Y, 1);
0723     plot->addCoordinateSystem(cSystem);
0724 
0725     auto* curve2 = new XYCurve(QStringLiteral("curve2"));
0726     plot->addChild(curve2);
0727 
0728     curve2->setCoordinateSystemIndex(1);
0729 
0730     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0731     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0732     QCOMPARE(plot->rangeFormat(Dimension::X, 1), RangeT::Format::Numeric);
0733     QCOMPARE(plot->rangeFormat(Dimension::Y, 1), RangeT::Format::Numeric);
0734 
0735     curve2->setXColumn(sheet->column(2));
0736 
0737     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0738     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0739     QCOMPARE(plot->rangeFormat(Dimension::X, 1), RangeT::Format::DateTime);
0740     QCOMPARE(plot->rangeFormat(Dimension::Y, 1), RangeT::Format::Numeric);
0741 
0742     curve2->setYColumn(sheet->column(3));
0743 
0744     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0745     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0746     QCOMPARE(plot->rangeFormat(Dimension::X, 1), RangeT::Format::DateTime);
0747     QCOMPARE(plot->rangeFormat(Dimension::Y, 1), RangeT::Format::Numeric);
0748 
0749     plot->dataChanged(curve2, Dimension::X);
0750 
0751     QCOMPARE(plot->rangeFormat(Dimension::X, 0), RangeT::Format::Numeric);
0752     QCOMPARE(plot->rangeFormat(Dimension::Y, 0), RangeT::Format::Numeric);
0753     QCOMPARE(plot->rangeFormat(Dimension::X, 1), RangeT::Format::DateTime);
0754     QCOMPARE(plot->rangeFormat(Dimension::Y, 1), RangeT::Format::Numeric);
0755 }
0756 
0757 /*!
0758  * \brief CartesianPlotTest::invalidcSystem
0759  * Plot with 2 CoordinateSystems (with common x range), but the second has invalid start end (0, 0).
0760  * This scenario shall not destroy the x range when zooming in
0761  *
0762  */
0763 void CartesianPlotTest::invalidcSystem() {
0764     Project project;
0765 
0766     auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0767     project.addChild(worksheet);
0768     auto* view = dynamic_cast<WorksheetView*>(worksheet->view());
0769     QVERIFY(view != nullptr);
0770     view->initActions(); // needed by SET_CARTESIAN_MOUSE_MODE()
0771 
0772     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0773     worksheet->addChild(plot);
0774     plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0775     SET_CARTESIAN_MOUSE_MODE(CartesianPlot::MouseMode::ZoomXSelection) // must be set after the plot was added
0776 
0777     // Create new cSystem
0778     Range<double> yRange;
0779     yRange.setFormat(RangeT::Format::Numeric);
0780     plot->addYRange(yRange);
0781     plot->addCoordinateSystem();
0782     QCOMPARE(plot->coordinateSystemCount(), 2);
0783 
0784     auto* cSystem{plot->coordinateSystem(1)};
0785     cSystem->setIndex(Dimension::Y, 1);
0786     plot->setRangeDirty(Dimension::Y, 1, true);
0787     plot->retransformScale(Dimension::Y, 1);
0788 
0789     {
0790         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::X, 0., 1.);
0791         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::Y, 0., 1.);
0792         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::X, 0., 1.);
0793         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::Y, 0., 1.);
0794         const Range<double> plotSceneRangeX = {plot->dataRect().x(), plot->dataRect().x() + plot->dataRect().width()};
0795         const Range<double> plotSceneRangeY = {plot->dataRect().y() + plot->dataRect().height(), plot->dataRect().y()};
0796 
0797         double bx = plotSceneRangeX.size() / (1 - 0);
0798         double ax = plotSceneRangeX.start() - bx * 0;
0799 
0800         double by = plotSceneRangeY.size() / (1 - 0);
0801         double ay = plotSceneRangeY.start() - by * 0;
0802 
0803         CHECK_SCALE_PLOT(plot, 0, Dimension::X, ax, bx, 0);
0804         CHECK_SCALE_PLOT(plot, 0, Dimension::Y, ay, by, 0);
0805         CHECK_SCALE_PLOT(plot, 1, Dimension::X, ax, bx, 0);
0806         CHECK_SCALE_PLOT(plot, 1, Dimension::Y, ay, by, 0);
0807     }
0808 
0809     // Set range of the unused y range
0810     Range<double> range;
0811     range.setStart(0); // Both are set to the same value
0812     range.setEnd(0); // Both are set to the same value
0813     range.setFormat(RangeT::Format::Numeric);
0814     range.setAutoScale(false);
0815     range.setScale(RangeT::Scale::Linear);
0816 
0817     {
0818         // plot->setRange(Dimension::Y, 1, range); // does not work
0819         // Implementation of setRange() must be used, because setRange() uses check to check if
0820         // the range is valid, which it isn't in this test. To test neverthless and not removing a test
0821         // use directly the implementation
0822         int index = 1;
0823         auto dimension = Dimension::Y;
0824         auto otherValue = range;
0825         auto plotPrivate = plot->d_func();
0826         plotPrivate->setRangeDirty(dimension, index, true);
0827         auto tmp = plotPrivate->rangeConst(dimension, index);
0828         plotPrivate->setRange(dimension, index, otherValue);
0829         otherValue = tmp;
0830         plotPrivate->retransformScale(dimension, index, true);
0831         Dimension dim_other = Dimension::Y;
0832         if (dimension == Dimension::Y)
0833             dim_other = Dimension::X;
0834 
0835         QVector<int> scaledIndices;
0836         for (int i = 0; i < plotPrivate->q->coordinateSystemCount(); i++) {
0837             auto cs = plotPrivate->q->coordinateSystem(i);
0838             auto index_other = cs->index(dim_other);
0839             if (cs->index(dimension) == index && scaledIndices.indexOf(index_other) == -1) {
0840                 scaledIndices << index_other;
0841                 if (plotPrivate->q->autoScale(dim_other, index_other) && plotPrivate->q->scaleAuto(dim_other, index_other, false))
0842                     plotPrivate->retransformScale(dim_other, index_other);
0843             }
0844         }
0845         plotPrivate->q->WorksheetElementContainer::retransform();
0846         Q_EMIT plotPrivate->q->rangeChanged(dimension, index, plotPrivate->rangeConst(dimension, index));
0847     }
0848 
0849     // Recalculate scales is triggered
0850     {
0851         QCOMPARE(plot->coordinateSystemCount(), 2);
0852 
0853         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::X, 0., 1.);
0854         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::Y, 0., 1.);
0855         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::X, 0., 1.);
0856         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::Y, 0., 0.);
0857         const Range<double> plotSceneRangeX = {plot->dataRect().x(), plot->dataRect().x() + plot->dataRect().width()};
0858         const Range<double> plotSceneRangeY = {plot->dataRect().y() + plot->dataRect().height(), plot->dataRect().y()};
0859 
0860         double bx = plotSceneRangeX.size() / (1 - 0);
0861         double ax = plotSceneRangeX.start() - bx * 0;
0862 
0863         double by = plotSceneRangeY.size() / (1 - 0);
0864         double ay = plotSceneRangeY.start() - by * 0;
0865 
0866         CHECK_SCALE_PLOT(plot, 0, Dimension::X, ax, bx, 0);
0867         CHECK_SCALE_PLOT(plot, 0, Dimension::Y, ay, by, 0);
0868         // Don't care what the second cSystem has, because it is invalid
0869         // CHECK_SCALE_PLOT(plot, 1, Dimension::X, ax, bx, 0);
0870         // CHECK_SCALE_PLOT(plot, 1, Dimension::Y, ay, by, 0);
0871     }
0872 
0873     QCOMPARE(plot->mouseMode(), CartesianPlot::MouseMode::ZoomXSelection);
0874     plot->mousePressZoomSelectionMode(QPointF(0.2, -150), -1);
0875     plot->mouseMoveZoomSelectionMode(QPointF(0.6, 100), -1);
0876     plot->mouseReleaseZoomSelectionMode(-1);
0877 
0878     {
0879         QCOMPARE(plot->coordinateSystemCount(), 2);
0880 
0881         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::X, 0.2, 0.6);
0882         CHECK_RANGE_CSYSTEMINDEX(plot, 0, Dimension::Y, 0., 1.);
0883         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::X, 0.2, 0.6);
0884         CHECK_RANGE_CSYSTEMINDEX(plot, 1, Dimension::Y, 0., 0.);
0885         const Range<double> plotSceneRangeX = {plot->dataRect().x(), plot->dataRect().x() + plot->dataRect().width()};
0886         const Range<double> plotSceneRangeY = {plot->dataRect().y() + plot->dataRect().height(), plot->dataRect().y()};
0887 
0888         double bx = plotSceneRangeX.size() / (0.6 - 0.2);
0889         double ax = plotSceneRangeX.start() - bx * 0.2;
0890 
0891         double by = plotSceneRangeY.size() / (1 - 0);
0892         double ay = plotSceneRangeY.start() - by * 0;
0893 
0894         CHECK_SCALE_PLOT(plot, 0, Dimension::X, ax, bx, 0);
0895         CHECK_SCALE_PLOT(plot, 0, Dimension::Y, ay, by, 0);
0896         // Don't care what the second cSystem has, because it is invalid
0897         // CHECK_SCALE_PLOT(plot, 1, Dimension::X, ax, bx, 0);
0898         // CHECK_SCALE_PLOT(plot, 1, Dimension::Y, ay, by, 0);
0899     }
0900 }
0901 
0902 void CartesianPlotTest::autoScaleFitCurveCalculation() {
0903     Project project;
0904 
0905     auto* worksheet = new Worksheet(QStringLiteral("Worksheet"));
0906     project.addChild(worksheet);
0907     auto* view = dynamic_cast<WorksheetView*>(worksheet->view());
0908     QVERIFY(view != nullptr);
0909     view->initActions(); // needed by SET_CARTESIAN_MOUSE_MODE()
0910 
0911     auto* plot = new CartesianPlot(QStringLiteral("plot"));
0912     worksheet->addChild(plot);
0913     plot->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
0914     plot->setNiceExtend(false);
0915 
0916     auto* equationCurve{new XYEquationCurve(QStringLiteral("f(x)"))};
0917     equationCurve->setCoordinateSystemIndex(plot->defaultCoordinateSystemIndex());
0918     plot->addChild(equationCurve);
0919 
0920     XYEquationCurve::EquationData data;
0921     data.min = QStringLiteral("0");
0922     data.max = QStringLiteral("1");
0923     data.count = 10;
0924     data.expression1 = QStringLiteral("x");
0925     equationCurve->setEquationData(data);
0926     equationCurve->recalculate();
0927 
0928     CHECK_RANGE(plot, equationCurve, Dimension::X, 0., 1.);
0929     CHECK_RANGE(plot, equationCurve, Dimension::Y, 0., 1.);
0930 
0931     auto* fitCurve = new XYFitCurve(QStringLiteral("Fit"));
0932     fitCurve->setCoordinateSystemIndex(plot->defaultCoordinateSystemIndex());
0933     plot->addChild(fitCurve);
0934 
0935     XYFitCurve::FitData f;
0936     f.autoRange = false;
0937     f.fitRange = Range<double>(0, 1);
0938     f.autoEvalRange = false;
0939     f.evalRange = Range<double>(0, 3); // larger than fit range
0940     f.modelCategory = nsl_fit_model_basic;
0941     f.modelType = nsl_fit_model_polynomial;
0942     f.degree = 1; // linear
0943     f.model = QStringLiteral("c0 + c1*x");
0944     fitCurve->initFitData(f); // Important, otherwise paramNames gets not filled
0945     fitCurve->setFitData(f);
0946     fitCurve->setDataSourceType(XYAnalysisCurve::DataSourceType::Curve);
0947     fitCurve->setDataSourceCurve(equationCurve);
0948     fitCurve->recalculate();
0949 
0950     CHECK_RANGE(plot, equationCurve, Dimension::X, 0., 3.);
0951     CHECK_RANGE(plot, equationCurve, Dimension::Y, 0., 3.);
0952 }
0953 
0954 QTEST_MAIN(CartesianPlotTest)