##// END OF EJS Templates
Removed controlPoint function from SplineSeries Public API
Marek Rosa -
r1160:9e86776df29c
parent child
Show More
@@ -1,269 +1,270
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qsplineseries.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "splinechartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include <QAbstractItemModel>
28 28
29 29 /*!
30 30 \class QSplineSeries
31 31 \brief Series type used to store data needed to draw a spline.
32 32
33 33 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
34 34 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
35 35
36 36 \image examples_splinechart.png
37 37
38 38 Creating basic spline chart is simple:
39 39 \code
40 40 QSplineSeries* series = new QSplineSeries();
41 41 series->append(0, 6);
42 42 series->append(2, 4);
43 43 ...
44 44 chart->addSeries(series);
45 45 \endcode
46 46 */
47 47
48 48 /*!
49 49 \fn QSeriesType QSplineSeries::type() const
50 50 Returns the type of the series
51 51 */
52 52
53 53 /*!
54 54 \fn QSeriesType QSplineSeries::controlPoint(int index) const
55 55 Returns the control point specified by \a index
56 56 */
57 57
58 58 QTCOMMERCIALCHART_BEGIN_NAMESPACE
59 59
60 60 /*!
61 61 Constructs empty series object which is a child of \a parent.
62 62 When series object is added to QChartView or QChart instance then the ownerships is transferred.
63 63 */
64 64
65 65 QSplineSeries::QSplineSeries(QObject *parent) :
66 66 QLineSeries(*new QSplineSeriesPrivate(this),parent)
67 67 {
68 68 }
69 69
70 70 QSplineSeries::~QSplineSeries()
71 71 {
72 72 Q_D(QSplineSeries);
73 73 if(d->m_dataset){
74 74 d->m_dataset->removeSeries(this);
75 75 }
76 76 }
77 77
78 78 QAbstractSeries::SeriesType QSplineSeries::type() const
79 79 {
80 80 return QAbstractSeries::SeriesTypeSpline;
81 81 }
82 82
83 QPointF QSplineSeries::controlPoint(int index) const
84 {
85 Q_D(const QSplineSeries);
86 return d->m_controlPoints[index];
87 }
88
89 83 /*!
90 84 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
91 85 as a data source for y coordinate. The \a orientation parameter specifies whether the data
92 86 is in columns or in rows.
93 87 \sa setModel()
94 88 */
95 89 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
96 90 {
97 91 Q_D(QSplineSeries);
98 92 QXYSeries::setModelMapping(modelX, modelY, orientation);
99 93 d->updateControlPoints();
100 94 }
101 95
102 96 void QSplineSeries::setModelMappingRange(int first, int count)
103 97 {
104 98 Q_D(QSplineSeries);
105 99 QXYSeries::setModelMappingRange(first, count);
106 100 d->updateControlPoints();
107 101
108 102 }
109 103
110 104 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
111 105
112 106 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
113 107 {
114 108 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
115 109 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
116 110 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
117 111 };
118 112
119 113 /*!
120 114 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
121 115 */
122 116 void QSplineSeriesPrivate::calculateControlPoints()
123 117 {
124 118 Q_Q(QSplineSeries);
125 119
126 120 const QList<QPointF>& points = q->points();
127 121
128 122 int n = points.count() - 1;
129 123
130 124 if (n == 1)
131 125 {
132 126 //for n==1
133 127 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
134 128 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
135 129 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
136 130 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
137 131 return;
138 132 }
139 133
140 134 // Calculate first Bezier control points
141 135 // Right hand side vector
142 136 // Set of equations for P0 to Pn points.
143 137 //
144 138 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
145 139 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
146 140 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
147 141 // | . . . . . . . . . . . . | | ... | | ... |
148 142 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
149 143 // | . . . . . . . . . . . . | | ... | | ... |
150 144 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
151 145 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
152 146 //
153 147 QVector<qreal> vector;
154 148 vector.resize(n);
155 149
156 150 vector[0] = points[0].x() + 2 * points[1].x();
157 151
158 152
159 153 for (int i = 1; i < n - 1; ++i){
160 154 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
161 155 }
162 156
163 157 vector[n - 1] = (8 * points[n-1].x() + points[n].x()) / 2.0;
164 158
165 159 QVector<qreal> xControl = firstControlPoints(vector);
166 160
167 161 vector[0] = points[0].y() + 2 * points[1].y();
168 162
169 163 for (int i = 1; i < n - 1; ++i) {
170 164 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
171 165 }
172 166
173 167 vector[n - 1] = (8 * points[n-1].y() + points[n].y()) / 2.0;
174 168
175 169 QVector<qreal> yControl = firstControlPoints(vector);
176 170
177 171 for (int i = 0,j =0; i < n; ++i, ++j) {
178 172
179 173 m_controlPoints[j].setX(xControl[i]);
180 174 m_controlPoints[j].setY(yControl[i]);
181 175
182 176 j++;
183 177
184 178 if (i < n - 1){
185 179 m_controlPoints[j].setX(2 * points[i+1].x() - xControl[i + 1]);
186 180 m_controlPoints[j].setY(2 * points[i+1].y() - yControl[i + 1]);
187 181 }else{
188 182 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
189 183 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
190 184 }
191 185 }
192 186 }
193 187
194 188 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
195 189 {
196 190 QVector<qreal> result;
197 191
198 192 int count = vector.count();
199 193 result.resize(count);
200 194 result[0] = vector[0] / 2.0;
201 195
202 196 QVector<qreal> temp;
203 197 temp.resize(count);
204 198 temp[0] = 0;
205 199
206 200 qreal b = 2.0;
207 201
208 202 for (int i = 1; i < count; i++) {
209 203 temp[i] = 1 / b;
210 204 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
211 205 result[i]=(vector[i] - result[i - 1]) / b;
212 206 }
213 207 for (int i = 1; i < count; i++)
214 208 result[count - i - 1] -= temp[count - i] * result[count - i];
215 209
216 210 return result;
217 211 }
218 212
213 QPointF QSplineSeriesPrivate::controlPoint(int index) const
214 {
215 // Q_D(const QSplineSeries);
216 // return d->m_controlPoints[index];
217 return m_controlPoints[index];
218 }
219
219 220 /*!
220 221 Updates the control points, besed on currently avaiable knots.
221 222 */
222 223 void QSplineSeriesPrivate::updateControlPoints()
223 224 {
224 225 Q_Q(QSplineSeries);
225 226 if (q->count() > 1) {
226 227 m_controlPoints.resize(2*q->count()-2);
227 228 calculateControlPoints();
228 229 }
229 230 }
230 231
231 232 void QSplineSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
232 233 {
233 234 updateControlPoints();
234 235 QXYSeriesPrivate::modelRowsAdded(parent, start, end);
235 236 }
236 237
237 238 void QSplineSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
238 239 {
239 240 updateControlPoints();
240 241 QXYSeriesPrivate::modelRowsRemoved(parent, start, end);
241 242 }
242 243
243 244 void QSplineSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
244 245 {
245 246 updateControlPoints();
246 247 QXYSeriesPrivate::modelColumnsAdded(parent, start, end);
247 248 }
248 249
249 250 void QSplineSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
250 251 {
251 252 updateControlPoints();
252 253 QXYSeriesPrivate::modelColumnsRemoved(parent, start, end);
253 254 }
254 255
255 256 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
256 257 {
257 258 Q_Q(QSplineSeries);
258 259 SplineChartItem* spline = new SplineChartItem(q,presenter);
259 260 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
260 261 presenter->animator()->addAnimation(spline);
261 262 }
262 263 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
263 264 return spline;
264 265 }
265 266
266 267 #include "moc_qsplineseries.cpp"
267 268 #include "moc_qsplineseries_p.cpp"
268 269
269 270 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,56 +1,56
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QSPLINESERIES_H
22 22 #define QSPLINESERIES_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <qlineseries.h>
26 26 #include <QList>
27 27 #include <QPointF>
28 28 #include <QtGlobal>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 class QSplineSeriesPrivate;
33 33
34 34 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
35 35 {
36 36 Q_OBJECT
37 37 public:
38 38
39 39 explicit QSplineSeries(QObject *parent = 0);
40 40 ~QSplineSeries();
41 41 QAbstractSeries::SeriesType type() const;
42 42
43 QPointF controlPoint(int index) const;
43 // QPointF controlPoint(int index) const;
44 44
45 45 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 46 void setModelMappingRange(int first, int count = -1);
47 47
48 48 private:
49 49 Q_DECLARE_PRIVATE(QSplineSeries);
50 50 Q_DISABLE_COPY(QSplineSeries);
51 51 friend class SplineChartItem;
52 52 };
53 53
54 54 QTCOMMERCIALCHART_END_NAMESPACE
55 55
56 56 #endif // QSPLINESERIES_H
@@ -1,66 +1,68
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QSPLINESERIES_P_H
31 31 #define QSPLINESERIES_P_H
32 32
33 33 #include "qlineseries_p.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37
38 38 class QSplineSeriesPrivate: public QLineSeriesPrivate
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 Chart* createGraphics(ChartPresenter* presenter);
43 43 QSplineSeriesPrivate(QSplineSeries* q);
44 44
45 QPointF controlPoint(int index) const;
46
45 47 public Q_SLOTS:
46 48 void updateControlPoints();
47 49
48 50 protected Q_SLOTS:
49 51 void modelRowsAdded(QModelIndex parent, int start, int end);
50 52 void modelRowsRemoved(QModelIndex parent, int start, int end);
51 53 void modelColumnsAdded(QModelIndex parent, int start, int end);
52 54 void modelColumnsRemoved(QModelIndex parent, int start, int end);
53 55
54 56 private:
55 57 void calculateControlPoints();
56 58 QVector<qreal> firstControlPoints(const QVector<qreal>& vector);
57 59
58 60 public:
59 61 QVector<QPointF> m_controlPoints;
60 62 private:
61 63 Q_DECLARE_PUBLIC(QSplineSeries)
62 64 };
63 65
64 66 QTCOMMERCIALCHART_END_NAMESPACE
65 67
66 68 #endif
@@ -1,148 +1,149
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "splinechartitem_p.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 25 #include <QPainter>
26 26 #include <QDebug>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
31 31 XYChartItem(series, presenter),
32 32 m_series(series),
33 33 m_pointsVisible(false)
34 34 {
35 35 setZValue(ChartPresenter::LineChartZValue);
36 36 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
37 37 handleUpdated();
38 38 }
39 39
40 40 QRectF SplineChartItem::boundingRect() const
41 41 {
42 42 return m_rect;
43 43 }
44 44
45 45 QPainterPath SplineChartItem::shape() const
46 46 {
47 47 return m_path;
48 48 }
49 49
50 50 void SplineChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
51 51 {
52 52 QVector<QPointF> controlPoints;
53 53
54 54 if(newPoints.count()>=2){
55 55 controlPoints.resize(newPoints.count()*2-2);
56 56 }
57 57
58 58 for (int i = 0; i < newPoints.size() - 1; i++) {
59 59 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
60 60 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
61 61 }
62 62
63 63 if (controlPoints.count()<2) {
64 64 setLayout(newPoints,controlPoints);
65 65 return;
66 66 }
67 67
68 68 if (animator()) {
69 69 animator()->updateLayout(this,oldPoints,newPoints,m_controlPoints,controlPoints,index);
70 70 } else {
71 71 setLayout(newPoints,controlPoints);
72 72 }
73 73 }
74 74
75 75 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
76 76 {
77 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
77 // return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
78 return XYChartItem::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
78 79 }
79 80
80 81 void SplineChartItem::setLayout(QVector<QPointF> &points)
81 82 {
82 83 // Dummy implementation because of a bug in Clang compiler
83 84 if (points.size() < 2) {
84 85 m_path = QPainterPath();
85 86 }
86 87 XYChartItem::setLayout(points);
87 88 }
88 89
89 90 void SplineChartItem::setLayout(QVector<QPointF> &points, QVector<QPointF> &controlPoints)
90 91 {
91 92 if ((points.size()<2) || (controlPoints.size()<2)) {
92 93 m_path = QPainterPath();
93 94 XYChartItem::setLayout(points);
94 95 m_controlPoints=controlPoints;
95 96 return;
96 97 }
97 98
98 99 Q_ASSERT(points.count()*2-2 == controlPoints.count());
99 100
100 101 QPainterPath splinePath(points.at(0));
101 102
102 103 for (int i = 0; i < points.size() - 1; i++) {
103 104 const QPointF& point = points.at(i + 1);
104 105 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
105 106 }
106 107
107 108 prepareGeometryChange();
108 109 m_path = splinePath;
109 110 m_rect = splinePath.boundingRect();
110 111 XYChartItem::setLayout(points);
111 112 m_controlPoints=controlPoints;
112 113
113 114 }
114 115
115 116 //handlers
116 117
117 118 void SplineChartItem::handleUpdated()
118 119 {
119 120 m_pointsVisible = m_series->pointsVisible();
120 121 m_linePen = m_series->pen();
121 122 m_pointPen = m_series->pen();
122 123 m_pointPen.setWidthF(2*m_pointPen.width());
123 124 update();
124 125 }
125 126
126 127 //painter
127 128
128 129 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
129 130 {
130 131 Q_UNUSED(widget)
131 132 Q_UNUSED(option)
132 133 qDebug()<<__FUNCTION__;
133 134 painter->save();
134 135 painter->setClipRect(clipRect());
135 136 painter->setPen(m_linePen);
136 137 painter->drawPath(m_path);
137 138 if (m_pointsVisible) {
138 139 painter->setPen(m_pointPen);
139 140 painter->drawPoints(points());
140 141 }
141 142 painter->restore();
142 143 }
143 144
144 145
145 146
146 147 #include "moc_splinechartitem_p.cpp"
147 148
148 149 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now