##// 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
1 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
@@ -1,66 +1,68
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += areachart \
3 3 customchart \
4 4 linechart \
5 5 percentbarchart \
6 6 piechart \
7 7 piechartdrilldown \
8 8 scatterchart \
9 9 scatterinteractions \
10 10 splinechart \
11 11 stackedbarchart \
12 12 stackedbarchartdrilldown \
13 13 zoomlinechart \
14 14 modeldata \
15 15 barchart \
16 16 boxplotchart \
17 candlestickchart \
17 18 legend \
18 19 barmodelmapper \
19 20 lineandbar \
20 21 horizontalbarchart \
21 22 horizontalstackedbarchart \
22 23 horizontalpercentbarchart \
23 24 donutbreakdown \
24 25 temperaturerecords \
25 26 donutchart \
26 27 multiaxis \
27 28 legendmarkers \
28 29 logvalueaxis \
29 30 polarchart \
30 31 piechartcustomization \
31 32 dynamicspline \
32 33 nesteddonuts \
33 34 chartinteractions \
34 35 callout \
35 36 chartthemes
36 37
37 38 qtHaveModule(quick) {
38 39 SUBDIRS += qmlboxplot \
40 qmlcandlestick \
39 41 qmlpiechart \
40 42 qmlweather \
41 43 qmlf1legends \
42 44 qmlcustomizations \
43 45 qmlaxes \
44 46 qmlcustomlegend \
45 47 qmlpolarchart \
46 48 qmlchart \
47 49 qmloscilloscope
48 50 }
49 51
50 52 qtHaveModule(multimedia) {
51 53 SUBDIRS += audio
52 54 } else {
53 55 message("QtMultimedia library not available. Some examples are disabled.")
54 56 }
55 57
56 58 contains(QT_CONFIG, opengl) {
57 59 SUBDIRS += openglseries
58 60 } else {
59 61 message("OpenGL not available. Some examples are disabled.")
60 62 }
61 63
62 64 !contains(QT_COORD_TYPE, float): {
63 65 SUBDIRS += \
64 66 datetimeaxis
65 67 }
66 68
@@ -1,26 +1,30
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/axisanimation.cpp \
6 6 $$PWD/xyanimation.cpp \
7 7 $$PWD/pieanimation.cpp \
8 8 $$PWD/piesliceanimation.cpp \
9 9 $$PWD/splineanimation.cpp \
10 10 $$PWD/baranimation.cpp \
11 11 $$PWD/scatteranimation.cpp \
12 12 $$PWD/boxplotanimation.cpp \
13 13 $$PWD/boxwhiskersanimation.cpp \
14 $$PWD/candlestickanimation.cpp \
15 $$PWD/candlestickbodywicksanimation.cpp \
14 16 $$PWD/chartanimation.cpp
15 17
16 18 PRIVATE_HEADERS += \
17 19 $$PWD/axisanimation_p.h \
18 20 $$PWD/chartanimation_p.h \
19 21 $$PWD/xyanimation_p.h \
20 22 $$PWD/pieanimation_p.h \
21 23 $$PWD/piesliceanimation_p.h \
22 24 $$PWD/splineanimation_p.h \
23 25 $$PWD/baranimation_p.h \
24 26 $$PWD/scatteranimation_p.h \
25 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
@@ -1,1104 +1,1106
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QAbstractBarSeries>
31 31 #include <private/qabstractbarseries_p.h>
32 32 #include <QtCharts/QBarSet>
33 33 #include <private/qbarset_p.h>
34 34 #include <private/abstractdomain_p.h>
35 35 #include <private/chartdataset_p.h>
36 36 #include <private/charttheme_p.h>
37 37 #include <QtCharts/QValueAxis>
38 38 #include <QtCharts/QBarCategoryAxis>
39 39 #include <QtCharts/QBarLegendMarker>
40 40 #include <private/baranimation_p.h>
41 41 #include <private/abstractbarchartitem_p.h>
42 42 #include <private/qchart_p.h>
43 43
44 44 QT_CHARTS_BEGIN_NAMESPACE
45 45
46 46 /*!
47 47 \class QAbstractBarSeries
48 48 \inmodule Qt Charts
49 49 \brief Series for creating a bar chart.
50 50
51 51 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
52 52 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
53 53 and y-value is the height of the bar. The category names are ignored with this series and x-axis
54 54 shows the x-values.
55 55
56 56 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
57 57 \image examples_barchart.png
58 58
59 59 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
60 60 */
61 61 /*!
62 62 \qmltype AbstractBarSeries
63 63 \instantiates QAbstractBarSeries
64 64 \inqmlmodule QtCharts
65 65
66 66 \inherits AbstractSeries
67 67
68 68 \brief Series type for creating a bar chart.
69 69
70 70 The following QML shows how to create a simple bar chart:
71 71 \snippet qmlchart/qml/qmlchart/View6.qml 1
72 72
73 73 \beginfloatleft
74 74 \image examples_qmlchart6.png
75 75 \endfloat
76 76 \clearfloat
77 77 */
78 78
79 79 /*!
80 80 \qmlproperty AbstractAxis AbstractBarSeries::axisX
81 81 The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
82 82 the series.
83 83 \sa axisXTop
84 84 */
85 85
86 86 /*!
87 87 \qmlproperty AbstractAxis AbstractBarSeries::axisY
88 88 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
89 89 the series.
90 90 \sa axisYRight
91 91 */
92 92
93 93 /*!
94 94 \qmlproperty AbstractAxis AbstractBarSeries::axisXTop
95 95 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
96 96 axisXTop, but not both.
97 97 \sa axisX
98 98 */
99 99
100 100 /*!
101 101 \qmlproperty AbstractAxis AbstractBarSeries::axisYRight
102 102 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
103 103 or axisYRight, but not both.
104 104 \sa axisY
105 105 */
106 106
107 107 /*!
108 108 \property QAbstractBarSeries::barWidth
109 109 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
110 110 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
111 111 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
112 112 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
113 113 \sa QBarSeries
114 114 */
115 115 /*!
116 116 \qmlproperty real AbstractBarSeries::barWidth
117 117 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
118 118 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
119 119 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
120 120 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
121 121 */
122 122
123 123 /*!
124 124 \property QAbstractBarSeries::count
125 125 Holds the number of sets in series.
126 126 */
127 127 /*!
128 128 \qmlproperty int AbstractBarSeries::count
129 129 Holds the number of sets in series.
130 130 */
131 131
132 132 /*!
133 133 \property QAbstractBarSeries::labelsVisible
134 134 Defines the visibility of the labels in series
135 135 */
136 136 /*!
137 137 \qmlproperty bool AbstractBarSeries::labelsVisible
138 138 Defines the visibility of the labels in series
139 139 */
140 140
141 141 /*!
142 142 \property QAbstractBarSeries::labelsFormat
143 143 The \a format used for showing labels in series.
144 144
145 145 QAbstractBarSeries supports the following format tag:
146 146 \table
147 147 \row
148 148 \li @value \li The value of the bar
149 149 \endtable
150 150
151 151 For example, the following usage of the format tags would produce labels that show the value
152 152 followed by unit ('u'):
153 153 \code
154 154 series->setLabelsFormat("@value u");
155 155 \endcode
156 156
157 157 By default, the labels shows the value of the bar. For percent bar series '%' is added after
158 158 the value. The labels are shown on the plot area, labels on the edge of the plot area are cut.
159 159 If the bars are close to each other the labels may overlap.
160 160
161 161 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsPosition
162 162 */
163 163 /*!
164 164 \qmlproperty string AbstractBarSeries::labelsFormat
165 165 The format used for showing labels in series.
166 166
167 167 \sa QAbstractBarSeries::labelsFormat, labelsVisible, labelsPosition
168 168 */
169 169 /*!
170 170 \fn void QAbstractBarSeries::labelsFormatChanged(const QString &format)
171 171 Signal is emitted when the \a format of data value labels is changed.
172 172 */
173 173 /*!
174 174 \qmlsignal XYSeries::onLabelsFormatChanged(string format)
175 175 Signal is emitted when the \a format of data value labels is changed.
176 176 */
177 177
178 178 /*!
179 179 \enum QAbstractBarSeries::LabelsPosition
180 180
181 181 This enum describes the position of the data value labels.
182 182
183 183 \value LabelsCenter Label is in the center of the bar.
184 184 \value LabelsInsideEnd Label is inside the bar at the high end of it.
185 185 \value LabelsInsideBase Label is inside the bar at the low end of it.
186 186 \value LabelsOutsideEnd Label is outside the bar at the high end of it.
187 187 */
188 188
189 189 /*!
190 190 \property QAbstractBarSeries::labelsPosition
191 191 Defines the \a position of value labels.
192 192
193 193 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsFormat
194 194 */
195 195 /*!
196 196 \qmlproperty string AbstractBarSeries::labelsPosition
197 197 Defines the \a position of value labels.
198 198
199 199 \sa labelsVisible, labelsFormat
200 200 */
201 201 /*!
202 202 \fn void QAbstractBarSeries::labelsPositionChanged(QAbstractBarSeries::LabelsPosition position)
203 203 Signal is emitted when the \a position of value labels is changed.
204 204 */
205 205 /*!
206 206 \qmlsignal AbstractBarSeries::onLabelsPositionChanged(LabelsPosition position)
207 207 Signal is emitted when the \a position of value labels is changed.
208 208 */
209 209
210 210 /*!
211 211 \property QAbstractBarSeries::labelsAngle
212 212 The angle of the value labels in degrees.
213 213 */
214 214 /*!
215 215 \qmlproperty qreal QAbstractBarSeries::labelsAngle
216 216 The angle of the value labels in degrees.
217 217 */
218 218 /*!
219 219 \fn void QAbstractBarSeries::labelsAngleChanged(qreal angle)
220 220 Signal is emitted when the \a angle of the value labels is changed.
221 221 */
222 222 /*!
223 223 \qmlsignal AbstractBarSeries::onLabelsAngleChanged(qreal angle)
224 224 Signal is emitted when the \a angle of the value labels is changed.
225 225 */
226 226
227 227 /*!
228 228 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
229 229 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
230 230 Clicked bar inside set is indexed by \a index
231 231 */
232 232 /*!
233 233 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
234 234 The signal is emitted if the user clicks with a mouse on top of BarSet.
235 235 Clicked bar inside set is indexed by \a index
236 236 */
237 237
238 238 /*!
239 239 \fn void QAbstractBarSeries::pressed(int index, QBarSet *barset)
240 240 The signal is emitted if the user presses with a mouse on top of QBarSet \a barset.
241 241 Pressed bar inside set is indexed by \a index
242 242 */
243 243 /*!
244 244 \qmlsignal AbstractBarSeries::onPressed(int index, BarSet barset)
245 245 The signal is emitted if the user presses with a mouse on top of BarSet.
246 246 Pressed bar inside set is indexed by \a index
247 247 */
248 248
249 249 /*!
250 250 \fn void QAbstractBarSeries::released(int index, QBarSet *barset)
251 251 The signal is emitted if the user releases with a mouse on top of QBarSet \a barset.
252 252 Released bar inside set is indexed by \a index
253 253 */
254 254 /*!
255 255 \qmlsignal AbstractBarSeries::onReleased(int index, BarSet barset)
256 256 The signal is emitted if the user releases with a mouse on top of BarSet.
257 257 Released bar inside set is indexed by \a index
258 258 */
259 259
260 260 /*!
261 261 \fn void QAbstractBarSeries::doubleClicked(int index, QBarSet *barset)
262 262 The signal is emitted if the user doubleclicks with a mouse on top of QBarSet \a barset.
263 263 DoubleClicked bar inside set is indexed by \a index
264 264 */
265 265 /*!
266 266 \qmlsignal AbstractBarSeries::onDoubleClicked(int index, BarSet barset)
267 267 The signal is emitted if the user doubleclicks with a mouse on top of BarSet.
268 268 Doubleclicked bar inside set is indexed by \a index
269 269 */
270 270
271 271 /*!
272 272 \fn void QAbstractBarSeries::hovered(bool status, int index, QBarSet* barset)
273 273
274 274 The signal is emitted if mouse is hovered on top of series.
275 275 Parameter \a barset is the pointer of barset, where hover happened.
276 276 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
277 277 Hovered bar inside the set is indexed by \a index.
278 278 */
279 279 /*!
280 280 \qmlsignal AbstractBarSeries::onHovered(bool status, int index, BarSet barset)
281 281
282 282 The signal is emitted if mouse is hovered on top of series.
283 283 Parameter \a barset is the pointer of barset, where hover happened.
284 284 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
285 285 Hovered bar inside the set is indexed by \a index.
286 286 */
287 287
288 288 /*!
289 289 \fn void QAbstractBarSeries::countChanged()
290 290 This signal is emitted when barset count has been changed, for example by append or remove.
291 291 */
292 292 /*!
293 293 \qmlsignal AbstractBarSeries::onCountChanged()
294 294 This signal is emitted when barset count has been changed, for example by append or remove.
295 295 */
296 296
297 297 /*!
298 298 \fn void QAbstractBarSeries::labelsVisibleChanged()
299 299 This signal is emitted when labels visibility have changed.
300 300 \sa isLabelsVisible(), setLabelsVisible()
301 301 */
302 302
303 303 /*!
304 304 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
305 305 This signal is emitted when \a sets have been added to the series.
306 306 \sa append(), insert()
307 307 */
308 308 /*!
309 309 \qmlsignal AbstractBarSeries::onBarsetsAdded(BarSet barset)
310 310 Emitted when \a barset has been added to the series.
311 311 */
312 312
313 313 /*!
314 314 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
315 315 This signal is emitted when \a sets have been removed from the series.
316 316 \sa remove()
317 317 */
318 318 /*!
319 319 \qmlsignal AbstractBarSeries::onBarsetsRemoved(BarSet barset)
320 320 Emitted when \a barset has been removed from the series.
321 321 */
322 322
323 323 /*!
324 324 \qmlmethod BarSet AbstractBarSeries::at(int index)
325 325 Returns bar set at \a index. Returns null if the index is not valid.
326 326 */
327 327
328 328 /*!
329 329 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
330 330 Adds a new bar set with \a label and \a values to \a index. Values is a list of reals.
331 331 For example:
332 332 \code
333 333 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
334 334 \endcode
335 335 */
336 336
337 337 /*!
338 338 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
339 339 Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
340 340 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
341 341 appended.
342 342 \sa AbstractBarSeries::append()
343 343 */
344 344
345 345 /*!
346 346 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
347 347 Removes the barset from the series. Returns true if successful, false otherwise.
348 348 */
349 349
350 350 /*!
351 351 \qmlmethod AbstractBarSeries::clear()
352 352 Removes all barsets from the series.
353 353 */
354 354
355 355 /*!
356 356 Destructs abstractbarseries and owned barsets.
357 357 */
358 358 QAbstractBarSeries::~QAbstractBarSeries()
359 359 {
360 360
361 361 }
362 362
363 363 /*!
364 364 \internal
365 365 */
366 366 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent)
367 367 : QAbstractSeries(o, parent)
368 368 {
369 369 Q_D(QAbstractSeries);
370 370 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
371 371 }
372 372
373 373 /*!
374 374 Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
375 375 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
376 376 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
377 377 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
378 378 */
379 379 void QAbstractBarSeries::setBarWidth(qreal width)
380 380 {
381 381 Q_D(QAbstractBarSeries);
382 382 d->setBarWidth(width);
383 383 }
384 384
385 385 /*!
386 386 Returns the width of the bars of the series.
387 387 \sa setBarWidth()
388 388 */
389 389 qreal QAbstractBarSeries::barWidth() const
390 390 {
391 391 Q_D(const QAbstractBarSeries);
392 392 return d->barWidth();
393 393 }
394 394
395 395 /*!
396 396 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
397 397 Returns true, if appending succeeded.
398 398 */
399 399 bool QAbstractBarSeries::append(QBarSet *set)
400 400 {
401 401 Q_D(QAbstractBarSeries);
402 402 bool success = d->append(set);
403 403 if (success) {
404 404 QList<QBarSet *> sets;
405 405 sets.append(set);
406 406 set->setParent(this);
407 407 emit barsetsAdded(sets);
408 408 emit countChanged();
409 409 }
410 410 return success;
411 411 }
412 412
413 413 /*!
414 414 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
415 415 was successful.
416 416 Returns true, if set was removed.
417 417 */
418 418 bool QAbstractBarSeries::remove(QBarSet *set)
419 419 {
420 420 Q_D(QAbstractBarSeries);
421 421 bool success = d->remove(set);
422 422 if (success) {
423 423 QList<QBarSet *> sets;
424 424 sets.append(set);
425 425 set->setParent(0);
426 426 emit barsetsRemoved(sets);
427 427 emit countChanged();
428 428 delete set;
429 429 set = 0;
430 430 }
431 431 return success;
432 432 }
433 433
434 434 /*!
435 435 Takes a single \a set from the series. Does not delete the barset object.
436 436
437 437 NOTE: The series remains as the barset's parent object. You must set the
438 438 parent object to take full ownership.
439 439
440 440 Returns true if take was successful.
441 441 */
442 442 bool QAbstractBarSeries::take(QBarSet *set)
443 443 {
444 444 Q_D(QAbstractBarSeries);
445 445 bool success = d->remove(set);
446 446 if (success) {
447 447 QList<QBarSet *> sets;
448 448 sets.append(set);
449 449 emit barsetsRemoved(sets);
450 450 emit countChanged();
451 451 }
452 452 return success;
453 453 }
454 454
455 455 /*!
456 456 Adds a list of barsets to series. Takes ownership of \a sets.
457 457 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
458 458 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
459 459 and function returns false.
460 460 */
461 461 bool QAbstractBarSeries::append(QList<QBarSet *> sets)
462 462 {
463 463 Q_D(QAbstractBarSeries);
464 464 bool success = d->append(sets);
465 465 if (success) {
466 466 foreach (QBarSet *set, sets)
467 467 set->setParent(this);
468 468 emit barsetsAdded(sets);
469 469 emit countChanged();
470 470 }
471 471 return success;
472 472 }
473 473
474 474 /*!
475 475 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
476 476 Returns true, if inserting succeeded.
477 477
478 478 */
479 479 bool QAbstractBarSeries::insert(int index, QBarSet *set)
480 480 {
481 481 Q_D(QAbstractBarSeries);
482 482 bool success = d->insert(index, set);
483 483 if (success) {
484 484 QList<QBarSet *> sets;
485 485 sets.append(set);
486 486 emit barsetsAdded(sets);
487 487 emit countChanged();
488 488 }
489 489 return success;
490 490 }
491 491
492 492 /*!
493 493 Removes all barsets from the series. Deletes removed sets.
494 494 */
495 495 void QAbstractBarSeries::clear()
496 496 {
497 497 Q_D(QAbstractBarSeries);
498 498 QList<QBarSet *> sets = barSets();
499 499 bool success = d->remove(sets);
500 500 if (success) {
501 501 emit barsetsRemoved(sets);
502 502 emit countChanged();
503 503 foreach (QBarSet *set, sets)
504 504 delete set;
505 505 }
506 506 }
507 507
508 508 /*!
509 509 Returns number of sets in series.
510 510 */
511 511 int QAbstractBarSeries::count() const
512 512 {
513 513 Q_D(const QAbstractBarSeries);
514 514 return d->m_barSets.count();
515 515 }
516 516
517 517 /*!
518 518 Returns a list of sets in series. Keeps ownership of sets.
519 519 */
520 520 QList<QBarSet *> QAbstractBarSeries::barSets() const
521 521 {
522 522 Q_D(const QAbstractBarSeries);
523 523 return d->m_barSets;
524 524 }
525 525
526 526 /*!
527 527 Sets the visibility of labels in series to \a visible
528 528 */
529 529 void QAbstractBarSeries::setLabelsVisible(bool visible)
530 530 {
531 531 Q_D(QAbstractBarSeries);
532 532 if (d->m_labelsVisible != visible) {
533 533 d->setLabelsVisible(visible);
534 534 emit labelsVisibleChanged();
535 535 }
536 536 }
537 537
538 538 /*!
539 539 Returns the visibility of labels
540 540 */
541 541 bool QAbstractBarSeries::isLabelsVisible() const
542 542 {
543 543 Q_D(const QAbstractBarSeries);
544 544 return d->m_labelsVisible;
545 545 }
546 546
547 547 void QAbstractBarSeries::setLabelsFormat(const QString &format)
548 548 {
549 549 Q_D(QAbstractBarSeries);
550 550 if (d->m_labelsFormat != format) {
551 551 d->m_labelsFormat = format;
552 552 emit labelsFormatChanged(format);
553 553 }
554 554 }
555 555
556 556 QString QAbstractBarSeries::labelsFormat() const
557 557 {
558 558 Q_D(const QAbstractBarSeries);
559 559 return d->m_labelsFormat;
560 560 }
561 561
562 562 void QAbstractBarSeries::setLabelsAngle(qreal angle)
563 563 {
564 564 Q_D(QAbstractBarSeries);
565 565 if (d->m_labelsAngle != angle) {
566 566 d->m_labelsAngle = angle;
567 567 emit labelsAngleChanged(angle);
568 568 }
569 569 }
570 570
571 571 qreal QAbstractBarSeries::labelsAngle() const
572 572 {
573 573 Q_D(const QAbstractBarSeries);
574 574 return d->m_labelsAngle;
575 575 }
576 576
577 577 void QAbstractBarSeries::setLabelsPosition(QAbstractBarSeries::LabelsPosition position)
578 578 {
579 579 Q_D(QAbstractBarSeries);
580 580 if (d->m_labelsPosition != position) {
581 581 d->m_labelsPosition = position;
582 582 emit labelsPositionChanged(position);
583 583 }
584 584 }
585 585
586 586 QAbstractBarSeries::LabelsPosition QAbstractBarSeries::labelsPosition() const
587 587 {
588 588 Q_D(const QAbstractBarSeries);
589 589 return d->m_labelsPosition;
590 590 }
591 591
592 592 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
593 593
594 594 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
595 595 QAbstractSeriesPrivate(q),
596 596 m_barWidth(0.5), // Default value is 50% of category width
597 597 m_labelsVisible(false),
598 598 m_visible(true),
599 599 m_blockBarUpdate(false),
600 600 m_labelsFormat(),
601 601 m_labelsPosition(QAbstractBarSeries::LabelsCenter),
602 602 m_labelsAngle(0)
603 603 {
604 604 }
605 605
606 606 int QAbstractBarSeriesPrivate::categoryCount() const
607 607 {
608 608 // No categories defined. return count of longest set.
609 609 int count = 0;
610 610 for (int i = 0; i < m_barSets.count(); i++) {
611 611 if (m_barSets.at(i)->count() > count)
612 612 count = m_barSets.at(i)->count();
613 613 }
614 614
615 615 return count;
616 616 }
617 617
618 618 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
619 619 {
620 620 if (width < 0.0)
621 621 width = 0.0;
622 622 m_barWidth = width;
623 623 emit updatedLayout();
624 624 }
625 625
626 626 qreal QAbstractBarSeriesPrivate::barWidth() const
627 627 {
628 628 return m_barWidth;
629 629 }
630 630
631 631 QBarSet *QAbstractBarSeriesPrivate::barsetAt(int index)
632 632 {
633 633 return m_barSets.at(index);
634 634 }
635 635
636 636 void QAbstractBarSeriesPrivate::setVisible(bool visible)
637 637 {
638 638 m_visible = visible;
639 639 emit visibleChanged();
640 640 }
641 641
642 642 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
643 643 {
644 644 m_labelsVisible = visible;
645 645 emit labelsVisibleChanged(visible);
646 646 }
647 647
648 648 qreal QAbstractBarSeriesPrivate::min()
649 649 {
650 650 if (m_barSets.count() <= 0)
651 651 return 0;
652 652
653 653 qreal min = INT_MAX;
654 654
655 655 for (int i = 0; i < m_barSets.count(); i++) {
656 656 int categoryCount = m_barSets.at(i)->count();
657 657 for (int j = 0; j < categoryCount; j++) {
658 658 qreal temp = m_barSets.at(i)->at(j);
659 659 if (temp < min)
660 660 min = temp;
661 661 }
662 662 }
663 663 return min;
664 664 }
665 665
666 666 qreal QAbstractBarSeriesPrivate::max()
667 667 {
668 668 if (m_barSets.count() <= 0)
669 669 return 0;
670 670
671 671 qreal max = INT_MIN;
672 672
673 673 for (int i = 0; i < m_barSets.count(); i++) {
674 674 int categoryCount = m_barSets.at(i)->count();
675 675 for (int j = 0; j < categoryCount; j++) {
676 676 qreal temp = m_barSets.at(i)->at(j);
677 677 if (temp > max)
678 678 max = temp;
679 679 }
680 680 }
681 681
682 682 return max;
683 683 }
684 684
685 685 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
686 686 {
687 687 if ((set < 0) || (set >= m_barSets.count()))
688 688 return 0; // No set, no value.
689 689 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
690 690 return 0; // No category, no value.
691 691
692 692 return m_barSets.at(set)->at(category);
693 693 }
694 694
695 695 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
696 696 {
697 697 if ((set < 0) || (set >= m_barSets.count()))
698 698 return 0; // No set, no value.
699 699 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
700 700 return 0; // No category, no value.
701 701
702 702 qreal value = m_barSets.at(set)->at(category);
703 703 qreal sum = categorySum(category);
704 704 if (qFuzzyCompare(sum, 0))
705 705 return 0;
706 706
707 707 return value / sum;
708 708 }
709 709
710 710 qreal QAbstractBarSeriesPrivate::categorySum(int category)
711 711 {
712 712 qreal sum(0);
713 713 int count = m_barSets.count(); // Count sets
714 714 for (int set = 0; set < count; set++) {
715 715 if (category < m_barSets.at(set)->count())
716 716 sum += m_barSets.at(set)->at(category);
717 717 }
718 718 return sum;
719 719 }
720 720
721 721 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
722 722 {
723 723 qreal sum(0);
724 724 int count = m_barSets.count(); // Count sets
725 725 for (int set = 0; set < count; set++) {
726 726 if (category < m_barSets.at(set)->count())
727 727 sum += qAbs(m_barSets.at(set)->at(category));
728 728 }
729 729 return sum;
730 730 }
731 731
732 732 qreal QAbstractBarSeriesPrivate::maxCategorySum()
733 733 {
734 734 qreal max = INT_MIN;
735 735 int count = categoryCount();
736 736 for (int i = 0; i < count; i++) {
737 737 qreal sum = categorySum(i);
738 738 if (sum > max)
739 739 max = sum;
740 740 }
741 741 return max;
742 742 }
743 743
744 744 qreal QAbstractBarSeriesPrivate::minX()
745 745 {
746 746 if (m_barSets.count() <= 0)
747 747 return 0;
748 748
749 749 qreal min = INT_MAX;
750 750
751 751 for (int i = 0; i < m_barSets.count(); i++) {
752 752 int categoryCount = m_barSets.at(i)->count();
753 753 for (int j = 0; j < categoryCount; j++) {
754 754 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
755 755 if (temp < min)
756 756 min = temp;
757 757 }
758 758 }
759 759 return min;
760 760 }
761 761
762 762 qreal QAbstractBarSeriesPrivate::maxX()
763 763 {
764 764 if (m_barSets.count() <= 0)
765 765 return 0;
766 766
767 767 qreal max = INT_MIN;
768 768
769 769 for (int i = 0; i < m_barSets.count(); i++) {
770 770 int categoryCount = m_barSets.at(i)->count();
771 771 for (int j = 0; j < categoryCount; j++) {
772 772 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
773 773 if (temp > max)
774 774 max = temp;
775 775 }
776 776 }
777 777
778 778 return max;
779 779 }
780 780
781 781 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
782 782 {
783 783 // Returns top (sum of all positive values) of category.
784 784 // Returns 0, if all values are negative
785 785 qreal top(0);
786 786 int count = m_barSets.count();
787 787 for (int set = 0; set < count; set++) {
788 788 if (category < m_barSets.at(set)->count()) {
789 789 qreal temp = m_barSets.at(set)->at(category);
790 790 if (temp > 0) {
791 791 top += temp;
792 792 }
793 793 }
794 794 }
795 795 return top;
796 796 }
797 797
798 798 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
799 799 {
800 800 // Returns bottom (sum of all negative values) of category
801 801 // Returns 0, if all values are positive
802 802 qreal bottom(0);
803 803 int count = m_barSets.count();
804 804 for (int set = 0; set < count; set++) {
805 805 if (category < m_barSets.at(set)->count()) {
806 806 qreal temp = m_barSets.at(set)->at(category);
807 807 if (temp < 0) {
808 808 bottom += temp;
809 809 }
810 810 }
811 811 }
812 812 return bottom;
813 813 }
814 814
815 815 qreal QAbstractBarSeriesPrivate::top()
816 816 {
817 817 // Returns top of all categories
818 818 qreal top(0);
819 819 int count = categoryCount();
820 820 for (int i = 0; i < count; i++) {
821 821 qreal temp = categoryTop(i);
822 822 if (temp > top)
823 823 top = temp;
824 824 }
825 825 return top;
826 826 }
827 827
828 828 qreal QAbstractBarSeriesPrivate::bottom()
829 829 {
830 830 // Returns bottom of all categories
831 831 qreal bottom(0);
832 832 int count = categoryCount();
833 833 for (int i = 0; i < count; i++) {
834 834 qreal temp = categoryBottom(i);
835 835 if (temp < bottom)
836 836 bottom = temp;
837 837 }
838 838 return bottom;
839 839 }
840 840
841 841 bool QAbstractBarSeriesPrivate::blockBarUpdate()
842 842 {
843 843 return m_blockBarUpdate;
844 844 }
845 845
846 846 qreal QAbstractBarSeriesPrivate::labelsAngle() const
847 847 {
848 848 return m_labelsAngle;
849 849 }
850 850
851 851 void QAbstractBarSeriesPrivate::initializeDomain()
852 852 {
853 853 qreal minX(domain()->minX());
854 854 qreal minY(domain()->minY());
855 855 qreal maxX(domain()->maxX());
856 856 qreal maxY(domain()->maxY());
857 857
858 858 qreal seriesMinX = this->minX();
859 859 qreal seriesMaxX = this->maxX();
860 860 qreal y = max();
861 861 minX = qMin(minX, seriesMinX - (qreal)0.5);
862 862 minY = qMin(minY, y);
863 863 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
864 864 maxY = qMax(maxY, y);
865 865
866 866 domain()->setRange(minX, maxX, minY, maxY);
867 867 }
868 868
869 869 QList<QLegendMarker*> QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend)
870 870 {
871 871 Q_Q(QAbstractBarSeries);
872 872 QList<QLegendMarker*> markers;
873 873
874 874 foreach(QBarSet* set, q->barSets()) {
875 875 QBarLegendMarker* marker = new QBarLegendMarker(q,set,legend);
876 876 markers << marker;
877 877 }
878 878 return markers;
879 879 }
880 880
881 881
882 882 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
883 883 {
884 884 if ((m_barSets.contains(set)) || (set == 0))
885 885 return false; // Fail if set is already in list or set is null.
886 886
887 887 m_barSets.append(set);
888 888 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
889 889 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
890 890 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
891 891
892 892 emit restructuredBars(); // this notifies barchartitem
893 893 return true;
894 894 }
895 895
896 896 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
897 897 {
898 898 if (!m_barSets.contains(set))
899 899 return false; // Fail if set is not in list
900 900
901 901 m_barSets.removeOne(set);
902 902 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
903 903 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
904 904 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
905 905
906 906 emit restructuredBars(); // this notifies barchartitem
907 907 return true;
908 908 }
909 909
910 910 bool QAbstractBarSeriesPrivate::append(QList<QBarSet * > sets)
911 911 {
912 912 foreach (QBarSet *set, sets) {
913 913 if ((set == 0) || (m_barSets.contains(set)))
914 914 return false; // Fail if any of the sets is null or is already appended.
915 915 if (sets.count(set) != 1)
916 916 return false; // Also fail if same set is more than once in given list.
917 917 }
918 918
919 919 foreach (QBarSet *set, sets) {
920 920 m_barSets.append(set);
921 921 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
922 922 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
923 923 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
924 924 }
925 925
926 926 emit restructuredBars(); // this notifies barchartitem
927 927 return true;
928 928 }
929 929
930 930 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet * > sets)
931 931 {
932 932 if (sets.count() == 0)
933 933 return false;
934 934
935 935 foreach (QBarSet *set, sets) {
936 936 if ((set == 0) || (!m_barSets.contains(set)))
937 937 return false; // Fail if any of the sets is null or is not in series
938 938 if (sets.count(set) != 1)
939 939 return false; // Also fail if same set is more than once in given list.
940 940 }
941 941
942 942 foreach (QBarSet *set, sets) {
943 943 m_barSets.removeOne(set);
944 944 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
945 945 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
946 946 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
947 947 }
948 948
949 949 emit restructuredBars(); // this notifies barchartitem
950 950
951 951 return true;
952 952 }
953 953
954 954 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
955 955 {
956 956 if ((m_barSets.contains(set)) || (set == 0))
957 957 return false; // Fail if set is already in list or set is null.
958 958
959 959 m_barSets.insert(index, set);
960 960 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
961 961 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
962 962 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
963 963
964 964 emit restructuredBars(); // this notifies barchartitem
965 965 return true;
966 966 }
967 967
968 968 void QAbstractBarSeriesPrivate::initializeAxes()
969 969 {
970 970 Q_Q(QAbstractBarSeries);
971 971
972 972 foreach(QAbstractAxis* axis, m_axes) {
973 973
974 974 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
975 975 switch (q->type()) {
976 976 case QAbstractSeries::SeriesTypeHorizontalBar:
977 977 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
978 978 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
979 979 if (axis->orientation() == Qt::Vertical)
980 980 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
981 981 break;
982 982 case QAbstractSeries::SeriesTypeBar:
983 983 case QAbstractSeries::SeriesTypePercentBar:
984 984 case QAbstractSeries::SeriesTypeStackedBar:
985 985 case QAbstractSeries::SeriesTypeBoxPlot:
986 case QAbstractSeries::SeriesTypeCandlestick:
986 987 if (axis->orientation() == Qt::Horizontal)
987 988 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
988 989 break;
989 990 default:
990 991 qWarning() << "Unexpected series type";
991 992 break;
992 993 }
993 994 }
994 995 }
995 996 }
996 997
997 998 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
998 999 {
999 1000 Q_Q(const QAbstractBarSeries);
1000 1001
1001 1002 switch (q->type()) {
1002 1003 case QAbstractSeries::SeriesTypeHorizontalBar:
1003 1004 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
1004 1005 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
1005 1006 if (orientation == Qt::Vertical)
1006 1007 return QAbstractAxis::AxisTypeBarCategory;
1007 1008 break;
1008 1009 case QAbstractSeries::SeriesTypeBar:
1009 1010 case QAbstractSeries::SeriesTypePercentBar:
1010 1011 case QAbstractSeries::SeriesTypeStackedBar:
1011 1012 case QAbstractSeries::SeriesTypeBoxPlot:
1013 case QAbstractSeries::SeriesTypeCandlestick:
1012 1014 if (orientation == Qt::Horizontal)
1013 1015 return QAbstractAxis::AxisTypeBarCategory;
1014 1016 break;
1015 1017 default:
1016 1018 qWarning() << "Unexpected series type";
1017 1019 break;
1018 1020 }
1019 1021 return QAbstractAxis::AxisTypeValue;
1020 1022
1021 1023 }
1022 1024
1023 1025 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
1024 1026 {
1025 1027 QStringList categories;
1026 1028 if (axis->categories().isEmpty()) {
1027 1029 for (int i(1); i < categoryCount() + 1; i++)
1028 1030 categories << presenter()->numberToString(i);
1029 1031 axis->append(categories);
1030 1032 }
1031 1033 }
1032 1034
1033 1035 QAbstractAxis* QAbstractBarSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
1034 1036 {
1035 1037 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
1036 1038 return new QBarCategoryAxis;
1037 1039 else
1038 1040 return new QValueAxis;
1039 1041 }
1040 1042
1041 1043 void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
1042 1044 {
1043 1045 m_blockBarUpdate = true; // Ensures that the bars are not updated before the theme is ready
1044 1046
1045 1047 const QList<QGradient> gradients = theme->seriesGradients();
1046 1048
1047 1049 qreal takeAtPos = 0.5;
1048 1050 qreal step = 0.2;
1049 1051 if (m_barSets.count() > 1) {
1050 1052 step = 1.0 / (qreal) m_barSets.count();
1051 1053 if (m_barSets.count() % gradients.count())
1052 1054 step *= gradients.count();
1053 1055 else
1054 1056 step *= (gradients.count() - 1);
1055 1057 }
1056 1058
1057 1059 for (int i(0); i < m_barSets.count(); i++) {
1058 1060 int colorIndex = (index + i) % gradients.count();
1059 1061 if (i > 0 && i %gradients.count() == 0) {
1060 1062 // There is no dedicated base color for each sets, generate more colors
1061 1063 takeAtPos += step;
1062 1064 if (takeAtPos == 1.0)
1063 1065 takeAtPos += step;
1064 1066 takeAtPos -= (int) takeAtPos;
1065 1067 }
1066 1068 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_brush)
1067 1069 m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos));
1068 1070
1069 1071 // Pick label color from the opposite end of the gradient.
1070 1072 // 0.3 as a boundary seems to work well.
1071 1073 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_labelBrush) {
1072 1074 if (takeAtPos < 0.3)
1073 1075 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1));
1074 1076 else
1075 1077 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0));
1076 1078 }
1077 1079 if (forced || QChartPrivate::defaultPen() == m_barSets.at(i)->d_ptr->m_pen) {
1078 1080 QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
1079 1081 m_barSets.at(i)->setPen(c);
1080 1082 }
1081 1083 }
1082 1084 m_blockBarUpdate = false;
1083 1085 emit updatedBars();
1084 1086 }
1085 1087
1086 1088 void QAbstractBarSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
1087 1089 QEasingCurve &curve)
1088 1090 {
1089 1091 AbstractBarChartItem *bar = static_cast<AbstractBarChartItem *>(m_item.data());
1090 1092 Q_ASSERT(bar);
1091 1093 if (bar->animation())
1092 1094 bar->animation()->stopAndDestroyLater();
1093 1095
1094 1096 if (options.testFlag(QChart::SeriesAnimations))
1095 1097 bar->setAnimation(new BarAnimation(bar, duration, curve));
1096 1098 else
1097 1099 bar->setAnimation(0);
1098 1100 QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
1099 1101 }
1100 1102
1101 1103 #include "moc_qabstractbarseries.cpp"
1102 1104 #include "moc_qabstractbarseries_p.cpp"
1103 1105
1104 1106 QT_CHARTS_END_NAMESPACE
@@ -1,657 +1,656
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <private/chartdataset_p.h>
31 31 #include <private/chartpresenter_p.h>
32 32 #include <QtCharts/QChart>
33 33 #include <private/qchart_p.h>
34 34 #include <QtCharts/QValueAxis>
35 35 #include <QtCharts/QBarCategoryAxis>
36 36 #include <private/qvalueaxis_p.h>
37 37 #include <QtCharts/QCategoryAxis>
38 38 #include <private/qabstractseries_p.h>
39 39 #include <QtCharts/QAbstractBarSeries>
40 40 #include <QtCharts/QStackedBarSeries>
41 41 #include <QtCharts/QPercentBarSeries>
42 42 #include <QtCharts/QPieSeries>
43 43 #include <private/chartitem_p.h>
44 44 #include <private/xydomain_p.h>
45 45 #include <private/xypolardomain_p.h>
46 46 #include <private/xlogydomain_p.h>
47 47 #include <private/logxydomain_p.h>
48 48 #include <private/logxlogydomain_p.h>
49 49 #include <private/xlogypolardomain_p.h>
50 50 #include <private/logxypolardomain_p.h>
51 51 #include <private/logxlogypolardomain_p.h>
52 52 #include <private/glxyseriesdata_p.h>
53 53
54 54 #ifndef QT_QREAL_IS_FLOAT
55 55 #include <QtCharts/QDateTimeAxis>
56 56 #endif
57 57
58 58 QT_CHARTS_BEGIN_NAMESPACE
59 59
60 60 ChartDataSet::ChartDataSet(QChart *chart)
61 61 : QObject(chart),
62 62 m_chart(chart),
63 63 m_glXYSeriesDataManager(new GLXYSeriesDataManager(this))
64 64 {
65 65
66 66 }
67 67
68 68 ChartDataSet::~ChartDataSet()
69 69 {
70 70 deleteAllSeries();
71 71 deleteAllAxes();
72 72 }
73 73
74 74 /*
75 75 * This method adds series to chartdataset, series ownership is taken from caller.
76 76 */
77 77 void ChartDataSet::addSeries(QAbstractSeries *series)
78 78 {
79 79 if (m_seriesList.contains(series)) {
80 80 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
81 81 return;
82 82 }
83 83
84 84 // Ignore unsupported series added to polar chart
85 85 if (m_chart && m_chart->chartType() == QChart::ChartTypePolar) {
86 86 if (!(series->type() == QAbstractSeries::SeriesTypeArea
87 87 || series->type() == QAbstractSeries::SeriesTypeLine
88 88 || series->type() == QAbstractSeries::SeriesTypeScatter
89 89 || series->type() == QAbstractSeries::SeriesTypeSpline)) {
90 90 qWarning() << QObject::tr("Can not add series. Series type is not supported by a polar chart.");
91 91 return;
92 92 }
93 93 // Disable OpenGL for series in polar charts
94 94 series->setUseOpenGL(false);
95 95 series->d_ptr->setDomain(new XYPolarDomain());
96 96 // Set the correct domain for upper and lower series too
97 97 if (series->type() == QAbstractSeries::SeriesTypeArea) {
98 98 foreach (QObject *child, series->children()) {
99 99 if (qobject_cast<QAbstractSeries *>(child)) {
100 100 QAbstractSeries *childSeries = qobject_cast<QAbstractSeries *>(child);
101 101 childSeries->d_ptr->setDomain(new XYPolarDomain());
102 102 }
103 103 }
104 104 }
105 105 } else {
106 106 series->d_ptr->setDomain(new XYDomain());
107 107 }
108 108
109 109 series->d_ptr->initializeDomain();
110 110 m_seriesList.append(series);
111 111
112 112 series->setParent(this); // take ownership
113 113 series->d_ptr->m_chart = m_chart;
114 114
115 115 emit seriesAdded(series);
116 116 }
117 117
118 118 /*
119 119 * This method adds axis to chartdataset, axis ownership is taken from caller.
120 120 */
121 121 void ChartDataSet::addAxis(QAbstractAxis *axis, Qt::Alignment aligment)
122 122 {
123 123 if (m_axisList.contains(axis)) {
124 124 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
125 125 return;
126 126 }
127 127
128 128 axis->d_ptr->setAlignment(aligment);
129 129
130 130 if (!axis->alignment()) {
131 131 qWarning() << QObject::tr("No alignment specified !");
132 132 return;
133 133 };
134 134
135 135 AbstractDomain *newDomain;
136 136 if (m_chart && m_chart->chartType() == QChart::ChartTypePolar)
137 137 newDomain = new XYPolarDomain();
138 138 else
139 139 newDomain = new XYDomain();
140 140
141 141 QSharedPointer<AbstractDomain> domain(newDomain);
142 142 axis->d_ptr->initializeDomain(domain.data());
143 143
144 144 axis->setParent(this);
145 145 axis->d_ptr->m_chart = m_chart;
146 146 m_axisList.append(axis);
147 147
148 148 emit axisAdded(axis);
149 149 }
150 150
151 151 /*
152 152 * This method removes series form chartdataset, series ownership is passed back to caller.
153 153 */
154 154 void ChartDataSet::removeSeries(QAbstractSeries *series)
155 155 {
156
157 156 if (! m_seriesList.contains(series)) {
158 157 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
159 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) {
165 detachAxis(series,axis);
163 foreach (QAbstractAxis *axis, axes) {
164 detachAxis(series, axis);
166 165 }
167 166
168 emit seriesRemoved(series);
169 167 m_seriesList.removeAll(series);
168 emit seriesRemoved(series);
170 169
171 170 // Reset domain to default
172 171 series->d_ptr->setDomain(new XYDomain());
173 172 series->setParent(0);
174 173 series->d_ptr->m_chart = 0;
175 174
176 175 QXYSeries *xySeries = qobject_cast<QXYSeries *>(series);
177 176 if (xySeries)
178 177 m_glXYSeriesDataManager->removeSeries(xySeries);
179 178 }
180 179
181 180 /*
182 181 * This method removes axis form chartdataset, series ownership is passed back to caller.
183 182 */
184 183 void ChartDataSet::removeAxis(QAbstractAxis *axis)
185 184 {
186 185 if (! m_axisList.contains(axis)) {
187 186 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
188 187 return;
189 188 }
190 189
191 190 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
192 191
193 192 foreach(QAbstractSeries* s, series) {
194 193 detachAxis(s,axis);
195 194 }
196 195
197 196 emit axisRemoved(axis);
198 197 m_axisList.removeAll(axis);
199 198
200 199 axis->setParent(0);
201 200 axis->d_ptr->m_chart = 0;
202 201 }
203 202
204 203 /*
205 204 * This method attaches axis to series, return true if success.
206 205 */
207 206 bool ChartDataSet::attachAxis(QAbstractSeries *series,QAbstractAxis *axis)
208 207 {
209 208 Q_ASSERT(axis);
210 209
211 210 if (!series)
212 211 return false;
213 212
214 213 QList<QAbstractSeries *> attachedSeriesList = axis->d_ptr->m_series;
215 214 QList<QAbstractAxis *> attachedAxisList = series->d_ptr->m_axes;
216 215
217 216 if (!m_seriesList.contains(series)) {
218 217 qWarning() << QObject::tr("Can not find series on the chart.");
219 218 return false;
220 219 }
221 220
222 221 if (axis && !m_axisList.contains(axis)) {
223 222 qWarning() << QObject::tr("Can not find axis on the chart.");
224 223 return false;
225 224 }
226 225
227 226 if (attachedAxisList.contains(axis)) {
228 227 qWarning() << QObject::tr("Axis already attached to series.");
229 228 return false;
230 229 }
231 230
232 231 if (attachedSeriesList.contains(series)) {
233 232 qWarning() << QObject::tr("Axis already attached to series.");
234 233 return false;
235 234 }
236 235
237 236 AbstractDomain *domain = series->d_ptr->domain();
238 237 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
239 238
240 239 if (type == AbstractDomain::UndefinedDomain) return false;
241 240
242 241 if (domain->type() != type) {
243 242 AbstractDomain *old = domain;
244 243 domain = createDomain(type);
245 244 domain->setRange(old->minX(), old->maxX(), old->minY(), old->maxY());
246 245 // Initialize domain size to old domain size, as it won't get updated
247 246 // unless geometry changes.
248 247 domain->setSize(old->size());
249 248 }
250 249
251 250 if (!domain)
252 251 return false;
253 252
254 253 if (!domain->attachAxis(axis))
255 254 return false;
256 255
257 256 QList<AbstractDomain *> blockedDomains;
258 257 domain->blockRangeSignals(true);
259 258 blockedDomains << domain;
260 259
261 260 if (domain != series->d_ptr->domain()) {
262 261 foreach (QAbstractAxis *axis, series->d_ptr->m_axes) {
263 262 series->d_ptr->domain()->detachAxis(axis);
264 263 domain->attachAxis(axis);
265 264 foreach (QAbstractSeries *otherSeries, axis->d_ptr->m_series) {
266 265 if (otherSeries != series && otherSeries->d_ptr->domain()) {
267 266 if (!otherSeries->d_ptr->domain()->rangeSignalsBlocked()) {
268 267 otherSeries->d_ptr->domain()->blockRangeSignals(true);
269 268 blockedDomains << otherSeries->d_ptr->domain();
270 269 }
271 270 }
272 271 }
273 272 }
274 273 series->d_ptr->setDomain(domain);
275 274 series->d_ptr->initializeDomain();
276 275 }
277 276
278 277 series->d_ptr->m_axes<<axis;
279 278 axis->d_ptr->m_series<<series;
280 279
281 280 series->d_ptr->initializeAxes();
282 281 axis->d_ptr->initializeDomain(domain);
283 282 connect(axis, &QAbstractAxis::reverseChanged, this, &ChartDataSet::reverseChanged);
284 283 foreach (AbstractDomain *blockedDomain, blockedDomains)
285 284 blockedDomain->blockRangeSignals(false);
286 285
287 286 return true;
288 287 }
289 288
290 289 /*
291 290 * This method detaches axis to series, return true if success.
292 291 */
293 292 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
294 293 {
295 294 Q_ASSERT(series);
296 295 Q_ASSERT(axis);
297 296
298 297 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
299 298 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
300 299 AbstractDomain* domain = series->d_ptr->domain();
301 300
302 301 if (!m_seriesList.contains(series)) {
303 302 qWarning() << QObject::tr("Can not find series on the chart.");
304 303 return false;
305 304 }
306 305
307 306 if (axis && !m_axisList.contains(axis)) {
308 307 qWarning() << QObject::tr("Can not find axis on the chart.");
309 308 return false;
310 309 }
311 310
312 311 if (!attachedAxisList.contains(axis)) {
313 312 qWarning() << QObject::tr("Axis not attached to series.");
314 313 return false;
315 314 }
316 315
317 316 Q_ASSERT(axis->d_ptr->m_series.contains(series));
318 317
319 318 domain->detachAxis(axis);
320 319 series->d_ptr->m_axes.removeAll(axis);
321 320 axis->d_ptr->m_series.removeAll(series);
322 321 disconnect(axis, &QAbstractAxis::reverseChanged, this, &ChartDataSet::reverseChanged);
323 322 return true;
324 323 }
325 324
326 325 void ChartDataSet::createDefaultAxes()
327 326 {
328 327 if (m_seriesList.isEmpty())
329 328 return;
330 329
331 330 QAbstractAxis::AxisTypes typeX(0);
332 331 QAbstractAxis::AxisTypes typeY(0);
333 332
334 333 // Remove possibly existing axes
335 334 deleteAllAxes();
336 335
337 336 Q_ASSERT(m_axisList.isEmpty());
338 337
339 338 // Select the required axis x and axis y types based on the types of the current series
340 339 foreach(QAbstractSeries* s, m_seriesList) {
341 340 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
342 341 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
343 342 }
344 343
345 344 createAxes(typeX, Qt::Horizontal);
346 345 createAxes(typeY, Qt::Vertical);
347 346 }
348 347
349 348 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
350 349 {
351 350 QAbstractAxis *axis = 0;
352 351 //decide what axis should be created
353 352
354 353 switch (type) {
355 354 case QAbstractAxis::AxisTypeValue:
356 355 axis = new QValueAxis(this);
357 356 break;
358 357 case QAbstractAxis::AxisTypeBarCategory:
359 358 axis = new QBarCategoryAxis(this);
360 359 break;
361 360 case QAbstractAxis::AxisTypeCategory:
362 361 axis = new QCategoryAxis(this);
363 362 break;
364 363 #ifndef QT_QREAL_IS_FLOAT
365 364 case QAbstractAxis::AxisTypeDateTime:
366 365 axis = new QDateTimeAxis(this);
367 366 break;
368 367 #endif
369 368 default:
370 369 axis = 0;
371 370 break;
372 371 }
373 372
374 373 if (axis) {
375 374 //create one axis for all
376 375
377 376 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
378 377 qreal min = 0;
379 378 qreal max = 0;
380 379 findMinMaxForSeries(m_seriesList,orientation,min,max);
381 380 foreach(QAbstractSeries *s, m_seriesList) {
382 381 attachAxis(s,axis);
383 382 }
384 383 axis->setRange(min,max);
385 384 } else {
386 385 // Create separate axis for each series
387 386 foreach(QAbstractSeries *s, m_seriesList) {
388 387 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
389 388 if(axis) {
390 389 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
391 390 attachAxis(s,axis);
392 391 }
393 392 }
394 393 }
395 394 }
396 395
397 396 void ChartDataSet::findMinMaxForSeries(QList<QAbstractSeries *> series,Qt::Orientations orientation, qreal &min, qreal &max)
398 397 {
399 398 Q_ASSERT(!series.isEmpty());
400 399
401 400 AbstractDomain *domain = series.first()->d_ptr->domain();
402 401 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
403 402 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
404 403
405 404 for (int i = 1; i< series.size(); i++) {
406 405 AbstractDomain *domain = series[i]->d_ptr->domain();
407 406 min = qMin((orientation == Qt::Vertical) ? domain->minY() : domain->minX(), min);
408 407 max = qMax((orientation == Qt::Vertical) ? domain->maxY() : domain->maxX(), max);
409 408 }
410 409 if (min == max) {
411 410 min -= 0.5;
412 411 max += 0.5;
413 412 }
414 413 }
415 414
416 415 void ChartDataSet::deleteAllSeries()
417 416 {
418 417 foreach (QAbstractSeries *s , m_seriesList){
419 418 removeSeries(s);
420 419 s->deleteLater();
421 420 }
422 421 Q_ASSERT(m_seriesList.count() == 0);
423 422 }
424 423
425 424 void ChartDataSet::deleteAllAxes()
426 425 {
427 426 foreach (QAbstractAxis *a , m_axisList){
428 427 removeAxis(a);
429 428 a->deleteLater();
430 429 }
431 430 Q_ASSERT(m_axisList.count() == 0);
432 431 }
433 432
434 433 void ChartDataSet::zoomInDomain(const QRectF &rect)
435 434 {
436 435 QList<AbstractDomain*> domains;
437 436 foreach(QAbstractSeries *s, m_seriesList) {
438 437 AbstractDomain* domain = s->d_ptr->domain();
439 438 s->d_ptr->m_domain->blockRangeSignals(true);
440 439 domains<<domain;
441 440 }
442 441
443 442 foreach(AbstractDomain *domain, domains)
444 443 domain->zoomIn(rect);
445 444
446 445 foreach(AbstractDomain *domain, domains)
447 446 domain->blockRangeSignals(false);
448 447 }
449 448
450 449 void ChartDataSet::zoomOutDomain(const QRectF &rect)
451 450 {
452 451 QList<AbstractDomain*> domains;
453 452 foreach(QAbstractSeries *s, m_seriesList) {
454 453 AbstractDomain* domain = s->d_ptr->domain();
455 454 s->d_ptr->m_domain->blockRangeSignals(true);
456 455 domains<<domain;
457 456 }
458 457
459 458 foreach(AbstractDomain *domain, domains)
460 459 domain->zoomOut(rect);
461 460
462 461 foreach(AbstractDomain *domain, domains)
463 462 domain->blockRangeSignals(false);
464 463 }
465 464
466 465 void ChartDataSet::zoomResetDomain()
467 466 {
468 467 QList<AbstractDomain*> domains;
469 468 foreach (QAbstractSeries *s, m_seriesList) {
470 469 AbstractDomain *domain = s->d_ptr->domain();
471 470 s->d_ptr->m_domain->blockRangeSignals(true);
472 471 domains << domain;
473 472 }
474 473
475 474 foreach (AbstractDomain *domain, domains)
476 475 domain->zoomReset();
477 476
478 477 foreach (AbstractDomain *domain, domains)
479 478 domain->blockRangeSignals(false);
480 479 }
481 480
482 481 bool ChartDataSet::isZoomedDomain()
483 482 {
484 483 foreach (QAbstractSeries *s, m_seriesList) {
485 484 if (s->d_ptr->domain()->isZoomed())
486 485 return true;
487 486 }
488 487 return false;
489 488 }
490 489
491 490 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
492 491 {
493 492 QList<AbstractDomain*> domains;
494 493 foreach(QAbstractSeries *s, m_seriesList) {
495 494 AbstractDomain* domain = s->d_ptr->domain();
496 495 s->d_ptr->m_domain->blockRangeSignals(true);
497 496 domains<<domain;
498 497 }
499 498
500 499 foreach(AbstractDomain *domain, domains)
501 500 domain->move(dx, dy);
502 501
503 502 foreach(AbstractDomain *domain, domains)
504 503 domain->blockRangeSignals(false);
505 504 }
506 505
507 506 QPointF ChartDataSet::mapToValue(const QPointF &position, QAbstractSeries *series)
508 507 {
509 508 QPointF point;
510 509 if (series == 0 && !m_seriesList.isEmpty())
511 510 series = m_seriesList.first();
512 511
513 512 if (series && series->type() == QAbstractSeries::SeriesTypePie)
514 513 return point;
515 514
516 515 if (series && m_seriesList.contains(series))
517 516 point = series->d_ptr->m_domain->calculateDomainPoint(position - m_chart->plotArea().topLeft());
518 517 return point;
519 518 }
520 519
521 520 QPointF ChartDataSet::mapToPosition(const QPointF &value, QAbstractSeries *series)
522 521 {
523 522 QPointF point = m_chart->plotArea().topLeft();
524 523 if (series == 0 && !m_seriesList.isEmpty())
525 524 series = m_seriesList.first();
526 525
527 526 if (series && series->type() == QAbstractSeries::SeriesTypePie)
528 527 return QPoint(0, 0);
529 528
530 529 bool ok;
531 530 if (series && m_seriesList.contains(series))
532 531 point += series->d_ptr->m_domain->calculateGeometryPoint(value, ok);
533 532 return point;
534 533 }
535 534
536 535 QList<QAbstractAxis *> ChartDataSet::axes() const
537 536 {
538 537 return m_axisList;
539 538 }
540 539
541 540 QList<QAbstractSeries *> ChartDataSet::series() const
542 541 {
543 542 return m_seriesList;
544 543 }
545 544
546 545 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis *> axes)
547 546 {
548 547 enum Type {
549 548 Undefined = 0,
550 549 LogType = 0x1,
551 550 ValueType = 0x2
552 551 };
553 552
554 553 int horizontal(Undefined);
555 554 int vertical(Undefined);
556 555
557 556 // Assume cartesian chart type, unless chart is set
558 557 QChart::ChartType chartType(QChart::ChartTypeCartesian);
559 558 if (m_chart)
560 559 chartType = m_chart->chartType();
561 560
562 561 foreach (QAbstractAxis *axis, axes)
563 562 {
564 563 switch (axis->type()) {
565 564 case QAbstractAxis::AxisTypeLogValue:
566 565 if (axis->orientation() == Qt::Horizontal)
567 566 horizontal |= LogType;
568 567 if (axis->orientation() == Qt::Vertical)
569 568 vertical |= LogType;
570 569 break;
571 570 case QAbstractAxis::AxisTypeValue:
572 571 case QAbstractAxis::AxisTypeBarCategory:
573 572 case QAbstractAxis::AxisTypeCategory:
574 573 case QAbstractAxis::AxisTypeDateTime:
575 574 if (axis->orientation() == Qt::Horizontal)
576 575 horizontal |= ValueType;
577 576 if (axis->orientation() == Qt::Vertical)
578 577 vertical |= ValueType;
579 578 break;
580 579 default:
581 580 qWarning() << "Undefined type";
582 581 break;
583 582 }
584 583 }
585 584
586 585 if (vertical == Undefined)
587 586 vertical = ValueType;
588 587 if (horizontal == Undefined)
589 588 horizontal = ValueType;
590 589
591 590 if (vertical == ValueType && horizontal == ValueType) {
592 591 if (chartType == QChart::ChartTypeCartesian)
593 592 return AbstractDomain::XYDomain;
594 593 else if (chartType == QChart::ChartTypePolar)
595 594 return AbstractDomain::XYPolarDomain;
596 595 }
597 596
598 597 if (vertical == LogType && horizontal == ValueType) {
599 598 if (chartType == QChart::ChartTypeCartesian)
600 599 return AbstractDomain::XLogYDomain;
601 600 if (chartType == QChart::ChartTypePolar)
602 601 return AbstractDomain::XLogYPolarDomain;
603 602 }
604 603
605 604 if (vertical == ValueType && horizontal == LogType) {
606 605 if (chartType == QChart::ChartTypeCartesian)
607 606 return AbstractDomain::LogXYDomain;
608 607 else if (chartType == QChart::ChartTypePolar)
609 608 return AbstractDomain::LogXYPolarDomain;
610 609 }
611 610
612 611 if (vertical == LogType && horizontal == LogType) {
613 612 if (chartType == QChart::ChartTypeCartesian)
614 613 return AbstractDomain::LogXLogYDomain;
615 614 else if (chartType == QChart::ChartTypePolar)
616 615 return AbstractDomain::LogXLogYPolarDomain;
617 616 }
618 617
619 618 return AbstractDomain::UndefinedDomain;
620 619 }
621 620
622 621 //refactor create factory
623 622 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
624 623 {
625 624 switch (type)
626 625 {
627 626 case AbstractDomain::LogXLogYDomain:
628 627 return new LogXLogYDomain();
629 628 case AbstractDomain::XYDomain:
630 629 return new XYDomain();
631 630 case AbstractDomain::XLogYDomain:
632 631 return new XLogYDomain();
633 632 case AbstractDomain::LogXYDomain:
634 633 return new LogXYDomain();
635 634 case AbstractDomain::XYPolarDomain:
636 635 return new XYPolarDomain();
637 636 case AbstractDomain::XLogYPolarDomain:
638 637 return new XLogYPolarDomain();
639 638 case AbstractDomain::LogXYPolarDomain:
640 639 return new LogXYPolarDomain();
641 640 case AbstractDomain::LogXLogYPolarDomain:
642 641 return new LogXLogYPolarDomain();
643 642 default:
644 643 return 0;
645 644 }
646 645 }
647 646
648 647 void ChartDataSet::reverseChanged()
649 648 {
650 649 QAbstractAxis *axis = qobject_cast<QAbstractAxis *>(sender());
651 650 if (axis)
652 651 m_glXYSeriesDataManager->handleAxisReverseChanged(axis->d_ptr->m_series);
653 652 }
654 653
655 654 #include "moc_chartdataset_p.cpp"
656 655
657 656 QT_CHARTS_END_NAMESPACE
@@ -1,220 +1,221
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 // W A R N I N G
31 31 // -------------
32 32 //
33 33 // This file is not part of the Qt Chart API. It exists purely as an
34 34 // implementation detail. This header file may change from version to
35 35 // version without notice, or even be removed.
36 36 //
37 37 // We mean it.
38 38
39 39 #ifndef CHARTPRESENTER_H
40 40 #define CHARTPRESENTER_H
41 41
42 42 #include <QtCharts/QChartGlobal>
43 43 #include <QtCharts/QChart> //because of QChart::ChartThemeId
44 44 #include <private/glwidget_p.h>
45 45 #include <QtCore/QRectF>
46 46 #include <QtCore/QMargins>
47 47 #include <QtCore/QLocale>
48 48 #include <QtCore/QPointer>
49 49 #include <QtCore/QEasingCurve>
50 50
51 51 QT_CHARTS_BEGIN_NAMESPACE
52 52
53 53 class ChartItem;
54 54 class AxisItem;
55 55 class QAbstractSeries;
56 56 class ChartDataSet;
57 57 class AbstractDomain;
58 58 class ChartAxisElement;
59 59 class ChartAnimator;
60 60 class ChartBackground;
61 61 class ChartTitle;
62 62 class ChartAnimation;
63 63 class AbstractChartLayout;
64 64
65 65 class ChartPresenter: public QObject
66 66 {
67 67 Q_OBJECT
68 68 public:
69 69 enum ZValues {
70 70 BackgroundZValue = -1,
71 71 PlotAreaZValue,
72 72 ShadesZValue,
73 73 GridZValue,
74 74 AxisZValue,
75 75 SeriesZValue,
76 76 LineChartZValue = SeriesZValue,
77 77 SplineChartZValue = SeriesZValue,
78 78 BarSeriesZValue = SeriesZValue,
79 79 ScatterSeriesZValue = SeriesZValue,
80 80 PieSeriesZValue = SeriesZValue,
81 81 BoxPlotSeriesZValue = SeriesZValue,
82 CandlestickSeriesZValue = SeriesZValue,
82 83 LegendZValue,
83 84 TopMostZValue
84 85 };
85 86
86 87 enum State {
87 88 ShowState,
88 89 ScrollUpState,
89 90 ScrollDownState,
90 91 ScrollLeftState,
91 92 ScrollRightState,
92 93 ZoomInState,
93 94 ZoomOutState
94 95 };
95 96
96 97 ChartPresenter(QChart *chart, QChart::ChartType type);
97 98 virtual ~ChartPresenter();
98 99
99 100
100 101 void setGeometry(QRectF rect);
101 102 QRectF geometry() const;
102 103
103 104 QGraphicsItem *rootItem(){ return m_chart; }
104 105 ChartBackground *backgroundElement();
105 106 QAbstractGraphicsShapeItem *plotAreaElement();
106 107 ChartTitle *titleElement();
107 108 QList<ChartAxisElement *> axisItems() const;
108 109 QList<ChartItem *> chartItems() const;
109 110
110 111 QLegend *legend();
111 112
112 113 void setBackgroundBrush(const QBrush &brush);
113 114 QBrush backgroundBrush() const;
114 115
115 116 void setBackgroundPen(const QPen &pen);
116 117 QPen backgroundPen() const;
117 118
118 119 void setBackgroundRoundness(qreal diameter);
119 120 qreal backgroundRoundness() const;
120 121
121 122 void setPlotAreaBackgroundBrush(const QBrush &brush);
122 123 QBrush plotAreaBackgroundBrush() const;
123 124
124 125 void setPlotAreaBackgroundPen(const QPen &pen);
125 126 QPen plotAreaBackgroundPen() const;
126 127
127 128 void setTitle(const QString &title);
128 129 QString title() const;
129 130
130 131 void setTitleFont(const QFont &font);
131 132 QFont titleFont() const;
132 133
133 134 void setTitleBrush(const QBrush &brush);
134 135 QBrush titleBrush() const;
135 136
136 137 void setBackgroundVisible(bool visible);
137 138 bool isBackgroundVisible() const;
138 139
139 140 void setPlotAreaBackgroundVisible(bool visible);
140 141 bool isPlotAreaBackgroundVisible() const;
141 142
142 143 void setBackgroundDropShadowEnabled(bool enabled);
143 144 bool isBackgroundDropShadowEnabled() const;
144 145
145 146 void setLocalizeNumbers(bool localize);
146 147 inline bool localizeNumbers() const { return m_localizeNumbers; }
147 148 void setLocale(const QLocale &locale);
148 149 inline const QLocale &locale() const { return m_locale; }
149 150
150 151 void setVisible(bool visible);
151 152
152 153 void setAnimationOptions(QChart::AnimationOptions options);
153 154 QChart::AnimationOptions animationOptions() const;
154 155 void setAnimationDuration(int msecs);
155 156 int animationDuration() const { return m_animationDuration; }
156 157 void setAnimationEasingCurve(const QEasingCurve &curve);
157 158 QEasingCurve animationEasingCurve() const { return m_animationCurve; }
158 159
159 160 void startAnimation(ChartAnimation *animation);
160 161
161 162 void setState(State state,QPointF point);
162 163 State state() const { return m_state; }
163 164 QPointF statePoint() const { return m_statePoint; }
164 165 AbstractChartLayout *layout();
165 166
166 167 QChart::ChartType chartType() const { return m_chart->chartType(); }
167 168 QChart *chart() { return m_chart; }
168 169
169 170 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
170 171 static QString truncatedText(const QFont &font, const QString &text, qreal angle,
171 172 qreal maxWidth, qreal maxHeight, QRectF &boundingRect);
172 173 inline static qreal textMargin() { return qreal(0.5); }
173 174
174 175 QString numberToString(double value, char f = 'g', int prec = 6);
175 176 QString numberToString(int value);
176 177
177 178 void updateGLWidget();
178 179 void glSetUseWidget(bool enable) { m_glUseWidget = enable; }
179 180
180 181 private:
181 182 void createBackgroundItem();
182 183 void createPlotAreaBackgroundItem();
183 184 void createTitleItem();
184 185
185 186 public Q_SLOTS:
186 187 void handleSeriesAdded(QAbstractSeries *series);
187 188 void handleSeriesRemoved(QAbstractSeries *series);
188 189 void handleAxisAdded(QAbstractAxis *axis);
189 190 void handleAxisRemoved(QAbstractAxis *axis);
190 191
191 192 Q_SIGNALS:
192 193 void plotAreaChanged(const QRectF &plotArea);
193 194
194 195 private:
195 196 QChart *m_chart;
196 197 QList<ChartItem *> m_chartItems;
197 198 QList<ChartAxisElement *> m_axisItems;
198 199 QList<QAbstractSeries *> m_series;
199 200 QList<QAbstractAxis *> m_axes;
200 201 QChart::AnimationOptions m_options;
201 202 int m_animationDuration;
202 203 QEasingCurve m_animationCurve;
203 204 State m_state;
204 205 QPointF m_statePoint;
205 206 AbstractChartLayout *m_layout;
206 207 ChartBackground *m_background;
207 208 QAbstractGraphicsShapeItem *m_plotAreaBackground;
208 209 ChartTitle *m_title;
209 210 QRectF m_rect;
210 211 bool m_localizeNumbers;
211 212 QLocale m_locale;
212 213 #ifndef QT_NO_OPENGL
213 214 QPointer<GLWidget> m_glWidget;
214 215 #endif
215 216 bool m_glUseWidget;
216 217 };
217 218
218 219 QT_CHARTS_END_NAMESPACE
219 220
220 221 #endif /* CHARTPRESENTER_H */
@@ -1,98 +1,99
1 1 ############################# BUILD CONFIG ######################################
2 2
3 3 TARGET = QtCharts
4 4
5 5 message($$QT_CONFIG)
6 6 QT = core gui widgets
7 7 DEFINES += QT_CHARTS_LIBRARY
8 8 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
9 9
10 10 # Fix exports in static builds for applications linking charts module
11 11 static: MODULE_DEFINES += QT_CHARTS_STATICLIB
12 12
13 13 MODULE_INCNAME = QtCharts
14 14
15 15 QMAKE_DOCS = $$PWD/doc/qtcharts.qdocconf
16 16
17 17 load(qt_module)
18 18
19 19 QMAKE_TARGET_PRODUCT = "Qt Charts (Qt $$QT_VERSION)"
20 20 QMAKE_TARGET_DESCRIPTION = "Charts component for Qt."
21 21
22 22 ############################# SOURCES ##########################################
23 23
24 24 SOURCES += \
25 25 $$PWD/chartdataset.cpp \
26 26 $$PWD/chartpresenter.cpp \
27 27 $$PWD/chartthememanager.cpp \
28 28 $$PWD/qchart.cpp \
29 29 $$PWD/qchartview.cpp \
30 30 $$PWD/qabstractseries.cpp \
31 31 $$PWD/chartbackground.cpp \
32 32 $$PWD/chartelement.cpp \
33 33 $$PWD/chartitem.cpp \
34 34 $$PWD/scroller.cpp \
35 35 $$PWD/charttitle.cpp \
36 36 $$PWD/qpolarchart.cpp
37 37
38 38 contains(QT_CONFIG, opengl): SOURCES += $$PWD/glwidget.cpp
39 39
40 40 PRIVATE_HEADERS += \
41 41 $$PWD/chartdataset_p.h \
42 42 $$PWD/chartitem_p.h \
43 43 $$PWD/chartpresenter_p.h \
44 44 $$PWD/chartthememanager_p.h \
45 45 $$PWD/chartbackground_p.h \
46 46 $$PWD/chartelement_p.h \
47 47 $$PWD/chartconfig_p.h \
48 48 $$PWD/qchart_p.h \
49 49 $$PWD/qchartview_p.h \
50 50 $$PWD/scroller_p.h \
51 51 $$PWD/qabstractseries_p.h \
52 52 $$PWD/charttitle_p.h \
53 53 $$PWD/charthelpers_p.h
54 54
55 55 contains(QT_CONFIG, opengl): PRIVATE_HEADERS += $$PWD/glwidget_p.h
56 56
57 57 PUBLIC_HEADERS += \
58 58 $$PWD/qchart.h \
59 59 $$PWD/qchartglobal.h \
60 60 $$PWD/qabstractseries.h \
61 61 $$PWD/qchartview.h \
62 62 $$PWD/chartsnamespace.h \
63 63 $$PWD/qpolarchart.h
64 64
65 65 include($$PWD/common.pri)
66 66 include($$PWD/animations/animations.pri)
67 67 include($$PWD/areachart/areachart.pri)
68 68 include($$PWD/axis/axis.pri)
69 69 include($$PWD/domain/domain.pri)
70 70 include($$PWD/barchart/barchart.pri)
71 71 include($$PWD/legend/legend.pri)
72 72 include($$PWD/linechart/linechart.pri)
73 73 include($$PWD/piechart/piechart.pri)
74 74 include($$PWD/scatterchart/scatter.pri)
75 75 include($$PWD/splinechart/splinechart.pri)
76 76 include($$PWD/themes/themes.pri)
77 77 include($$PWD/xychart/xychart.pri)
78 78 include($$PWD/layout/layout.pri)
79 79 include($$PWD/boxplotchart/boxplotchart.pri)
80 include($$PWD/candlestickchart/candlestickchart.pri)
80 81
81 82 HEADERS += $$PUBLIC_HEADERS
82 83 HEADERS += $$PRIVATE_HEADERS
83 84 HEADERS += $$THEMES
84 85
85 86 OTHER_FILES += doc/qtcharts.qdocconf \
86 87 doc/src/* \
87 88 doc/images/*
88 89
89 90 msvc {
90 91 # Suppress "conversion from 'size_t' to 'int', possible loss of data" warnings in 64bit
91 92 # builds resulting from usage of str::sort
92 93 QMAKE_CXXFLAGS_WARN_ON += -wd4267
93 94 }
94 95
95 96 win32:!winrt:!wince {
96 97 # ChartThemeSystem uses Windows native API
97 98 LIBS += -luser32
98 99 }
@@ -1,15 +1,16
1 1 INCLUDEPATH += $$PWD/ \
2 2 $$PWD/animations \
3 3 $$PWD/areachart \
4 4 $$PWD/axis \
5 5 $$PWD/barchart \
6 6 $$PWD/boxplotchart \
7 $$PWD/candlestickchart \
7 8 $$PWD/domain \
8 9 $$PWD/layout \
9 10 $$PWD/legend \
10 11 $$PWD/linechart \
11 12 $$PWD/piechart \
12 13 $$PWD/scatterchart \
13 14 $$PWD/splinechart \
14 15 $$PWD/themes \
15 16 $$PWD/xychart
@@ -1,32 +1,32
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 //! [0]
31 import QtCharts 2.0
31 import QtCharts 2.2
32 32 //! [0]
@@ -1,88 +1,88
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 /*!
31 31 \module Qt Charts
32 32 \title Qt Charts C++ Classes
33 33 \ingroup modules
34 34
35 35 \brief C++ classes for the Qt Charts API.
36 36
37 37 Charts API is built on top of Qt Graphics View Framework. Charts can be displayed as QGraphicsWidget using the QChart class. However
38 38 there is also the convenience class QChartView, which is QWidget based. These enable us to quickly use Qt Charts as a normal Qt widget.
39 39
40 40 Each chart type is represented by the QAbstractSeries derived class. To create charts, the users have to use an instance of the related
41 41 series class and add it to a QChart instance.
42 42 \code
43 43 QLineSeries* series = new QLineSeries();
44 44 series->add(0, 6);
45 45 series->add(2, 4);
46 46 ...
47 47 chartView->chart()->addSeries(series);
48 48 chartView->chart()->createDefaultAxes();
49 49 \endcode
50 50 */
51 51
52 52 /*!
53 \qmlmodule QtCharts 2.1
53 \qmlmodule QtCharts 2.2
54 54 \title Qt Charts QML Types
55 55 \ingroup qmlmodules
56 56
57 57 \brief QML types for the Qt Charts API.
58 58
59 59 The Qt Charts QML API is an intuitive and simple way to show charts in your QML
60 60 applications.
61 61
62 62 Use the following QML to create a simple pie chart:
63 63 \image examples_qmlpiechart.png
64 64 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
65 65 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
66 66 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
67 67
68 68 \note Since Qt Creator 3.0 the project created with Qt Quick Application wizard based on
69 69 Qt Quick 2 template uses QGuiApplication by default. As Qt Charts utilizes Qt Graphics View
70 70 Framework for drawing, QApplication must be used. The project created with the wizard is
71 71 usable with Qt Charts after the QGuiApplication is replaced with QApplication.
72 72
73 73 \section1 QML Types
74 74 */
75 75
76 76 /*!
77 77 \group charts_examples
78 78 \ingroup all-examples
79 79 \title Qt Charts Examples
80 80
81 81 \brief Examples for the Qt Charts.
82 82
83 83 For some code examples, see one of the Qt Charts examples:
84 84
85 85 \section1 Examples
86 86
87 87 \annotatedlist qtcharts_examples
88 88 */
@@ -1,36 +1,38
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/qlegend.cpp \
6 6 $$PWD/legendlayout.cpp \
7 7 $$PWD/qlegendmarker.cpp \
8 8 $$PWD/qpielegendmarker.cpp \
9 9 $$PWD/legendmarkeritem.cpp \
10 10 $$PWD/qbarlegendmarker.cpp \
11 11 $$PWD/qxylegendmarker.cpp \
12 12 $$PWD/qarealegendmarker.cpp \
13 13 $$PWD/legendscroller.cpp \
14 $$PWD/qboxplotlegendmarker.cpp
15
14 $$PWD/qboxplotlegendmarker.cpp \
15 $$PWD/qcandlesticklegendmarker.cpp
16
16 17 PRIVATE_HEADERS += \
17 18 $$PWD/legendscroller_p.h \
18 19 $$PWD/qlegend_p.h \
19 20 $$PWD/legendlayout_p.h \
20 21 $$PWD/qlegendmarker_p.h \
21 22 $$PWD/legendmarkeritem_p.h \
22 23 $$PWD/qpielegendmarker_p.h \
23 24 $$PWD/qbarlegendmarker_p.h \
24 25 $$PWD/qxylegendmarker_p.h \
25 26 $$PWD/qarealegendmarker_p.h \
26 $$PWD/qboxplotlegendmarker_p.h
27
28
27 $$PWD/qboxplotlegendmarker_p.h \
28 $$PWD/qcandlesticklegendmarker_p.h
29
29 30 PUBLIC_HEADERS += \
30 31 $$PWD/qlegend.h \
31 32 $$PWD/qlegendmarker.h \
32 33 $$PWD/qpielegendmarker.h \
33 34 $$PWD/qbarlegendmarker.h \
34 35 $$PWD/qxylegendmarker.h \
35 36 $$PWD/qarealegendmarker.h \
36 $$PWD/qboxplotlegendmarker.h
37 $$PWD/qboxplotlegendmarker.h \
38 $$PWD/qcandlesticklegendmarker.h
@@ -1,215 +1,226
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtGui/QPainter>
31 31 #include <QtWidgets/QGraphicsSceneEvent>
32 32 #include <QtWidgets/QGraphicsTextItem>
33 33 #include <QtGui/QTextDocument>
34 34
35 35 #include <QtCharts/QLegend>
36 36 #include <private/qlegend_p.h>
37 37 #include <QtCharts/QLegendMarker>
38 38 #include <private/qlegendmarker_p.h>
39 39 #include <private/legendmarkeritem_p.h>
40 40 #include <private/chartpresenter_p.h>
41 41
42 42 QT_CHARTS_BEGIN_NAMESPACE
43 43
44 44 LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) :
45 45 QGraphicsObject(parent),
46 46 m_marker(marker),
47 47 m_markerRect(0,0,10.0,10.0),
48 48 m_boundingRect(0,0,0,0),
49 49 m_textItem(new QGraphicsTextItem(this)),
50 50 m_rectItem(new QGraphicsRectItem(this)),
51 51 m_margin(3),
52 52 m_space(4),
53 53 m_hovering(false),
54 54 m_pressPos(0, 0)
55 55 {
56 56 m_rectItem->setRect(m_markerRect);
57 57 m_textItem->document()->setDocumentMargin(ChartPresenter::textMargin());
58 58 setAcceptHoverEvents(true);
59 59 }
60 60
61 61 LegendMarkerItem::~LegendMarkerItem()
62 62 {
63 63 if (m_hovering) {
64 64 emit m_marker->q_ptr->hovered(false);
65 65 }
66 66 }
67 67
68 68 void LegendMarkerItem::setPen(const QPen &pen)
69 69 {
70 70 m_rectItem->setPen(pen);
71 71 }
72 72
73 73 QPen LegendMarkerItem::pen() const
74 74 {
75 75 return m_rectItem->pen();
76 76 }
77 77
78 78 void LegendMarkerItem::setBrush(const QBrush &brush)
79 79 {
80 80 m_rectItem->setBrush(brush);
81 81 }
82 82
83 83 QBrush LegendMarkerItem::brush() const
84 84 {
85 85 return m_rectItem->brush();
86 86 }
87 87
88 88 void LegendMarkerItem::setFont(const QFont &font)
89 89 {
90 90 m_textItem->setFont(font);
91
91 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 99 updateGeometry();
94 100 }
95 101
96 102 QFont LegendMarkerItem::font() const
97 103 {
98 104 return m_textItem->font();
99 105 }
100 106
101 107 void LegendMarkerItem::setLabel(const QString label)
102 108 {
103 109 m_label = label;
104 110 updateGeometry();
105 111 }
106 112
107 113 QString LegendMarkerItem::label() const
108 114 {
109 115 return m_label;
110 116 }
111 117
112 118 void LegendMarkerItem::setLabelBrush(const QBrush &brush)
113 119 {
114 120 m_textItem->setDefaultTextColor(brush.color());
115 121 }
116 122
117 123 QBrush LegendMarkerItem::labelBrush() const
118 124 {
119 125 return QBrush(m_textItem->defaultTextColor());
120 126 }
121 127
122 128 void LegendMarkerItem::setGeometry(const QRectF &rect)
123 129 {
124 130 qreal width = rect.width();
125 131 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
126 132 QRectF truncatedRect;
127 133 const QString html = ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0),
128 134 width - x, rect.height(), truncatedRect);
129 135 m_textItem->setHtml(html);
130 136 if (m_marker->m_legend->showToolTips() && html != m_label)
131 137 m_textItem->setToolTip(m_label);
132 138 else
133 139 m_textItem->setToolTip(QString());
134 140
135 141 m_textItem->setTextWidth(truncatedRect.width());
136 142
137 143 qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin);
138 144
139 145 const QRectF &textRect = m_textItem->boundingRect();
140 146
141 147 m_textItem->setPos(x - m_margin, y / 2 - textRect.height() / 2);
142 148 m_rectItem->setRect(m_markerRect);
143 149 // The textMargin adjustments to position are done to make default case rects less blurry with anti-aliasing
144 150 m_rectItem->setPos(m_margin - ChartPresenter::textMargin(), y / 2.0 - m_markerRect.height() / 2.0 + ChartPresenter::textMargin());
145 151
146 152 prepareGeometryChange();
147 153 m_boundingRect = QRectF(0, 0, x + textRect.width() + m_margin, y);
148 154 }
149 155
150 156 QRectF LegendMarkerItem::boundingRect() const
151 157 {
152 158 return m_boundingRect;
153 159 }
154 160
161 QRectF LegendMarkerItem::markerRect() const
162 {
163 return m_markerRect;
164 }
165
155 166 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
156 167 {
157 168 Q_UNUSED(option)
158 169 Q_UNUSED(widget)
159 170 Q_UNUSED(painter)
160 171 }
161 172
162 173 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
163 174 {
164 175 Q_UNUSED(constraint)
165 176
166 177 QSizeF sh;
167 178
168 179 switch (which) {
169 180 case Qt::MinimumSize: {
170 181 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(),
171 182 QStringLiteral("..."));
172 183 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
173 184 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
174 185 break;
175 186 }
176 187 case Qt::PreferredSize: {
177 188 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), m_label);
178 189 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
179 190 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
180 191 break;
181 192 }
182 193 default:
183 194 break;
184 195 }
185 196
186 197 return sh;
187 198 }
188 199
189 200 void LegendMarkerItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
190 201 {
191 202 Q_UNUSED(event)
192 203 m_hovering = true;
193 204 emit m_marker->q_ptr->hovered(true);
194 205 }
195 206
196 207 void LegendMarkerItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
197 208 {
198 209 Q_UNUSED(event)
199 210 m_hovering = false;
200 211 emit m_marker->q_ptr->hovered(false);
201 212 }
202 213
203 214 QString LegendMarkerItem::displayedLabel() const
204 215 {
205 216 return m_textItem->toHtml();
206 217 }
207 218
208 219 void LegendMarkerItem::setToolTip(const QString &tip)
209 220 {
210 221 m_textItem->setToolTip(tip);
211 222 }
212 223
213 224 #include "moc_legendmarkeritem_p.cpp"
214 225
215 226 QT_CHARTS_END_NAMESPACE
@@ -1,112 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 // W A R N I N G
31 31 // -------------
32 32 //
33 33 // This file is not part of the Qt Chart API. It exists purely as an
34 34 // implementation detail. This header file may change from version to
35 35 // version without notice, or even be removed.
36 36 //
37 37 // We mean it.
38 38
39 39 #ifndef LEGENDMARKERITEM_P_H
40 40 #define LEGENDMARKERITEM_P_H
41 41
42 42 #include <QtCharts/QChartGlobal>
43 43 #include <QGraphicsObject>
44 44 #include <QtGui/QFont>
45 45 #include <QtGui/QBrush>
46 46 #include <QtGui/QPen>
47 47 #include <QtWidgets/QGraphicsTextItem>
48 48 #include <QtWidgets/QGraphicsLayoutItem>
49 49
50 50 QT_CHARTS_BEGIN_NAMESPACE
51 51
52 52 class QLegendMarkerPrivate;
53 53
54 54 class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem
55 55 {
56 56 Q_OBJECT
57 57 Q_INTERFACES(QGraphicsLayoutItem)
58 58 public:
59 explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = 0);
59 explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = nullptr);
60 60 ~LegendMarkerItem();
61 61
62 62 void setPen(const QPen &pen);
63 63 QPen pen() const;
64 64
65 65 void setBrush(const QBrush &brush);
66 66 QBrush brush() const;
67 67
68 68 void setFont(const QFont &font);
69 69 QFont font() const;
70 70
71 71 void setLabel(const QString label);
72 72 QString label() const;
73 73
74 74 void setLabelBrush(const QBrush &brush);
75 75 QBrush labelBrush() const;
76 76
77 77 void setGeometry(const QRectF &rect);
78 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 82 QSizeF sizeHint (Qt::SizeHint which, const QSizeF &constraint) const;
82 83
83 84 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
84 85 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
85 86
86 87 QString displayedLabel() const;
87 88 void setToolTip(const QString &tooltip);
89
90 Q_SIGNALS:
91 void markerRectChanged();
92
88 93 protected:
89 94 QLegendMarkerPrivate *m_marker; // Knows
90 95 QRectF m_markerRect;
91 96 QRectF m_boundingRect;
92 97 QGraphicsTextItem *m_textItem;
93 98 QGraphicsRectItem *m_rectItem;
94 99 qreal m_margin;
95 100 qreal m_space;
96 101 QString m_label;
97 102
98 103 QBrush m_labelBrush;
99 104 QPen m_pen;
100 105 QBrush m_brush;
101 106 bool m_hovering;
102 107
103 108 QPointF m_pressPos;
104 109
105 110 friend class QLegendMarker;
106 111 friend class QLegendMarkerPrivate;
107 112 friend class LegendLayout;
108 113 };
109 114
110 115 QT_CHARTS_END_NAMESPACE
111 116
112 117 #endif // LEGENDMARKERITEM_P_H
@@ -1,302 +1,303
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QLegendMarker>
31 31 #include <private/qlegendmarker_p.h>
32 32 #include <private/legendmarkeritem_p.h>
33 33 #include <QtCharts/QLegend>
34 34 #include <private/qlegend_p.h>
35 35 #include <private/legendlayout_p.h>
36 36 #include <QtGui/QFontMetrics>
37 37 #include <QtWidgets/QGraphicsSceneEvent>
38 38 #include <QtCharts/QAbstractSeries>
39 39
40 40 QT_CHARTS_BEGIN_NAMESPACE
41 41
42 42 /*!
43 43 \class QLegendMarker
44 44 \inmodule Qt Charts
45 45 \brief LegendMarker object.
46 46
47 47 QLegendMarker is abstract object that can be used to access markers inside QLegend. Legend marker consists of two
48 48 items: The colored box, which reflects the color of series and label, which is the name of series (or label of slice/barset
49 49 in case of pie or bar series)
50 50 The QLegendMarker is always related to one series.
51 51
52 52 \image examples_percentbarchart_legend.png
53 53
54 54 \sa QLegend
55 55 */
56 56 /*!
57 57 \enum QLegendMarker::LegendMarkerType
58 58
59 59 The type of the legendmarker object.
60 60
61 61 \value LegendMarkerTypeArea
62 62 \value LegendMarkerTypeBar
63 63 \value LegendMarkerTypePie
64 64 \value LegendMarkerTypeXY
65 65 \value LegendMarkerTypeBoxPlot
66 \value LegendMarkerTypeCandlestick
66 67 */
67 68
68 69 /*!
69 70 \fn virtual LegendMarkerType QLegendMarker::type() = 0;
70 71 Returns the type of legendmarker. Type depends of the related series. LegendMarkerTypeXY is used for all QXYSeries derived
71 72 classes.
72 73 */
73 74
74 75 /*!
75 76 \fn virtual QAbstractSeries* QLegendMarker::series() = 0;
76 77 Returns pointer to series, which is related to this marker. Marker is always related to some series.
77 78 */
78 79
79 80 /*!
80 81 \fn void QLegendMarker::clicked();
81 82 This signal is emitted, when marker is clicked with mouse.
82 83 */
83 84
84 85 /*!
85 86 \fn void QLegendMarker::hovered(bool status);
86 87 This signal is emitted, when mouse is hovered over marker. \a status is true, when mouse enters the marker
87 88 and false when it leaves the marker.
88 89 */
89 90
90 91 /*!
91 92 \fn void QLegendMarker::labelChanged()
92 93 This signal is emitted when the label of the legend marker has changed.
93 94 */
94 95
95 96 /*!
96 97 \fn void QLegendMarker::labelBrushChanged()
97 98 This signal is emitted when the label brush of the legend marker has changed.
98 99 */
99 100
100 101 /*!
101 102 \fn void QLegendMarker::fontChanged()
102 103 This signal is emitted when the (label) font of the legend marker has changed.
103 104 */
104 105
105 106 /*!
106 107 \fn void QLegendMarker::penChanged()
107 108 This signal is emitted when the pen of the legend marker has changed.
108 109 */
109 110
110 111 /*!
111 112 \fn void QLegendMarker::brushChanged()
112 113 This signal is emitted when the brush of the legend marker has changed.
113 114 */
114 115
115 116 /*!
116 117 \fn void QLegendMarker::visibleChanged()
117 118 This signal is emitted when the visibility of the legend marker has changed.
118 119 */
119 120
120 121 /*!
121 122 \property QLegendMarker::label
122 123 Label of the marker. This is the text that is shown in legend.
123 124 */
124 125
125 126 /*!
126 127 \property QLegendMarker::labelBrush
127 128 Brush of the label
128 129 */
129 130
130 131 /*!
131 132 \property QLegendMarker::font
132 133 Font of the label
133 134 */
134 135
135 136 /*!
136 137 \property QLegendMarker::pen
137 138 Pen of the marker. This is the outline of the colored square.
138 139 */
139 140
140 141 /*!
141 142 \property QLegendMarker::brush
142 143 Brush of the marker. This is the inside of the colored square.
143 144 */
144 145
145 146 /*!
146 147 \property QLegendMarker::visible
147 148 Visibility of the legend marker. Affects label and the colored square.
148 149 */
149 150
150 151
151 152 /*!
152 153 \internal
153 154 */
154 155 QLegendMarker::QLegendMarker(QLegendMarkerPrivate &d, QObject *parent) :
155 156 QObject(parent),
156 157 d_ptr(&d)
157 158 {
158 159 d_ptr->m_item->setVisible(d_ptr->series()->isVisible());
159 160 }
160 161
161 162 /*!
162 163 Destructor of marker
163 164 */
164 165 QLegendMarker::~QLegendMarker()
165 166 {
166 167 }
167 168
168 169 /*!
169 170 Returns the label of the marker.
170 171 */
171 172 QString QLegendMarker::label() const
172 173 {
173 174 return d_ptr->m_item->label();
174 175 }
175 176
176 177 /*!
177 178 Sets the \a label of marker. Note that changing name of series will also change label of its marker.
178 179 */
179 180 void QLegendMarker::setLabel(const QString &label)
180 181 {
181 182 if (label.isEmpty()) {
182 183 d_ptr->m_customLabel = false;
183 184 } else {
184 185 d_ptr->m_customLabel = true;
185 186 d_ptr->m_item->setLabel(label);
186 187 }
187 188 }
188 189 /*!
189 190 Returns the brush which is used to draw label.
190 191 */
191 192 QBrush QLegendMarker::labelBrush() const
192 193 {
193 194 return d_ptr->m_item->labelBrush();
194 195 }
195 196
196 197 /*!
197 198 Sets the \a brush of label
198 199 */
199 200 void QLegendMarker::setLabelBrush(const QBrush &brush)
200 201 {
201 202 d_ptr->m_item->setLabelBrush(brush);
202 203 }
203 204
204 205 /*!
205 206 Retuns the font of label
206 207 */
207 208 QFont QLegendMarker::font() const
208 209 {
209 210 return d_ptr->m_item->font();
210 211 }
211 212
212 213 /*!
213 214 Sets the \a font of label
214 215 */
215 216 void QLegendMarker::setFont(const QFont &font)
216 217 {
217 218 d_ptr->m_item->setFont(font);
218 219 }
219 220
220 221 /*!
221 222 Returns the pen of marker item
222 223 */
223 224 QPen QLegendMarker::pen() const
224 225 {
225 226 return d_ptr->m_item->pen();
226 227 }
227 228
228 229 /*!
229 230 Sets the \a pen of marker item
230 231 */
231 232 void QLegendMarker::setPen(const QPen &pen)
232 233 {
233 234 if (pen == QPen(Qt::NoPen)) {
234 235 d_ptr->m_customPen = false;
235 236 } else {
236 237 d_ptr->m_customPen = true;
237 238 d_ptr->m_item->setPen(pen);
238 239 }
239 240 }
240 241
241 242 /*!
242 243 Returns the brush of marker item
243 244 */
244 245 QBrush QLegendMarker::brush() const
245 246 {
246 247 return d_ptr->m_item->brush();
247 248 }
248 249
249 250 /*!
250 251 Sets the \a brush of marker item. Note that changing color of the series also changes this.
251 252 */
252 253 void QLegendMarker::setBrush(const QBrush &brush)
253 254 {
254 255 if (brush == QBrush(Qt::NoBrush)) {
255 256 d_ptr->m_customBrush = false;
256 257 } else {
257 258 d_ptr->m_customBrush = true;
258 259 d_ptr->m_item->setBrush(brush);
259 260 }
260 261 }
261 262
262 263 /*!
263 264 Returns visibility of the marker
264 265 */
265 266 bool QLegendMarker::isVisible() const
266 267 {
267 268 return d_ptr->m_item->isVisible();
268 269 }
269 270
270 271 /*!
271 272 Sets markers visibility to \a visible
272 273 */
273 274 void QLegendMarker::setVisible(bool visible)
274 275 {
275 276 d_ptr->m_item->setVisible(visible);
276 277 }
277 278
278 279 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
279 280 QLegendMarkerPrivate::QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend) :
280 281 m_legend(legend),
281 282 m_customLabel(false),
282 283 m_customBrush(false),
283 284 m_customPen(false),
284 285 q_ptr(q)
285 286 {
286 287 m_item = new LegendMarkerItem(this);
287 288 }
288 289
289 290 QLegendMarkerPrivate::~QLegendMarkerPrivate()
290 291 {
291 292 delete m_item;
292 293 }
293 294
294 295 void QLegendMarkerPrivate::invalidateLegend()
295 296 {
296 297 m_legend->d_ptr->m_layout->invalidate();
297 298 }
298 299
299 300 #include "moc_qlegendmarker.cpp"
300 301 #include "moc_qlegendmarker_p.cpp"
301 302
302 303 QT_CHARTS_END_NAMESPACE
@@ -1,116 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QLEGENDMARKER_H
31 31 #define QLEGENDMARKER_H
32 32
33 33 #include <QtCharts/QChartGlobal>
34 34 #include <QtCore/QObject>
35 35 #include <QtGui/QPen>
36 36 #include <QtGui/QBrush>
37 37 #include <QtGui/QFont>
38 38
39 39 QT_CHARTS_BEGIN_NAMESPACE
40 40
41 41 class QLegendMarkerPrivate;
42 42 class QAbstractSeries;
43 43 class QLegend;
44 44
45 45 class QT_CHARTS_EXPORT QLegendMarker : public QObject
46 46 {
47 47 Q_OBJECT
48 48
49 49 public:
50 50 enum LegendMarkerType {
51 51 LegendMarkerTypeArea,
52 52 LegendMarkerTypeBar,
53 53 LegendMarkerTypePie,
54 54 LegendMarkerTypeXY,
55 LegendMarkerTypeBoxPlot
55 LegendMarkerTypeBoxPlot,
56 LegendMarkerTypeCandlestick
56 57 };
57 58
58 59 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
59 60 Q_PROPERTY(QBrush labelBrush READ labelBrush WRITE setLabelBrush NOTIFY labelBrushChanged)
60 61 Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
61 62 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
62 63 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
63 64 Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
64 65 Q_ENUMS(LegendMarkerType)
65 66
66 67 public:
67 68 virtual ~QLegendMarker();
68 69 virtual LegendMarkerType type() = 0;
69 70
70 71 QString label() const;
71 72 void setLabel(const QString &label);
72 73
73 74 QBrush labelBrush() const;
74 75 void setLabelBrush(const QBrush &brush);
75 76
76 77 QFont font() const;
77 78 void setFont(const QFont &font);
78 79
79 80 QPen pen() const;
80 81 void setPen(const QPen &pen);
81 82
82 83 QBrush brush() const;
83 84 void setBrush(const QBrush &brush);
84 85
85 86 bool isVisible() const;
86 87 void setVisible(bool visible);
87 88
88 89 virtual QAbstractSeries* series() = 0;
89 90
90 91 Q_SIGNALS:
91 92 void clicked();
92 93 void hovered(bool status);
93 94 void labelChanged();
94 95 void labelBrushChanged();
95 96 void fontChanged();
96 97 void penChanged();
97 98 void brushChanged();
98 99 void visibleChanged();
99 100
100 101 protected:
101 102 explicit QLegendMarker(QLegendMarkerPrivate &d, QObject *parent = Q_NULLPTR);
102 103
103 104 QScopedPointer<QLegendMarkerPrivate> d_ptr;
104 105 friend class QLegendPrivate;
105 106 friend class QLegendMarkerPrivate;
106 107 friend class LegendMarkerItem;
107 108 friend class LegendLayout;
108 109 friend class LegendScroller;
109 110
110 111 private:
111 112 Q_DISABLE_COPY(QLegendMarker)
112 113 };
113 114
114 115 QT_CHARTS_END_NAMESPACE
115 116
116 117 #endif // QLEGENDMARKER_H
@@ -1,508 +1,509
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QAbstractSeries>
31 31 #include <private/qabstractseries_p.h>
32 32 #include <private/chartdataset_p.h>
33 33 #include <QtCharts/QChart>
34 34 #include <private/qchart_p.h>
35 35 #include <private/chartitem_p.h>
36 36 #include <private/xydomain_p.h>
37 37 #include <private/xlogydomain_p.h>
38 38 #include <private/logxydomain_p.h>
39 39 #include <private/logxlogydomain_p.h>
40 40
41 41 QT_CHARTS_BEGIN_NAMESPACE
42 42
43 43 /*!
44 44 \class QAbstractSeries
45 45 \inmodule Qt Charts
46 46 \brief Base class for all Qt Chart series.
47 47
48 48 Usually you use the series type specific inherited classes instead of the base class.
49 49 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QAbstractBarSeries, QStackedBarSeries,
50 50 QPercentBarSeries, QPieSeries
51 51 */
52 52 /*!
53 53 \qmltype AbstractSeries
54 54 \instantiates QAbstractSeries
55 55 \inqmlmodule QtCharts
56 56
57 57 \brief Base class for all Qt Chart series.
58 58
59 59 AbstractSeries is the base class for all series.
60 60 The class cannot be instantiated by the user.
61 61 */
62 62
63 63 /*!
64 64 \enum QAbstractSeries::SeriesType
65 65
66 66 The type of the series object.
67 67
68 68 \value SeriesTypeLine
69 69 \value SeriesTypeArea
70 70 \value SeriesTypeBar
71 71 \value SeriesTypeStackedBar
72 72 \value SeriesTypePercentBar
73 73 \value SeriesTypePie
74 74 \value SeriesTypeScatter
75 75 \value SeriesTypeSpline
76 76 \value SeriesTypeHorizontalBar
77 77 \value SeriesTypeHorizontalStackedBar
78 78 \value SeriesTypeHorizontalPercentBar
79 79 \value SeriesTypeBoxPlot
80 \value SeriesTypeCandlestick
80 81 */
81 82
82 83 /*!
83 84 \property QAbstractSeries::type
84 85 The type of the series.
85 86 */
86 87 /*!
87 88 \qmlproperty ChartView.SeriesType AbstractSeries::type
88 89 The type of the series.
89 90 */
90 91
91 92 /*!
92 93 \property QAbstractSeries::name
93 94 \brief name of the series property. The name is shown in legend for series and supports html formatting.
94 95 */
95 96 /*!
96 97 \qmlproperty string AbstractSeries::name
97 98 Name of the series. The name is shown in legend for series and supports html formatting.
98 99 */
99 100
100 101 /*!
101 102 \fn void QAbstractSeries::nameChanged()
102 103 This signal is emitted when the series name changes.
103 104 */
104 105 /*!
105 106 \qmlsignal AbstractSeries::onNameChanged()
106 107 This signal is emitted when the series name changes.
107 108 */
108 109
109 110 /*!
110 111 \property QAbstractSeries::visible
111 112 \brief whether the series is visible or not; true by default.
112 113 */
113 114 /*!
114 115 \qmlproperty bool AbstractSeries::visible
115 116 Visibility of the series. True by default.
116 117 */
117 118
118 119 /*!
119 120 \fn void QAbstractSeries::visibleChanged()
120 121 Emitted when the series visibility changes.
121 122 */
122 123 /*!
123 124 \qmlsignal AbstractSeries::onVisibleChanged()
124 125 Emitted when the series visibility changes.
125 126 */
126 127
127 128 /*!
128 129 \property QAbstractSeries::opacity
129 130 \brief The opacity of the series.
130 131
131 132 By default the opacity is 1.0. The valid values range from 0.0 (transparent) to 1.0 (opaque).
132 133 */
133 134 /*!
134 135 \qmlproperty real AbstractSeries::opacity
135 136 The opacity of the series. By default the opacity is 1.0.
136 137 The valid values range from 0.0 (transparent) to 1.0 (opaque).
137 138 */
138 139
139 140 /*!
140 141 \fn void QAbstractSeries::opacityChanged()
141 142 Emitted when the opacity of the series changes.
142 143 */
143 144 /*!
144 145 \qmlsignal AbstractSeries::onOpacityChanged()
145 146 Emitted when the opacity of the series changes.
146 147 */
147 148
148 149 /*!
149 150 \property QAbstractSeries::useOpenGL
150 151 \brief Specifies whether or not the series drawing is accelerated with OpenGL.
151 152
152 153 Drawing series with OpenGL is supported only for QLineSeries and QScatterSeries.
153 154 Line series used as edge series for a QAreaSeries cannot use OpenGL acceleration.
154 155 When a chart contains any series that are drawn with OpenGL, a transparent QOpenGLWidget
155 156 is created on top of the chart plot area. The accelerated series are not drawn on the underlying
156 157 QGraphicsView, but are instead drawn on the created QOpenGLWidget.
157 158
158 159 Performance gained from using OpenGL to accelerate series drawing depends on the underlying
159 160 hardware, but in most cases it is significant. For example, on a standard desktop computer,
160 161 enabling OpenGL acceleration for a series typically allows rendering at least hundred times
161 162 more points without reduction on the frame rate.
162 163 Chart size also has less effect on the frame rate.
163 164
164 165 The OpenGL acceleration of series drawing is meant for use cases that need fast drawing of
165 166 large numbers of points. It is optimized for efficiency, and therefore the series using
166 167 it lack support for many features available to non-accelerated series:
167 168
168 169 \list
169 170 \li Series animations are not supported for accelerated series.
170 171 \li Antialiasing is not supported for accelerated series.
171 172 \li Point labels are not supported for accelerated series.
172 173 \li Pen styles and marker shapes are ignored for accelerated series.
173 174 Only solid lines and plain scatter dots are supported.
174 175 The scatter dots may be circular or rectangular, depending on the underlying graphics
175 176 hardware and drivers.
176 177 \li Polar charts do not support accelerated series.
177 178 \li Mouse events are not supported for accelerated series.
178 179 \li Enabling chart drop shadow or using transparent chart background color is not recommended
179 180 when using accelerated series, as that can slow the frame rate down significantly.
180 181 \endlist
181 182
182 183 These additional restrictions stem from the fact that the accelerated series is drawn on a
183 184 separate widget on top of the chart:
184 185
185 186 \list
186 187 \li If you draw any graphics items on top of a chart containing an accelerated series,
187 188 the accelerated series is drawn over those items.
188 189 \li To enable QOpenGLWidget to be partially transparent, it needs to be stacked on top of
189 190 all other widgets. This means you cannot have other widgets partially covering the
190 191 chart when using accelerated series.
191 192 \li Accelerated series are not supported for use cases where the graphics scene has more than
192 193 one graphics view attached to it.
193 194 \li Accelerated series are not supported for use cases where the chart doesn't fill the entire
194 195 graphics view or has non-default geometry. For example, scrolling the view with scroll
195 196 bars or adding transformations to the graphics view cause the accelerated series to
196 197 be drawn in incorrect position related to the chart.
197 198 \endlist
198 199
199 200 The default value is \c{false}.
200 201 */
201 202 /*!
202 203 \qmlproperty bool AbstractSeries::useOpenGL
203 204 Specifies whether or not the series is drawn with OpenGL.
204 205
205 206 Drawing series with OpenGL is supported only for LineSeries and ScatterSeries.
206 207 Line series used as edge series for a AreaSeries cannot use OpenGL acceleration.
207 208 When a chart contains any series that are drawn with OpenGL, an additional transparent child
208 209 node is created for the ChartView node. The accelerated series are not drawn on the
209 210 ChartView node, but are instead drawn on the child node.
210 211
211 212 Performance gained from using OpenGL to accelerate series drawing depends on the underlying
212 213 hardware, but in most cases it is significant. For example, on a standard desktop computer,
213 214 enabling OpenGL acceleration for a series typically allows rendering at least hundred times
214 215 more points without reduction on the frame rate.
215 216 Chart size also has less effect on the frame rate.
216 217 The biggest performance sink when rendering ChartView is rendering and uploading the underlying
217 218 chart texture. If the underlying chart itself is not changing rapidly, significant extra
218 219 performance is gained from not needing to regenerate the chart texture for each frame.
219 220
220 221 The OpenGL acceleration of series drawing is meant for use cases that need fast drawing of
221 222 large numbers of points. It is optimized for efficiency, and therefore the series using
222 223 it lack support for many features available to non-accelerated series:
223 224
224 225 \list
225 226 \li Series animations are not supported for accelerated series.
226 227 \li Antialiasing is not supported for accelerated series.
227 228 \li Point labels are not supported for accelerated series.
228 229 \li Marker shapes are ignored for accelerated series.
229 230 Only plain scatter dots are supported.
230 231 The scatter dots may be circular or rectangular, depending on the underlying graphics
231 232 hardware and drivers.
232 233 \li Polar charts do not support accelerated series.
233 234 \li Mouse events are not supported for accelerated series.
234 235 \li Enabling chart drop shadow or using transparent chart background color is not recommended
235 236 when using accelerated series, as that can slow the frame rate down significantly.
236 237 \endlist
237 238
238 239 The default value is \c{false}.
239 240 */
240 241
241 242 /*!
242 243 \fn void QAbstractSeries::useOpenGLChanged()
243 244 Emitted when the useOpenGL property value changes.
244 245 */
245 246 /*!
246 247 \qmlsignal AbstractSeries::onUseOpenGLChanged()
247 248 Emitted when the useOpenGL property value changes.
248 249 */
249 250
250 251 /*!
251 252 \internal
252 253 \brief Constructs QAbstractSeries object with \a parent.
253 254 */
254 255 QAbstractSeries::QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent) :
255 256 QObject(parent),
256 257 d_ptr(&d)
257 258 {
258 259 }
259 260
260 261 /*!
261 262 \brief Virtual destructor for the chart series.
262 263 */
263 264 QAbstractSeries::~QAbstractSeries()
264 265 {
265 266 if (d_ptr->m_chart)
266 267 qFatal("Series still bound to a chart when destroyed!");
267 268 }
268 269
269 270 void QAbstractSeries::setName(const QString &name)
270 271 {
271 272 if (name != d_ptr->m_name) {
272 273 d_ptr->m_name = name;
273 274 emit nameChanged();
274 275 }
275 276 }
276 277
277 278 QString QAbstractSeries::name() const
278 279 {
279 280 return d_ptr->m_name;
280 281 }
281 282
282 283 void QAbstractSeries::setVisible(bool visible)
283 284 {
284 285 if (visible != d_ptr->m_visible) {
285 286 d_ptr->m_visible = visible;
286 287 emit visibleChanged();
287 288 }
288 289 }
289 290
290 291 bool QAbstractSeries::isVisible() const
291 292 {
292 293 return d_ptr->m_visible;
293 294 }
294 295
295 296 qreal QAbstractSeries::opacity() const
296 297 {
297 298 return d_ptr->m_opacity;
298 299 }
299 300
300 301 void QAbstractSeries::setOpacity(qreal opacity)
301 302 {
302 303 if (opacity != d_ptr->m_opacity) {
303 304 d_ptr->m_opacity = opacity;
304 305 emit opacityChanged();
305 306 }
306 307 }
307 308
308 309 void QAbstractSeries::setUseOpenGL(bool enable)
309 310 {
310 311 #ifdef QT_NO_OPENGL
311 312 Q_UNUSED(enable)
312 313 #else
313 314 bool polarChart = d_ptr->m_chart && d_ptr->m_chart->chartType() == QChart::ChartTypePolar;
314 315 bool supportedSeries = (type() == SeriesTypeLine || type() == SeriesTypeScatter);
315 316 if ((!enable || !d_ptr->m_blockOpenGL)
316 317 && supportedSeries
317 318 && enable != d_ptr->m_useOpenGL
318 319 && (!enable || !polarChart)) {
319 320 d_ptr->m_useOpenGL = enable;
320 321 emit useOpenGLChanged();
321 322 }
322 323 #endif
323 324 }
324 325
325 326 bool QAbstractSeries::useOpenGL() const
326 327 {
327 328 return d_ptr->m_useOpenGL;
328 329 }
329 330
330 331 /*!
331 332 \brief Returns the chart where series belongs to.
332 333
333 334 Set automatically when the series is added to the chart
334 335 and unset when the series is removed from the chart.
335 336 */
336 337 QChart *QAbstractSeries::chart() const
337 338 {
338 339 return d_ptr->m_chart;
339 340 }
340 341
341 342 /*!
342 343 \brief Sets the visibility of the series to true.
343 344
344 345 \sa setVisible(), isVisible()
345 346 */
346 347 void QAbstractSeries::show()
347 348 {
348 349 setVisible(true);
349 350 }
350 351
351 352 /*!
352 353 \brief Sets the visibility of the series to false.
353 354
354 355 \sa setVisible(), isVisible()
355 356 */
356 357 void QAbstractSeries::hide()
357 358 {
358 359 setVisible(false);
359 360 }
360 361
361 362 /*!
362 363 Attach \a axis to the series.
363 364 \return true if the axis was attached successfully, false otherwise.
364 365 \note If multiple axes of same orientation are attached to same series,
365 366 they will have same min/max ranges.
366 367 \sa QChart::addAxis(), QChart::createDefaultAxes()
367 368 */
368 369 bool QAbstractSeries::attachAxis(QAbstractAxis* axis)
369 370 {
370 371 if(d_ptr->m_chart) {
371 372 return d_ptr->m_chart->d_ptr->m_dataset->attachAxis(this, axis);
372 373 } else {
373 374 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
374 375 return false;
375 376 }
376 377 }
377 378
378 379 /*!
379 380 Detach \a axis from the series.
380 381 \return true if the axis was detached successfully, false otherwise.
381 382 \sa QChart::removeAxis()
382 383 */
383 384 bool QAbstractSeries::detachAxis(QAbstractAxis* axis)
384 385 {
385 386 if(d_ptr->m_chart) {
386 387 return d_ptr->m_chart->d_ptr->m_dataset->detachAxis(this, axis);
387 388 }
388 389 else {
389 390 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
390 391 return false;
391 392 }
392 393 }
393 394
394 395 /*!
395 396 Returns the list of axes attached to the series. Usually there is an x-axis and a y-axis attached to a series, except
396 397 in case of a QPieSeries, which does not have any axes attached.
397 398 \sa attachAxis(), detachAxis()
398 399 */
399 400 QList<QAbstractAxis*> QAbstractSeries::attachedAxes()
400 401 {
401 402 return d_ptr->m_axes;
402 403 }
403 404
404 405 ///////////////////////////////////////////////////////////////////////////////////////////////////
405 406
406 407 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries *q)
407 408 : q_ptr(q),
408 409 m_chart(0),
409 410 m_item(0),
410 411 m_domain(new XYDomain()),
411 412 m_visible(true),
412 413 m_opacity(1.0),
413 414 m_useOpenGL(false),
414 415 m_blockOpenGL(false)
415 416 {
416 417 }
417 418
418 419 QAbstractSeriesPrivate::~QAbstractSeriesPrivate()
419 420 {
420 421 }
421 422
422 423 void QAbstractSeriesPrivate::setDomain(AbstractDomain* domain)
423 424 {
424 425 Q_ASSERT(domain);
425 426 if(m_domain.data()!=domain) {
426 427 if(!m_item.isNull()) QObject::disconnect(m_domain.data(), SIGNAL(updated()), m_item.data(), SLOT(handleDomainUpdated()));
427 428 m_domain.reset(domain);
428 429 if(!m_item.isNull()) {
429 430 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
430 431 m_item->handleDomainUpdated();
431 432 }
432 433 }
433 434 }
434 435
435 436 void QAbstractSeriesPrivate::setPresenter(ChartPresenter *presenter)
436 437 {
437 438 m_presenter = presenter;
438 439 }
439 440
440 441 ChartPresenter *QAbstractSeriesPrivate::presenter() const
441 442 {
442 443 return m_presenter;
443 444 }
444 445
445 446 void QAbstractSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
446 447 {
447 448 Q_ASSERT(!m_item.isNull());
448 449 Q_UNUSED(parent);
449 450 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
450 451 }
451 452
452 453 void QAbstractSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
453 454 QEasingCurve &curve)
454 455 {
455 456 Q_UNUSED(options);
456 457 Q_UNUSED(duration);
457 458 Q_UNUSED(curve);
458 459 }
459 460
460 461 bool QAbstractSeriesPrivate::reverseXAxis()
461 462 {
462 463 bool reverseXAxis = false;
463 464 if (m_axes.size() != 0 && !(m_chart->chartType() == QChart::ChartTypePolar)) {
464 465 int i = 0;
465 466 while (i < m_axes.size()) {
466 467 if (m_axes.at(i)->orientation() == Qt::Horizontal && m_axes.at(i)->isReverse()) {
467 468 reverseXAxis = true;
468 469 break;
469 470 }
470 471 i++;
471 472 }
472 473 }
473 474
474 475 return reverseXAxis;
475 476 }
476 477
477 478 bool QAbstractSeriesPrivate::reverseYAxis()
478 479 {
479 480 bool reverseYAxis = false;
480 481 if (m_axes.size() != 0 && !(m_chart->chartType() == QChart::ChartTypePolar)) {
481 482 int i = 0;
482 483 while (i < m_axes.size()) {
483 484 if (m_axes.at(i)->orientation() == Qt::Vertical && m_axes.at(i)->isReverse()) {
484 485 reverseYAxis = true;
485 486 break;
486 487 }
487 488 i++;
488 489 }
489 490 }
490 491
491 492 return reverseYAxis;
492 493 }
493 494
494 495 // This function can be used to explicitly block OpenGL use from some otherwise supported series,
495 496 // such as the line series used as edge series of an area series.
496 497 void QAbstractSeriesPrivate::setBlockOpenGL(bool enable)
497 498 {
498 499 m_blockOpenGL = enable;
499 500 if (enable)
500 501 q_ptr->setUseOpenGL(false);
501 502 }
502 503
503 504 #include "moc_qabstractseries.cpp"
504 505 #include "moc_qabstractseries_p.cpp"
505 506
506 507 QT_CHARTS_END_NAMESPACE
507 508
508 509
@@ -1,112 +1,113
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QABSTRACTSERIES_H
31 31 #define QABSTRACTSERIES_H
32 32
33 33 #include <QtCharts/QChartGlobal>
34 34 #include <QtCharts/QAbstractAxis>
35 35 #include <QtCore/QObject>
36 36 #include <QtGui/QPen>
37 37
38 38 QT_CHARTS_BEGIN_NAMESPACE
39 39
40 40 class QAbstractSeriesPrivate;
41 41 class QChart;
42 42
43 43 class QT_CHARTS_EXPORT QAbstractSeries : public QObject
44 44 {
45 45 Q_OBJECT
46 46 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
47 47 Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
48 48 Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
49 49 Q_PROPERTY(SeriesType type READ type)
50 50 Q_PROPERTY(bool useOpenGL READ useOpenGL WRITE setUseOpenGL NOTIFY useOpenGLChanged)
51 51 Q_ENUMS(SeriesType)
52 52
53 53 public:
54 54 enum SeriesType {
55 55 SeriesTypeLine,
56 56 SeriesTypeArea,
57 57 SeriesTypeBar,
58 58 SeriesTypeStackedBar,
59 59 SeriesTypePercentBar,
60 60 SeriesTypePie,
61 61 SeriesTypeScatter,
62 62 SeriesTypeSpline,
63 63 SeriesTypeHorizontalBar,
64 64 SeriesTypeHorizontalStackedBar,
65 65 SeriesTypeHorizontalPercentBar,
66 SeriesTypeBoxPlot
66 SeriesTypeBoxPlot,
67 SeriesTypeCandlestick
67 68 };
68 69
69 70 protected:
70 QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent = Q_NULLPTR);
71 QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent = nullptr);
71 72
72 73 public:
73 74 ~QAbstractSeries();
74 75 virtual SeriesType type() const = 0;
75 76
76 77 void setName(const QString &name);
77 78 QString name() const;
78 79 void setVisible(bool visible = true);
79 80 bool isVisible() const;
80 81 qreal opacity() const;
81 82 void setOpacity(qreal opacity);
82 83 void setUseOpenGL(bool enable = true);
83 84 bool useOpenGL() const;
84 85
85 86 QChart *chart() const;
86 87
87 88 bool attachAxis(QAbstractAxis *axis);
88 89 bool detachAxis(QAbstractAxis *axis);
89 90 QList<QAbstractAxis*> attachedAxes();
90 91
91 92 void show();
92 93 void hide();
93 94
94 95 Q_SIGNALS:
95 96 void nameChanged();
96 97 void visibleChanged();
97 98 void opacityChanged();
98 99 void useOpenGLChanged();
99 100
100 101 protected:
101 102 QScopedPointer<QAbstractSeriesPrivate> d_ptr;
102 103 friend class ChartDataSet;
103 104 friend class ChartPresenter;
104 105 friend class ChartThemeManager;
105 106 friend class QLegendPrivate;
106 107 friend class DeclarativeChart;
107 108 friend class QAreaSeries;
108 109 };
109 110
110 111 QT_CHARTS_END_NAMESPACE
111 112
112 113 #endif // QABSTRACTSERIES_H
@@ -1,203 +1,204
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QCHART_H
31 31 #define QCHART_H
32 32
33 33 #include <QtCharts/QAbstractSeries>
34 34 #include <QtCharts/QLegend>
35 35 #include <QtWidgets/QGraphicsWidget>
36 36 #include <QtCore/QMargins>
37 37
38 38 QT_BEGIN_NAMESPACE
39 39 class QGraphicsSceneResizeEvent;
40 40 QT_END_NAMESPACE
41 41
42 42 QT_CHARTS_BEGIN_NAMESPACE
43 43
44 44 class QAbstractSeries;
45 45 class QAbstractAxis;
46 46 class QLegend;
47 47 class QChartPrivate;
48 48 class QBoxPlotSeries;
49 49
50 50 class QT_CHARTS_EXPORT QChart : public QGraphicsWidget
51 51 {
52 52 Q_OBJECT
53 53 Q_PROPERTY(QChart::ChartTheme theme READ theme WRITE setTheme)
54 54 Q_PROPERTY(QString title READ title WRITE setTitle)
55 55 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
56 56 Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
57 57 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness)
58 58 Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions)
59 59 Q_PROPERTY(int animationDuration READ animationDuration WRITE setAnimationDuration)
60 60 Q_PROPERTY(QEasingCurve animationEasingCurve READ animationEasingCurve WRITE setAnimationEasingCurve)
61 61 Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
62 62 Q_PROPERTY(QChart::ChartType chartType READ chartType)
63 63 Q_PROPERTY(bool plotAreaBackgroundVisible READ isPlotAreaBackgroundVisible WRITE setPlotAreaBackgroundVisible)
64 64 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers)
65 65 Q_PROPERTY(QLocale locale READ locale WRITE setLocale)
66 66 Q_PROPERTY(QRectF plotArea READ plotArea NOTIFY plotAreaChanged)
67 67 Q_ENUMS(ChartTheme)
68 68 Q_ENUMS(AnimationOption)
69 69 Q_ENUMS(ChartType)
70 70
71 71 public:
72 72 enum ChartType {
73 73 ChartTypeUndefined = 0,
74 74 ChartTypeCartesian,
75 75 ChartTypePolar
76 76 };
77 77
78 78 enum ChartTheme {
79 79 ChartThemeLight = 0,
80 80 ChartThemeBlueCerulean,
81 81 ChartThemeDark,
82 82 ChartThemeBrownSand,
83 83 ChartThemeBlueNcs,
84 84 ChartThemeHighContrast,
85 85 ChartThemeBlueIcy,
86 86 ChartThemeQt
87 87 };
88 88
89 89 enum AnimationOption {
90 90 NoAnimation = 0x0,
91 91 GridAxisAnimations = 0x1,
92 92 SeriesAnimations = 0x2,
93 93 AllAnimations = 0x3
94 94 };
95 95
96 96 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
97 97
98 98 public:
99 99 explicit QChart(QGraphicsItem *parent = Q_NULLPTR, Qt::WindowFlags wFlags = Qt::WindowFlags());
100 100 ~QChart();
101 101
102 102 void addSeries(QAbstractSeries *series);
103 103 void removeSeries(QAbstractSeries *series);
104 104 void removeAllSeries();
105 105 QList<QAbstractSeries *> series() const;
106 106
107 107 // *** deprecated ***
108 108 void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = Q_NULLPTR);
109 109 void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = Q_NULLPTR);
110 110 QAbstractAxis *axisX(QAbstractSeries *series = Q_NULLPTR) const;
111 111 QAbstractAxis *axisY(QAbstractSeries *series = Q_NULLPTR) const;
112 112 // ******************
113 113
114 114 void addAxis(QAbstractAxis *axis, Qt::Alignment alignment);
115 115 void removeAxis(QAbstractAxis *axis);
116 116 QList<QAbstractAxis*> axes(Qt::Orientations orientation = Qt::Horizontal|Qt::Vertical, QAbstractSeries *series = Q_NULLPTR) const;
117 117
118 118 void createDefaultAxes();
119 119
120 120 void setTheme(QChart::ChartTheme theme);
121 121 QChart::ChartTheme theme() const;
122 122
123 123 void setTitle(const QString &title);
124 124 QString title() const;
125 125 void setTitleFont(const QFont &font);
126 126 QFont titleFont() const;
127 127 void setTitleBrush(const QBrush &brush);
128 128 QBrush titleBrush() const;
129 129
130 130 void setBackgroundBrush(const QBrush &brush);
131 131 QBrush backgroundBrush() const;
132 132 void setBackgroundPen(const QPen &pen);
133 133 QPen backgroundPen() const;
134 134 void setBackgroundVisible(bool visible = true);
135 135 bool isBackgroundVisible() const;
136 136
137 137 void setDropShadowEnabled(bool enabled = true);
138 138 bool isDropShadowEnabled() const;
139 139 void setBackgroundRoundness(qreal diameter);
140 140 qreal backgroundRoundness() const;
141 141
142 142 void setAnimationOptions(AnimationOptions options);
143 143 AnimationOptions animationOptions() const;
144 144 void setAnimationDuration(int msecs);
145 145 int animationDuration() const;
146 146 void setAnimationEasingCurve(const QEasingCurve &curve);
147 147 QEasingCurve animationEasingCurve() const;
148 148
149 149 void zoomIn();
150 150 void zoomOut();
151 151
152 152 void zoomIn(const QRectF &rect);
153 153 void zoom(qreal factor);
154 154 void zoomReset();
155 155 bool isZoomed();
156 156
157 157 void scroll(qreal dx, qreal dy);
158 158
159 159 QLegend *legend() const;
160 160
161 161 void setMargins(const QMargins &margins);
162 162 QMargins margins() const;
163 163
164 164 QRectF plotArea() const;
165 165 void setPlotAreaBackgroundBrush(const QBrush &brush);
166 166 QBrush plotAreaBackgroundBrush() const;
167 167 void setPlotAreaBackgroundPen(const QPen &pen);
168 168 QPen plotAreaBackgroundPen() const;
169 169 void setPlotAreaBackgroundVisible(bool visible = true);
170 170 bool isPlotAreaBackgroundVisible() const;
171 171 void setLocalizeNumbers(bool localize);
172 172 bool localizeNumbers() const;
173 173 void setLocale(const QLocale &locale);
174 174 QLocale locale() const;
175 175
176 176 QPointF mapToValue(const QPointF &position, QAbstractSeries *series = Q_NULLPTR);
177 177 QPointF mapToPosition(const QPointF &value, QAbstractSeries *series = Q_NULLPTR);
178 178
179 179 ChartType chartType() const;
180 180
181 181 Q_SIGNALS:
182 182 void plotAreaChanged(const QRectF &plotArea);
183 183
184 184 protected:
185 185 explicit QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags);
186 186 QScopedPointer<QChartPrivate> d_ptr;
187 187 friend class QLegend;
188 188 friend class DeclarativeChart;
189 189 friend class ChartDataSet;
190 190 friend class ChartPresenter;
191 191 friend class ChartThemeManager;
192 192 friend class QAbstractSeries;
193 193 friend class QBoxPlotSeriesPrivate;
194 friend class QCandlestickSeriesPrivate;
194 195
195 196 private:
196 197 Q_DISABLE_COPY(QChart)
197 198 };
198 199
199 200 QT_CHARTS_END_NAMESPACE
200 201
201 202 Q_DECLARE_OPERATORS_FOR_FLAGS(QT_CHARTS_NAMESPACE::QChart::AnimationOptions)
202 203
203 204 #endif // QCHART_H
@@ -1,73 +1,75
1 1
2 2 TARGET = qtchartsqml2
3 3 QT += qml quick
4 4 QT += charts charts-private
5 5 TARGETPATH = QtCharts
6 6 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
7 7
8 8 IMPORT_VERSION = $$MODULE_VERSION
9 9
10 10 # Only build qml plugin static if Qt itself is also built static
11 11 !contains(QT_CONFIG, static): CONFIG -= static staticlib
12 12
13 13 include($$PWD/designer/designer.pri)
14 14
15 15 INCLUDEPATH += ../../include \
16 16 ../../include/QtCharts \
17 17 ../charts \
18 18 ../charts/animations \
19 19 ../charts/axis \
20 20 ../charts/domain
21 21
22 22 SOURCES += \
23 23 chartsqml2_plugin.cpp \
24 24 declarativechart.cpp \
25 25 declarativexypoint.cpp \
26 26 declarativexyseries.cpp \
27 27 declarativelineseries.cpp \
28 28 declarativesplineseries.cpp \
29 29 declarativeareaseries.cpp \
30 30 declarativescatterseries.cpp \
31 31 declarativepieseries.cpp \
32 32 declarativebarseries.cpp \
33 33 declarativecategoryaxis.cpp \
34 34 declarativemargins.cpp \
35 35 declarativeaxes.cpp \
36 36 declarativepolarchart.cpp \
37 37 declarativeboxplotseries.cpp \
38 38 declarativechartnode.cpp \
39 declarativerendernode.cpp
39 declarativerendernode.cpp \
40 declarativecandlestickseries.cpp
40 41
41 42 HEADERS += \
42 43 declarativechart.h \
43 44 declarativexypoint.h \
44 45 declarativexyseries.h \
45 46 declarativelineseries.h \
46 47 declarativesplineseries.h \
47 48 declarativeareaseries.h \
48 49 declarativescatterseries.h \
49 50 declarativepieseries.h \
50 51 declarativebarseries.h \
51 52 declarativecategoryaxis.h \
52 53 declarativemargins.h \
53 54 declarativeaxes.h \
54 55 declarativepolarchart.h \
55 56 declarativeboxplotseries.h \
56 57 declarativechartnode.h \
57 declarativerendernode.h
58 declarativerendernode.h \
59 declarativecandlestickseries.h
58 60
59 61 OTHER_FILES = qmldir
60 62
61 63 CONFIG += no_cxx_module
62 64
63 65 load(qml_plugin)
64 66
65 67 win32 {
66 68 CONFIG += skip_target_version_ext
67 69 VERSION = $$MODULE_VERSION
68 70 QMAKE_TARGET_PRODUCT = "Qt Charts (Qt $$QT_VERSION)"
69 71 QMAKE_TARGET_DESCRIPTION = "Charts QML plugin for Qt."
70 72 }
71 73
72 74 QML_FILES += \
73 75 $$PWD/plugins.qmltypes
@@ -1,336 +1,353
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QChart>
31 31 #include <QtCharts/QAbstractAxis>
32 32 #include <QtCharts/QValueAxis>
33 33 #include <QtCharts/QLogValueAxis>
34 34 #include "declarativecategoryaxis.h"
35 35 #include <QtCharts/QBarCategoryAxis>
36 36 #include "declarativechart.h"
37 37 #include "declarativepolarchart.h"
38 38 #include "declarativexypoint.h"
39 39 #include "declarativelineseries.h"
40 40 #include "declarativesplineseries.h"
41 41 #include "declarativeareaseries.h"
42 42 #include "declarativescatterseries.h"
43 43 #include "declarativebarseries.h"
44 44 #include "declarativeboxplotseries.h"
45 #include "declarativecandlestickseries.h"
45 46 #include "declarativepieseries.h"
46 47 #include "declarativeaxes.h"
47 48 #include <QtCharts/QVXYModelMapper>
48 49 #include <QtCharts/QHXYModelMapper>
49 50 #include <QtCharts/QHPieModelMapper>
50 51 #include <QtCharts/QVPieModelMapper>
51 52 #include <QtCharts/QHBarModelMapper>
52 53 #include <QtCharts/QVBarModelMapper>
53 54 #include "declarativemargins.h"
54 55 #include <QtCharts/QAreaLegendMarker>
55 56 #include <QtCharts/QBarLegendMarker>
56 57 #include <QtCharts/QPieLegendMarker>
57 58 #include <QtCharts/QXYLegendMarker>
58 59 #include <QtCharts/QBoxPlotModelMapper>
59 60 #include <QtCharts/QHBoxPlotModelMapper>
60 61 #include <QtCharts/QVBoxPlotModelMapper>
62 #include <QtCharts/QCandlestickModelMapper>
63 #include <QtCharts/QHCandlestickModelMapper>
64 #include <QtCharts/QVCandlestickModelMapper>
61 65 #ifndef QT_QREAL_IS_FLOAT
62 66 #include <QtCharts/QDateTimeAxis>
63 67 #endif
64 68 #include <QtCore/QAbstractItemModel>
65 69 #include <QtQml>
66 70
67 71 QT_CHARTS_USE_NAMESPACE
68 72
69 73 QML_DECLARE_TYPE(QList<QPieSlice *>)
70 74 QML_DECLARE_TYPE(QList<QBarSet *>)
71 75 QML_DECLARE_TYPE(QList<QAbstractAxis *>)
72 76
73 77 QML_DECLARE_TYPE(DeclarativeChart)
74 78 QML_DECLARE_TYPE(DeclarativePolarChart)
75 79 QML_DECLARE_TYPE(DeclarativeMargins)
76 80 QML_DECLARE_TYPE(DeclarativeAreaSeries)
77 81 QML_DECLARE_TYPE(DeclarativeBarSeries)
78 82 QML_DECLARE_TYPE(DeclarativeBarSet)
79 83 QML_DECLARE_TYPE(DeclarativeBoxPlotSeries)
80 84 QML_DECLARE_TYPE(DeclarativeBoxSet)
85 QML_DECLARE_TYPE(DeclarativeCandlestickSeries)
86 QML_DECLARE_TYPE(DeclarativeCandlestickSet)
81 87 QML_DECLARE_TYPE(DeclarativeLineSeries)
82 88 QML_DECLARE_TYPE(DeclarativePieSeries)
83 89 QML_DECLARE_TYPE(DeclarativePieSlice)
84 90 QML_DECLARE_TYPE(DeclarativeScatterSeries)
85 91 QML_DECLARE_TYPE(DeclarativeSplineSeries)
86 92
87 93 QML_DECLARE_TYPE(QAbstractAxis)
88 94 QML_DECLARE_TYPE(QValueAxis)
89 95 QML_DECLARE_TYPE(QBarCategoryAxis)
90 96 QML_DECLARE_TYPE(QCategoryAxis)
91 97 #ifndef QT_QREAL_IS_FLOAT
92 98 QML_DECLARE_TYPE(QDateTimeAxis)
93 99 #endif
94 100 QML_DECLARE_TYPE(QLogValueAxis)
95 101
96 102 QML_DECLARE_TYPE(QLegend)
97 103 QML_DECLARE_TYPE(QLegendMarker)
98 104 QML_DECLARE_TYPE(QAreaLegendMarker)
99 105 QML_DECLARE_TYPE(QBarLegendMarker)
100 106 QML_DECLARE_TYPE(QPieLegendMarker)
101 107
102 108 QML_DECLARE_TYPE(QHPieModelMapper)
103 109 QML_DECLARE_TYPE(QHXYModelMapper)
104 110 QML_DECLARE_TYPE(QPieModelMapper)
105 111 QML_DECLARE_TYPE(QHBarModelMapper)
106 112 QML_DECLARE_TYPE(QBarModelMapper)
107 113 QML_DECLARE_TYPE(QVBarModelMapper)
108 114 QML_DECLARE_TYPE(QVPieModelMapper)
109 115 QML_DECLARE_TYPE(QVXYModelMapper)
110 116 QML_DECLARE_TYPE(QXYLegendMarker)
111 117 QML_DECLARE_TYPE(QXYModelMapper)
112 118 QML_DECLARE_TYPE(QBoxPlotModelMapper)
113 119 QML_DECLARE_TYPE(QHBoxPlotModelMapper)
114 120 QML_DECLARE_TYPE(QVBoxPlotModelMapper)
121 QML_DECLARE_TYPE(QCandlestickModelMapper)
122 QML_DECLARE_TYPE(QHCandlestickModelMapper)
123 QML_DECLARE_TYPE(QVCandlestickModelMapper)
115 124
116 125 QML_DECLARE_TYPE(QAbstractSeries)
117 126 QML_DECLARE_TYPE(QXYSeries)
118 127 QML_DECLARE_TYPE(QAbstractBarSeries)
119 128 QML_DECLARE_TYPE(QBarSeries)
120 129 QML_DECLARE_TYPE(QBarSet)
121 130 QML_DECLARE_TYPE(QAreaSeries)
122 131 QML_DECLARE_TYPE(QHorizontalBarSeries)
123 132 QML_DECLARE_TYPE(QHorizontalPercentBarSeries)
124 133 QML_DECLARE_TYPE(QHorizontalStackedBarSeries)
125 134 QML_DECLARE_TYPE(QLineSeries)
126 135 QML_DECLARE_TYPE(QPercentBarSeries)
127 136 QML_DECLARE_TYPE(QPieSeries)
128 137 QML_DECLARE_TYPE(QPieSlice)
129 138 QML_DECLARE_TYPE(QScatterSeries)
130 139 QML_DECLARE_TYPE(QSplineSeries)
131 140 QML_DECLARE_TYPE(QStackedBarSeries)
132 141
133 142 QT_CHARTS_BEGIN_NAMESPACE
134 143
135 144 class QtChartsQml2Plugin : public QQmlExtensionPlugin
136 145 {
137 146 Q_OBJECT
138 147
139 148 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
140 149
141 150 public:
142 151 virtual void registerTypes(const char *uri)
143 152 {
144 153 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCharts"));
145 154
146 155 // @uri QtCharts
147 156
148 157 qRegisterMetaType<QList<QPieSlice *> >();
149 158 qRegisterMetaType<QList<QBarSet *> >();
150 159 qRegisterMetaType<QList<QAbstractAxis *> >();
151 160
152 161 // QtCharts 1.0
153 162 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "ChartView");
154 163 qmlRegisterType<DeclarativeXYPoint>(uri, 1, 0, "XYPoint");
155 164 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
156 165 qmlRegisterType<DeclarativeLineSeries>(uri, 1, 0, "LineSeries");
157 166 qmlRegisterType<DeclarativeSplineSeries>(uri, 1, 0, "SplineSeries");
158 167 qmlRegisterType<DeclarativeAreaSeries>(uri, 1, 0, "AreaSeries");
159 168 qmlRegisterType<DeclarativeBarSeries>(uri, 1, 0, "BarSeries");
160 169 qmlRegisterType<DeclarativeStackedBarSeries>(uri, 1, 0, "StackedBarSeries");
161 170 qmlRegisterType<DeclarativePercentBarSeries>(uri, 1, 0, "PercentBarSeries");
162 171 qmlRegisterType<DeclarativePieSeries>(uri, 1, 0, "PieSeries");
163 172 qmlRegisterType<QPieSlice>(uri, 1, 0, "PieSlice");
164 173 qmlRegisterType<DeclarativeBarSet>(uri, 1, 0, "BarSet");
165 174 qmlRegisterType<QHXYModelMapper>(uri, 1, 0, "HXYModelMapper");
166 175 qmlRegisterType<QVXYModelMapper>(uri, 1, 0, "VXYModelMapper");
167 176 qmlRegisterType<QHPieModelMapper>(uri, 1, 0, "HPieModelMapper");
168 177 qmlRegisterType<QVPieModelMapper>(uri, 1, 0, "VPieModelMapper");
169 178 qmlRegisterType<QHBarModelMapper>(uri, 1, 0, "HBarModelMapper");
170 179 qmlRegisterType<QVBarModelMapper>(uri, 1, 0, "VBarModelMapper");
171 180
172 181 qmlRegisterType<QValueAxis>(uri, 1, 0, "ValuesAxis");
173 182 qmlRegisterType<QBarCategoryAxis>(uri, 1, 0, "BarCategoriesAxis");
174 183 qmlRegisterUncreatableType<QLegend>(uri, 1, 0, "Legend",
175 184 QLatin1String("Trying to create uncreatable: Legend."));
176 185 qmlRegisterUncreatableType<QXYSeries>(uri, 1, 0, "XYSeries",
177 186 QLatin1String("Trying to create uncreatable: XYSeries."));
178 187 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
179 188 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
180 189 qmlRegisterUncreatableType<QXYModelMapper>(uri, 1, 0, "XYModelMapper",
181 190 QLatin1String("Trying to create uncreatable: XYModelMapper."));
182 191 qmlRegisterUncreatableType<QPieModelMapper>(uri, 1, 0, "PieModelMapper",
183 192 QLatin1String("Trying to create uncreatable: PieModelMapper."));
184 193 qmlRegisterUncreatableType<QBarModelMapper>(uri, 1, 0, "BarModelMapper",
185 194 QLatin1String("Trying to create uncreatable: BarModelMapper."));
186 195 qmlRegisterUncreatableType<QAbstractSeries>(uri, 1, 0, "AbstractSeries",
187 196 QLatin1String("Trying to create uncreatable: AbstractSeries."));
188 197 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 1, 0, "AbstractBarSeries",
189 198 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
190 199 qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
191 200 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
192 201 qmlRegisterUncreatableType<QBarSet>(uri, 1, 0, "BarSetBase",
193 202 QLatin1String("Trying to create uncreatable: BarsetBase."));
194 203 qmlRegisterUncreatableType<QPieSeries>(uri, 1, 0, "QPieSeries",
195 204 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
196 205 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 1, 0, "DeclarativeAxes",
197 206 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
198 207
199 208 // QtCharts 1.1
200 209 qmlRegisterType<DeclarativeChart, 1>(uri, 1, 1, "ChartView");
201 210 qmlRegisterType<DeclarativeScatterSeries, 1>(uri, 1, 1, "ScatterSeries");
202 211 qmlRegisterType<DeclarativeLineSeries, 1>(uri, 1, 1, "LineSeries");
203 212 qmlRegisterType<DeclarativeSplineSeries, 1>(uri, 1, 1, "SplineSeries");
204 213 qmlRegisterType<DeclarativeAreaSeries, 1>(uri, 1, 1, "AreaSeries");
205 214 qmlRegisterType<DeclarativeBarSeries, 1>(uri, 1, 1, "BarSeries");
206 215 qmlRegisterType<DeclarativeStackedBarSeries, 1>(uri, 1, 1, "StackedBarSeries");
207 216 qmlRegisterType<DeclarativePercentBarSeries, 1>(uri, 1, 1, "PercentBarSeries");
208 217 qmlRegisterType<DeclarativeHorizontalBarSeries, 1>(uri, 1, 1, "HorizontalBarSeries");
209 218 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 1>(uri, 1, 1, "HorizontalStackedBarSeries");
210 219 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 1>(uri, 1, 1, "HorizontalPercentBarSeries");
211 220 qmlRegisterType<DeclarativePieSeries>(uri, 1, 1, "PieSeries");
212 221 qmlRegisterType<DeclarativeBarSet>(uri, 1, 1, "BarSet");
213 222 qmlRegisterType<QValueAxis>(uri, 1, 1, "ValueAxis");
214 223 #ifndef QT_QREAL_IS_FLOAT
215 224 qmlRegisterType<QDateTimeAxis>(uri, 1, 1, "DateTimeAxis");
216 225 #endif
217 226 qmlRegisterType<DeclarativeCategoryAxis>(uri, 1, 1, "CategoryAxis");
218 227 qmlRegisterType<DeclarativeCategoryRange>(uri, 1, 1, "CategoryRange");
219 228 qmlRegisterType<QBarCategoryAxis>(uri, 1, 1, "BarCategoryAxis");
220 229 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 1, 1, "Margins",
221 230 QLatin1String("Trying to create uncreatable: Margins."));
222 231
223 232 // QtCharts 1.2
224 233 qmlRegisterType<DeclarativeChart, 2>(uri, 1, 2, "ChartView");
225 234 qmlRegisterType<DeclarativeScatterSeries, 2>(uri, 1, 2, "ScatterSeries");
226 235 qmlRegisterType<DeclarativeLineSeries, 2>(uri, 1, 2, "LineSeries");
227 236 qmlRegisterType<DeclarativeSplineSeries, 2>(uri, 1, 2, "SplineSeries");
228 237 qmlRegisterType<DeclarativeAreaSeries, 2>(uri, 1, 2, "AreaSeries");
229 238 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 1, 2, "BarSeries");
230 239 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 1, 2, "StackedBarSeries");
231 240 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 1, 2, "PercentBarSeries");
232 241 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 1, 2, "HorizontalBarSeries");
233 242 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 1, 2, "HorizontalStackedBarSeries");
234 243 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 1, 2, "HorizontalPercentBarSeries");
235 244
236 245 // QtCharts 1.3
237 246 qmlRegisterType<DeclarativeChart, 3>(uri, 1, 3, "ChartView");
238 247 qmlRegisterType<DeclarativePolarChart, 1>(uri, 1, 3, "PolarChartView");
239 248 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 1, 3, "SplineSeries");
240 249 qmlRegisterType<DeclarativeScatterSeries, 3>(uri, 1, 3, "ScatterSeries");
241 250 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 1, 3, "LineSeries");
242 251 qmlRegisterType<DeclarativeAreaSeries, 3>(uri, 1, 3, "AreaSeries");
243 252 qmlRegisterType<QLogValueAxis>(uri, 1, 3, "LogValueAxis");
244 253 qmlRegisterType<DeclarativeBoxPlotSeries>(uri, 1, 3, "BoxPlotSeries");
245 254 qmlRegisterType<DeclarativeBoxSet>(uri, 1, 3, "BoxSet");
246 255
247 256 // QtCharts 1.4
248 257 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 1, 4, "AreaSeries");
249 258 qmlRegisterType<DeclarativeBarSet, 2>(uri, 1, 4, "BarSet");
250 259 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 1, 4, "BoxPlotSeries");
251 260 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 1, 4, "BoxSet");
252 261 qmlRegisterType<DeclarativePieSlice>(uri, 1, 4, "PieSlice");
253 262 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 1, 4, "ScatterSeries");
254 263
255 264 // QtCharts 2.0
256 265 qmlRegisterType<QHBoxPlotModelMapper>(uri, 2, 0, "HBoxPlotModelMapper");
257 266 qmlRegisterType<QVBoxPlotModelMapper>(uri, 2, 0, "VBoxPlotModelMapper");
258 267 qmlRegisterUncreatableType<QBoxPlotModelMapper>(uri, 2, 0, "BoxPlotModelMapper",
259 268 QLatin1String("Trying to create uncreatable: BoxPlotModelMapper."));
260 269 qmlRegisterType<DeclarativeChart, 4>(uri, 2, 0, "ChartView");
261 270 qmlRegisterType<DeclarativeXYPoint>(uri, 2, 0, "XYPoint");
262 271 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 2, 0, "ScatterSeries");
263 272 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 2, 0, "LineSeries");
264 273 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 2, 0, "SplineSeries");
265 274 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 2, 0, "AreaSeries");
266 275 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 2, 0, "BarSeries");
267 276 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 2, 0, "StackedBarSeries");
268 277 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 2, 0, "PercentBarSeries");
269 278 qmlRegisterType<DeclarativePieSeries>(uri, 2, 0, "PieSeries");
270 279 qmlRegisterType<QPieSlice>(uri, 2, 0, "PieSlice");
271 280 qmlRegisterType<DeclarativeBarSet, 2>(uri, 2, 0, "BarSet");
272 281 qmlRegisterType<QHXYModelMapper>(uri, 2, 0, "HXYModelMapper");
273 282 qmlRegisterType<QVXYModelMapper>(uri, 2, 0, "VXYModelMapper");
274 283 qmlRegisterType<QHPieModelMapper>(uri, 2, 0, "HPieModelMapper");
275 284 qmlRegisterType<QVPieModelMapper>(uri, 2, 0, "VPieModelMapper");
276 285 qmlRegisterType<QHBarModelMapper>(uri, 2, 0, "HBarModelMapper");
277 286 qmlRegisterType<QVBarModelMapper>(uri, 2, 0, "VBarModelMapper");
278 287 qmlRegisterType<QValueAxis>(uri, 2, 0, "ValueAxis");
279 288 #ifndef QT_QREAL_IS_FLOAT
280 289 qmlRegisterType<QDateTimeAxis>(uri, 2, 0, "DateTimeAxis");
281 290 #endif
282 291 qmlRegisterType<DeclarativeCategoryAxis>(uri, 2, 0, "CategoryAxis");
283 292 qmlRegisterType<DeclarativeCategoryRange>(uri, 2, 0, "CategoryRange");
284 293 qmlRegisterType<QBarCategoryAxis>(uri, 2, 0, "BarCategoryAxis");
285 294 qmlRegisterType<DeclarativePolarChart, 1>(uri, 2, 0, "PolarChartView");
286 295 qmlRegisterType<QLogValueAxis, 1>(uri, 2, 0, "LogValueAxis");
287 296 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 2, 0, "BoxPlotSeries");
288 297 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 2, 0, "BoxSet");
289 298 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 2, 0, "HorizontalBarSeries");
290 299 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 2, 0, "HorizontalStackedBarSeries");
291 300 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 2, 0, "HorizontalPercentBarSeries");
292 301 qmlRegisterType<DeclarativePieSlice>(uri, 2, 0, "PieSlice");
293 302 qmlRegisterUncreatableType<QLegend>(uri, 2, 0, "Legend",
294 303 QLatin1String("Trying to create uncreatable: Legend."));
295 304 qmlRegisterUncreatableType<QXYSeries>(uri, 2, 0, "XYSeries",
296 305 QLatin1String("Trying to create uncreatable: XYSeries."));
297 306 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 2, 0, "AbstractItemModel",
298 307 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
299 308 qmlRegisterUncreatableType<QXYModelMapper>(uri, 2, 0, "XYModelMapper",
300 309 QLatin1String("Trying to create uncreatable: XYModelMapper."));
301 310 qmlRegisterUncreatableType<QPieModelMapper>(uri, 2, 0, "PieModelMapper",
302 311 QLatin1String("Trying to create uncreatable: PieModelMapper."));
303 312 qmlRegisterUncreatableType<QBarModelMapper>(uri, 2, 0, "BarModelMapper",
304 313 QLatin1String("Trying to create uncreatable: BarModelMapper."));
305 314 qmlRegisterUncreatableType<QAbstractSeries>(uri, 2, 0, "AbstractSeries",
306 315 QLatin1String("Trying to create uncreatable: AbstractSeries."));
307 316 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 2, 0, "AbstractBarSeries",
308 317 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
309 318 qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 0, "AbstractAxis",
310 319 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
311 320 qmlRegisterUncreatableType<QBarSet>(uri, 2, 0, "BarSetBase",
312 321 QLatin1String("Trying to create uncreatable: BarsetBase."));
313 322 qmlRegisterUncreatableType<QPieSeries>(uri, 2, 0, "QPieSeries",
314 323 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
315 324 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 2, 0, "DeclarativeAxes",
316 325 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
317 326 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 2, 0, "Margins",
318 327 QLatin1String("Trying to create uncreatable: Margins."));
319 328
320 329 // QtCharts 2.1
321 330 qmlRegisterType<DeclarativeCategoryAxis, 1>(uri, 2, 1, "CategoryAxis");
322 331 qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 1, "AbstractAxis",
323 332 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
324 333 qmlRegisterType<DeclarativeChart, 5>(uri, 2, 1, "ChartView");
325 334 qmlRegisterType<DeclarativeScatterSeries, 5>(uri, 2, 1, "ScatterSeries");
326 335 qmlRegisterType<DeclarativeLineSeries, 4>(uri, 2, 1, "LineSeries");
327 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 };
331 348
332 349 QT_CHARTS_END_NAMESPACE
333 350
334 351 #include "chartsqml2_plugin.moc"
335 352
336 353 QT_CHARTS_USE_NAMESPACE
@@ -1,1252 +1,1258
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include "declarativechart.h"
31 31 #include <QtGui/QPainter>
32 32 #include "declarativelineseries.h"
33 33 #include "declarativeareaseries.h"
34 34 #include "declarativebarseries.h"
35 35 #include "declarativepieseries.h"
36 36 #include "declarativesplineseries.h"
37 37 #include "declarativeboxplotseries.h"
38 #include "declarativecandlestickseries.h"
38 39 #include "declarativescatterseries.h"
39 40 #include "declarativechartnode.h"
40 41 #include "declarativerendernode.h"
41 42 #include <QtCharts/QBarCategoryAxis>
42 43 #include <QtCharts/QValueAxis>
43 44 #include <QtCharts/QLogValueAxis>
44 45 #include <QtCharts/QCategoryAxis>
45 46 #include <private/qabstractseries_p.h>
46 47 #include "declarativemargins.h"
47 48 #include <private/chartdataset_p.h>
48 49 #include "declarativeaxes.h"
49 50 #include <private/qchart_p.h>
50 51 #include <private/chartpresenter_p.h>
51 52 #include <QtCharts/QPolarChart>
52 53
53 54 #ifndef QT_QREAL_IS_FLOAT
54 55 #include <QtCharts/QDateTimeAxis>
55 56 #endif
56 57
57 58 #include <QtWidgets/QGraphicsSceneMouseEvent>
58 59 #include <QtWidgets/QGraphicsSceneHoverEvent>
59 60 #include <QtWidgets/QApplication>
60 61 #include <QtCore/QTimer>
61 62 #include <QtCore/QThread>
62 63
63 64 QT_CHARTS_BEGIN_NAMESPACE
64 65
65 66 /*!
66 67 \qmltype ChartView
67 68 \instantiates DeclarativeChart
68 69 \inqmlmodule QtCharts
69 70
70 71 \brief Chart element.
71 72
72 73 ChartView element is the parent that is responsible for showing different chart series types.
73 74
74 75 The following QML shows how to create a simple chart with one pie series:
75 76 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
76 77 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
77 78 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
78 79
79 80 \beginfloatleft
80 81 \image examples_qmlpiechart.png
81 82 \endfloat
82 83 \clearfloat
83 84 */
84 85
85 86 /*!
86 87 \qmlproperty Theme ChartView::theme
87 88 Theme defines the visual appearance of the chart, including for example colors, fonts, line
88 89 widths and chart background.
89 90 */
90 91
91 92 /*!
92 93 \qmlproperty Animation ChartView::animationOptions
93 94 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
94 95 ChartView.SeriesAnimations or ChartView.AllAnimations.
95 96 */
96 97
97 98 /*!
98 99 \qmlproperty int ChartView::animationDuration
99 100 The duration of the animation for the chart.
100 101 */
101 102
102 103 /*!
103 104 \qmlproperty easing ChartView::animationEasingCurve
104 105 The easing curve of the animation for the chart.
105 106 */
106 107
107 108 /*!
108 109 \qmlproperty Font ChartView::titleFont
109 110 The title font of the chart.
110 111
111 112 See the Qt documentation for more details of Font.
112 113 */
113 114
114 115 /*!
115 116 \qmlproperty string ChartView::title
116 117 The title of the chart, shown on top of the chart.
117 118 \sa ChartView::titleColor
118 119 */
119 120
120 121 /*!
121 122 \qmlproperty color ChartView::titleColor
122 123 The color of the title text.
123 124 */
124 125
125 126 /*!
126 127 \qmlproperty Legend ChartView::legend
127 128 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
128 129 */
129 130
130 131 /*!
131 132 \qmlproperty int ChartView::count
132 133 The count of series added to the chart.
133 134 */
134 135
135 136 /*!
136 137 \qmlproperty color ChartView::backgroundColor
137 138 The color of the chart's background. By default background color is defined by chart theme.
138 139 \sa ChartView::theme
139 140 */
140 141
141 142 /*!
142 143 \qmlproperty real ChartView::backgroundRoundness
143 144 The diameter of the rounding circle at the corners of the chart background.
144 145 */
145 146
146 147 /*!
147 148 \qmlproperty color ChartView::plotAreaColor
148 149 The color of the background of the chart's plot area. By default plot area background uses chart's
149 150 background color.
150 151 \sa ChartView::backgroundColor
151 152 */
152 153
153 154 /*!
154 155 \qmlproperty list<AbstractAxis> ChartView::axes
155 156 The axes of the ChartView.
156 157 */
157 158
158 159 /*!
159 160 \qmlproperty bool ChartView::dropShadowEnabled
160 161 The chart's border drop shadow. Set to true to enable drop shadow.
161 162 */
162 163
163 164 /*!
164 165 \qmlproperty rect ChartView::plotArea
165 166 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
166 167 margins.
167 168 \sa ChartView::margins
168 169 */
169 170
170 171 /*!
171 172 \qmlproperty Margins ChartView::margins
172 173 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
173 174 area of ChartView is used for drawing title, axes and legend.
174 175 */
175 176
176 177 /*!
177 178 \qmlproperty bool ChartView::localizeNumbers
178 179 \since QtCharts 2.0
179 180 When \c{true}, all generated numbers appearing in various series and axis labels will be
180 181 localized using the default QLocale of the application, which defaults to the system locale.
181 182 When \c{false}, the "C" locale is always used.
182 183 Defaults to \c{false}.
183 184
184 185 \sa locale
185 186 */
186 187
187 188 /*!
188 189 \qmlproperty locale ChartView::locale
189 190 \since QtCharts 2.0
190 191 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
191 192 This also determines the locale used to format DateTimeAxis labels regardless of
192 193 localizeNumbers property.
193 194 Defaults to application default locale at the time the chart is constructed.
194 195
195 196 \sa localizeNumbers
196 197 */
197 198
198 199 /*!
199 200 \qmlmethod AbstractSeries ChartView::series(int index)
200 201 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
201 202 the count property of the chart.
202 203 */
203 204
204 205 /*!
205 206 \qmlmethod AbstractSeries ChartView::series(string name)
206 207 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
207 208 */
208 209
209 210 /*!
210 211 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
211 212 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
212 213 optional axis \a axisY. For example:
213 214 \code
214 215 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
215 216 var myAxisX = chartView.axisX(lineSeries);
216 217 var myAxisY = chartView.axisY(lineSeries);
217 218 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
218 219 \endcode
219 220 */
220 221
221 222 /*!
222 223 \qmlmethod ChartView::removeSeries(AbstractSeries series)
223 224 Removes the \a series from the chart. The series object is also destroyed.
224 225 */
225 226
226 227 /*!
227 228 \qmlmethod ChartView::removeAllSeries()
228 229 Removes all series from the chart. All the series objects are also destroyed.
229 230 */
230 231
231 232 /*!
232 233 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
233 234 The x-axis of the series.
234 235 */
235 236
236 237 /*!
237 238 \qmlmethod ChartView::setAxisX(AbstractAxis axis, AbstractSeries series)
238 239 Set the x-axis of the series.
239 240 */
240 241
241 242 /*!
242 243 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
243 244 The y-axis of the series.
244 245 */
245 246
246 247 /*!
247 248 \qmlmethod ChartView::setAxisY(AbstractAxis axis, AbstractSeries series)
248 249 Set the y-axis of the series.
249 250 */
250 251
251 252 /*!
252 253 \qmlmethod ChartView::zoom(real factor)
253 254 Zooms in by \a factor on the center of the chart.
254 255
255 256 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
256 257 */
257 258
258 259 /*!
259 260 \qmlmethod ChartView::zoomIn()
260 261 Zooms in the view by a factor of two.
261 262 */
262 263
263 264 /*!
264 265 \qmlmethod ChartView::zoomIn(rect rectangle)
265 266 Zooms in the view to a maximum level at which \a rectangle is still fully visible.
266 267 \note This is not supported for polar charts.
267 268 */
268 269
269 270 /*!
270 271 \qmlmethod ChartView::zoomOut()
271 272 Zooms out the view by a factor of two.
272 273 */
273 274
274 275 /*!
275 276 \qmlmethod ChartView::zoomReset()
276 277 Resets the series domains to what they were before any zoom method was called.
277 278 Note that this will also reset any scrolls and explicit axis range settings done between
278 279 the first zoom operation and calling this method. If no zoom operation has been
279 280 done, this method does nothing.
280 281 */
281 282
282 283 /*!
283 284 \qmlmethod ChartView::isZoomed()
284 285 Returns true if any series has a zoomed domain.
285 286 */
286 287
287 288 /*!
288 289 \qmlmethod ChartView::scrollLeft(real pixels)
289 290 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
290 291 */
291 292
292 293 /*!
293 294 \qmlmethod ChartView::scrollRight(real pixels)
294 295 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
295 296 */
296 297
297 298 /*!
298 299 \qmlmethod ChartView::scrollUp(real pixels)
299 300 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
300 301 */
301 302
302 303 /*!
303 304 \qmlmethod ChartView::scrollDown(real pixels)
304 305 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
305 306 */
306 307
307 308 /*!
308 309 \qmlmethod point ChartView::mapToValue(point position, AbstractSeries series)
309 310 Returns the value in the \a series domain that corresponds to the \a position relative to the
310 311 chart.
311 312 */
312 313
313 314 /*!
314 315 \qmlmethod point ChartView::mapToPosition(point value, AbstractSeries series)
315 316 Returns the position on the chart that corresponds to the \a value in the \a series domain.
316 317 */
317 318
318 319 /*!
319 320 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
320 321 The \a series has been added to the chart.
321 322 */
322 323
323 324 /*!
324 325 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
325 326 The \a series has been removed from the chart. Please note that \a series is no longer a valid
326 327 object after the signal handler has completed.
327 328 */
328 329
329 330 DeclarativeChart::DeclarativeChart(QQuickItem *parent)
330 331 : QQuickItem(parent)
331 332 {
332 333 initChart(QChart::ChartTypeCartesian);
333 334 }
334 335
335 336 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent)
336 337 : QQuickItem(parent)
337 338 {
338 339 initChart(type);
339 340 }
340 341
341 342 void DeclarativeChart::initChart(QChart::ChartType type)
342 343 {
343 344 m_sceneImage = 0;
344 345 m_sceneImageDirty = false;
345 346 m_sceneImageNeedsClear = false;
346 347 m_guiThreadId = QThread::currentThreadId();
347 348 m_paintThreadId = 0;
348 349 m_updatePending = false;
349 350
350 351 setFlag(ItemHasContents, true);
351 352
352 353 if (type == QChart::ChartTypePolar)
353 354 m_chart = new QPolarChart();
354 355 else
355 356 m_chart = new QChart();
356 357
357 358 m_chart->d_ptr->m_presenter->glSetUseWidget(false);
358 359 m_glXYDataManager = m_chart->d_ptr->m_dataset->glXYSeriesDataManager();
359 360
360 361 m_scene = new QGraphicsScene(this);
361 362 m_scene->addItem(m_chart);
362 363
363 364 setAntialiasing(QQuickItem::antialiasing());
364 365 connect(m_scene, &QGraphicsScene::changed, this, &DeclarativeChart::sceneChanged);
365 366 connect(this, &DeclarativeChart::needRender, this, &DeclarativeChart::renderScene,
366 367 Qt::QueuedConnection);
367 368 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
368 369
369 370 setAcceptedMouseButtons(Qt::AllButtons);
370 371 setAcceptHoverEvents(true);
371 372
372 373 m_margins = new DeclarativeMargins(this);
373 374 m_margins->setTop(m_chart->margins().top());
374 375 m_margins->setLeft(m_chart->margins().left());
375 376 m_margins->setRight(m_chart->margins().right());
376 377 m_margins->setBottom(m_chart->margins().bottom());
377 378 connect(m_margins, SIGNAL(topChanged(int,int,int,int)),
378 379 this, SLOT(changeMargins(int,int,int,int)));
379 380 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)),
380 381 this, SLOT(changeMargins(int,int,int,int)));
381 382 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)),
382 383 this, SLOT(changeMargins(int,int,int,int)));
383 384 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)),
384 385 this, SLOT(changeMargins(int,int,int,int)));
385 386 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
386 387 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
387 388 connect(m_chart, &QChart::plotAreaChanged, this, &DeclarativeChart::plotAreaChanged);
388 389 }
389 390
390 391 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
391 392 {
392 393 emit seriesAdded(series);
393 394 }
394 395
395 396 void DeclarativeChart::changeMargins(int top, int bottom, int left, int right)
396 397 {
397 398 m_chart->setMargins(QMargins(left, top, right, bottom));
398 399 emit marginsChanged();
399 400 }
400 401
401 402 DeclarativeChart::~DeclarativeChart()
402 403 {
403 404 delete m_chart;
404 405 delete m_sceneImage;
405 406 }
406 407
407 408 void DeclarativeChart::childEvent(QChildEvent *event)
408 409 {
409 410 if (event->type() == QEvent::ChildAdded) {
410 411 if (qobject_cast<QAbstractSeries *>(event->child())) {
411 412 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
412 413 }
413 414 }
414 415 }
415 416
416 417 void DeclarativeChart::componentComplete()
417 418 {
418 419 foreach (QObject *child, children()) {
419 420 if (qobject_cast<QAbstractSeries *>(child)) {
420 421 // Add series to the chart
421 422 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
422 423 m_chart->addSeries(series);
423 424
424 425 // Connect to axis changed signals (unless this is a pie series)
425 426 if (!qobject_cast<DeclarativePieSeries *>(series)) {
426 427 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
427 428 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
428 429 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
429 430 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
430 431 }
431 432
432 433 initializeAxes(series);
433 434 }
434 435 }
435 436
436 437 QQuickItem::componentComplete();
437 438 }
438 439
439 440 void DeclarativeChart::seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
440 441 Qt::Orientations orientation,
441 442 Qt::Alignment alignment)
442 443 {
443 444 if (!series->attachedAxes().contains(axis)) {
444 445 // Remove & delete old axes that are not attached to any other series
445 446 foreach (QAbstractAxis* oldAxis, m_chart->axes(orientation, series)) {
446 447 bool otherAttachments = false;
447 448 if (oldAxis != axis) {
448 449 foreach (QAbstractSeries *oldSeries, m_chart->series()) {
449 450 if (oldSeries != series && oldSeries->attachedAxes().contains(oldAxis)) {
450 451 otherAttachments = true;
451 452 break;
452 453 }
453 454 }
454 455 if (!otherAttachments) {
455 456 m_chart->removeAxis(oldAxis);
456 457 delete oldAxis;
457 458 }
458 459 }
459 460 }
460 461 if (!m_chart->axes(orientation).contains(axis))
461 462 m_chart->addAxis(axis, alignment);
462 463
463 464 series->attachAxis(axis);
464 465 }
465 466 }
466 467
467 468 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
468 469 {
469 470 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
470 471 if (axis && s) {
471 472 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignBottom);
472 473 } else {
473 474 qWarning() << "Trying to set axisX to null.";
474 475 }
475 476 }
476 477
477 478 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
478 479 {
479 480 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
480 481 if (axis && s) {
481 482 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignTop);
482 483 } else {
483 484 qWarning() << "Trying to set axisXTop to null.";
484 485 }
485 486 }
486 487
487 488 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
488 489 {
489 490 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
490 491 if (axis && s) {
491 492 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignLeft);
492 493 } else {
493 494 qWarning() << "Trying to set axisY to null.";
494 495 }
495 496 }
496 497
497 498 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
498 499 {
499 500 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
500 501 if (axis && s) {
501 502 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignRight);
502 503 } else {
503 504 qWarning() << "Trying to set axisYRight to null.";
504 505 }
505 506 }
506 507
507 508 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
508 509 {
509 510 if (newGeometry.isValid()) {
510 511 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
511 512 m_chart->resize(newGeometry.width(), newGeometry.height());
512 513 }
513 514 }
514 515 QQuickItem::geometryChanged(newGeometry, oldGeometry);
515 516 }
516 517
517 518 QSGNode *DeclarativeChart::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
518 519 {
519 520 DeclarativeChartNode *node = static_cast<DeclarativeChartNode *>(oldNode);
520 521
521 522 if (!node) {
522 523 node = new DeclarativeChartNode(window());
523 524 if (node->glRenderNode()) {
524 525 connect(window(), &QQuickWindow::beforeRendering,
525 526 node->glRenderNode(), &DeclarativeRenderNode::render);
526 527 }
527 528 }
528 529
529 530 const QRectF &bRect = boundingRect();
530 531
531 532 // Update GL data
532 533 if (node->glRenderNode() && (m_glXYDataManager->dataMap().size() || m_glXYDataManager->mapDirty())) {
533 534 const QRectF &plotArea = m_chart->plotArea();
534 535 const QSizeF &chartAreaSize = m_chart->size();
535 536
536 537 // We can't use chart's plot area directly, as graphicscene has some internal minimum size
537 538 const qreal normalizedX = plotArea.x() / chartAreaSize.width();
538 539 const qreal normalizedY = plotArea.y() / chartAreaSize.height();
539 540 const qreal normalizedWidth = plotArea.width() / chartAreaSize.width();
540 541 const qreal normalizedHeight = plotArea.height() / chartAreaSize.height();
541 542
542 543 QRectF adjustedPlotArea(normalizedX * bRect.width(),
543 544 normalizedY * bRect.height(),
544 545 normalizedWidth * bRect.width(),
545 546 normalizedHeight * bRect.height());
546 547
547 548 const QSize &adjustedPlotSize = adjustedPlotArea.size().toSize();
548 549 if (adjustedPlotSize != node->glRenderNode()->textureSize())
549 550 node->glRenderNode()->setTextureSize(adjustedPlotSize);
550 551
551 552 node->glRenderNode()->setRect(adjustedPlotArea);
552 553 node->glRenderNode()->setSeriesData(m_glXYDataManager->mapDirty(),
553 554 m_glXYDataManager->dataMap());
554 555
555 556 // Clear dirty flags from original xy data
556 557 m_glXYDataManager->clearAllDirty();
557 558 }
558 559
559 560 // Copy chart (if dirty) to chart node
560 561 if (m_sceneImageDirty) {
561 562 node->createTextureFromImage(*m_sceneImage);
562 563 m_sceneImageDirty = false;
563 564 }
564 565
565 566 node->setRect(bRect);
566 567
567 568 return node;
568 569 }
569 570
570 571 void DeclarativeChart::sceneChanged(QList<QRectF> region)
571 572 {
572 573 const int count = region.size();
573 574 const qreal limitSize = 0.01;
574 575 if (count && !m_updatePending) {
575 576 qreal totalSize = 0.0;
576 577 for (int i = 0; i < count; i++) {
577 578 const QRectF &reg = region.at(i);
578 579 totalSize += (reg.height() * reg.width());
579 580 if (totalSize >= limitSize)
580 581 break;
581 582 }
582 583 // Ignore region updates that change less than small fraction of a pixel, as there is
583 584 // little point regenerating the image in these cases. These are typically cases
584 585 // where OpenGL series are drawn to otherwise static chart.
585 586 if (totalSize >= limitSize) {
586 587 m_updatePending = true;
587 588 // Do async render to avoid some unnecessary renders.
588 589 emit needRender();
589 590 } else {
590 591 // We do want to call update to trigger possible gl series updates.
591 592 update();
592 593 }
593 594 }
594 595 }
595 596
596 597 void DeclarativeChart::renderScene()
597 598 {
598 599 m_updatePending = false;
599 600 m_sceneImageDirty = true;
600 601 QSize chartSize = m_chart->size().toSize();
601 602 if (!m_sceneImage || chartSize != m_sceneImage->size()) {
602 603 delete m_sceneImage;
603 604 qreal dpr = window() ? window()->devicePixelRatio() : 1.0;
604 605 m_sceneImage = new QImage(chartSize * dpr, QImage::Format_ARGB32);
605 606 m_sceneImage->setDevicePixelRatio(dpr);
606 607 m_sceneImageNeedsClear = true;
607 608 }
608 609
609 610 if (m_sceneImageNeedsClear) {
610 611 m_sceneImage->fill(Qt::transparent);
611 612 // Don't clear the flag if chart background has any transparent element to it
612 613 if (m_chart->backgroundBrush().color().alpha() == 0xff && !m_chart->isDropShadowEnabled())
613 614 m_sceneImageNeedsClear = false;
614 615 }
615 616 QPainter painter(m_sceneImage);
616 617 if (antialiasing()) {
617 618 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
618 619 | QPainter::SmoothPixmapTransform);
619 620 }
620 621 QRect renderRect(QPoint(0, 0), chartSize);
621 622 m_scene->render(&painter, renderRect, renderRect);
622 623 update();
623 624 }
624 625
625 626 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
626 627 {
627 628 m_mousePressScenePoint = event->pos();
628 629 m_mousePressScreenPoint = event->globalPos();
629 630 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
630 631 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
631 632 m_mousePressButton = event->button();
632 633 m_mousePressButtons = event->buttons();
633 634
634 635 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
635 636 mouseEvent.setWidget(0);
636 637 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
637 638 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
638 639 mouseEvent.setScenePos(m_mousePressScenePoint);
639 640 mouseEvent.setScreenPos(m_mousePressScreenPoint);
640 641 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
641 642 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
642 643 mouseEvent.setButtons(m_mousePressButtons);
643 644 mouseEvent.setButton(m_mousePressButton);
644 645 mouseEvent.setModifiers(event->modifiers());
645 646 mouseEvent.setAccepted(false);
646 647
647 648 QApplication::sendEvent(m_scene, &mouseEvent);
648 649 }
649 650
650 651 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
651 652 {
652 653 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
653 654 mouseEvent.setWidget(0);
654 655 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
655 656 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
656 657 mouseEvent.setScenePos(event->pos());
657 658 mouseEvent.setScreenPos(event->globalPos());
658 659 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
659 660 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
660 661 mouseEvent.setButtons(event->buttons());
661 662 mouseEvent.setButton(event->button());
662 663 mouseEvent.setModifiers(event->modifiers());
663 664 mouseEvent.setAccepted(false);
664 665
665 666 QApplication::sendEvent(m_scene, &mouseEvent);
666 667
667 668 m_mousePressButtons = event->buttons();
668 669 m_mousePressButton = Qt::NoButton;
669 670 }
670 671
671 672 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
672 673 {
673 674 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
674 675 // QGraphicsScene generates hover events from mouse move events, so we don't need
675 676 // to pass hover events there.
676 677 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
677 678 mouseEvent.setWidget(0);
678 679 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
679 680 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
680 681 mouseEvent.setScenePos(event->pos());
681 682 // Hover events do not have global pos in them, and the screen position doesn't seem to
682 683 // matter anyway in this use case, so just pass event pos instead of trying to
683 684 // calculate the real screen position.
684 685 mouseEvent.setScreenPos(event->pos());
685 686 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
686 687 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
687 688 mouseEvent.setButtons(m_mousePressButtons);
688 689 mouseEvent.setButton(m_mousePressButton);
689 690 mouseEvent.setModifiers(event->modifiers());
690 691 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
691 692 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
692 693 mouseEvent.setAccepted(false);
693 694
694 695 QApplication::sendEvent(m_scene, &mouseEvent);
695 696 }
696 697
697 698 void DeclarativeChart::mouseDoubleClickEvent(QMouseEvent *event)
698 699 {
699 700 m_mousePressScenePoint = event->pos();
700 701 m_mousePressScreenPoint = event->globalPos();
701 702 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
702 703 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
703 704 m_mousePressButton = event->button();
704 705 m_mousePressButtons = event->buttons();
705 706
706 707 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
707 708 mouseEvent.setWidget(0);
708 709 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
709 710 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
710 711 mouseEvent.setScenePos(m_mousePressScenePoint);
711 712 mouseEvent.setScreenPos(m_mousePressScreenPoint);
712 713 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
713 714 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
714 715 mouseEvent.setButtons(m_mousePressButtons);
715 716 mouseEvent.setButton(m_mousePressButton);
716 717 mouseEvent.setModifiers(event->modifiers());
717 718 mouseEvent.setAccepted(false);
718 719
719 720 QApplication::sendEvent(m_scene, &mouseEvent);
720 721 }
721 722
722 723 void DeclarativeChart::handleAntialiasingChanged(bool enable)
723 724 {
724 725 setAntialiasing(enable);
725 726 }
726 727
727 728 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
728 729 {
729 730 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
730 731 if (chartTheme != m_chart->theme())
731 732 m_chart->setTheme(chartTheme);
732 733 }
733 734
734 735 DeclarativeChart::Theme DeclarativeChart::theme()
735 736 {
736 737 return (DeclarativeChart::Theme) m_chart->theme();
737 738 }
738 739
739 740 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
740 741 {
741 742 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
742 743 if (animationOptions != m_chart->animationOptions())
743 744 m_chart->setAnimationOptions(animationOptions);
744 745 }
745 746
746 747 DeclarativeChart::Animation DeclarativeChart::animationOptions()
747 748 {
748 749 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
749 750 return DeclarativeChart::AllAnimations;
750 751 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
751 752 return DeclarativeChart::GridAxisAnimations;
752 753 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
753 754 return DeclarativeChart::SeriesAnimations;
754 755 else
755 756 return DeclarativeChart::NoAnimation;
756 757 }
757 758
758 759 void DeclarativeChart::setAnimationDuration(int msecs)
759 760 {
760 761 if (msecs != m_chart->animationDuration()) {
761 762 m_chart->setAnimationDuration(msecs);
762 763 emit animationDurationChanged(msecs);
763 764 }
764 765 }
765 766
766 767 int DeclarativeChart::animationDuration() const
767 768 {
768 769 return m_chart->animationDuration();
769 770 }
770 771
771 772 void DeclarativeChart::setAnimationEasingCurve(const QEasingCurve &curve)
772 773 {
773 774 if (curve != m_chart->animationEasingCurve()) {
774 775 m_chart->setAnimationEasingCurve(curve);
775 776 emit animationEasingCurveChanged(curve);
776 777 }
777 778 }
778 779
779 780 QEasingCurve DeclarativeChart::animationEasingCurve() const
780 781 {
781 782 return m_chart->animationEasingCurve();
782 783 }
783 784
784 785 void DeclarativeChart::setTitle(QString title)
785 786 {
786 787 if (title != m_chart->title())
787 788 m_chart->setTitle(title);
788 789 }
789 790 QString DeclarativeChart::title()
790 791 {
791 792 return m_chart->title();
792 793 }
793 794
794 795 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
795 796 {
796 797 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
797 798 if (axes.count())
798 799 return axes[0];
799 800 return 0;
800 801 }
801 802
802 803 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
803 804 {
804 805 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
805 806 if (axes.count())
806 807 return axes[0];
807 808 return 0;
808 809 }
809 810
810 811 QLegend *DeclarativeChart::legend()
811 812 {
812 813 return m_chart->legend();
813 814 }
814 815
815 816 void DeclarativeChart::setTitleColor(QColor color)
816 817 {
817 818 QBrush b = m_chart->titleBrush();
818 819 if (color != b.color()) {
819 820 b.setColor(color);
820 821 m_chart->setTitleBrush(b);
821 822 emit titleColorChanged(color);
822 823 }
823 824 }
824 825
825 826 QFont DeclarativeChart::titleFont() const
826 827 {
827 828 return m_chart->titleFont();
828 829 }
829 830
830 831 void DeclarativeChart::setTitleFont(const QFont &font)
831 832 {
832 833 m_chart->setTitleFont(font);
833 834 }
834 835
835 836 QColor DeclarativeChart::titleColor()
836 837 {
837 838 return m_chart->titleBrush().color();
838 839 }
839 840
840 841 void DeclarativeChart::setBackgroundColor(QColor color)
841 842 {
842 843 QBrush b = m_chart->backgroundBrush();
843 844 if (b.style() != Qt::SolidPattern || color != b.color()) {
844 845 if (color.alpha() < 0xff)
845 846 m_sceneImageNeedsClear = true;
846 847 b.setStyle(Qt::SolidPattern);
847 848 b.setColor(color);
848 849 m_chart->setBackgroundBrush(b);
849 850 emit backgroundColorChanged();
850 851 }
851 852 }
852 853
853 854 QColor DeclarativeChart::backgroundColor()
854 855 {
855 856 return m_chart->backgroundBrush().color();
856 857 }
857 858
858 859 void QtCharts::DeclarativeChart::setPlotAreaColor(QColor color)
859 860 {
860 861 QBrush b = m_chart->plotAreaBackgroundBrush();
861 862 if (b.style() != Qt::SolidPattern || color != b.color()) {
862 863 b.setStyle(Qt::SolidPattern);
863 864 b.setColor(color);
864 865 m_chart->setPlotAreaBackgroundBrush(b);
865 866 m_chart->setPlotAreaBackgroundVisible(true);
866 867 emit plotAreaColorChanged();
867 868 }
868 869 }
869 870
870 871 QColor QtCharts::DeclarativeChart::plotAreaColor()
871 872 {
872 873 return m_chart->plotAreaBackgroundBrush().color();
873 874 }
874 875
875 876 void DeclarativeChart::setLocalizeNumbers(bool localize)
876 877 {
877 878 if (m_chart->localizeNumbers() != localize) {
878 879 m_chart->setLocalizeNumbers(localize);
879 880 emit localizeNumbersChanged();
880 881 }
881 882 }
882 883
883 884 bool DeclarativeChart::localizeNumbers() const
884 885 {
885 886 return m_chart->localizeNumbers();
886 887 }
887 888
888 889 void QtCharts::DeclarativeChart::setLocale(const QLocale &locale)
889 890 {
890 891 if (m_chart->locale() != locale) {
891 892 m_chart->setLocale(locale);
892 893 emit localeChanged();
893 894 }
894 895 }
895 896
896 897 QLocale QtCharts::DeclarativeChart::locale() const
897 898 {
898 899 return m_chart->locale();
899 900 }
900 901
901 902 int DeclarativeChart::count()
902 903 {
903 904 return m_chart->series().count();
904 905 }
905 906
906 907 void DeclarativeChart::setDropShadowEnabled(bool enabled)
907 908 {
908 909 if (enabled != m_chart->isDropShadowEnabled()) {
909 910 m_sceneImageNeedsClear = true;
910 911 m_chart->setDropShadowEnabled(enabled);
911 912 dropShadowEnabledChanged(enabled);
912 913 }
913 914 }
914 915
915 916 bool DeclarativeChart::dropShadowEnabled()
916 917 {
917 918 return m_chart->isDropShadowEnabled();
918 919 }
919 920
920 921 qreal DeclarativeChart::backgroundRoundness() const
921 922 {
922 923 return m_chart->backgroundRoundness();
923 924 }
924 925
925 926 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
926 927 {
927 928 if (m_chart->backgroundRoundness() != diameter) {
928 929 m_sceneImageNeedsClear = true;
929 930 m_chart->setBackgroundRoundness(diameter);
930 931 emit backgroundRoundnessChanged(diameter);
931 932 }
932 933 }
933 934
934 935 void DeclarativeChart::zoom(qreal factor)
935 936 {
936 937 m_chart->zoom(factor);
937 938 }
938 939
939 940 void DeclarativeChart::zoomIn()
940 941 {
941 942 m_chart->zoomIn();
942 943 }
943 944
944 945 void DeclarativeChart::zoomIn(const QRectF &rectangle)
945 946 {
946 947 m_chart->zoomIn(rectangle);
947 948 }
948 949
949 950 void DeclarativeChart::zoomOut()
950 951 {
951 952 m_chart->zoomOut();
952 953 }
953 954
954 955 void DeclarativeChart::zoomReset()
955 956 {
956 957 m_chart->zoomReset();
957 958 }
958 959
959 960 bool DeclarativeChart::isZoomed()
960 961 {
961 962 return m_chart->isZoomed();
962 963 }
963 964
964 965 void DeclarativeChart::scrollLeft(qreal pixels)
965 966 {
966 967 m_chart->scroll(-pixels, 0);
967 968 }
968 969
969 970 void DeclarativeChart::scrollRight(qreal pixels)
970 971 {
971 972 m_chart->scroll(pixels, 0);
972 973 }
973 974
974 975 void DeclarativeChart::scrollUp(qreal pixels)
975 976 {
976 977 m_chart->scroll(0, pixels);
977 978 }
978 979
979 980 void DeclarativeChart::scrollDown(qreal pixels)
980 981 {
981 982 m_chart->scroll(0, -pixels);
982 983 }
983 984
984 985 QQmlListProperty<QAbstractAxis> DeclarativeChart::axes()
985 986 {
986 987 return QQmlListProperty<QAbstractAxis>(this, 0,
987 988 &DeclarativeChart::axesAppendFunc,
988 989 &DeclarativeChart::axesCountFunc,
989 990 &DeclarativeChart::axesAtFunc,
990 991 &DeclarativeChart::axesClearFunc);
991 992 }
992 993
993 994 void DeclarativeChart::axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element)
994 995 {
995 996 // Empty implementation
996 997 Q_UNUSED(list);
997 998 Q_UNUSED(element);
998 999 }
999 1000
1000 1001 int DeclarativeChart::axesCountFunc(QQmlListProperty<QAbstractAxis> *list)
1001 1002 {
1002 1003 if (qobject_cast<DeclarativeChart *>(list->object)) {
1003 1004 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1004 1005 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
1005 1006 }
1006 1007 return 0;
1007 1008 }
1008 1009
1009 1010 QAbstractAxis *DeclarativeChart::axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index)
1010 1011 {
1011 1012 if (qobject_cast<DeclarativeChart *>(list->object)) {
1012 1013 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1013 1014 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
1014 1015 return axes.at(index);
1015 1016 }
1016 1017 return 0;
1017 1018 }
1018 1019
1019 1020 void DeclarativeChart::axesClearFunc(QQmlListProperty<QAbstractAxis> *list)
1020 1021 {
1021 1022 // Empty implementation
1022 1023 Q_UNUSED(list);
1023 1024 }
1024 1025
1025 1026
1026 1027 QAbstractSeries *DeclarativeChart::series(int index)
1027 1028 {
1028 1029 if (index < m_chart->series().count()) {
1029 1030 return m_chart->series().at(index);
1030 1031 }
1031 1032 return 0;
1032 1033 }
1033 1034
1034 1035 QAbstractSeries *DeclarativeChart::series(QString seriesName)
1035 1036 {
1036 1037 foreach (QAbstractSeries *series, m_chart->series()) {
1037 1038 if (series->name() == seriesName)
1038 1039 return series;
1039 1040 }
1040 1041 return 0;
1041 1042 }
1042 1043
1043 1044 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
1044 1045 {
1045 1046 QAbstractSeries *series = 0;
1046 1047
1047 1048 switch (type) {
1048 1049 case DeclarativeChart::SeriesTypeLine:
1049 1050 series = new DeclarativeLineSeries();
1050 1051 break;
1051 1052 case DeclarativeChart::SeriesTypeArea: {
1052 1053 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
1053 1054 DeclarativeLineSeries *line = new DeclarativeLineSeries();
1054 1055 line->setParent(area);
1055 1056 area->setUpperSeries(line);
1056 1057 series = area;
1057 1058 break;
1058 1059 }
1059 1060 case DeclarativeChart::SeriesTypeStackedBar:
1060 1061 series = new DeclarativeStackedBarSeries();
1061 1062 break;
1062 1063 case DeclarativeChart::SeriesTypePercentBar:
1063 1064 series = new DeclarativePercentBarSeries();
1064 1065 break;
1065 1066 case DeclarativeChart::SeriesTypeBar:
1066 1067 series = new DeclarativeBarSeries();
1067 1068 break;
1068 1069 case DeclarativeChart::SeriesTypeHorizontalBar:
1069 1070 series = new DeclarativeHorizontalBarSeries();
1070 1071 break;
1071 1072 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
1072 1073 series = new DeclarativeHorizontalPercentBarSeries();
1073 1074 break;
1074 1075 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
1075 1076 series = new DeclarativeHorizontalStackedBarSeries();
1076 1077 break;
1077 1078 case DeclarativeChart::SeriesTypeBoxPlot:
1078 1079 series = new DeclarativeBoxPlotSeries();
1079 1080 break;
1081 case DeclarativeChart::SeriesTypeCandlestick:
1082 series = new DeclarativeCandlestickSeries();
1083 break;
1080 1084 case DeclarativeChart::SeriesTypePie:
1081 1085 series = new DeclarativePieSeries();
1082 1086 break;
1083 1087 case DeclarativeChart::SeriesTypeScatter:
1084 1088 series = new DeclarativeScatterSeries();
1085 1089 break;
1086 1090 case DeclarativeChart::SeriesTypeSpline:
1087 1091 series = new DeclarativeSplineSeries();
1088 1092 break;
1089 1093 default:
1090 1094 qWarning() << "Illegal series type";
1091 1095 }
1092 1096
1093 1097 if (series) {
1094 1098 // Connect to axis changed signals (unless this is a pie series)
1095 1099 if (!qobject_cast<DeclarativePieSeries *>(series)) {
1096 1100 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1097 1101 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1098 1102 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
1099 1103 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
1100 1104 }
1101 1105
1102 1106 series->setName(name);
1103 1107 m_chart->addSeries(series);
1104 1108
1105 1109 if (!axisX || !axisY)
1106 1110 initializeAxes(series);
1107 1111
1108 1112 if (axisX)
1109 1113 setAxisX(axisX, series);
1110 1114 if (axisY)
1111 1115 setAxisY(axisY, series);
1112 1116 }
1113 1117
1114 1118 return series;
1115 1119 }
1116 1120
1117 1121 void DeclarativeChart::removeSeries(QAbstractSeries *series)
1118 1122 {
1119 1123 if (series)
1120 1124 m_chart->removeSeries(series);
1121 1125 else
1122 1126 qWarning("removeSeries: cannot remove null");
1123 1127 }
1124 1128
1125 1129 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
1126 1130 {
1127 1131 if (axis && series)
1128 1132 seriesAxisAttachHelper(series, axis, Qt::Horizontal, Qt::AlignBottom);
1129 1133 }
1130 1134
1131 1135 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
1132 1136 {
1133 1137 if (axis && series)
1134 1138 seriesAxisAttachHelper(series, axis, Qt::Vertical, Qt::AlignLeft);
1135 1139 }
1136 1140
1137 1141 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
1138 1142 {
1139 1143 if (!series) {
1140 1144 qWarning() << "No axis type defined for null series";
1141 1145 return 0;
1142 1146 }
1143 1147
1144 1148 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
1145 1149 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
1146 1150 return existingAxis;
1147 1151 }
1148 1152
1149 1153 switch (series->d_ptr->defaultAxisType(orientation)) {
1150 1154 case QAbstractAxis::AxisTypeValue:
1151 1155 return new QValueAxis(this);
1152 1156 case QAbstractAxis::AxisTypeBarCategory:
1153 1157 return new QBarCategoryAxis(this);
1154 1158 case QAbstractAxis::AxisTypeCategory:
1155 1159 return new QCategoryAxis(this);
1156 1160 #ifndef QT_QREAL_IS_FLOAT
1157 1161 case QAbstractAxis::AxisTypeDateTime:
1158 1162 return new QDateTimeAxis(this);
1159 1163 #endif
1160 1164 case QAbstractAxis::AxisTypeLogValue:
1161 1165 return new QLogValueAxis(this);
1162 1166 default:
1163 1167 // assume AxisTypeNoAxis
1164 1168 return 0;
1165 1169 }
1166 1170 }
1167 1171
1168 1172 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1169 1173 {
1170 1174 if (qobject_cast<DeclarativeLineSeries *>(series))
1171 1175 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1172 1176 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1173 1177 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1174 1178 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1175 1179 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1176 1180 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1177 1181 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1178 1182 else if (qobject_cast<DeclarativeBarSeries *>(series))
1179 1183 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1180 1184 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1181 1185 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1182 1186 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1183 1187 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1184 1188 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1185 1189 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1186 1190 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1187 1191 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1188 1192 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1189 1193 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1190 1194 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1191 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 1198 // else: do nothing
1193 1199 }
1194 1200
1195 1201 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1196 1202 {
1197 1203 qreal min;
1198 1204 qreal max;
1199 1205 // Initialize axis X
1200 1206 if (axes->axisX()) {
1201 1207 axes->emitAxisXChanged();
1202 1208 } else if (axes->axisXTop()) {
1203 1209 axes->emitAxisXTopChanged();
1204 1210 } else {
1205 1211 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1206 1212 findMinMaxForSeries(series, Qt::Horizontal, min, max);
1207 1213 axes->axisX()->setRange(min, max);
1208 1214 }
1209 1215
1210 1216 // Initialize axis Y
1211 1217 if (axes->axisY()) {
1212 1218 axes->emitAxisYChanged();
1213 1219 } else if (axes->axisYRight()) {
1214 1220 axes->emitAxisYRightChanged();
1215 1221 } else {
1216 1222 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1217 1223 findMinMaxForSeries(series, Qt::Vertical, min, max);
1218 1224 axes->axisY()->setRange(min, max);
1219 1225 }
1220 1226 }
1221 1227
1222 1228 void DeclarativeChart::findMinMaxForSeries(QAbstractSeries *series, Qt::Orientations orientation,
1223 1229 qreal &min, qreal &max)
1224 1230 {
1225 1231 if (!series) {
1226 1232 min = 0.5;
1227 1233 max = 0.5;
1228 1234 } else {
1229 1235 AbstractDomain *domain = series->d_ptr->domain();
1230 1236 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
1231 1237 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
1232 1238
1233 1239 if (min == max) {
1234 1240 min -= 0.5;
1235 1241 max += 0.5;
1236 1242 }
1237 1243 }
1238 1244 }
1239 1245
1240 1246 QPointF DeclarativeChart::mapToValue(const QPointF &position, QAbstractSeries *series)
1241 1247 {
1242 1248 return m_chart->mapToValue(position, series);
1243 1249 }
1244 1250
1245 1251 QPointF DeclarativeChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
1246 1252 {
1247 1253 return m_chart->mapToPosition(value, series);
1248 1254 }
1249 1255
1250 1256 #include "moc_declarativechart.cpp"
1251 1257
1252 1258 QT_CHARTS_END_NAMESPACE
@@ -1,254 +1,255
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef DECLARATIVECHART_H
31 31 #define DECLARATIVECHART_H
32 32
33 33 #include <private/glxyseriesdata_p.h>
34 34
35 35 #include <QtCore/QtGlobal>
36 36 #include <QtQuick/QQuickItem>
37 37 #include <QtWidgets/QGraphicsScene>
38 38
39 39 #include <QtCharts/QChart>
40 40 #include <QtCore/QLocale>
41 41
42 42 QT_CHARTS_BEGIN_NAMESPACE
43 43
44 44 class DeclarativeMargins;
45 45 class Domain;
46 46 class DeclarativeAxes;
47 47
48 48 class DeclarativeChart : public QQuickItem
49 49 {
50 50 Q_OBJECT
51 51 Q_PROPERTY(Theme theme READ theme WRITE setTheme)
52 52 Q_PROPERTY(Animation animationOptions READ animationOptions WRITE setAnimationOptions)
53 53 Q_PROPERTY(int animationDuration READ animationDuration WRITE setAnimationDuration NOTIFY animationDurationChanged REVISION 5)
54 54 Q_PROPERTY(QEasingCurve animationEasingCurve READ animationEasingCurve WRITE setAnimationEasingCurve NOTIFY animationEasingCurveChanged REVISION 5)
55 55 Q_PROPERTY(QString title READ title WRITE setTitle)
56 56 Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont)
57 57 Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor NOTIFY titleColorChanged)
58 58 Q_PROPERTY(QLegend *legend READ legend CONSTANT)
59 59 Q_PROPERTY(int count READ count)
60 60 Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
61 61 Q_PROPERTY(bool dropShadowEnabled READ dropShadowEnabled WRITE setDropShadowEnabled NOTIFY dropShadowEnabledChanged)
62 62 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness NOTIFY backgroundRoundnessChanged REVISION 3)
63 63 Q_PROPERTY(DeclarativeMargins *margins READ margins NOTIFY marginsChanged REVISION 2)
64 64 Q_PROPERTY(QRectF plotArea READ plotArea NOTIFY plotAreaChanged REVISION 1)
65 65 Q_PROPERTY(QColor plotAreaColor READ plotAreaColor WRITE setPlotAreaColor NOTIFY plotAreaColorChanged REVISION 3)
66 66 Q_PROPERTY(QQmlListProperty<QAbstractAxis> axes READ axes REVISION 2)
67 67 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers NOTIFY localizeNumbersChanged REVISION 4)
68 68 Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged REVISION 4)
69 69 Q_ENUMS(Animation)
70 70 Q_ENUMS(Theme)
71 71 Q_ENUMS(SeriesType)
72 72
73 73 public:
74 74 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
75 75 enum Theme {
76 76 ChartThemeLight = 0,
77 77 ChartThemeBlueCerulean,
78 78 ChartThemeDark,
79 79 ChartThemeBrownSand,
80 80 ChartThemeBlueNcs,
81 81 ChartThemeHighContrast,
82 82 ChartThemeBlueIcy,
83 83 ChartThemeQt
84 84 };
85 85
86 86 enum Animation {
87 87 NoAnimation = 0x0,
88 88 GridAxisAnimations = 0x1,
89 89 SeriesAnimations = 0x2,
90 90 AllAnimations = 0x3
91 91 };
92 92
93 93 enum SeriesType {
94 94 SeriesTypeLine,
95 95 SeriesTypeArea,
96 96 SeriesTypeBar,
97 97 SeriesTypeStackedBar,
98 98 SeriesTypePercentBar,
99 99 SeriesTypeBoxPlot,
100 SeriesTypeCandlestick,
100 101 SeriesTypePie,
101 102 SeriesTypeScatter,
102 103 SeriesTypeSpline,
103 104 SeriesTypeHorizontalBar,
104 105 SeriesTypeHorizontalStackedBar,
105 106 SeriesTypeHorizontalPercentBar
106 107 };
107 108
108 109 public:
109 110 DeclarativeChart(QQuickItem *parent = 0);
110 111 ~DeclarativeChart();
111 112
112 113 public: // From parent classes
113 114 void childEvent(QChildEvent *event);
114 115 void componentComplete();
115 116 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
116 117 QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
117 118 protected:
118 119 void mousePressEvent(QMouseEvent *event);
119 120 void mouseReleaseEvent(QMouseEvent *event);
120 121 void hoverMoveEvent(QHoverEvent *event);
121 122 void mouseDoubleClickEvent(QMouseEvent *event);
122 123 private Q_SLOTS:
123 124 void handleAntialiasingChanged(bool enable);
124 125 void sceneChanged(QList<QRectF> region);
125 126 void renderScene();
126 127
127 128 public:
128 129 void setTheme(DeclarativeChart::Theme theme);
129 130 DeclarativeChart::Theme theme();
130 131 void setAnimationOptions(DeclarativeChart::Animation animations);
131 132 DeclarativeChart::Animation animationOptions();
132 133 void setAnimationDuration(int msecs);
133 134 int animationDuration() const;
134 135 void setAnimationEasingCurve(const QEasingCurve &curve);
135 136 QEasingCurve animationEasingCurve() const;
136 137 void setTitle(QString title);
137 138 QString title();
138 139 QLegend *legend();
139 140 QFont titleFont() const;
140 141 void setTitleFont(const QFont &font);
141 142 void setTitleColor(QColor color);
142 143 QColor titleColor();
143 144 void setBackgroundColor(QColor color);
144 145 QColor backgroundColor();
145 146 void setPlotAreaColor(QColor color);
146 147 QColor plotAreaColor();
147 148 void setLocalizeNumbers(bool localize);
148 149 bool localizeNumbers() const;
149 150 void setLocale(const QLocale &locale);
150 151 QLocale locale() const;
151 152
152 153 int count();
153 154 void setDropShadowEnabled(bool enabled);
154 155 bool dropShadowEnabled();
155 156 qreal backgroundRoundness() const;
156 157 void setBackgroundRoundness(qreal diameter);
157 158
158 159 // Margins & plotArea
159 160 DeclarativeMargins *margins() { return m_margins; }
160 161 QRectF plotArea() { return m_chart->plotArea(); }
161 162
162 163 // Axis handling
163 164 QAbstractAxis *defaultAxis(Qt::Orientation orientation, QAbstractSeries *series);
164 165 void initializeAxes(QAbstractSeries *series);
165 166 void doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes);
166 167 QQmlListProperty<QAbstractAxis> axes();
167 168 static void axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element);
168 169 static int axesCountFunc(QQmlListProperty<QAbstractAxis> *list);
169 170 static QAbstractAxis *axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index);
170 171 static void axesClearFunc(QQmlListProperty<QAbstractAxis> *list);
171 172
172 173 public:
173 174 Q_INVOKABLE QAbstractSeries *series(int index);
174 175 Q_INVOKABLE QAbstractSeries *series(QString seriesName);
175 176 Q_INVOKABLE QAbstractSeries *createSeries(int type, QString name = "", QAbstractAxis *axisX = 0, QAbstractAxis *axisY = 0);
176 177 Q_INVOKABLE void removeSeries(QAbstractSeries *series);
177 178 Q_INVOKABLE void removeAllSeries() { m_chart->removeAllSeries(); }
178 179 Q_INVOKABLE void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
179 180 Q_INVOKABLE void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
180 181 Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0);
181 182 Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0);
182 183 Q_INVOKABLE void zoom(qreal factor);
183 184 Q_REVISION(5) Q_INVOKABLE void zoomIn();
184 185 Q_REVISION(5) Q_INVOKABLE void zoomIn(const QRectF &rectangle);
185 186 Q_REVISION(5) Q_INVOKABLE void zoomOut();
186 187 Q_REVISION(5) Q_INVOKABLE void zoomReset();
187 188 Q_REVISION(5) Q_INVOKABLE bool isZoomed();
188 189 Q_INVOKABLE void scrollLeft(qreal pixels);
189 190 Q_INVOKABLE void scrollRight(qreal pixels);
190 191 Q_INVOKABLE void scrollUp(qreal pixels);
191 192 Q_INVOKABLE void scrollDown(qreal pixels);
192 193 Q_REVISION(5) Q_INVOKABLE QPointF mapToValue(const QPointF &position,
193 194 QAbstractSeries *series = 0);
194 195 Q_REVISION(5) Q_INVOKABLE QPointF mapToPosition(const QPointF &value,
195 196 QAbstractSeries *series = 0);
196 197
197 198
198 199 Q_SIGNALS:
199 200 void axisLabelsChanged();
200 201 void titleColorChanged(QColor color);
201 202 void backgroundColorChanged();
202 203 void dropShadowEnabledChanged(bool enabled);
203 204 Q_REVISION(2) void marginsChanged();
204 205 void plotAreaChanged(QRectF plotArea);
205 206 void seriesAdded(QAbstractSeries *series);
206 207 void seriesRemoved(QAbstractSeries *series);
207 208 Q_REVISION(3) void plotAreaColorChanged();
208 209 Q_REVISION(3) void backgroundRoundnessChanged(qreal diameter);
209 210 Q_REVISION(4) void localizeNumbersChanged();
210 211 Q_REVISION(4) void localeChanged();
211 212 Q_REVISION(5) void animationDurationChanged(int msecs);
212 213 Q_REVISION(5) void animationEasingCurveChanged(QEasingCurve curve);
213 214 void needRender();
214 215
215 216 private Q_SLOTS:
216 217 void changeMargins(int top, int bottom, int left, int right);
217 218 void handleAxisXSet(QAbstractAxis *axis);
218 219 void handleAxisYSet(QAbstractAxis *axis);
219 220 void handleAxisXTopSet(QAbstractAxis *axis);
220 221 void handleAxisYRightSet(QAbstractAxis *axis);
221 222 void handleSeriesAdded(QAbstractSeries *series);
222 223
223 224 protected:
224 225 explicit DeclarativeChart(QChart::ChartType type, QQuickItem *parent);
225 226
226 227 private:
227 228 void initChart(QChart::ChartType type);
228 229 void seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
229 230 Qt::Orientations orientation, Qt::Alignment alignment);
230 231 void findMinMaxForSeries(QAbstractSeries *series,Qt::Orientations orientation,
231 232 qreal &min, qreal &max);
232 233 // Extending QChart with DeclarativeChart is not possible because QObject does not support
233 234 // multi inheritance, so we now have a QChart as a member instead
234 235 QChart *m_chart;
235 236 QGraphicsScene *m_scene;
236 237 QPointF m_mousePressScenePoint;
237 238 QPoint m_mousePressScreenPoint;
238 239 QPointF m_lastMouseMoveScenePoint;
239 240 QPoint m_lastMouseMoveScreenPoint;
240 241 Qt::MouseButton m_mousePressButton;
241 242 Qt::MouseButtons m_mousePressButtons;
242 243 QImage *m_sceneImage;
243 244 bool m_sceneImageDirty;
244 245 bool m_updatePending;
245 246 Qt::HANDLE m_paintThreadId;
246 247 Qt::HANDLE m_guiThreadId;
247 248 DeclarativeMargins *m_margins;
248 249 GLXYSeriesDataManager *m_glXYDataManager;
249 250 bool m_sceneImageNeedsClear;
250 251 };
251 252
252 253 QT_CHARTS_END_NAMESPACE
253 254
254 255 #endif // DECLARATIVECHART_H
@@ -1,41 +1,44
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += \
3 3 qchartview \
4 4 qchart \
5 5 qlineseries \
6 6 qbarset \
7 7 qbarseries \
8 8 qstackedbarseries \
9 9 qpercentbarseries \
10 10 qpieslice qpieseries \
11 11 qpiemodelmapper \
12 12 qsplineseries \
13 13 qscatterseries \
14 14 qxymodelmapper \
15 15 qbarmodelmapper \
16 16 qhorizontalbarseries \
17 17 qhorizontalstackedbarseries \
18 18 qhorizontalpercentbarseries \
19 19 qvalueaxis \
20 20 qlogvalueaxis \
21 21 qcategoryaxis \
22 22 qbarcategoryaxis \
23 23 domain \
24 24 chartdataset \
25 25 qlegend \
26 cmake
26 cmake \
27 qcandlestickmodelmapper \
28 qcandlestickseries \
29 qcandlestickset
27 30
28 31 !contains(QT_COORD_TYPE, float): {
29 32 SUBDIRS += \
30 33 qdatetimeaxis
31 34 }
32 35
33 36 qtHaveModule(quick) {
34 37 SUBDIRS += qml \
35 38 qml-qtquicktest
36 39 }
37 40
38 41 !contains(QT_CONFIG, private_tests): SUBDIRS -= \
39 42 domain \
40 43 chartdataset
41 44
@@ -1,19 +1,20
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += \
3 3 presenterchart \
4 4 polarcharttest \
5 boxplottester
5 boxplottester \
6 candlesticktester
6 7
7 8 contains(QT_CONFIG, opengl) {
8 9 SUBDIRS += chartwidgettest \
9 10 wavechart \
10 11 chartviewer \
11 12 openglseriestest
12 13 } else {
13 14 message("OpenGL not available. Some test apps are disabled")
14 15 }
15 16
16 17 qtHaveModule(quick) {
17 18 SUBDIRS += qmlchartproperties \
18 19 qmlchartaxis
19 20 }
General Comments 0
You need to be logged in to leave comments. Login now