File indexing completed on 2024-10-06 06:35:01
0001 /* 0002 File : AxisTest2.cpp 0003 Project : LabPlot 0004 Description : More tests for Axis 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2022 Martin Marmsoler <martin.marmsoler@gmail.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "AxisTest2.h" 0012 #include "backend/core/Project.h" 0013 #include "backend/spreadsheet/Spreadsheet.h" 0014 #include "backend/worksheet/Worksheet.h" 0015 #include "backend/worksheet/plots/cartesian/CartesianPlot.h" 0016 #include "src/backend/core/Time.h" 0017 #include "src/backend/worksheet/Line.h" 0018 #include "src/backend/worksheet/TextLabel.h" 0019 #include "src/backend/worksheet/WorksheetElement.h" 0020 #include "src/backend/worksheet/plots/cartesian/Axis.h" // already included in CartesianPlot 0021 #include "src/backend/worksheet/plots/cartesian/AxisPrivate.h" 0022 #include "src/kdefrontend/dockwidgets/AxisDock.h" // access ui elements 0023 #include "src/kdefrontend/widgets/LabelWidget.h" 0024 #include "src/kdefrontend/widgets/LineWidget.h" 0025 0026 #include <QUndoStack> 0027 0028 // TODO: write test switching between numeric and datetime 0029 0030 #define CHECK_TITLE_COLOR(color_) \ 0031 QCOMPARE(a->title()->fontColor(), color_); \ 0032 QCOMPARE(dock.labelWidget->ui.kcbFontColor->color(), color_); 0033 0034 #define CHECK_MAJOR_TICKS_LINE_COLOR(color_) \ 0035 QCOMPARE(a->majorTicksLine()->color(), color_); \ 0036 QCOMPARE(dock.majorTicksLineWidget->ui.kcbColor->color(), color_); 0037 0038 #define CHECK_MINOR_TICKS_LINE_COLOR(color_) \ 0039 QCOMPARE(a->minorTicksLine()->color(), color_); \ 0040 QCOMPARE(dock.minorTicksLineWidget->ui.kcbColor->color(), color_); 0041 0042 #define CHECK_LINE_COLOR(color_) \ 0043 QCOMPARE(a->line()->color(), color_); \ 0044 QCOMPARE(dock.lineWidget->ui.kcbColor->color(), color_); 0045 0046 #define CHECK_TICK_LABLES_COLOR(color_) \ 0047 QCOMPARE(a->labelsColor(), color_); \ 0048 QCOMPARE(dock.ui.kcbLabelsFontColor->color(), color_); 0049 0050 #define CHECK_COMMON_COLOR(color_) \ 0051 CHECK_TITLE_COLOR(color_); \ 0052 CHECK_MAJOR_TICKS_LINE_COLOR(color_); \ 0053 CHECK_MINOR_TICKS_LINE_COLOR(color_); \ 0054 CHECK_LINE_COLOR(color_); \ 0055 CHECK_TICK_LABLES_COLOR(color_); \ 0056 QCOMPARE(dock.ui.kcbAxisColor->color(), color_); 0057 0058 #define CREATE_PROJECT \ 0059 Project project; \ 0060 auto* ws = new Worksheet(QStringLiteral("worksheet")); \ 0061 QVERIFY(ws != nullptr); \ 0062 project.addChild(ws); \ 0063 \ 0064 auto* p = new CartesianPlot(QStringLiteral("plot")); \ 0065 p->setType(CartesianPlot::Type::TwoAxes); /* Otherwise no axis are created */ \ 0066 QVERIFY(p != nullptr); \ 0067 ws->addChild(p); \ 0068 \ 0069 auto axes = p->children<Axis>(); \ 0070 QCOMPARE(axes.count(), 2); \ 0071 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); \ 0072 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); \ 0073 auto a = axes.at(0); \ 0074 AxisDock dock(nullptr); \ 0075 dock.setAxes({a}); \ 0076 CHECK_COMMON_COLOR(Qt::black); 0077 0078 void AxisTest2::setAxisColor() { 0079 CREATE_PROJECT 0080 0081 // set axis color 0082 dock.ui.kcbAxisColor->setColor(Qt::red); 0083 CHECK_COMMON_COLOR(Qt::red); 0084 0085 // undo/redo 0086 a->undoStack()->undo(); 0087 CHECK_COMMON_COLOR(Qt::black); 0088 a->undoStack()->redo(); 0089 CHECK_COMMON_COLOR(Qt::red); 0090 } 0091 0092 void AxisTest2::setTitleColor() { 0093 CREATE_PROJECT 0094 0095 // change title color 0096 dock.labelWidget->ui.kcbFontColor->setColor(Qt::green); 0097 CHECK_TITLE_COLOR(Qt::green); 0098 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0099 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0100 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0101 CHECK_LINE_COLOR(Qt::black); 0102 CHECK_TICK_LABLES_COLOR(Qt::black); 0103 0104 a->undoStack()->undo(); 0105 CHECK_COMMON_COLOR(Qt::black); 0106 0107 a->undoStack()->redo(); 0108 CHECK_TITLE_COLOR(Qt::green); 0109 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0110 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0111 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0112 CHECK_LINE_COLOR(Qt::black); 0113 CHECK_TICK_LABLES_COLOR(Qt::black); 0114 } 0115 0116 void AxisTest2::setMajorTickColor() { 0117 CREATE_PROJECT 0118 0119 // change title color 0120 dock.majorTicksLineWidget->setColor(Qt::green); 0121 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::green); 0122 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0123 CHECK_TITLE_COLOR(Qt::black); 0124 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0125 CHECK_LINE_COLOR(Qt::black); 0126 CHECK_TICK_LABLES_COLOR(Qt::black); 0127 0128 a->undoStack()->undo(); 0129 CHECK_COMMON_COLOR(Qt::black); 0130 0131 a->undoStack()->redo(); 0132 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::green); 0133 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0134 CHECK_TITLE_COLOR(Qt::black); 0135 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0136 CHECK_LINE_COLOR(Qt::black); 0137 CHECK_TICK_LABLES_COLOR(Qt::black); 0138 } 0139 0140 void AxisTest2::setMinorTickColor() { 0141 CREATE_PROJECT 0142 0143 // change title color 0144 dock.minorTicksLineWidget->setColor(Qt::green); 0145 CHECK_MINOR_TICKS_LINE_COLOR(Qt::green); 0146 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0147 CHECK_TITLE_COLOR(Qt::black); 0148 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0149 CHECK_LINE_COLOR(Qt::black); 0150 CHECK_TICK_LABLES_COLOR(Qt::black); 0151 0152 a->undoStack()->undo(); 0153 CHECK_COMMON_COLOR(Qt::black); 0154 0155 a->undoStack()->redo(); 0156 CHECK_MINOR_TICKS_LINE_COLOR(Qt::green); 0157 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0158 CHECK_TITLE_COLOR(Qt::black); 0159 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0160 CHECK_LINE_COLOR(Qt::black); 0161 CHECK_TICK_LABLES_COLOR(Qt::black); 0162 } 0163 0164 void AxisTest2::setLineColor() { 0165 CREATE_PROJECT 0166 0167 // change title color 0168 dock.lineWidget->setColor(Qt::green); 0169 CHECK_LINE_COLOR(Qt::green); 0170 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0171 CHECK_TITLE_COLOR(Qt::black); 0172 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0173 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0174 CHECK_TICK_LABLES_COLOR(Qt::black); 0175 0176 a->undoStack()->undo(); 0177 CHECK_COMMON_COLOR(Qt::black); 0178 0179 a->undoStack()->redo(); 0180 CHECK_LINE_COLOR(Qt::green); 0181 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0182 CHECK_TITLE_COLOR(Qt::black); 0183 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0184 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0185 CHECK_TICK_LABLES_COLOR(Qt::black); 0186 } 0187 0188 void AxisTest2::setTickLabelColor() { 0189 CREATE_PROJECT 0190 0191 // change title color 0192 dock.ui.kcbLabelsFontColor->setColor(Qt::green); 0193 CHECK_TICK_LABLES_COLOR(Qt::green); 0194 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0195 CHECK_TITLE_COLOR(Qt::black); 0196 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0197 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0198 CHECK_LINE_COLOR(Qt::black); 0199 0200 a->undoStack()->undo(); 0201 CHECK_COMMON_COLOR(Qt::black); 0202 0203 a->undoStack()->redo(); 0204 CHECK_TICK_LABLES_COLOR(Qt::green); 0205 QCOMPARE(dock.ui.kcbAxisColor->color(), Qt::transparent); 0206 CHECK_TITLE_COLOR(Qt::black); 0207 CHECK_MAJOR_TICKS_LINE_COLOR(Qt::black); 0208 CHECK_MINOR_TICKS_LINE_COLOR(Qt::black); 0209 CHECK_LINE_COLOR(Qt::black); 0210 } 0211 0212 void AxisTest2::automaticTicNumberUpdateDockMajorTicks() { 0213 Project project; 0214 auto* ws = new Worksheet(QStringLiteral("worksheet")); 0215 QVERIFY(ws != nullptr); 0216 project.addChild(ws); 0217 0218 auto* p = new CartesianPlot(QStringLiteral("plot")); 0219 p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created 0220 QVERIFY(p != nullptr); 0221 ws->addChild(p); 0222 0223 auto axes = p->children<Axis>(); 0224 QCOMPARE(axes.count(), 2); 0225 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); 0226 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); 0227 auto* yAxis = static_cast<Axis*>(axes.at(1)); 0228 auto* xAxis = static_cast<Axis*>(axes.at(0)); 0229 0230 AxisDock dock(nullptr); 0231 0232 dock.setAxes({xAxis, yAxis}); 0233 dock.ui.cbMajorTicksAutoNumber->setChecked(false); 0234 dock.ui.sbMajorTicksNumber->setValue(10); 0235 0236 // Check majorticks numbers of the axes 0237 QCOMPARE(xAxis->majorTicksNumber(), 10); 0238 QCOMPARE(xAxis->majorTicksAutoNumber(), false); 0239 QCOMPARE(yAxis->majorTicksNumber(), 10); 0240 QCOMPARE(xAxis->majorTicksAutoNumber(), false); 0241 QCOMPARE(dock.ui.cbMajorTicksAutoNumber->isChecked(), false); 0242 0243 dock.setAxes({xAxis, yAxis}); // Another time 0244 dock.ui.cbMajorTicksAutoNumber->setChecked(true); 0245 0246 QCOMPARE(xAxis->majorTicksNumber(), 6); 0247 QCOMPARE(xAxis->majorTicksAutoNumber(), true); 0248 QCOMPARE(yAxis->majorTicksNumber(), 6); 0249 QCOMPARE(xAxis->majorTicksAutoNumber(), true); 0250 QCOMPARE(dock.ui.sbMajorTicksNumber->value(), 6); 0251 } 0252 0253 void AxisTest2::automaticTicNumberUpdateDockMinorTicks() { 0254 Project project; 0255 auto* ws = new Worksheet(QStringLiteral("worksheet")); 0256 QVERIFY(ws != nullptr); 0257 project.addChild(ws); 0258 0259 auto* p = new CartesianPlot(QStringLiteral("plot")); 0260 p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created 0261 QVERIFY(p != nullptr); 0262 ws->addChild(p); 0263 0264 auto axes = p->children<Axis>(); 0265 QCOMPARE(axes.count(), 2); 0266 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); 0267 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); 0268 auto* yAxis = static_cast<Axis*>(axes.at(1)); 0269 auto* xAxis = static_cast<Axis*>(axes.at(0)); 0270 0271 AxisDock dock(nullptr); 0272 dock.setAxes({xAxis, yAxis}); 0273 dock.ui.cbMinorTicksAutoNumber->setChecked(false); 0274 dock.ui.sbMinorTicksNumber->setValue(10); 0275 0276 // Check minorticks numbers of the axes 0277 QCOMPARE(xAxis->minorTicksNumber(), 10); 0278 QCOMPARE(xAxis->minorTicksAutoNumber(), false); 0279 QCOMPARE(yAxis->minorTicksNumber(), 10); 0280 QCOMPARE(xAxis->minorTicksAutoNumber(), false); 0281 QCOMPARE(dock.ui.cbMinorTicksAutoNumber->isChecked(), false); 0282 0283 dock.setAxes({xAxis, yAxis}); // Another time 0284 QCOMPARE(dock.ui.cbMinorTicksAutoNumber->isChecked(), false); 0285 dock.ui.cbMinorTicksAutoNumber->setChecked(true); 0286 0287 // 1 is the default value for automatic 0288 QCOMPARE(xAxis->minorTicksNumber(), 1); 0289 QCOMPARE(xAxis->minorTicksAutoNumber(), true); 0290 QCOMPARE(yAxis->minorTicksNumber(), 1); 0291 QCOMPARE(xAxis->minorTicksAutoNumber(), true); 0292 QCOMPARE(dock.ui.sbMinorTicksNumber->value(), 1); 0293 } 0294 0295 void AxisTest2::columnLabelValues() { 0296 QLocale::setDefault(QLocale::C); // . as decimal separator 0297 Project project; 0298 auto* ws = new Worksheet(QStringLiteral("worksheet")); 0299 QVERIFY(ws != nullptr); 0300 project.addChild(ws); 0301 0302 Spreadsheet* spreadsheet = new Spreadsheet(QStringLiteral("test"), false); 0303 spreadsheet->setColumnCount(2); 0304 spreadsheet->setRowCount(3); 0305 project.addChild(spreadsheet); 0306 0307 auto* xCol = spreadsheet->column(0); 0308 xCol->replaceValues(0, QVector<double>({1, 2, 3})); 0309 0310 auto* yCol = spreadsheet->column(1); 0311 yCol->replaceValues(0, QVector<double>({2, 3, 4})); 0312 0313 QCOMPARE(spreadsheet->rowCount(), 3); 0314 QCOMPARE(spreadsheet->columnCount(), 2); 0315 0316 yCol->addValueLabel(2, QStringLiteral("Status 1")); 0317 yCol->addValueLabel(3, QStringLiteral("Status 2")); 0318 yCol->addValueLabel(4, QStringLiteral("Status 3")); 0319 0320 auto* p = new CartesianPlot(QStringLiteral("plot")); 0321 p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created 0322 QVERIFY(p != nullptr); 0323 ws->addChild(p); 0324 0325 auto* curve = new XYCurve(QStringLiteral("xy-curve")); 0326 curve->setXColumn(xCol); 0327 curve->setYColumn(yCol); 0328 p->addChild(curve); 0329 0330 auto axes = p->children<Axis>(); 0331 QCOMPARE(axes.count(), 2); 0332 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); 0333 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); 0334 auto* yAxis = static_cast<Axis*>(axes.at(1)); 0335 // auto* xAxis = static_cast<Axis*>(axes.at(0)); 0336 0337 { 0338 QCOMPARE(yAxis->labelsFormat(), Axis::LabelsFormat::Decimal); 0339 const auto v = yAxis->tickLabelStrings(); 0340 QStringList expectedStrings{ 0341 QStringLiteral("2.0"), 0342 QStringLiteral("2.5"), 0343 QStringLiteral("3.0"), 0344 QStringLiteral("3.5"), 0345 QStringLiteral("4.0"), 0346 }; 0347 COMPARE_STRING_VECTORS(yAxis->tickLabelStrings(), expectedStrings); 0348 } 0349 0350 { 0351 yAxis->setMajorTicksType(Axis::TicksType::ColumnLabels); 0352 yAxis->setMajorTicksColumn(yCol); 0353 0354 QStringList expectedStrings{ 0355 QStringLiteral("Status 1"), 0356 QStringLiteral("Status 2"), 0357 QStringLiteral("Status 3"), 0358 }; 0359 COMPARE_STRING_VECTORS(yAxis->tickLabelStrings(), expectedStrings); 0360 } 0361 } 0362 0363 /*! 0364 * \brief AxisTest2::columnLabelValuesMaxValues 0365 * Same as columnLabelValuesMaxValues() with the difference 0366 * that more columnLabels are available than the maximum number of ticks allowed 0367 * in the axis. This leads to a limited representation of ticks/labels 0368 */ 0369 void AxisTest2::columnLabelValuesMaxValues() { 0370 constexpr int valueLabelsCount = 1000; 0371 QLocale::setDefault(QLocale::C); // . as decimal separator 0372 Project project; 0373 auto* ws = new Worksheet(QStringLiteral("worksheet")); 0374 QVERIFY(ws != nullptr); 0375 project.addChild(ws); 0376 0377 Spreadsheet* spreadsheet = new Spreadsheet(QStringLiteral("test"), false); 0378 spreadsheet->setColumnCount(2); 0379 spreadsheet->setRowCount(3); 0380 project.addChild(spreadsheet); 0381 0382 auto* xCol = spreadsheet->column(0); 0383 xCol->replaceValues(-1, QVector<double>({1., 100.})); 0384 0385 auto* yCol = spreadsheet->column(1); 0386 yCol->replaceValues(-1, QVector<double>({1., 1000.})); 0387 0388 QCOMPARE(spreadsheet->rowCount(), 2); 0389 QCOMPARE(spreadsheet->columnCount(), 2); 0390 0391 for (int i = 0; i <= valueLabelsCount; i++) { 0392 yCol->addValueLabel(i, QStringLiteral("Status ") + QString::number(i)); 0393 } 0394 0395 auto* p = new CartesianPlot(QStringLiteral("plot")); 0396 p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created 0397 QVERIFY(p != nullptr); 0398 ws->addChild(p); 0399 0400 auto* curve = new XYCurve(QStringLiteral("xy-curve")); 0401 curve->setXColumn(xCol); 0402 curve->setYColumn(yCol); 0403 p->addChild(curve); 0404 0405 auto axes = p->children<Axis>(); 0406 QCOMPARE(axes.count(), 2); 0407 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); 0408 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); 0409 auto* yAxis = static_cast<Axis*>(axes.at(1)); 0410 // auto* xAxis = static_cast<Axis*>(axes.at(0)); 0411 0412 { 0413 yAxis->setMajorTicksType(Axis::TicksType::ColumnLabels); 0414 yAxis->setMajorTicksColumn(yCol); 0415 0416 const auto v = yAxis->tickLabelStrings(); 0417 QStringList expectedStrings; 0418 for (int i = 0; i <= valueLabelsCount; i += valueLabelsCount / (Axis::maxNumberMajorTicksCustomColumn() - 1)) 0419 expectedStrings.push_back(QStringLiteral("Status ") + QString::number(i)); 0420 0421 COMPARE_STRING_VECTORS(yAxis->tickLabelStrings(), expectedStrings); 0422 } 0423 } 0424 0425 void AxisTest2::customTextLabels() { 0426 QLocale::setDefault(QLocale::C); // . as decimal separator 0427 Project project; 0428 auto* ws = new Worksheet(QStringLiteral("worksheet")); 0429 QVERIFY(ws != nullptr); 0430 project.addChild(ws); 0431 0432 Spreadsheet* spreadsheetData = new Spreadsheet(QStringLiteral("data"), false); 0433 spreadsheetData->setColumnCount(2); 0434 spreadsheetData->setRowCount(3); 0435 project.addChild(spreadsheetData); 0436 0437 auto* xCol = spreadsheetData->column(0); 0438 xCol->replaceValues(0, QVector<double>({1, 2, 3})); 0439 0440 auto* yCol = spreadsheetData->column(1); 0441 yCol->replaceValues(0, QVector<double>({2, 3, 4})); 0442 0443 QCOMPARE(spreadsheetData->rowCount(), 3); 0444 QCOMPARE(spreadsheetData->columnCount(), 2); 0445 0446 Spreadsheet* spreadsheetLabels = new Spreadsheet(QStringLiteral("data"), false); 0447 spreadsheetLabels->setColumnCount(1); 0448 spreadsheetLabels->setRowCount(3); 0449 project.addChild(spreadsheetLabels); 0450 auto* labelsCol = spreadsheetLabels->column(0); 0451 labelsCol->setColumnMode(AbstractColumn::ColumnMode::Text); 0452 labelsCol->replaceTexts(-1, QVector<QString>({QStringLiteral("A"), QStringLiteral("B"), QStringLiteral("C")})); 0453 0454 auto* p = new CartesianPlot(QStringLiteral("plot")); 0455 p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created 0456 QVERIFY(p != nullptr); 0457 ws->addChild(p); 0458 0459 auto* curve = new XYCurve(QStringLiteral("xy-curve")); 0460 curve->setXColumn(xCol); 0461 curve->setYColumn(yCol); 0462 p->addChild(curve); 0463 0464 auto axes = p->children<Axis>(); 0465 QCOMPARE(axes.count(), 2); 0466 QCOMPARE(axes.at(0)->name(), QStringLiteral("x")); 0467 QCOMPARE(axes.at(1)->name(), QStringLiteral("y")); 0468 0469 auto* xAxis = static_cast<Axis*>(axes.at(0)); 0470 xAxis->setMajorTicksNumber(3, false); 0471 xAxis->setLabelsTextType(Axis::LabelsTextType::CustomValues); 0472 xAxis->setLabelsTextColumn(labelsCol); 0473 0474 { 0475 const auto v = xAxis->tickLabelStrings(); 0476 QStringList expectedStrings{ 0477 QStringLiteral("A"), 0478 QStringLiteral("B"), 0479 QStringLiteral("C"), 0480 }; 0481 COMPARE_STRING_VECTORS(xAxis->tickLabelStrings(), expectedStrings); 0482 } 0483 } 0484 0485 QTEST_MAIN(AxisTest2)