summaryrefslogtreecommitdiffstats
path: root/tests/manual/candlesticktester/mainwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/candlesticktester/mainwidget.cpp')
-rw-r--r--tests/manual/candlesticktester/mainwidget.cpp691
1 files changed, 691 insertions, 0 deletions
diff --git a/tests/manual/candlesticktester/mainwidget.cpp b/tests/manual/candlesticktester/mainwidget.cpp
new file mode 100644
index 00000000..7364f023
--- /dev/null
+++ b/tests/manual/candlesticktester/mainwidget.cpp
@@ -0,0 +1,691 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCharts/QBarCategoryAxis>
+#include <QtCharts/QCandlestickSeries>
+#include <QtCharts/QCandlestickSet>
+#include <QtCharts/QDateTimeAxis>
+#include <QtCharts/QHCandlestickModelMapper>
+#include <QtCharts/QValueAxis>
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QDoubleSpinBox>
+#include <QtWidgets/QGridLayout>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QTableView>
+#include "customtablemodel.h"
+#include "mainwidget.h"
+
+QT_CHARTS_USE_NAMESPACE
+
+MainWidget::MainWidget(QWidget *parent)
+ : QWidget(parent),
+ m_chart(new QChart()),
+ m_chartView(new QChartView(m_chart, this)),
+ m_axisX(nullptr),
+ m_axisY(nullptr),
+ m_maximumColumnWidth(-1.0),
+ m_minimumColumnWidth(5.0),
+ m_bodyOutlineVisible(true),
+ m_capsVisible(false),
+ m_bodyWidth(0.5),
+ m_capsWidth(0.5),
+ m_customIncreasingColor(false),
+ m_customDecreasingColor(false),
+ m_hModelMapper(new QHCandlestickModelMapper(this))
+{
+ qsrand(QDateTime::currentDateTime().toTime_t());
+
+ m_chartView->setRenderHint(QPainter::Antialiasing, false);
+
+ m_hModelMapper->setModel(new CustomTableModel(this));
+ m_hModelMapper->setTimestampColumn(0);
+ m_hModelMapper->setOpenColumn(1);
+ m_hModelMapper->setHighColumn(2);
+ m_hModelMapper->setLowColumn(3);
+ m_hModelMapper->setCloseColumn(4);
+
+ QGridLayout *mainLayout = new QGridLayout();
+ mainLayout->addLayout(createSeriesControlsLayout(), 0, 0);
+ mainLayout->addLayout(createSetsControlsLayout(), 1, 0);
+ mainLayout->addLayout(createCandlestickControlsLayout(), 2, 0);
+ mainLayout->addLayout(createMiscellaneousControlsLayout(), 3, 0);
+ mainLayout->addWidget(m_chartView, 0, 1, mainLayout->rowCount() + 1, 1);
+ mainLayout->addLayout(createModelMapperControlsLayout(), 0, 2, mainLayout->rowCount(), 1);
+ setLayout(mainLayout);
+
+ addSeries();
+}
+
+MainWidget::~MainWidget()
+{
+}
+
+QGridLayout *MainWidget::createSeriesControlsLayout()
+{
+ QGridLayout *layout = new QGridLayout();
+ int row = 0;
+
+ layout->addWidget(new QLabel(QStringLiteral("Series controls:")), row, 0, Qt::AlignLeft);
+
+ QPushButton *addSeriesButton = new QPushButton(QStringLiteral("Add a series"));
+ connect(addSeriesButton, SIGNAL(clicked(bool)), this, SLOT(addSeries()));
+ layout->addWidget(addSeriesButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *removeSeriesButton = new QPushButton(QStringLiteral("Remove a series"));
+ connect(removeSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeSeries()));
+ layout->addWidget(removeSeriesButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *removeAllSeriesButton = new QPushButton(QStringLiteral("Remove all series"));
+ connect(removeAllSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSeries()));
+ layout->addWidget(removeAllSeriesButton, row++, 1, Qt::AlignLeft);
+
+ return layout;
+}
+
+QGridLayout *MainWidget::createSetsControlsLayout()
+{
+ QGridLayout *layout = new QGridLayout();
+ int row = 0;
+
+ layout->addWidget(new QLabel(QStringLiteral("Sets controls:")), row, 0, Qt::AlignLeft);
+
+ QPushButton *addSetButton = new QPushButton(QStringLiteral("Add a set"));
+ connect(addSetButton, SIGNAL(clicked(bool)), this, SLOT(addSet()));
+ layout->addWidget(addSetButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *insertSetButton = new QPushButton(QStringLiteral("Insert a set"));
+ connect(insertSetButton, SIGNAL(clicked(bool)), this, SLOT(insertSet()));
+ layout->addWidget(insertSetButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *removeSetButton = new QPushButton(QStringLiteral("Remove a set"));
+ connect(removeSetButton, SIGNAL(clicked(bool)), this, SLOT(removeSet()));
+ layout->addWidget(removeSetButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *removeAllSetsButton = new QPushButton(QStringLiteral("Remove all sets"));
+ connect(removeAllSetsButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSets()));
+ layout->addWidget(removeAllSetsButton, row++, 1, Qt::AlignLeft);
+
+ return layout;
+}
+
+QGridLayout *MainWidget::createCandlestickControlsLayout()
+{
+ QGridLayout *layout = new QGridLayout();
+ int row = 0;
+
+ layout->addWidget(new QLabel(QStringLiteral("Maximum column width:")), row, 0, Qt::AlignLeft);
+ QDoubleSpinBox *maximumColumnWidthSpinBox = new QDoubleSpinBox();
+ maximumColumnWidthSpinBox->setRange(-1.0, 1024.0);
+ maximumColumnWidthSpinBox->setDecimals(0);
+ maximumColumnWidthSpinBox->setValue(m_maximumColumnWidth);
+ maximumColumnWidthSpinBox->setSingleStep(1.0);
+ connect(maximumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(changeMaximumColumnWidth(double)));
+ layout->addWidget(maximumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
+
+ layout->addWidget(new QLabel(QStringLiteral("Minimum column width:")), row, 0, Qt::AlignLeft);
+ QDoubleSpinBox *minimumColumnWidthSpinBox = new QDoubleSpinBox();
+ minimumColumnWidthSpinBox->setRange(-1.0, 1024.0);
+ minimumColumnWidthSpinBox->setDecimals(0);
+ minimumColumnWidthSpinBox->setValue(m_minimumColumnWidth);
+ minimumColumnWidthSpinBox->setSingleStep(1.0);
+ connect(minimumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(changeMinimumColumnWidth(double)));
+ layout->addWidget(minimumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
+
+ QCheckBox *bodyOutlineVisible = new QCheckBox(QStringLiteral("Body outline visible"));
+ connect(bodyOutlineVisible, SIGNAL(toggled(bool)), this, SLOT(bodyOutlineVisibleToggled(bool)));
+ bodyOutlineVisible->setChecked(m_bodyOutlineVisible);
+ layout->addWidget(bodyOutlineVisible, row++, 0, Qt::AlignLeft);
+
+ QCheckBox *capsVisible = new QCheckBox(QStringLiteral("Caps visible"));
+ connect(capsVisible, SIGNAL(toggled(bool)), this, SLOT(capsVisibleToggled(bool)));
+ capsVisible->setChecked(m_capsVisible);
+ layout->addWidget(capsVisible, row++, 0, Qt::AlignLeft);
+
+ layout->addWidget(new QLabel(QStringLiteral("Candlestick body width:")), row, 0, Qt::AlignLeft);
+ QDoubleSpinBox *bodyWidthSpinBox = new QDoubleSpinBox();
+ bodyWidthSpinBox->setRange(-1.0, 2.0);
+ bodyWidthSpinBox->setValue(m_bodyWidth);
+ bodyWidthSpinBox->setSingleStep(0.1);
+ connect(bodyWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeBodyWidth(double)));
+ layout->addWidget(bodyWidthSpinBox, row++, 1, Qt::AlignLeft);
+
+ layout->addWidget(new QLabel(QStringLiteral("Candlestick caps width:")), row, 0, Qt::AlignLeft);
+ QDoubleSpinBox *capsWidthSpinBox = new QDoubleSpinBox();
+ capsWidthSpinBox->setRange(-1.0, 2.0);
+ capsWidthSpinBox->setValue(m_capsWidth);
+ capsWidthSpinBox->setSingleStep(0.1);
+ connect(capsWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeCapsWidth(double)));
+ layout->addWidget(capsWidthSpinBox, row++, 1, Qt::AlignLeft);
+
+ QCheckBox *increasingColor = new QCheckBox(QStringLiteral("Custom increasing color (only S1)"));
+ connect(increasingColor, SIGNAL(toggled(bool)), this, SLOT(customIncreasingColorToggled(bool)));
+ increasingColor->setChecked(m_customIncreasingColor);
+ layout->addWidget(increasingColor, row++, 0, 1, 2, Qt::AlignLeft);
+
+ QCheckBox *decreasingColor = new QCheckBox(QStringLiteral("Custom decreasing color (only S1)"));
+ connect(decreasingColor, SIGNAL(toggled(bool)), this, SLOT(customDecreasingColorToggled(bool)));
+ decreasingColor->setChecked(m_customDecreasingColor);
+ layout->addWidget(decreasingColor, row++, 0, 1, 2, Qt::AlignLeft);
+
+ return layout;
+}
+
+QGridLayout *MainWidget::createMiscellaneousControlsLayout()
+{
+ QGridLayout *layout = new QGridLayout();
+ int row = 0;
+
+ layout->addWidget(new QLabel(QStringLiteral("Miscellaneous:")), row, 0, Qt::AlignLeft);
+
+ QCheckBox *antialiasingCheckBox = new QCheckBox(QStringLiteral("Antialiasing"));
+ connect(antialiasingCheckBox, SIGNAL(toggled(bool)), this, SLOT(antialiasingToggled(bool)));
+ antialiasingCheckBox->setChecked(false);
+ layout->addWidget(antialiasingCheckBox, row++, 1, Qt::AlignLeft);
+
+ QCheckBox *animationCheckBox = new QCheckBox(QStringLiteral("Animation"));
+ connect(animationCheckBox, SIGNAL(toggled(bool)), this, SLOT(animationToggled(bool)));
+ animationCheckBox->setChecked(false);
+ layout->addWidget(animationCheckBox, row++, 1, Qt::AlignLeft);
+
+ QCheckBox *legendCheckBox = new QCheckBox(QStringLiteral("Legend"));
+ connect(legendCheckBox, SIGNAL(toggled(bool)), this, SLOT(legendToggled(bool)));
+ legendCheckBox->setChecked(true);
+ layout->addWidget(legendCheckBox, row++, 1, Qt::AlignLeft);
+
+ QCheckBox *titleCheckBox = new QCheckBox(QStringLiteral("Title"));
+ connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
+ titleCheckBox->setChecked(true);
+ layout->addWidget(titleCheckBox, row++, 1, Qt::AlignLeft);
+
+ layout->addWidget(new QLabel(QStringLiteral("Chart theme:")), row, 0, Qt::AlignLeft);
+ QComboBox *chartThemeComboBox = new QComboBox();
+ chartThemeComboBox->addItem(QStringLiteral("Light"));
+ chartThemeComboBox->addItem(QStringLiteral("Blue Cerulean"));
+ chartThemeComboBox->addItem(QStringLiteral("Dark"));
+ chartThemeComboBox->addItem(QStringLiteral("Brown Sand"));
+ chartThemeComboBox->addItem(QStringLiteral("Blue Ncs"));
+ chartThemeComboBox->addItem(QStringLiteral("High Contrast"));
+ chartThemeComboBox->addItem(QStringLiteral("Blue Icy"));
+ chartThemeComboBox->addItem(QStringLiteral("Qt"));
+ connect(chartThemeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeChartTheme(int)));
+ layout->addWidget(chartThemeComboBox, row++, 1, Qt::AlignLeft);
+
+ layout->addWidget(new QLabel(QStringLiteral("Axis X:")), row, 0, Qt::AlignLeft);
+ QComboBox *axisXComboBox = new QComboBox();
+ axisXComboBox->addItem(QStringLiteral("BarCategory"));
+ axisXComboBox->addItem(QStringLiteral("DateTime"));
+ axisXComboBox->addItem(QStringLiteral("Value"));
+ connect(axisXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAxisX(int)));
+ layout->addWidget(axisXComboBox, row++, 1, Qt::AlignLeft);
+
+ return layout;
+}
+
+QGridLayout *MainWidget::createModelMapperControlsLayout()
+{
+ QGridLayout *layout = new QGridLayout();
+ int row = 0;
+
+ layout->addWidget(new QLabel(QStringLiteral("First series:")), row, 0, Qt::AlignLeft);
+
+ QPushButton *attachModelMapperButton = new QPushButton(QStringLiteral("Attach model mapper"));
+ connect(attachModelMapperButton, SIGNAL(clicked(bool)), this, SLOT(attachModelMapper()));
+ layout->addWidget(attachModelMapperButton, row++, 1, Qt::AlignLeft);
+
+ QPushButton *detachModelMappeButton = new QPushButton(QStringLiteral("Detach model mapper"));
+ connect(detachModelMappeButton, SIGNAL(clicked(bool)), this, SLOT(detachModelMapper()));
+ layout->addWidget(detachModelMappeButton, row++, 1, Qt::AlignLeft);
+
+ QTableView *tableView = new QTableView();
+ tableView->setMinimumSize(320, 480);
+ tableView->setMaximumSize(320, 480);
+ tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ Q_ASSERT_X(m_hModelMapper->model(), Q_FUNC_INFO, "Model is not initialized");
+ tableView->setModel(m_hModelMapper->model());
+ layout->addWidget(tableView, row++, 0, 1, 2, Qt::AlignLeft);
+
+ layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);
+
+ return layout;
+}
+
+qreal MainWidget::randomValue(int min, int max) const
+{
+ return (qrand() / (qreal(RAND_MAX) + 1)) * ((qMax(min, max) - qMin(min, max)) + qMin(min, max));
+}
+
+QCandlestickSet *MainWidget::randomSet(qreal timestamp)
+{
+ QCandlestickSet *set = new QCandlestickSet(timestamp);
+ set->setOpen(randomValue(4, 11));
+ set->setHigh(randomValue(12, 15));
+ set->setLow(randomValue(0, 3));
+ set->setClose(randomValue(4, 11));
+
+ return set;
+}
+
+void MainWidget::updateAxes()
+{
+ if (m_chart->axes().isEmpty())
+ m_chart->createDefaultAxes();
+
+ QCandlestickSeries *series;
+ if (!m_chart->series().isEmpty())
+ series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
+ else
+ series = nullptr;
+
+ m_axisX = m_chart->axes(Qt::Horizontal).first();
+ if (series && !series->candlestickSets().isEmpty()) {
+ if (m_axisX->type() == QAbstractAxis::AxisTypeBarCategory) {
+ QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(m_axisX);
+ QStringList categories;
+ for (int i = 0; i < series->candlestickSets().count(); ++i)
+ categories.append(QString::number(i));
+ axisX->setCategories(categories);
+ } else { // QAbstractAxis::AxisTypeDateTime || QAbstractAxis::AxisTypeValue
+ qreal msInMonth = 31.0 * 24.0 * 60.0 * 60.0 * 1000.0;
+ qreal min = series->candlestickSets().first()->timestamp() - msInMonth;
+ qreal max = series->candlestickSets().last()->timestamp() + msInMonth;
+ QDateTime minDateTime = QDateTime::fromMSecsSinceEpoch(min);
+ QDateTime maxDateTime = QDateTime::fromMSecsSinceEpoch(max);
+
+ if (m_axisX->type() == QAbstractAxis::AxisTypeDateTime)
+ m_axisX->setRange(minDateTime, maxDateTime);
+ else
+ m_axisX->setRange(min, max);
+ }
+ }
+
+ m_axisY = m_chart->axes(Qt::Vertical).first();
+ m_axisY->setMax(15);
+ m_axisY->setMin(0);
+}
+
+void MainWidget::addSeries()
+{
+ if (m_chart->series().count() > 9) {
+ qDebug() << "Maximum series count is 10";
+ return;
+ }
+
+ QCandlestickSeries *series = new QCandlestickSeries();
+ series->setName(QStringLiteral("S%1").arg(m_chart->series().count() + 1));
+ series->setMaximumColumnWidth(m_maximumColumnWidth);
+ series->setMinimumColumnWidth(m_minimumColumnWidth);
+ series->setBodyOutlineVisible(m_bodyOutlineVisible);
+ series->setBodyWidth(m_bodyWidth);
+ series->setCapsVisible(m_capsVisible);
+ series->setCapsWidth(m_capsWidth);
+
+ if (m_chart->series().isEmpty()) {
+ if (m_customIncreasingColor)
+ series->setIncreasingColor(QColor(Qt::green));
+ if (m_customDecreasingColor)
+ series->setDecreasingColor(QColor(Qt::red));
+
+ for (int month = 1; month <= 12; ++month) {
+ QDateTime dateTime;
+ dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), month, 1));
+ dateTime.setTime(QTime(12, 34, 56, 789));
+
+ QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
+ series->append(set);
+ }
+ } else {
+ QCandlestickSeries *s = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
+ for (int i = 0; i < s->candlestickSets().count(); ++i) {
+ QCandlestickSet *set = randomSet(s->candlestickSets().at(i)->timestamp());
+ series->append(set);
+ }
+ }
+
+ m_chart->addSeries(series);
+
+ updateAxes();
+ if (!series->attachedAxes().contains(m_axisX))
+ series->attachAxis(m_axisX);
+ if (!series->attachedAxes().contains(m_axisY))
+ series->attachAxis(m_axisY);
+}
+
+void MainWidget::removeSeries()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ if (m_chart->series().count() == 1)
+ detachModelMapper();
+
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().last());
+ m_chart->removeSeries(series);
+ delete series;
+ series = nullptr;
+}
+
+void MainWidget::removeAllSeries()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ detachModelMapper();
+
+ m_chart->removeAllSeries();
+}
+
+void MainWidget::addSet()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+
+ QDateTime dateTime;
+ if (series->count()) {
+ dateTime.setMSecsSinceEpoch(series->candlestickSets().last()->timestamp());
+ dateTime = dateTime.addMonths(1);
+ } else {
+ dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
+ dateTime.setTime(QTime(12, 34, 56, 789));
+ }
+
+ QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
+ series->append(set);
+ }
+
+ updateAxes();
+}
+
+void MainWidget::insertSet()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+
+ QDateTime dateTime;
+ if (series->count()) {
+ dateTime.setMSecsSinceEpoch(series->candlestickSets().first()->timestamp());
+ dateTime = dateTime.addMonths(-1);
+ } else {
+ dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
+ dateTime.setTime(QTime(12, 34, 56, 789));
+ }
+
+ QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
+ series->insert(0, set);
+ }
+
+ updateAxes();
+}
+
+void MainWidget::removeSet()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ if (series->candlestickSets().isEmpty())
+ qDebug() << "Create a set first";
+ else
+ series->remove(series->candlestickSets().last());
+ }
+
+ updateAxes();
+}
+
+void MainWidget::removeAllSets()
+{
+ if (m_chart->series().isEmpty()) {
+ qDebug() << "Create a series first";
+ return;
+ }
+
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ if (series->candlestickSets().isEmpty())
+ qDebug() << "Create a set first";
+ else
+ series->clear();
+ }
+
+ updateAxes();
+}
+
+void MainWidget::changeMaximumColumnWidth(double width)
+{
+ m_maximumColumnWidth = width;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setMaximumColumnWidth(m_maximumColumnWidth);
+ }
+}
+
+void MainWidget::changeMinimumColumnWidth(double width)
+{
+ m_minimumColumnWidth = width;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setMinimumColumnWidth(m_minimumColumnWidth);
+ }
+}
+
+void MainWidget::bodyOutlineVisibleToggled(bool visible)
+{
+ m_bodyOutlineVisible = visible;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setBodyOutlineVisible(m_bodyOutlineVisible);
+ }
+}
+
+void MainWidget::capsVisibleToggled(bool visible)
+{
+ m_capsVisible = visible;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setCapsVisible(m_capsVisible);
+ }
+}
+
+void MainWidget::changeBodyWidth(double width)
+{
+ m_bodyWidth = width;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setBodyWidth(m_bodyWidth);
+ }
+}
+
+void MainWidget::changeCapsWidth(double width)
+{
+ m_capsWidth = width;
+ foreach (QAbstractSeries *s, m_chart->series()) {
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
+ series->setCapsWidth(m_capsWidth);
+ }
+}
+
+void MainWidget::customIncreasingColorToggled(bool custom)
+{
+ m_customIncreasingColor = custom;
+
+ if (m_chart->series().isEmpty())
+ return;
+
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
+ if (series) {
+ QColor color = m_customIncreasingColor ? QColor(Qt::green) : QColor();
+ series->setIncreasingColor(color);
+ }
+}
+
+void MainWidget::customDecreasingColorToggled(bool custom)
+{
+ m_customDecreasingColor = custom;
+
+ if (m_chart->series().isEmpty())
+ return;
+
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
+ if (series) {
+ QColor color = m_customDecreasingColor ? QColor(Qt::red) : QColor();
+ series->setDecreasingColor(color);
+ }
+}
+
+void MainWidget::antialiasingToggled(bool enabled)
+{
+ m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
+}
+
+void MainWidget::animationToggled(bool enabled)
+{
+ if (enabled)
+ m_chart->setAnimationOptions(QChart::SeriesAnimations);
+ else
+ m_chart->setAnimationOptions(QChart::NoAnimation);
+}
+
+void MainWidget::legendToggled(bool visible)
+{
+ m_chart->legend()->setVisible(visible);
+ if (visible)
+ m_chart->legend()->setAlignment(Qt::AlignBottom);
+}
+
+void MainWidget::titleToggled(bool visible)
+{
+ if (visible)
+ m_chart->setTitle(QStringLiteral("Candlestick Chart"));
+ else
+ m_chart->setTitle(QString());
+}
+
+void MainWidget::changeChartTheme(int themeIndex)
+{
+ if (themeIndex < QChart::ChartThemeLight || themeIndex > QChart::ChartThemeQt) {
+ qDebug() << "Invalid chart theme index:" << themeIndex;
+ return;
+ }
+
+ m_chart->setTheme((QChart::ChartTheme)(themeIndex));
+}
+
+void MainWidget::changeAxisX(int axisXIndex)
+{
+ if (m_axisX) {
+ m_chart->removeAxis(m_axisX);
+ delete m_axisX;
+ }
+
+ switch (axisXIndex) {
+ case 0:
+ m_axisX = new QBarCategoryAxis();
+ break;
+ case 1:
+ m_axisX = new QDateTimeAxis();
+ break;
+ case 2:
+ m_axisX = new QValueAxis();
+ break;
+ default:
+ qDebug() << "Invalid axis x index:" << axisXIndex;
+ return;
+ }
+
+ m_chart->addAxis(m_axisX, Qt::AlignBottom);
+
+ updateAxes();
+
+ foreach (QAbstractSeries *series, m_chart->series())
+ series->attachAxis(m_axisX);
+}
+
+void MainWidget::attachModelMapper()
+{
+ if (m_hModelMapper->series()) {
+ qDebug() << "Model mapper is already attached";
+ return;
+ }
+
+ if (m_chart->series().isEmpty())
+ addSeries();
+
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
+ Q_ASSERT(series);
+ series->setName(QStringLiteral("SWMM")); // Series With Model Mapper
+
+ CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
+ foreach (QCandlestickSet *set, series->candlestickSets())
+ model->addRow(set);
+
+ m_hModelMapper->setFirstCandlestickSetRow(0);
+ m_hModelMapper->setLastCandlestickSetRow(model->rowCount() - 1);
+ m_hModelMapper->setSeries(series);
+}
+
+void MainWidget::detachModelMapper()
+{
+ if (!m_hModelMapper->series())
+ return;
+
+ QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_hModelMapper->series());
+ Q_ASSERT(series);
+ series->setName(QStringLiteral("S1"));
+
+ m_hModelMapper->setSeries(nullptr);
+ m_hModelMapper->setFirstCandlestickSetRow(-1);
+ m_hModelMapper->setLastCandlestickSetRow(-1);
+
+ CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
+ model->clearRows();
+}