##// END OF EJS Templates
Fixes and improvments to series API...
Michal Klocek -
r1057:d444309c9f1b
parent child
Show More
@@ -189,9 +189,10 QChart* ThemeWidget::createAreaChart() const
189 189 QLineSeries *upperSeries = new QLineSeries(chart);
190 190 for (int j(0); j < m_dataTable[i].count(); j++) {
191 191 Data data = m_dataTable[i].at(j);
192 if (lowerSeries)
193 upperSeries->append(QPointF(j, lowerSeries->y(i) + data.first.y()));
194 else
192 if (lowerSeries){
193 const QList<QPointF>& points = lowerSeries->points();
194 upperSeries->append(QPointF(j, points[i].y() + data.first.y()));
195 }else
195 196 upperSeries->append(QPointF(j, data.first.y()));
196 197 }
197 198 QAreaSeries *area = new QAreaSeries(upperSeries, lowerSeries);
@@ -57,9 +57,10 Chart::~Chart()
57 57 void Chart::handleTimeout()
58 58 {
59 59 m_x += m_step;
60 qreal y = m_y;
60 61 m_y = qrand() % 5 - 2.5;
61 62 m_series->append(m_x, m_y);
62 63 if (m_x >= 10)
63 m_series->remove(m_x - 10);
64 m_series->remove(m_x - 10,y);
64 65 scrollRight();
65 66 }
@@ -231,20 +231,25 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
231 231 QLineSeries* upperSeries = q->upperSeries();
232 232 QLineSeries* lowerSeries = q->lowerSeries();
233 233
234 for (int i = 0; i < upperSeries->count(); i++)
234 const QList<QPointF>& points = upperSeries->points();
235
236 for (int i = 0; i < points.count(); i++)
235 237 {
236 qreal x = upperSeries->x(i);
237 qreal y = upperSeries->y(i);
238 qreal x = points[i].x();
239 qreal y = points[i].y();
238 240 minX = qMin(minX, x);
239 241 minY = qMin(minY, y);
240 242 maxX = qMax(maxX, x);
241 243 maxY = qMax(maxY, y);
242 244 }
243 245 if(lowerSeries) {
244 for (int i = 0; i < lowerSeries->count(); i++)
246
247 const QList<QPointF>& points = upperSeries->points();
248
249 for (int i = 0; i < points.count(); i++)
245 250 {
246 qreal x = lowerSeries->x(i);
247 qreal y = lowerSeries->y(i);
251 qreal x = points[i].x();
252 qreal y = points[i].y();
248 253 minX = qMin(minX, x);
249 254 minY = qMin(minY, y);
250 255 maxX = qMax(maxX, x);
@@ -98,7 +98,7 void ScatterChartItem::deletePoints(int count)
98 98
99 99 void ScatterChartItem::markerSelected(Marker *marker)
100 100 {
101 emit XYChartItem::clicked(QPointF(m_series->x(marker->index()), m_series->y(marker->index())));
101 emit XYChartItem::clicked(marker->point());
102 102 }
103 103
104 104 void ScatterChartItem::setLayout(QVector<QPointF>& points)
@@ -126,7 +126,7 void ScatterChartItem::setLayout(QVector<QPointF>& points)
126 126 Marker* item = static_cast<Marker*>(items.at(i));
127 127 const QPointF& point = points.at(i);
128 128 const QRectF& rect = item->boundingRect();
129 item->setIndex(i);
129 item->setPoint(point);
130 130 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
131 131 if(!clipRect().contains(point)) {
132 132 item->setVisible(false);
@@ -72,7 +72,7 class Marker: public QAbstractGraphicsShapeItem
72 72
73 73 public:
74 74
75 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent), m_index(-1)
75 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent)
76 76 {
77 77 }
78 78
@@ -81,14 +81,14 public:
81 81 delete m_item;
82 82 }
83 83
84 void setIndex(int index)
84 void setPoint(const QPointF& point)
85 85 {
86 m_index=index;
86 m_point=point;
87 87 }
88 88
89 int index() const
89 QPointF point() const
90 90 {
91 return m_index;
91 return m_point;
92 92 }
93 93
94 94 QPainterPath shape() const
@@ -132,7 +132,7 protected:
132 132 private:
133 133 QAbstractGraphicsShapeItem* m_item;
134 134 ScatterChartItem* m_parent;
135 int m_index;
135 QPointF m_point;
136 136 };
137 137
138 138 QTCOMMERCIALCHART_END_NAMESPACE
@@ -105,15 +105,15 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(
105 105 void QSplineSeriesPrivate::calculateControlPoints()
106 106 {
107 107
108 Q_Q(QSplineSeries);
109
110 int n = q->count() - 1;
108 int n = m_points.count() - 1;
111 109
112 110 if (n == 1)
113 111 {
114 112 //for n==1
115 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
116 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
113 m_controlPoints[0].setX((2 * m_points[0].x() + m_points[1].x()) / 3);
114 m_controlPoints[0].setY((2 * m_points[0].y() + m_points[1].y()) / 3);
115 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - m_points[0].x());
116 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - m_points[0].y());
117 117 return;
118 118 }
119 119
@@ -130,53 +130,68 void QSplineSeriesPrivate::calculateControlPoints()
130 130 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
131 131 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
132 132 //
133 QList<qreal> points;
133 QVector<qreal> vector;
134 vector.resize(n);
135
136 vector[0] = m_points[0].x() + 2 * m_points[1].x();
134 137
135 points.append(q->x(0) + 2 * q->x(1));
136 138
139 for (int i = 1; i < n - 1; ++i){
140 vector[i] = 4 * m_points[i].x() + 2 * m_points[i + 1].x();
141 }
137 142
138 for (int i = 1; i < n - 1; ++i)
139 points.append(4 * q->x(i) + 2 * q->x(i + 1));
143 vector[n - 1] = (8 * m_points[n-1].x() + m_points[n].x()) / 2.0;
140 144
141 points.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
145 QVector<qreal> xControl = firstControlPoints(vector);
142 146
143 QList<qreal> xControl = firstControlPoints(points);
144 points[0] = q->y(0) + 2 * q->y(1);
147 vector[0] = m_points[0].y() + 2 * m_points[1].y();
145 148
146 149 for (int i = 1; i < n - 1; ++i) {
147 points[i] = 4 * q->y(i) + 2 * q->y(i + 1);
150 vector[i] = 4 * m_points[i].y() + 2 * m_points[i + 1].y();
148 151 }
149 152
150 points[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
153 vector[n - 1] = (8 * m_points[n-1].y() + m_points[n].y()) / 2.0;
154
155 QVector<qreal> yControl = firstControlPoints(vector);
151 156
152 QList<qreal> yControl = firstControlPoints(points);
157 for (int i = 0,j =0; i < n; ++i, ++j) {
153 158
154 for (int i = 0; i < n; ++i) {
159 m_controlPoints[j].setX(xControl[i]);
160 m_controlPoints[j].setY(yControl[i]);
155 161
156 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
162 j++;
157 163
158 if (i < n - 1)
159 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
160 else
161 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
164 if (i < n - 1){
165 m_controlPoints[j].setX(2 * m_points[i+1].x() - xControl[i + 1]);
166 m_controlPoints[j].setY(2 * m_points[i+1].y() - yControl[i + 1]);
167 }else{
168 m_controlPoints[j].setX((m_points[n].x() + xControl[n - 1]) / 2);
169 m_controlPoints[j].setY((m_points[n].y() + yControl[n - 1]) / 2);
170 }
162 171 }
163 172 }
164 173
165 QList<qreal> QSplineSeriesPrivate::firstControlPoints(QList<qreal> list)
174 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
166 175 {
167 QList<qreal> result;
168 QList<qreal> temp;
176 QVector<qreal> result;
177
178 int count = vector.count();
179 result.resize(count);
180 result[0] = vector[0] / 2.0;
181
182 QVector<qreal> temp;
183 temp.resize(count);
184 temp[0] = 0;
169 185
170 186 qreal b = 2.0;
171 result.append(list[0] / b);
172 temp.append(0);
173 for (int i = 1; i < list.size(); i++) {
174 temp.append(1 / b);
175 b = (i < list.size() - 1 ? 4.0 : 3.5) - temp[i];
176 result.append((list[i] - result[i - 1]) / b);
187
188 for (int i = 1; i < count; i++) {
189 temp[i] = 1 / b;
190 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
191 result[i]=(vector[i] - result[i - 1]) / b;
177 192 }
178 for (int i = 1; i < list.size(); i++)
179 result[list.size() - i - 1] -= temp[list.size() - i] * result[list.size() - i];
193 for (int i = 1; i < count; i++)
194 result[count - i - 1] -= temp[count - i] * result[count - i];
180 195
181 196 return result;
182 197 }
@@ -186,9 +201,8 QList<qreal> QSplineSeriesPrivate::firstControlPoints(QList<qreal> list)
186 201 */
187 202 void QSplineSeriesPrivate::updateControlPoints()
188 203 {
189 Q_Q(QSplineSeries);
190 if (q->count() > 1) {
191 m_controlPoints.clear();
204 if (m_points.count() > 1) {
205 m_controlPoints.resize(2*m_points.count()-2);
192 206 calculateControlPoints();
193 207 }
194 208 }
@@ -41,13 +41,16 class QSplineSeriesPrivate: public QLineSeriesPrivate
41 41 public:
42 42 Chart* createGraphics(ChartPresenter* presenter);
43 43 QSplineSeriesPrivate(QSplineSeries* q);
44 void calculateControlPoints();
45 QList<qreal> firstControlPoints(QList<qreal> rhs);
46 44
47 45 public Q_SLOTS:
48 46 void updateControlPoints();
47
48 private:
49 void calculateControlPoints();
50 QVector<qreal> firstControlPoints(const QVector<qreal>& vector);
51
49 52 public:
50 QList<QPointF> m_controlPoints;
53 QVector<QPointF> m_controlPoints;
51 54 private:
52 55 Q_DECLARE_PUBLIC(QSplineSeries)
53 56 };
@@ -98,11 +98,7 QXYSeries::~QXYSeries()
98 98 */
99 99 void QXYSeries::append(qreal x,qreal y)
100 100 {
101 Q_D(QXYSeries);
102 Q_ASSERT(d->m_x.size() == d->m_y.size());
103 d->m_x<<x;
104 d->m_y<<y;
105 emit d->pointAdded(d->m_x.size()-1);
101 append(QPointF(x,y));
106 102 }
107 103
108 104 /*!
@@ -111,55 +107,35 void QXYSeries::append(qreal x,qreal y)
111 107 */
112 108 void QXYSeries::append(const QPointF &point)
113 109 {
114 append(point.x(),point.y());
110 Q_D(QXYSeries);
111 d->m_points<<point;
112 emit d->pointAdded(d->m_points.count()-1);
115 113 }
116 114
117 115 /*!
118 116 This is an overloaded function.
119 117 Adds list of data \a points to the series. Points are connected with lines on the chart.
120 118 */
121 void QXYSeries::append(const QList<QPointF> points)
119 void QXYSeries::append(const QList<QPointF> &points)
122 120 {
123 121 foreach(const QPointF& point , points) {
124 append(point.x(),point.y());
122 append(point);
125 123 }
126 124 }
127 125
128 /*!
129 Modifies \a y value for given \a x a value.
130 */
131 void QXYSeries::replace(qreal x,qreal y)
132 {
133 Q_D(QXYSeries);
134 int index = d->m_x.indexOf(x);
135 d->m_x[index] = x;
136 d->m_y[index] = y;
137 emit d->pointReplaced(index);
138 }
139 126
140 /*!
141 This is an overloaded function.
142 Replaces current y value of for given \a point x value with \a point y value.
143 */
144 void QXYSeries::replace(const QPointF &point)
127 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
145 128 {
146 replace(point.x(),point.y());
129 replace(QPointF(oldX,oldY),QPointF(newX,newY));
147 130 }
148 131
149 /*!
150 Removes first \a x value and related y value.
151 */
152 void QXYSeries::remove(qreal x)
132 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
153 133 {
154 134 Q_D(QXYSeries);
155 int index = d->m_x.indexOf(x);
156
157 if (index == -1) return;
158
159 d->m_x.remove(index);
160 d->m_y.remove(index);
161
162 emit d->pointRemoved(index);
135 int index = d->m_points.indexOf(oldPoint);
136 if(index==1) return;
137 d->m_points[index] = newPoint;
138 emit d->pointReplaced(index);
163 139 }
164 140
165 141 /*!
@@ -167,17 +143,7 void QXYSeries::remove(qreal x)
167 143 */
168 144 void QXYSeries::remove(qreal x,qreal y)
169 145 {
170 Q_D(QXYSeries);
171 int index =-1;
172 do {
173 index = d->m_x.indexOf(x,index+1);
174 } while (index !=-1 && d->m_y.at(index)!=y);
175
176 if (index==-1) return;
177
178 d->m_x.remove(index);
179 d->m_y.remove(index);
180 emit d->pointRemoved(index);
146 remove(QPointF(x,y));
181 147 }
182 148
183 149 /*!
@@ -185,7 +151,11 void QXYSeries::remove(qreal x,qreal y)
185 151 */
186 152 void QXYSeries::remove(const QPointF &point)
187 153 {
188 remove(point.x(),point.y());
154 Q_D(QXYSeries);
155 int index = d->m_points.indexOf(point);
156 if(index==1) return;
157 d->m_points.remove(index);
158 emit d->pointRemoved(index);
189 159 }
190 160
191 161 /*!
@@ -194,45 +164,41 void QXYSeries::remove(const QPointF &point)
194 164 void QXYSeries::removeAll()
195 165 {
196 166 Q_D(QXYSeries);
197 d->m_x.clear();
198 d->m_y.clear();
167 foreach(const QPointF& point, d->m_points) {
168 remove(point);
169 }
199 170 }
200 171
201 172 /*!
202 173 \internal \a pos
203 174 */
204 qreal QXYSeries::x(int pos) const
175 QList<QPointF> QXYSeries::points() const
205 176 {
206 177 Q_D(const QXYSeries);
207 178 if (d->m_model) {
208 if (d->m_mapOrientation == Qt::Vertical)
179 QList<QPointF> result;
180 if (d->m_mapOrientation == Qt::Vertical){
209 181 // consecutive data is read from model's column
210 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapX), Qt::DisplayRole).toDouble();
211 else
212 // consecutive data is read from model's row
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
214 } else {
215 // model is not specified, return the data from series' internal data store
216 return d->m_x.at(pos);
182
183 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
184 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapX), Qt::DisplayRole).toReal();
185 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapY), Qt::DisplayRole).toReal();
186 result << QPointF(x,y);
217 187 }
188 return result;
218 189 }
219
220 /*!
221 \internal \a pos
222 */
223 qreal QXYSeries::y(int pos) const
224 {
225 Q_D(const QXYSeries);
226 if (d->m_model) {
227 if (d->m_mapOrientation == Qt::Vertical)
228 // consecutive data is read from model's column
229 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapY), Qt::DisplayRole).toDouble();
230 else
190 else{
231 191 // consecutive data is read from model's row
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
192 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
193 qreal x = d->m_model->data(d->m_model->index(d->m_mapX, i), Qt::DisplayRole).toReal();
194 qreal y = d->m_model->data(d->m_model->index(d->m_mapY, i), Qt::DisplayRole).toReal();
195 result << QPointF(x,y);
196 }
197 return result;
198 }
233 199 } else {
234 200 // model is not specified, return the data from series' internal data store
235 return d->m_y.at(pos);
201 return d->m_points.toList();
236 202 }
237 203 }
238 204
@@ -243,8 +209,6 int QXYSeries::count() const
243 209 {
244 210 Q_D(const QXYSeries);
245 211
246 Q_ASSERT(d->m_x.size() == d->m_y.size());
247
248 212 if (d->m_model) {
249 213 if (d->m_mapOrientation == Qt::Vertical) {
250 214 // data is in a column. Return the number of mapped items if the model's column have enough items
@@ -264,19 +228,7 int QXYSeries::count() const
264 228 }
265 229
266 230 // model is not specified, return the number of points in the series internal data store
267 return d->m_x.size();
268 }
269
270 /*!
271 Returns the data points of the series.
272 */
273 QList<QPointF> QXYSeries::data()
274 {
275 Q_D(QXYSeries);
276 QList<QPointF> data;
277 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
278 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
279 return data;
231 return d->m_points.count();
280 232 }
281 233
282 234
@@ -359,7 +311,7 QXYSeries& QXYSeries::operator<< (const QPointF &point)
359 311 \sa append()
360 312 */
361 313
362 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
314 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
363 315 {
364 316 append(points);
365 317 return *this;
@@ -443,11 +395,11 void QXYSeriesPrivate::scaleDomain(Domain& domain)
443 395 int tickXCount(domain.tickXCount());
444 396 int tickYCount(domain.tickYCount());
445 397
446 Q_Q(QXYSeries);
447 for (int i = 0; i < q->count(); i++)
398 for (int i = 0; i < m_points.count(); i++)
448 399 {
449 qreal x = q->x(i);
450 qreal y = q->y(i);
400
401 qreal x = m_points[i].x();
402 qreal y = m_points[i].y();
451 403 minX = qMin(minX, x);
452 404 minY = qMin(minY, y);
453 405 maxX = qMax(maxX, x);
@@ -42,21 +42,18 protected:
42 42 public:
43 43 void append(qreal x, qreal y);
44 44 void append(const QPointF &point);
45 void append(const QList<QPointF> points);
46 void replace(qreal x,qreal y);
47 void replace(const QPointF &point);
48 void remove(qreal x);
45 void append(const QList<QPointF> &points);
46 void replace(qreal oldX,qreal oldY,qreal newX,qreal newY);
47 void replace(const QPointF &oldPoint,const QPointF &newPoint);
49 48 void remove(qreal x, qreal y);
50 49 void remove(const QPointF &point);
51 50 void removeAll();
52 51
53 52 int count() const;
54 qreal x(int pos) const;
55 qreal y(int pos) const;
56 QList<QPointF> data();
53 QList<QPointF> points() const;
57 54
58 55 QXYSeries& operator << (const QPointF &point);
59 QXYSeries& operator << (const QList<QPointF> points);
56 QXYSeries& operator << (const QList<QPointF> &points);
60 57
61 58 void setPen(const QPen &pen);
62 59 QPen pen() const;
@@ -62,8 +62,7 Q_SIGNALS:
62 62
63 63
64 64 protected:
65 QVector<qreal> m_x;
66 QVector<qreal> m_y;
65 QVector<QPointF> m_points;
67 66
68 67 QPen m_pen;
69 68 QBrush m_brush;
@@ -61,8 +61,9 QPointF XYChartItem::calculateGeometryPoint(int index) const
61 61 {
62 62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
63 63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
64 qreal x = (m_series->x(index) - m_minX)* deltaX;
65 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
64 const QList<QPointF>& vector = m_series->points();
65 qreal x = (vector[index].x() - m_minX)* deltaX;
66 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
66 67 return QPointF(x,y);
67 68 }
68 69
@@ -71,14 +72,16 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
71 72 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
72 73 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
73 74
74 QVector<QPointF> points;
75 points.reserve(m_series->count());
75 QVector<QPointF> result;
76 result.resize(m_series->count());
77 const QList<QPointF>& vector = m_series->points();
76 78 for (int i = 0; i < m_series->count(); ++i) {
77 qreal x = (m_series->x(i) - m_minX)* deltaX;
78 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
79 points << QPointF(x,y);
79 qreal x = (vector[i].x() - m_minX)* deltaX;
80 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
81 result[i].setX(x);
82 result[i].setY(y);
80 83 }
81 return points;
84 return result;
82 85 }
83 86
84 87 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
@@ -3,7 +3,7
3 3 }
4 4
5 5 TEMPLATE = subdirs
6 SUBDIRS += qchartview qchart
6 SUBDIRS += qchartview qchart qlineseries
7 7
8 8 test_private:{
9 9 SUBDIRS += chartdataset domain
@@ -58,10 +58,10 void WaveChart::update()
58 58 {
59 59
60 60 int fluctuate;
61
61 const QList<QPointF>& points = m_series->points();
62 62 for (qreal i = 0, x = 0; x <= 2 * PI; x += m_step, i++) {
63 63 fluctuate = qrand() % 100;
64 m_series->replace(x, fabs(sin(x) * fluctuate));
64 m_series->replace(x,points[i].y(),x,fabs(sin(x) * fluctuate));
65 65
66 66 }
67 67
General Comments 0
You need to be logged in to leave comments. Login now