| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the Qt Charts module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 or (at your option) any later version | 
| 20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by | 
| 21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 | 
| 22 | ** included in the packaging of this file. Please review the following | 
| 23 | ** information to ensure the GNU General Public License requirements will | 
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 25 | ** | 
| 26 | ** $QT_END_LICENSE$ | 
| 27 | ** | 
| 28 | ****************************************************************************/ | 
| 29 |  | 
| 30 | #include "mainwidget.h" | 
| 31 | #include "customtablemodel.h" | 
| 32 | #include "pentool.h" | 
| 33 | #include <QtCharts/QVBoxPlotModelMapper> | 
| 34 | #include <QtWidgets/QTableView> | 
| 35 | #include <QtWidgets/QHeaderView> | 
| 36 | #include <QtCharts/QChartView> | 
| 37 | #include <QtCharts/QBoxPlotSeries> | 
| 38 | #include <QtCharts/QBoxSet> | 
| 39 | #include <QtCharts/QLegend> | 
| 40 | #include <QtCharts/QBarCategoryAxis> | 
| 41 | #include <QtGui/QBrush> | 
| 42 | #include <QtGui/QColor> | 
| 43 | #include <QtWidgets/QPushButton> | 
| 44 | #include <QtWidgets/QComboBox> | 
| 45 | #include <QtWidgets/QSpinBox> | 
| 46 | #include <QtWidgets/QCheckBox> | 
| 47 | #include <QtWidgets/QGridLayout> | 
| 48 | #include <QtWidgets/QHBoxLayout> | 
| 49 | #include <QtWidgets/QLabel> | 
| 50 | #include <QtWidgets/QSpacerItem> | 
| 51 | #include <QtWidgets/QMessageBox> | 
| 52 | #include <cmath> | 
| 53 | #include <QtCore/QDebug> | 
| 54 | #include <QtGui/QStandardItemModel> | 
| 55 | #include <QtCharts/QBarCategoryAxis> | 
| 56 | #include <QtCharts/QLogValueAxis> | 
| 57 |  | 
| 58 | QT_CHARTS_USE_NAMESPACE | 
| 59 |  | 
| 60 | static const QString allCategories[] = {"Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" }; | 
| 61 | static const int maxCategories = 12; | 
| 62 |  | 
| 63 | MainWidget::MainWidget(QWidget *parent) : | 
| 64 |     QWidget(parent), | 
| 65 |     m_chart(0), | 
| 66 |     m_axis(0), | 
| 67 |     m_rowPos(0), | 
| 68 |     m_seriesCount(0) | 
| 69 | { | 
| 70 |     m_chart = new QChart(); | 
| 71 |  | 
| 72 |     m_penTool = new PenTool("Whiskers pen" , this); | 
| 73 |  | 
| 74 |     // Grid layout for the controls for configuring the chart widget | 
| 75 |     QGridLayout *grid = new QGridLayout(); | 
| 76 |  | 
| 77 |     // Create add a series button | 
| 78 |     QPushButton *addSeriesButton = new QPushButton("Add a series" ); | 
| 79 |     connect(sender: addSeriesButton, SIGNAL(clicked()), receiver: this, SLOT(addSeries())); | 
| 80 |     grid->addWidget(addSeriesButton, row: m_rowPos++, column: 1); | 
| 81 |  | 
| 82 |     // Create remove a series button | 
| 83 |     QPushButton *removeSeriesButton = new QPushButton("Remove a series" ); | 
| 84 |     connect(sender: removeSeriesButton, SIGNAL(clicked()), receiver: this, SLOT(removeSeries())); | 
| 85 |     grid->addWidget(removeSeriesButton, row: m_rowPos++, column: 1); | 
| 86 |  | 
| 87 |     // Create add a single box button | 
| 88 |     QPushButton *addBoxButton = new QPushButton("Add a box" ); | 
| 89 |     connect(sender: addBoxButton, SIGNAL(clicked()), receiver: this, SLOT(addBox())); | 
| 90 |     grid->addWidget(addBoxButton, row: m_rowPos++, column: 1); | 
| 91 |  | 
| 92 |     // Create insert a box button | 
| 93 |     QPushButton *insertBoxButton = new QPushButton("Insert a box" ); | 
| 94 |     connect(sender: insertBoxButton, SIGNAL(clicked()), receiver: this, SLOT(insertBox())); | 
| 95 |     grid->addWidget(insertBoxButton, row: m_rowPos++, column: 1); | 
| 96 |  | 
| 97 |     // Create add a single box button | 
| 98 |     QPushButton *removeBoxButton = new QPushButton("Remove a box" ); | 
| 99 |     connect(sender: removeBoxButton, SIGNAL(clicked()), receiver: this, SLOT(removeBox())); | 
| 100 |     grid->addWidget(removeBoxButton, row: m_rowPos++, column: 1); | 
| 101 |  | 
| 102 |     // Create clear button | 
| 103 |     QPushButton *clearButton = new QPushButton("Clear" ); | 
| 104 |     connect(sender: clearButton, SIGNAL(clicked()), receiver: this, SLOT(clear())); | 
| 105 |     grid->addWidget(clearButton, row: m_rowPos++, column: 1); | 
| 106 |  | 
| 107 |     // Create clear button | 
| 108 |     QPushButton *clearBoxButton = new QPushButton("ClearBox" ); | 
| 109 |     connect(sender: clearBoxButton, SIGNAL(clicked()), receiver: this, SLOT(clearBox())); | 
| 110 |     grid->addWidget(clearBoxButton, row: m_rowPos++, column: 1); | 
| 111 |  | 
| 112 |     // Create set brush button | 
| 113 |     QPushButton *setBrushButton = new QPushButton("Set brush" ); | 
| 114 |     connect(sender: setBrushButton, SIGNAL(clicked()), receiver: this, SLOT(setBrush())); | 
| 115 |     grid->addWidget(setBrushButton, row: m_rowPos++, column: 1); | 
| 116 |  | 
| 117 |     // Create set whiskers pen button | 
| 118 |     QPushButton *setWhiskersButton = new QPushButton("Whiskers pen" ); | 
| 119 |     connect(sender: setWhiskersButton, SIGNAL(clicked()), receiver: m_penTool, SLOT(show())); | 
| 120 |     connect(sender: m_penTool, SIGNAL(changed()), receiver: this, SLOT(changePen())); | 
| 121 |     grid->addWidget(setWhiskersButton, row: m_rowPos++, column: 1); | 
| 122 |  | 
| 123 |     // Box width setting | 
| 124 |     m_boxWidthSB = new QDoubleSpinBox(); | 
| 125 |     m_boxWidthSB->setMinimum(-1.0); | 
| 126 |     m_boxWidthSB->setMaximum(2.0); | 
| 127 |     m_boxWidthSB->setSingleStep(0.1); | 
| 128 |     m_boxWidthSB->setValue(0.5); | 
| 129 |     grid->addWidget(new QLabel("Box width:" ), row: m_rowPos, column: 0); | 
| 130 |     grid->addWidget(m_boxWidthSB, row: m_rowPos++, column: 1); | 
| 131 |     connect(sender: m_boxWidthSB, SIGNAL(valueChanged(double)), receiver: this, SLOT(setBoxWidth(double))); | 
| 132 |  | 
| 133 |     initThemeCombo(grid); | 
| 134 |     initCheckboxes(grid); | 
| 135 |  | 
| 136 |     QTableView *tableView = new QTableView; | 
| 137 |     m_model = new CustomTableModel(tableView); | 
| 138 |     tableView->setModel(m_model); | 
| 139 |     tableView->setMaximumWidth(200); | 
| 140 |     grid->addWidget(tableView, row: m_rowPos++, column: 0, rowSpan: 3, columnSpan: 2, Qt::AlignLeft); | 
| 141 |     tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); | 
| 142 |     tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); | 
| 143 |  | 
| 144 |     // add row with empty label to make all the other rows static | 
| 145 |     grid->addWidget(new QLabel("" ), row: grid->rowCount(), column: 0); | 
| 146 |     grid->setRowStretch(row: grid->rowCount() - 1, stretch: 1); | 
| 147 |  | 
| 148 |     // Create chart view with the chart | 
| 149 |     m_chartView = new QChartView(m_chart, this); | 
| 150 |  | 
| 151 |     // As a default antialiasing is off | 
| 152 |     m_chartView->setRenderHint(hint: QPainter::Antialiasing, enabled: false); | 
| 153 |  | 
| 154 |     // Another grid layout as a main layout | 
| 155 |     QGridLayout *mainLayout = new QGridLayout(); | 
| 156 |     mainLayout->addLayout(grid, row: 0, column: 0); | 
| 157 |     mainLayout->addWidget(m_chartView, row: 0, column: 1, rowSpan: 3, columnSpan: 1); | 
| 158 |     setLayout(mainLayout); | 
| 159 |  | 
| 160 |     legendToggled(enabled: false); | 
| 161 |     animationToggled(enabled: false); | 
| 162 | } | 
| 163 |  | 
| 164 | // Combo box for selecting theme | 
| 165 | void MainWidget::initThemeCombo(QGridLayout *grid) | 
| 166 | { | 
| 167 |     QComboBox *chartTheme = new QComboBox(); | 
| 168 |     chartTheme->addItem(atext: "Default" ); | 
| 169 |     chartTheme->addItem(atext: "Light" ); | 
| 170 |     chartTheme->addItem(atext: "Blue Cerulean" ); | 
| 171 |     chartTheme->addItem(atext: "Dark" ); | 
| 172 |     chartTheme->addItem(atext: "Brown Sand" ); | 
| 173 |     chartTheme->addItem(atext: "Blue NCS" ); | 
| 174 |     chartTheme->addItem(atext: "High Contrast" ); | 
| 175 |     chartTheme->addItem(atext: "Blue Icy" ); | 
| 176 |     chartTheme->addItem(atext: "Qt" ); | 
| 177 |     connect(sender: chartTheme, SIGNAL(currentIndexChanged(int)), | 
| 178 |             receiver: this, SLOT(changeChartTheme(int))); | 
| 179 |     grid->addWidget(new QLabel("Chart theme:" ), row: m_rowPos, column: 0); | 
| 180 |     grid->addWidget(chartTheme, row: m_rowPos++, column: 1); | 
| 181 | } | 
| 182 |  | 
| 183 | // Different check boxes for customizing chart | 
| 184 | void MainWidget::initCheckboxes(QGridLayout *grid) | 
| 185 | { | 
| 186 |     QCheckBox *animationCheckBox = new QCheckBox("Animation" ); | 
| 187 |     connect(sender: animationCheckBox, SIGNAL(toggled(bool)), receiver: this, SLOT(animationToggled(bool))); | 
| 188 |     animationCheckBox->setChecked(false); | 
| 189 |     grid->addWidget(animationCheckBox, row: m_rowPos++, column: 0); | 
| 190 |  | 
| 191 |     QCheckBox *legendCheckBox = new QCheckBox("Legend" ); | 
| 192 |     connect(sender: legendCheckBox, SIGNAL(toggled(bool)), receiver: this, SLOT(legendToggled(bool))); | 
| 193 |     legendCheckBox->setChecked(false); | 
| 194 |     grid->addWidget(legendCheckBox, row: m_rowPos++, column: 0); | 
| 195 |  | 
| 196 |     QCheckBox *titleCheckBox = new QCheckBox("Title" ); | 
| 197 |     connect(sender: titleCheckBox, SIGNAL(toggled(bool)), receiver: this, SLOT(titleToggled(bool))); | 
| 198 |     titleCheckBox->setChecked(false); | 
| 199 |     grid->addWidget(titleCheckBox, row: m_rowPos++, column: 0); | 
| 200 |  | 
| 201 |     QCheckBox *antialiasingCheckBox = new QCheckBox("Antialiasing" ); | 
| 202 |     connect(sender: antialiasingCheckBox, SIGNAL(toggled(bool)), receiver: this, SLOT(antialiasingToggled(bool))); | 
| 203 |     antialiasingCheckBox->setChecked(false); | 
| 204 |     grid->addWidget(antialiasingCheckBox, row: m_rowPos++, column: 0); | 
| 205 |  | 
| 206 |     QCheckBox *modelMapperCheckBox = new QCheckBox("Use model mapper" ); | 
| 207 |     connect(sender: modelMapperCheckBox, SIGNAL(toggled(bool)), receiver: this, SLOT(modelMapperToggled(bool))); | 
| 208 |     modelMapperCheckBox->setChecked(false); | 
| 209 |     grid->addWidget(modelMapperCheckBox, row: m_rowPos++, column: 0); | 
| 210 |  | 
| 211 |     m_boxOutlined = new QCheckBox("Box outlined" ); | 
| 212 |     connect(sender: m_boxOutlined, SIGNAL(toggled(bool)), receiver: this, SLOT(boxOutlineToggled(bool))); | 
| 213 |     m_boxOutlined->setChecked(true); | 
| 214 |     grid->addWidget(m_boxOutlined, row: m_rowPos++, column: 0); | 
| 215 | } | 
| 216 |  | 
| 217 | void MainWidget::updateAxis(int categoryCount) | 
| 218 | { | 
| 219 |     if (!m_axis) { | 
| 220 |         m_chart->createDefaultAxes(); | 
| 221 |         m_axis = new QBarCategoryAxis(); | 
| 222 |     } | 
| 223 |     QStringList categories; | 
| 224 |     for (int i = 0; i < categoryCount; i++) | 
| 225 |         categories << allCategories[i]; | 
| 226 |     m_axis->setCategories(categories); | 
| 227 | } | 
| 228 |  | 
| 229 | void MainWidget::addSeries() | 
| 230 | { | 
| 231 |     qDebug() << "BoxPlotTester::MainWidget::addSeries()" ; | 
| 232 |  | 
| 233 |     if (m_seriesCount > 9) | 
| 234 |         return; | 
| 235 |  | 
| 236 |     // Initial data | 
| 237 |     QBoxSet *set0 = new QBoxSet(); | 
| 238 |     QBoxSet *set1 = new QBoxSet(); | 
| 239 |     QBoxSet *set2 = new QBoxSet(); | 
| 240 |     QBoxSet *set3 = new QBoxSet(); | 
| 241 |     QBoxSet *set4 = new QBoxSet(); | 
| 242 |     QBoxSet *set5 = new QBoxSet(); | 
| 243 |  | 
| 244 |     //      low  bot   med   top  upp | 
| 245 |     *set0 << -1 << 2 << 4 << 13 << 15; | 
| 246 |     *set1 << 5 << 6 << 7.5 << 8 << 12; | 
| 247 |     *set2 << 3 << 5 << 5.7 << 8 << 9; | 
| 248 |     *set3 << 5 << 6 << 6.8 << 7 << 8; | 
| 249 |     *set4 << 4 << 5 << 5.2 << 6 << 7; | 
| 250 |     *set5 << 4 << 7 << 8.2 << 9 << 10; | 
| 251 |  | 
| 252 |     m_series[m_seriesCount] = new QBoxPlotSeries(); | 
| 253 |     m_series[m_seriesCount]->append(box: set0); | 
| 254 |     m_series[m_seriesCount]->append(box: set1); | 
| 255 |     m_series[m_seriesCount]->append(box: set2); | 
| 256 |     m_series[m_seriesCount]->append(box: set3); | 
| 257 |     m_series[m_seriesCount]->append(box: set4); | 
| 258 |     m_series[m_seriesCount]->append(box: set5); | 
| 259 |     m_series[m_seriesCount]->setName("Box & Whiskers" ); | 
| 260 |  | 
| 261 |     connect(sender: m_series[m_seriesCount], SIGNAL(clicked(QBoxSet*)), receiver: this, SLOT(boxClicked(QBoxSet*))); | 
| 262 |     connect(sender: m_series[m_seriesCount], SIGNAL(pressed(QBoxSet*)), receiver: this, SLOT(boxPressed(QBoxSet*))); | 
| 263 |     connect(sender: m_series[m_seriesCount], SIGNAL(released(QBoxSet*)), receiver: this, SLOT(boxReleased(QBoxSet*))); | 
| 264 |     connect(sender: m_series[m_seriesCount], SIGNAL(doubleClicked(QBoxSet*)), | 
| 265 |             receiver: this, SLOT(boxDoubleClicked(QBoxSet*))); | 
| 266 |     connect(sender: m_series[m_seriesCount], SIGNAL(hovered(bool, QBoxSet*)), receiver: this, SLOT(boxHovered(bool, QBoxSet*))); | 
| 267 |     connect(sender: set1, SIGNAL(clicked()), receiver: this, SLOT(singleBoxClicked())); | 
| 268 |     connect(sender: set1, SIGNAL(pressed()), receiver: this, SLOT(singleBoxPressed())); | 
| 269 |     connect(sender: set1, SIGNAL(released()), receiver: this, SLOT(singleBoxReleased())); | 
| 270 |     connect(sender: set1, SIGNAL(doubleClicked()), receiver: this, SLOT(singleBoxDoubleClicked())); | 
| 271 |     connect(sender: set2, SIGNAL(hovered(bool)), receiver: this, SLOT(singleBoxHovered(bool))); | 
| 272 |  | 
| 273 |     m_series[m_seriesCount]->setBoxOutlineVisible(m_boxOutlined->checkState()); | 
| 274 |     m_series[m_seriesCount]->setBoxWidth(m_boxWidthSB->value()); | 
| 275 |  | 
| 276 |     m_chart->addSeries(series: m_series[m_seriesCount]); | 
| 277 |  | 
| 278 |     updateAxis(categoryCount: m_series[0]->count()); | 
| 279 |     m_chart->setAxisX(axis: m_axis, series: m_series[m_seriesCount]); | 
| 280 |  | 
| 281 |     m_seriesCount++; | 
| 282 | } | 
| 283 |  | 
| 284 | void MainWidget::removeSeries() | 
| 285 | { | 
| 286 |     qDebug() << "BoxPlotTester::MainWidget::removeSeries()" ; | 
| 287 |  | 
| 288 |     if (m_seriesCount > 0) { | 
| 289 |         m_seriesCount--; | 
| 290 |         m_chart->removeSeries(series: m_series[m_seriesCount]); | 
| 291 |         delete m_series[m_seriesCount]; | 
| 292 |         m_series[m_seriesCount] = 0; | 
| 293 |     } else { | 
| 294 |         qDebug() << "Create a series first" ; | 
| 295 |     } | 
| 296 | } | 
| 297 |  | 
| 298 | void MainWidget::addBox() | 
| 299 | { | 
| 300 |     qDebug() << "BoxPlotTester::MainWidget::addBox()" ; | 
| 301 |  | 
| 302 |     if (m_seriesCount > 0 && m_series[0]->count() < maxCategories) { | 
| 303 |         QBoxSet *newSet = new QBoxSet(); | 
| 304 |         newSet->setValue(index: QBoxSet::LowerExtreme, value: 5.0); | 
| 305 |         newSet->setValue(index: QBoxSet::LowerQuartile, value: 6.0); | 
| 306 |         newSet->setValue(index: QBoxSet::Median, value: 6.8); | 
| 307 |         newSet->setValue(index: QBoxSet::UpperQuartile, value: 7.0); | 
| 308 |         newSet->setValue(index: QBoxSet::UpperExtreme, value: 8.0); | 
| 309 |  | 
| 310 |         updateAxis(categoryCount: m_series[0]->count() + 1); | 
| 311 |  | 
| 312 |         m_series[0]->append(box: newSet); | 
| 313 |     } | 
| 314 | } | 
| 315 |  | 
| 316 | void MainWidget::insertBox() | 
| 317 | { | 
| 318 |     qDebug() << "BoxPlotTester::MainWidget::insertBox()" ; | 
| 319 |  | 
| 320 |     if (m_seriesCount > 0 && m_series[0]->count() < maxCategories) { | 
| 321 |         updateAxis(categoryCount: m_series[0]->count() + 1); | 
| 322 |         for (int i = 0; i < m_seriesCount; i++) { | 
| 323 |             QBoxSet *newSet = new QBoxSet(); | 
| 324 |             *newSet << 2 << 6 << 6.8 << 7 << 10; | 
| 325 |             m_series[i]->insert(index: 1, box: newSet); | 
| 326 |         } | 
| 327 |     } | 
| 328 | } | 
| 329 |  | 
| 330 | void MainWidget::removeBox() | 
| 331 | { | 
| 332 |     qDebug() << "BoxPlotTester::MainWidget::removeBox" ; | 
| 333 |  | 
| 334 |     if (m_seriesCount > 0) { | 
| 335 |         for (int i = 0; i < m_seriesCount; i++) { | 
| 336 |             qDebug() << "m_series[i]->count() = "  << m_series[i]->count(); | 
| 337 |             if (m_series[i]->count()) { | 
| 338 |                 QList<QBoxSet *> sets = m_series[i]->boxSets(); | 
| 339 |                 m_series[i]->remove(box: sets.at(i: m_series[i]->count() - 1)); | 
| 340 |             } | 
| 341 |         } | 
| 342 |  | 
| 343 |         updateAxis(categoryCount: m_series[0]->count()); | 
| 344 |     } else { | 
| 345 |         qDebug() << "Create a series first" ; | 
| 346 |     } | 
| 347 | } | 
| 348 |  | 
| 349 | void MainWidget::clear() | 
| 350 | { | 
| 351 |     qDebug() << "BoxPlotTester::MainWidget::clear" ; | 
| 352 |  | 
| 353 |     if (m_seriesCount > 0) | 
| 354 |         m_series[0]->clear(); | 
| 355 |     else | 
| 356 |         qDebug() << "Create a series first" ; | 
| 357 | } | 
| 358 |  | 
| 359 | void MainWidget::clearBox() | 
| 360 | { | 
| 361 |     qDebug() << "BoxPlotTester::MainWidget::clearBox" ; | 
| 362 |  | 
| 363 |     if (m_seriesCount > 0) { | 
| 364 |         QList<QBoxSet *> sets = m_series[0]->boxSets(); | 
| 365 |         if (sets.count() > 1) | 
| 366 |             sets.at(i: 1)->clear(); | 
| 367 |         else | 
| 368 |             qDebug() << "Create a series with at least two items first" ; | 
| 369 |     } else { | 
| 370 |         qDebug() << "Create a series first" ; | 
| 371 |     } | 
| 372 | } | 
| 373 |  | 
| 374 | void MainWidget::setBrush() | 
| 375 | { | 
| 376 |     qDebug() << "BoxPlotTester::MainWidget::setBrush" ; | 
| 377 |  | 
| 378 |     if (m_seriesCount > 0) { | 
| 379 |         QList<QBoxSet *> sets = m_series[0]->boxSets(); | 
| 380 |         if (sets.count() > 1) | 
| 381 |             sets.at(i: 1)->setBrush(QBrush(QColor(Qt::yellow))); | 
| 382 |         else | 
| 383 |             qDebug() << "Create a series with at least two items first" ; | 
| 384 |     } else { | 
| 385 |         qDebug() << "Create a series first" ; | 
| 386 |     } | 
| 387 | } | 
| 388 |  | 
| 389 | void MainWidget::animationToggled(bool enabled) | 
| 390 | { | 
| 391 |     qDebug() << "BoxPlotTester::Animation toggled to "  << enabled; | 
| 392 |     if (enabled) | 
| 393 |         m_chart->setAnimationOptions(QChart::SeriesAnimations); | 
| 394 |     else | 
| 395 |         m_chart->setAnimationOptions(QChart::NoAnimation); | 
| 396 | } | 
| 397 |  | 
| 398 | void MainWidget::legendToggled(bool enabled) | 
| 399 | { | 
| 400 |     qDebug() << "BoxPlotTester::Legend toggled to "  << enabled; | 
| 401 |     m_chart->legend()->setVisible(enabled); | 
| 402 |     if (enabled) | 
| 403 |         m_chart->legend()->setAlignment(Qt::AlignBottom); | 
| 404 | } | 
| 405 |  | 
| 406 | void MainWidget::titleToggled(bool enabled) | 
| 407 | { | 
| 408 |     qDebug() << "BoxPlotTester::Title toggled to "  << enabled; | 
| 409 |     if (enabled) | 
| 410 |         m_chart->setTitle("Simple boxplotchart example" ); | 
| 411 |     else | 
| 412 |         m_chart->setTitle("" ); | 
| 413 | } | 
| 414 |  | 
| 415 | void MainWidget::antialiasingToggled(bool enabled) | 
| 416 | { | 
| 417 |     qDebug() << "BoxPlotTester::antialiasingToggled toggled to "  << enabled; | 
| 418 |     m_chartView->setRenderHint(hint: QPainter::Antialiasing, enabled); | 
| 419 | } | 
| 420 |  | 
| 421 | void MainWidget::boxOutlineToggled(bool visible) | 
| 422 | { | 
| 423 |     qDebug() << "BoxPlotTester::boxOutlineToggled toggled to "  << visible; | 
| 424 |     for (int i = 0; i <  m_seriesCount; i++) | 
| 425 |         m_series[i]->setBoxOutlineVisible(visible); | 
| 426 | } | 
| 427 |  | 
| 428 | void MainWidget::modelMapperToggled(bool enabled) | 
| 429 | { | 
| 430 |     if (enabled) { | 
| 431 |         m_series[m_seriesCount] = new QBoxPlotSeries(); | 
| 432 |  | 
| 433 |         int first = 0; | 
| 434 |         int count = 5; | 
| 435 |         QVBoxPlotModelMapper *mapper = new QVBoxPlotModelMapper(this); | 
| 436 |         mapper->setFirstBoxSetColumn(0); | 
| 437 |         mapper->setLastBoxSetColumn(5); | 
| 438 |         mapper->setFirstRow(first); | 
| 439 |         mapper->setRowCount(count); | 
| 440 |         mapper->setSeries(m_series[m_seriesCount]); | 
| 441 |         mapper->setModel(m_model); | 
| 442 |         m_chart->addSeries(series: m_series[m_seriesCount]); | 
| 443 |  | 
| 444 |         m_seriesCount++; | 
| 445 |     } else { | 
| 446 |         removeSeries(); | 
| 447 |     } | 
| 448 | } | 
| 449 |  | 
| 450 | void MainWidget::changeChartTheme(int themeIndex) | 
| 451 | { | 
| 452 |     qDebug() << "BoxPlotTester::changeChartTheme: "  << themeIndex; | 
| 453 |     if (themeIndex == 0) | 
| 454 |         m_chart->setTheme(QChart::ChartThemeLight); | 
| 455 |     else | 
| 456 |         m_chart->setTheme((QChart::ChartTheme) (themeIndex - 1)); | 
| 457 | } | 
| 458 |  | 
| 459 | void MainWidget::boxClicked(QBoxSet *set) | 
| 460 | { | 
| 461 |     qDebug() << "boxClicked, median = "  << set->at(index: QBoxSet::Median); | 
| 462 | } | 
| 463 |  | 
| 464 | void MainWidget::boxHovered(bool state, QBoxSet *set) | 
| 465 | { | 
| 466 |     if (state) | 
| 467 |         qDebug() << "box median "  << set->at(index: QBoxSet::Median) << " hover started" ; | 
| 468 |     else | 
| 469 |         qDebug() << "box median "  << set->at(index: QBoxSet::Median) << " hover ended" ; | 
| 470 | } | 
| 471 |  | 
| 472 | void MainWidget::boxPressed(QBoxSet *set) | 
| 473 | { | 
| 474 |     qDebug() << "boxPressed, median = "  << set->at(index: QBoxSet::Median); | 
| 475 | } | 
| 476 |  | 
| 477 | void MainWidget::boxReleased(QBoxSet *set) | 
| 478 | { | 
| 479 |     qDebug() << "boxReleased, median = "  << set->at(index: QBoxSet::Median); | 
| 480 | } | 
| 481 |  | 
| 482 | void MainWidget::boxDoubleClicked(QBoxSet *set) | 
| 483 | { | 
| 484 |     qDebug() << "boxDoubleClicked, median = "  << set->at(index: QBoxSet::Median); | 
| 485 | } | 
| 486 |  | 
| 487 | void MainWidget::singleBoxClicked() | 
| 488 | { | 
| 489 |     qDebug() << "singleBoxClicked" ; | 
| 490 | } | 
| 491 |  | 
| 492 | void MainWidget::singleBoxPressed() | 
| 493 | { | 
| 494 |     qDebug() << "singleBoxPressed" ; | 
| 495 | } | 
| 496 |  | 
| 497 | void MainWidget::singleBoxReleased() | 
| 498 | { | 
| 499 |     qDebug() << "singleBoxReleased" ; | 
| 500 | } | 
| 501 |  | 
| 502 | void MainWidget::singleBoxDoubleClicked() | 
| 503 | { | 
| 504 |     qDebug() << "singleBoxDoubleClicked" ; | 
| 505 | } | 
| 506 |  | 
| 507 | void MainWidget::singleBoxHovered(bool state) | 
| 508 | { | 
| 509 |     if (state) | 
| 510 |         qDebug() << "single box hover started" ; | 
| 511 |     else | 
| 512 |         qDebug() << "single box hover ended" ; | 
| 513 | } | 
| 514 |  | 
| 515 | void MainWidget::changePen() | 
| 516 | { | 
| 517 |     qDebug() << "changePen() = "  << m_penTool->pen(); | 
| 518 |     for (int i = 0; i <  m_seriesCount; i++) | 
| 519 |         m_series[i]->setPen(m_penTool->pen()); | 
| 520 | } | 
| 521 |  | 
| 522 | void MainWidget::setBoxWidth(double width) | 
| 523 | { | 
| 524 |     qDebug() << "setBoxWidth to "  << width; | 
| 525 |  | 
| 526 |     for (int i = 0; i <  m_seriesCount; i++) | 
| 527 |         m_series[i]->setBoxWidth(qreal(width)); | 
| 528 | } | 
| 529 |  |