##// END OF EJS Templates
minor. Release polishing
Michal Klocek -
r1049:4e3b4d910737
parent child
Show More
@@ -1,67 +1,60
1 --------------------------------
1 --------------------------------
2 Commercial Charts Add-on Preview
2 Commercial Charts Add-on Preview
3 --------------------------------
3 --------------------------------
4
4
5
6 Whats in Qt Commercial Charts
5 Whats in Qt Commercial Charts
7 =============================
6 =============================
8
7
9 Directory structure:
8 Directory structure:
10
9
11 src/
10 src/
12 Source code of the Qt Commercial Charts
11 Source code of the Qt Commercial Charts
13 qmlplugin/
12 qmlplugin/
14 QML bindings for the charts
13 QML bindings for the charts
15 examples/
14 examples/
16 Some examples of using Qt Commercial Charts
15 Some examples of using Qt Commercial Charts
17 demos/
16 demos/
18 More versatile example applications showing how to customize charts,
17 More versatile example applications showing how to customize charts,
19 combine several chart types and implement interaction in charts
18 combine several chart types and implement interaction in charts
20 doc/
19 doc/
21 Documentation
20 Documentation
22 Licensing/
21 licenses/
23 Licensing infromation
22 Licensing infromation
24
23
25
24 Building
26 Building
27 ========
25 ========
28
26
29 qmake
27 Configure project with qmake:
30 make (linux), mingw32-make (Windows with MinGw) or nmake (Visual Studio)
28 qmake CONFIG+=release
29
30 Build poject with make:
31 (Linux) make
32 (Windows with MinGw) mingw32-make
33 (Visual Studio) namke
31
34
32 If you want to install the libraries to your Qt library directory use:
35 If you want to install the libraries to your Qt library directory use:
33 make install
36 make install
34
37
38 If you want to uninstall the libraries
39 make uninstall
35
40
36 Documentation
41 Documentation
37 =============
42 =============
38
43
39 The documentation can be generated with "make docs". It will be placed
44 The documentation can be generated with "make docs". It will be placed
40 into "doc/html" in the build directory.
45 into "doc/html" in the build directory.
41
46
42 KNOWN ISSUES
47 KNOWN ISSUES
43 ============
48 ============
44 - General
49 * The preview version of Qt Commercial Charts is still under development
45 * The preview version of Qt Commercial Charts is still under development
46 and thus should not be used in e.g. product development
50 and thus should not be used in e.g. product development
47 * The Charts API might change between the Preview and first official release
51 * The Charts API might change between the Preview and first official release
48 * Some areas will be refactored before the first official release
52 * Some areas will be refactored before the first official release
49 * Qt Designer plugin is missing
53 * Qt Designer plugin is missing
50 * Enable/disable tooltip is missing from the API
54 * Enable/disable tooltip is missing from the API
51
55 * Mutliple axis are not suported at the moment.
52 - QML API
56 * Logartmic, polar axis are not supported at the moment.
53 * The QML Bindings are still under development and to be considered as early preview
57 * Getting data from QAbstractItemModel is not feature complete.
54 * All the current QML APIs are shown in qmlchart demo app
58 * Interlnal layout hadnling is not working properly.
55 * If doing a developer build (not installing into your Qt instance) you
59 * The QML Bindings are still under development and to be considered as early draft
56 need to copy qmldir file to the qmlplugin installation folder; it is not
60 * All the current QML APIs are shown in qmlchart demo app No newline at end of file
57 copied during build.
58
59 - Model based
60
61 - Bar Chart
62 * Modifying bar categories is not possible
63
64 - Pie Chart
65 * Slice labels drawn on top of the label arm
66
67 - Line Chart
1 NO CONTENT: file renamed from Licenses/LICENSE-ALLOS to licenses/LICENSE-ALLOS
NO CONTENT: file renamed from Licenses/LICENSE-ALLOS to licenses/LICENSE-ALLOS
1 NO CONTENT: file renamed from Licenses/LICENSE-ALLOS-US to licenses/LICENSE-ALLOS-US
NO CONTENT: file renamed from Licenses/LICENSE-ALLOS-US to licenses/LICENSE-ALLOS-US
1 NO CONTENT: file renamed from Licenses/LICENSE-DESKTOP to licenses/LICENSE-DESKTOP
NO CONTENT: file renamed from Licenses/LICENSE-DESKTOP to licenses/LICENSE-DESKTOP
1 NO CONTENT: file renamed from Licenses/LICENSE-DESKTOP-US to licenses/LICENSE-DESKTOP-US
NO CONTENT: file renamed from Licenses/LICENSE-DESKTOP-US to licenses/LICENSE-DESKTOP-US
1 NO CONTENT: file renamed from Licenses/LICENSE-EVALUATION to licenses/LICENSE-EVALUATION
NO CONTENT: file renamed from Licenses/LICENSE-EVALUATION to licenses/LICENSE-EVALUATION
1 NO CONTENT: file renamed from Licenses/LICENSE-EVALUATION-US to licenses/LICENSE-EVALUATION-US
NO CONTENT: file renamed from Licenses/LICENSE-EVALUATION-US to licenses/LICENSE-EVALUATION-US
1 NO CONTENT: file renamed from Licenses/LICENSE.COMMERCIAL.FI to licenses/LICENSE.COMMERCIAL.FI
NO CONTENT: file renamed from Licenses/LICENSE.COMMERCIAL.FI to licenses/LICENSE.COMMERCIAL.FI
1 NO CONTENT: file renamed from Licenses/LICENSE.COMMERCIAL.US to licenses/LICENSE.COMMERCIAL.US
NO CONTENT: file renamed from Licenses/LICENSE.COMMERCIAL.US to licenses/LICENSE.COMMERCIAL.US
@@ -1,251 +1,251
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scroller_p.h"
21 #include "scroller_p.h"
22 #include "qlegend.h"
22 #include "qlegend.h"
23 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsSceneMouseEvent>
24 #include <QDebug>
24 #include <QDebug>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 Scroller::Scroller():
28 Scroller::Scroller():
29 m_ticker(this),
29 m_ticker(this),
30 m_state(Idle),
30 m_state(Idle),
31 m_moveThreshold(10),
31 m_moveThreshold(10),
32 m_timeTreshold(50)
32 m_timeTreshold(50)
33 {
33 {
34
34
35 }
35 }
36
36
37 Scroller::~Scroller()
37 Scroller::~Scroller()
38 {
38 {
39 }
39 }
40
40
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
42 {
42 {
43 if (event->button() == Qt::LeftButton) {
43 if (event->button() == Qt::LeftButton) {
44
44
45 switch (m_state) {
45 switch (m_state) {
46 case Idle:
46 case Idle:
47 {
47 {
48 m_state = Pressed;
48 m_state = Pressed;
49 m_offset = offset();
49 m_offset = offset();
50 m_press = event->pos();
50 m_press = event->pos();
51 m_timeStamp = QTime::currentTime();
51 m_timeStamp = QTime::currentTime();
52 event->accept();
52 event->accept();
53 break;
53 break;
54 }
54 }
55 case Scroll:
55 case Scroll:
56 {
56 {
57 m_state = Stop;
57 m_state = Stop;
58 m_speed = QPoint(0, 0);
58 m_speed = QPoint(0, 0);
59 m_offset = offset();
59 m_offset = offset();
60 m_press = event->pos();
60 m_press = event->pos();
61 event->accept();
61 event->accept();
62 break;
62 break;
63 }
63 }
64 case Pressed:
64 case Pressed:
65 case Move:
65 case Move:
66 case Stop:
66 case Stop:
67 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
67 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
68 event->ignore();
68 event->ignore();
69 break;
69 break;
70 }
70 }
71 }
71 }
72 }
72 }
73
73
74 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
74 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
75 {
75 {
76 QPointF delta = event->pos() - m_press;
76 QPointF delta = event->pos() - m_press;
77
77
78 switch (m_state) {
78 switch (m_state) {
79 case Pressed:
79 case Pressed:
80 case Stop:
80 case Stop:
81 {
81 {
82 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
82 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
83 m_state = Move;
83 m_state = Move;
84 m_timeStamp = QTime::currentTime();
84 m_timeStamp = QTime::currentTime();
85 m_distance = QPointF(0, 0);
85 m_distance = QPointF(0, 0);
86 m_press = event->pos();
86 m_press = event->pos();
87 event->accept();
87 event->accept();
88 break;
88 break;
89 }
89 }
90 else {
90 else {
91 event->ignore();
91 event->ignore();
92 break;
92 break;
93 }
93 }
94 }
94 }
95 case Move:
95 case Move:
96 {
96 {
97 setOffset(m_offset - delta);
97 setOffset(m_offset - delta);
98 calculateSpeed(event->pos());
98 calculateSpeed(event->pos());
99 event->accept();
99 event->accept();
100 break;
100 break;
101 }
101 }
102 case Idle:
102 case Idle:
103 case Scroll:
103 case Scroll:
104 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
104 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
105 event->ignore();
105 event->ignore();
106 break;
106 break;
107 }
107 }
108
108
109 }
109 }
110
110
111 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
111 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
112 {
112 {
113 if (event->button() == Qt::LeftButton) {
113 if (event->button() == Qt::LeftButton) {
114
114
115 switch (m_state) {
115 switch (m_state) {
116
116
117 case Scroll:
117 case Scroll:
118 m_state = Stop;
118 m_state = Stop;
119 m_speed = QPointF(0, 0);
119 m_speed = QPointF(0, 0);
120 m_offset = offset();
120 m_offset = offset();
121 event->accept();
121 event->accept();
122 break;
122 break;
123 case Pressed:
123 case Pressed:
124 {
124 {
125 m_state = Idle;
125 m_state = Idle;
126 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
126 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
127
127
128 //emit clicked(m_offset.toPoint());
128 //emit clicked(m_offset.toPoint());
129 //}
129 //}
130 event->accept();
130 event->accept();
131 break;
131 break;
132 }
132 }
133 case Move:
133 case Move:
134 {
134 {
135 calculateSpeed(event->pos());
135 calculateSpeed(event->pos());
136 m_offset = offset();
136 m_offset = offset();
137 m_press = event->pos();
137 m_press = event->pos();
138 if (m_speed == QPointF(0, 0)) {
138 if (m_speed == QPointF(0, 0)) {
139 m_state = Idle;
139 m_state = Idle;
140 }
140 }
141 else {
141 else {
142 m_speed /= 4;
142 m_speed /= 3.75;
143 m_state = Scroll;
143 m_state = Scroll;
144 m_ticker.start(20);
144 m_ticker.start(25);
145 }
145 }
146 event->accept();
146 event->accept();
147 break;
147 break;
148 }
148 }
149
149
150 case Stop:
150 case Stop:
151 case Idle:
151 case Idle:
152 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
152 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
153 event->ignore();
153 event->ignore();
154 break;
154 break;
155
155
156 }
156 }
157 }
157 }
158 }
158 }
159
159
160 void Scroller::scrollTick()
160 void Scroller::scrollTick()
161 {
161 {
162 switch (m_state) {
162 switch (m_state) {
163 case Scroll:
163 case Scroll:
164 {
164 {
165 lowerSpeed(m_speed);
165 lowerSpeed(m_speed);
166 setOffset(m_offset - m_speed);
166 setOffset(m_offset - m_speed);
167 m_offset = offset();
167 m_offset = offset();
168 if (m_speed == QPointF(0, 0)) {
168 if (m_speed == QPointF(0, 0)) {
169 m_state = Idle;
169 m_state = Idle;
170 m_ticker.stop();
170 m_ticker.stop();
171 }
171 }
172 break;
172 break;
173 }
173 }
174 case Stop:
174 case Stop:
175 m_ticker.stop();
175 m_ticker.stop();
176 break;
176 break;
177 case Idle:
177 case Idle:
178 case Move:
178 case Move:
179 case Pressed:
179 case Pressed:
180 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
180 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
181 m_ticker.stop();
181 m_ticker.stop();
182 break;
182 break;
183
183
184 }
184 }
185 }
185 }
186
186
187 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
187 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
188 {
188 {
189 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
189 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
190 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
190 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
191
191
192 x = (x == 0) ? x :
192 x = (x == 0) ? x :
193 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
193 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
194 y = (y == 0) ? y :
194 y = (y == 0) ? y :
195 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
195 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
196 speed.setX(x);
196 speed.setX(x);
197 speed.setY(y);
197 speed.setY(y);
198 }
198 }
199
199
200 void Scroller::calculateSpeed(const QPointF& position)
200 void Scroller::calculateSpeed(const QPointF& position)
201 {
201 {
202 if (m_timeStamp.elapsed() > m_timeTreshold) {
202 if (m_timeStamp.elapsed() > m_timeTreshold) {
203
203
204 QPointF distance = position - m_press;
204 QPointF distance = position - m_press;
205
205
206 m_timeStamp = QTime::currentTime();
206 m_timeStamp = QTime::currentTime();
207 m_speed = distance - m_distance;
207 m_speed = distance - m_distance;
208 m_distance = distance;
208 m_distance = distance;
209
209
210 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
210 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
211
211
212 if (fraction != 0) {
212 if (fraction != 0) {
213 m_fraction.setX(qAbs(m_speed.x() / fraction));
213 m_fraction.setX(qAbs(m_speed.x() / fraction));
214 m_fraction.setY(qAbs(m_speed.y() / fraction));
214 m_fraction.setY(qAbs(m_speed.y() / fraction));
215 }
215 }
216 else {
216 else {
217 m_fraction.setX(1);
217 m_fraction.setX(1);
218 m_fraction.setY(1);
218 m_fraction.setY(1);
219 }
219 }
220 }
220 }
221 }
221 }
222
222
223 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224
224
225 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
225 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
226 m_scroller(scroller)
226 m_scroller(scroller)
227 {
227 {
228
228
229 }
229 }
230
230
231 void ScrollTicker::start(int interval)
231 void ScrollTicker::start(int interval)
232 {
232 {
233 if (!m_timer.isActive()){
233 if (!m_timer.isActive()){
234 m_timer.start(interval, this);
234 m_timer.start(interval, this);
235 }
235 }
236 }
236 }
237
237
238 void ScrollTicker::stop()
238 void ScrollTicker::stop()
239 {
239 {
240 m_timer.stop();
240 m_timer.stop();
241 }
241 }
242
242
243 void ScrollTicker::timerEvent(QTimerEvent *event)
243 void ScrollTicker::timerEvent(QTimerEvent *event)
244 {
244 {
245 Q_UNUSED(event);
245 Q_UNUSED(event);
246 m_scroller->scrollTick();
246 m_scroller->scrollTick();
247 }
247 }
248
248
249 #include "moc_scroller_p.cpp"
249 #include "moc_scroller_p.cpp"
250
250
251 QTCOMMERCIALCHART_END_NAMESPACE
251 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,220 +1,210
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qsplineseries.h"
21 #include "qsplineseries.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "splinechartitem_p.h"
23 #include "splinechartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27
28 /*!
28 /*!
29 \class QSplineSeries
29 \class QSplineSeries
30 \brief Series type used to store data needed to draw a spline.
30 \brief Series type used to store data needed to draw a spline.
31
31
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34
34
35 \image examples_splinechart.png
35 \image examples_splinechart.png
36
36
37 Creating basic spline chart is simple:
37 Creating basic spline chart is simple:
38 \code
38 \code
39 QSplineSeries* series = new QSplineSeries();
39 QSplineSeries* series = new QSplineSeries();
40 series->append(0, 6);
40 series->append(0, 6);
41 series->append(2, 4);
41 series->append(2, 4);
42 ...
42 ...
43 chart->addSeries(series);
43 chart->addSeries(series);
44 \endcode
44 \endcode
45 */
45 */
46
46
47 /*!
47 /*!
48 \fn QSeriesType QSplineSeries::type() const
48 \fn QSeriesType QSplineSeries::type() const
49 Returns the type of the series
49 Returns the type of the series
50 */
50 */
51
51
52 /*!
52 /*!
53 \fn QSeriesType QSplineSeries::controlPoint(int index) const
53 \fn QSeriesType QSplineSeries::controlPoint(int index) const
54 Returns the control point specified by \a index
54 Returns the control point specified by \a index
55 */
55 */
56
56
57 QTCOMMERCIALCHART_BEGIN_NAMESPACE
57 QTCOMMERCIALCHART_BEGIN_NAMESPACE
58
58
59 /*!
59 /*!
60 Constructs empty series object which is a child of \a parent.
60 Constructs empty series object which is a child of \a parent.
61 When series object is added to QChartView or QChart instance then the ownerships is transferred.
61 When series object is added to QChartView or QChart instance then the ownerships is transferred.
62 */
62 */
63
63
64 QSplineSeries::QSplineSeries(QObject *parent) :
64 QSplineSeries::QSplineSeries(QObject *parent) :
65 QLineSeries(*new QSplineSeriesPrivate(this),parent)
65 QLineSeries(*new QSplineSeriesPrivate(this),parent)
66 {
66 {
67 }
67 }
68
68
69 QAbstractSeries::QSeriesType QSplineSeries::type() const
69 QAbstractSeries::QSeriesType QSplineSeries::type() const
70 {
70 {
71 return QAbstractSeries::SeriesTypeSpline;
71 return QAbstractSeries::SeriesTypeSpline;
72 }
72 }
73
73
74 QPointF QSplineSeries::controlPoint(int index) const
74 QPointF QSplineSeries::controlPoint(int index) const
75 {
75 {
76 Q_D(const QSplineSeries);
76 Q_D(const QSplineSeries);
77 return d->m_controlPoints[index];
77 return d->m_controlPoints[index];
78 }
78 }
79
79
80 /*!
80 /*!
81 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
81 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
82 as a data source for y coordinate. The \a orientation parameter specifies whether the data
82 as a data source for y coordinate. The \a orientation parameter specifies whether the data
83 is in columns or in rows.
83 is in columns or in rows.
84 \sa setModel()
84 \sa setModel()
85 */
85 */
86 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
86 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
87 {
87 {
88 Q_D(QSplineSeries);
88 Q_D(QSplineSeries);
89 QXYSeries::setModelMapping(modelX, modelY, orientation);
89 QXYSeries::setModelMapping(modelX, modelY, orientation);
90 d->calculateControlPoints();
90 d->calculateControlPoints();
91 }
91 }
92
92
93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
94
94
95 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
95 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
96 {
96 {
97 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
97 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
98 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
98 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
100 };
100 };
101
101
102 /*!
102 /*!
103 \internal
104 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
103 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
105 */
104 */
106 void QSplineSeriesPrivate::calculateControlPoints()
105 void QSplineSeriesPrivate::calculateControlPoints()
107 {
106 {
108
107
109 Q_Q(QSplineSeries);
108 Q_Q(QSplineSeries);
110 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
111 // CPOL License
112
109
113 int n = q->count() - 1;
110 int n = q->count() - 1;
111
114 if (n == 1)
112 if (n == 1)
115 { // Special case: Bezier curve should be a straight line.
113 {
116 // firstControlPoints = new Point[1];
114 //for n==1
117 // 3P1 = 2P0 + P3
118 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
115 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
119
120 // P2 = 2P1 P0
121 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
116 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
122 return;
117 return;
123 }
118 }
124
119
125 // Calculate first Bezier control points
120 // Calculate first Bezier control points
126 // Right hand side vector
121 // Right hand side vector
127 // Set of equations for P0 to Pn points.
122 // Set of equations for P0 to Pn points.
128 //
123 //
129 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
124 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
130 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
125 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
131 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
126 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
132 // | . . . . . . . . . . . . | | ... | | ... |
127 // | . . . . . . . . . . . . | | ... | | ... |
133 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
128 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
134 // | . . . . . . . . . . . . | | ... | | ... |
129 // | . . . . . . . . . . . . | | ... | | ... |
135 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
130 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
136 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
131 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
137 //
132 //
138 QList<qreal> rhs;
133 QList<qreal> points;
139 rhs.append(q->x(0) + 2 * q->x(1));
140
134
141 // Set right hand side X values
135 points.append(q->x(0) + 2 * q->x(1));
142 for (int i = 1; i < n - 1; ++i)
143 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
144
136
145 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
146 // Get first control points X-values
147 QList<qreal> xControl = getFirstControlPoints(rhs);
148 rhs[0] = q->y(0) + 2 * q->y(1);
149
137
150 // Set right hand side Y values
151 for (int i = 1; i < n - 1; ++i)
138 for (int i = 1; i < n - 1; ++i)
152 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
139 points.append(4 * q->x(i) + 2 * q->x(i + 1));
140
141 points.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
142
143 QList<qreal> xControl = firstControlPoints(points);
144 points[0] = q->y(0) + 2 * q->y(1);
145
146 for (int i = 1; i < n - 1; ++i) {
147 points[i] = 4 * q->y(i) + 2 * q->y(i + 1);
148 }
149
150 points[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
153
151
154 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
152 QList<qreal> yControl = firstControlPoints(points);
155 // Get first control points Y-values
156 QList<qreal> yControl = getFirstControlPoints(rhs);
157
153
158 // Fill output arrays.
159 for (int i = 0; i < n; ++i) {
154 for (int i = 0; i < n; ++i) {
160 // First control point
155
161 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
156 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
162 // Second control point
157
163 if (i < n - 1)
158 if (i < n - 1)
164 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
159 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
165 else
160 else
166 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
161 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
167 }
162 }
168 }
163 }
169
164
170 /*!
165 QList<qreal> QSplineSeriesPrivate::firstControlPoints(QList<qreal> list)
171 \internal
172 */
173 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
174 {
166 {
175 QList<qreal> x; // Solution vector.
167 QList<qreal> result;
176 QList<qreal> tmp; // Temp workspace.
168 QList<qreal> temp;
177
169
178 qreal b = 2.0;
170 qreal b = 2.0;
179 x.append(rhs[0] / b);
171 result.append(list[0] / b);
180 tmp.append(0);
172 temp.append(0);
181 for (int i = 1; i < rhs.size(); i++) {
173 for (int i = 1; i < list.size(); i++) {
182 // Decomposition and forward substitution.
174 temp.append(1 / b);
183 tmp.append(1 / b);
175 b = (i < list.size() - 1 ? 4.0 : 3.5) - temp[i];
184 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
176 result.append((list[i] - result[i - 1]) / b);
185 x.append((rhs[i] - x[i - 1]) / b);
186 }
177 }
187 for (int i = 1; i < rhs.size(); i++)
178 for (int i = 1; i < list.size(); i++)
188 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
179 result[list.size() - i - 1] -= temp[list.size() - i] * result[list.size() - i];
189
180
190 return x;
181 return result;
191 }
182 }
192
183
193 /*!
184 /*!
194 \internal
195 Updates the control points, besed on currently avaiable knots.
185 Updates the control points, besed on currently avaiable knots.
196 */
186 */
197 void QSplineSeriesPrivate::updateControlPoints()
187 void QSplineSeriesPrivate::updateControlPoints()
198 {
188 {
199 Q_Q(QSplineSeries);
189 Q_Q(QSplineSeries);
200 if (q->count() > 1) {
190 if (q->count() > 1) {
201 m_controlPoints.clear();
191 m_controlPoints.clear();
202 calculateControlPoints();
192 calculateControlPoints();
203 }
193 }
204 }
194 }
205
195
206 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
196 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
207 {
197 {
208 Q_Q(QSplineSeries);
198 Q_Q(QSplineSeries);
209 SplineChartItem* spline = new SplineChartItem(q,presenter);
199 SplineChartItem* spline = new SplineChartItem(q,presenter);
210 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
200 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
211 presenter->animator()->addAnimation(spline);
201 presenter->animator()->addAnimation(spline);
212 }
202 }
213 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
203 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
214 return spline;
204 return spline;
215 }
205 }
216
206
217 #include "moc_qsplineseries.cpp"
207 #include "moc_qsplineseries.cpp"
218 #include "moc_qsplineseries_p.cpp"
208 #include "moc_qsplineseries_p.cpp"
219
209
220 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,57 +1,57
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QSPLINESERIES_P_H
30 #ifndef QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
32
32
33 #include "qlineseries_p.h"
33 #include "qlineseries_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37
37
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 Chart* createGraphics(ChartPresenter* presenter);
42 Chart* createGraphics(ChartPresenter* presenter);
43 QSplineSeriesPrivate(QSplineSeries* q);
43 QSplineSeriesPrivate(QSplineSeries* q);
44 void calculateControlPoints();
44 void calculateControlPoints();
45 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
45 QList<qreal> firstControlPoints(QList<qreal> rhs);
46
46
47 public Q_SLOTS:
47 public Q_SLOTS:
48 void updateControlPoints();
48 void updateControlPoints();
49 public:
49 public:
50 QList<QPointF> m_controlPoints;
50 QList<QPointF> m_controlPoints;
51 private:
51 private:
52 Q_DECLARE_PUBLIC(QSplineSeries)
52 Q_DECLARE_PUBLIC(QSplineSeries)
53 };
53 };
54
54
55 QTCOMMERCIALCHART_END_NAMESPACE
55 QTCOMMERCIALCHART_END_NAMESPACE
56
56
57 #endif
57 #endif
General Comments 0
You need to be logged in to leave comments. Login now