##// END OF EJS Templates
Added candlestick chart type...
Alexander Mishin -
r2896:facc2941efbf
parent child
Show More
@@ -0,0 +1,24
1 # Acme Ltd Historical Data (July 2015)
2 # timestamp, open, high, low, close
3 1435708800000 126.90 126.94 125.99 126.60
4 1435795200000 126.69 126.69 126.69 126.69
5 1436140800000 124.85 126.23 124.85 126.00
6 1436227200000 125.89 126.15 123.77 125.69
7 1436313600000 124.64 124.64 122.54 122.54
8 1436400000000 123.85 124.06 119.22 120.07
9 1436486400000 121.94 123.85 121.21 123.28
10 1436745600000 125.03 125.76 124.32 125.66
11 1436832000000 126.04 126.37 125.04 125.61
12 1436918400000 125.72 127.15 125.58 126.82
13 1437004800000 127.74 128.57 127.35 128.51
14 1437091200000 129.08 129.62 128.31 129.62
15 1437350400000 130.97 132.97 130.70 132.07
16 1437436800000 132.85 132.92 130.32 130.75
17 1437523200000 121.99 125.50 121.99 125.22
18 1437609600000 126.20 127.09 125.06 125.16
19 1437696000000 125.32 125.74 123.90 124.50
20 1437955200000 123.09 123.61 122.12 122.77
21 1438041600000 123.38 123.91 122.55 123.38
22 1438128000000 123.15 123.50 122.27 122.99
23 1438214400000 122.32 122.57 121.71 122.37
24 1438300800000 122.60 122.64 120.91 121.30
@@ -0,0 +1,14
1 !include( ../examples.pri ) {
2 error( "Couldn't find the examples.pri file!" )
3 }
4
5 TARGET = candlestickchart
6
7 SOURCES += main.cpp \
8 candlestickdatareader.cpp
9
10 HEADERS += \
11 candlestickdatareader.h
12
13 RESOURCES += \
14 candlestickdata.qrc
@@ -0,0 +1,5
1 <RCC>
2 <qresource prefix="/">
3 <file alias="acme">acme_data.txt</file>
4 </qresource>
5 </RCC>
@@ -0,0 +1,77
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 "candlestickdatareader.h"
31
32 CandlestickDataReader::CandlestickDataReader(QIODevice *device)
33 : QTextStream(device)
34 {
35 }
36
37 CandlestickDataReader::~CandlestickDataReader()
38 {
39 }
40
41 void CandlestickDataReader::readFile(QIODevice *device)
42 {
43 QTextStream::setDevice(device);
44 }
45
46 QCandlestickSet *CandlestickDataReader::readCandlestickSet()
47 {
48 //! [1]
49 QString line = readLine();
50 if (line.startsWith("#") || line.isEmpty())
51 return 0;
52 //! [1]
53
54 //! [2]
55 QStringList strList = line.split(" ", QString::SkipEmptyParts);
56 if (strList.count() != 5)
57 return 0;
58 //! [2]
59
60 //! [3]
61 const qreal timestamp = strList.at(0).toDouble();
62 const qreal open = strList.at(1).toDouble();
63 const qreal high = strList.at(2).toDouble();
64 const qreal low = strList.at(3).toDouble();
65 const qreal close = strList.at(4).toDouble();
66 //! [3]
67
68 //! [4]
69 QCandlestickSet *candlestickSet = new QCandlestickSet(timestamp);
70 candlestickSet->setOpen(open);
71 candlestickSet->setHigh(high);
72 candlestickSet->setLow(low);
73 candlestickSet->setClose(close);
74 //! [4]
75
76 return candlestickSet;
77 }
@@ -0,0 +1,48
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 #ifndef CANDLESTICKDATAREADER_H
31 #define CANDLESTICKDATAREADER_H
32
33 #include <QtCharts/QCandlestickSet>
34 #include <QtCore/QTextStream>
35
36 QT_CHARTS_USE_NAMESPACE
37
38 class CandlestickDataReader : public QTextStream
39 {
40 public:
41 explicit CandlestickDataReader(QIODevice *device);
42 ~CandlestickDataReader();
43
44 void readFile(QIODevice *device);
45 QCandlestickSet *readCandlestickSet();
46 };
47
48 #endif // CANDLESTICKDATAREADER_H
@@ -0,0 +1,106
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 <QtCharts/QBarCategoryAxis>
31 #include <QtCharts/QCandlestickSeries>
32 #include <QtCharts/QChartView>
33 #include <QtCharts/QValueAxis>
34 #include <QtCore/QDateTime>
35 #include <QtWidgets/QApplication>
36 #include <QtWidgets/QMainWindow>
37
38 #include "candlestickdatareader.h"
39
40 QT_CHARTS_USE_NAMESPACE
41
42 int main(int argc, char *argv[])
43 {
44 QApplication a(argc, argv);
45
46 //! [1]
47 QCandlestickSeries *acmeSeries = new QCandlestickSeries();
48 acmeSeries->setName("Acme Ltd");
49 acmeSeries->setIncreasingColor(QColor(Qt::green));
50 acmeSeries->setDecreasingColor(QColor(Qt::red));
51 //! [1]
52
53 //! [2]
54 QFile acmeData(":acme");
55 if (!acmeData.open(QIODevice::ReadOnly | QIODevice::Text))
56 return 1;
57
58 QStringList categories;
59
60 CandlestickDataReader dataReader(&acmeData);
61 while (!dataReader.atEnd()) {
62 QCandlestickSet *set = dataReader.readCandlestickSet();
63 if (set) {
64 acmeSeries->append(set);
65 categories << QDateTime::fromMSecsSinceEpoch(set->timestamp()).toString("dd");
66 }
67 }
68 //! [2]
69
70 //! [3]
71 QChart *chart = new QChart();
72 chart->addSeries(acmeSeries);
73 chart->setTitle("Acme Ltd Historical Data (July 2015)");
74 chart->setAnimationOptions(QChart::SeriesAnimations);
75 //! [3]
76
77 //! [4]
78 chart->createDefaultAxes();
79
80 QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(chart->axes(Qt::Horizontal).at(0));
81 axisX->setCategories(categories);
82
83 QValueAxis *axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).at(0));
84 axisY->setMax(axisY->max() * 1.01);
85 axisY->setMin(axisY->min() * 0.99);
86 //! [4]
87
88 //! [5]
89 chart->legend()->setVisible(true);
90 chart->legend()->setAlignment(Qt::AlignBottom);
91 //! [5]
92
93 //! [6]
94 QChartView *chartView = new QChartView(chart);
95 chartView->setRenderHint(QPainter::Antialiasing);
96 //! [6]
97
98 //! [7]
99 QMainWindow window;
100 window.setCentralWidget(chartView);
101 window.resize(800, 600);
102 window.show();
103 //! [7]
104
105 return a.exec();
106 }
@@ -0,0 +1,59
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 <QtCore/QDir>
31 #include <QtQml/QQmlEngine>
32 #include <QtQuick/QQuickView>
33 #include <QtWidgets/QApplication>
34
35 int main(int argc, char *argv[])
36 {
37 // Qt Charts uses Qt Graphics View Framework for drawing, therefore QApplication must be used.
38 QApplication app(argc, argv);
39
40 QQuickView viewer;
41
42 // The following are needed to make examples run without having to install the module
43 // in desktop environments.
44 #ifdef Q_OS_WIN
45 QString extraImportPath(QStringLiteral("%1/../../../../%2"));
46 #else
47 QString extraImportPath(QStringLiteral("%1/../../../%2"));
48 #endif
49 viewer.engine()->addImportPath(extraImportPath.arg(QApplication::applicationDirPath(),
50 QString::fromLatin1("qml")));
51 QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
52
53 viewer.setTitle(QStringLiteral("QML Candlestick"));
54 viewer.setSource(QUrl("qrc:/qml/qmlcandlestick/main.qml"));
55 viewer.setResizeMode(QQuickView::SizeRootObjectToView);
56 viewer.show();
57
58 return app.exec();
59 }
@@ -0,0 +1,52
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 import QtQuick 2.0
31 import QtCharts 2.2
32
33 ChartView {
34 title: "Candlestick series"
35 width: 800
36 height: 600
37 theme: ChartView.ChartThemeLight
38 legend.alignment: Qt.AlignBottom
39 antialiasing: true
40
41 CandlestickSeries {
42 name: "Acme Ltd."
43 increasingColor: "green"
44 decreasingColor: "red"
45
46 CandlestickSet { timestamp: 1435708800000; open: 6.90; high: 6.94; low: 5.99; close: 6.60 }
47 CandlestickSet { timestamp: 1435795200000; open: 6.69; high: 6.69; low: 6.69; close: 6.69 }
48 CandlestickSet { timestamp: 1436140800000; open: 4.85; high: 6.23; low: 4.85; close: 6.00 }
49 CandlestickSet { timestamp: 1436227200000; open: 5.89; high: 6.15; low: 3.77; close: 5.69 }
50 CandlestickSet { timestamp: 1436313600000; open: 4.64; high: 4.64; low: 2.54; close: 2.54 }
51 }
52 }
@@ -0,0 +1,10
1 !include( ../examples.pri ) {
2 error( "Couldn't find the examples.pri file!" )
3 }
4
5 RESOURCES += resources.qrc
6
7 SOURCES += main.cpp
8
9 OTHER_FILES += \
10 qml/qmlcandlestick/main.qml
@@ -0,0 +1,5
1 <RCC>
2 <qresource prefix="/">
3 <file>qml/qmlcandlestick/main.qml</file>
4 </qresource>
5 </RCC>
@@ -0,0 +1,116
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 <private/candlestick_p.h>
31 #include <private/candlestickanimation_p.h>
32 #include <private/candlestickbodywicksanimation_p.h>
33 #include <private/candlestickchartitem_p.h>
34 #include <private/candlestickdata_p.h>
35
36 QT_CHARTS_BEGIN_NAMESPACE
37
38 CandlestickAnimation::CandlestickAnimation(CandlestickChartItem *item, int duration,
39 QEasingCurve &curve)
40 : QObject(item),
41 m_item(item),
42 m_animationDuration(duration),
43 m_animationCurve(curve)
44 {
45 }
46
47 CandlestickAnimation::~CandlestickAnimation()
48 {
49 }
50
51 void CandlestickAnimation::addCandlestick(Candlestick *candlestick)
52 {
53 CandlestickBodyWicksAnimation *animation = m_animations.value(candlestick, 0);
54 if (!animation) {
55 animation = new CandlestickBodyWicksAnimation(candlestick, this, m_animationDuration,
56 m_animationCurve);
57 m_animations.insert(candlestick, animation);
58
59 qreal median = (candlestick->m_data.m_open + candlestick->m_data.m_close) / 2;
60 CandlestickData start;
61 start.m_open = median;
62 start.m_high = median;
63 start.m_low = median;
64 start.m_close = median;
65 animation->setup(start, candlestick->m_data);
66 } else {
67 animation->stop();
68 animation->setEndData(candlestick->m_data);
69 }
70 }
71
72 ChartAnimation *CandlestickAnimation::candlestickAnimation(Candlestick *candlestick)
73 {
74 CandlestickBodyWicksAnimation *animation = m_animations.value(candlestick, 0);
75 if (animation)
76 animation->m_changeAnimation = false;
77
78 return animation;
79 }
80
81 ChartAnimation *CandlestickAnimation::candlestickChangeAnimation(Candlestick *candlestick)
82 {
83 CandlestickBodyWicksAnimation *animation = m_animations.value(candlestick, 0);
84 if (animation) {
85 animation->m_changeAnimation = true;
86 animation->setEndData(candlestick->m_data);
87 }
88
89 return animation;
90 }
91
92 void CandlestickAnimation::setAnimationStart(Candlestick *candlestick)
93 {
94 CandlestickBodyWicksAnimation *animation = m_animations.value(candlestick, 0);
95 if (animation)
96 animation->setStartData(candlestick->m_data);
97 }
98
99 void CandlestickAnimation::stopAll()
100 {
101 foreach (Candlestick *candlestick, m_animations.keys()) {
102 CandlestickBodyWicksAnimation *animation = m_animations.value(candlestick, 0);
103 if (animation)
104 animation->stopAndDestroyLater();
105 m_animations.remove(candlestick);
106 }
107 }
108
109 void CandlestickAnimation::removeCandlestickAnimation(Candlestick *candlestick)
110 {
111 m_animations.remove(candlestick);
112 }
113
114 #include "moc_candlestickanimation_p.cpp"
115
116 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,75
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef CANDLESTICKANIMATION_P_H
40 #define CANDLESTICKANIMATION_P_H
41
42 #include <private/chartanimation_p.h>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 class Candlestick;
47 class CandlestickChartItem;
48 class CandlestickBodyWicksAnimation;
49
50 class CandlestickAnimation : public QObject
51 {
52 Q_OBJECT
53
54 public:
55 CandlestickAnimation(CandlestickChartItem *item, int duration, QEasingCurve &curve);
56 ~CandlestickAnimation();
57
58 void addCandlestick(Candlestick *candlestick);
59 ChartAnimation *candlestickAnimation(Candlestick *candlestick);
60 ChartAnimation *candlestickChangeAnimation(Candlestick *candlestick);
61
62 void setAnimationStart(Candlestick *candlestick);
63 void stopAll();
64 void removeCandlestickAnimation(Candlestick *candlestick);
65
66 protected:
67 QHash<Candlestick *, CandlestickBodyWicksAnimation *> m_animations;
68 CandlestickChartItem *m_item;
69 int m_animationDuration;
70 QEasingCurve m_animationCurve;
71 };
72
73 QT_CHARTS_END_NAMESPACE
74
75 #endif // CANDLESTICKANIMATION_P_H
@@ -0,0 +1,112
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 <private/candlestick_p.h>
31 #include <private/candlestickanimation_p.h>
32 #include <private/candlestickbodywicksanimation_p.h>
33
34 Q_DECLARE_METATYPE(QVector<QRectF>)
35 Q_DECLARE_METATYPE(QT_CHARTS_NAMESPACE::CandlestickData)
36 Q_DECLARE_METATYPE(qreal)
37
38 QT_CHARTS_BEGIN_NAMESPACE
39
40 CandlestickBodyWicksAnimation::CandlestickBodyWicksAnimation(Candlestick *candlestick,
41 CandlestickAnimation *animation,
42 int duration, QEasingCurve &curve)
43 : ChartAnimation(candlestick),
44 m_candlestick(candlestick),
45 m_candlestickAnimation(animation),
46 m_changeAnimation(false)
47 {
48 setDuration(duration);
49 setEasingCurve(curve);
50 }
51
52 CandlestickBodyWicksAnimation::~CandlestickBodyWicksAnimation()
53 {
54 if (m_candlestickAnimation)
55 m_candlestickAnimation->removeCandlestickAnimation(m_candlestick);
56 }
57
58 void CandlestickBodyWicksAnimation::setup(const CandlestickData &startData,
59 const CandlestickData &endData)
60 {
61 setKeyValueAt(0.0, qVariantFromValue(startData));
62 setKeyValueAt(1.0, qVariantFromValue(endData));
63 }
64
65 void CandlestickBodyWicksAnimation::setStartData(const CandlestickData &startData)
66 {
67 if (state() != QAbstractAnimation::Stopped)
68 stop();
69
70 setStartValue(qVariantFromValue(startData));
71 }
72
73 void CandlestickBodyWicksAnimation::setEndData(const CandlestickData &endData)
74 {
75 if (state() != QAbstractAnimation::Stopped)
76 stop();
77
78 setEndValue(qVariantFromValue(endData));
79 }
80
81 void CandlestickBodyWicksAnimation::updateCurrentValue(const QVariant &value)
82 {
83 CandlestickData data = qvariant_cast<CandlestickData>(value);
84 m_candlestick->setLayout(data);
85 }
86
87 QVariant CandlestickBodyWicksAnimation::interpolated(const QVariant &from, const QVariant &to,
88 qreal progress) const
89 {
90 CandlestickData startData = qvariant_cast<CandlestickData>(from);
91 CandlestickData endData = qvariant_cast<CandlestickData>(to);
92 CandlestickData result = endData;
93
94 if (m_changeAnimation) {
95 result.m_open = startData.m_open + progress * (endData.m_open - startData.m_open);
96 result.m_high = startData.m_high + progress * (endData.m_high - startData.m_high);
97 result.m_low = startData.m_low + progress * (endData.m_low - startData.m_low);
98 result.m_close = startData.m_close + progress * (endData.m_close - startData.m_close);
99 } else {
100 const qreal median = (endData.m_open + endData.m_close) / 2;
101 result.m_low = median + progress * (endData.m_low - median);
102 result.m_close = median + progress * (endData.m_close - median);
103 result.m_open = median + progress * (endData.m_open - median);
104 result.m_high = median + progress * (endData.m_high - median);
105 }
106
107 return qVariantFromValue(result);
108 }
109
110 #include "moc_candlestickbodywicksanimation_p.cpp"
111
112 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,77
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef CANDLESTICKBODYWICKSANIMATION_P_H
40 #define CANDLESTICKBODYWICKSANIMATION_P_H
41
42 #include <private/candlestickdata_p.h>
43 #include <private/chartanimation_p.h>
44
45 QT_CHARTS_BEGIN_NAMESPACE
46
47 class Candlestick;
48 class CandlestickAnimation;
49
50 class CandlestickBodyWicksAnimation : public ChartAnimation
51 {
52 Q_OBJECT
53
54 public:
55 CandlestickBodyWicksAnimation(Candlestick *candlestick, CandlestickAnimation *animation,
56 int duration, QEasingCurve &curve);
57 ~CandlestickBodyWicksAnimation();
58
59 void setup(const CandlestickData &startData, const CandlestickData &endData);
60 void setStartData(const CandlestickData &startData);
61 void setEndData(const CandlestickData &endData);
62
63 // from QVariantAnimation
64 virtual void updateCurrentValue(const QVariant &value);
65 virtual QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress) const;
66
67 protected:
68 Candlestick *m_candlestick;
69 CandlestickAnimation *m_candlestickAnimation;
70 bool m_changeAnimation;
71
72 friend class CandlestickAnimation;
73 };
74
75 QT_CHARTS_END_NAMESPACE
76
77 #endif // CANDLESTICKBODYWICKSANIMATION_P_H
@@ -0,0 +1,351
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 <QtCharts/QCandlestickSet>
31 #include <QtGui/QPainter>
32 #include <private/abstractdomain_p.h>
33 #include <private/candlestick_p.h>
34 #include <private/qchart_p.h>
35
36 QT_CHARTS_BEGIN_NAMESPACE
37
38 Candlestick::Candlestick(QCandlestickSet *set, AbstractDomain *domain, QGraphicsObject *parent)
39 : QGraphicsObject(parent),
40 m_set(set),
41 m_domain(domain),
42 m_timePeriod(0.0),
43 m_maximumColumnWidth(-1.0), // no maximum column width by default
44 m_minimumColumnWidth(-1.0), // no minimum column width by default
45 m_bodyWidth(0.5),
46 m_bodyOutlineVisible(true),
47 m_capsWidth(0.5),
48 m_capsVisible(false),
49 m_brush(QChartPrivate::defaultBrush()),
50 m_pen(QChartPrivate::defaultPen()),
51 m_hovering(false),
52 m_mousePressed(false)
53 {
54 setAcceptHoverEvents(true);
55 setAcceptedMouseButtons(Qt::MouseButtonMask);
56 setFlag(QGraphicsObject::ItemIsSelectable);
57 }
58
59 Candlestick::~Candlestick()
60 {
61 // End hover event, if candlestick is deleted during it.
62 if (m_hovering)
63 emit hovered(false, m_set);
64 }
65
66 void Candlestick::setTimePeriod(qreal timePeriod)
67 {
68 m_timePeriod = timePeriod;
69 }
70
71 void Candlestick::setMaximumColumnWidth(qreal maximumColumnWidth)
72 {
73 m_maximumColumnWidth = maximumColumnWidth;
74 }
75
76 void Candlestick::setMinimumColumnWidth(qreal minimumColumnWidth)
77 {
78 m_minimumColumnWidth = minimumColumnWidth;
79 }
80
81 void Candlestick::setBodyWidth(qreal bodyWidth)
82 {
83 m_bodyWidth = bodyWidth;
84 }
85
86 void Candlestick::setBodyOutlineVisible(bool bodyOutlineVisible)
87 {
88 m_bodyOutlineVisible = bodyOutlineVisible;
89 }
90
91 void Candlestick::setCapsWidth(qreal capsWidth)
92 {
93 m_capsWidth = capsWidth;
94 }
95
96 void Candlestick::setCapsVisible(bool capsVisible)
97 {
98 m_capsVisible = capsVisible;
99 }
100
101 void Candlestick::setIncreasingColor(const QColor &color)
102 {
103 m_increasingColor = color;
104
105 update();
106 }
107
108 void Candlestick::setDecreasingColor(const QColor &color)
109 {
110 m_decreasingColor = color;
111
112 update();
113 }
114
115 void Candlestick::setBrush(const QBrush &brush)
116 {
117 m_brush = brush;
118
119 update();
120 }
121
122 void Candlestick::setPen(const QPen &pen)
123 {
124 qreal widthDiff = pen.widthF() - m_pen.widthF();
125 m_boundingRect.adjust(-widthDiff, -widthDiff, widthDiff, widthDiff);
126
127 m_pen = pen;
128
129 update();
130 }
131
132 void Candlestick::setLayout(const CandlestickData &data)
133 {
134 m_data = data;
135
136 updateGeometry(m_domain);
137 update();
138 }
139
140 void Candlestick::mousePressEvent(QGraphicsSceneMouseEvent *event)
141 {
142 m_mousePressed = true;
143 emit pressed(m_set);
144 QGraphicsItem::mousePressEvent(event);
145 }
146
147 void Candlestick::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
148 {
149 Q_UNUSED(event)
150
151 m_hovering = true;
152 emit hovered(m_hovering, m_set);
153 }
154
155 void Candlestick::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
156 {
157 Q_UNUSED(event)
158
159 m_hovering = false;
160 emit hovered(m_hovering, m_set);
161 }
162
163 void Candlestick::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
164 {
165 emit released(m_set);
166 if (m_mousePressed)
167 emit clicked(m_set);
168 m_mousePressed = false;
169 QGraphicsItem::mouseReleaseEvent(event);
170 }
171
172 void Candlestick::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
173 {
174 // For candlestick a pressed signal needs to be explicitly fired for mouseDoubleClickEvent.
175 emit pressed(m_set);
176 emit doubleClicked(m_set);
177 QGraphicsItem::mouseDoubleClickEvent(event);
178 }
179
180 QRectF Candlestick::boundingRect() const
181 {
182 return m_boundingRect;
183 }
184
185 void Candlestick::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
186 {
187 Q_UNUSED(option)
188 Q_UNUSED(widget)
189
190 bool increasingTrend = (m_data.m_open < m_data.m_close);
191 QColor color = increasingTrend ? m_increasingColor : m_decreasingColor;
192
193 QBrush brush(m_brush);
194 brush.setColor(color);
195
196 painter->save();
197 painter->setBrush(brush);
198 painter->setPen(m_pen);
199 painter->setClipRect(m_boundingRect);
200 if (m_capsVisible)
201 painter->drawPath(m_capsPath);
202 painter->drawPath(m_wicksPath);
203 if (!m_bodyOutlineVisible)
204 painter->setPen(QColor(Qt::transparent));
205 painter->drawRect(m_bodyRect);
206 painter->restore();
207 }
208
209 void Candlestick::updateGeometry(AbstractDomain *domain)
210 {
211 m_domain = domain;
212
213 prepareGeometryChange();
214
215 m_capsPath = QPainterPath();
216 m_wicksPath = QPainterPath();
217 m_boundingRect = QRectF();
218
219 if (!m_data.m_series->chart())
220 return;
221
222 QList<QAbstractAxis *> axes = m_data.m_series->chart()->axes(Qt::Horizontal, m_data.m_series);
223 if (axes.isEmpty())
224 return;
225
226 QAbstractAxis *axisX = axes.value(0);
227 if (!axisX)
228 return;
229
230 qreal columnWidth = 0.0;
231 qreal columnCenter = 0.0;
232 switch (axisX->type()) {
233 case QAbstractAxis::AxisTypeBarCategory:
234 columnWidth = 1.0 / m_data.m_seriesCount;
235 columnCenter = m_data.m_index - 0.5
236 + m_data.m_seriesIndex * columnWidth
237 + columnWidth / 2.0;
238 break;
239 case QAbstractAxis::AxisTypeDateTime:
240 case QAbstractAxis::AxisTypeValue:
241 columnWidth = m_timePeriod;
242 columnCenter = m_data.m_timestamp;
243 break;
244 default:
245 qWarning() << "Unexpected axis type";
246 return;
247 }
248
249 const qreal bodyWidth = m_bodyWidth * columnWidth;
250 const qreal bodyLeft = columnCenter - (bodyWidth / 2.0);
251 const qreal bodyRight = bodyLeft + bodyWidth;
252
253 const qreal upperBody = qMax(m_data.m_open, m_data.m_close);
254 const qreal lowerBody = qMin(m_data.m_open, m_data.m_close);
255 const bool upperWickVisible = (m_data.m_high > upperBody);
256 const bool lowerWickVisible = (m_data.m_low < lowerBody);
257
258 QPointF geometryPoint;
259 bool validData;
260
261 // upper extreme
262 geometryPoint = m_domain->calculateGeometryPoint(QPointF(bodyLeft, m_data.m_high), validData);
263 if (!validData)
264 return;
265 const qreal geometryUpperExtreme = geometryPoint.y();
266 // upper body
267 geometryPoint = m_domain->calculateGeometryPoint(QPointF(bodyLeft, upperBody), validData);
268 if (!validData)
269 return;
270 const qreal geometryBodyLeft = geometryPoint.x();
271 const qreal geometryUpperBody = geometryPoint.y();
272 // lower body
273 geometryPoint = m_domain->calculateGeometryPoint(QPointF(bodyRight, lowerBody), validData);
274 if (!validData)
275 return;
276 const qreal geometryBodyRight = geometryPoint.x();
277 const qreal geometryLowerBody = geometryPoint.y();
278 // lower extreme
279 geometryPoint = m_domain->calculateGeometryPoint(QPointF(bodyRight, m_data.m_low), validData);
280 if (!validData)
281 return;
282 const qreal geometryLowerExtreme = geometryPoint.y();
283
284 // Real Body
285 m_bodyRect.setCoords(geometryBodyLeft, geometryUpperBody, geometryBodyRight, geometryLowerBody);
286 if (m_maximumColumnWidth != -1.0) {
287 if (m_bodyRect.width() > m_maximumColumnWidth) {
288 qreal extra = (m_bodyRect.width() - m_maximumColumnWidth) / 2.0;
289 m_bodyRect.adjust(extra, 0.0, 0.0, 0.0);
290 m_bodyRect.setWidth(m_maximumColumnWidth);
291 }
292 }
293 if (m_minimumColumnWidth != -1.0) {
294 if (m_bodyRect.width() < m_minimumColumnWidth) {
295 qreal extra = (m_minimumColumnWidth - m_bodyRect.width()) / 2.0;
296 m_bodyRect.adjust(-extra, 0.0, 0.0, 0.0);
297 m_bodyRect.setWidth(m_minimumColumnWidth);
298 }
299 }
300
301 const qreal geometryCapsExtra = (m_bodyRect.width() - (m_bodyRect.width() * m_capsWidth)) /2.0;
302 const qreal geometryCapsLeft = m_bodyRect.left() + geometryCapsExtra;
303 const qreal geometryCapsRight = m_bodyRect.right() - geometryCapsExtra;
304
305 // Upper Wick and Cap
306 if (upperWickVisible) {
307 m_capsPath.moveTo(geometryCapsLeft, geometryUpperExtreme);
308 m_capsPath.lineTo(geometryCapsRight, geometryUpperExtreme);
309 m_wicksPath.moveTo((geometryCapsLeft + geometryCapsRight) / 2.0, geometryUpperExtreme);
310 m_wicksPath.lineTo((geometryCapsLeft + geometryCapsRight) / 2.0, geometryUpperBody);
311 }
312 // Lower Wick and Cap
313 if (lowerWickVisible) {
314 m_capsPath.moveTo(geometryCapsLeft, geometryLowerExtreme);
315 m_capsPath.lineTo(geometryCapsRight, geometryLowerExtreme);
316 m_wicksPath.moveTo((geometryCapsLeft + geometryCapsRight) / 2.0, geometryLowerBody);
317 m_wicksPath.lineTo((geometryCapsLeft + geometryCapsRight) / 2.0, geometryLowerExtreme);
318 }
319 m_wicksPath.closeSubpath();
320
321 // bounding rectangle top
322 qreal boundingRectTop;
323 if (upperWickVisible)
324 boundingRectTop = m_wicksPath.boundingRect().top();
325 else
326 boundingRectTop = m_bodyRect.top();
327 boundingRectTop = qMax(boundingRectTop, parentItem()->boundingRect().top());
328 // bounding rectangle right
329 qreal boundingRectRight = qMin(m_bodyRect.right(), parentItem()->boundingRect().right());
330 // bounding rectangle bottom
331 qreal boundingRectBottom;
332 if (lowerWickVisible)
333 boundingRectBottom = m_wicksPath.boundingRect().bottom();
334 else
335 boundingRectBottom = m_bodyRect.bottom();
336 boundingRectBottom = qMin(boundingRectBottom, parentItem()->boundingRect().bottom());
337 // bounding rectangle left
338 qreal boundingRectLeft = qMax(m_bodyRect.left(), parentItem()->boundingRect().left());
339
340 m_boundingRect.setTop(boundingRectTop);
341 m_boundingRect.setRight(boundingRectRight);
342 m_boundingRect.setBottom(boundingRectBottom);
343 m_boundingRect.setLeft(boundingRectLeft);
344
345 qreal extra = m_pen.widthF();
346 m_boundingRect.adjust(-extra, -extra, extra, extra);
347 }
348
349 #include "moc_candlestick_p.cpp"
350
351 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,121
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef CANDLESTICK_P_H
40 #define CANDLESTICK_P_H
41
42 #include <QtGui/QBrush>
43 #include <QtGui/QPainterPath>
44 #include <QtGui/QPen>
45 #include <QtWidgets/QGraphicsObject>
46 #include <private/candlestickdata_p.h>
47
48 QT_CHARTS_BEGIN_NAMESPACE
49
50 class AbstractDomain;
51 class QCandlestickSet;
52
53 class Candlestick : public QGraphicsObject
54 {
55 Q_OBJECT
56
57 public:
58 Candlestick(QCandlestickSet *set, AbstractDomain *domain, QGraphicsObject *parent);
59 ~Candlestick();
60
61 void setTimePeriod(qreal timePeriod);
62 void setMaximumColumnWidth(qreal maximumColumnWidth);
63 void setMinimumColumnWidth(qreal minimumColumnWidth);
64 void setBodyWidth(qreal bodyWidth);
65 void setBodyOutlineVisible(bool bodyOutlineVisible);
66 void setCapsWidth(qreal capsWidth);
67 void setCapsVisible(bool capsVisible);
68 void setIncreasingColor(const QColor &color);
69 void setDecreasingColor(const QColor &color);
70 void setBrush(const QBrush &brush);
71 void setPen(const QPen &pen);
72 void setLayout(const CandlestickData &data);
73
74 void mousePressEvent(QGraphicsSceneMouseEvent *event);
75 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
76 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
77 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
78 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
79
80 QRectF boundingRect() const;
81 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget = nullptr);
82
83 Q_SIGNALS:
84 void clicked(QCandlestickSet *set);
85 void hovered(bool status, QCandlestickSet *set);
86 void pressed(QCandlestickSet *set);
87 void released(QCandlestickSet *set);
88 void doubleClicked(QCandlestickSet *set);
89
90 private:
91 void updateGeometry(AbstractDomain *domain);
92
93 private:
94 QCandlestickSet *m_set;
95 AbstractDomain *m_domain;
96 qreal m_timePeriod;
97 qreal m_maximumColumnWidth;
98 qreal m_minimumColumnWidth;
99 qreal m_bodyWidth;
100 bool m_bodyOutlineVisible;
101 qreal m_capsWidth;
102 bool m_capsVisible;
103 QColor m_increasingColor;
104 QColor m_decreasingColor;
105 QBrush m_brush;
106 QPen m_pen;
107 CandlestickData m_data;
108 bool m_hovering;
109 bool m_mousePressed;
110 QRectF m_boundingRect;
111 QRectF m_bodyRect;
112 QPainterPath m_wicksPath;
113 QPainterPath m_capsPath;
114
115 friend class CandlestickAnimation;
116 friend class CandlestickChartItem;
117 };
118
119 QT_CHARTS_END_NAMESPACE
120
121 #endif // CANDLESTICK_P_H
@@ -0,0 +1,26
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/candlestick.cpp \
6 $$PWD/candlestickchartitem.cpp \
7 $$PWD/qcandlestickseries.cpp \
8 $$PWD/qcandlestickset.cpp \
9 $$PWD/qcandlestickmodelmapper.cpp \
10 $$PWD/qhcandlestickmodelmapper.cpp \
11 $$PWD/qvcandlestickmodelmapper.cpp
12
13 PRIVATE_HEADERS += \
14 $$PWD/candlestick_p.h \
15 $$PWD/candlestickchartitem_p.h \
16 $$PWD/candlestickdata_p.h \
17 $$PWD/qcandlestickseries_p.h \
18 $$PWD/qcandlestickset_p.h \
19 $$PWD/qcandlestickmodelmapper_p.h
20
21 PUBLIC_HEADERS += \
22 $$PWD/qcandlestickseries.h \
23 $$PWD/qcandlestickset.h \
24 $$PWD/qcandlestickmodelmapper.h \
25 $$PWD/qhcandlestickmodelmapper.h \
26 $$PWD/qvcandlestickmodelmapper.h
@@ -0,0 +1,347
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 <QtCharts/QCandlestickSeries>
31 #include <QtCharts/QCandlestickSet>
32 #include <private/candlestickchartitem_p.h>
33 #include <private/candlestick_p.h>
34 #include <private/candlestickdata_p.h>
35 #include <private/qcandlestickseries_p.h>
36 #include <private/candlestickanimation_p.h>
37
38 QT_CHARTS_BEGIN_NAMESPACE
39
40 CandlestickChartItem::CandlestickChartItem(QCandlestickSeries *series, QGraphicsItem *item)
41 : ChartItem(series->d_func(), item),
42 m_series(series),
43 m_seriesIndex(0),
44 m_seriesCount(0),
45 m_timePeriod(0.0),
46 m_animation(nullptr)
47 {
48 connect(series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)),
49 this, SLOT(handleCandlestickSetsAdd(QList<QCandlestickSet *>)));
50 connect(series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet *>)),
51 this, SLOT(handleCandlestickSetsRemove(QList<QCandlestickSet *>)));
52
53 connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleCandlesticksUpdated()));
54 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutUpdated()));
55 connect(series->d_func(), SIGNAL(updatedCandlesticks()),
56 this, SLOT(handleCandlesticksUpdated()));
57
58 setZValue(ChartPresenter::CandlestickSeriesZValue);
59
60 handleCandlestickSetsAdd(m_series->candlestickSets());
61 }
62
63 CandlestickChartItem::~CandlestickChartItem()
64 {
65 }
66
67 void CandlestickChartItem::setAnimation(CandlestickAnimation *animation)
68 {
69 m_animation = animation;
70
71 if (m_animation) {
72 foreach (Candlestick *item, m_candlesticks.values())
73 m_animation->addCandlestick(item);
74
75 handleDomainUpdated();
76 }
77 }
78
79 QRectF CandlestickChartItem::boundingRect() const
80 {
81 return m_boundingRect;
82 }
83
84 void CandlestickChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
85 QWidget *widget)
86 {
87 Q_UNUSED(painter);
88 Q_UNUSED(option);
89 Q_UNUSED(widget);
90 }
91
92 void CandlestickChartItem::handleDomainUpdated()
93 {
94 if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0))
95 return;
96
97 // Set bounding rectangle to same as domain size. Add one pixel at the top (-1.0) and the bottom
98 // as 0.0 would snip a bit off from the wick at the grid line.
99 m_boundingRect.setRect(0.0, -1.0, domain()->size().width(), domain()->size().height() + 1.0);
100
101 foreach (Candlestick *item, m_candlesticks.values()) {
102 item->updateGeometry(domain());
103
104 if (m_animation)
105 presenter()->startAnimation(m_animation->candlestickAnimation(item));
106 }
107 }
108
109 void CandlestickChartItem::handleLayoutUpdated()
110 {
111 bool timestampChanged = false;
112 foreach (QCandlestickSet *set, m_candlesticks.keys()) {
113 qreal oldTimestamp = m_candlesticks.value(set)->m_data.m_timestamp;
114 qreal newTimestamp = set->timestamp();
115 if (Q_UNLIKELY(oldTimestamp != newTimestamp)) {
116 removeTimestamp(oldTimestamp);
117 addTimestamp(newTimestamp);
118 timestampChanged = true;
119 }
120 }
121 if (timestampChanged)
122 updateTimePeriod();
123
124 foreach (Candlestick *item, m_candlesticks.values()) {
125 if (m_animation)
126 m_animation->setAnimationStart(item);
127
128 item->setTimePeriod(m_timePeriod);
129 item->setMaximumColumnWidth(m_series->maximumColumnWidth());
130 item->setMinimumColumnWidth(m_series->minimumColumnWidth());
131 item->setBodyWidth(m_series->bodyWidth());
132 item->setCapsWidth(m_series->capsWidth());
133
134 bool dirty = updateCandlestickGeometry(item, item->m_data.m_index);
135 if (dirty && m_animation)
136 presenter()->startAnimation(m_animation->candlestickChangeAnimation(item));
137 else
138 item->updateGeometry(domain());
139 }
140 }
141
142 void CandlestickChartItem::handleCandlesticksUpdated()
143 {
144 foreach (QCandlestickSet *set, m_candlesticks.keys())
145 updateCandlestickAppearance(m_candlesticks.value(set), set);
146 }
147
148 void CandlestickChartItem::handleCandlestickSeriesChange()
149 {
150 int seriesIndex = 0;
151 int seriesCount = 0;
152
153 int index = 0;
154 foreach (QAbstractSeries *series, m_series->chart()->series()) {
155 if (series->type() == QAbstractSeries::SeriesTypeCandlestick) {
156 if (m_series == static_cast<QCandlestickSeries *>(series))
157 seriesIndex = index;
158 index++;
159 }
160 }
161 seriesCount = index;
162
163 bool changed;
164 if ((m_seriesIndex != seriesIndex) || (m_seriesCount != seriesCount))
165 changed = true;
166 else
167 changed = false;
168
169 if (changed) {
170 m_seriesIndex = seriesIndex;
171 m_seriesCount = seriesCount;
172 handleDataStructureChanged();
173 }
174 }
175
176 void CandlestickChartItem::handleCandlestickSetsAdd(const QList<QCandlestickSet *> &sets)
177 {
178 foreach (QCandlestickSet *set, sets) {
179 Candlestick *item = m_candlesticks.value(set, 0);
180 if (item) {
181 qWarning() << "There is already a candlestick for this set in the hash";
182 continue;
183 }
184
185 item = new Candlestick(set, domain(), this);
186 m_candlesticks.insert(set, item);
187 addTimestamp(set->timestamp());
188
189 connect(item, SIGNAL(clicked(QCandlestickSet *)),
190 m_series, SIGNAL(clicked(QCandlestickSet *)));
191 connect(item, SIGNAL(hovered(bool, QCandlestickSet *)),
192 m_series, SIGNAL(hovered(bool, QCandlestickSet *)));
193 connect(item, SIGNAL(pressed(QCandlestickSet *)),
194 m_series, SIGNAL(pressed(QCandlestickSet *)));
195 connect(item, SIGNAL(released(QCandlestickSet *)),
196 m_series, SIGNAL(released(QCandlestickSet *)));
197 connect(item, SIGNAL(doubleClicked(QCandlestickSet *)),
198 m_series, SIGNAL(doubleClicked(QCandlestickSet *)));
199 connect(item, SIGNAL(clicked(QCandlestickSet *)), set, SIGNAL(clicked()));
200 connect(item, SIGNAL(hovered(bool, QCandlestickSet *)), set, SIGNAL(hovered(bool)));
201 connect(item, SIGNAL(pressed(QCandlestickSet *)), set, SIGNAL(pressed()));
202 connect(item, SIGNAL(released(QCandlestickSet *)), set, SIGNAL(released()));
203 connect(item, SIGNAL(doubleClicked(QCandlestickSet *)), set, SIGNAL(doubleClicked()));
204 }
205
206 handleDataStructureChanged();
207 }
208
209 void CandlestickChartItem::handleCandlestickSetsRemove(const QList<QCandlestickSet *> &sets)
210 {
211 foreach (QCandlestickSet *set, sets) {
212 Candlestick *item = m_candlesticks.value(set);
213
214 m_candlesticks.remove(set);
215 removeTimestamp(set->timestamp());
216
217 if (m_animation) {
218 ChartAnimation *animation = m_animation->candlestickAnimation(item);
219 if (animation) {
220 animation->stop();
221 delete animation;
222 }
223 }
224
225 delete item;
226 }
227
228 handleDataStructureChanged();
229 }
230
231 void CandlestickChartItem::handleDataStructureChanged()
232 {
233 updateTimePeriod();
234
235 for (int i = 0; i < m_series->count(); ++i) {
236 QCandlestickSet *set = m_series->candlestickSets().at(i);
237 Candlestick *item = m_candlesticks.value(set);
238
239 updateCandlestickGeometry(item, i);
240 updateCandlestickAppearance(item, set);
241
242 item->updateGeometry(domain());
243
244 if (m_animation)
245 m_animation->addCandlestick(item);
246 }
247
248 handleDomainUpdated();
249 }
250
251 bool CandlestickChartItem::updateCandlestickGeometry(Candlestick *item, int index)
252 {
253 bool changed = false;
254
255 QCandlestickSet *set = m_series->candlestickSets().at(index);
256 CandlestickData &data = item->m_data;
257
258 if ((data.m_open != set->open())
259 || (data.m_high != set->high())
260 || (data.m_low != set->low())
261 || (data.m_close != set->close())) {
262 changed = true;
263 }
264
265 data.m_timestamp = set->timestamp();
266 data.m_open = set->open();
267 data.m_high = set->high();
268 data.m_low = set->low();
269 data.m_close = set->close();
270 data.m_index = index;
271
272 data.m_maxX = domain()->maxX();
273 data.m_minX = domain()->minX();
274 data.m_maxY = domain()->maxY();
275 data.m_minY = domain()->minY();
276
277 data.m_series = m_series;
278 data.m_seriesIndex = m_seriesIndex;
279 data.m_seriesCount = m_seriesCount;
280
281 return changed;
282 }
283
284 void CandlestickChartItem::updateCandlestickAppearance(Candlestick *item, QCandlestickSet *set)
285 {
286 item->setTimePeriod(m_timePeriod);
287 item->setMaximumColumnWidth(m_series->maximumColumnWidth());
288 item->setMinimumColumnWidth(m_series->minimumColumnWidth());
289 item->setBodyWidth(m_series->bodyWidth());
290 item->setBodyOutlineVisible(m_series->bodyOutlineVisible());
291 item->setCapsWidth(m_series->capsWidth());
292 item->setCapsVisible(m_series->capsVisible());
293 item->setIncreasingColor(m_series->increasingColor());
294 item->setDecreasingColor(m_series->decreasingColor());
295
296 // Set the decorative issues for the candlestick so that
297 // the brush and pen already defined for the set are kept.
298 if (set->brush() == Qt::NoBrush)
299 item->setBrush(m_series->brush());
300 else
301 item->setBrush(set->brush());
302
303 if (set->pen() == Qt::NoPen)
304 item->setPen(m_series->pen());
305 else
306 item->setPen(set->pen());
307 }
308
309 void CandlestickChartItem::addTimestamp(qreal timestamp)
310 {
311 int index = 0;
312 for (int i = m_timestamps.count() - 1; i >= 0; --i) {
313 if (timestamp > m_timestamps.at(i)) {
314 index = i + 1;
315 break;
316 }
317 }
318 m_timestamps.insert(index, timestamp);
319 }
320
321 void CandlestickChartItem::removeTimestamp(qreal timestamp)
322 {
323 m_timestamps.removeOne(timestamp);
324 }
325
326 void CandlestickChartItem::updateTimePeriod()
327 {
328 if (m_timestamps.count() == 0) {
329 m_timePeriod = 0;
330 return;
331 }
332
333 if (m_timestamps.count() == 1) {
334 m_timePeriod = qAbs(domain()->maxX() - domain()->minX());
335 return;
336 }
337
338 qreal timePeriod = qAbs(m_timestamps.at(1) - m_timestamps.at(0));
339 for (int i = 1; i < m_timestamps.count(); ++i) {
340 timePeriod = qMin(timePeriod, qAbs(m_timestamps.at(i) - m_timestamps.at(i - 1)));
341 }
342 m_timePeriod = timePeriod;
343 }
344
345 #include "moc_candlestickchartitem_p.cpp"
346
347 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,96
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef CANDLESTICKCHARTITEM_P_H
40 #define CANDLESTICKCHARTITEM_P_H
41
42 #include <private/chartitem_p.h>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 class Candlestick;
47 class CandlestickAnimation;
48 class QCandlestickSeries;
49 class QCandlestickSet;
50
51 class CandlestickChartItem : public ChartItem
52 {
53 Q_OBJECT
54
55 public:
56 CandlestickChartItem(QCandlestickSeries *series, QGraphicsItem *item = nullptr);
57 ~CandlestickChartItem();
58
59 void setAnimation(CandlestickAnimation *animation);
60
61 QRectF boundingRect() const;
62 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
63
64 public Q_SLOTS:
65 void handleDomainUpdated();
66 void handleLayoutUpdated();
67 void handleCandlesticksUpdated();
68 void handleCandlestickSeriesChange();
69
70 private Q_SLOTS:
71 void handleCandlestickSetsAdd(const QList<QCandlestickSet *> &sets);
72 void handleCandlestickSetsRemove(const QList<QCandlestickSet *> &sets);
73 void handleDataStructureChanged();
74
75 private:
76 bool updateCandlestickGeometry(Candlestick *item, int index);
77 void updateCandlestickAppearance(Candlestick *item, QCandlestickSet *set);
78
79 void addTimestamp(qreal timestamp);
80 void removeTimestamp(qreal timestamp);
81 void updateTimePeriod();
82
83 protected:
84 QRectF m_boundingRect;
85 QCandlestickSeries *m_series; // Not owned.
86 int m_seriesIndex;
87 int m_seriesCount;
88 QHash<QCandlestickSet *, Candlestick *> m_candlesticks;
89 QList<qreal> m_timestamps;
90 qreal m_timePeriod;
91 CandlestickAnimation *m_animation;
92 };
93
94 QT_CHARTS_END_NAMESPACE
95
96 #endif // CANDLESTICKCHARTITEM_P_H
@@ -0,0 +1,88
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef CANDLESTICKDATA_P_H
40 #define CANDLESTICKDATA_P_H
41
42 #include <QtCharts/QCandlestickSeries>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 class CandlestickData
47 {
48 public:
49 CandlestickData() :
50 m_timestamp(0.0),
51 m_open(0.0),
52 m_high(0.0),
53 m_low(0.0),
54 m_close(0.0),
55 m_index(0),
56 m_maxX(0.0),
57 m_minX(0.0),
58 m_maxY(0.0),
59 m_minY(0.0),
60 m_series(nullptr),
61 m_seriesIndex(0),
62 m_seriesCount(0)
63 {
64 }
65
66 // Candlestick related statistics
67 qreal m_timestamp;
68 qreal m_open;
69 qreal m_high;
70 qreal m_low;
71 qreal m_close;
72 int m_index;
73
74 // Domain boundaries
75 qreal m_maxX;
76 qreal m_minX;
77 qreal m_maxY;
78 qreal m_minY;
79
80 // Series related data
81 QCandlestickSeries *m_series;
82 int m_seriesIndex;
83 int m_seriesCount;
84 };
85
86 QT_CHARTS_END_NAMESPACE
87
88 #endif // CANDLESTICKDATA_P_H
This diff has been collapsed as it changes many lines, (706 lines changed) Show them Hide them
@@ -0,0 +1,706
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 <QtCharts/QCandlestickModelMapper>
31 #include <QtCharts/QCandlestickSeries>
32 #include <QtCharts/QCandlestickSet>
33 #include <QtCore/QAbstractItemModel>
34 #include <private/qcandlestickmodelmapper_p.h>
35
36 QT_CHARTS_BEGIN_NAMESPACE
37
38 /*!
39 \class QCandlestickModelMapper
40 \since 5.8
41 \inmodule Qt Charts
42 \brief Abstract model mapper class for candlestick series.
43
44 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
45 series, creating a connection between a QCandlestickSeries and the model object. A model mapper
46 maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}.
47
48 \note The model used must support adding and removing rows/columns and modifying the data of the
49 cells.
50 */
51
52 /*!
53 \property QCandlestickModelMapper::model
54 \brief Defines the model that is used by the mapper.
55 */
56
57 /*!
58 \property QCandlestickModelMapper::series
59 \brief Defines the QCandlestickSeries object that is used by the mapper.
60
61 \note All data in the series is discarded when it is set to the mapper. When a new series is
62 specified, the old series is disconnected (preserving its data).
63 */
64
65 /*!
66 \fn Qt::Orientation QCandlestickModelMapper::orientation() const
67 Returns the orientation that is used when QCandlestickModelMapper accesses the model. This
68 determines whether the consecutive values of the set are read from rows (Qt::Horizontal) or from
69 columns (Qt::Vertical).
70 */
71
72 /*!
73 \fn void QCandlestickModelMapper::modelReplaced()
74 \brief Emitted when the model, to which the mapper is connected, has changed.
75 \sa model
76 */
77
78 /*!
79 \fn void QCandlestickModelMapper::seriesReplaced()
80 \brief Emitted when the series to which mapper is connected to has changed.
81 \sa series
82 */
83
84 /*!
85 Constructs a model mapper object as a child of \a parent.
86 */
87 QCandlestickModelMapper::QCandlestickModelMapper(QObject *parent)
88 : QObject(parent),
89 d_ptr(new QCandlestickModelMapperPrivate(this))
90 {
91 }
92
93 void QCandlestickModelMapper::setModel(QAbstractItemModel *model)
94 {
95 Q_D(QCandlestickModelMapper);
96
97 if (d->m_model == model)
98 return;
99
100 if (d->m_model)
101 disconnect(d->m_model, 0, d, 0);
102
103 d->m_model = model;
104 emit modelReplaced();
105
106 if (!d->m_model)
107 return;
108
109 d->initializeCandlestickFromModel();
110 // connect signals from the model
111 connect(d->m_model, SIGNAL(modelReset()), d, SLOT(initializeCandlestickFromModel()));
112 connect(d->m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
113 d, SLOT(modelDataUpdated(QModelIndex, QModelIndex)));
114 connect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)),
115 d, SLOT(modelHeaderDataUpdated(Qt::Orientation, int, int)));
116 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)),
117 d, SLOT(modelRowsInserted(QModelIndex, int, int)));
118 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
119 d, SLOT(modelRowsRemoved(QModelIndex, int, int)));
120 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)),
121 d, SLOT(modelColumnsInserted(QModelIndex, int, int)));
122 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
123 d, SLOT(modelColumnsRemoved(QModelIndex, int, int)));
124 connect(d->m_model, SIGNAL(destroyed()), d, SLOT(modelDestroyed()));
125 }
126
127 QAbstractItemModel *QCandlestickModelMapper::model() const
128 {
129 Q_D(const QCandlestickModelMapper);
130
131 return d->m_model;
132 }
133
134 void QCandlestickModelMapper::setSeries(QCandlestickSeries *series)
135 {
136 Q_D(QCandlestickModelMapper);
137
138 if (d->m_series == series)
139 return;
140
141 if (d->m_series)
142 disconnect(d->m_series, 0, d, 0);
143
144 d->m_series = series;
145 emit seriesReplaced();
146
147 if (!d->m_series)
148 return;
149
150 d->initializeCandlestickFromModel();
151 // connect the signals from the series
152 connect(d->m_series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)),
153 d, SLOT(candlestickSetsAdded(QList<QCandlestickSet *>)));
154 connect(d->m_series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet*>)),
155 d, SLOT(candlestickSetsRemoved(QList<QCandlestickSet *>)));
156 connect(d->m_series, SIGNAL(destroyed()), d, SLOT(seriesDestroyed()));
157 }
158
159 QCandlestickSeries *QCandlestickModelMapper::series() const
160 {
161 Q_D(const QCandlestickModelMapper);
162
163 return d->m_series;
164 }
165
166 /*!
167 Sets the row/column of the model that contains the \a timestamp values of the sets in the
168 series. Default value is -1 (invalid mapping).
169 */
170 void QCandlestickModelMapper::setTimestamp(int timestamp)
171 {
172 Q_D(QCandlestickModelMapper);
173
174 timestamp = qMax(timestamp, -1);
175
176 if (d->m_timestamp == timestamp)
177 return;
178
179 d->m_timestamp = timestamp;
180 emit d->timestampChanged();
181 d->initializeCandlestickFromModel();
182 }
183
184 /*!
185 Returns the row/column of the model that contains the timestamp values of the sets in the
186 series. Default value is -1 (invalid mapping).
187 */
188 int QCandlestickModelMapper::timestamp() const
189 {
190 Q_D(const QCandlestickModelMapper);
191
192 return d->m_timestamp;
193 }
194
195 /*!
196 Sets the row/column of the model that contains the \a open values of the sets in the series.
197 Default value is -1 (invalid mapping).
198 */
199 void QCandlestickModelMapper::setOpen(int open)
200 {
201 Q_D(QCandlestickModelMapper);
202
203 open = qMax(open, -1);
204
205 if (d->m_open == open)
206 return;
207
208 d->m_open = open;
209 emit d->openChanged();
210 d->initializeCandlestickFromModel();
211 }
212
213 /*!
214 Returns the row/column of the model that contains the open values of the sets in the series.
215 Default value is -1 (invalid mapping).
216 */
217 int QCandlestickModelMapper::open() const
218 {
219 Q_D(const QCandlestickModelMapper);
220
221 return d->m_open;
222 }
223
224 /*!
225 Sets the row/column of the model that contains the \a high values of the sets in the series.
226 Default value is -1 (invalid mapping).
227 */
228 void QCandlestickModelMapper::setHigh(int high)
229 {
230 Q_D(QCandlestickModelMapper);
231
232 high = qMax(high, -1);
233
234 if (d->m_high == high)
235 return;
236
237 d->m_high = high;
238 emit d->highChanged();
239 d->initializeCandlestickFromModel();
240 }
241
242 /*!
243 Returns the row/column of the model that contains the high values of the sets in the series.
244 Default value is -1 (invalid mapping).
245 */
246 int QCandlestickModelMapper::high() const
247 {
248 Q_D(const QCandlestickModelMapper);
249
250 return d->m_high;
251 }
252
253 /*!
254 Sets the row/column of the model that contains the \a low values of the sets in the series.
255 Default value is -1 (invalid mapping).
256 */
257 void QCandlestickModelMapper::setLow(int low)
258 {
259 Q_D(QCandlestickModelMapper);
260
261 low = qMax(low, -1);
262
263 if (d->m_low == low)
264 return;
265
266 d->m_low = low;
267 emit d->lowChanged();
268 d->initializeCandlestickFromModel();
269 }
270
271 /*!
272 Returns the row/column of the model that contains the low values of the sets in the series.
273 Default value is -1 (invalid mapping).
274 */
275 int QCandlestickModelMapper::low() const
276 {
277 Q_D(const QCandlestickModelMapper);
278
279 return d->m_low;
280 }
281
282 /*!
283 Sets the row/column of the model that contains the \a close values of the sets in the series.
284 Default value is -1 (invalid mapping).
285 */
286 void QCandlestickModelMapper::setClose(int close)
287 {
288 Q_D(QCandlestickModelMapper);
289
290 close = qMax(close, -1);
291
292 if (d->m_close == close)
293 return;
294
295 d->m_close = close;
296 emit d->closeChanged();
297 d->initializeCandlestickFromModel();
298 }
299
300 /*!
301 Returns the row/column of the model that contains the close values of the sets in the series.
302 Default value is -1 (invalid mapping).
303 */
304 int QCandlestickModelMapper::close() const
305 {
306 Q_D(const QCandlestickModelMapper);
307
308 return d->m_close;
309 }
310
311 /*!
312 Sets the section of the model that is used as the data source for the first candlestick set.
313 Parameter \a firstCandlestickSetSection specifies the section of the model. Default value is -1.
314 */
315 void QCandlestickModelMapper::setFirstCandlestickSetSection(int firstCandlestickSetSection)
316 {
317 Q_D(QCandlestickModelMapper);
318
319 firstCandlestickSetSection = qMax(firstCandlestickSetSection, -1);
320
321 if (d->m_firstCandlestickSetSection == firstCandlestickSetSection)
322 return;
323
324 d->m_firstCandlestickSetSection = firstCandlestickSetSection;
325 emit d->firstCandlestickSetSectionChanged();
326 d->initializeCandlestickFromModel();
327 }
328
329 /*!
330 Returns the section of the model that is used as the data source for the first candlestick set.
331 Default value is -1 (invalid mapping).
332 */
333 int QCandlestickModelMapper::firstCandlestickSetSection() const
334 {
335 Q_D(const QCandlestickModelMapper);
336
337 return d->m_firstCandlestickSetSection;
338 }
339
340 /*!
341 Sets the section of the model that is used as the data source for the last candlestick set.
342 Parameter \a lastCandlestickSetSection specifies the section of the model. Default value is -1.
343 */
344 void QCandlestickModelMapper::setLastCandlestickSetSection(int lastCandlestickSetSection)
345 {
346 Q_D(QCandlestickModelMapper);
347
348 lastCandlestickSetSection = qMax(lastCandlestickSetSection, -1);
349
350 if (d->m_lastCandlestickSetSection == lastCandlestickSetSection)
351 return;
352
353 d->m_lastCandlestickSetSection = lastCandlestickSetSection;
354 emit d->lastCandlestickSetSectionChanged();
355 d->initializeCandlestickFromModel();
356 }
357
358 /*!
359 Returns the section of the model that is used as the data source for the last candlestick set.
360 Default value is -1 (invalid mapping).
361 */
362 int QCandlestickModelMapper::lastCandlestickSetSection() const
363 {
364 Q_D(const QCandlestickModelMapper);
365
366 return d->m_lastCandlestickSetSection;
367 }
368
369 ////////////////////////////////////////////////////////////////////////////////////////////////////
370
371 QCandlestickModelMapperPrivate::QCandlestickModelMapperPrivate(QCandlestickModelMapper *q)
372 : QObject(q),
373 m_model(nullptr),
374 m_series(nullptr),
375 m_timestamp(-1),
376 m_open(-1),
377 m_high(-1),
378 m_low(-1),
379 m_close(-1),
380 m_firstCandlestickSetSection(-1),
381 m_lastCandlestickSetSection(-1),
382 m_modelSignalsBlock(false),
383 m_seriesSignalsBlock(false),
384 q_ptr(q)
385 {
386 }
387
388 void QCandlestickModelMapperPrivate::initializeCandlestickFromModel()
389 {
390 if (!m_model || !m_series)
391 return;
392
393 blockSeriesSignals();
394 // clear current content
395 m_series->clear();
396 m_candlestickSets.clear();
397
398 // create the initial candlestick sets
399 QList<QCandlestickSet *> candlestickSets;
400 for (int i = m_firstCandlestickSetSection; i <= m_lastCandlestickSetSection; ++i) {
401 QModelIndex timestampIndex = candlestickModelIndex(i, m_timestamp);
402 QModelIndex openIndex = candlestickModelIndex(i, m_open);
403 QModelIndex highIndex = candlestickModelIndex(i, m_high);
404 QModelIndex lowIndex = candlestickModelIndex(i, m_low);
405 QModelIndex closeIndex = candlestickModelIndex(i, m_close);
406 if (timestampIndex.isValid()
407 && openIndex.isValid()
408 && highIndex.isValid()
409 && lowIndex.isValid()
410 && closeIndex.isValid()) {
411 QCandlestickSet *set = new QCandlestickSet();
412 set->setTimestamp(m_model->data(timestampIndex, Qt::DisplayRole).toReal());
413 set->setOpen(m_model->data(openIndex, Qt::DisplayRole).toReal());
414 set->setHigh(m_model->data(highIndex, Qt::DisplayRole).toReal());
415 set->setLow(m_model->data(lowIndex, Qt::DisplayRole).toReal());
416 set->setClose(m_model->data(closeIndex, Qt::DisplayRole).toReal());
417
418 connect(set, SIGNAL(timestampChanged()), this, SLOT(candlestickSetChanged()));
419 connect(set, SIGNAL(openChanged()), this, SLOT(candlestickSetChanged()));
420 connect(set, SIGNAL(highChanged()), this, SLOT(candlestickSetChanged()));
421 connect(set, SIGNAL(lowChanged()), this, SLOT(candlestickSetChanged()));
422 connect(set, SIGNAL(closeChanged()), this, SLOT(candlestickSetChanged()));
423
424 candlestickSets.append(set);
425 } else {
426 break;
427 }
428 }
429 m_series->append(candlestickSets);
430 m_candlestickSets.append(candlestickSets);
431 blockSeriesSignals(false);
432 }
433
434 void QCandlestickModelMapperPrivate::modelDataUpdated(QModelIndex topLeft, QModelIndex bottomRight)
435 {
436 Q_Q(QCandlestickModelMapper);
437
438 if (!m_model || !m_series)
439 return;
440
441 if (m_modelSignalsBlock)
442 return;
443
444 blockSeriesSignals();
445 QModelIndex index;
446 for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
447 for (int column = topLeft.column(); column <= bottomRight.column(); ++column) {
448 index = topLeft.sibling(row, column);
449 QCandlestickSet *set = candlestickSet(index);
450 if (set) {
451 int pos = (q->orientation() == Qt::Vertical) ? row : column;
452 if (pos == m_timestamp)
453 set->setTimestamp(m_model->data(index).toReal());
454 else if (pos == m_open)
455 set->setOpen(m_model->data(index).toReal());
456 else if (pos == m_high)
457 set->setHigh(m_model->data(index).toReal());
458 else if (pos == m_low)
459 set->setLow(m_model->data(index).toReal());
460 else if (pos == m_close)
461 set->setClose(m_model->data(index).toReal());
462 }
463 }
464 }
465 blockSeriesSignals(false);
466 }
467
468 void QCandlestickModelMapperPrivate::modelHeaderDataUpdated(Qt::Orientation orientation, int first,
469 int last)
470 {
471 Q_UNUSED(orientation);
472 Q_UNUSED(first);
473 Q_UNUSED(last);
474 }
475
476 void QCandlestickModelMapperPrivate::modelRowsInserted(QModelIndex parent, int start, int end)
477 {
478 Q_UNUSED(parent)
479
480 Q_Q(QCandlestickModelMapper);
481
482 if (m_modelSignalsBlock)
483 return;
484
485 blockSeriesSignals();
486 if (q->orientation() == Qt::Vertical)
487 insertData(start, end);
488 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
489 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
490 blockSeriesSignals(false);
491 }
492
493 void QCandlestickModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
494 {
495 Q_UNUSED(parent)
496
497 Q_Q(QCandlestickModelMapper);
498
499 if (m_modelSignalsBlock)
500 return;
501
502 blockSeriesSignals();
503 if (q->orientation() == Qt::Vertical)
504 removeData(start, end);
505 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
506 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
507 blockSeriesSignals(false);
508 }
509
510 void QCandlestickModelMapperPrivate::modelColumnsInserted(QModelIndex parent, int start, int end)
511 {
512 Q_UNUSED(parent)
513
514 Q_Q(QCandlestickModelMapper);
515
516 if (m_modelSignalsBlock)
517 return;
518
519 blockSeriesSignals();
520 if (q->orientation() == Qt::Horizontal)
521 insertData(start, end);
522 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
523 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
524 blockSeriesSignals(false);
525 }
526
527 void QCandlestickModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
528 {
529 Q_UNUSED(parent)
530
531 Q_Q(QCandlestickModelMapper);
532
533 if (m_modelSignalsBlock)
534 return;
535
536 blockSeriesSignals();
537 if (q->orientation() == Qt::Horizontal)
538 removeData(start, end);
539 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
540 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
541 blockSeriesSignals(false);
542 }
543
544 void QCandlestickModelMapperPrivate::modelDestroyed()
545 {
546 m_model = 0;
547 }
548
549 void QCandlestickModelMapperPrivate::candlestickSetsAdded(const QList<QCandlestickSet *> &sets)
550 {
551 Q_Q(QCandlestickModelMapper);
552
553 if (m_seriesSignalsBlock)
554 return;
555
556 if (sets.isEmpty())
557 return;
558
559 int firstIndex = m_series->candlestickSets().indexOf(sets.at(0));
560 if (firstIndex == -1)
561 return;
562
563 m_lastCandlestickSetSection += sets.count();
564
565 blockModelSignals();
566 if (q->orientation() == Qt::Vertical)
567 m_model->insertColumns(firstIndex + m_firstCandlestickSetSection, sets.count());
568 else
569 m_model->insertRows(firstIndex + m_firstCandlestickSetSection, sets.count());
570
571 for (int i = 0; i < sets.count(); ++i) {
572 int section = i + firstIndex + m_firstCandlestickSetSection;
573 m_model->setData(candlestickModelIndex(section, m_timestamp), sets.at(i)->timestamp());
574 m_model->setData(candlestickModelIndex(section, m_open), sets.at(i)->open());
575 m_model->setData(candlestickModelIndex(section, m_high), sets.at(i)->high());
576 m_model->setData(candlestickModelIndex(section, m_low), sets.at(i)->low());
577 m_model->setData(candlestickModelIndex(section, m_close), sets.at(i)->close());
578 }
579 blockModelSignals(false);
580 initializeCandlestickFromModel();
581 }
582
583 void QCandlestickModelMapperPrivate::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets)
584 {
585 Q_Q(QCandlestickModelMapper);
586
587 if (m_seriesSignalsBlock)
588 return;
589
590 if (sets.isEmpty())
591 return;
592
593 int firstIndex = m_candlestickSets.indexOf(sets.at(0));
594 if (firstIndex == -1)
595 return;
596
597 m_lastCandlestickSetSection -= sets.count();
598
599 for (int i = firstIndex + sets.count() - 1; i >= firstIndex; --i)
600 m_candlestickSets.removeAt(i);
601
602 blockModelSignals();
603 if (q->orientation() == Qt::Vertical)
604 m_model->removeColumns(firstIndex + m_firstCandlestickSetSection, sets.count());
605 else
606 m_model->removeRows(firstIndex + m_firstCandlestickSetSection, sets.count());
607 blockModelSignals(false);
608 initializeCandlestickFromModel();
609 }
610
611 void QCandlestickModelMapperPrivate::candlestickSetChanged()
612 {
613 if (m_seriesSignalsBlock)
614 return;
615
616 QCandlestickSet *set = qobject_cast<QCandlestickSet *>(QObject::sender());
617 if (!set)
618 return;
619
620 int section = m_series->candlestickSets().indexOf(set);
621 if (section < 0)
622 return;
623
624 section += m_firstCandlestickSetSection;
625
626 blockModelSignals();
627 m_model->setData(candlestickModelIndex(section, m_timestamp), set->timestamp());
628 m_model->setData(candlestickModelIndex(section, m_open), set->open());
629 m_model->setData(candlestickModelIndex(section, m_high), set->high());
630 m_model->setData(candlestickModelIndex(section, m_low), set->low());
631 m_model->setData(candlestickModelIndex(section, m_close), set->close());
632 blockModelSignals(false);
633 }
634
635 void QCandlestickModelMapperPrivate::seriesDestroyed()
636 {
637 m_series = 0;
638 }
639
640 QCandlestickSet *QCandlestickModelMapperPrivate::candlestickSet(QModelIndex index)
641 {
642 Q_Q(QCandlestickModelMapper);
643
644 if (!index.isValid())
645 return 0;
646
647 int section = (q->orientation() == Qt::Vertical) ? index.column() : index.row();
648 int pos = (q->orientation() == Qt::Vertical) ? index.row() : index.column();
649
650 if (section < m_firstCandlestickSetSection || section > m_lastCandlestickSetSection)
651 return 0; // This part of model has not been mapped to any candlestick set.
652
653 if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close)
654 return 0; // This part of model has not been mapped to any candlestick set.
655
656 return m_series->candlestickSets().at(section - m_firstCandlestickSetSection);
657 }
658
659 QModelIndex QCandlestickModelMapperPrivate::candlestickModelIndex(int section, int pos)
660 {
661 Q_Q(QCandlestickModelMapper);
662
663 if (section < m_firstCandlestickSetSection || section > m_lastCandlestickSetSection)
664 return QModelIndex(); // invalid
665
666 if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close)
667 return QModelIndex(); // invalid
668
669 if (q->orientation() == Qt::Vertical)
670 return m_model->index(pos, section);
671 else
672 return m_model->index(section, pos);
673 }
674
675 void QCandlestickModelMapperPrivate::insertData(int start, int end)
676 {
677 Q_UNUSED(start)
678 Q_UNUSED(end)
679
680 // Currently candlestickchart needs to be fully recalculated when change is made.
681 initializeCandlestickFromModel();
682 }
683
684 void QCandlestickModelMapperPrivate::removeData(int start, int end)
685 {
686 Q_UNUSED(start)
687 Q_UNUSED(end)
688
689 // Currently candlestickchart needs to be fully recalculated when change is made.
690 initializeCandlestickFromModel();
691 }
692
693 void QCandlestickModelMapperPrivate::blockModelSignals(bool block)
694 {
695 m_modelSignalsBlock = block;
696 }
697
698 void QCandlestickModelMapperPrivate::blockSeriesSignals(bool block)
699 {
700 m_seriesSignalsBlock = block;
701 }
702
703 #include "moc_qcandlestickmodelmapper.cpp"
704 #include "moc_qcandlestickmodelmapper_p.cpp"
705
706 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,95
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 #ifndef QCANDLESTICKMODELMAPPER_H
31 #define QCANDLESTICKMODELMAPPER_H
32
33 #include <QtCharts/QChartGlobal>
34 #include <QtCore/QObject>
35
36 QT_BEGIN_NAMESPACE
37 class QAbstractItemModel;
38 QT_END_NAMESPACE
39
40 QT_CHARTS_BEGIN_NAMESPACE
41
42 class QCandlestickModelMapperPrivate;
43 class QCandlestickSeries;
44
45 class QT_CHARTS_EXPORT QCandlestickModelMapper : public QObject
46 {
47 Q_OBJECT
48 Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelReplaced)
49 Q_PROPERTY(QCandlestickSeries *series READ series WRITE setSeries NOTIFY seriesReplaced)
50
51 public:
52 explicit QCandlestickModelMapper(QObject *parent = nullptr);
53
54 void setModel(QAbstractItemModel *model);
55 QAbstractItemModel *model() const;
56
57 void setSeries(QCandlestickSeries *series);
58 QCandlestickSeries *series() const;
59
60 virtual Qt::Orientation orientation() const = 0;
61
62 Q_SIGNALS:
63 void modelReplaced();
64 void seriesReplaced();
65
66 protected:
67 void setTimestamp(int timestamp);
68 int timestamp() const;
69
70 void setOpen(int open);
71 int open() const;
72
73 void setHigh(int high);
74 int high() const;
75
76 void setLow(int low);
77 int low() const;
78
79 void setClose(int close);
80 int close() const;
81
82 void setFirstCandlestickSetSection(int firstCandlestickSetSection);
83 int firstCandlestickSetSection() const;
84
85 void setLastCandlestickSetSection(int lastCandlestickSetSection);
86 int lastCandlestickSetSection() const;
87
88 protected:
89 QCandlestickModelMapperPrivate * const d_ptr;
90 Q_DECLARE_PRIVATE(QCandlestickModelMapper)
91 };
92
93 QT_CHARTS_END_NAMESPACE
94
95 #endif // QCANDLESTICKMODELMAPPER_H
@@ -0,0 +1,116
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef QCANDLESTICKMODELMAPPER_P_H
40 #define QCANDLESTICKMODELMAPPER_P_H
41
42 #include <QtCharts/QCandlestickModelMapper>
43 #include <QtCore/QObject>
44
45 QT_BEGIN_NAMESPACE
46 class QModelIndex;
47 QT_END_NAMESPACE
48
49 QT_CHARTS_BEGIN_NAMESPACE
50
51 class QCandlestickSet;
52
53 class QCandlestickModelMapperPrivate : public QObject
54 {
55 Q_OBJECT
56
57 public:
58 explicit QCandlestickModelMapperPrivate(QCandlestickModelMapper *q);
59
60 Q_SIGNALS:
61 void timestampChanged();
62 void openChanged();
63 void highChanged();
64 void lowChanged();
65 void closeChanged();
66 void firstCandlestickSetSectionChanged();
67 void lastCandlestickSetSectionChanged();
68
69 private Q_SLOTS:
70 void initializeCandlestickFromModel();
71
72 // for the model
73 void modelDataUpdated(QModelIndex topLeft, QModelIndex bottomRight);
74 void modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last);
75 void modelRowsInserted(QModelIndex parent, int start, int end);
76 void modelRowsRemoved(QModelIndex parent, int start, int end);
77 void modelColumnsInserted(QModelIndex parent, int start, int end);
78 void modelColumnsRemoved(QModelIndex parent, int start, int end);
79 void modelDestroyed();
80
81 // for the series
82 void candlestickSetsAdded(const QList<QCandlestickSet *> &sets);
83 void candlestickSetsRemoved(const QList<QCandlestickSet *> &sets);
84 void candlestickSetChanged();
85 void seriesDestroyed();
86
87 private:
88 QCandlestickSet *candlestickSet(QModelIndex index);
89 QModelIndex candlestickModelIndex(int section, int pos);
90 void insertData(int start, int end);
91 void removeData(int start, int end);
92 void blockModelSignals(bool block = true);
93 void blockSeriesSignals(bool block = true);
94
95 private:
96 QAbstractItemModel *m_model;
97 QCandlestickSeries *m_series;
98 int m_timestamp;
99 int m_open;
100 int m_high;
101 int m_low;
102 int m_close;
103 int m_firstCandlestickSetSection;
104 int m_lastCandlestickSetSection;
105 QList<QCandlestickSet *> m_candlestickSets;
106 bool m_modelSignalsBlock;
107 bool m_seriesSignalsBlock;
108
109 private:
110 QCandlestickModelMapper *q_ptr;
111 Q_DECLARE_PUBLIC(QCandlestickModelMapper)
112 };
113
114 QT_CHARTS_END_NAMESPACE
115
116 #endif // QCANDLESTICKMODELMAPPER_P_H
This diff has been collapsed as it changes many lines, (1138 lines changed) Show them Hide them
@@ -0,0 +1,1138
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 <QtCharts/QBarCategoryAxis>
31 #include <QtCharts/QCandlestickLegendMarker>
32 #include <QtCharts/QCandlestickSeries>
33 #include <QtCharts/QCandlestickSet>
34 #include <QtCharts/QValueAxis>
35 #include <QtCore/QDateTime>
36 #include <private/candlestickanimation_p.h>
37 #include <private/candlestickchartitem_p.h>
38 #include <private/chartdataset_p.h>
39 #include <private/charttheme_p.h>
40 #include <private/qcandlestickseries_p.h>
41 #include <private/qcandlestickset_p.h>
42 #include <private/qchart_p.h>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 /*!
47 \class QCandlestickSeries
48 \since 5.8
49 \inmodule Qt Charts
50 \brief Series for creating a candlestick chart.
51
52 QCandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
53 is to act as a container for single candlestick items. Each item is drawn to its own category
54 when using QBarCategoryAxis. QDateTimeAxis and QValueAxis can be used as alternatives to
55 QBarCategoryAxis. In this case, each candlestick item is drawn according to its timestamp value.
56
57 \note The timestamps must be unique within a QCandlestickSeries. When using QBarCategoryAxis,
58 only the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
59 multiple instances of QCandlestickSeries, items from different series sharing a timestamp are
60 drawn to the same category. When using QValueAxis or QDateTimeAxis, candlestick items sharing a
61 timestamp will overlap each other.
62
63 See the \l {Candlestick Chart Example} {candlestick chart example} to learn how to create
64 a candlestick chart.
65 \image examples_candlestickchart.png
66
67 \sa QCandlestickSet, QBarCategoryAxis, QDateTimeAxis, QValueAxis
68 */
69
70 /*!
71 \qmltype CandlestickSeries
72 \since 2.2
73 \instantiates QCandlestickSeries
74 \inqmlmodule QtCharts
75 \inherits AbstractSeries
76 \brief Series for creating a candlestick chart.
77
78 CandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
79 is to act as a container for single candlestick items. Each item is drawn to its own category
80 when using BarCategoryAxis. DateTimeAxis and ValueAxis can be used as an alternative to
81 BarCategoryAxis. In this case each candlestick item is drawn according to its timestamp value.
82
83 \note The timestamps must be unique within a CandlestickSeries. When using BarCategoryAxis, only
84 the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
85 multiple instances of CandlestickSeries, items from different series sharing a timestamp are
86 drawn to the same category. When using ValueAxis or DateTimeAxis, candlestick items sharing a
87 timestamp will overlap each other.
88
89 The following QML shows how to create a simple candlestick chart:
90 \code
91 import QtQuick 2.5
92 import QtCharts 2.2
93
94 ChartView {
95 title: "Candlestick Series"
96 width: 400
97 height: 300
98
99 CandlestickSeries {
100 name: "Acme Ltd."
101 increasingColor: "green"
102 decreasingColor: "red"
103
104 CandlestickSet { timestamp: 1435708800000; open: 690; high: 694; low: 599; close: 660 }
105 CandlestickSet { timestamp: 1435795200000; open: 669; high: 669; low: 669; close: 669 }
106 CandlestickSet { timestamp: 1436140800000; open: 485; high: 623; low: 485; close: 600 }
107 CandlestickSet { timestamp: 1436227200000; open: 589; high: 615; low: 377; close: 569 }
108 CandlestickSet { timestamp: 1436313600000; open: 464; high: 464; low: 254; close: 254 }
109 }
110 }
111 \endcode
112
113 \beginfloatleft
114 \image examples_qmlcandlestick.png
115 \endfloat
116 \clearfloat
117
118 \sa CandlestickSet, BarCategoryAxis, DateTimeAxis, ValueAxis
119 */
120
121 /*!
122 \property QCandlestickSeries::count
123 \brief The count of sets in series.
124 */
125
126 /*!
127 \qmlproperty int CandlestickSeries::count
128 The count of sets in series.
129 */
130
131 /*!
132 \property QCandlestickSeries::maximumColumnWidth
133 \brief The maximum width of the candlestick items in pixels. Setting a negative value means
134 there is no maximum width. All negative values are converted to -1.0.
135 */
136
137 /*!
138 \qmlproperty qreal CandlestickSeries::maximumColumnWidth
139 \brief The maximum width of the candlestick items in pixels. Setting a negative value means
140 there is no maximum width. All negative values are converted to -1.0.
141 */
142
143 /*!
144 \property QCandlestickSeries::minimumColumnWidth
145 \brief The minimum width of the candlestick items in pixels. Setting a negative value means
146 there is no minimum width. All negative values are converted to -1.0.
147 */
148
149 /*!
150 \qmlproperty qreal CandlestickSeries::minimumColumnWidth
151 \brief The minimum width of the candlestick items in pixels. Setting a negative value means
152 there is no minimum width. All negative values are converted to -1.0.
153 */
154
155 /*!
156 \property QCandlestickSeries::bodyWidth
157 \brief The width of the candlestick items.
158
159 The value signifies the relative width of the candlestick item inside its own slot, in the range
160 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
161 */
162
163 /*!
164 \qmlproperty qreal CandlestickSeries::bodyWidth
165 \brief The width of the candlestick items.
166
167 The value signifies the relative width of the candlestick item inside its own slot, in the range
168 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
169 */
170
171 /*!
172 \property QCandlestickSeries::bodyOutlineVisible
173 \brief The visibility of the candlestick body outlines.
174 */
175
176 /*!
177 \qmlproperty bool CandlestickSeries::bodyOutlineVisible
178 \brief The visibility of the candlestick body outlines.
179 */
180
181 /*!
182 \property QCandlestickSeries::capsWidth
183 \brief The width of the caps.
184
185 The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
186 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
187 */
188
189 /*!
190 \qmlproperty qreal CandlestickSeries::capsWidth
191 \brief The width of the caps.
192
193 The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
194 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
195 */
196
197 /*!
198 \property QCandlestickSeries::capsVisible
199 \brief The visibility of the caps.
200 */
201
202 /*!
203 \qmlproperty bool CandlestickSeries::capsVisible
204 \brief The visibility of the caps.
205 */
206
207 /*!
208 \property QCandlestickSeries::increasingColor
209 \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
210 close value is higher than the open value. By default this property is set to brush color.
211 Default color is used also when the property is set to an invalid color value.
212 */
213
214 /*!
215 \qmlproperty QColor CandlestickSeries::increasingColor
216 \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
217 close value is higher than the open value. By default this property is set to brush color.
218 Default color is used also when the property is set to an invalid color value.
219 */
220
221 /*!
222 \property QCandlestickSeries::decreasingColor
223 \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
224 open value is higher than the close value. By default this property is set to brush color with
225 alpha channel set to 128. Default color is used also when the property is set to an invalid
226 color value.
227 */
228
229 /*!
230 \qmlproperty QColor CandlestickSeries::decreasingColor
231 \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
232 open value is higher than the close value. By default this property is set to brush color with
233 alpha channel set to 128. Default color is used also when the property is set to an invalid
234 color value.
235 */
236
237 /*!
238 \property QCandlestickSeries::brush
239 \brief The brush of the candlestick items.
240 */
241
242 /*!
243 \property QCandlestickSeries::pen
244 \brief The pen of the candlestick items.
245 */
246
247 /*!
248 \qmlproperty QString CandlestickSeries::brushFilename
249 \brief The name of the file used as a brush for the series.
250 */
251
252 /*!
253 \fn void QCandlestickSeries::clicked(QCandlestickSet *set)
254 \brief Emitted when a \a set is clicked (pressed and released) on the chart.
255 */
256
257 /*!
258 \qmlsignal CandlestickSeries::clicked(CandlestickSet set)
259 \brief Emitted when a \a set is clicked (pressed and released) on the chart.
260
261 The corresponding signal handler is \c {onClicked}.
262 */
263
264 /*!
265 \fn void QCandlestickSeries::hovered(bool status, QCandlestickSet *set)
266 \brief Emitted when there is change in hover \a status over the \a set.
267 */
268
269 /*!
270 \qmlsignal CandlestickSeries::hovered(bool status, CandlestickSet set)
271 \brief Emitted when there is change in hover \a status over the \a set.
272
273 The corresponding signal handler is \c {onHovered}.
274 */
275
276 /*!
277 \fn void QCandlestickSeries::pressed(QCandlestickSet *set)
278 \brief Emitted when a \a set is pressed on the chart.
279 */
280
281 /*!
282 \qmlsignal CandlestickSeries::pressed(CandlestickSet set)
283 \brief Emitted when a \a set is pressed on the chart.
284
285 The corresponding signal handler is \c {onPressed}.
286 */
287
288 /*!
289 \fn void QCandlestickSeries::released(QCandlestickSet *set)
290 \brief Emitted when a \a set is released on the chart.
291 */
292
293 /*!
294 \qmlsignal CandlestickSeries::released(CandlestickSet set)
295 \brief Emitted when a \a set is released on the chart.
296
297 The corresponding signal handler is \c {onReleased}.
298 */
299
300 /*!
301 \fn void QCandlestickSeries::doubleClicked(QCandlestickSet *set)
302 \brief Emitted when a \a set is double-clicked on the chart.
303 */
304
305 /*!
306 \qmlsignal CandlestickSeries::doubleClicked(CandlestickSet set)
307 \brief Emitted when a \a set is double-clicked on the chart.
308
309 The corresponding signal handler is \c {onDoubleClicked}.
310 */
311
312 /*!
313 \fn void QCandlestickSeries::candlestickSetsAdded(const QList<QCandlestickSet *> &sets)
314 \brief Emitted when new \a sets are added to the series.
315 */
316
317 /*!
318 \qmlsignal CandlestickSeries::candlestickSetsAdded(list<CandlestickSet> sets)
319 \brief Emitted when new \a sets are added to the series.
320
321 The corresponding signal handler is \c {onCandlestickSetsAdded}.
322 */
323
324 /*!
325 \fn void QCandlestickSeries::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets)
326 \brief Emitted when \a sets are removed from the series.
327 */
328
329 /*!
330 \qmlsignal CandlestickSeries::candlestickSetsRemoved(list<CandlestickSet> sets)
331 \brief Emitted when \a sets are removed from the series.
332
333 The corresponding signal handler is \c {onCandlestickSetsRemoved}.
334 */
335
336 /*!
337 \fn void QCandlestickSeries::countChanged()
338 \brief Emitted when there is a change in the count of candlestick items in the series.
339 \sa count
340 */
341
342 /*!
343 \qmlsignal CandlestickSeries::countChanged()
344 \brief Emitted when there is a change in the count of candlestick items in the series.
345 \sa count
346
347 The corresponding signal handler is \c {onCountChanged}.
348 */
349
350 /*!
351 \fn void QCandlestickSeries::maximumColumnWidthChanged()
352 \brief Emitted when there is a change in the maximum column width of candlestick items.
353 \sa maximumColumnWidth
354 */
355
356 /*!
357 \qmlsignal CandlestickSeries::maximumColumnWidthChanged()
358 \brief Emitted when there is a change in the maximum column width of candlestick items.
359 \sa maximumColumnWidth
360
361 The corresponding signal handler is \c {onMaximumColumnWidthChanged}.
362 */
363
364 /*!
365 \fn void QCandlestickSeries::minimumColumnWidthChanged()
366 \brief Emitted when there is a change in the minimum column width of candlestick items.
367 \sa minimumColumnWidth
368 */
369
370 /*!
371 \qmlsignal CandlestickSeries::minimumColumnWidthChanged()
372 \brief Emitted when there is a change in the minimum column width of candlestick items.
373 \sa minimumColumnWidth
374
375 The corresponding signal handler is \c {onMinimumColumnWidthChanged}.
376 */
377
378 /*!
379 \fn void QCandlestickSeries::bodyWidthChanged()
380 \brief Emitted when the candlestick item width is changed.
381 \sa bodyWidth
382 */
383
384 /*!
385 \qmlsignal CandlestickSeries::bodyWidthChanged()
386 \brief Emitted when the candlestick item width is changed.
387 \sa bodyWidth
388
389 The corresponding signal handler is \c {onBodyWidthChanged}.
390 */
391
392 /*!
393 \fn void QCandlestickSeries::bodyOutlineVisibilityChanged()
394 \brief Emitted when the visibility of the candlestick item body outline is changed.
395 \sa bodyOutlineVisible
396 */
397
398 /*!
399 \qmlsignal CandlestickSeries::bodyOutlineVisibilityChanged()
400 \brief Emitted when the visibility of the candlestick item body outline is changed.
401 \sa bodyOutlineVisible
402
403 The corresponding signal handler is \c {onBodyOutlineVisibilityChanged}.
404 */
405
406 /*!
407 \fn void QCandlestickSeries::capsWidthChanged()
408 \brief Emitted when the candlestick item caps width is changed.
409 \sa capsWidth
410 */
411
412 /*!
413 \qmlsignal CandlestickSeries::capsWidthChanged()
414 \brief Emitted when the candlestick item caps width is changed.
415 \sa capsWidth
416
417 The corresponding signal handler is \c {onCapsWidthChanged}.
418 */
419
420 /*!
421 \fn void QCandlestickSeries::capsVisibilityChanged()
422 \brief Emitted when the visibility of the candlestick item caps is changed.
423 \sa capsVisible
424 */
425
426 /*!
427 \qmlsignal CandlestickSeries::capsVisibilityChanged()
428 \brief Emitted when the visibility of the candlestick item caps is changed.
429 \sa capsVisible
430
431 The corresponding signal handler is \c {onCapsVisibilityChanged}.
432 */
433
434 /*!
435 \fn void QCandlestickSeries::increasingColorChanged()
436 \brief Emitted when the candlestick item increasing color is changed.
437 \sa increasingColor
438 */
439
440 /*!
441 \qmlsignal CandlestickSeries::increasingColorChanged()
442 \brief Emitted when the candlestick item increasing color is changed.
443 \sa increasingColor
444
445 The corresponding signal handler is \c {onIncreasingColorChanged}.
446 */
447
448 /*!
449 \fn void QCandlestickSeries::decreasingColorChanged()
450 \brief Emitted when the candlestick item decreasing color is changed.
451 \sa decreasingColor
452 */
453
454 /*!
455 \qmlsignal CandlestickSeries::decreasingColorChanged()
456 \brief Emitted when the candlestick item decreasing color is changed.
457 \sa decreasingColor
458
459 The corresponding signal handler is \c {onDecreasingColorChanged}.
460 */
461
462 /*!
463 \fn void QCandlestickSeries::brushChanged()
464 \brief Emitted when the candlestick item brush is changed.
465 \sa brush
466 */
467
468 /*!
469 \fn void QCandlestickSeries::penChanged()
470 \brief Emitted when the candlestick item pen is changed.
471 \sa pen
472 */
473
474 /*!
475 Constructs an empty QCandlestickSeries. The \a parent is optional.
476 */
477 QCandlestickSeries::QCandlestickSeries(QObject *parent)
478 : QAbstractSeries(*new QCandlestickSeriesPrivate(this), parent)
479 {
480 }
481
482 /*!
483 Destroys the series. Removes the series from the chart.
484 */
485 QCandlestickSeries::~QCandlestickSeries()
486 {
487 Q_D(QCandlestickSeries);
488 if (d->m_chart)
489 d->m_chart->removeSeries(this);
490 }
491
492 /*!
493 Adds a single set to the series. Takes ownership of the \a set. If the set is \e null or is
494 already in the series, it won't be appended.
495 Returns \c true if appending succeeded, \c false otherwise.
496 */
497 bool QCandlestickSeries::append(QCandlestickSet *set)
498 {
499 QList<QCandlestickSet *> sets;
500 sets.append(set);
501
502 return append(sets);
503 }
504
505 /*!
506 Removes a single set from the series.
507 Returns \c true if the \a set is successfully deleted, \c false otherwise.
508 */
509 bool QCandlestickSeries::remove(QCandlestickSet *set)
510 {
511 QList<QCandlestickSet *> sets;
512 sets.append(set);
513
514 return remove(sets);
515 }
516
517 /*!
518 Adds a list of sets to the series. Takes ownership of the \a sets. If any of the sets are
519 \e null, already appended to the series, or the list contains duplicated sets, nothing is
520 appended.
521 Returns \c true if all sets were appended successfully, \c false otherwise.
522 */
523 bool QCandlestickSeries::append(const QList<QCandlestickSet *> &sets)
524 {
525 Q_D(QCandlestickSeries);
526
527 bool success = d->append(sets);
528 if (success) {
529 emit candlestickSetsAdded(sets);
530 emit countChanged();
531 }
532
533 return success;
534 }
535
536 /*!
537 Removes a list of sets from the series. If any of the \a sets are \e null, already removed from
538 the series, or the list contains duplicated sets, nothing is removed.
539 Returns \c true if all sets were removed successfully, \c false otherwise.
540 */
541 bool QCandlestickSeries::remove(const QList<QCandlestickSet *> &sets)
542 {
543 Q_D(QCandlestickSeries);
544
545 bool success = d->remove(sets);
546 if (success) {
547 emit candlestickSetsRemoved(sets);
548 emit countChanged();
549 foreach (QCandlestickSet *set, sets)
550 set->deleteLater();
551 }
552
553 return success;
554 }
555
556 /*!
557 Inserts a set to the series at \a index position. Takes ownership of the \a set. If the set is
558 \e null or already in the series, it won't be appended.
559 Returns \c true if inserting succeeded, \c false otherwise.
560 */
561 bool QCandlestickSeries::insert(int index, QCandlestickSet *set)
562 {
563 Q_D(QCandlestickSeries);
564
565 bool success = d->insert(index, set);
566 if (success) {
567 QList<QCandlestickSet *> sets;
568 sets.append(set);
569 emit candlestickSetsAdded(sets);
570 emit countChanged();
571 }
572
573 return success;
574 }
575
576 /*!
577 Takes a single \a set from the series. Does not delete the set object.
578 Returns \c true if take was successful, \c false otherwise.
579 \note The series remains as the set's parent object. You must set the parent object to take full
580 ownership.
581 */
582 bool QCandlestickSeries::take(QCandlestickSet *set)
583 {
584 Q_D(QCandlestickSeries);
585
586 QList<QCandlestickSet *> sets;
587 sets.append(set);
588
589 bool success = d->remove(sets);
590 if (success) {
591 emit candlestickSetsRemoved(sets);
592 emit countChanged();
593 }
594
595 return success;
596 }
597
598 /*!
599 Removes all sets from the series, and deletes them.
600 */
601 void QCandlestickSeries::clear()
602 {
603 Q_D(QCandlestickSeries);
604
605 QList<QCandlestickSet *> sets = candlestickSets();
606
607 bool success = d->remove(sets);
608 if (success) {
609 emit candlestickSetsRemoved(sets);
610 emit countChanged();
611 foreach (QCandlestickSet *set, sets)
612 set->deleteLater();
613 }
614 }
615
616 /*!
617 Returns the list of sets in the series. Ownership of the sets is unchanged.
618 */
619 QList<QCandlestickSet *> QCandlestickSeries::candlestickSets() const
620 {
621 Q_D(const QCandlestickSeries);
622
623 return d->m_candlestickSets;
624 }
625
626 /*!
627 Returns the number of the sets in the series.
628 */
629 int QCandlestickSeries::count() const
630 {
631 return candlestickSets().count();
632 }
633
634 /*!
635 Returns the type of the series (QAbstractSeries::SeriesTypeCandlestick).
636 */
637 QAbstractSeries::SeriesType QCandlestickSeries::type() const
638 {
639 return QAbstractSeries::SeriesTypeCandlestick;
640 }
641
642 void QCandlestickSeries::setMaximumColumnWidth(qreal maximumColumnWidth)
643 {
644 Q_D(QCandlestickSeries);
645
646 if (maximumColumnWidth < 0.0 && maximumColumnWidth != -1.0)
647 maximumColumnWidth = -1.0;
648
649 if (d->m_maximumColumnWidth == maximumColumnWidth)
650 return;
651
652 d->m_maximumColumnWidth = maximumColumnWidth;
653
654 emit d->updatedLayout();
655 emit maximumColumnWidthChanged();
656 }
657
658 qreal QCandlestickSeries::maximumColumnWidth() const
659 {
660 Q_D(const QCandlestickSeries);
661
662 return d->m_maximumColumnWidth;
663 }
664
665 void QCandlestickSeries::setMinimumColumnWidth(qreal minimumColumnWidth)
666 {
667 Q_D(QCandlestickSeries);
668
669 if (minimumColumnWidth < 0.0 && minimumColumnWidth != -1.0)
670 minimumColumnWidth = -1.0;
671
672 if (d->m_minimumColumnWidth == minimumColumnWidth)
673 return;
674
675 d->m_minimumColumnWidth = minimumColumnWidth;
676
677 d->updatedLayout();
678 emit minimumColumnWidthChanged();
679 }
680
681 qreal QCandlestickSeries::minimumColumnWidth() const
682 {
683 Q_D(const QCandlestickSeries);
684
685 return d->m_minimumColumnWidth;
686 }
687
688 void QCandlestickSeries::setBodyWidth(qreal bodyWidth)
689 {
690 Q_D(QCandlestickSeries);
691
692 if (bodyWidth < 0.0)
693 bodyWidth = 0.0;
694 else if (bodyWidth > 1.0)
695 bodyWidth = 1.0;
696
697 if (d->m_bodyWidth == bodyWidth)
698 return;
699
700 d->m_bodyWidth = bodyWidth;
701
702 emit d->updatedLayout();
703 emit bodyWidthChanged();
704 }
705
706 qreal QCandlestickSeries::bodyWidth() const
707 {
708 Q_D(const QCandlestickSeries);
709
710 return d->m_bodyWidth;
711 }
712
713 void QCandlestickSeries::setBodyOutlineVisible(bool bodyOutlineVisible)
714 {
715 Q_D(QCandlestickSeries);
716
717 if (d->m_bodyOutlineVisible == bodyOutlineVisible)
718 return;
719
720 d->m_bodyOutlineVisible = bodyOutlineVisible;
721
722 emit d->updated();
723 emit bodyOutlineVisibilityChanged();
724 }
725
726 bool QCandlestickSeries::bodyOutlineVisible() const
727 {
728 Q_D(const QCandlestickSeries);
729
730 return d->m_bodyOutlineVisible;
731 }
732
733 void QCandlestickSeries::setCapsWidth(qreal capsWidth)
734 {
735 Q_D(QCandlestickSeries);
736
737 if (capsWidth < 0.0)
738 capsWidth = 0.0;
739 else if (capsWidth > 1.0)
740 capsWidth = 1.0;
741
742 if (d->m_capsWidth == capsWidth)
743 return;
744
745 d->m_capsWidth = capsWidth;
746
747 emit d->updatedLayout();
748 emit capsWidthChanged();
749 }
750
751 qreal QCandlestickSeries::capsWidth() const
752 {
753 Q_D(const QCandlestickSeries);
754
755 return d->m_capsWidth;
756 }
757
758 void QCandlestickSeries::setCapsVisible(bool capsVisible)
759 {
760 Q_D(QCandlestickSeries);
761
762 if (d->m_capsVisible == capsVisible)
763 return;
764
765 d->m_capsVisible = capsVisible;
766
767 emit d->updated();
768 emit capsVisibilityChanged();
769 }
770
771 bool QCandlestickSeries::capsVisible() const
772 {
773 Q_D(const QCandlestickSeries);
774
775 return d->m_capsVisible;
776 }
777
778 void QCandlestickSeries::setIncreasingColor(const QColor &increasingColor)
779 {
780 Q_D(QCandlestickSeries);
781
782 QColor color;
783 if (increasingColor.isValid()) {
784 color = increasingColor;
785 d->m_customIncreasingColor = true;
786 } else {
787 color = d->m_brush.color();
788 color.setAlpha(128);
789 d->m_customIncreasingColor = false;
790 }
791
792 if (d->m_increasingColor == color)
793 return;
794
795 d->m_increasingColor = color;
796
797 emit d->updated();
798 emit increasingColorChanged();
799 }
800
801 QColor QCandlestickSeries::increasingColor() const
802 {
803 Q_D(const QCandlestickSeries);
804
805 return d->m_increasingColor;
806 }
807
808 void QCandlestickSeries::setDecreasingColor(const QColor &decreasingColor)
809 {
810 Q_D(QCandlestickSeries);
811
812 QColor color;
813 if (decreasingColor.isValid()) {
814 color = decreasingColor;
815 d->m_customDecreasingColor = true;
816 } else {
817 color = d->m_brush.color();
818 d->m_customDecreasingColor = false;
819 }
820
821 if (d->m_decreasingColor == color)
822 return;
823
824 d->m_decreasingColor = color;
825
826 emit d->updated();
827 emit decreasingColorChanged();
828 }
829
830 QColor QCandlestickSeries::decreasingColor() const
831 {
832 Q_D(const QCandlestickSeries);
833
834 return d->m_decreasingColor;
835 }
836
837 void QCandlestickSeries::setBrush(const QBrush &brush)
838 {
839 Q_D(QCandlestickSeries);
840
841 if (d->m_brush == brush)
842 return;
843
844 d->m_brush = brush;
845 if (!d->m_customIncreasingColor) {
846 QColor color = d->m_brush.color();
847 color.setAlpha(128);
848 if (d->m_increasingColor != color) {
849 d->m_increasingColor = color;
850 emit increasingColorChanged();
851 }
852 }
853 if (!d->m_customDecreasingColor && d->m_decreasingColor != d->m_brush.color()) {
854 d->m_decreasingColor = d->m_brush.color();
855 emit decreasingColorChanged();
856 }
857
858 emit d->updated();
859 emit brushChanged();
860 }
861
862 QBrush QCandlestickSeries::brush() const
863 {
864 Q_D(const QCandlestickSeries);
865
866 return d->m_brush;
867 }
868
869 void QCandlestickSeries::setPen(const QPen &pen)
870 {
871 Q_D(QCandlestickSeries);
872
873 if (d->m_pen == pen)
874 return;
875
876 d->m_pen = pen;
877
878 emit d->updated();
879 emit penChanged();
880 }
881
882 QPen QCandlestickSeries::pen() const
883 {
884 Q_D(const QCandlestickSeries);
885
886 return d->m_pen;
887 }
888
889 ////////////////////////////////////////////////////////////////////////////////////////////////////
890
891 QCandlestickSeriesPrivate::QCandlestickSeriesPrivate(QCandlestickSeries *q)
892 : QAbstractSeriesPrivate(q),
893 m_maximumColumnWidth(-1.0),
894 m_minimumColumnWidth(5.0),
895 m_bodyWidth(0.5),
896 m_bodyOutlineVisible(true),
897 m_capsWidth(0.5),
898 m_capsVisible(false),
899 m_increasingColor(QColor(Qt::transparent)),
900 m_decreasingColor(QChartPrivate::defaultBrush().color()),
901 m_customIncreasingColor(false),
902 m_customDecreasingColor(false),
903 m_brush(QChartPrivate::defaultBrush()),
904 m_pen(QChartPrivate::defaultPen()),
905 m_animation(nullptr)
906 {
907 }
908
909 QCandlestickSeriesPrivate::~QCandlestickSeriesPrivate()
910 {
911 disconnect(this, 0, 0, 0);
912 }
913
914 void QCandlestickSeriesPrivate::initializeDomain()
915 {
916 qreal minX(domain()->minX());
917 qreal maxX(domain()->maxX());
918 qreal minY(domain()->minY());
919 qreal maxY(domain()->maxY());
920
921 if (m_candlestickSets.count()) {
922 QCandlestickSet *set = m_candlestickSets.first();
923 minX = set->timestamp();
924 maxX = set->timestamp();
925 minY = set->low();
926 maxY = set->high();
927 for (int i = 1; i < m_candlestickSets.count(); ++i) {
928 set = m_candlestickSets.at(i);
929 minX = qMin(minX, qreal(set->timestamp()));
930 maxX = qMax(maxX, qreal(set->timestamp()));
931 minY = qMin(minY, set->low());
932 maxY = qMax(maxY, set->high());
933 }
934 qreal extra = (maxX - minX) / m_candlestickSets.count() / 2;
935 minX = minX - extra;
936 maxX = maxX + extra;
937 }
938
939 domain()->setRange(minX, maxX, minY, maxY);
940 }
941
942 void QCandlestickSeriesPrivate::initializeAxes()
943 {
944 foreach (QAbstractAxis* axis, m_axes) {
945 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
946 if (axis->orientation() == Qt::Horizontal)
947 populateBarCategories(qobject_cast<QBarCategoryAxis *>(axis));
948 }
949 }
950 }
951
952 void QCandlestickSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
953 {
954 Q_Q(QCandlestickSeries);
955
956 if (forced || QChartPrivate::defaultBrush() == m_brush) {
957 const QList<QGradient> gradients = theme->seriesGradients();
958 const QGradient gradient = gradients.at(index % gradients.size());
959 const QBrush brush(ChartThemeManager::colorAt(gradient, 0.5));
960 q->setBrush(brush);
961 }
962
963 if (forced || QChartPrivate::defaultPen() == m_pen) {
964 QPen pen = theme->outlinePen();
965 pen.setCosmetic(true);
966 q->setPen(pen);
967 }
968 }
969
970 void QCandlestickSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
971 {
972 Q_Q(QCandlestickSeries);
973
974 CandlestickChartItem *item = new CandlestickChartItem(q, parent);
975 m_item.reset(item);
976 QAbstractSeriesPrivate::initializeGraphics(parent);
977
978 if (m_chart) {
979 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries *)),
980 this, SLOT(handleSeriesChange(QAbstractSeries *)));
981 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)),
982 this, SLOT(handleSeriesRemove(QAbstractSeries *)));
983
984 item->handleCandlestickSeriesChange();
985 }
986 }
987
988 void QCandlestickSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
989 QEasingCurve &curve)
990 {
991 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
992 Q_ASSERT(item);
993
994 if (item->animation())
995 item->animation()->stopAndDestroyLater();
996
997 if (options.testFlag(QChart::SeriesAnimations))
998 m_animation = new CandlestickAnimation(item, duration, curve);
999 else
1000 m_animation = nullptr;
1001 item->setAnimation(m_animation);
1002
1003 QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
1004 }
1005
1006 QList<QLegendMarker *> QCandlestickSeriesPrivate::createLegendMarkers(QLegend *legend)
1007 {
1008 Q_Q(QCandlestickSeries);
1009
1010 QList<QLegendMarker *> list;
1011
1012 return list << new QCandlestickLegendMarker(q, legend);
1013 }
1014
1015 QAbstractAxis::AxisType QCandlestickSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
1016 {
1017 if (orientation == Qt::Horizontal)
1018 return QAbstractAxis::AxisTypeBarCategory;
1019
1020 if (orientation == Qt::Vertical)
1021 return QAbstractAxis::AxisTypeValue;
1022
1023 return QAbstractAxis::AxisTypeNoAxis;
1024 }
1025
1026 QAbstractAxis* QCandlestickSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
1027 {
1028 const QAbstractAxis::AxisType axisType = defaultAxisType(orientation);
1029
1030 if (axisType == QAbstractAxis::AxisTypeBarCategory)
1031 return new QBarCategoryAxis;
1032
1033 if (axisType == QAbstractAxis::AxisTypeValue)
1034 return new QValueAxis;
1035
1036 return 0; // axisType == QAbstractAxis::AxisTypeNoAxis
1037 }
1038
1039 bool QCandlestickSeriesPrivate::append(const QList<QCandlestickSet *> &sets)
1040 {
1041 foreach (QCandlestickSet *set, sets) {
1042 if ((set == 0) || m_candlestickSets.contains(set) || set->d_ptr->m_series)
1043 return false; // Fail if any of the sets is null or is already appended.
1044 if (sets.count(set) != 1)
1045 return false; // Also fail if the same set occurs more than once in the given list.
1046 }
1047
1048 foreach (QCandlestickSet *set, sets) {
1049 m_candlestickSets.append(set);
1050 connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1051 connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
1052 set->d_ptr->m_series = this;
1053 }
1054
1055 return true;
1056 }
1057
1058 bool QCandlestickSeriesPrivate::remove(const QList<QCandlestickSet *> &sets)
1059 {
1060 if (sets.count() == 0)
1061 return false;
1062
1063 foreach (QCandlestickSet *set, sets) {
1064 if ((set == 0) || (!m_candlestickSets.contains(set)))
1065 return false; // Fail if any of the sets is null or is not in series.
1066 if (sets.count(set) != 1)
1067 return false; // Also fail if the same set occurs more than once in the given list.
1068 }
1069
1070 foreach (QCandlestickSet *set, sets) {
1071 set->d_ptr->m_series = nullptr;
1072 m_candlestickSets.removeOne(set);
1073 disconnect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1074 disconnect(set->d_func(), SIGNAL(updatedCandlestick()),this, SIGNAL(updatedCandlesticks()));
1075 }
1076
1077 return true;
1078 }
1079
1080 bool QCandlestickSeriesPrivate::insert(int index, QCandlestickSet *set)
1081 {
1082 if ((m_candlestickSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
1083 return false; // Fail if set is already in list or set is null.
1084
1085 m_candlestickSets.insert(index, set);
1086 connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1087 connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
1088 set->d_ptr->m_series = this;
1089
1090 return true;
1091 }
1092
1093 void QCandlestickSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
1094 {
1095 Q_UNUSED(series);
1096
1097 if (m_chart) {
1098 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
1099 if (item)
1100 item->handleCandlestickSeriesChange();
1101 }
1102 }
1103
1104 void QCandlestickSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
1105 {
1106 Q_Q(const QCandlestickSeries);
1107
1108 QCandlestickSeries *removedSeries = static_cast<QCandlestickSeries *>(series);
1109
1110 if (q == removedSeries && m_animation) {
1111 m_animation->stopAll();
1112 disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
1113 }
1114
1115 if (q != removedSeries) {
1116 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
1117 if (item)
1118 item->handleCandlestickSeriesChange();
1119 }
1120 }
1121
1122 void QCandlestickSeriesPrivate::populateBarCategories(QBarCategoryAxis *axis)
1123 {
1124 if (axis->categories().isEmpty()) {
1125 QStringList categories;
1126 for (int i = 0; i < m_candlestickSets.count(); ++i) {
1127 const qint64 timestamp = qRound64(m_candlestickSets.at(i)->timestamp());
1128 const QString timestampFormat = m_chart->locale().dateTimeFormat(QLocale::ShortFormat);
1129 categories << QDateTime::fromMSecsSinceEpoch(timestamp).toString(timestampFormat);
1130 }
1131 axis->append(categories);
1132 }
1133 }
1134
1135 #include "moc_qcandlestickseries.cpp"
1136 #include "moc_qcandlestickseries_p.cpp"
1137
1138 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,131
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 #ifndef QCANDLESTICKSERIES_H
31 #define QCANDLESTICKSERIES_H
32
33 #include <QtCharts/QAbstractSeries>
34
35 QT_CHARTS_BEGIN_NAMESPACE
36
37 class QCandlestickSeriesPrivate;
38 class QCandlestickSet;
39
40 class QT_CHARTS_EXPORT QCandlestickSeries : public QAbstractSeries
41 {
42 Q_OBJECT
43 Q_PROPERTY(int count READ count NOTIFY countChanged)
44 Q_PROPERTY(qreal maximumColumnWidth READ maximumColumnWidth WRITE setMaximumColumnWidth NOTIFY maximumColumnWidthChanged)
45 Q_PROPERTY(qreal minimumColumnWidth READ minimumColumnWidth WRITE setMinimumColumnWidth NOTIFY minimumColumnWidthChanged)
46 Q_PROPERTY(qreal bodyWidth READ bodyWidth WRITE setBodyWidth NOTIFY bodyWidthChanged)
47 Q_PROPERTY(bool bodyOutlineVisible READ bodyOutlineVisible WRITE setBodyOutlineVisible NOTIFY bodyOutlineVisibilityChanged)
48 Q_PROPERTY(qreal capsWidth READ capsWidth WRITE setCapsWidth NOTIFY capsWidthChanged)
49 Q_PROPERTY(bool capsVisible READ capsVisible WRITE setCapsVisible NOTIFY capsVisibilityChanged)
50 Q_PROPERTY(QColor increasingColor READ increasingColor WRITE setIncreasingColor NOTIFY increasingColorChanged)
51 Q_PROPERTY(QColor decreasingColor READ decreasingColor WRITE setDecreasingColor NOTIFY decreasingColorChanged)
52 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
53 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
54
55 public:
56 explicit QCandlestickSeries(QObject *parent = nullptr);
57 ~QCandlestickSeries();
58
59 bool append(QCandlestickSet *set);
60 bool remove(QCandlestickSet *set);
61 bool append(const QList<QCandlestickSet *> &sets);
62 bool remove(const QList<QCandlestickSet *> &sets);
63 bool insert(int index, QCandlestickSet *set);
64 bool take(QCandlestickSet *set);
65 void clear();
66
67 QList<QCandlestickSet *> candlestickSets() const;
68 int count() const;
69
70 QAbstractSeries::SeriesType type() const;
71
72 void setMaximumColumnWidth(qreal maximumColumnWidth);
73 qreal maximumColumnWidth() const;
74
75 void setMinimumColumnWidth(qreal minimumColumnWidth);
76 qreal minimumColumnWidth() const;
77
78 void setBodyWidth(qreal bodyWidth);
79 qreal bodyWidth() const;
80
81 void setBodyOutlineVisible(bool bodyOutlineVisible);
82 bool bodyOutlineVisible() const;
83
84 void setCapsWidth(qreal capsWidth);
85 qreal capsWidth() const;
86
87 void setCapsVisible(bool capsVisible);
88 bool capsVisible() const;
89
90 void setIncreasingColor(const QColor &increasingColor);
91 QColor increasingColor() const;
92
93 void setDecreasingColor(const QColor &decreasingColor);
94 QColor decreasingColor() const;
95
96 void setBrush(const QBrush &brush);
97 QBrush brush() const;
98
99 void setPen(const QPen &pen);
100 QPen pen() const;
101
102 Q_SIGNALS:
103 void clicked(QCandlestickSet *set);
104 void hovered(bool status, QCandlestickSet *set);
105 void pressed(QCandlestickSet *set);
106 void released(QCandlestickSet *set);
107 void doubleClicked(QCandlestickSet *set);
108 void candlestickSetsAdded(const QList<QCandlestickSet *> &sets);
109 void candlestickSetsRemoved(const QList<QCandlestickSet *> &sets);
110 void countChanged();
111 void maximumColumnWidthChanged();
112 void minimumColumnWidthChanged();
113 void bodyWidthChanged();
114 void bodyOutlineVisibilityChanged();
115 void capsWidthChanged();
116 void capsVisibilityChanged();
117 void increasingColorChanged();
118 void decreasingColorChanged();
119 void brushChanged();
120 void penChanged();
121
122 private:
123 Q_DISABLE_COPY(QCandlestickSeries)
124 Q_DECLARE_PRIVATE(QCandlestickSeries)
125 friend class CandlestickChartItem;
126 friend class QCandlestickLegendMarkerPrivate;
127 };
128
129 QT_CHARTS_END_NAMESPACE
130
131 #endif // QCANDLESTICKSERIES_H
@@ -0,0 +1,113
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef QCANDLESTICKSERIES_P_H
40 #define QCANDLESTICKSERIES_P_H
41
42 #include <private/qabstractseries_p.h>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 class CandlestickAnimation;
47 class QBarCategoryAxis;
48 class QCandlestickSeries;
49 class QCandlestickSet;
50 class QDateTimeAxis;
51
52 class QCandlestickSeriesPrivate : public QAbstractSeriesPrivate
53 {
54 Q_OBJECT
55
56 public:
57 QCandlestickSeriesPrivate(QCandlestickSeries *q);
58 ~QCandlestickSeriesPrivate();
59
60 void initializeDomain();
61 void initializeAxes();
62 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
63 void initializeGraphics(QGraphicsItem* parent);
64 void initializeAnimations(QChart::AnimationOptions options, int duration, QEasingCurve &curve);
65
66 QList<QLegendMarker *> createLegendMarkers(QLegend *legend);
67
68 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
69 QAbstractAxis *createDefaultAxis(Qt::Orientation orientation) const;
70
71 bool append(const QList<QCandlestickSet *> &sets);
72 bool remove(const QList<QCandlestickSet *> &sets);
73 bool insert(int index, QCandlestickSet *set);
74
75 Q_SIGNALS:
76 void clicked(int index, QCandlestickSet *set);
77 void pressed(int index, QCandlestickSet *set);
78 void released(int index, QCandlestickSet *set);
79 void doubleClicked(int index, QCandlestickSet *set);
80 void updated();
81 void updatedLayout();
82 void updatedCandlesticks();
83
84 private Q_SLOTS:
85 void handleSeriesChange(QAbstractSeries *series);
86 void handleSeriesRemove(QAbstractSeries *series);
87
88 private:
89 void populateBarCategories(QBarCategoryAxis *axis);
90
91 protected:
92 QList<QCandlestickSet *> m_candlestickSets;
93 qreal m_maximumColumnWidth;
94 qreal m_minimumColumnWidth;
95 qreal m_bodyWidth;
96 bool m_bodyOutlineVisible;
97 qreal m_capsWidth;
98 bool m_capsVisible;
99 QColor m_increasingColor;
100 QColor m_decreasingColor;
101 bool m_customIncreasingColor;
102 bool m_customDecreasingColor;
103 QBrush m_brush;
104 QPen m_pen;
105 CandlestickAnimation *m_animation;
106
107 private:
108 Q_DECLARE_PUBLIC(QCandlestickSeries)
109 };
110
111 QT_CHARTS_END_NAMESPACE
112
113 #endif // QCANDLESTICKSERIES_P_H
@@ -0,0 +1,487
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 <QtCharts/QCandlestickSet>
31 #include <private/qcandlestickset_p.h>
32
33 QT_CHARTS_BEGIN_NAMESPACE
34
35 /*!
36 \class QCandlestickSet
37 \since 5.8
38 \inmodule Qt Charts
39 \brief Building block for a candlestick chart.
40
41 QCandlestickSet represents a single candlestick item in a QCandlestickSeries. It takes five
42 values to create a graphical representation of a candlestick item: \e open, \e high, \e low,
43 \e close, and \e timestamp. These values can be either passed to a QCandlestickSet constructor,
44 or set by using setOpen(), setHigh(), setLow(), setClose(), and setTimestamp().
45
46 \sa QCandlestickSeries
47 */
48
49 /*!
50 \qmltype CandlestickSet
51 \since 2.2
52 \instantiates QCandlestickSet
53 \inqmlmodule QtCharts
54 \brief Building block for a candlestick chart.
55
56 CandlestickSet represents a single candlestick item in a CandlestickSeries. It takes five
57 values to create a graphical representation of a candlestick item: \l open, \l high, \l low,
58 \l close, and \l timestamp.
59
60 \sa CandlestickSeries
61 */
62
63 /*!
64 \property QCandlestickSet::timestamp
65 \brief The timestamp value of the set.
66 */
67
68 /*!
69 \qmlproperty qreal CandlestickSet::timestamp
70 \brief The timestamp value of the set.
71 */
72
73 /*!
74 \property QCandlestickSet::open
75 \brief The open value of the set.
76 */
77
78 /*!
79 \qmlproperty qreal CandlestickSet::open
80 \brief The open value of the set.
81 */
82
83 /*!
84 \property QCandlestickSet::high
85 \brief The high value of the set.
86 */
87
88 /*!
89 \qmlproperty qreal CandlestickSet::high
90 \brief The high value of the set.
91 */
92
93 /*!
94 \property QCandlestickSet::low
95 \brief The low value of the set.
96 */
97
98 /*!
99 \qmlproperty qreal CandlestickSet::low
100 \brief The low value of the set.
101 */
102
103 /*!
104 \property QCandlestickSet::close
105 \brief The close value of the set.
106 */
107
108 /*!
109 \qmlproperty qreal CandlestickSet::close
110 \brief The close value of the set.
111 */
112
113 /*!
114 \property QCandlestickSet::brush
115 \brief The brush used for drawing the candlestick.
116 */
117
118 /*!
119 \property QCandlestickSet::pen
120 \brief The pen used for drawing the candlestick.
121 */
122
123 /*!
124 \qmlproperty QString CandlestickSet::brushFilename
125 \brief The name of the file used as a brush for the set.
126 */
127
128 /*!
129 \fn void QCandlestickSet::clicked()
130 \brief Emitted when the candlestick item is clicked (pressed and released).
131 */
132
133 /*!
134 \qmlsignal CandlestickSet::clicked()
135 \brief Emitted when the candlestick item is clicked (pressed and released).
136
137 The corresponding signal handler is \c {onClicked}.
138 */
139
140 /*!
141 \fn void QCandlestickSet::hovered(bool status)
142 \brief Emitted when there is change in hover \a status over a candlestick item.
143
144 Parameter \a status indicates whether the mouse has entered (\c true) or left (\c false) the
145 area of the candlestick item.
146 */
147
148 /*!
149 \qmlsignal CandlestickSet::hovered(bool status)
150 \brief Emitted when there is change in hover \a status over a candlestick item.
151
152 Parameter \a status indicates whether the mouse has entered (\c true) or left (\c false) the
153 area of the candlestick item.
154
155 The corresponding signal handler is \c {onHovered}.
156 */
157
158 /*!
159 \fn void QCandlestickSet::pressed()
160 \brief Emitted when there is a press on a candlestick item.
161 */
162
163 /*!
164 \qmlsignal CandlestickSet::pressed()
165 \brief Emitted when there is a press on a candlestick item.
166
167 The corresponding signal handler is \c {onPressed}.
168 */
169
170 /*!
171 \fn void QCandlestickSet::released()
172 \brief Emitted when there is a release on a candlestick item.
173 */
174
175 /*!
176 \qmlsignal CandlestickSet::released()
177 \brief Emitted when there is a release on a candlestick item.
178
179 The corresponding signal handler is \c {onReleased}.
180 */
181
182 /*!
183 \fn void QCandlestickSet::doubleClicked()
184 \brief Emitted when there is a double-click on a candlestick item.
185 */
186
187 /*!
188 \qmlsignal CandlestickSet::doubleClicked()
189 \brief Emitted when there is a double-click on a candlestick item.
190
191 The corresponding signal handler is \c {onDoubleClicked}.
192 */
193
194 /*!
195 \fn void QCandlestickSet::timestampChanged()
196 \brief Emitted when the candlestick item timestamp is changed.
197 \sa timestamp
198 */
199
200 /*!
201 \qmlsignal CandlestickSet::timestampChanged()
202 \brief Emitted when the candlestick item timestamp is changed.
203 \sa timestamp
204
205 The corresponding signal handler is \c {onTimestampChanged}.
206 */
207
208 /*!
209 \fn void QCandlestickSet::openChanged()
210 \brief Emitted when the candlestick item open value is changed.
211 \sa open
212 */
213
214 /*!
215 \qmlsignal CandlestickSet::openChanged()
216 \brief Emitted when the candlestick item open value is changed.
217 \sa open
218
219 The corresponding signal handler is \c {onOpenChanged}.
220 */
221
222 /*!
223 \fn void QCandlestickSet::highChanged()
224 \brief Emitted when the candlestick item high value is changed.
225 \sa high
226 */
227
228 /*!
229 \qmlsignal CandlestickSet::highChanged()
230 \brief Emitted when the candlestick item high value is changed.
231 \sa high
232
233 The corresponding signal handler is \c {onHighChanged}.
234 */
235
236 /*!
237 \fn void QCandlestickSet::lowChanged()
238 \brief Emitted when the candlestick item low value is changed.
239 \sa low
240 */
241
242 /*!
243 \qmlsignal CandlestickSet::lowChanged()
244 \brief Emitted when the candlestick item low value is changed.
245 \sa low
246
247 The corresponding signal handler is \c {onLowChanged}.
248 */
249
250 /*!
251 \fn void QCandlestickSet::closeChanged()
252 \brief Emitted when the candlestick item close value is changed.
253 \sa close
254 */
255
256 /*!
257 \qmlsignal CandlestickSet::closeChanged()
258 \brief Emitted when the candlestick item close value is changed.
259 \sa close
260
261 The corresponding signal handler is \c {onCloseChanged}.
262 */
263
264 /*!
265 \fn void QCandlestickSet::brushChanged()
266 \brief Emitted when the candlestick item brush is changed.
267 \sa brush
268 */
269
270 /*!
271 \fn void QCandlestickSet::penChanged()
272 \brief Emitted when the candlestick item pen is changed.
273 \sa pen
274 */
275
276 /*!
277 Constructs a QCandlestickSet with an optional \a timestamp and a \a parent.
278 */
279 QCandlestickSet::QCandlestickSet(qreal timestamp, QObject *parent)
280 : QObject(parent),
281 d_ptr(new QCandlestickSetPrivate(timestamp, this))
282 {
283 }
284
285 /*!
286 Constructs a QCandlestickSet with given ordered values. The values \a open, \a high, \a low
287 and \a close are mandatory. The values \a timestamp and \a parent are optional.
288 */
289 QCandlestickSet::QCandlestickSet(qreal open, qreal high, qreal low, qreal close, qreal timestamp,
290 QObject *parent)
291 : QObject(parent),
292 d_ptr(new QCandlestickSetPrivate(timestamp, this))
293 {
294 Q_D(QCandlestickSet);
295
296 d->m_open = open;
297 d->m_high = high;
298 d->m_low = low;
299 d->m_close = close;
300
301 emit d->updatedLayout();
302 }
303
304 /*!
305 Destroys the set.
306 */
307 QCandlestickSet::~QCandlestickSet()
308 {
309 }
310
311 void QCandlestickSet::setTimestamp(qreal timestamp)
312 {
313 Q_D(QCandlestickSet);
314
315 bool changed = d->setTimestamp(timestamp);
316 if (!changed)
317 return;
318
319 emit d->updatedLayout();
320 emit timestampChanged();
321 }
322
323 qreal QCandlestickSet::timestamp() const
324 {
325 Q_D(const QCandlestickSet);
326
327 return d->m_timestamp;
328 }
329
330 void QCandlestickSet::setOpen(qreal open)
331 {
332 Q_D(QCandlestickSet);
333
334 if (d->m_open == open)
335 return;
336
337 d->m_open = open;
338
339 emit d->updatedLayout();
340 emit openChanged();
341 }
342
343 qreal QCandlestickSet::open() const
344 {
345 Q_D(const QCandlestickSet);
346
347 return d->m_open;
348 }
349
350 void QCandlestickSet::setHigh(qreal high)
351 {
352 Q_D(QCandlestickSet);
353
354 if (d->m_high == high)
355 return;
356
357 d->m_high = high;
358
359 emit d->updatedLayout();
360 emit highChanged();
361 }
362
363 qreal QCandlestickSet::high() const
364 {
365 Q_D(const QCandlestickSet);
366
367 return d->m_high;
368 }
369
370 void QCandlestickSet::setLow(qreal low)
371 {
372 Q_D(QCandlestickSet);
373
374 if (d->m_low == low)
375 return;
376
377 d->m_low = low;
378
379 emit d->updatedLayout();
380 emit lowChanged();
381 }
382
383 qreal QCandlestickSet::low() const
384 {
385 Q_D(const QCandlestickSet);
386
387 return d->m_low;
388 }
389
390 void QCandlestickSet::setClose(qreal close)
391 {
392 Q_D(QCandlestickSet);
393
394 if (d->m_close == close)
395 return;
396
397 d->m_close = close;
398
399 emit d->updatedLayout();
400 emit closeChanged();
401 }
402
403 qreal QCandlestickSet::close() const
404 {
405 Q_D(const QCandlestickSet);
406
407 return d->m_close;
408 }
409
410 void QCandlestickSet::setBrush(const QBrush &brush)
411 {
412 Q_D(QCandlestickSet);
413
414 if (d->m_brush == brush)
415 return;
416
417 d->m_brush = brush;
418
419 emit d->updatedCandlestick();
420 emit brushChanged();
421 }
422
423 QBrush QCandlestickSet::brush() const
424 {
425 Q_D(const QCandlestickSet);
426
427 return d->m_brush;
428 }
429
430 void QCandlestickSet::setPen(const QPen &pen)
431 {
432 Q_D(QCandlestickSet);
433
434 if (d->m_pen == pen)
435 return;
436
437 d->m_pen = pen;
438
439 emit d->updatedCandlestick();
440 emit penChanged();
441 }
442
443 QPen QCandlestickSet::pen() const
444 {
445 Q_D(const QCandlestickSet);
446
447 return d->m_pen;
448 }
449
450 ////////////////////////////////////////////////////////////////////////////////////////////////////
451
452 QCandlestickSetPrivate::QCandlestickSetPrivate(qreal timestamp, QCandlestickSet *parent)
453 : QObject(parent),
454 q_ptr(parent),
455 m_timestamp(0.0),
456 m_open(0.0),
457 m_high(0.0),
458 m_low(0.0),
459 m_close(0.0),
460 m_brush(QBrush(Qt::NoBrush)),
461 m_pen(QPen(Qt::NoPen)),
462 m_series(nullptr)
463 {
464 setTimestamp(timestamp);
465 }
466
467 QCandlestickSetPrivate::~QCandlestickSetPrivate()
468 {
469 }
470
471 bool QCandlestickSetPrivate::setTimestamp(qreal timestamp)
472 {
473 timestamp = qMax(timestamp, 0.0);
474 timestamp = qRound64(timestamp);
475
476 if (m_timestamp == timestamp)
477 return false;
478
479 m_timestamp = timestamp;
480
481 return true;
482 }
483
484 #include "moc_qcandlestickset.cpp"
485 #include "moc_qcandlestickset_p.cpp"
486
487 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,102
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 #ifndef QCANDLESTICKSET_H
31 #define QCANDLESTICKSET_H
32
33 #include <QtCharts/QChartGlobal>
34 #include <QtGui/QBrush>
35 #include <QtGui/QPen>
36
37 QT_CHARTS_BEGIN_NAMESPACE
38
39 class QCandlestickSetPrivate;
40
41 class QT_CHARTS_EXPORT QCandlestickSet : public QObject
42 {
43 Q_OBJECT
44 Q_PROPERTY(qreal timestamp READ timestamp WRITE setTimestamp NOTIFY timestampChanged)
45 Q_PROPERTY(qreal open READ open WRITE setOpen NOTIFY openChanged)
46 Q_PROPERTY(qreal high READ high WRITE setHigh NOTIFY highChanged)
47 Q_PROPERTY(qreal low READ low WRITE setLow NOTIFY lowChanged)
48 Q_PROPERTY(qreal close READ close WRITE setClose NOTIFY closeChanged)
49 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
50 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
51
52 public:
53 explicit QCandlestickSet(qreal timestamp = 0.0, QObject *parent = nullptr);
54 explicit QCandlestickSet(qreal open, qreal high, qreal low, qreal close, qreal timestamp = 0.0,
55 QObject *parent = nullptr);
56 virtual ~QCandlestickSet();
57
58 void setTimestamp(qreal timestamp);
59 qreal timestamp() const;
60
61 void setOpen(qreal open);
62 qreal open() const;
63
64 void setHigh(qreal high);
65 qreal high() const;
66
67 void setLow(qreal low);
68 qreal low() const;
69
70 void setClose(qreal close);
71 qreal close() const;
72
73 void setBrush(const QBrush &brush);
74 QBrush brush() const;
75
76 void setPen(const QPen &pen);
77 QPen pen() const;
78
79 Q_SIGNALS:
80 void clicked();
81 void hovered(bool status);
82 void pressed();
83 void released();
84 void doubleClicked();
85 void timestampChanged();
86 void openChanged();
87 void highChanged();
88 void lowChanged();
89 void closeChanged();
90 void brushChanged();
91 void penChanged();
92
93 private:
94 QScopedPointer<QCandlestickSetPrivate> d_ptr;
95 Q_DECLARE_PRIVATE(QCandlestickSet)
96 Q_DISABLE_COPY(QCandlestickSet)
97 friend class QCandlestickSeriesPrivate;
98 };
99
100 QT_CHARTS_END_NAMESPACE
101
102 #endif // QCANDLESTICKSET_H
@@ -0,0 +1,83
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef QCANDLESTICKSET_P_H
40 #define QCANDLESTICKSET_P_H
41
42 #include <QtCharts/QChartGlobal>
43 #include <QtGui/QBrush>
44 #include <QtGui/QPen>
45
46 QT_CHARTS_BEGIN_NAMESPACE
47
48 class QCandlestickSeriesPrivate;
49 class QCandlestickSet;
50
51 class QCandlestickSetPrivate : public QObject
52 {
53 Q_OBJECT
54
55 public:
56 QCandlestickSetPrivate(qreal timestamp, QCandlestickSet *parent);
57 ~QCandlestickSetPrivate();
58
59 bool setTimestamp(qreal timestamp);
60
61 Q_SIGNALS:
62 void updatedLayout();
63 void updatedCandlestick();
64
65 private:
66 QCandlestickSet *q_ptr;
67 qreal m_timestamp;
68 qreal m_open;
69 qreal m_high;
70 qreal m_low;
71 qreal m_close;
72 QBrush m_brush;
73 QPen m_pen;
74 QCandlestickSeriesPrivate *m_series;
75
76 private:
77 Q_DECLARE_PUBLIC(QCandlestickSet)
78 friend class QCandlestickSeriesPrivate;
79 };
80
81 QT_CHARTS_END_NAMESPACE
82
83 #endif // QCANDLESTICKSET_P_H
@@ -0,0 +1,322
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 <QtCharts/QHCandlestickModelMapper>
31 #include <private/qcandlestickmodelmapper_p.h>
32
33 QT_CHARTS_BEGIN_NAMESPACE
34
35 /*!
36 \class QHCandlestickModelMapper
37 \since 5.8
38 \inmodule Qt Charts
39 \brief Horizontal model mapper for a candlestick series.
40
41 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
42 series, creating a connection between a QCandlestickSeries and the model object. A horizontal
43 model mapper maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}, and
44 reads the values of the set from the model's rows.
45
46 \note The model used must support adding and removing rows/columns and modifying the data of the
47 cells.
48 */
49
50 /*!
51 \qmltype HCandlestickModelMapper
52 \since 2.2
53 \instantiates QHCandlestickModelMapper
54 \inqmlmodule QtCharts
55 \brief Horizontal model mapper for a candlestick series.
56
57 HCandlestickModelMapper allows the use of a QAbstractItemModel-derived model with data in rows
58 as a data source for a candlestick series. It's possible to manipulate the data either through
59 QAbstractItemModel or QCandlestickSeries.
60
61 The following QML example creates a candlestick series with three candlestick sets (assuming the
62 model has at least four rows). Each candlestick set would contain data defined by timestamp,
63 open, high, low and close columns. The name of a set would be defined by the vertical header of
64 the row.
65 \qml
66 CandlestickSeries {
67 HCandlestickModelMapper {
68 model: myCustomModel // QAbstractItemModel derived implementation
69 timestampColumn: 1
70 openColumn: 2
71 highColumn: 3
72 lowColumn: 4
73 closeColumn: 5
74 firstCandlestickSetRow: 1
75 lastCandlestickSetRow: 3
76 }
77 }
78 \endqml
79
80 \note HCandlestickModelMapper keeps the series and the model in sync.
81 */
82
83 /*!
84 \qmlproperty QAbstractItemModel HCandlestickModelMapper::model
85 \brief The QAbstractItemModel-based model that is used by the mapper. The model must be
86 implemented and exposed to QML.
87
88 \note The model used must support adding and removing rows/columns and modifying the data of the
89 cells.
90 */
91
92 /*!
93 \qmlproperty CandlestickSeries HCandlestickModelMapper::series
94 \brief Defines the CandlestickSeries based object that is used by the mapper.
95
96 All the data in the series is discarded when it is set to the mapper. When a new series is
97 specified, the old series is disconnected (preserving its data).
98 */
99
100 /*!
101 \property QHCandlestickModelMapper::timestampColumn
102 \brief Defines the column of the model that contains the timestamp values of the
103 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
104 */
105
106 /*!
107 \qmlproperty int HCandlestickModelMapper::timestampColumn
108 \brief Defines the column of the model that contains the timestamp values of the
109 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
110 */
111
112 /*!
113 \property QHCandlestickModelMapper::openColumn
114 \brief Defines the column of the model that contains the open values of the
115 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
116 */
117
118 /*!
119 \qmlproperty int HCandlestickModelMapper::openColumn
120 \brief Defines the column of the model that contains the open values of the
121 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
122 */
123
124 /*!
125 \property QHCandlestickModelMapper::highColumn
126 \brief Defines the column of the model that contains the high values of the
127 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
128 */
129
130 /*!
131 \qmlproperty int HCandlestickModelMapper::highColumn
132 \brief Defines the column of the model that contains the high values of the
133 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
134 */
135
136 /*!
137 \property QHCandlestickModelMapper::lowColumn
138 \brief Defines the column of the model that contains the low values of the
139 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
140 */
141
142 /*!
143 \qmlproperty int HCandlestickModelMapper::lowColumn
144 \brief Defines the column of the model that contains the low values of the
145 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
146 */
147
148 /*!
149 \property QHCandlestickModelMapper::closeColumn
150 \brief Defines the column of the model that contains the close values of the
151 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
152 */
153
154 /*!
155 \qmlproperty int HCandlestickModelMapper::closeColumn
156 \brief Defines the column of the model that contains the close values of the
157 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
158 */
159
160 /*!
161 \property QHCandlestickModelMapper::firstCandlestickSetRow
162 \brief Defines the row of the model that is used as the data source for the first set. Default
163 value is -1 (invalid mapping).
164 */
165
166 /*!
167 \qmlproperty int HCandlestickModelMapper::firstCandlestickSetRow
168 \brief Defines the row of the model that is used as the data source for the first set. Default
169 value is -1 (invalid mapping).
170 */
171
172 /*!
173 \property QHCandlestickModelMapper::lastCandlestickSetRow
174 \brief Defines the row of the model that is used as the data source for the last set. Default
175 value is -1 (invalid mapping).
176 */
177
178 /*!
179 \qmlproperty int HCandlestickModelMapper::lastCandlestickSetRow
180 \brief Defines the row of the model that is used as the data source for the last set. Default
181 value is -1 (invalid mapping).
182 */
183
184 /*!
185 \fn void QHCandlestickModelMapper::timestampColumnChanged()
186 \brief Emitted when the column of the model that contains timestamp values is changed
187 \sa timestampColumn
188 */
189
190 /*!
191 \fn void QHCandlestickModelMapper::openColumnChanged()
192 \brief Emitted when the column of the model that contains open values is changed.
193 \sa openColumn
194 */
195 /*!
196 \fn void QHCandlestickModelMapper::highColumnChanged()
197 \brief Emitted when the column of the model that contains high values is changed.
198 \sa highColumn
199 */
200
201 /*!
202 \fn void QHCandlestickModelMapper::lowColumnChanged()
203 \brief Emitted when the column of the model that contains low values is changed.
204 \sa lowColumn
205 */
206
207 /*!
208 \fn void QHCandlestickModelMapper::closeColumnChanged()
209 \brief Emitted when the column of the model that contains close values is changed.
210 \sa closeColumn
211 */
212
213 /*!
214 \fn void QHCandlestickModelMapper::firstCandlestickSetRowChanged()
215 \brief Emitted when the row of the model that contains the data of the first set is changed.
216 \sa firstCandlestickSetRow
217 */
218
219 /*!
220 \fn void QHCandlestickModelMapper::lastCandlestickSetRowChanged()
221 \brief Emitted when the row of the model that contains the data of the last set is changed.
222 \sa lastCandlestickSetRow
223 */
224
225 /*!
226 Constructs a horizontal model mapper object which is a child of \a parent.
227 */
228 QHCandlestickModelMapper::QHCandlestickModelMapper(QObject *parent)
229 : QCandlestickModelMapper(parent)
230 {
231 connect(d_ptr, SIGNAL(timestampChanged()), this, SIGNAL(timestampColumnChanged()));
232 connect(d_ptr, SIGNAL(openChanged()), this, SIGNAL(openColumnChanged()));
233 connect(d_ptr, SIGNAL(highChanged()), this, SIGNAL(highColumnChanged()));
234 connect(d_ptr, SIGNAL(lowChanged()), this, SIGNAL(lowColumnChanged()));
235 connect(d_ptr, SIGNAL(closeChanged()), this, SIGNAL(closeColumnChanged()));
236 connect(d_ptr, SIGNAL(firstCandlestickSetSectionChanged()),
237 this, SIGNAL(firstCandlestickSetRowChanged()));
238 connect(d_ptr, SIGNAL(lastCandlestickSetSectionChanged()),
239 this, SIGNAL(lastCandlestickSetRowChanged()));
240 }
241
242 /*!
243 Returns Qt::Horizontal. This means that values of the set are read from rows.
244 */
245 Qt::Orientation QHCandlestickModelMapper::orientation() const
246 {
247 return Qt::Horizontal;
248 }
249
250 void QHCandlestickModelMapper::setTimestampColumn(int timestampColumn)
251 {
252 QCandlestickModelMapper::setTimestamp(timestampColumn);
253 }
254
255 int QHCandlestickModelMapper::timestampColumn() const
256 {
257 return QCandlestickModelMapper::timestamp();
258 }
259
260 void QHCandlestickModelMapper::setOpenColumn(int openColumn)
261 {
262 QCandlestickModelMapper::setOpen(openColumn);
263 }
264
265 int QHCandlestickModelMapper::openColumn() const
266 {
267 return QCandlestickModelMapper::open();
268 }
269
270 void QHCandlestickModelMapper::setHighColumn(int highColumn)
271 {
272 QCandlestickModelMapper::setHigh(highColumn);
273 }
274
275 int QHCandlestickModelMapper::highColumn() const
276 {
277 return QCandlestickModelMapper::high();
278 }
279
280 void QHCandlestickModelMapper::setLowColumn(int lowColumn)
281 {
282 QCandlestickModelMapper::setLow(lowColumn);
283 }
284
285 int QHCandlestickModelMapper::lowColumn() const
286 {
287 return QCandlestickModelMapper::low();
288 }
289
290 void QHCandlestickModelMapper::setCloseColumn(int closeColumn)
291 {
292 QCandlestickModelMapper::setClose(closeColumn);
293 }
294
295 int QHCandlestickModelMapper::closeColumn() const
296 {
297 return QCandlestickModelMapper::close();
298 }
299
300 void QHCandlestickModelMapper::setFirstCandlestickSetRow(int firstCandlestickSetRow)
301 {
302 QCandlestickModelMapper::setFirstCandlestickSetSection(firstCandlestickSetRow);
303 }
304
305 int QHCandlestickModelMapper::firstCandlestickSetRow() const
306 {
307 return QCandlestickModelMapper::firstCandlestickSetSection();
308 }
309
310 void QHCandlestickModelMapper::setLastCandlestickSetRow(int lastCandlestickSetRow)
311 {
312 QCandlestickModelMapper::setLastCandlestickSetSection(lastCandlestickSetRow);
313 }
314
315 int QHCandlestickModelMapper::lastCandlestickSetRow() const
316 {
317 return QCandlestickModelMapper::lastCandlestickSetSection();
318 }
319
320 #include "moc_qhcandlestickmodelmapper.cpp"
321
322 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,86
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 #ifndef QHCANDLESTICKMODELMAPPER_H
31 #define QHCANDLESTICKMODELMAPPER_H
32
33 #include <QtCharts/QCandlestickModelMapper>
34
35 QT_CHARTS_BEGIN_NAMESPACE
36 /* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
37 class QT_CHARTS_EXPORT QHCandlestickModelMapper : public QCandlestickModelMapper
38 {
39 Q_OBJECT
40 Q_PROPERTY(int timestampColumn READ timestampColumn WRITE setTimestampColumn NOTIFY timestampColumnChanged)
41 Q_PROPERTY(int openColumn READ openColumn WRITE setOpenColumn NOTIFY openColumnChanged)
42 Q_PROPERTY(int highColumn READ highColumn WRITE setHighColumn NOTIFY highColumnChanged)
43 Q_PROPERTY(int lowColumn READ lowColumn WRITE setLowColumn NOTIFY lowColumnChanged)
44 Q_PROPERTY(int closeColumn READ closeColumn WRITE setCloseColumn NOTIFY closeColumnChanged)
45 Q_PROPERTY(int firstCandlestickSetRow READ firstCandlestickSetRow WRITE setFirstCandlestickSetRow NOTIFY firstCandlestickSetRowChanged)
46 Q_PROPERTY(int lastCandlestickSetRow READ lastCandlestickSetRow WRITE setLastCandlestickSetRow NOTIFY lastCandlestickSetRowChanged)
47
48 public:
49 explicit QHCandlestickModelMapper(QObject *parent = nullptr);
50
51 Qt::Orientation orientation() const;
52
53 void setTimestampColumn(int timestampColumn);
54 int timestampColumn() const;
55
56 void setOpenColumn(int openColumn);
57 int openColumn() const;
58
59 void setHighColumn(int highColumn);
60 int highColumn() const;
61
62 void setLowColumn(int lowColumn);
63 int lowColumn() const;
64
65 void setCloseColumn(int closeColumn);
66 int closeColumn() const;
67
68 void setFirstCandlestickSetRow(int firstCandlestickSetRow);
69 int firstCandlestickSetRow() const;
70
71 void setLastCandlestickSetRow(int lastCandlestickSetRow);
72 int lastCandlestickSetRow() const;
73
74 Q_SIGNALS:
75 void timestampColumnChanged();
76 void openColumnChanged();
77 void highColumnChanged();
78 void lowColumnChanged();
79 void closeColumnChanged();
80 void firstCandlestickSetRowChanged();
81 void lastCandlestickSetRowChanged();
82 };
83
84 QT_CHARTS_END_NAMESPACE
85
86 #endif // QHCANDLESTICKMODELMAPPER_H
@@ -0,0 +1,323
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 <QtCharts/QVCandlestickModelMapper>
31 #include <private/qcandlestickmodelmapper_p.h>
32
33 QT_CHARTS_BEGIN_NAMESPACE
34
35 /*!
36 \class QVCandlestickModelMapper
37 \since 5.8
38 \inmodule Qt Charts
39 \brief Vertical model mapper for a candlestick series.
40
41 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
42 series, creating a connection between a QCandlestickSeries and the model object. A vertical
43 model mapper maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}, and
44 reads the values of the set from the model's columns.
45
46 \note The model used must support adding and removing rows/columns and modifying the data of the
47 cells.
48 */
49
50 /*!
51 \qmltype VCandlestickModelMapper
52 \since 2.2
53 \instantiates QVCandlestickModelMapper
54 \inqmlmodule QtCharts
55 \brief Vertical model mapper for a candlestick series.
56
57 VCandlestickModelMapper allows the use of a QAbstractItemModel-derived model with data in
58 columns as a data source for a candlestick series. It's possible to manipulate the data either
59 through QAbstractItemModel or QCandlestickSeries.
60
61 The following QML example creates a candlestick series with three candlestick sets (assuming the
62 model has at least four columns). Each candlestick set would contain data defined by timestamp,
63 open, high, low and close rows. The name of a set would be defined by the horizontal header of
64 the column.
65 \qml
66 CandlestickSeries {
67 VCandlestickModelMapper {
68 model: myCustomModel // QAbstractItemModel derived implementation
69 timestampRow: 1
70 openRow: 2
71 highRow: 3
72 lowRow: 4
73 closeRow: 5
74 firstCandlestickSetColumn: 1
75 lastCandlestickSetColumn: 3
76 }
77 }
78 \endqml
79
80 \note VCandlestickModelMapper keeps the series and the model in sync.
81 */
82
83 /*!
84 \qmlproperty QAbstractItemModel VCandlestickModelMapper::model
85 \brief The QAbstractItemModel-based model that is used by the mapper. The model must be
86 implemented and exposed to QML.
87
88 \note The model used must support adding and removing rows/columns and modifying the data of the
89 cells.
90 */
91
92 /*!
93 \qmlproperty CandlestickSeries VCandlestickModelMapper::series
94 \brief Defines the CandlestickSeries based object that is used by the mapper.
95
96 All the data in the series is discarded when it is set to the mapper. When a new series is
97 specified, the old series is disconnected (preserving its data).
98 */
99
100 /*!
101 \property QVCandlestickModelMapper::timestampRow
102 \brief Defines the row of the model that contains the timestamp values of the
103 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
104 */
105
106 /*!
107 \qmlproperty int VCandlestickModelMapper::timestampRow
108 \brief Defines the row of the model that contains the timestamp values of the
109 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
110 */
111
112 /*!
113 \property QVCandlestickModelMapper::openRow
114 \brief Defines the row of the model that contains the open values of the
115 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
116 */
117
118 /*!
119 \qmlproperty int VCandlestickModelMapper::openRow
120 \brief Defines the row of the model that contains the open values of the
121 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
122 */
123
124 /*!
125 \property QVCandlestickModelMapper::highRow
126 \brief Defines the row of the model that contains the high values of the
127 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
128 */
129
130 /*!
131 \qmlproperty int VCandlestickModelMapper::highRow
132 \brief Defines the row of the model that contains the high values of the
133 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
134 */
135
136 /*!
137 \property QVCandlestickModelMapper::lowRow
138 \brief Defines the row of the model that contains the low values of the
139 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
140 */
141
142 /*!
143 \qmlproperty int VCandlestickModelMapper::lowRow
144 \brief Defines the row of the model that contains the low values of the
145 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
146 */
147
148 /*!
149 \property QVCandlestickModelMapper::closeRow
150 \brief Defines the row of the model that contains the close values of the
151 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
152 */
153
154 /*!
155 \qmlproperty int VCandlestickModelMapper::closeRow
156 \brief Defines the row of the model that contains the close values of the
157 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
158 */
159
160 /*!
161 \property QVCandlestickModelMapper::firstCandlestickSetColumn
162 \brief Defines the column of the model that is used as the data source for the first set.
163 Default value is -1 (invalid mapping).
164 */
165
166 /*!
167 \qmlproperty int VCandlestickModelMapper::firstCandlestickSetColumn
168 \brief Defines the column of the model that is used as the data source for the first set.
169 Default value is -1 (invalid mapping).
170 */
171
172 /*!
173 \property QVCandlestickModelMapper::lastCandlestickSetColumn
174 \brief Defines the column of the model that is used as the data source for the last set. Default
175 value is -1 (invalid mapping).
176 */
177
178 /*!
179 \qmlproperty int VCandlestickModelMapper::lastCandlestickSetColumn
180 \brief Defines the column of the model that is used as the data source for the last set. Default
181 value is -1 (invalid mapping).
182 */
183
184 /*!
185 \fn void QVCandlestickModelMapper::timestampRowChanged()
186 \brief Emitted when the row of the model that contains timestamp values is changed.
187 \sa timestampRow
188 */
189
190 /*!
191 \fn void QVCandlestickModelMapper::openRowChanged()
192 \brief Emitted when the row of the model that contains open values is changed.
193 \sa openRow
194 */
195
196 /*!
197 \fn void QVCandlestickModelMapper::highRowChanged()
198 \brief Emitted when the row of the model that contains high values is changed.
199 \sa highRow
200 */
201
202 /*!
203 \fn void QVCandlestickModelMapper::lowRowChanged()
204 \brief Emitted when the row of the model that contains low values is changed.
205 \sa lowRow
206 */
207
208 /*!
209 \fn void QVCandlestickModelMapper::closeRowChanged()
210 \brief Emitted when the row of the model that contains close values is changed.
211 \sa closeRow
212 */
213
214 /*!
215 \fn void QVCandlestickModelMapper::firstCandlestickSetColumnChanged()
216 \brief Emitted when the column of the model that contains the data of the first set is changed.
217 \sa firstCandlestickSetColumn
218 */
219
220 /*!
221 \fn void QVCandlestickModelMapper::lastCandlestickSetColumnChanged()
222 \brief Emitted when the column of the model that contains the data of the last set is changed.
223 \sa lastCandlestickSetColumn
224 */
225
226 /*!
227 Constructs a vertical model mapper object which is a child of \a parent.
228 */
229 QVCandlestickModelMapper::QVCandlestickModelMapper(QObject *parent)
230 : QCandlestickModelMapper(parent)
231 {
232 connect(d_ptr, SIGNAL(timestampChanged()), this, SIGNAL(timestampRowChanged()));
233 connect(d_ptr, SIGNAL(openChanged()), this, SIGNAL(openRowChanged()));
234 connect(d_ptr, SIGNAL(highChanged()), this, SIGNAL(highRowChanged()));
235 connect(d_ptr, SIGNAL(lowChanged()), this, SIGNAL(lowRowChanged()));
236 connect(d_ptr, SIGNAL(closeChanged()), this, SIGNAL(closeRowChanged()));
237 connect(d_ptr, SIGNAL(firstCandlestickSetSectionChanged()),
238 this, SIGNAL(firstCandlestickSetColumnChanged()));
239 connect(d_ptr, SIGNAL(lastCandlestickSetSectionChanged()),
240 this, SIGNAL(lastCandlestickSetColumnChanged()));
241 }
242
243 /*!
244 Returns Qt::Vertical. This means that values of the set are read from columns.
245 */
246 Qt::Orientation QVCandlestickModelMapper::orientation() const
247 {
248 return Qt::Vertical;
249 }
250
251 void QVCandlestickModelMapper::setTimestampRow(int timestampRow)
252 {
253 QCandlestickModelMapper::setTimestamp(timestampRow);
254 }
255
256 int QVCandlestickModelMapper::timestampRow() const
257 {
258 return QCandlestickModelMapper::timestamp();
259 }
260
261 void QVCandlestickModelMapper::setOpenRow(int openRow)
262 {
263 QCandlestickModelMapper::setOpen(openRow);
264 }
265
266 int QVCandlestickModelMapper::openRow() const
267 {
268 return QCandlestickModelMapper::open();
269 }
270
271 void QVCandlestickModelMapper::setHighRow(int highRow)
272 {
273 QCandlestickModelMapper::setHigh(highRow);
274 }
275
276 int QVCandlestickModelMapper::highRow() const
277 {
278 return QCandlestickModelMapper::high();
279 }
280
281 void QVCandlestickModelMapper::setLowRow(int lowRow)
282 {
283 QCandlestickModelMapper::setLow(lowRow);
284 }
285
286 int QVCandlestickModelMapper::lowRow() const
287 {
288 return QCandlestickModelMapper::low();
289 }
290
291 void QVCandlestickModelMapper::setCloseRow(int closeRow)
292 {
293 QCandlestickModelMapper::setClose(closeRow);
294 }
295
296 int QVCandlestickModelMapper::closeRow() const
297 {
298 return QCandlestickModelMapper::close();
299 }
300
301 void QVCandlestickModelMapper::setFirstCandlestickSetColumn(int firstCandlestickSetColumn)
302 {
303 QCandlestickModelMapper::setFirstCandlestickSetSection(firstCandlestickSetColumn);
304 }
305
306 int QVCandlestickModelMapper::firstCandlestickSetColumn() const
307 {
308 return QCandlestickModelMapper::firstCandlestickSetSection();
309 }
310
311 void QVCandlestickModelMapper::setLastCandlestickSetColumn(int lastCandlestickSetColumn)
312 {
313 QCandlestickModelMapper::setLastCandlestickSetSection(lastCandlestickSetColumn);
314 }
315
316 int QVCandlestickModelMapper::lastCandlestickSetColumn() const
317 {
318 return QCandlestickModelMapper::lastCandlestickSetSection();
319 }
320
321 #include "moc_qvcandlestickmodelmapper.cpp"
322
323 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,86
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 #ifndef QVCANDLESTICKMODELMAPPER_H
31 #define QVCANDLESTICKMODELMAPPER_H
32
33 #include <QtCharts/QCandlestickModelMapper>
34
35 QT_CHARTS_BEGIN_NAMESPACE
36 /* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
37 class QT_CHARTS_EXPORT QVCandlestickModelMapper : public QCandlestickModelMapper
38 {
39 Q_OBJECT
40 Q_PROPERTY(int timestampRow READ timestampRow WRITE setTimestampRow NOTIFY timestampRowChanged)
41 Q_PROPERTY(int openRow READ openRow WRITE setOpenRow NOTIFY openRowChanged)
42 Q_PROPERTY(int highRow READ highRow WRITE setHighRow NOTIFY highRowChanged)
43 Q_PROPERTY(int lowRow READ lowRow WRITE setLowRow NOTIFY lowRowChanged)
44 Q_PROPERTY(int closeRow READ closeRow WRITE setCloseRow NOTIFY closeRowChanged)
45 Q_PROPERTY(int firstCandlestickSetColumn READ firstCandlestickSetColumn WRITE setFirstCandlestickSetColumn NOTIFY firstCandlestickSetColumnChanged)
46 Q_PROPERTY(int lastCandlestickSetColumn READ lastCandlestickSetColumn WRITE setLastCandlestickSetColumn NOTIFY lastCandlestickSetColumnChanged)
47
48 public:
49 explicit QVCandlestickModelMapper(QObject *parent = nullptr);
50
51 Qt::Orientation orientation() const;
52
53 void setTimestampRow(int timestampRow);
54 int timestampRow() const;
55
56 void setOpenRow(int openRow);
57 int openRow() const;
58
59 void setHighRow(int highRow);
60 int highRow() const;
61
62 void setLowRow(int lowRow);
63 int lowRow() const;
64
65 void setCloseRow(int closeRow);
66 int closeRow() const;
67
68 void setFirstCandlestickSetColumn(int firstCandlestickSetColumn);
69 int firstCandlestickSetColumn() const;
70
71 void setLastCandlestickSetColumn(int lastCandlestickSetColumn);
72 int lastCandlestickSetColumn() const;
73
74 Q_SIGNALS:
75 void timestampRowChanged();
76 void openRowChanged();
77 void highRowChanged();
78 void lowRowChanged();
79 void closeRowChanged();
80 void firstCandlestickSetColumnChanged();
81 void lastCandlestickSetColumnChanged();
82 };
83
84 QT_CHARTS_END_NAMESPACE
85
86 #endif // QVCANDLESTICKMODELMAPPER_H
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100755, binary diff hidden
NO CONTENT: new file 100755, binary diff hidden
@@ -0,0 +1,99
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 /*!
31 \example candlestickchart
32 \title Candlestick Chart Example
33 \ingroup qtcharts_examples
34
35 \brief Shows how to create a candlestick chart.
36
37 \image examples_candlestickchart.png
38
39 To display a candlestick chart, we start by creating QCandlestickSeries to handle daily data. We
40 are also specifying custom increasing and decreasing body colors.
41
42 \snippet candlestickchart/main.cpp 1
43
44 QFile is used for accessing a text file where the non-continuous data is kept. The
45 \c CandlestickDataReader is an auxiliary class for reading the text file and finding the open,
46 high, low, close, and timestamp values from the data. The \c CandlestickDataReader is explained
47 in more detail later. The method \c readCandlestickSet() reads the values and sets them to the
48 QCandlestickSet item which the method returns for the caller. The returned QCandlestickSet item
49 is added to the series. We are also saving custom categories list for later use.
50
51 \snippet candlestickchart/main.cpp 2
52
53 Below, a new QChart instance is created and the previously created series object is added to it.
54 We also define a title, and set an animation as
55 \l {QChart::AnimationOption} {QChart::SeriesAnimation}.
56
57 \snippet candlestickchart/main.cpp 3
58
59 Here, we ask the chart to create default axes for our presentation. Then, we set custom
60 categories for the horizontal axis by querying the pointer for the axis from the chart, and then
61 setting the categories from previously saved custom categories list. We also set the range for
62 the vertical axis by querying the pointer for the axis from the chart, and then setting the min
63 and max values for that axis.
64
65 \snippet candlestickchart/main.cpp 4
66
67 Below, we set the legend to be visible and place it at the bottom of the chart.
68
69 \snippet candlestickchart/main.cpp 5
70
71 Finally, we add the chart onto a view. We also turn on the antialiasing for the chartView.
72
73 \snippet candlestickchart/main.cpp 6
74
75 The chart is ready to be shown. We set the chart to be the central widget of the window. We also
76 set the size for the chart window and show it.
77
78 \snippet candlestickchart/main.cpp 7
79
80 Here, the method \c readCandlestickSet() is explained in detail. First, a line is read from
81 the file, rejecting any lines starting with # as they are considered comment lines.
82
83 \snippet candlestickchart/candlestickdatareader.cpp 1
84
85 In the file, the data is arranged as a space-delimited sequence of numbers. On this snippet the
86 line is split into single number strings which are stored in a QStringList.
87
88 \snippet candlestickchart/candlestickdatareader.cpp 2
89
90 To select values from the continuous data, following code is used. The values in a \c strList
91 are stored in the following order: timestamp, open, high, low, close.
92
93 \snippet candlestickchart/candlestickdatareader.cpp 3
94
95 Finally, the following snippet shows how to create a new QCandlestickSet and provide it with all
96 the necessary values.
97
98 \snippet candlestickchart/candlestickdatareader.cpp 4
99 */
@@ -0,0 +1,125
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 <QtCharts/QCandlestickLegendMarker>
31 #include <private/legendmarkeritem_p.h>
32 #include <private/qcandlesticklegendmarker_p.h>
33 #include <private/qcandlestickseries_p.h>
34
35 QT_CHARTS_BEGIN_NAMESPACE
36
37 QCandlestickLegendMarker::QCandlestickLegendMarker(QCandlestickSeries *series, QLegend *legend,
38 QObject *parent)
39 : QLegendMarker(*new QCandlestickLegendMarkerPrivate(this, series, legend), parent)
40 {
41 Q_D(QCandlestickLegendMarker);
42
43 d->updated();
44 }
45
46 QCandlestickLegendMarker::~QCandlestickLegendMarker()
47 {
48 }
49
50 QLegendMarker::LegendMarkerType QCandlestickLegendMarker::type()
51 {
52 return LegendMarkerTypeCandlestick;
53 }
54
55 QCandlestickSeries* QCandlestickLegendMarker::series()
56 {
57 Q_D(QCandlestickLegendMarker);
58
59 return d->m_series;
60 }
61
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63
64 QCandlestickLegendMarkerPrivate::QCandlestickLegendMarkerPrivate(QCandlestickLegendMarker *q,
65 QCandlestickSeries *series,
66 QLegend *legend)
67 : QLegendMarkerPrivate(q, legend),
68 q_ptr(q),
69 m_series(series)
70 {
71 QObject::connect(m_item, SIGNAL(markerRectChanged()), this, SLOT(updated()));
72 QObject::connect(m_series, SIGNAL(nameChanged()), this, SLOT(updated()));
73 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(updated()));
74 }
75
76 QCandlestickLegendMarkerPrivate::~QCandlestickLegendMarkerPrivate()
77 {
78 }
79
80 QAbstractSeries* QCandlestickLegendMarkerPrivate::series()
81 {
82 return m_series;
83 }
84
85 QObject* QCandlestickLegendMarkerPrivate::relatedObject()
86 {
87 return m_series;
88 }
89
90 void QCandlestickLegendMarkerPrivate::updated()
91 {
92 bool labelChanged = false;
93 bool brushChanged = false;
94
95 if (!m_customLabel && (m_item->label() != m_series->name())) {
96 m_item->setLabel(m_series->name());
97 labelChanged = true;
98 }
99 if (!m_customBrush) {
100 QLinearGradient gradient;
101 gradient.setStart(0.0, 0.0);
102 gradient.setFinalStop(m_item->markerRect().width(), m_item->markerRect().height());
103 gradient.setColorAt(0.0, m_series->increasingColor());
104 gradient.setColorAt(0.49, m_series->increasingColor());
105 gradient.setColorAt(0.50, m_series->decreasingColor());
106 gradient.setColorAt(1.0, m_series->decreasingColor());
107
108 QBrush brush(gradient);
109 if (m_item->brush() != brush) {
110 m_item->setBrush(brush);
111 brushChanged = true;
112 }
113 }
114 invalidateLegend();
115
116 if (labelChanged)
117 emit q_ptr->labelChanged();
118 if (brushChanged)
119 emit q_ptr->brushChanged();
120 }
121
122 #include "moc_qcandlesticklegendmarker.cpp"
123 #include "moc_qcandlesticklegendmarker_p.cpp"
124
125 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,61
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 #ifndef QCANDLESTICKLEGENDMARKER_H
31 #define QCANDLESTICKLEGENDMARKER_H
32
33 #include <QtCharts/QCandlestickSeries>
34 #include <QtCharts/QLegendMarker>
35
36 QT_CHARTS_BEGIN_NAMESPACE
37
38 class QCandlestickLegendMarkerPrivate;
39
40 class QT_CHARTS_EXPORT QCandlestickLegendMarker : public QLegendMarker
41 {
42 Q_OBJECT
43
44 public:
45 explicit QCandlestickLegendMarker(QCandlestickSeries *series, QLegend *legend,
46 QObject *parent = nullptr);
47 virtual ~QCandlestickLegendMarker();
48
49 virtual LegendMarkerType type();
50
51 // Related series
52 virtual QCandlestickSeries* series();
53
54 private:
55 Q_DECLARE_PRIVATE(QCandlestickLegendMarker)
56 Q_DISABLE_COPY(QCandlestickLegendMarker)
57 };
58
59 QT_CHARTS_END_NAMESPACE
60
61 #endif // QCANDLESTICKLEGENDMARKER_H
@@ -0,0 +1,72
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 // W A R N I N G
31 // -------------
32 //
33 // This file is not part of the Qt Chart API. It exists purely as an
34 // implementation detail. This header file may change from version to
35 // version without notice, or even be removed.
36 //
37 // We mean it.
38
39 #ifndef QCANDLESTICKLEGENDMARKER_P_H
40 #define QCANDLESTICKLEGENDMARKER_P_H
41
42 #include <private/qlegendmarker_p.h>
43
44 QT_CHARTS_BEGIN_NAMESPACE
45
46 class QCandlestickLegendMarker;
47 class QCandlestickSeries;
48
49 class QCandlestickLegendMarkerPrivate : public QLegendMarkerPrivate
50 {
51 Q_OBJECT
52 public:
53 explicit QCandlestickLegendMarkerPrivate(QCandlestickLegendMarker *q,
54 QCandlestickSeries *series, QLegend *legend);
55 virtual ~QCandlestickLegendMarkerPrivate();
56
57 virtual QAbstractSeries *series();
58 virtual QObject *relatedObject();
59
60 public Q_SLOTS:
61 virtual void updated();
62
63 private:
64 QCandlestickLegendMarker *q_ptr;
65 QCandlestickSeries *m_series;
66
67 Q_DECLARE_PUBLIC(QCandlestickLegendMarker)
68 };
69
70 QT_CHARTS_END_NAMESPACE
71
72 #endif // QCANDLESTICKLEGENDMARKER_P_H
@@ -0,0 +1,244
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 <QtCharts/QHCandlestickModelMapper>
31 #include <QtCharts/QVCandlestickModelMapper>
32 #include "declarativeaxes.h"
33 #include "declarativecandlestickseries.h"
34
35 QT_CHARTS_BEGIN_NAMESPACE
36
37 DeclarativeCandlestickSet::DeclarativeCandlestickSet(qreal timestamp, QObject *parent)
38 : QCandlestickSet(timestamp, parent)
39 {
40 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
41 }
42
43 void DeclarativeCandlestickSet::setBrushFilename(const QString &brushFilename)
44 {
45 QImage brushImage(brushFilename);
46 if (QCandlestickSet::brush().textureImage() != brushImage) {
47 QBrush brush = QCandlestickSet::brush();
48 brush.setTextureImage(brushImage);
49
50 QCandlestickSet::setBrush(brush);
51
52 m_brushFilename = brushFilename;
53 m_brushImage = brushImage;
54
55 emit brushFilenameChanged(brushFilename);
56 }
57 }
58
59 QString DeclarativeCandlestickSet::brushFilename() const
60 {
61 return m_brushFilename;
62 }
63
64 void DeclarativeCandlestickSet::handleBrushChanged()
65 {
66 // If the texture image of the brush has changed along the brush
67 // the brush file name needs to be cleared.
68 if (!m_brushFilename.isEmpty() && QCandlestickSet::brush().textureImage() != m_brushImage) {
69 m_brushFilename.clear();
70 emit brushFilenameChanged(QString());
71 }
72 }
73
74 // Declarative candlestick series ==================================================================
75
76 DeclarativeCandlestickSeries::DeclarativeCandlestickSeries(QQuickItem *parent)
77 : QCandlestickSeries(parent),
78 m_axes(new DeclarativeAxes(this))
79 {
80 connect(m_axes, SIGNAL(axisXChanged(QAbstractAxis*)),
81 this, SIGNAL(axisXChanged(QAbstractAxis*)));
82 connect(m_axes, SIGNAL(axisYChanged(QAbstractAxis*)),
83 this, SIGNAL(axisYChanged(QAbstractAxis*)));
84 connect(m_axes, SIGNAL(axisXTopChanged(QAbstractAxis*)),
85 this, SIGNAL(axisXTopChanged(QAbstractAxis*)));
86 connect(m_axes, SIGNAL(axisYRightChanged(QAbstractAxis*)),
87 this, SIGNAL(axisYRightChanged(QAbstractAxis*)));
88
89 connect(this, SIGNAL(hovered(bool, QCandlestickSet *)),
90 this, SLOT(onHovered(bool, QCandlestickSet *)));
91 connect(this, SIGNAL(clicked(QCandlestickSet *)), this, SLOT(onClicked(QCandlestickSet *)));
92 connect(this, SIGNAL(pressed(QCandlestickSet *)), this, SLOT(onPressed(QCandlestickSet *)));
93 connect(this, SIGNAL(released(QCandlestickSet *)), this, SLOT(onReleased(QCandlestickSet *)));
94 connect(this, SIGNAL(doubleClicked(QCandlestickSet *)),
95 this, SLOT(onDoubleClicked(QCandlestickSet *)));
96
97 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
98 }
99
100 QQmlListProperty<QObject> DeclarativeCandlestickSeries::seriesChildren()
101 {
102 return QQmlListProperty<QObject>(this, 0, &DeclarativeCandlestickSeries::appendSeriesChildren,
103 0, 0, 0);
104 }
105
106 void DeclarativeCandlestickSeries::setBrushFilename(const QString &brushFilename)
107 {
108 QImage brushImage(brushFilename);
109 if (QCandlestickSeries::brush().textureImage() != brushImage) {
110 QBrush brush = QCandlestickSeries::brush();
111 brush.setTextureImage(brushImage);
112
113 QCandlestickSeries::setBrush(brush);
114
115 m_brushFilename = brushFilename;
116 m_brushImage = brushImage;
117
118 emit brushFilenameChanged(brushFilename);
119 }
120 }
121
122 QString DeclarativeCandlestickSeries::brushFilename() const
123 {
124 return m_brushFilename;
125 }
126
127 DeclarativeCandlestickSet *DeclarativeCandlestickSeries::at(int index)
128 {
129 QList<QCandlestickSet *> sets = candlestickSets();
130 if (index >= 0 && index < sets.count())
131 return qobject_cast<DeclarativeCandlestickSet *>(sets[index]);
132
133 return 0;
134 }
135
136 bool DeclarativeCandlestickSeries::append(DeclarativeCandlestickSet *set)
137 {
138 return QCandlestickSeries::append(qobject_cast<QCandlestickSet *>(set));
139 }
140
141 bool DeclarativeCandlestickSeries::remove(DeclarativeCandlestickSet *set)
142 {
143 return QCandlestickSeries::remove(qobject_cast<QCandlestickSet *>(set));
144 }
145
146 bool DeclarativeCandlestickSeries::append(qreal open, qreal high, qreal low, qreal close,
147 qreal timestamp)
148 {
149 QCandlestickSet *set = new QCandlestickSet(open, high, low, close, timestamp);
150 if (!QCandlestickSeries::append(set)) {
151 delete set;
152 return false;
153 }
154
155 return true;
156 }
157
158 bool DeclarativeCandlestickSeries::remove(qreal timestamp)
159 {
160 for (int i = 0; i < count(); ++i) {
161 QCandlestickSet *set = candlestickSets().at(i);
162 if (set->timestamp() == timestamp)
163 return QCandlestickSeries::remove(set);
164 }
165
166 return false;
167 }
168
169 bool DeclarativeCandlestickSeries::insert(int index, DeclarativeCandlestickSet *set)
170 {
171 return QCandlestickSeries::insert(index, qobject_cast<QCandlestickSet *>(set));
172 }
173
174 void DeclarativeCandlestickSeries::clear()
175 {
176 QCandlestickSeries::clear();
177 }
178
179 void DeclarativeCandlestickSeries::classBegin()
180 {
181 // do nothing
182 }
183
184 void DeclarativeCandlestickSeries::componentComplete()
185 {
186 foreach (QObject *child, children()) {
187 if (qobject_cast<DeclarativeCandlestickSet *>(child)) {
188 QCandlestickSeries::append(qobject_cast<DeclarativeCandlestickSet *>(child));
189 } else if (qobject_cast<QHCandlestickModelMapper *>(child)) {
190 QHCandlestickModelMapper *mapper = qobject_cast<QHCandlestickModelMapper *>(child);
191 mapper->setSeries(this);
192 } else if (qobject_cast<QVCandlestickModelMapper *>(child)) {
193 QVCandlestickModelMapper *mapper = qobject_cast<QVCandlestickModelMapper *>(child);
194 mapper->setSeries(this);
195 } // else: do nothing
196 }
197 }
198
199 void DeclarativeCandlestickSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
200 QObject *element)
201 {
202 // Empty implementation; the children are parsed in componentComplete instead
203 Q_UNUSED(list);
204 Q_UNUSED(element);
205 }
206
207 void DeclarativeCandlestickSeries::onClicked(QCandlestickSet *set)
208 {
209 emit clicked(qobject_cast<DeclarativeCandlestickSet *>(set));
210 }
211
212 void DeclarativeCandlestickSeries::onHovered(bool status, QCandlestickSet *set)
213 {
214 emit hovered(status, qobject_cast<DeclarativeCandlestickSet *>(set));
215 }
216
217 void DeclarativeCandlestickSeries::onPressed(QCandlestickSet *set)
218 {
219 emit pressed(qobject_cast<DeclarativeCandlestickSet *>(set));
220 }
221
222 void DeclarativeCandlestickSeries::onReleased(QCandlestickSet *set)
223 {
224 emit released(qobject_cast<DeclarativeCandlestickSet *>(set));
225 }
226
227 void DeclarativeCandlestickSeries::onDoubleClicked(QCandlestickSet *set)
228 {
229 emit doubleClicked(qobject_cast<DeclarativeCandlestickSet *>(set));
230 }
231
232 void DeclarativeCandlestickSeries::handleBrushChanged()
233 {
234 // If the texture image of the brush has changed along the brush
235 // the brush file name needs to be cleared.
236 if (!m_brushFilename.isEmpty() && QCandlestickSeries::brush().textureImage() != m_brushImage) {
237 m_brushFilename.clear();
238 emit brushFilenameChanged(QString());
239 }
240 }
241
242 #include "moc_declarativecandlestickseries.cpp"
243
244 QT_CHARTS_END_NAMESPACE
@@ -0,0 +1,136
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 #ifndef DECLARATIVECANDLESTICKSERIES_H
31 #define DECLARATIVECANDLESTICKSERIES_H
32
33 #include <QtCharts/QCandlestickSeries>
34 #include <QtCharts/QCandlestickSet>
35 #include <QtQml/QQmlParserStatus>
36 #include <QtQuick/QQuickItem>
37
38 QT_CHARTS_BEGIN_NAMESPACE
39
40 class DeclarativeAxes;
41 class QAbstractAxis;
42
43 class DeclarativeCandlestickSet : public QCandlestickSet
44 {
45 Q_OBJECT
46 Q_PROPERTY(QString brushFilename READ brushFilename WRITE setBrushFilename NOTIFY brushFilenameChanged)
47
48 public:
49 explicit DeclarativeCandlestickSet(qreal timestamp = 0.0, QObject *parent = nullptr);
50 void setBrushFilename(const QString &brushFilename);
51 QString brushFilename() const;
52
53 Q_SIGNALS:
54 void brushFilenameChanged(const QString &brushFilename);
55
56 private Q_SLOTS:
57 void handleBrushChanged();
58
59 private:
60 QString m_brushFilename;
61 QImage m_brushImage;
62 };
63
64 class DeclarativeCandlestickSeries : public QCandlestickSeries, public QQmlParserStatus
65 {
66 Q_OBJECT
67 Q_INTERFACES(QQmlParserStatus)
68 Q_PROPERTY(QAbstractAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
69 Q_PROPERTY(QAbstractAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
70 Q_PROPERTY(QAbstractAxis *axisXTop READ axisXTop WRITE setAxisXTop NOTIFY axisXTopChanged)
71 Q_PROPERTY(QAbstractAxis *axisYRight READ axisYRight WRITE setAxisYRight NOTIFY axisYRightChanged)
72 Q_PROPERTY(QQmlListProperty<QObject> seriesChildren READ seriesChildren)
73 Q_PROPERTY(QString brushFilename READ brushFilename WRITE setBrushFilename NOTIFY brushFilenameChanged)
74 Q_CLASSINFO("DefaultProperty", "seriesChildren")
75
76 public:
77 explicit DeclarativeCandlestickSeries(QQuickItem *parent = nullptr);
78 void setAxisX(QAbstractAxis *axis) { m_axes->setAxisX(axis); }
79 QAbstractAxis *axisX() { return m_axes->axisX(); }
80 void setAxisY(QAbstractAxis *axis) { m_axes->setAxisY(axis); }
81 QAbstractAxis *axisY() { return m_axes->axisY(); }
82 void setAxisXTop(QAbstractAxis *axis) { m_axes->setAxisXTop(axis); }
83 QAbstractAxis *axisXTop() { return m_axes->axisXTop(); }
84 void setAxisYRight(QAbstractAxis *axis) { m_axes->setAxisYRight(axis); }
85 QAbstractAxis *axisYRight() { return m_axes->axisYRight(); }
86 QQmlListProperty<QObject> seriesChildren();
87 void setBrushFilename(const QString &brushFilename);
88 QString brushFilename() const;
89
90 public:
91 Q_INVOKABLE DeclarativeCandlestickSet *at(int index);
92 Q_INVOKABLE bool append(DeclarativeCandlestickSet *set);
93 Q_INVOKABLE bool remove(DeclarativeCandlestickSet *set);
94 Q_INVOKABLE bool append(qreal open, qreal high, qreal low, qreal close, qreal timestamp);
95 Q_INVOKABLE bool remove(qreal timestamp);
96 Q_INVOKABLE bool insert(int index, DeclarativeCandlestickSet *set);
97 Q_INVOKABLE void clear();
98
99 public: // from QDeclarativeParserStatus
100 void classBegin();
101 void componentComplete();
102
103 Q_SIGNALS:
104 void axisXChanged(QAbstractAxis *axis);
105 void axisYChanged(QAbstractAxis *axis);
106 void axisXTopChanged(QAbstractAxis *axis);
107 void axisYRightChanged(QAbstractAxis *axis);
108 void clicked(DeclarativeCandlestickSet *set);
109 void hovered(bool status, DeclarativeCandlestickSet *set);
110 void pressed(DeclarativeCandlestickSet *set);
111 void released(DeclarativeCandlestickSet *set);
112 void doubleClicked(DeclarativeCandlestickSet *set);
113 void brushFilenameChanged(const QString &brushFilename);
114
115 public Q_SLOTS:
116 static void appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element);
117 void onClicked(QCandlestickSet *set);
118 void onHovered(bool status, QCandlestickSet *set);
119 void onPressed(QCandlestickSet *set);
120 void onReleased(QCandlestickSet *set);
121 void onDoubleClicked(QCandlestickSet *set);
122
123 private Q_SLOTS:
124 void handleBrushChanged();
125
126 public:
127 DeclarativeAxes *m_axes;
128
129 private:
130 QString m_brushFilename;
131 QImage m_brushImage;
132 };
133
134 QT_CHARTS_END_NAMESPACE
135
136 #endif // DECLARATIVECANDLESTICKSERIES_H
@@ -0,0 +1,5
1 !include( ../auto.pri ) {
2 error( "Couldn't find the auto.pri file!" )
3 }
4
5 SOURCES += tst_qcandlestickmodelmapper.cpp
This diff has been collapsed as it changes many lines, (632 lines changed) Show them Hide them
@@ -0,0 +1,632
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 <QtCharts/QCandlestickSeries>
31 #include <QtCharts/QCandlestickSet>
32 #include <QtCharts/QChartView>
33 #include <QtCharts/QHCandlestickModelMapper>
34 #include <QtCharts/QVCandlestickModelMapper>
35 #include <QtCore/QString>
36 #include <QtGui/QStandardItemModel>
37 #include <QtTest/QtTest>
38
39 QT_CHARTS_USE_NAMESPACE
40
41 class tst_qcandlestickmodelmapper : public QObject
42 {
43 Q_OBJECT
44
45 public:
46 tst_qcandlestickmodelmapper();
47
48 void createVerticalMapper();
49 void createHorizontalMapper();
50
51 public Q_SLOTS:
52 void initTestCase();
53 void cleanupTestCase();
54 void init();
55 void cleanup();
56
57 private Q_SLOTS:
58 void verticalMapper_data();
59 void verticalMapper();
60 void verticalMapperCustomMapping_data();
61 void verticalMapperCustomMapping();
62 void horizontalMapper_data();
63 void horizontalMapper();
64 void horizontalMapperCustomMapping_data();
65 void horizontalMapperCustomMapping();
66 void seriesUpdated();
67 void verticalModelInsertRows();
68 void verticalModelRemoveRows();
69 void verticalModelInsertColumns();
70 void verticalModelRemoveColumns();
71 void horizontalModelInsertRows();
72 void horizontalModelRemoveRows();
73 void horizontalModelInsertColumns();
74 void horizontalModelRemoveColumns();
75 void modelUpdateCell();
76 void verticalMapperSignals();
77 void horizontalMapperSignals();
78
79 private:
80 QStandardItemModel *m_model;
81 int m_modelRowCount;
82 int m_modelColumnCount;
83
84 QCandlestickSeries *m_series;
85 QChart *m_chart;
86 QChartView *m_chartView;
87
88 QHCandlestickModelMapper *m_hMapper;
89 QVCandlestickModelMapper *m_vMapper;
90 };
91
92 tst_qcandlestickmodelmapper::tst_qcandlestickmodelmapper()
93 : m_model(nullptr),
94 m_modelRowCount(10),
95 m_modelColumnCount(8),
96 m_series(nullptr),
97 m_chart(nullptr),
98 m_chartView(nullptr),
99 m_hMapper(nullptr),
100 m_vMapper(nullptr)
101 {
102 }
103
104 void tst_qcandlestickmodelmapper::createHorizontalMapper()
105 {
106 m_hMapper = new QHCandlestickModelMapper;
107 QVERIFY(m_hMapper->model() == nullptr);
108 m_hMapper->setTimestampColumn(0);
109 m_hMapper->setOpenColumn(1);
110 m_hMapper->setHighColumn(3);
111 m_hMapper->setLowColumn(5);
112 m_hMapper->setCloseColumn(6);
113 m_hMapper->setFirstCandlestickSetRow(0);
114 m_hMapper->setLastCandlestickSetRow(4);
115 m_hMapper->setModel(m_model);
116 m_hMapper->setSeries(m_series);
117 }
118
119 void tst_qcandlestickmodelmapper::createVerticalMapper()
120 {
121 m_vMapper = new QVCandlestickModelMapper;
122 QVERIFY(m_vMapper->model() == nullptr);
123 m_vMapper->setTimestampRow(0);
124 m_vMapper->setOpenRow(1);
125 m_vMapper->setHighRow(3);
126 m_vMapper->setLowRow(5);
127 m_vMapper->setCloseRow(6);
128 m_vMapper->setFirstCandlestickSetColumn(0);
129 m_vMapper->setLastCandlestickSetColumn(4);
130 m_vMapper->setModel(m_model);
131 m_vMapper->setSeries(m_series);
132 }
133
134 void tst_qcandlestickmodelmapper::initTestCase()
135 {
136 m_chart = new QChart();
137 m_chartView = new QChartView(m_chart);
138 m_chartView->show();
139 }
140
141 void tst_qcandlestickmodelmapper::cleanupTestCase()
142 {
143 delete m_chartView;
144 QTest::qWait(1); // Allow final deleteLaters to run
145 }
146
147 void tst_qcandlestickmodelmapper::init()
148 {
149 m_series = new QCandlestickSeries();
150 m_chart->addSeries(m_series);
151
152 m_model = new QStandardItemModel(m_modelRowCount, m_modelColumnCount, this);
153 for (int row = 0; row < m_modelRowCount; ++row) {
154 for (int column = 0; column < m_modelColumnCount; ++column)
155 m_model->setData(m_model->index(row, column), row * column);
156 }
157 }
158
159 void tst_qcandlestickmodelmapper::cleanup()
160 {
161 m_chart->removeSeries(m_series);
162 delete m_series;
163 m_series = nullptr;
164
165 m_model->clear();
166 m_model->deleteLater();
167 m_model = nullptr;
168
169 if (m_vMapper) {
170 m_vMapper->deleteLater();
171 m_vMapper = nullptr;
172 }
173
174 if (m_hMapper) {
175 m_hMapper->deleteLater();
176 m_hMapper = nullptr;
177 }
178 }
179
180 void tst_qcandlestickmodelmapper::verticalMapper_data()
181 {
182 QTest::addColumn<int>("firstCandlestickSetColumn");
183 QTest::addColumn<int>("lastCandlestickSetColumn");
184 QTest::addColumn<int>("expectedCandlestickSetCount");
185
186 QTest::newRow("last column greater than first column") << 0 << 1 << 2;
187 QTest::newRow("last column equal to first column") << 1 << 1 << 1;
188 QTest::newRow("last column lesser than first column") << 1 << 0 << 0;
189 QTest::newRow("invalid first column and correct last column") << -3 << 1 << 0;
190 QTest::newRow("first column beyond the size of model and correct last column") << m_modelColumnCount << 1 << 0;
191 QTest::newRow("first column beyond the size of model and invalid last column") << m_modelColumnCount << -1 << 0;
192 }
193
194 void tst_qcandlestickmodelmapper::verticalMapper()
195 {
196 QFETCH(int, firstCandlestickSetColumn);
197 QFETCH(int, lastCandlestickSetColumn);
198 QFETCH(int, expectedCandlestickSetCount);
199
200 QCandlestickSeries *series = new QCandlestickSeries();
201 m_chart->addSeries(series);
202
203 createVerticalMapper();
204 m_vMapper->setFirstCandlestickSetColumn(firstCandlestickSetColumn);
205 m_vMapper->setLastCandlestickSetColumn(lastCandlestickSetColumn);
206 m_vMapper->setSeries(series);
207
208 QCOMPARE(m_vMapper->firstCandlestickSetColumn(), qMax(firstCandlestickSetColumn, -1));
209 QCOMPARE(m_vMapper->lastCandlestickSetColumn(), qMax(lastCandlestickSetColumn, -1));
210 QCOMPARE(series->count(), expectedCandlestickSetCount);
211
212 m_chart->removeSeries(series);
213 delete series;
214 }
215
216 void tst_qcandlestickmodelmapper::verticalMapperCustomMapping_data()
217 {
218 QTest::addColumn<int>("timestampRow");
219 QTest::addColumn<int>("openRow");
220 QTest::addColumn<int>("highRow");
221 QTest::addColumn<int>("lowRow");
222 QTest::addColumn<int>("closeRow");
223
224 QTest::newRow("all rows are correct") << 0 << 1 << 2 << 3 << 4;
225 QTest::newRow("all rows are invalid") << -3 << -3 << -3 << -3 << -3;
226 QTest::newRow("timestamp: -1 (invalid)") << -1 << 1 << 2 << 3 << 4;
227 QTest::newRow("timestamp: -3 (invalid - should default to -1)") << -3 << 1 << 2 << 3 << 4;
228 QTest::newRow("timestamp: +1 greater than the number of rows in the model") << m_modelRowCount + 1 << 1 << 2 << 3 << 4;
229 QTest::newRow("open: -1 (invalid)") << 0 << -1 << 2 << 3 << 4;
230 QTest::newRow("open: -3 (invalid - should default to -1)") << 0 << -3 << 2 << 3 << 4;
231 QTest::newRow("open: +1 greater than the number of rows in the model") << 0 << m_modelRowCount + 1 << 2 << 3 << 4;
232 QTest::newRow("high: -1 (invalid)") << 0 << 1 << -1 << 3 << 4;
233 QTest::newRow("high: -3 (invalid - should default to -1)") << 0 << 1 << -3 << 3 << 4;
234 QTest::newRow("high: +1 greater than the number of rows in the model") << 0 << 1 << m_modelRowCount + 1 << 3 << 4;
235 QTest::newRow("low: -1 (invalid)") << 0 << 1 << 2 << -1 << 4;
236 QTest::newRow("low: -3 (invalid - should default to -1)") << 0 << 1 << 2 << -3 << 4;
237 QTest::newRow("low: +1 greater than the number of rows in the model") << 0 << 1 << 2 << m_modelRowCount + 1 << 4;
238 QTest::newRow("close: -1 (invalid)") << 0 << 1 << 2 << 3 << -1;
239 QTest::newRow("close: -3 (invalid - should default to -1)") << 0 << 1 << 2 << 3 << -3;
240 QTest::newRow("close: +1 greater than the number of rows in the model") << 0 << 1 << 2 << 3 << m_modelRowCount + 1;
241 }
242
243 void tst_qcandlestickmodelmapper::verticalMapperCustomMapping()
244 {
245 QFETCH(int, timestampRow);
246 QFETCH(int, openRow);
247 QFETCH(int, highRow);
248 QFETCH(int, lowRow);
249 QFETCH(int, closeRow);
250
251 QCandlestickSeries *series = new QCandlestickSeries();
252 m_chart->addSeries(series);
253 QCOMPARE(series->count(), 0);
254
255 createVerticalMapper();
256 m_vMapper->setTimestampRow(timestampRow);
257 m_vMapper->setOpenRow(openRow);
258 m_vMapper->setHighRow(highRow);
259 m_vMapper->setLowRow(lowRow);
260 m_vMapper->setCloseRow(closeRow);
261 m_vMapper->setSeries(series);
262
263 QCOMPARE(m_vMapper->timestampRow(), qMax(timestampRow, -1));
264 QCOMPARE(m_vMapper->openRow(), qMax(openRow, -1));
265 QCOMPARE(m_vMapper->highRow(), qMax(highRow, -1));
266 QCOMPARE(m_vMapper->lowRow(), qMax(lowRow, -1));
267 QCOMPARE(m_vMapper->closeRow(), qMax(closeRow, -1));
268
269 int count;
270 if ((m_vMapper->timestampRow() >= 0 && m_vMapper->timestampRow() < m_modelRowCount)
271 && (m_vMapper->openRow() >= 0 && m_vMapper->openRow() < m_modelRowCount)
272 && (m_vMapper->highRow() >= 0 && m_vMapper->highRow() < m_modelRowCount)
273 && (m_vMapper->lowRow() >= 0 && m_vMapper->lowRow() < m_modelRowCount)
274 && (m_vMapper->closeRow() >= 0 && m_vMapper->closeRow() < m_modelRowCount))
275 count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
276 else
277 count = 0;
278 QCOMPARE(series->count(), count);
279
280 // change values column mapping to invalid
281 m_vMapper->setFirstCandlestickSetColumn(-1);
282 m_vMapper->setLastCandlestickSetColumn(1);
283 QCOMPARE(series->count(), 0);
284
285 m_chart->removeSeries(series);
286 delete series;
287 }
288
289 void tst_qcandlestickmodelmapper::horizontalMapper_data()
290 {
291 QTest::addColumn<int>("firstCandlestickSetRow");
292 QTest::addColumn<int>("lastCandlestickSetRow");
293 QTest::addColumn<int>("expectedCandlestickSetCount");
294
295 QTest::newRow("last row greater than first row") << 0 << 1 << 2;
296 QTest::newRow("last row equal to first row") << 1 << 1 << 1;
297 QTest::newRow("last row lesser than first row") << 1 << 0 << 0;
298 QTest::newRow("invalid first row and correct last row") << -3 << 1 << 0;
299 QTest::newRow("first row beyond the size of model and correct last row") << m_modelRowCount << 1 << 0;
300 QTest::newRow("first row beyond the size of model and invalid last row") << m_modelRowCount << -1 << 0;
301 }
302
303 void tst_qcandlestickmodelmapper::horizontalMapper()
304 {
305 QFETCH(int, firstCandlestickSetRow);
306 QFETCH(int, lastCandlestickSetRow);
307 QFETCH(int, expectedCandlestickSetCount);
308
309 QCandlestickSeries *series = new QCandlestickSeries();
310 m_chart->addSeries(series);
311
312 createHorizontalMapper();
313 m_hMapper->setFirstCandlestickSetRow(firstCandlestickSetRow);
314 m_hMapper->setLastCandlestickSetRow(lastCandlestickSetRow);
315 m_hMapper->setSeries(series);
316
317 QCOMPARE(m_hMapper->firstCandlestickSetRow(), qMax(firstCandlestickSetRow, -1));
318 QCOMPARE(m_hMapper->lastCandlestickSetRow(), qMax(lastCandlestickSetRow, -1));
319 QCOMPARE(series->count(), expectedCandlestickSetCount);
320
321 m_chart->removeSeries(series);
322 delete series;
323 }
324
325 void tst_qcandlestickmodelmapper::horizontalMapperCustomMapping_data()
326 {
327 QTest::addColumn<int>("timestampColumn");
328 QTest::addColumn<int>("openColumn");
329 QTest::addColumn<int>("highColumn");
330 QTest::addColumn<int>("lowColumn");
331 QTest::addColumn<int>("closeColumn");
332
333 QTest::newRow("all columns are correct") << 0 << 1 << 2 << 3 << 4;
334 QTest::newRow("all columns are invalid") << -3 << -3 << -3 << -3 << -3;
335 QTest::newRow("timestamp: -1 (invalid)") << -1 << 1 << 2 << 3 << 4;
336 QTest::newRow("timestamp: -3 (invalid - should default to -1)") << -3 << 1 << 2 << 3 << 4;
337 QTest::newRow("timestamp: +1 greater than the number of columns in the model") << m_modelColumnCount + 1 << 1 << 2 << 3 << 4;
338 QTest::newRow("open: -1 (invalid)") << 0 << -1 << 2 << 3 << 4;
339 QTest::newRow("open: -3 (invalid - should default to -1)") << 0 << -3 << 2 << 3 << 4;
340 QTest::newRow("open: +1 greater than the number of columns in the model") << 0 << m_modelColumnCount + 1 << 2 << 3 << 4;
341 QTest::newRow("high: -1 (invalid)") << 0 << 1 << -1 << 3 << 4;
342 QTest::newRow("high: -3 (invalid - should default to -1)") << 0 << 1 << -3 << 3 << 4;
343 QTest::newRow("high: +1 greater than the number of columns in the model") << 0 << 1 << m_modelColumnCount + 1 << 3 << 4;
344 QTest::newRow("low: -1 (invalid)") << 0 << 1 << 2 << -1 << 4;
345 QTest::newRow("low: -3 (invalid - should default to -1)") << 0 << 1 << 2 << -3 << 4;
346 QTest::newRow("low: +1 greater than the number of columns in the model") << 0 << 1 << 2 << m_modelColumnCount + 1 << 4;
347 QTest::newRow("close: -1 (invalid)") << 0 << 1 << 2 << 3 << -1;
348 QTest::newRow("close: -3 (invalid - should default to -1)") << 0 << 1 << 2 << 3 << -3;
349 QTest::newRow("close: +1 greater than the number of columns in the model") << 0 << 1 << 2 << 3 << m_modelColumnCount + 1;
350 }
351
352 void tst_qcandlestickmodelmapper::horizontalMapperCustomMapping()
353 {
354 QFETCH(int, timestampColumn);
355 QFETCH(int, openColumn);
356 QFETCH(int, highColumn);
357 QFETCH(int, lowColumn);
358 QFETCH(int, closeColumn);
359
360 QCandlestickSeries *series = new QCandlestickSeries();
361 m_chart->addSeries(series);
362 QCOMPARE(series->count(), 0);
363
364 createHorizontalMapper();
365 m_hMapper->setTimestampColumn(timestampColumn);
366 m_hMapper->setOpenColumn(openColumn);
367 m_hMapper->setHighColumn(highColumn);
368 m_hMapper->setLowColumn(lowColumn);
369 m_hMapper->setCloseColumn(closeColumn);
370 m_hMapper->setSeries(series);
371
372 QCOMPARE(m_hMapper->timestampColumn(), qMax(timestampColumn, -1));
373 QCOMPARE(m_hMapper->openColumn(), qMax(openColumn, -1));
374 QCOMPARE(m_hMapper->highColumn(), qMax(highColumn, -1));
375 QCOMPARE(m_hMapper->lowColumn(), qMax(lowColumn, -1));
376 QCOMPARE(m_hMapper->closeColumn(), qMax(closeColumn, -1));
377
378 int count;
379 if ((m_hMapper->timestampColumn() >= 0 && m_hMapper->timestampColumn() < m_modelColumnCount)
380 && (m_hMapper->openColumn() >= 0 && m_hMapper->openColumn() < m_modelColumnCount)
381 && (m_hMapper->highColumn() >= 0 && m_hMapper->highColumn() < m_modelColumnCount)
382 && (m_hMapper->lowColumn() >= 0 && m_hMapper->lowColumn() < m_modelColumnCount)
383 && (m_hMapper->closeColumn() >= 0 && m_hMapper->closeColumn() < m_modelColumnCount))
384 count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
385 else
386 count = 0;
387 QCOMPARE(series->count(), count);
388
389 // change values row mapping to invalid
390 m_hMapper->setFirstCandlestickSetRow(-1);
391 m_hMapper->setLastCandlestickSetRow(1);
392 QCOMPARE(series->count(), 0);
393
394 m_chart->removeSeries(series);
395 delete series;
396 }
397
398 void tst_qcandlestickmodelmapper::seriesUpdated()
399 {
400 createVerticalMapper();
401 QVERIFY(m_vMapper->model() != nullptr);
402
403 QCandlestickSet *set = m_series->candlestickSets().value(0, 0);
404 QVERIFY(set != nullptr);
405
406 // update values
407 QCOMPARE(m_model->data(m_model->index(m_vMapper->timestampRow(), 0)).toReal(),set->timestamp());
408 QCOMPARE(m_model->data(m_model->index(m_vMapper->openRow(), 0)).toReal(), set->open());
409 QCOMPARE(m_model->data(m_model->index(m_vMapper->highRow(), 0)).toReal(), set->high());
410 QCOMPARE(m_model->data(m_model->index(m_vMapper->lowRow(), 0)).toReal(), set->low());
411 QCOMPARE(m_model->data(m_model->index(m_vMapper->closeRow(), 0)).toReal(), set->close());
412 set->setTimestamp(set->timestamp() + 5.0);
413 set->setOpen(set->open() + 6.0);
414 set->setHigh(set->high() + 7.0);
415 set->setLow(set->low() + 8.0);
416 set->setClose(set->close() + 9.0);
417 QCOMPARE(m_model->data(m_model->index(m_vMapper->timestampRow(), 0)).toReal(),set->timestamp());
418 QCOMPARE(m_model->data(m_model->index(m_vMapper->openRow(), 0)).toReal(), set->open());
419 QCOMPARE(m_model->data(m_model->index(m_vMapper->highRow(), 0)).toReal(), set->high());
420 QCOMPARE(m_model->data(m_model->index(m_vMapper->lowRow(), 0)).toReal(), set->low());
421 QCOMPARE(m_model->data(m_model->index(m_vMapper->closeRow(), 0)).toReal(), set->close());
422
423 // append new sets
424 QList<QCandlestickSet *> newCandlestickSets;
425 newCandlestickSets << new QCandlestickSet(3.0, 5.0, 2.0, 4.0, 1234);
426 newCandlestickSets << new QCandlestickSet(5.0, 7.0, 4.0, 6.0, 5678);
427 m_series->append(newCandlestickSets);
428 QCOMPARE(m_model->columnCount(), m_modelColumnCount + newCandlestickSets.count());
429
430 // remove sets
431 newCandlestickSets.clear();
432 newCandlestickSets << m_series->candlestickSets().at(m_series->count() - 1);
433 newCandlestickSets << m_series->candlestickSets().at(m_series->count() - 2);
434 m_series->remove(newCandlestickSets);
435 QCOMPARE(m_model->columnCount(), m_modelColumnCount);
436 }
437
438 void tst_qcandlestickmodelmapper::verticalModelInsertRows()
439 {
440 createVerticalMapper();
441 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
442 QVERIFY(m_vMapper->model() != 0);
443 QCOMPARE(m_series->count(), count);
444
445 m_model->insertRows(3, 4);
446 QCOMPARE(m_series->count(), count);
447 }
448
449 void tst_qcandlestickmodelmapper::verticalModelRemoveRows()
450 {
451 createVerticalMapper();
452 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
453 QVERIFY(m_vMapper->model() != 0);
454 QCOMPARE(m_series->count(), count);
455
456 m_model->removeRows(m_modelRowCount - 1, 1);
457 QCOMPARE(m_series->count(), count);
458
459 int removeCount = m_model->rowCount() - m_vMapper->closeRow();
460 m_model->removeRows(m_vMapper->closeRow(), removeCount);
461 QCOMPARE(m_series->count(), 0);
462 }
463
464 void tst_qcandlestickmodelmapper::verticalModelInsertColumns()
465 {
466 createVerticalMapper();
467 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
468 QVERIFY(m_vMapper->model() != 0);
469 QCOMPARE(m_series->count(), count);
470
471 m_model->insertColumns(3, 4);
472 QCOMPARE(m_series->count(), count);
473 }
474
475 void tst_qcandlestickmodelmapper::verticalModelRemoveColumns()
476 {
477 createVerticalMapper();
478 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
479 QVERIFY(m_vMapper->model() != 0);
480 QCOMPARE(m_series->count(), count);
481
482 int removeCount = m_modelColumnCount - 2;
483 m_model->removeColumns(0, removeCount);
484 QCOMPARE(m_series->count(), qMin(m_model->columnCount(), count));
485
486 // leave all the columns
487 m_model->removeColumns(0, m_modelColumnCount - removeCount);
488 QCOMPARE(m_series->count(), 0);
489 }
490
491 void tst_qcandlestickmodelmapper::horizontalModelInsertRows()
492 {
493 createHorizontalMapper();
494 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
495 QVERIFY(m_hMapper->model() != 0);
496 QCOMPARE(m_series->count(), count);
497
498 m_model->insertRows(3, 4);
499 QCOMPARE(m_series->count(), count);
500 }
501
502 void tst_qcandlestickmodelmapper::horizontalModelRemoveRows()
503 {
504 createHorizontalMapper();
505 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
506 QVERIFY(m_hMapper->model() != 0);
507 QCOMPARE(m_series->count(), qMin(m_model->rowCount(), count));
508
509 int removeCount = m_modelRowCount - 2;
510 m_model->removeRows(0, removeCount);
511 QCOMPARE(m_series->count(), qMin(m_model->rowCount(), count));
512
513 // leave all the columns
514 m_model->removeRows(0, m_modelRowCount - removeCount);
515 QCOMPARE(m_series->count(), 0);
516 }
517
518 void tst_qcandlestickmodelmapper::horizontalModelInsertColumns()
519 {
520 createHorizontalMapper();
521 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
522 QVERIFY(m_hMapper->model() != 0);
523 QCOMPARE(m_series->count(), count);
524
525 m_model->insertColumns(3, 4);
526 QCOMPARE(m_series->count(), count);
527 }
528
529 void tst_qcandlestickmodelmapper::horizontalModelRemoveColumns()
530 {
531 createHorizontalMapper();
532 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
533 QVERIFY(m_hMapper->model() != 0);
534 QCOMPARE(m_series->count(), count);
535
536 m_model->removeColumns(m_modelColumnCount - 1, 1);
537 QCOMPARE(m_series->count(), count);
538
539 int removeCount = m_model->columnCount() - m_hMapper->closeColumn();
540 m_model->removeColumns(m_hMapper->closeColumn(), removeCount);
541 QCOMPARE(m_series->count(), 0);
542 }
543
544 void tst_qcandlestickmodelmapper::modelUpdateCell()
545 {
546 createVerticalMapper();
547 QVERIFY(m_vMapper->model() != 0);
548
549 QModelIndex index = m_model->index(m_vMapper->timestampRow(), 0);
550 qreal newValue = 44.0;
551 QVERIFY(m_model->setData(index, newValue));
552 QCOMPARE(m_model->data(index).toReal(), newValue);
553 QCOMPARE(m_series->candlestickSets().at(index.row())->timestamp(), newValue);
554 }
555
556 void tst_qcandlestickmodelmapper::verticalMapperSignals()
557 {
558 QVCandlestickModelMapper *mapper = new QVCandlestickModelMapper();
559
560 QSignalSpy spy0(mapper, SIGNAL(modelReplaced()));
561 QSignalSpy spy1(mapper, SIGNAL(seriesReplaced()));
562 QSignalSpy spy2(mapper, SIGNAL(timestampRowChanged()));
563 QSignalSpy spy3(mapper, SIGNAL(openRowChanged()));
564 QSignalSpy spy4(mapper, SIGNAL(highRowChanged()));
565 QSignalSpy spy5(mapper, SIGNAL(lowRowChanged()));
566 QSignalSpy spy6(mapper, SIGNAL(closeRowChanged()));
567 QSignalSpy spy7(mapper, SIGNAL(firstCandlestickSetColumnChanged()));
568 QSignalSpy spy8(mapper, SIGNAL(lastCandlestickSetColumnChanged()));
569
570 mapper->setModel(m_model);
571 mapper->setSeries(m_series);
572 mapper->setTimestampRow(1);
573 mapper->setOpenRow(2);
574 mapper->setHighRow(3);
575 mapper->setLowRow(4);
576 mapper->setCloseRow(5);
577 mapper->setFirstCandlestickSetColumn(0);
578 mapper->setLastCandlestickSetColumn(1);
579
580 QCOMPARE(spy0.count(), 1);
581 QCOMPARE(spy1.count(), 1);
582 QCOMPARE(spy2.count(), 1);
583 QCOMPARE(spy3.count(), 1);
584 QCOMPARE(spy4.count(), 1);
585 QCOMPARE(spy5.count(), 1);
586 QCOMPARE(spy6.count(), 1);
587 QCOMPARE(spy7.count(), 1);
588 QCOMPARE(spy8.count(), 1);
589
590 delete mapper;
591 }
592
593 void tst_qcandlestickmodelmapper::horizontalMapperSignals()
594 {
595 QHCandlestickModelMapper *mapper = new QHCandlestickModelMapper();
596
597 QSignalSpy spy0(mapper, SIGNAL(modelReplaced()));
598 QSignalSpy spy1(mapper, SIGNAL(seriesReplaced()));
599 QSignalSpy spy2(mapper, SIGNAL(timestampColumnChanged()));
600 QSignalSpy spy3(mapper, SIGNAL(openColumnChanged()));
601 QSignalSpy spy4(mapper, SIGNAL(highColumnChanged()));
602 QSignalSpy spy5(mapper, SIGNAL(lowColumnChanged()));
603 QSignalSpy spy6(mapper, SIGNAL(closeColumnChanged()));
604 QSignalSpy spy7(mapper, SIGNAL(firstCandlestickSetRowChanged()));
605 QSignalSpy spy8(mapper, SIGNAL(lastCandlestickSetRowChanged()));
606
607 mapper->setModel(m_model);
608 mapper->setSeries(m_series);
609 mapper->setTimestampColumn(1);
610 mapper->setOpenColumn(2);
611 mapper->setHighColumn(3);
612 mapper->setLowColumn(4);
613 mapper->setCloseColumn(5);
614 mapper->setFirstCandlestickSetRow(0);
615 mapper->setLastCandlestickSetRow(1);
616
617 QCOMPARE(spy0.count(), 1);
618 QCOMPARE(spy1.count(), 1);
619 QCOMPARE(spy2.count(), 1);
620 QCOMPARE(spy3.count(), 1);
621 QCOMPARE(spy4.count(), 1);
622 QCOMPARE(spy5.count(), 1);
623 QCOMPARE(spy6.count(), 1);
624 QCOMPARE(spy7.count(), 1);
625 QCOMPARE(spy8.count(), 1);
626
627 delete mapper;
628 }
629
630 QTEST_MAIN(tst_qcandlestickmodelmapper)
631
632 #include "tst_qcandlestickmodelmapper.moc"
@@ -0,0 +1,5
1 !include( ../auto.pri ) {
2 error( "Couldn't find the auto.pri file!" )
3 }
4
5 SOURCES += tst_qcandlestickseries.cpp
This diff has been collapsed as it changes many lines, (936 lines changed) Show them Hide them
@@ -0,0 +1,936
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 <QtCharts/QCandlestickSeries>
31 #include <QtCharts/QCandlestickSet>
32 #include <QtCharts/QChartView>
33 #include <QtTest/QtTest>
34 #include "tst_definitions.h"
35
36 QT_CHARTS_USE_NAMESPACE
37
38 Q_DECLARE_METATYPE(QCandlestickSet *)
39 Q_DECLARE_METATYPE(QList<QCandlestickSet *>)
40
41 class tst_QCandlestickSeries : public QObject
42 {
43 Q_OBJECT
44
45 public Q_SLOTS:
46 void initTestCase();
47 void cleanupTestCase();
48 void init();
49 void cleanup();
50
51 private Q_SLOTS:
52 void qCandlestickSeries();
53 void append();
54 void remove();
55 void appendList();
56 void removeList();
57 void insert();
58 void take();
59 void clear();
60 void candlestickSets();
61 void count();
62 void type();
63 void maximumColumnWidth_data();
64 void maximumColumnWidth();
65 void minimumColumnWidth_data();
66 void minimumColumnWidth();
67 void bodyWidth_data();
68 void bodyWidth();
69 void bodyOutlineVisible();
70 void capsWidth_data();
71 void capsWidth();
72 void capsVisible();
73 void increasingColor();
74 void decreasingColor();
75 void brush();
76 void pen();
77 void mouseClicked();
78 void mouseHovered();
79 void mousePressed();
80 void mouseReleased();
81 void mouseDoubleClicked();
82
83 private:
84 QCandlestickSeries *m_series;
85 QList<QCandlestickSet *> m_sets;
86 };
87
88 void tst_QCandlestickSeries::initTestCase()
89 {
90 qRegisterMetaType<QCandlestickSet *>("QCandlestickSet *");
91 qRegisterMetaType<QList<QCandlestickSet *>>("QList<QCandlestickSet *>");
92 }
93
94 void tst_QCandlestickSeries::cleanupTestCase()
95 {
96 QTest::qWait(1); // Allow final deleteLaters to run
97 }
98
99 void tst_QCandlestickSeries::init()
100 {
101 m_series = new QCandlestickSeries();
102 m_series->setMaximumColumnWidth(5432.1);
103 m_series->setMinimumColumnWidth(2.0);
104 m_series->setBodyWidth(0.99);
105 m_series->setCapsWidth(0.99);
106
107 for (int i = 0; i < 5; ++i) {
108 qreal timestamp = QDateTime::currentMSecsSinceEpoch() + i * 1000000;
109
110 QCandlestickSet *set = new QCandlestickSet(timestamp);
111 set->setOpen(4);
112 set->setHigh(4);
113 set->setLow(1);
114 set->setClose(1);
115
116 m_sets.append(set);
117 }
118 }
119
120 void tst_QCandlestickSeries::cleanup()
121 {
122 foreach (QCandlestickSet *set, m_sets) {
123 m_series->remove(set);
124 m_sets.removeAll(set);
125 delete set;
126 }
127
128 delete m_series;
129 m_series = nullptr;
130 }
131
132 void tst_QCandlestickSeries::qCandlestickSeries()
133 {
134 QCandlestickSeries *series = new QCandlestickSeries();
135
136 QVERIFY(series != nullptr);
137
138 delete series;
139 series = nullptr;
140 }
141
142 void tst_QCandlestickSeries::append()
143 {
144 QCOMPARE(m_series->count(), 0);
145
146 // Try adding set
147 QCandlestickSet *set1 = new QCandlestickSet(1234.0);
148 QVERIFY(m_series->append(set1));
149 QCOMPARE(m_series->count(), 1);
150
151 // Try adding another set
152 QCandlestickSet *set2 = new QCandlestickSet(2345.0);
153 QVERIFY(m_series->append(set2));
154 QCOMPARE(m_series->count(), 2);
155
156 // Try adding same set again
157 QVERIFY(!m_series->append(set2));
158 QCOMPARE(m_series->count(), 2);
159
160 // Try adding null set
161 QVERIFY(!m_series->append(nullptr));
162 QCOMPARE(m_series->count(), 2);
163 }
164
165 void tst_QCandlestickSeries::remove()
166 {
167 m_series->append(m_sets);
168 QCOMPARE(m_series->count(), m_sets.count());
169
170 // Try to remove null pointer (should not remove, should not crash)
171 QVERIFY(!m_series->remove(nullptr));
172 QCOMPARE(m_series->count(), m_sets.count());
173
174 // Try to remove invalid pointer (should not remove, should not crash)
175 QVERIFY(!m_series->remove((QCandlestickSet *)(m_sets.at(0) + 1)));
176 QCOMPARE(m_series->count(), m_sets.count());
177
178 // Remove some sets
179 const int removeCount = 3;
180 for (int i = 0; i < removeCount; ++i)
181 QVERIFY(m_series->remove(m_sets.at(i)));
182 QCOMPARE(m_series->count(), m_sets.count() - removeCount);
183
184 for (int i = removeCount; i < m_sets.count(); ++i)
185 QCOMPARE(m_series->candlestickSets().at(i - removeCount), m_sets.at(i));
186
187 // Try removing all sets again (should be ok, even if some sets have already been removed)
188 for (int i = 0; i < m_sets.count(); ++i)
189 m_series->remove(m_sets.at(i));
190 QCOMPARE(m_series->count(), 0);
191 }
192
193 void tst_QCandlestickSeries::appendList()
194 {
195 QCOMPARE(m_series->count(), 0);
196
197 // Append new sets (should succeed, count should match the count of sets)
198 QVERIFY(m_series->append(m_sets));
199 QCOMPARE(m_series->count(), m_series->count());
200
201 // Append same sets again (should fail, count should remain same)
202 QVERIFY(!m_series->append(m_sets));
203 QCOMPARE(m_series->count(), m_series->count());
204
205 // Try append empty list (should succeed, but count should remain same)
206 QList<QCandlestickSet *> invalidList;
207 QVERIFY(m_series->append(invalidList));
208 QCOMPARE(m_series->count(), m_sets.count());
209
210 // Try append list with one new and one existing set (should fail, count remains same)
211 invalidList.append(new QCandlestickSet());
212 invalidList.append(m_sets.at(0));
213 QVERIFY(!m_series->append(invalidList));
214 QCOMPARE(m_series->count(), m_sets.count());
215 delete invalidList.at(0);
216 invalidList.clear();
217
218 // Try append list with null pointers (should fail, count remains same)
219 QVERIFY(invalidList.isEmpty());
220 invalidList.append(nullptr);
221 invalidList.append(nullptr);
222 invalidList.append(nullptr);
223 QVERIFY(!m_series->append(invalidList));
224 QCOMPARE(m_series->count(), m_sets.count());
225 }
226
227 void tst_QCandlestickSeries::removeList()
228 {
229 m_series->append(m_sets);
230 QCOMPARE(m_series->count(), m_sets.count());
231
232 // Try remove empty list (should fail, but count should remain same)
233 QList<QCandlestickSet *> invalidList;
234 QVERIFY(!m_series->remove(invalidList));
235 QCOMPARE(m_series->count(), m_sets.count());
236
237 // Try remove list with one new and one existing set (should fail, count remains same)
238 invalidList.append(new QCandlestickSet());
239 invalidList.append(m_sets.at(0));
240 QVERIFY(!m_series->remove(invalidList));
241 QCOMPARE(m_series->count(), m_sets.count());
242 delete invalidList.at(0);
243 invalidList.clear();
244
245 // Try remove list with null pointers (should fail, count remains same)
246 QVERIFY(invalidList.isEmpty());
247 invalidList.append(nullptr);
248 invalidList.append(nullptr);
249 invalidList.append(nullptr);
250 QVERIFY(!m_series->remove(invalidList));
251 QCOMPARE(m_series->count(), m_sets.count());
252
253 // Remove all sets (should succeed, count should be zero)
254 QVERIFY(m_series->remove(m_sets));
255 QCOMPARE(m_series->count(), 0);
256
257 // Remove same sets again (should fail, count should remain zero)
258 QVERIFY(!m_series->remove(m_sets));
259 QCOMPARE(m_series->count(), 0);
260 }
261
262 void tst_QCandlestickSeries::insert()
263 {
264 QCOMPARE(m_series->count(), 0);
265
266 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
267 QSignalSpy addedSpy(m_series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)));
268
269 for (int i = 0; i < m_sets.count(); ++i) {
270 QCandlestickSet *set = m_sets.at(i);
271 QVERIFY(m_series->insert(0, set));
272 QCOMPARE(m_series->count(), i + 1);
273 QTRY_COMPARE(countSpy.count(), i + 1);
274 QTRY_COMPARE(addedSpy.count(), i + 1);
275
276 QList<QVariant> args = addedSpy.value(i);
277 QCOMPARE(args.count(), 1);
278 QList<QCandlestickSet *> sets = qvariant_cast<QList<QCandlestickSet *>>(args.at(0));
279 QCOMPARE(sets.count(), 1);
280 QCOMPARE(sets.first(), set);
281 }
282 }
283
284 void tst_QCandlestickSeries::take()
285 {
286 m_series->append(m_sets);
287 QCOMPARE(m_series->count(), m_sets.count());
288
289 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
290 QSignalSpy removedSpy(m_series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet *>)));
291
292 for (int i = 0; i < m_sets.count(); ++i) {
293 QCandlestickSet *set = m_sets.at(i);
294 QVERIFY(m_series->take(set));
295 QCOMPARE(m_series->count(), m_sets.count() - i - 1);
296 QTRY_COMPARE(countSpy.count(), i + 1);
297 QTRY_COMPARE(removedSpy.count(), i + 1);
298
299 QList<QVariant> args = removedSpy.value(i);
300 QCOMPARE(args.count(), 1);
301 QList<QCandlestickSet *> sets = qvariant_cast<QList<QCandlestickSet *>>(args.at(0));
302 QCOMPARE(sets.count(), 1);
303 QCOMPARE(sets.first(), set);
304 }
305 }
306
307 void tst_QCandlestickSeries::clear()
308 {
309 m_series->append(m_sets);
310 QCOMPARE(m_series->count(), m_sets.count());
311
312 m_series->clear();
313 QCOMPARE(m_series->count(), 0);
314 }
315
316 void tst_QCandlestickSeries::candlestickSets()
317 {
318 m_series->append(m_sets);
319 QCOMPARE(m_series->candlestickSets(), m_sets);
320
321 for (int i = 0; i < m_sets.count(); ++i)
322 QCOMPARE(m_series->candlestickSets().at(i), m_sets.at(i));
323
324 m_series->clear();
325 QCOMPARE(m_series->candlestickSets(), QList<QCandlestickSet *>());
326 }
327
328 void tst_QCandlestickSeries::count()
329 {
330 m_series->append(m_sets);
331 QCOMPARE(m_series->count(), m_sets.count());
332 QCOMPARE(m_series->count(), m_series->candlestickSets().count());
333 }
334
335 void tst_QCandlestickSeries::type()
336 {
337 QCOMPARE(m_series->type(), QAbstractSeries::SeriesTypeCandlestick);
338 }
339
340 void tst_QCandlestickSeries::maximumColumnWidth_data()
341 {
342 QTest::addColumn<qreal>("maximumColumnWidth");
343 QTest::addColumn<qreal>("expectedMaximumColumnWidth");
344
345 QTest::newRow("maximum column width less than -1.0") << -3.0 << -1.0;
346 QTest::newRow("maximum column equals to -1.0") << -1.0 << -1.0;
347 QTest::newRow("maximum column width greater than -1.0, but less than zero") << -0.5 << -1.0;
348 QTest::newRow("maximum column width equals zero") << 0.0 << 0.0;
349 QTest::newRow("maximum column width greater than zero") << 1.0 << 1.0;
350 QTest::newRow("maximum column width contains a fractional part") << 3.4 << 3.4;
351 }
352
353 void tst_QCandlestickSeries::maximumColumnWidth()
354 {
355 QFETCH(qreal, maximumColumnWidth);
356 QFETCH(qreal, expectedMaximumColumnWidth);
357
358 QSignalSpy spy(m_series, SIGNAL(maximumColumnWidthChanged()));
359
360 m_series->setMaximumColumnWidth(maximumColumnWidth);
361 QCOMPARE(m_series->maximumColumnWidth(), expectedMaximumColumnWidth);
362 QCOMPARE(spy.count(), 1);
363
364 // Try set same maximum column width
365 m_series->setMaximumColumnWidth(expectedMaximumColumnWidth);
366 QCOMPARE(m_series->maximumColumnWidth(), expectedMaximumColumnWidth);
367 QCOMPARE(spy.count(), 1);
368 }
369
370 void tst_QCandlestickSeries::minimumColumnWidth_data()
371 {
372 QTest::addColumn<qreal>("minimumColumnWidth");
373 QTest::addColumn<qreal>("expectedMinimumColumnWidth");
374
375 QTest::newRow("minimum column width less than -1.0") << -3.0 << -1.0;
376 QTest::newRow("minimum column equals to -1.0") << -1.0 << -1.0;
377 QTest::newRow("minimum column width greater than -1.0, but less than zero") << -0.5 << -1.0;
378 QTest::newRow("minimum column width equals zero") << 0.0 << 0.0;
379 QTest::newRow("minimum column width greater than zero") << 1.0 << 1.0;
380 QTest::newRow("minimum column width contains a fractional part") << 3.4 << 3.4;
381 }
382
383 void tst_QCandlestickSeries::minimumColumnWidth()
384 {
385 QFETCH(qreal, minimumColumnWidth);
386 QFETCH(qreal, expectedMinimumColumnWidth);
387
388 QSignalSpy spy(m_series, SIGNAL(minimumColumnWidthChanged()));
389
390 m_series->setMinimumColumnWidth(minimumColumnWidth);
391 QCOMPARE(m_series->minimumColumnWidth(), expectedMinimumColumnWidth);
392 QCOMPARE(spy.count(), 1);
393
394 // Try set same minimum column width
395 m_series->setMinimumColumnWidth(expectedMinimumColumnWidth);
396 QCOMPARE(m_series->minimumColumnWidth(), expectedMinimumColumnWidth);
397 QCOMPARE(spy.count(), 1);
398 }
399
400 void tst_QCandlestickSeries::bodyWidth_data()
401 {
402 QTest::addColumn<qreal>("bodyWidth");
403 QTest::addColumn<qreal>("expectedBodyWidth");
404
405 QTest::newRow("body width less than zero") << -1.0 << 0.0;
406 QTest::newRow("body width equals zero") << 0.0 << 0.0;
407 QTest::newRow("body width greater than zero and less than one") << 0.5 << 0.5;
408 QTest::newRow("body width equals one") << 1.0 << 1.0;
409 QTest::newRow("body width greater than one") << 2.0 << 1.0;
410 }
411
412 void tst_QCandlestickSeries::bodyWidth()
413 {
414 QFETCH(qreal, bodyWidth);
415 QFETCH(qreal, expectedBodyWidth);
416
417 QSignalSpy spy(m_series, SIGNAL(bodyWidthChanged()));
418
419 m_series->setBodyWidth(bodyWidth);
420 QCOMPARE(m_series->bodyWidth(), expectedBodyWidth);
421 QCOMPARE(spy.count(), 1);
422
423 // Try set same body width
424 m_series->setBodyWidth(bodyWidth);
425 QCOMPARE(m_series->bodyWidth(), expectedBodyWidth);
426 QCOMPARE(spy.count(), 1);
427 }
428
429 void tst_QCandlestickSeries::bodyOutlineVisible()
430 {
431 QSignalSpy spy(m_series, SIGNAL(bodyOutlineVisibilityChanged()));
432
433 bool visible = !m_series->bodyOutlineVisible();
434 m_series->setBodyOutlineVisible(visible);
435 QCOMPARE(m_series->bodyOutlineVisible(), visible);
436 QCOMPARE(spy.count(), 1);
437
438 // Try set same body outline visibility
439 m_series->setBodyOutlineVisible(visible);
440 QCOMPARE(m_series->bodyOutlineVisible(), visible);
441 QCOMPARE(spy.count(), 1);
442 }
443
444 void tst_QCandlestickSeries::capsWidth_data()
445 {
446 QTest::addColumn<qreal>("capsWidth");
447 QTest::addColumn<qreal>("expectedCapsWidth");
448
449 QTest::newRow("caps width less than zero") << -1.0 << 0.0;
450 QTest::newRow("caps width equals zero") << 0.0 << 0.0;
451 QTest::newRow("caps width greater than zero and less than one") << 0.5 << 0.5;
452 QTest::newRow("caps width equals one") << 1.0 << 1.0;
453 QTest::newRow("caps width greater than one") << 2.0 << 1.0;
454 }
455
456 void tst_QCandlestickSeries::capsWidth()
457 {
458 QFETCH(qreal, capsWidth);
459 QFETCH(qreal, expectedCapsWidth);
460
461 QSignalSpy spy(m_series, SIGNAL(capsWidthChanged()));
462
463 m_series->setCapsWidth(capsWidth);
464 QCOMPARE(m_series->capsWidth(), expectedCapsWidth);
465 QCOMPARE(spy.count(), 1);
466
467 // Try set same caps width
468 m_series->setCapsWidth(capsWidth);
469 QCOMPARE(m_series->capsWidth(), expectedCapsWidth);
470 QCOMPARE(spy.count(), 1);
471 }
472
473 void tst_QCandlestickSeries::capsVisible()
474 {
475 QSignalSpy spy(m_series, SIGNAL(capsVisibilityChanged()));
476
477 bool visible = !m_series->capsVisible();
478 m_series->setCapsVisible(visible);
479 QCOMPARE(m_series->capsVisible(), visible);
480 QCOMPARE(spy.count(), 1);
481
482 // Try set same caps visibility
483 m_series->setCapsVisible(visible);
484 QCOMPARE(m_series->capsVisible(), visible);
485 QCOMPARE(spy.count(), 1);
486 }
487
488 void tst_QCandlestickSeries::increasingColor()
489 {
490 QSignalSpy spy(m_series, SIGNAL(increasingColorChanged()));
491
492 // Try set new increasing color
493 QColor newColor(200, 200, 200, 200);
494 m_series->setIncreasingColor(newColor);
495 QCOMPARE(m_series->increasingColor(), newColor);
496 QCOMPARE(spy.count(), 1);
497
498 // Try set same increasing color again
499 m_series->setIncreasingColor(newColor);
500 QCOMPARE(m_series->increasingColor(), newColor);
501 QCOMPARE(spy.count(), 1);
502
503 // Try set invalid increasing color (should change to default color)
504 QColor defaultColor = m_series->brush().color();
505 defaultColor.setAlpha(128);
506 m_series->setIncreasingColor(QColor());
507 QCOMPARE(m_series->increasingColor(), defaultColor);
508 QCOMPARE(spy.count(), 2);
509
510 // Set new brush, increasing color should change accordingly
511 QBrush brush(newColor);
512 defaultColor = brush.color();
513 defaultColor.setAlpha(128);
514 m_series->setBrush(brush);
515 QCOMPARE(m_series->increasingColor(), defaultColor);
516 QCOMPARE(spy.count(), 3);
517 }
518
519 void tst_QCandlestickSeries::decreasingColor()
520 {
521 QSignalSpy spy(m_series, SIGNAL(decreasingColorChanged()));
522
523 // Try set new decreasing color
524 QColor newColor(200, 200, 200, 200);
525 m_series->setDecreasingColor(newColor);
526 QCOMPARE(m_series->decreasingColor(), newColor);
527 QCOMPARE(spy.count(), 1);
528
529 // Try set same decreasing color again
530 m_series->setDecreasingColor(newColor);
531 QCOMPARE(m_series->decreasingColor(), newColor);
532 QCOMPARE(spy.count(), 1);
533
534 // Try set invalid decreasing color (should change to default color)
535 m_series->setDecreasingColor(QColor());
536 QCOMPARE(m_series->decreasingColor(), m_series->brush().color());
537 QCOMPARE(spy.count(), 2);
538
539 // Set new brush, decreasing color should change accordingly
540 m_series->setBrush(QBrush(newColor));
541 QCOMPARE(m_series->decreasingColor(), m_series->brush().color());
542 QCOMPARE(spy.count(), 3);
543 }
544
545 void tst_QCandlestickSeries::brush()
546 {
547 QSignalSpy spy(m_series, SIGNAL(brushChanged()));
548
549 QBrush brush(QColor(128, 128, 128, 128));
550 QColor increasingColor(brush.color());
551 increasingColor.setAlpha(128);
552 QColor decreasingColor(brush.color());
553 m_series->setBrush(brush);
554 QCOMPARE(m_series->brush(), brush);
555 QCOMPARE(m_series->increasingColor(), increasingColor);
556 QCOMPARE(m_series->decreasingColor(), decreasingColor);
557 QCOMPARE(spy.count(), 1);
558
559 // Try set same brush
560 m_series->setBrush(brush);
561 QCOMPARE(m_series->brush(), brush);
562 QCOMPARE(m_series->increasingColor(), increasingColor);
563 QCOMPARE(m_series->decreasingColor(), decreasingColor);
564 QCOMPARE(spy.count(), 1);
565 }
566
567 void tst_QCandlestickSeries::pen()
568 {
569 QSignalSpy spy(m_series, SIGNAL(penChanged()));
570
571 QPen pen(QColor(128, 128, 128, 128));
572 m_series->setPen(pen);
573 QCOMPARE(m_series->pen(), pen);
574 QCOMPARE(spy.count(), 1);
575
576 // Try set same pen
577 m_series->setPen(pen);
578 QCOMPARE(m_series->pen(), pen);
579 QCOMPARE(spy.count(), 1);
580 }
581
582 void tst_QCandlestickSeries::mouseClicked()
583 {
584 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
585
586 QVERIFY(m_series->append(m_sets));
587 QCOMPARE(m_series->count(), m_sets.count());
588
589 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
590 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
591
592 QSignalSpy seriesSpy(m_series, SIGNAL(clicked(QCandlestickSet *)));
593 QSignalSpy setSpy1(set1, SIGNAL(clicked()));
594 QSignalSpy setSpy2(set2, SIGNAL(clicked()));
595
596 QChartView view(new QChart());
597 view.resize(400, 300);
598 view.chart()->addSeries(m_series);
599 view.chart()->createDefaultAxes();
600 view.show();
601 QTest::qWaitForWindowShown(&view);
602
603 // Calculate expected layout for candlesticks
604 QRectF plotArea = view.chart()->plotArea();
605 qreal candlestickWidth = plotArea.width() / m_series->count();
606 qreal candlestickHeight = plotArea.height();
607
608 QMap<QCandlestickSet *, QRectF> layout;
609 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
610 plotArea.top(), candlestickWidth, candlestickHeight));
611 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
612 plotArea.top(), candlestickWidth, candlestickHeight));
613
614 // Click set 1
615 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
616 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
617
618 QCOMPARE(seriesSpy.count(), 1);
619 QCOMPARE(setSpy1.count(), 1);
620 QCOMPARE(setSpy2.count(), 0);
621
622 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
623 QCOMPARE(seriesSpyArgs.count(), 1);
624 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
625 seriesSpyArgs.clear();
626
627 QVERIFY(setSpy1.takeFirst().isEmpty());
628
629 // Click set 2
630 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
631 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
632
633 QCOMPARE(seriesSpy.count(), 1);
634 QCOMPARE(setSpy1.count(), 0);
635 QCOMPARE(setSpy2.count(), 1);
636
637 seriesSpyArgs = seriesSpy.takeFirst();
638 QCOMPARE(seriesSpyArgs.count(), 1);
639 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
640 seriesSpyArgs.clear();
641
642 QVERIFY(setSpy2.takeFirst().isEmpty());
643 }
644
645 void tst_QCandlestickSeries::mouseHovered()
646 {
647 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
648
649 QVERIFY(m_series->append(m_sets));
650 QCOMPARE(m_series->count(), m_sets.count());
651
652 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
653 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
654
655 QSignalSpy seriesSpy(m_series, SIGNAL(hovered(bool, QCandlestickSet *)));
656 QSignalSpy setSpy1(set1, SIGNAL(hovered(bool)));
657 QSignalSpy setSpy2(set2, SIGNAL(hovered(bool)));
658
659 QChartView view(new QChart());
660 view.resize(400, 300);
661 view.chart()->addSeries(m_series);
662 view.chart()->createDefaultAxes();
663 view.show();
664 QTest::qWaitForWindowShown(&view);
665
666 // This is hack since view does not get events otherwise
667 view.setMouseTracking(true);
668
669 // Calculate expected layout for candlesticks
670 QRectF plotArea = view.chart()->plotArea();
671 qreal candlestickWidth = plotArea.width() / m_series->count();
672 qreal candlestickHeight = plotArea.height();
673
674 QMap<QCandlestickSet *, QRectF> layout;
675 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
676 plotArea.top(), candlestickWidth, candlestickHeight));
677 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
678 plotArea.top(), candlestickWidth, candlestickHeight));
679
680 // Move mouse to left border
681 QTest::mouseMove(view.viewport(), QPoint(0, layout.value(set1).center().y()));
682 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
683
684 QCOMPARE(seriesSpy.count(), 0);
685 QCOMPARE(setSpy1.count(), 0);
686 QCOMPARE(setSpy2.count(), 0);
687
688 // Move mouse on top of set 1
689 QTest::mouseMove(view.viewport(), layout.value(set1).center().toPoint());
690 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
691
692 QCOMPARE(seriesSpy.count(), 1);
693 QCOMPARE(setSpy1.count(), 1);
694 QCOMPARE(setSpy2.count(), 0);
695
696 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
697 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set1);
698 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
699 QCOMPARE(seriesSpyArgs.at(0).toBool(), true);
700 seriesSpyArgs.clear();
701
702 QList<QVariant> setSpyArgs = setSpy1.takeFirst();
703 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
704 QCOMPARE(setSpyArgs.at(0).toBool(), true);
705 setSpyArgs.clear();
706
707 // Move mouse from top of set 1 to top of set 2
708 QTest::mouseMove(view.viewport(), layout.value(set2).center().toPoint());
709 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
710
711 QCOMPARE(seriesSpy.count(), 2);
712 QCOMPARE(setSpy1.count(), 1);
713 QCOMPARE(setSpy2.count(), 1);
714
715 // Should leave set 1
716 seriesSpyArgs = seriesSpy.takeFirst();
717 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set1);
718 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
719 QCOMPARE(seriesSpyArgs.at(0).toBool(), false);
720 // Don't call seriesSpyArgs.clear() here
721
722 setSpyArgs = setSpy1.takeFirst();
723 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
724 QCOMPARE(setSpyArgs.at(0).toBool(), false);
725 // Don't call setSpyArgs.clear() here
726
727 // Should enter set 2
728 seriesSpyArgs = seriesSpy.takeFirst();
729 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set2);
730 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
731 QCOMPARE(seriesSpyArgs.at(0).toBool(), true);
732 seriesSpyArgs.clear();
733
734 setSpyArgs = setSpy2.takeFirst();
735 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
736 QCOMPARE(setSpyArgs.at(0).toBool(), true);
737 setSpyArgs.clear();
738
739 // Move mouse from top of set 2 to background
740 QTest::mouseMove(view.viewport(), QPoint(layout.value(set2).center().x(), 0));
741 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
742
743 QCOMPARE(seriesSpy.count(), 1);
744 QCOMPARE(setSpy1.count(), 0);
745 QCOMPARE(setSpy2.count(), 1);
746
747 // Should leave set 2
748 seriesSpyArgs = seriesSpy.takeFirst();
749 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set2);
750 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
751 QCOMPARE(seriesSpyArgs.at(0).toBool(), false);
752 seriesSpyArgs.clear();
753
754 setSpyArgs = setSpy2.takeFirst();
755 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
756 QCOMPARE(setSpyArgs.at(0).toBool(), false);
757 setSpyArgs.clear();
758 }
759
760 void tst_QCandlestickSeries::mousePressed()
761 {
762 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
763
764 QVERIFY(m_series->append(m_sets));
765 QCOMPARE(m_series->count(), m_sets.count());
766
767 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
768 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
769
770 QSignalSpy seriesSpy(m_series, SIGNAL(pressed(QCandlestickSet *)));
771 QSignalSpy setSpy1(set1, SIGNAL(pressed()));
772 QSignalSpy setSpy2(set2, SIGNAL(pressed()));
773
774 QChartView view(new QChart());
775 view.resize(400, 300);
776 view.chart()->addSeries(m_series);
777 view.chart()->createDefaultAxes();
778 view.show();
779 QTest::qWaitForWindowShown(&view);
780
781 // Calculate expected layout for candlesticks
782 QRectF plotArea = view.chart()->plotArea();
783 qreal candlestickWidth = plotArea.width() / m_series->count();
784 qreal candlestickHeight = plotArea.height();
785
786 QMap<QCandlestickSet *, QRectF> layout;
787 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
788 plotArea.top(), candlestickWidth, candlestickHeight));
789 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
790 plotArea.top(), candlestickWidth, candlestickHeight));
791
792 // Press set 1
793 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
794 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
795
796 QCOMPARE(seriesSpy.count(), 1);
797 QCOMPARE(setSpy1.count(), 1);
798 QCOMPARE(setSpy2.count(), 0);
799
800 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
801 QCOMPARE(seriesSpyArgs.count(), 1);
802 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
803 seriesSpyArgs.clear();
804
805 QVERIFY(setSpy1.takeFirst().isEmpty());
806
807 // Press set 2
808 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
809 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
810
811 QCOMPARE(seriesSpy.count(), 1);
812 QCOMPARE(setSpy1.count(), 0);
813 QCOMPARE(setSpy2.count(), 1);
814
815 seriesSpyArgs = seriesSpy.takeFirst();
816 QCOMPARE(seriesSpyArgs.count(), 1);
817 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
818 seriesSpyArgs.clear();
819
820 QVERIFY(setSpy2.takeFirst().isEmpty());
821 }
822
823 void tst_QCandlestickSeries::mouseReleased()
824 {
825 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
826
827 QVERIFY(m_series->append(m_sets));
828 QCOMPARE(m_series->count(), m_sets.count());
829
830 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
831 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
832
833 QSignalSpy seriesSpy(m_series, SIGNAL(released(QCandlestickSet *)));
834 QSignalSpy setSpy1(set1, SIGNAL(released()));
835 QSignalSpy setSpy2(set2, SIGNAL(released()));
836
837 QChartView view(new QChart());
838 view.resize(400, 300);
839 view.chart()->addSeries(m_series);
840 view.chart()->createDefaultAxes();
841 view.show();
842 QTest::qWaitForWindowShown(&view);
843
844 // Calculate expected layout for candlesticks
845 QRectF plotArea = view.chart()->plotArea();
846 qreal candlestickWidth = plotArea.width() / m_series->count();
847 qreal candlestickHeight = plotArea.height();
848
849 QMap<QCandlestickSet *, QRectF> layout;
850 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
851 plotArea.top(), candlestickWidth, candlestickHeight));
852 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
853 plotArea.top(), candlestickWidth, candlestickHeight));
854
855 // Release mouse over set 1
856 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
857 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
858
859 QCOMPARE(seriesSpy.count(), 1);
860 QCOMPARE(setSpy1.count(), 1);
861 QCOMPARE(setSpy2.count(), 0);
862
863 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
864 QCOMPARE(seriesSpyArgs.count(), 1);
865 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
866 seriesSpyArgs.clear();
867
868 QVERIFY(setSpy1.takeFirst().isEmpty());
869
870 // Release mouse over set 2
871 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
872 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
873
874 QCOMPARE(seriesSpy.count(), 1);
875 QCOMPARE(setSpy1.count(), 0);
876 QCOMPARE(setSpy2.count(), 1);
877
878 seriesSpyArgs = seriesSpy.takeFirst();
879 QCOMPARE(seriesSpyArgs.count(), 1);
880 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
881 seriesSpyArgs.clear();
882
883 QVERIFY(setSpy2.takeFirst().isEmpty());
884 }
885
886 void tst_QCandlestickSeries::mouseDoubleClicked()
887 {
888 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
889
890 QVERIFY(m_series->append(m_sets));
891 QCOMPARE(m_series->count(), m_sets.count());
892
893 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
894 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
895
896 QSignalSpy seriesSpy(m_series, SIGNAL(doubleClicked(QCandlestickSet *)));
897 QSignalSpy setSpy1(set1, SIGNAL(doubleClicked()));
898 QSignalSpy setSpy2(set2, SIGNAL(doubleClicked()));
899
900 QChartView view(new QChart());
901 view.resize(400, 300);
902 view.chart()->addSeries(m_series);
903 view.chart()->createDefaultAxes();
904 view.show();
905 QTest::qWaitForWindowShown(&view);
906
907 // Calculate expected layout for candlesticks
908 QRectF plotArea = view.chart()->plotArea();
909 qreal candlestickWidth = plotArea.width() / m_series->count();
910 qreal candlestickHeight = plotArea.height();
911
912 QMap<QCandlestickSet *, QRectF> layout;
913 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
914 plotArea.top(), candlestickWidth, candlestickHeight));
915 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
916 plotArea.top(), candlestickWidth, candlestickHeight));
917
918 // Double-click set 1
919 QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
920 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
921
922 QCOMPARE(seriesSpy.count(), 1);
923 QCOMPARE(setSpy1.count(), 1);
924 QCOMPARE(setSpy2.count(), 0);
925
926 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
927 QCOMPARE(seriesSpyArgs.count(), 1);
928 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
929 seriesSpyArgs.clear();
930
931 QVERIFY(setSpy1.takeFirst().isEmpty());
932 }
933
934 QTEST_MAIN(tst_QCandlestickSeries)
935
936 #include "tst_qcandlestickseries.moc"
@@ -0,0 +1,5
1 !include( ../auto.pri ) {
2 error( "Couldn't find the auto.pri file!" )
3 }
4
5 SOURCES += tst_qcandlestickset.cpp
@@ -0,0 +1,284
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 <QtCharts/QCandlestickSet>
31 #include <QtCore/QDateTime>
32 #include <QtTest/QtTest>
33
34 QT_CHARTS_USE_NAMESPACE
35
36 class tst_QCandlestickSet : public QObject
37 {
38 Q_OBJECT
39
40 public Q_SLOTS:
41 void initTestCase();
42 void cleanupTestCase();
43 void init();
44 void cleanup();
45
46 private Q_SLOTS:
47 void qCandlestickSet_data();
48 void qCandlestickSet();
49 void timestamp_data();
50 void timestamp();
51 void open_data();
52 void open();
53 void high_data();
54 void high();
55 void low_data();
56 void low();
57 void close_data();
58 void close();
59 void brush();
60 void pen();
61
62 private:
63 QCandlestickSet* m_candlestickSet;
64 };
65
66 void tst_QCandlestickSet::initTestCase()
67 {
68 }
69
70 void tst_QCandlestickSet::cleanupTestCase()
71 {
72 QTest::qWait(1); // Allow final deleteLaters to run
73 }
74
75 void tst_QCandlestickSet::init()
76 {
77 m_candlestickSet = new QCandlestickSet(QDateTime::currentMSecsSinceEpoch());
78 m_candlestickSet->setOpen(2345.67);
79 m_candlestickSet->setHigh(4567.89);
80 m_candlestickSet->setLow(1234.56);
81 m_candlestickSet->setClose(3456.78);
82 }
83
84 void tst_QCandlestickSet::cleanup()
85 {
86 delete m_candlestickSet;
87 m_candlestickSet = nullptr;
88 }
89
90 void tst_QCandlestickSet::qCandlestickSet_data()
91 {
92 QTest::addColumn<qreal>("timestamp");
93 QTest::addColumn<qreal>("expectedTimestamp");
94
95 QTest::newRow("timestamp less than zero") << -1.0 << 0.0;
96 QTest::newRow("timestamp equals zero") << 0.0 << 0.0;
97 QTest::newRow("timestamp greater than zero") << 1.0 << 1.0;
98 QTest::newRow("timestamp rounded down") << 4.321 << 4.0;
99 QTest::newRow("timestamp rounded up") << 5.678 << 6.0;
100 }
101
102 void tst_QCandlestickSet::qCandlestickSet()
103 {
104 QFETCH(qreal, timestamp);
105 QFETCH(qreal, expectedTimestamp);
106
107 QCandlestickSet candlestickSet(timestamp);
108 QCOMPARE(candlestickSet.timestamp(), expectedTimestamp);
109 }
110
111 void tst_QCandlestickSet::timestamp_data()
112 {
113 QTest::addColumn<qreal>("timestamp");
114 QTest::addColumn<qreal>("expectedTimestamp");
115
116 QTest::newRow("timestamp less than zero") << -1.0 << 0.0;
117 QTest::newRow("timestamp equals zero") << 0.0 << 0.0;
118 QTest::newRow("timestamp greater than zero") << 1.0 << 1.0;
119 QTest::newRow("timestamp rounded down") << 4.321 << 4.0;
120 QTest::newRow("timestamp rounded up") << 5.678 << 6.0;
121 }
122
123 void tst_QCandlestickSet::timestamp()
124 {
125 QFETCH(qreal, timestamp);
126 QFETCH(qreal, expectedTimestamp);
127
128 QSignalSpy spy(m_candlestickSet, SIGNAL(timestampChanged()));
129
130 m_candlestickSet->setTimestamp(timestamp);
131 QCOMPARE(m_candlestickSet->timestamp(), expectedTimestamp);
132 QCOMPARE(spy.count(), 1);
133
134 // Try set same timestamp value
135 m_candlestickSet->setTimestamp(expectedTimestamp);
136 QCOMPARE(m_candlestickSet->timestamp(), expectedTimestamp);
137 QCOMPARE(spy.count(), 1);
138 }
139
140 void tst_QCandlestickSet::open_data()
141 {
142 QTest::addColumn<qreal>("open");
143
144 QTest::newRow("open less than zero") << -1.234;
145 QTest::newRow("open equals zero") << 0.0;
146 QTest::newRow("open greater than zero") << 1.234;
147 }
148
149 void tst_QCandlestickSet::open()
150 {
151 QFETCH(qreal, open);
152
153 QSignalSpy spy(m_candlestickSet, SIGNAL(openChanged()));
154
155 m_candlestickSet->setOpen(open);
156 QCOMPARE(m_candlestickSet->open(), open);
157 QCOMPARE(spy.count(), 1);
158
159 // Try set same open value
160 m_candlestickSet->setOpen(open);
161 QCOMPARE(m_candlestickSet->open(), open);
162 QCOMPARE(spy.count(), 1);
163 }
164
165 void tst_QCandlestickSet::high_data()
166 {
167 QTest::addColumn<qreal>("high");
168
169 QTest::newRow("high less than zero") << -1.234;
170 QTest::newRow("high equals zero") << 0.0;
171 QTest::newRow("high greater than zero") << 1.234;
172 }
173
174 void tst_QCandlestickSet::high()
175 {
176 QFETCH(qreal, high);
177
178 QSignalSpy spy(m_candlestickSet, SIGNAL(highChanged()));
179
180 m_candlestickSet->setHigh(high);
181 QCOMPARE(m_candlestickSet->high(), high);
182 QCOMPARE(spy.count(), 1);
183
184 // Try set same high value
185 m_candlestickSet->setHigh(high);
186 QCOMPARE(m_candlestickSet->high(), high);
187 QCOMPARE(spy.count(), 1);
188 }
189
190 void tst_QCandlestickSet::low_data()
191 {
192 QTest::addColumn<qreal>("low");
193
194 QTest::newRow("low less than zero") << -1.234;
195 QTest::newRow("low equals zero") << 0.0;
196 QTest::newRow("low greater than zero") << 1.234;
197 }
198
199 void tst_QCandlestickSet::low()
200 {
201 QFETCH(qreal, low);
202
203 QSignalSpy spy(m_candlestickSet, SIGNAL(lowChanged()));
204
205 m_candlestickSet->setLow(low);
206 QCOMPARE(m_candlestickSet->low(), low);
207 QCOMPARE(spy.count(), 1);
208
209 // Try set same low value
210 m_candlestickSet->setLow(low);
211 QCOMPARE(m_candlestickSet->low(), low);
212 QCOMPARE(spy.count(), 1);
213 }
214
215 void tst_QCandlestickSet::close_data()
216 {
217 QTest::addColumn<qreal>("close");
218
219 QTest::newRow("close less than zero") << -1.234;
220 QTest::newRow("close equals zero") << 0.0;
221 QTest::newRow("close greater than zero") << 1.234;
222 }
223
224 void tst_QCandlestickSet::close()
225 {
226 QFETCH(qreal, close);
227
228 QSignalSpy spy(m_candlestickSet, SIGNAL(closeChanged()));
229
230 m_candlestickSet->setClose(close);
231 QCOMPARE(m_candlestickSet->close(), close);
232 QCOMPARE(spy.count(), 1);
233
234 // Try set same close value
235 m_candlestickSet->setClose(close);
236 QCOMPARE(m_candlestickSet->close(), close);
237 QCOMPARE(spy.count(), 1);
238 }
239
240 void tst_QCandlestickSet::brush()
241 {
242 QSignalSpy spy(m_candlestickSet, SIGNAL(brushChanged()));
243
244 QCOMPARE(m_candlestickSet->brush(), QBrush(Qt::NoBrush));
245
246 m_candlestickSet->setBrush(QBrush(Qt::NoBrush));
247 QCOMPARE(m_candlestickSet->brush(), QBrush(Qt::NoBrush));
248 QCOMPARE(spy.count(), 0);
249
250 QBrush brush(QColor(128, 128, 128, 128));
251 m_candlestickSet->setBrush(brush);
252 QCOMPARE(m_candlestickSet->brush(), brush);
253 QCOMPARE(spy.count(), 1);
254
255 // Try set same brush
256 m_candlestickSet->setBrush(brush);
257 QCOMPARE(m_candlestickSet->brush(), brush);
258 QCOMPARE(spy.count(), 1);
259 }
260
261 void tst_QCandlestickSet::pen()
262 {
263 QSignalSpy spy(m_candlestickSet, SIGNAL(penChanged()));
264
265 QCOMPARE(m_candlestickSet->pen(), QPen(Qt::NoPen));
266
267 m_candlestickSet->setPen(QPen(Qt::NoPen));
268 QCOMPARE(m_candlestickSet->pen(), QPen(Qt::NoPen));
269 QCOMPARE(spy.count(), 0);
270
271 QPen pen(QColor(128, 128, 128, 128));
272 m_candlestickSet->setPen(pen);
273 QCOMPARE(m_candlestickSet->pen(), pen);
274 QCOMPARE(spy.count(), 1);
275
276 // Try set same pen
277 m_candlestickSet->setPen(pen);
278 QCOMPARE(m_candlestickSet->pen(), pen);
279 QCOMPARE(spy.count(), 1);
280 }
281
282 QTEST_GUILESS_MAIN(tst_QCandlestickSet)
283
284 #include "tst_qcandlestickset.moc"
@@ -0,0 +1,13
1 !include( ../../tests.pri ) {
2 error( "Couldn't find the test.pri file!" )
3 }
4
5 QT += widgets
6
7 SOURCES += main.cpp \
8 mainwidget.cpp \
9 customtablemodel.cpp
10
11 HEADERS += \
12 mainwidget.h \
13 customtablemodel.h
@@ -0,0 +1,160
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 <QtCharts/QCandlestickSet>
31 #include <QtCore/QRect>
32 #include <QtCore/QVector>
33 #include <QtGui/QColor>
34 #include "customtablemodel.h"
35
36 CustomTableModel::CustomTableModel(QObject *parent)
37 : QAbstractTableModel(parent)
38 {
39 m_categories.append(QStringLiteral("Timestamp"));
40 m_categories.append(QStringLiteral("Open"));
41 m_categories.append(QStringLiteral("High"));
42 m_categories.append(QStringLiteral("Low"));
43 m_categories.append(QStringLiteral("Close"));
44 }
45
46 CustomTableModel::~CustomTableModel()
47 {
48 qDeleteAll(m_data);
49 }
50
51 int CustomTableModel::rowCount(const QModelIndex &parent) const
52 {
53 Q_UNUSED(parent)
54
55 return m_data.count();
56 }
57
58 int CustomTableModel::columnCount(const QModelIndex &parent) const
59 {
60 Q_UNUSED(parent)
61
62 return m_categories.count();
63 }
64
65 QVariant CustomTableModel::headerData(int section, Qt::Orientation orientation, int role) const
66 {
67 if (role != Qt::DisplayRole)
68 return QVariant();
69
70 if (orientation == Qt::Horizontal)
71 return m_categories[section];
72 else
73 return QStringLiteral("%1").arg(section);
74 }
75
76 bool CustomTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
77 {
78 if (index.isValid() && role == Qt::EditRole) {
79 m_data[index.row()]->replace(index.column(), value.toDouble());
80 emit dataChanged(index, index);
81
82 return true;
83 }
84
85 return false;
86 }
87
88 QVariant CustomTableModel::data(const QModelIndex &index, int role) const
89 {
90 switch (role) {
91 case Qt::DisplayRole:
92 // fall through
93 case Qt::EditRole:
94 return m_data[index.row()]->at(index.column());
95 case Qt::BackgroundRole:
96 foreach (QRect rect, m_mapping) {
97 if (rect.contains(index.column(), index.row()))
98 return QColor(m_mapping.key(rect));
99 }
100 // cell is not mapped, return white color
101 return QColor(Qt::white);
102 default:
103 return QVariant();
104 }
105 }
106
107 Qt::ItemFlags CustomTableModel::flags(const QModelIndex &index) const
108 {
109 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
110 }
111
112 bool CustomTableModel::insertRows(int row, int count, const QModelIndex &parent)
113 {
114 beginInsertRows(parent, row, row + count - 1);
115 m_data.append(new QVector<qreal>(columnCount()));
116 endInsertRows();
117
118 return true;
119 }
120
121 bool CustomTableModel::removeRows(int row, int count, const QModelIndex &parent)
122 {
123 beginRemoveRows(parent, row, row + count - 1);
124 for (int i = row + count; i >= row; --i)
125 m_data.removeAt(i);
126 endRemoveRows();
127
128 return true;
129 }
130
131 void CustomTableModel::addRow(QCandlestickSet *set)
132 {
133 bool changed = insertRows(m_data.count(), 1);
134
135 if (changed) {
136 QVector<qreal> *row = m_data.last();
137 row->insert(0, set->timestamp());
138 row->insert(1, set->open());
139 row->insert(2, set->high());
140 row->insert(3, set->low());
141 row->insert(4, set->close());
142 }
143 }
144
145 void CustomTableModel::clearRows()
146 {
147 bool changed = removeRows(0, m_data.count());
148 if (changed)
149 m_data.clear();
150 }
151
152 void CustomTableModel::addMapping(QString color, QRect area)
153 {
154 m_mapping.insertMulti(color, area);
155 }
156
157 void CustomTableModel::clearMapping()
158 {
159 m_mapping.clear();
160 }
@@ -0,0 +1,73
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 #ifndef CUSTOMTABLEMODEL_H
31 #define CUSTOMTABLEMODEL_H
32
33 #include <QtCharts/QChartGlobal>
34 #include <QtCore/QAbstractTableModel>
35 #include <QtCore/QHash>
36 #include <QtCore/QRect>
37
38 QT_CHARTS_BEGIN_NAMESPACE
39 class QCandlestickSet;
40 QT_CHARTS_END_NAMESPACE
41
42 QT_CHARTS_USE_NAMESPACE
43
44 class CustomTableModel : public QAbstractTableModel
45 {
46 Q_OBJECT
47
48 public:
49 explicit CustomTableModel(QObject *parent = nullptr);
50 virtual ~CustomTableModel();
51
52 int rowCount(const QModelIndex &parent = QModelIndex()) const;
53 int columnCount(const QModelIndex &parent = QModelIndex()) const;
54 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
55 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
56 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
57 Qt::ItemFlags flags(const QModelIndex &index) const;
58 bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
59 bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
60
61 void addRow(QCandlestickSet *set);
62 void clearRows();
63
64 void addMapping(QString color, QRect area);
65 void clearMapping();
66
67 private:
68 QStringList m_categories;
69 QList<QVector<qreal> *> m_data;
70 QHash<QString, QRect> m_mapping;
71 };
72
73 #endif // CUSTOMTABLEMODEL_H
@@ -0,0 +1,43
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 <QtWidgets/QApplication>
31 #include "mainwidget.h"
32
33 int main(int argc, char *argv[])
34 {
35 QApplication a(argc, argv);
36
37 MainWidget w;
38 w.setWindowTitle(QStringLiteral("Candlestick Chart Tester"));
39 w.resize(1280, 720);
40 w.show();
41
42 return a.exec();
43 }
This diff has been collapsed as it changes many lines, (691 lines changed) Show them Hide them
@@ -0,0 +1,691
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 <QtCharts/QBarCategoryAxis>
31 #include <QtCharts/QCandlestickSeries>
32 #include <QtCharts/QCandlestickSet>
33 #include <QtCharts/QDateTimeAxis>
34 #include <QtCharts/QHCandlestickModelMapper>
35 #include <QtCharts/QValueAxis>
36 #include <QtCore/QDateTime>
37 #include <QtCore/QDebug>
38 #include <QtWidgets/QCheckBox>
39 #include <QtWidgets/QComboBox>
40 #include <QtWidgets/QDoubleSpinBox>
41 #include <QtWidgets/QGridLayout>
42 #include <QtWidgets/QHeaderView>
43 #include <QtWidgets/QLabel>
44 #include <QtWidgets/QPushButton>
45 #include <QtWidgets/QTableView>
46 #include "customtablemodel.h"
47 #include "mainwidget.h"
48
49 QT_CHARTS_USE_NAMESPACE
50
51 MainWidget::MainWidget(QWidget *parent)
52 : QWidget(parent),
53 m_chart(new QChart()),
54 m_chartView(new QChartView(m_chart, this)),
55 m_axisX(nullptr),
56 m_axisY(nullptr),
57 m_maximumColumnWidth(-1.0),
58 m_minimumColumnWidth(5.0),
59 m_bodyOutlineVisible(true),
60 m_capsVisible(false),
61 m_bodyWidth(0.5),
62 m_capsWidth(0.5),
63 m_customIncreasingColor(false),
64 m_customDecreasingColor(false),
65 m_hModelMapper(new QHCandlestickModelMapper(this))
66 {
67 qsrand(QDateTime::currentDateTime().toTime_t());
68
69 m_chartView->setRenderHint(QPainter::Antialiasing, false);
70
71 m_hModelMapper->setModel(new CustomTableModel(this));
72 m_hModelMapper->setTimestampColumn(0);
73 m_hModelMapper->setOpenColumn(1);
74 m_hModelMapper->setHighColumn(2);
75 m_hModelMapper->setLowColumn(3);
76 m_hModelMapper->setCloseColumn(4);
77
78 QGridLayout *mainLayout = new QGridLayout();
79 mainLayout->addLayout(createSeriesControlsLayout(), 0, 0);
80 mainLayout->addLayout(createSetsControlsLayout(), 1, 0);
81 mainLayout->addLayout(createCandlestickControlsLayout(), 2, 0);
82 mainLayout->addLayout(createMiscellaneousControlsLayout(), 3, 0);
83 mainLayout->addWidget(m_chartView, 0, 1, mainLayout->rowCount() + 1, 1);
84 mainLayout->addLayout(createModelMapperControlsLayout(), 0, 2, mainLayout->rowCount(), 1);
85 setLayout(mainLayout);
86
87 addSeries();
88 }
89
90 MainWidget::~MainWidget()
91 {
92 }
93
94 QGridLayout *MainWidget::createSeriesControlsLayout()
95 {
96 QGridLayout *layout = new QGridLayout();
97 int row = 0;
98
99 layout->addWidget(new QLabel(QStringLiteral("Series controls:")), row, 0, Qt::AlignLeft);
100
101 QPushButton *addSeriesButton = new QPushButton(QStringLiteral("Add a series"));
102 connect(addSeriesButton, SIGNAL(clicked(bool)), this, SLOT(addSeries()));
103 layout->addWidget(addSeriesButton, row++, 1, Qt::AlignLeft);
104
105 QPushButton *removeSeriesButton = new QPushButton(QStringLiteral("Remove a series"));
106 connect(removeSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeSeries()));
107 layout->addWidget(removeSeriesButton, row++, 1, Qt::AlignLeft);
108
109 QPushButton *removeAllSeriesButton = new QPushButton(QStringLiteral("Remove all series"));
110 connect(removeAllSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSeries()));
111 layout->addWidget(removeAllSeriesButton, row++, 1, Qt::AlignLeft);
112
113 return layout;
114 }
115
116 QGridLayout *MainWidget::createSetsControlsLayout()
117 {
118 QGridLayout *layout = new QGridLayout();
119 int row = 0;
120
121 layout->addWidget(new QLabel(QStringLiteral("Sets controls:")), row, 0, Qt::AlignLeft);
122
123 QPushButton *addSetButton = new QPushButton(QStringLiteral("Add a set"));
124 connect(addSetButton, SIGNAL(clicked(bool)), this, SLOT(addSet()));
125 layout->addWidget(addSetButton, row++, 1, Qt::AlignLeft);
126
127 QPushButton *insertSetButton = new QPushButton(QStringLiteral("Insert a set"));
128 connect(insertSetButton, SIGNAL(clicked(bool)), this, SLOT(insertSet()));
129 layout->addWidget(insertSetButton, row++, 1, Qt::AlignLeft);
130
131 QPushButton *removeSetButton = new QPushButton(QStringLiteral("Remove a set"));
132 connect(removeSetButton, SIGNAL(clicked(bool)), this, SLOT(removeSet()));
133 layout->addWidget(removeSetButton, row++, 1, Qt::AlignLeft);
134
135 QPushButton *removeAllSetsButton = new QPushButton(QStringLiteral("Remove all sets"));
136 connect(removeAllSetsButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSets()));
137 layout->addWidget(removeAllSetsButton, row++, 1, Qt::AlignLeft);
138
139 return layout;
140 }
141
142 QGridLayout *MainWidget::createCandlestickControlsLayout()
143 {
144 QGridLayout *layout = new QGridLayout();
145 int row = 0;
146
147 layout->addWidget(new QLabel(QStringLiteral("Maximum column width:")), row, 0, Qt::AlignLeft);
148 QDoubleSpinBox *maximumColumnWidthSpinBox = new QDoubleSpinBox();
149 maximumColumnWidthSpinBox->setRange(-1.0, 1024.0);
150 maximumColumnWidthSpinBox->setDecimals(0);
151 maximumColumnWidthSpinBox->setValue(m_maximumColumnWidth);
152 maximumColumnWidthSpinBox->setSingleStep(1.0);
153 connect(maximumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
154 this, SLOT(changeMaximumColumnWidth(double)));
155 layout->addWidget(maximumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
156
157 layout->addWidget(new QLabel(QStringLiteral("Minimum column width:")), row, 0, Qt::AlignLeft);
158 QDoubleSpinBox *minimumColumnWidthSpinBox = new QDoubleSpinBox();
159 minimumColumnWidthSpinBox->setRange(-1.0, 1024.0);
160 minimumColumnWidthSpinBox->setDecimals(0);
161 minimumColumnWidthSpinBox->setValue(m_minimumColumnWidth);
162 minimumColumnWidthSpinBox->setSingleStep(1.0);
163 connect(minimumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
164 this, SLOT(changeMinimumColumnWidth(double)));
165 layout->addWidget(minimumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
166
167 QCheckBox *bodyOutlineVisible = new QCheckBox(QStringLiteral("Body outline visible"));
168 connect(bodyOutlineVisible, SIGNAL(toggled(bool)), this, SLOT(bodyOutlineVisibleToggled(bool)));
169 bodyOutlineVisible->setChecked(m_bodyOutlineVisible);
170 layout->addWidget(bodyOutlineVisible, row++, 0, Qt::AlignLeft);
171
172 QCheckBox *capsVisible = new QCheckBox(QStringLiteral("Caps visible"));
173 connect(capsVisible, SIGNAL(toggled(bool)), this, SLOT(capsVisibleToggled(bool)));
174 capsVisible->setChecked(m_capsVisible);
175 layout->addWidget(capsVisible, row++, 0, Qt::AlignLeft);
176
177 layout->addWidget(new QLabel(QStringLiteral("Candlestick body width:")), row, 0, Qt::AlignLeft);
178 QDoubleSpinBox *bodyWidthSpinBox = new QDoubleSpinBox();
179 bodyWidthSpinBox->setRange(-1.0, 2.0);
180 bodyWidthSpinBox->setValue(m_bodyWidth);
181 bodyWidthSpinBox->setSingleStep(0.1);
182 connect(bodyWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeBodyWidth(double)));
183 layout->addWidget(bodyWidthSpinBox, row++, 1, Qt::AlignLeft);
184
185 layout->addWidget(new QLabel(QStringLiteral("Candlestick caps width:")), row, 0, Qt::AlignLeft);
186 QDoubleSpinBox *capsWidthSpinBox = new QDoubleSpinBox();
187 capsWidthSpinBox->setRange(-1.0, 2.0);
188 capsWidthSpinBox->setValue(m_capsWidth);
189 capsWidthSpinBox->setSingleStep(0.1);
190 connect(capsWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeCapsWidth(double)));
191 layout->addWidget(capsWidthSpinBox, row++, 1, Qt::AlignLeft);
192
193 QCheckBox *increasingColor = new QCheckBox(QStringLiteral("Custom increasing color (only S1)"));
194 connect(increasingColor, SIGNAL(toggled(bool)), this, SLOT(customIncreasingColorToggled(bool)));
195 increasingColor->setChecked(m_customIncreasingColor);
196 layout->addWidget(increasingColor, row++, 0, 1, 2, Qt::AlignLeft);
197
198 QCheckBox *decreasingColor = new QCheckBox(QStringLiteral("Custom decreasing color (only S1)"));
199 connect(decreasingColor, SIGNAL(toggled(bool)), this, SLOT(customDecreasingColorToggled(bool)));
200 decreasingColor->setChecked(m_customDecreasingColor);
201 layout->addWidget(decreasingColor, row++, 0, 1, 2, Qt::AlignLeft);
202
203 return layout;
204 }
205
206 QGridLayout *MainWidget::createMiscellaneousControlsLayout()
207 {
208 QGridLayout *layout = new QGridLayout();
209 int row = 0;
210
211 layout->addWidget(new QLabel(QStringLiteral("Miscellaneous:")), row, 0, Qt::AlignLeft);
212
213 QCheckBox *antialiasingCheckBox = new QCheckBox(QStringLiteral("Antialiasing"));
214 connect(antialiasingCheckBox, SIGNAL(toggled(bool)), this, SLOT(antialiasingToggled(bool)));
215 antialiasingCheckBox->setChecked(false);
216 layout->addWidget(antialiasingCheckBox, row++, 1, Qt::AlignLeft);
217
218 QCheckBox *animationCheckBox = new QCheckBox(QStringLiteral("Animation"));
219 connect(animationCheckBox, SIGNAL(toggled(bool)), this, SLOT(animationToggled(bool)));
220 animationCheckBox->setChecked(false);
221 layout->addWidget(animationCheckBox, row++, 1, Qt::AlignLeft);
222
223 QCheckBox *legendCheckBox = new QCheckBox(QStringLiteral("Legend"));
224 connect(legendCheckBox, SIGNAL(toggled(bool)), this, SLOT(legendToggled(bool)));
225 legendCheckBox->setChecked(true);
226 layout->addWidget(legendCheckBox, row++, 1, Qt::AlignLeft);
227
228 QCheckBox *titleCheckBox = new QCheckBox(QStringLiteral("Title"));
229 connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
230 titleCheckBox->setChecked(true);
231 layout->addWidget(titleCheckBox, row++, 1, Qt::AlignLeft);
232
233 layout->addWidget(new QLabel(QStringLiteral("Chart theme:")), row, 0, Qt::AlignLeft);
234 QComboBox *chartThemeComboBox = new QComboBox();
235 chartThemeComboBox->addItem(QStringLiteral("Light"));
236 chartThemeComboBox->addItem(QStringLiteral("Blue Cerulean"));
237 chartThemeComboBox->addItem(QStringLiteral("Dark"));
238 chartThemeComboBox->addItem(QStringLiteral("Brown Sand"));
239 chartThemeComboBox->addItem(QStringLiteral("Blue Ncs"));
240 chartThemeComboBox->addItem(QStringLiteral("High Contrast"));
241 chartThemeComboBox->addItem(QStringLiteral("Blue Icy"));
242 chartThemeComboBox->addItem(QStringLiteral("Qt"));
243 connect(chartThemeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeChartTheme(int)));
244 layout->addWidget(chartThemeComboBox, row++, 1, Qt::AlignLeft);
245
246 layout->addWidget(new QLabel(QStringLiteral("Axis X:")), row, 0, Qt::AlignLeft);
247 QComboBox *axisXComboBox = new QComboBox();
248 axisXComboBox->addItem(QStringLiteral("BarCategory"));
249 axisXComboBox->addItem(QStringLiteral("DateTime"));
250 axisXComboBox->addItem(QStringLiteral("Value"));
251 connect(axisXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAxisX(int)));
252 layout->addWidget(axisXComboBox, row++, 1, Qt::AlignLeft);
253
254 return layout;
255 }
256
257 QGridLayout *MainWidget::createModelMapperControlsLayout()
258 {
259 QGridLayout *layout = new QGridLayout();
260 int row = 0;
261
262 layout->addWidget(new QLabel(QStringLiteral("First series:")), row, 0, Qt::AlignLeft);
263
264 QPushButton *attachModelMapperButton = new QPushButton(QStringLiteral("Attach model mapper"));
265 connect(attachModelMapperButton, SIGNAL(clicked(bool)), this, SLOT(attachModelMapper()));
266 layout->addWidget(attachModelMapperButton, row++, 1, Qt::AlignLeft);
267
268 QPushButton *detachModelMappeButton = new QPushButton(QStringLiteral("Detach model mapper"));
269 connect(detachModelMappeButton, SIGNAL(clicked(bool)), this, SLOT(detachModelMapper()));
270 layout->addWidget(detachModelMappeButton, row++, 1, Qt::AlignLeft);
271
272 QTableView *tableView = new QTableView();
273 tableView->setMinimumSize(320, 480);
274 tableView->setMaximumSize(320, 480);
275 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
276 tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
277 Q_ASSERT_X(m_hModelMapper->model(), Q_FUNC_INFO, "Model is not initialized");
278 tableView->setModel(m_hModelMapper->model());
279 layout->addWidget(tableView, row++, 0, 1, 2, Qt::AlignLeft);
280
281 layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);
282
283 return layout;
284 }
285
286 qreal MainWidget::randomValue(int min, int max) const
287 {
288 return (qrand() / (qreal(RAND_MAX) + 1)) * ((qMax(min, max) - qMin(min, max)) + qMin(min, max));
289 }
290
291 QCandlestickSet *MainWidget::randomSet(qreal timestamp)
292 {
293 QCandlestickSet *set = new QCandlestickSet(timestamp);
294 set->setOpen(randomValue(4, 11));
295 set->setHigh(randomValue(12, 15));
296 set->setLow(randomValue(0, 3));
297 set->setClose(randomValue(4, 11));
298
299 return set;
300 }
301
302 void MainWidget::updateAxes()
303 {
304 if (m_chart->axes().isEmpty())
305 m_chart->createDefaultAxes();
306
307 QCandlestickSeries *series;
308 if (!m_chart->series().isEmpty())
309 series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
310 else
311 series = nullptr;
312
313 m_axisX = m_chart->axes(Qt::Horizontal).first();
314 if (series && !series->candlestickSets().isEmpty()) {
315 if (m_axisX->type() == QAbstractAxis::AxisTypeBarCategory) {
316 QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(m_axisX);
317 QStringList categories;
318 for (int i = 0; i < series->candlestickSets().count(); ++i)
319 categories.append(QString::number(i));
320 axisX->setCategories(categories);
321 } else { // QAbstractAxis::AxisTypeDateTime || QAbstractAxis::AxisTypeValue
322 qreal msInMonth = 31.0 * 24.0 * 60.0 * 60.0 * 1000.0;
323 qreal min = series->candlestickSets().first()->timestamp() - msInMonth;
324 qreal max = series->candlestickSets().last()->timestamp() + msInMonth;
325 QDateTime minDateTime = QDateTime::fromMSecsSinceEpoch(min);
326 QDateTime maxDateTime = QDateTime::fromMSecsSinceEpoch(max);
327
328 if (m_axisX->type() == QAbstractAxis::AxisTypeDateTime)
329 m_axisX->setRange(minDateTime, maxDateTime);
330 else
331 m_axisX->setRange(min, max);
332 }
333 }
334
335 m_axisY = m_chart->axes(Qt::Vertical).first();
336 m_axisY->setMax(15);
337 m_axisY->setMin(0);
338 }
339
340 void MainWidget::addSeries()
341 {
342 if (m_chart->series().count() > 9) {
343 qDebug() << "Maximum series count is 10";
344 return;
345 }
346
347 QCandlestickSeries *series = new QCandlestickSeries();
348 series->setName(QStringLiteral("S%1").arg(m_chart->series().count() + 1));
349 series->setMaximumColumnWidth(m_maximumColumnWidth);
350 series->setMinimumColumnWidth(m_minimumColumnWidth);
351 series->setBodyOutlineVisible(m_bodyOutlineVisible);
352 series->setBodyWidth(m_bodyWidth);
353 series->setCapsVisible(m_capsVisible);
354 series->setCapsWidth(m_capsWidth);
355
356 if (m_chart->series().isEmpty()) {
357 if (m_customIncreasingColor)
358 series->setIncreasingColor(QColor(Qt::green));
359 if (m_customDecreasingColor)
360 series->setDecreasingColor(QColor(Qt::red));
361
362 for (int month = 1; month <= 12; ++month) {
363 QDateTime dateTime;
364 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), month, 1));
365 dateTime.setTime(QTime(12, 34, 56, 789));
366
367 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
368 series->append(set);
369 }
370 } else {
371 QCandlestickSeries *s = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
372 for (int i = 0; i < s->candlestickSets().count(); ++i) {
373 QCandlestickSet *set = randomSet(s->candlestickSets().at(i)->timestamp());
374 series->append(set);
375 }
376 }
377
378 m_chart->addSeries(series);
379
380 updateAxes();
381 if (!series->attachedAxes().contains(m_axisX))
382 series->attachAxis(m_axisX);
383 if (!series->attachedAxes().contains(m_axisY))
384 series->attachAxis(m_axisY);
385 }
386
387 void MainWidget::removeSeries()
388 {
389 if (m_chart->series().isEmpty()) {
390 qDebug() << "Create a series first";
391 return;
392 }
393
394 if (m_chart->series().count() == 1)
395 detachModelMapper();
396
397 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().last());
398 m_chart->removeSeries(series);
399 delete series;
400 series = nullptr;
401 }
402
403 void MainWidget::removeAllSeries()
404 {
405 if (m_chart->series().isEmpty()) {
406 qDebug() << "Create a series first";
407 return;
408 }
409
410 detachModelMapper();
411
412 m_chart->removeAllSeries();
413 }
414
415 void MainWidget::addSet()
416 {
417 if (m_chart->series().isEmpty()) {
418 qDebug() << "Create a series first";
419 return;
420 }
421
422 foreach (QAbstractSeries *s, m_chart->series()) {
423 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
424
425 QDateTime dateTime;
426 if (series->count()) {
427 dateTime.setMSecsSinceEpoch(series->candlestickSets().last()->timestamp());
428 dateTime = dateTime.addMonths(1);
429 } else {
430 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
431 dateTime.setTime(QTime(12, 34, 56, 789));
432 }
433
434 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
435 series->append(set);
436 }
437
438 updateAxes();
439 }
440
441 void MainWidget::insertSet()
442 {
443 if (m_chart->series().isEmpty()) {
444 qDebug() << "Create a series first";
445 return;
446 }
447
448 foreach (QAbstractSeries *s, m_chart->series()) {
449 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
450
451 QDateTime dateTime;
452 if (series->count()) {
453 dateTime.setMSecsSinceEpoch(series->candlestickSets().first()->timestamp());
454 dateTime = dateTime.addMonths(-1);
455 } else {
456 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
457 dateTime.setTime(QTime(12, 34, 56, 789));
458 }
459
460 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
461 series->insert(0, set);
462 }
463
464 updateAxes();
465 }
466
467 void MainWidget::removeSet()
468 {
469 if (m_chart->series().isEmpty()) {
470 qDebug() << "Create a series first";
471 return;
472 }
473
474 foreach (QAbstractSeries *s, m_chart->series()) {
475 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
476 if (series->candlestickSets().isEmpty())
477 qDebug() << "Create a set first";
478 else
479 series->remove(series->candlestickSets().last());
480 }
481
482 updateAxes();
483 }
484
485 void MainWidget::removeAllSets()
486 {
487 if (m_chart->series().isEmpty()) {
488 qDebug() << "Create a series first";
489 return;
490 }
491
492 foreach (QAbstractSeries *s, m_chart->series()) {
493 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
494 if (series->candlestickSets().isEmpty())
495 qDebug() << "Create a set first";
496 else
497 series->clear();
498 }
499
500 updateAxes();
501 }
502
503 void MainWidget::changeMaximumColumnWidth(double width)
504 {
505 m_maximumColumnWidth = width;
506 foreach (QAbstractSeries *s, m_chart->series()) {
507 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
508 series->setMaximumColumnWidth(m_maximumColumnWidth);
509 }
510 }
511
512 void MainWidget::changeMinimumColumnWidth(double width)
513 {
514 m_minimumColumnWidth = width;
515 foreach (QAbstractSeries *s, m_chart->series()) {
516 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
517 series->setMinimumColumnWidth(m_minimumColumnWidth);
518 }
519 }
520
521 void MainWidget::bodyOutlineVisibleToggled(bool visible)
522 {
523 m_bodyOutlineVisible = visible;
524 foreach (QAbstractSeries *s, m_chart->series()) {
525 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
526 series->setBodyOutlineVisible(m_bodyOutlineVisible);
527 }
528 }
529
530 void MainWidget::capsVisibleToggled(bool visible)
531 {
532 m_capsVisible = visible;
533 foreach (QAbstractSeries *s, m_chart->series()) {
534 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
535 series->setCapsVisible(m_capsVisible);
536 }
537 }
538
539 void MainWidget::changeBodyWidth(double width)
540 {
541 m_bodyWidth = width;
542 foreach (QAbstractSeries *s, m_chart->series()) {
543 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
544 series->setBodyWidth(m_bodyWidth);
545 }
546 }
547
548 void MainWidget::changeCapsWidth(double width)
549 {
550 m_capsWidth = width;
551 foreach (QAbstractSeries *s, m_chart->series()) {
552 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
553 series->setCapsWidth(m_capsWidth);
554 }
555 }
556
557 void MainWidget::customIncreasingColorToggled(bool custom)
558 {
559 m_customIncreasingColor = custom;
560
561 if (m_chart->series().isEmpty())
562 return;
563
564 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
565 if (series) {
566 QColor color = m_customIncreasingColor ? QColor(Qt::green) : QColor();
567 series->setIncreasingColor(color);
568 }
569 }
570
571 void MainWidget::customDecreasingColorToggled(bool custom)
572 {
573 m_customDecreasingColor = custom;
574
575 if (m_chart->series().isEmpty())
576 return;
577
578 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
579 if (series) {
580 QColor color = m_customDecreasingColor ? QColor(Qt::red) : QColor();
581 series->setDecreasingColor(color);
582 }
583 }
584
585 void MainWidget::antialiasingToggled(bool enabled)
586 {
587 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
588 }
589
590 void MainWidget::animationToggled(bool enabled)
591 {
592 if (enabled)
593 m_chart->setAnimationOptions(QChart::SeriesAnimations);
594 else
595 m_chart->setAnimationOptions(QChart::NoAnimation);
596 }
597
598 void MainWidget::legendToggled(bool visible)
599 {
600 m_chart->legend()->setVisible(visible);
601 if (visible)
602 m_chart->legend()->setAlignment(Qt::AlignBottom);
603 }
604
605 void MainWidget::titleToggled(bool visible)
606 {
607 if (visible)
608 m_chart->setTitle(QStringLiteral("Candlestick Chart"));
609 else
610 m_chart->setTitle(QString());
611 }
612
613 void MainWidget::changeChartTheme(int themeIndex)
614 {
615 if (themeIndex < QChart::ChartThemeLight || themeIndex > QChart::ChartThemeQt) {
616 qDebug() << "Invalid chart theme index:" << themeIndex;
617 return;
618 }
619
620 m_chart->setTheme((QChart::ChartTheme)(themeIndex));
621 }
622
623 void MainWidget::changeAxisX(int axisXIndex)
624 {
625 if (m_axisX) {
626 m_chart->removeAxis(m_axisX);
627 delete m_axisX;
628 }
629
630 switch (axisXIndex) {
631 case 0:
632 m_axisX = new QBarCategoryAxis();
633 break;
634 case 1:
635 m_axisX = new QDateTimeAxis();
636 break;
637 case 2:
638 m_axisX = new QValueAxis();
639 break;
640 default:
641 qDebug() << "Invalid axis x index:" << axisXIndex;
642 return;
643 }
644
645 m_chart->addAxis(m_axisX, Qt::AlignBottom);
646
647 updateAxes();
648
649 foreach (QAbstractSeries *series, m_chart->series())
650 series->attachAxis(m_axisX);
651 }
652
653 void MainWidget::attachModelMapper()
654 {
655 if (m_hModelMapper->series()) {
656 qDebug() << "Model mapper is already attached";
657 return;
658 }
659
660 if (m_chart->series().isEmpty())
661 addSeries();
662
663 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
664 Q_ASSERT(series);
665 series->setName(QStringLiteral("SWMM")); // Series With Model Mapper
666
667 CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
668 foreach (QCandlestickSet *set, series->candlestickSets())
669 model->addRow(set);
670
671 m_hModelMapper->setFirstCandlestickSetRow(0);
672 m_hModelMapper->setLastCandlestickSetRow(model->rowCount() - 1);
673 m_hModelMapper->setSeries(series);
674 }
675
676 void MainWidget::detachModelMapper()
677 {
678 if (!m_hModelMapper->series())
679 return;
680
681 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_hModelMapper->series());
682 Q_ASSERT(series);
683 series->setName(QStringLiteral("S1"));
684
685 m_hModelMapper->setSeries(nullptr);
686 m_hModelMapper->setFirstCandlestickSetRow(-1);
687 m_hModelMapper->setLastCandlestickSetRow(-1);
688
689 CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
690 model->clearRows();
691 }
@@ -0,0 +1,108
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 #ifndef MAINWIDGET_H
31 #define MAINWIDGET_H
32
33 #include <QtCharts/QChartView>
34 #include <QtWidgets/QWidget>
35
36 QT_BEGIN_NAMESPACE
37 class QGridLayout;
38 QT_END_NAMESPACE
39
40 QT_CHARTS_BEGIN_NAMESPACE
41 class QCandlestickSet;
42 class QHCandlestickModelMapper;
43 QT_CHARTS_END_NAMESPACE
44
45 QT_CHARTS_USE_NAMESPACE
46
47 class MainWidget : public QWidget
48 {
49 Q_OBJECT
50
51 public:
52 explicit MainWidget(QWidget *parent = nullptr);
53 ~MainWidget();
54
55 private:
56 QGridLayout *createSeriesControlsLayout();
57 QGridLayout *createSetsControlsLayout();
58 QGridLayout *createCandlestickControlsLayout();
59 QGridLayout *createMiscellaneousControlsLayout();
60 QGridLayout *createModelMapperControlsLayout();
61
62 qreal randomValue(int min, int max) const;
63 QCandlestickSet *randomSet(qreal timestamp);
64
65 void updateAxes();
66
67 private slots:
68 void addSeries();
69 void removeSeries();
70 void removeAllSeries();
71 void addSet();
72 void insertSet();
73 void removeSet();
74 void removeAllSets();
75 void changeMaximumColumnWidth(double width);
76 void changeMinimumColumnWidth(double width);
77 void bodyOutlineVisibleToggled(bool visible);
78 void capsVisibleToggled(bool visible);
79 void changeBodyWidth(double width);
80 void changeCapsWidth(double width);
81 void customIncreasingColorToggled(bool custom);
82 void customDecreasingColorToggled(bool custom);
83 void antialiasingToggled(bool enabled);
84 void animationToggled(bool enabled);
85 void legendToggled(bool visible);
86 void titleToggled(bool visible);
87 void changeChartTheme(int themeIndex);
88 void changeAxisX(int axisXIndex);
89 void attachModelMapper();
90 void detachModelMapper();
91
92 private:
93 QChart *m_chart;
94 QChartView *m_chartView;
95 QAbstractAxis *m_axisX;
96 QAbstractAxis *m_axisY;
97 qreal m_maximumColumnWidth;
98 qreal m_minimumColumnWidth;
99 bool m_bodyOutlineVisible;
100 bool m_capsVisible;
101 qreal m_bodyWidth;
102 qreal m_capsWidth;
103 bool m_customIncreasingColor;
104 bool m_customDecreasingColor;
105 QHCandlestickModelMapper *m_hModelMapper;
106 };
107
108 #endif // MAINWIDGET_H
@@ -14,6 +14,7 SUBDIRS += areachart \
14 modeldata \
14 modeldata \
15 barchart \
15 barchart \
16 boxplotchart \
16 boxplotchart \
17 candlestickchart \
17 legend \
18 legend \
18 barmodelmapper \
19 barmodelmapper \
19 lineandbar \
20 lineandbar \
@@ -36,6 +37,7 SUBDIRS += areachart \
36
37
37 qtHaveModule(quick) {
38 qtHaveModule(quick) {
38 SUBDIRS += qmlboxplot \
39 SUBDIRS += qmlboxplot \
40 qmlcandlestick \
39 qmlpiechart \
41 qmlpiechart \
40 qmlweather \
42 qmlweather \
41 qmlf1legends \
43 qmlf1legends \
@@ -11,6 +11,8 SOURCES += \
11 $$PWD/scatteranimation.cpp \
11 $$PWD/scatteranimation.cpp \
12 $$PWD/boxplotanimation.cpp \
12 $$PWD/boxplotanimation.cpp \
13 $$PWD/boxwhiskersanimation.cpp \
13 $$PWD/boxwhiskersanimation.cpp \
14 $$PWD/candlestickanimation.cpp \
15 $$PWD/candlestickbodywicksanimation.cpp \
14 $$PWD/chartanimation.cpp
16 $$PWD/chartanimation.cpp
15
17
16 PRIVATE_HEADERS += \
18 PRIVATE_HEADERS += \
@@ -23,4 +25,6 PRIVATE_HEADERS += \
23 $$PWD/baranimation_p.h \
25 $$PWD/baranimation_p.h \
24 $$PWD/scatteranimation_p.h \
26 $$PWD/scatteranimation_p.h \
25 $$PWD/boxplotanimation_p.h \
27 $$PWD/boxplotanimation_p.h \
26 $$PWD/boxwhiskersanimation_p.h
28 $$PWD/boxwhiskersanimation_p.h \
29 $$PWD/candlestickanimation_p.h \
30 $$PWD/candlestickbodywicksanimation_p.h
@@ -983,6 +983,7 void QAbstractBarSeriesPrivate::initializeAxes()
983 case QAbstractSeries::SeriesTypePercentBar:
983 case QAbstractSeries::SeriesTypePercentBar:
984 case QAbstractSeries::SeriesTypeStackedBar:
984 case QAbstractSeries::SeriesTypeStackedBar:
985 case QAbstractSeries::SeriesTypeBoxPlot:
985 case QAbstractSeries::SeriesTypeBoxPlot:
986 case QAbstractSeries::SeriesTypeCandlestick:
986 if (axis->orientation() == Qt::Horizontal)
987 if (axis->orientation() == Qt::Horizontal)
987 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
988 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
988 break;
989 break;
@@ -1009,6 +1010,7 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientati
1009 case QAbstractSeries::SeriesTypePercentBar:
1010 case QAbstractSeries::SeriesTypePercentBar:
1010 case QAbstractSeries::SeriesTypeStackedBar:
1011 case QAbstractSeries::SeriesTypeStackedBar:
1011 case QAbstractSeries::SeriesTypeBoxPlot:
1012 case QAbstractSeries::SeriesTypeBoxPlot:
1013 case QAbstractSeries::SeriesTypeCandlestick:
1012 if (orientation == Qt::Horizontal)
1014 if (orientation == Qt::Horizontal)
1013 return QAbstractAxis::AxisTypeBarCategory;
1015 return QAbstractAxis::AxisTypeBarCategory;
1014 break;
1016 break;
@@ -153,20 +153,19 void ChartDataSet::addAxis(QAbstractAxis *axis, Qt::Alignment aligment)
153 */
153 */
154 void ChartDataSet::removeSeries(QAbstractSeries *series)
154 void ChartDataSet::removeSeries(QAbstractSeries *series)
155 {
155 {
156
157 if (! m_seriesList.contains(series)) {
156 if (! m_seriesList.contains(series)) {
158 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
157 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
159 return;
158 return;
160 }
159 }
161
160
162 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
161 QList<QAbstractAxis *> axes = series->d_ptr->m_axes;
163
162
164 foreach(QAbstractAxis* axis, axes) {
163 foreach (QAbstractAxis *axis, axes) {
165 detachAxis(series,axis);
164 detachAxis(series, axis);
166 }
165 }
167
166
168 emit seriesRemoved(series);
169 m_seriesList.removeAll(series);
167 m_seriesList.removeAll(series);
168 emit seriesRemoved(series);
170
169
171 // Reset domain to default
170 // Reset domain to default
172 series->d_ptr->setDomain(new XYDomain());
171 series->d_ptr->setDomain(new XYDomain());
@@ -79,6 +79,7 public:
79 ScatterSeriesZValue = SeriesZValue,
79 ScatterSeriesZValue = SeriesZValue,
80 PieSeriesZValue = SeriesZValue,
80 PieSeriesZValue = SeriesZValue,
81 BoxPlotSeriesZValue = SeriesZValue,
81 BoxPlotSeriesZValue = SeriesZValue,
82 CandlestickSeriesZValue = SeriesZValue,
82 LegendZValue,
83 LegendZValue,
83 TopMostZValue
84 TopMostZValue
84 };
85 };
@@ -77,6 +77,7 include($$PWD/themes/themes.pri)
77 include($$PWD/xychart/xychart.pri)
77 include($$PWD/xychart/xychart.pri)
78 include($$PWD/layout/layout.pri)
78 include($$PWD/layout/layout.pri)
79 include($$PWD/boxplotchart/boxplotchart.pri)
79 include($$PWD/boxplotchart/boxplotchart.pri)
80 include($$PWD/candlestickchart/candlestickchart.pri)
80
81
81 HEADERS += $$PUBLIC_HEADERS
82 HEADERS += $$PUBLIC_HEADERS
82 HEADERS += $$PRIVATE_HEADERS
83 HEADERS += $$PRIVATE_HEADERS
@@ -4,6 +4,7 INCLUDEPATH += $$PWD/ \
4 $$PWD/axis \
4 $$PWD/axis \
5 $$PWD/barchart \
5 $$PWD/barchart \
6 $$PWD/boxplotchart \
6 $$PWD/boxplotchart \
7 $$PWD/candlestickchart \
7 $$PWD/domain \
8 $$PWD/domain \
8 $$PWD/layout \
9 $$PWD/layout \
9 $$PWD/legend \
10 $$PWD/legend \
@@ -28,5 +28,5
28 ****************************************************************************/
28 ****************************************************************************/
29
29
30 //! [0]
30 //! [0]
31 import QtCharts 2.0
31 import QtCharts 2.2
32 //! [0]
32 //! [0]
@@ -50,7 +50,7
50 */
50 */
51
51
52 /*!
52 /*!
53 \qmlmodule QtCharts 2.1
53 \qmlmodule QtCharts 2.2
54 \title Qt Charts QML Types
54 \title Qt Charts QML Types
55 \ingroup qmlmodules
55 \ingroup qmlmodules
56
56
@@ -11,8 +11,9 SOURCES += \
11 $$PWD/qxylegendmarker.cpp \
11 $$PWD/qxylegendmarker.cpp \
12 $$PWD/qarealegendmarker.cpp \
12 $$PWD/qarealegendmarker.cpp \
13 $$PWD/legendscroller.cpp \
13 $$PWD/legendscroller.cpp \
14 $$PWD/qboxplotlegendmarker.cpp
14 $$PWD/qboxplotlegendmarker.cpp \
15
15 $$PWD/qcandlesticklegendmarker.cpp
16
16 PRIVATE_HEADERS += \
17 PRIVATE_HEADERS += \
17 $$PWD/legendscroller_p.h \
18 $$PWD/legendscroller_p.h \
18 $$PWD/qlegend_p.h \
19 $$PWD/qlegend_p.h \
@@ -23,9 +24,9 PRIVATE_HEADERS += \
23 $$PWD/qbarlegendmarker_p.h \
24 $$PWD/qbarlegendmarker_p.h \
24 $$PWD/qxylegendmarker_p.h \
25 $$PWD/qxylegendmarker_p.h \
25 $$PWD/qarealegendmarker_p.h \
26 $$PWD/qarealegendmarker_p.h \
26 $$PWD/qboxplotlegendmarker_p.h
27 $$PWD/qboxplotlegendmarker_p.h \
27
28 $$PWD/qcandlesticklegendmarker_p.h
28
29
29 PUBLIC_HEADERS += \
30 PUBLIC_HEADERS += \
30 $$PWD/qlegend.h \
31 $$PWD/qlegend.h \
31 $$PWD/qlegendmarker.h \
32 $$PWD/qlegendmarker.h \
@@ -33,4 +34,5 PUBLIC_HEADERS += \
33 $$PWD/qbarlegendmarker.h \
34 $$PWD/qbarlegendmarker.h \
34 $$PWD/qxylegendmarker.h \
35 $$PWD/qxylegendmarker.h \
35 $$PWD/qarealegendmarker.h \
36 $$PWD/qarealegendmarker.h \
36 $$PWD/qboxplotlegendmarker.h
37 $$PWD/qboxplotlegendmarker.h \
38 $$PWD/qcandlesticklegendmarker.h
@@ -88,8 +88,14 QBrush LegendMarkerItem::brush() const
88 void LegendMarkerItem::setFont(const QFont &font)
88 void LegendMarkerItem::setFont(const QFont &font)
89 {
89 {
90 m_textItem->setFont(font);
90 m_textItem->setFont(font);
91
91 QFontMetrics fn(font);
92 QFontMetrics fn(font);
92 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
93 QRectF markerRect = QRectF(0, 0, fn.height() / 2, fn.height() / 2);
94 if (m_markerRect != markerRect) {
95 m_markerRect = markerRect;
96 emit markerRectChanged();
97 }
98
93 updateGeometry();
99 updateGeometry();
94 }
100 }
95
101
@@ -152,6 +158,11 QRectF LegendMarkerItem::boundingRect() const
152 return m_boundingRect;
158 return m_boundingRect;
153 }
159 }
154
160
161 QRectF LegendMarkerItem::markerRect() const
162 {
163 return m_markerRect;
164 }
165
155 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
166 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
156 {
167 {
157 Q_UNUSED(option)
168 Q_UNUSED(option)
@@ -56,7 +56,7 class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem
56 Q_OBJECT
56 Q_OBJECT
57 Q_INTERFACES(QGraphicsLayoutItem)
57 Q_INTERFACES(QGraphicsLayoutItem)
58 public:
58 public:
59 explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = 0);
59 explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = nullptr);
60 ~LegendMarkerItem();
60 ~LegendMarkerItem();
61
61
62 void setPen(const QPen &pen);
62 void setPen(const QPen &pen);
@@ -76,8 +76,9 public:
76
76
77 void setGeometry(const QRectF &rect);
77 void setGeometry(const QRectF &rect);
78 QRectF boundingRect() const;
78 QRectF boundingRect() const;
79 QRectF markerRect() const;
79
80
80 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
81 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget = nullptr);
81 QSizeF sizeHint (Qt::SizeHint which, const QSizeF &constraint) const;
82 QSizeF sizeHint (Qt::SizeHint which, const QSizeF &constraint) const;
82
83
83 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
84 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
@@ -85,6 +86,10 public:
85
86
86 QString displayedLabel() const;
87 QString displayedLabel() const;
87 void setToolTip(const QString &tooltip);
88 void setToolTip(const QString &tooltip);
89
90 Q_SIGNALS:
91 void markerRectChanged();
92
88 protected:
93 protected:
89 QLegendMarkerPrivate *m_marker; // Knows
94 QLegendMarkerPrivate *m_marker; // Knows
90 QRectF m_markerRect;
95 QRectF m_markerRect;
@@ -63,6 +63,7 QT_CHARTS_BEGIN_NAMESPACE
63 \value LegendMarkerTypePie
63 \value LegendMarkerTypePie
64 \value LegendMarkerTypeXY
64 \value LegendMarkerTypeXY
65 \value LegendMarkerTypeBoxPlot
65 \value LegendMarkerTypeBoxPlot
66 \value LegendMarkerTypeCandlestick
66 */
67 */
67
68
68 /*!
69 /*!
@@ -52,7 +52,8 public:
52 LegendMarkerTypeBar,
52 LegendMarkerTypeBar,
53 LegendMarkerTypePie,
53 LegendMarkerTypePie,
54 LegendMarkerTypeXY,
54 LegendMarkerTypeXY,
55 LegendMarkerTypeBoxPlot
55 LegendMarkerTypeBoxPlot,
56 LegendMarkerTypeCandlestick
56 };
57 };
57
58
58 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
59 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
@@ -77,6 +77,7 QT_CHARTS_BEGIN_NAMESPACE
77 \value SeriesTypeHorizontalStackedBar
77 \value SeriesTypeHorizontalStackedBar
78 \value SeriesTypeHorizontalPercentBar
78 \value SeriesTypeHorizontalPercentBar
79 \value SeriesTypeBoxPlot
79 \value SeriesTypeBoxPlot
80 \value SeriesTypeCandlestick
80 */
81 */
81
82
82 /*!
83 /*!
@@ -63,11 +63,12 public:
63 SeriesTypeHorizontalBar,
63 SeriesTypeHorizontalBar,
64 SeriesTypeHorizontalStackedBar,
64 SeriesTypeHorizontalStackedBar,
65 SeriesTypeHorizontalPercentBar,
65 SeriesTypeHorizontalPercentBar,
66 SeriesTypeBoxPlot
66 SeriesTypeBoxPlot,
67 SeriesTypeCandlestick
67 };
68 };
68
69
69 protected:
70 protected:
70 QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent = Q_NULLPTR);
71 QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent = nullptr);
71
72
72 public:
73 public:
73 ~QAbstractSeries();
74 ~QAbstractSeries();
@@ -191,6 +191,7 protected:
191 friend class ChartThemeManager;
191 friend class ChartThemeManager;
192 friend class QAbstractSeries;
192 friend class QAbstractSeries;
193 friend class QBoxPlotSeriesPrivate;
193 friend class QBoxPlotSeriesPrivate;
194 friend class QCandlestickSeriesPrivate;
194
195
195 private:
196 private:
196 Q_DISABLE_COPY(QChart)
197 Q_DISABLE_COPY(QChart)
@@ -36,7 +36,8 SOURCES += \
36 declarativepolarchart.cpp \
36 declarativepolarchart.cpp \
37 declarativeboxplotseries.cpp \
37 declarativeboxplotseries.cpp \
38 declarativechartnode.cpp \
38 declarativechartnode.cpp \
39 declarativerendernode.cpp
39 declarativerendernode.cpp \
40 declarativecandlestickseries.cpp
40
41
41 HEADERS += \
42 HEADERS += \
42 declarativechart.h \
43 declarativechart.h \
@@ -54,7 +55,8 HEADERS += \
54 declarativepolarchart.h \
55 declarativepolarchart.h \
55 declarativeboxplotseries.h \
56 declarativeboxplotseries.h \
56 declarativechartnode.h \
57 declarativechartnode.h \
57 declarativerendernode.h
58 declarativerendernode.h \
59 declarativecandlestickseries.h
58
60
59 OTHER_FILES = qmldir
61 OTHER_FILES = qmldir
60
62
@@ -42,6 +42,7
42 #include "declarativescatterseries.h"
42 #include "declarativescatterseries.h"
43 #include "declarativebarseries.h"
43 #include "declarativebarseries.h"
44 #include "declarativeboxplotseries.h"
44 #include "declarativeboxplotseries.h"
45 #include "declarativecandlestickseries.h"
45 #include "declarativepieseries.h"
46 #include "declarativepieseries.h"
46 #include "declarativeaxes.h"
47 #include "declarativeaxes.h"
47 #include <QtCharts/QVXYModelMapper>
48 #include <QtCharts/QVXYModelMapper>
@@ -58,6 +59,9
58 #include <QtCharts/QBoxPlotModelMapper>
59 #include <QtCharts/QBoxPlotModelMapper>
59 #include <QtCharts/QHBoxPlotModelMapper>
60 #include <QtCharts/QHBoxPlotModelMapper>
60 #include <QtCharts/QVBoxPlotModelMapper>
61 #include <QtCharts/QVBoxPlotModelMapper>
62 #include <QtCharts/QCandlestickModelMapper>
63 #include <QtCharts/QHCandlestickModelMapper>
64 #include <QtCharts/QVCandlestickModelMapper>
61 #ifndef QT_QREAL_IS_FLOAT
65 #ifndef QT_QREAL_IS_FLOAT
62 #include <QtCharts/QDateTimeAxis>
66 #include <QtCharts/QDateTimeAxis>
63 #endif
67 #endif
@@ -78,6 +82,8 QML_DECLARE_TYPE(DeclarativeBarSeries)
78 QML_DECLARE_TYPE(DeclarativeBarSet)
82 QML_DECLARE_TYPE(DeclarativeBarSet)
79 QML_DECLARE_TYPE(DeclarativeBoxPlotSeries)
83 QML_DECLARE_TYPE(DeclarativeBoxPlotSeries)
80 QML_DECLARE_TYPE(DeclarativeBoxSet)
84 QML_DECLARE_TYPE(DeclarativeBoxSet)
85 QML_DECLARE_TYPE(DeclarativeCandlestickSeries)
86 QML_DECLARE_TYPE(DeclarativeCandlestickSet)
81 QML_DECLARE_TYPE(DeclarativeLineSeries)
87 QML_DECLARE_TYPE(DeclarativeLineSeries)
82 QML_DECLARE_TYPE(DeclarativePieSeries)
88 QML_DECLARE_TYPE(DeclarativePieSeries)
83 QML_DECLARE_TYPE(DeclarativePieSlice)
89 QML_DECLARE_TYPE(DeclarativePieSlice)
@@ -112,6 +118,9 QML_DECLARE_TYPE(QXYModelMapper)
112 QML_DECLARE_TYPE(QBoxPlotModelMapper)
118 QML_DECLARE_TYPE(QBoxPlotModelMapper)
113 QML_DECLARE_TYPE(QHBoxPlotModelMapper)
119 QML_DECLARE_TYPE(QHBoxPlotModelMapper)
114 QML_DECLARE_TYPE(QVBoxPlotModelMapper)
120 QML_DECLARE_TYPE(QVBoxPlotModelMapper)
121 QML_DECLARE_TYPE(QCandlestickModelMapper)
122 QML_DECLARE_TYPE(QHCandlestickModelMapper)
123 QML_DECLARE_TYPE(QVCandlestickModelMapper)
115
124
116 QML_DECLARE_TYPE(QAbstractSeries)
125 QML_DECLARE_TYPE(QAbstractSeries)
117 QML_DECLARE_TYPE(QXYSeries)
126 QML_DECLARE_TYPE(QXYSeries)
@@ -325,6 +334,14 public:
325 qmlRegisterType<DeclarativeScatterSeries, 5>(uri, 2, 1, "ScatterSeries");
334 qmlRegisterType<DeclarativeScatterSeries, 5>(uri, 2, 1, "ScatterSeries");
326 qmlRegisterType<DeclarativeLineSeries, 4>(uri, 2, 1, "LineSeries");
335 qmlRegisterType<DeclarativeLineSeries, 4>(uri, 2, 1, "LineSeries");
327 qmlRegisterType<DeclarativeSplineSeries, 4>(uri, 2, 1, "SplineSeries");
336 qmlRegisterType<DeclarativeSplineSeries, 4>(uri, 2, 1, "SplineSeries");
337
338 // QtCharts 2.2
339 qmlRegisterType<DeclarativeCandlestickSeries>(uri, 2, 2, "CandlestickSeries");
340 qmlRegisterType<DeclarativeCandlestickSet>(uri, 2, 2, "CandlestickSet");
341 qmlRegisterUncreatableType<QCandlestickModelMapper>(uri, 2, 2, "CandlestickModelMapper",
342 QLatin1String("Trying to create uncreatable: CandlestickModelMapper."));
343 qmlRegisterType<QHCandlestickModelMapper>(uri, 2, 2, "HCandlestickModelMapper");
344 qmlRegisterType<QVCandlestickModelMapper>(uri, 2, 2, "VCandlestickModelMapper");
328 }
345 }
329
346
330 };
347 };
@@ -35,6 +35,7
35 #include "declarativepieseries.h"
35 #include "declarativepieseries.h"
36 #include "declarativesplineseries.h"
36 #include "declarativesplineseries.h"
37 #include "declarativeboxplotseries.h"
37 #include "declarativeboxplotseries.h"
38 #include "declarativecandlestickseries.h"
38 #include "declarativescatterseries.h"
39 #include "declarativescatterseries.h"
39 #include "declarativechartnode.h"
40 #include "declarativechartnode.h"
40 #include "declarativerendernode.h"
41 #include "declarativerendernode.h"
@@ -1077,6 +1078,9 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstrac
1077 case DeclarativeChart::SeriesTypeBoxPlot:
1078 case DeclarativeChart::SeriesTypeBoxPlot:
1078 series = new DeclarativeBoxPlotSeries();
1079 series = new DeclarativeBoxPlotSeries();
1079 break;
1080 break;
1081 case DeclarativeChart::SeriesTypeCandlestick:
1082 series = new DeclarativeCandlestickSeries();
1083 break;
1080 case DeclarativeChart::SeriesTypePie:
1084 case DeclarativeChart::SeriesTypePie:
1081 series = new DeclarativePieSeries();
1085 series = new DeclarativePieSeries();
1082 break;
1086 break;
@@ -1189,6 +1193,8 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1189 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1193 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1190 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1194 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1191 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1195 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1196 else if (qobject_cast<DeclarativeCandlestickSeries *>(series))
1197 doInitializeAxes(series, qobject_cast<DeclarativeCandlestickSeries *>(series)->m_axes);
1192 // else: do nothing
1198 // else: do nothing
1193 }
1199 }
1194
1200
@@ -97,6 +97,7 public:
97 SeriesTypeStackedBar,
97 SeriesTypeStackedBar,
98 SeriesTypePercentBar,
98 SeriesTypePercentBar,
99 SeriesTypeBoxPlot,
99 SeriesTypeBoxPlot,
100 SeriesTypeCandlestick,
100 SeriesTypePie,
101 SeriesTypePie,
101 SeriesTypeScatter,
102 SeriesTypeScatter,
102 SeriesTypeSpline,
103 SeriesTypeSpline,
@@ -23,7 +23,10 SUBDIRS += \
23 domain \
23 domain \
24 chartdataset \
24 chartdataset \
25 qlegend \
25 qlegend \
26 cmake
26 cmake \
27 qcandlestickmodelmapper \
28 qcandlestickseries \
29 qcandlestickset
27
30
28 !contains(QT_COORD_TYPE, float): {
31 !contains(QT_COORD_TYPE, float): {
29 SUBDIRS += \
32 SUBDIRS += \
@@ -2,7 +2,8 TEMPLATE = subdirs
2 SUBDIRS += \
2 SUBDIRS += \
3 presenterchart \
3 presenterchart \
4 polarcharttest \
4 polarcharttest \
5 boxplottester
5 boxplottester \
6 candlesticktester
6
7
7 contains(QT_CONFIG, opengl) {
8 contains(QT_CONFIG, opengl) {
8 SUBDIRS += chartwidgettest \
9 SUBDIRS += chartwidgettest \
General Comments 0
You need to be logged in to leave comments. Login now