##// END OF EJS Templates
No errors anymore when generating docs, wohoo! For now.
Tero Ahola -
r1002:f486aabc62ff
parent child
Show More
@@ -1,452 +1,460
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 "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieslice.h"
38 #include "qpieslice.h"
39 #include "chartpresenter_p.h"
39 #include "chartpresenter_p.h"
40 #include <QPainter>
40 #include <QPainter>
41 #include <QPen>
41 #include <QPen>
42 #include <QTimer>
42 #include <QTimer>
43
43
44 #include <QGraphicsSceneEvent>
44 #include <QGraphicsSceneEvent>
45
45
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47
47
48 /*!
48 /*!
49 \class QLegend
49 \class QLegend
50 \brief part of QtCommercial chart API.
50 \brief part of QtCommercial chart API.
51 \mainclass
51 \mainclass
52
52
53 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
53 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
54 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 handle the drawing manually.
55 handle the drawing manually.
56 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
56 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57
57
58 \image examples_percentbarchart_legend.png
58 \image examples_percentbarchart_legend.png
59
59
60 \sa QChart
60 \sa QChart
61 */
61 */
62
62
63 /*!
63 /*!
64 \enum QLegend::Alignment
64 \enum QLegend::Alignment
65
65
66 This enum describes the possible position for legend inside chart.
66 This enum describes the possible position for legend inside chart.
67
67
68 \value AlignmentTop
68 \value AlignmentTop
69 \value AlignmentBottom
69 \value AlignmentBottom
70 \value AlignmentLeft
70 \value AlignmentLeft
71 \value AlignmentRight
71 \value AlignmentRight
72 */
72 */
73
73
74 /*!
74 /*!
75 \fn qreal QLegend::minWidth() const
75 \fn qreal QLegend::minWidth() const
76 Returns minimum width of the legend
76 Returns minimum width of the legend
77 */
77 */
78
78
79 /*!
79 /*!
80 \fn qreal QLegend::minHeight() const
80 \fn qreal QLegend::minHeight() const
81 Returns minimum height of the legend
81 Returns minimum height of the legend
82 */
82 */
83
83
84 /*!
84 /*!
85 Constructs the legend object and sets the parent to \a parent
85 Constructs the legend object and sets the parent to \a parent
86 */
86 */
87
87
88 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
88 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
89 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
89 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
90 {
90 {
91 setZValue(ChartPresenter::LegendZValue);
91 setZValue(ChartPresenter::LegendZValue);
92 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
92 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
93 setEnabled(false); // By default legend is disabled
93 setEnabled(false); // By default legend is disabled
94 setVisible(false);
94 setVisible(false);
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries *,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries *,Domain*)));
96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries *)));
96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries *)));
97 }
97 }
98
98
99 /*!
100 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
101 */
99 QLegend::~QLegend()
102 QLegend::~QLegend()
100 {
103 {
101
102 }
104 }
103
105
104 /*!
106 /*!
105 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
107 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
106 */
108 */
107
109
108 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
109 {
111 {
110 Q_UNUSED(option)
112 Q_UNUSED(option)
111 Q_UNUSED(widget)
113 Q_UNUSED(widget)
112 if(!d_ptr->m_backgroundVisible) return;
114 if(!d_ptr->m_backgroundVisible) return;
113
115
114 painter->setOpacity(opacity());
116 painter->setOpacity(opacity());
115 painter->setPen(d_ptr->m_pen);
117 painter->setPen(d_ptr->m_pen);
116 painter->setBrush(d_ptr->m_brush);
118 painter->setBrush(d_ptr->m_brush);
117 painter->drawRect(boundingRect());
119 painter->drawRect(boundingRect());
118 }
120 }
119
121
120 /*!
122 /*!
121 Bounding rect of legend.
123 Bounding rect of legend.
122 */
124 */
123
125
124 QRectF QLegend::boundingRect() const
126 QRectF QLegend::boundingRect() const
125 {
127 {
126 return d_ptr->m_rect;
128 return d_ptr->m_rect;
127 }
129 }
128
130
129 /*!
131 /*!
130 Sets the \a brush of legend. Brush affects the background of legend.
132 Sets the \a brush of legend. Brush affects the background of legend.
131 */
133 */
132 void QLegend::setBrush(const QBrush &brush)
134 void QLegend::setBrush(const QBrush &brush)
133 {
135 {
134 if (d_ptr->m_brush != brush) {
136 if (d_ptr->m_brush != brush) {
135 d_ptr->m_brush = brush;
137 d_ptr->m_brush = brush;
136 update();
138 update();
137 }
139 }
138 }
140 }
139
141
140 /*!
142 /*!
141 Returns the brush used by legend.
143 Returns the brush used by legend.
142 */
144 */
143 QBrush QLegend::brush() const
145 QBrush QLegend::brush() const
144 {
146 {
145 return d_ptr->m_brush;
147 return d_ptr->m_brush;
146 }
148 }
147
149
148 /*!
150 /*!
149 Sets the \a pen of legend. Pen affects the legend borders.
151 Sets the \a pen of legend. Pen affects the legend borders.
150 */
152 */
151 void QLegend::setPen(const QPen &pen)
153 void QLegend::setPen(const QPen &pen)
152 {
154 {
153 if (d_ptr->m_pen != pen) {
155 if (d_ptr->m_pen != pen) {
154 d_ptr->m_pen = pen;
156 d_ptr->m_pen = pen;
155 update();
157 update();
156 }
158 }
157 }
159 }
158
160
159 /*!
161 /*!
160 Returns the pen used by legend
162 Returns the pen used by legend
161 */
163 */
162
164
163 QPen QLegend::pen() const
165 QPen QLegend::pen() const
164 {
166 {
165 return d_ptr->m_pen;
167 return d_ptr->m_pen;
166 }
168 }
167
169
168 /*!
170 /*!
169 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
171 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
170 \sa QLegend::Alignment
172 \sa QLegend::Alignment
171 */
173 */
172 void QLegend::setAlignment(QLegend::Alignments alignment)
174 void QLegend::setAlignment(QLegend::Alignments alignment)
173 {
175 {
174 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
176 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
175 d_ptr->m_alignment = alignment;
177 d_ptr->m_alignment = alignment;
176 d_ptr->updateLayout();
178 d_ptr->updateLayout();
177 }
179 }
178 }
180 }
179
181
180 /*!
182 /*!
181 Returns the preferred layout for legend
183 Returns the preferred layout for legend
182 */
184 */
183 QLegend::Alignments QLegend::alignment() const
185 QLegend::Alignments QLegend::alignment() const
184 {
186 {
185 return d_ptr->m_alignment;
187 return d_ptr->m_alignment;
186 }
188 }
187
189
188 /*!
190 /*!
189 Detaches the legend from chart. Chart won't change layout of the legend.
191 Detaches the legend from chart. Chart won't change layout of the legend.
190 */
192 */
191 void QLegend::detachFromChart()
193 void QLegend::detachFromChart()
192 {
194 {
193 d_ptr->m_attachedToChart = false;
195 d_ptr->m_attachedToChart = false;
194 }
196 }
195
197
196 /*!
198 /*!
197 Attaches the legend to chart. Chart may change layout of the legend.
199 Attaches the legend to chart. Chart may change layout of the legend.
198 */
200 */
199 void QLegend::attachToChart()
201 void QLegend::attachToChart()
200 {
202 {
201 d_ptr->m_attachedToChart = true;
203 d_ptr->m_attachedToChart = true;
202 }
204 }
203
205
204 /*!
206 /*!
205 Returns true, if legend is attached to chart.
207 Returns true, if legend is attached to chart.
206 */
208 */
207 bool QLegend::isAttachedToChart()
209 bool QLegend::isAttachedToChart()
208 {
210 {
209 return d_ptr->m_attachedToChart;
211 return d_ptr->m_attachedToChart;
210 }
212 }
211
213
214 /*!
215 Sets the legend's scrolling offset to value defined by \a point.
216 */
212 void QLegend::setOffset(const QPointF& point)
217 void QLegend::setOffset(const QPointF& point)
213 {
218 {
214 d_ptr->setOffset(point.x(),point.y());
219 d_ptr->setOffset(point.x(),point.y());
215 }
220 }
216
221
222 /*!
223 Returns the legend's scrolling offset.
224 */
217 QPointF QLegend::offset() const
225 QPointF QLegend::offset() const
218 {
226 {
219 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
227 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
220 }
228 }
221
229
222 /*!
230 /*!
223 Sets the visibility of legend background to \a visible
231 Sets the visibility of legend background to \a visible
224 */
232 */
225 void QLegend::setBackgroundVisible(bool visible)
233 void QLegend::setBackgroundVisible(bool visible)
226 {
234 {
227 if(d_ptr->m_backgroundVisible!=visible)
235 if(d_ptr->m_backgroundVisible!=visible)
228 {
236 {
229 d_ptr->m_backgroundVisible=visible;
237 d_ptr->m_backgroundVisible=visible;
230 update();
238 update();
231 }
239 }
232 }
240 }
233
241
234 /*!
242 /*!
235 Returns the visibility of legend background
243 Returns the visibility of legend background
236 */
244 */
237 bool QLegend::isBackgroundVisible() const
245 bool QLegend::isBackgroundVisible() const
238 {
246 {
239 return d_ptr->m_backgroundVisible;
247 return d_ptr->m_backgroundVisible;
240 }
248 }
241
249
242 /*!
250 /*!
243 \internal \a event see QGraphicsWidget for details
251 \internal \a event see QGraphicsWidget for details
244 */
252 */
245 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
253 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
246 {
254 {
247 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
255 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
248 QGraphicsWidget::resizeEvent(event);
256 QGraphicsWidget::resizeEvent(event);
249 if(d_ptr->m_rect != rect) {
257 if(d_ptr->m_rect != rect) {
250 d_ptr->m_rect = rect;
258 d_ptr->m_rect = rect;
251 d_ptr->updateLayout();
259 d_ptr->updateLayout();
252 }
260 }
253 }
261 }
254
262
255 /*!
263 /*!
256 \internal \a event see QGraphicsWidget for details
264 \internal \a event see QGraphicsWidget for details
257 */
265 */
258 void QLegend::hideEvent(QHideEvent *event)
266 void QLegend::hideEvent(QHideEvent *event)
259 {
267 {
260 QGraphicsWidget::hideEvent(event);
268 QGraphicsWidget::hideEvent(event);
261 setEnabled(false);
269 setEnabled(false);
262 d_ptr->updateLayout();
270 d_ptr->updateLayout();
263 }
271 }
264
272
265 /*!
273 /*!
266 \internal \a event see QGraphicsWidget for details
274 \internal \a event see QGraphicsWidget for details
267 */
275 */
268 void QLegend::showEvent(QShowEvent *event)
276 void QLegend::showEvent(QShowEvent *event)
269 {
277 {
270 QGraphicsWidget::showEvent(event);
278 QGraphicsWidget::showEvent(event);
271 setEnabled(true);
279 setEnabled(true);
272 d_ptr->updateLayout();
280 d_ptr->updateLayout();
273 }
281 }
274
282
275 qreal QLegend::minWidth() const
283 qreal QLegend::minWidth() const
276 {
284 {
277 return d_ptr->m_minWidth;
285 return d_ptr->m_minWidth;
278 }
286 }
279
287
280 qreal QLegend::minHeight() const
288 qreal QLegend::minHeight() const
281 {
289 {
282 return d_ptr->m_minHeight;
290 return d_ptr->m_minHeight;
283 }
291 }
284
292
285 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
286
294
287 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
295 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
288 q_ptr(q),
296 q_ptr(q),
289 m_presenter(presenter),
297 m_presenter(presenter),
290 m_markers(new QGraphicsItemGroup(q)),
298 m_markers(new QGraphicsItemGroup(q)),
291 m_alignment(QLegend::AlignmentTop),
299 m_alignment(QLegend::AlignmentTop),
292 m_offsetX(0),
300 m_offsetX(0),
293 m_offsetY(0),
301 m_offsetY(0),
294 m_minWidth(0),
302 m_minWidth(0),
295 m_minHeight(0),
303 m_minHeight(0),
296 m_width(0),
304 m_width(0),
297 m_height(0),
305 m_height(0),
298 m_attachedToChart(true),
306 m_attachedToChart(true),
299 m_backgroundVisible(false)
307 m_backgroundVisible(false)
300 {
308 {
301
309
302 }
310 }
303
311
304 QLegendPrivate::~QLegendPrivate()
312 QLegendPrivate::~QLegendPrivate()
305 {
313 {
306
314
307 }
315 }
308
316
309 void QLegendPrivate::setOffset(qreal x, qreal y)
317 void QLegendPrivate::setOffset(qreal x, qreal y)
310 {
318 {
311
319
312 switch(m_alignment) {
320 switch(m_alignment) {
313
321
314 case QLegend::AlignmentTop:
322 case QLegend::AlignmentTop:
315 case QLegend::AlignmentBottom: {
323 case QLegend::AlignmentBottom: {
316 if(m_width<=m_rect.width()) return;
324 if(m_width<=m_rect.width()) return;
317
325
318 if (x != m_offsetX) {
326 if (x != m_offsetX) {
319 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
327 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
320 m_markers->setPos(-m_offsetX,m_rect.top());
328 m_markers->setPos(-m_offsetX,m_rect.top());
321 }
329 }
322 break;
330 break;
323 }
331 }
324 case QLegend::AlignmentLeft:
332 case QLegend::AlignmentLeft:
325 case QLegend::AlignmentRight: {
333 case QLegend::AlignmentRight: {
326
334
327 if(m_height<=m_rect.height()) return;
335 if(m_height<=m_rect.height()) return;
328
336
329 if (y != m_offsetY) {
337 if (y != m_offsetY) {
330 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
338 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
331 m_markers->setPos(m_rect.left(),-m_offsetY);
339 m_markers->setPos(m_rect.left(),-m_offsetY);
332 }
340 }
333 break;
341 break;
334 }
342 }
335 }
343 }
336 }
344 }
337
345
338
346
339 void QLegendPrivate::updateLayout()
347 void QLegendPrivate::updateLayout()
340 {
348 {
341 m_offsetX=0;
349 m_offsetX=0;
342 QList<QGraphicsItem *> items = m_markers->childItems();
350 QList<QGraphicsItem *> items = m_markers->childItems();
343
351
344 if(items.isEmpty()) return;
352 if(items.isEmpty()) return;
345
353
346 m_minWidth=0;
354 m_minWidth=0;
347 m_minHeight=0;
355 m_minHeight=0;
348
356
349 switch(m_alignment) {
357 switch(m_alignment) {
350
358
351 case QLegend::AlignmentTop:
359 case QLegend::AlignmentTop:
352 case QLegend::AlignmentBottom: {
360 case QLegend::AlignmentBottom: {
353 QPointF point = m_rect.topLeft();
361 QPointF point = m_rect.topLeft();
354 m_width = 0;
362 m_width = 0;
355 foreach (QGraphicsItem *item, items) {
363 foreach (QGraphicsItem *item, items) {
356 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
364 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
357 const QRectF& rect = item->boundingRect();
365 const QRectF& rect = item->boundingRect();
358 qreal w = rect.width();
366 qreal w = rect.width();
359 m_minWidth=qMax(m_minWidth,w);
367 m_minWidth=qMax(m_minWidth,w);
360 m_minHeight=qMax(m_minHeight,rect.height());
368 m_minHeight=qMax(m_minHeight,rect.height());
361 m_width+=w;
369 m_width+=w;
362 point.setX(point.x() + w);
370 point.setX(point.x() + w);
363 }
371 }
364 if(m_width<m_rect.width()) {
372 if(m_width<m_rect.width()) {
365 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
373 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
366 }
374 }
367 else {
375 else {
368 m_markers->setPos(m_rect.topLeft());
376 m_markers->setPos(m_rect.topLeft());
369 }
377 }
370 m_height=m_minHeight;
378 m_height=m_minHeight;
371 }
379 }
372 break;
380 break;
373 case QLegend::AlignmentLeft:
381 case QLegend::AlignmentLeft:
374 case QLegend::AlignmentRight: {
382 case QLegend::AlignmentRight: {
375 QPointF point = m_rect.topLeft();
383 QPointF point = m_rect.topLeft();
376 m_height = 0;
384 m_height = 0;
377 foreach (QGraphicsItem *item, items) {
385 foreach (QGraphicsItem *item, items) {
378 item->setPos(point);
386 item->setPos(point);
379 const QRectF& rect = item->boundingRect();
387 const QRectF& rect = item->boundingRect();
380 qreal h = rect.height();
388 qreal h = rect.height();
381 m_minWidth=qMax(m_minWidth,rect.width());
389 m_minWidth=qMax(m_minWidth,rect.width());
382 m_minHeight=qMax(m_minHeight,h);
390 m_minHeight=qMax(m_minHeight,h);
383 m_height+=h;
391 m_height+=h;
384 point.setY(point.y() + h);
392 point.setY(point.y() + h);
385 }
393 }
386 if(m_height<m_rect.height()) {
394 if(m_height<m_rect.height()) {
387 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
395 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
388 }
396 }
389 else {
397 else {
390 m_markers->setPos(m_rect.topLeft());
398 m_markers->setPos(m_rect.topLeft());
391 }
399 }
392 m_width=m_minWidth;
400 m_width=m_minWidth;
393 }
401 }
394 break;
402 break;
395 }
403 }
396
404
397 m_presenter->updateLayout();
405 m_presenter->updateLayout();
398 }
406 }
399
407
400 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
408 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
401 {
409 {
402 Q_UNUSED(domain)
410 Q_UNUSED(domain)
403
411
404 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
412 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
405 foreach(LegendMarker* marker , markers)
413 foreach(LegendMarker* marker , markers)
406 m_markers->addToGroup(marker);
414 m_markers->addToGroup(marker);
407
415
408 if(series->type() == QAbstractSeries::SeriesTypePie)
416 if(series->type() == QAbstractSeries::SeriesTypePie)
409 {
417 {
410 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
418 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
411 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
419 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
412 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
420 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
413 }
421 }
414
422
415 updateLayout();
423 updateLayout();
416 }
424 }
417
425
418 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
426 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
419 {
427 {
420
428
421 QList<QGraphicsItem *> items = m_markers->childItems();
429 QList<QGraphicsItem *> items = m_markers->childItems();
422
430
423 foreach (QGraphicsItem *markers, items) {
431 foreach (QGraphicsItem *markers, items) {
424 LegendMarker *marker = static_cast<LegendMarker*>(markers);
432 LegendMarker *marker = static_cast<LegendMarker*>(markers);
425 if (marker->series() == series) {
433 if (marker->series() == series) {
426 delete marker;
434 delete marker;
427 }
435 }
428 }
436 }
429
437
430 if(series->type() == QAbstractSeries::SeriesTypePie)
438 if(series->type() == QAbstractSeries::SeriesTypePie)
431 {
439 {
432 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
440 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
433 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
441 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
434 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
442 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
435 }
443 }
436
444
437 updateLayout();
445 updateLayout();
438 }
446 }
439
447
440 void QLegendPrivate::handleUpdateSeries()
448 void QLegendPrivate::handleUpdateSeries()
441 {
449 {
442 //TODO: reimplement to be optimal
450 //TODO: reimplement to be optimal
443 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
451 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
444 Q_ASSERT(series);
452 Q_ASSERT(series);
445 handleSeriesRemoved(series);
453 handleSeriesRemoved(series);
446 handleSeriesAdded(series,0);
454 handleSeriesAdded(series,0);
447 }
455 }
448
456
449 #include "moc_qlegend.cpp"
457 #include "moc_qlegend.cpp"
450 #include "moc_qlegend_p.cpp"
458 #include "moc_qlegend_p.cpp"
451
459
452 QTCOMMERCIALCHART_END_NAMESPACE
460 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,428 +1,434
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 "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "legendscroller_p.h"
23 #include "legendscroller_p.h"
24 #include "qlegend_p.h"
24 #include "qlegend_p.h"
25 #include <QGraphicsScene>
25 #include <QGraphicsScene>
26 #include <QGraphicsSceneResizeEvent>
26 #include <QGraphicsSceneResizeEvent>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 /*!
30 /*!
31 \enum QChart::ChartTheme
31 \enum QChart::ChartTheme
32
32
33 This enum describes the theme used by the chart.
33 This enum describes the theme used by the chart.
34
34
35 \value ChartThemeLight The default theme
35 \value ChartThemeLight The default theme
36 \value ChartThemeBlueCerulean
36 \value ChartThemeBlueCerulean
37 \value ChartThemeDark
37 \value ChartThemeDark
38 \value ChartThemeBrownSand
38 \value ChartThemeBrownSand
39 \value ChartThemeBlueNcs
39 \value ChartThemeBlueNcs
40 \value ChartThemeHighContrast
40 \value ChartThemeHighContrast
41 \value ChartThemeBlueIcy
41 \value ChartThemeBlueIcy
42 */
42 */
43
43
44 /*!
44 /*!
45 \enum QChart::AnimationOption
45 \enum QChart::AnimationOption
46
46
47 For enabling/disabling animations. Defaults to NoAnimation.
47 For enabling/disabling animations. Defaults to NoAnimation.
48
48
49 \value NoAnimation
49 \value NoAnimation
50 \value GridAxisAnimations
50 \value GridAxisAnimations
51 \value SeriesAnimations
51 \value SeriesAnimations
52 \value AllAnimations
52 \value AllAnimations
53 */
53 */
54
54
55 /*!
55 /*!
56 \class QChart
56 \class QChart
57 \brief QtCommercial chart API.
57 \brief QtCommercial chart API.
58
58
59 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
59 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
60 representation of different types of QChartSeries and other chart related objects like
60 representation of different types of QChartSeries and other chart related objects like
61 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
61 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
62 convenience class QChartView instead of QChart.
62 convenience class QChartView instead of QChart.
63 \sa QChartView
63 \sa QChartView
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
67 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
68 */
68 */
69 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
69 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
70 d_ptr(new QChartPrivate())
70 d_ptr(new QChartPrivate())
71 {
71 {
72 d_ptr->m_dataset = new ChartDataSet(this);
72 d_ptr->m_dataset = new ChartDataSet(this);
73 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
73 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
74 d_ptr->createConnections();
74 d_ptr->createConnections();
75 d_ptr->m_legend = new LegendScroller(this);
75 d_ptr->m_legend = new LegendScroller(this);
76 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
76 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
77 }
77 }
78
78
79 /*!
79 /*!
80 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
80 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
81 */
81 */
82 QChart::~QChart()
82 QChart::~QChart()
83 {
83 {
84 //delete first presenter , since this is a root of all the graphical items
84 //delete first presenter , since this is a root of all the graphical items
85 delete d_ptr->m_presenter;
85 delete d_ptr->m_presenter;
86 d_ptr->m_presenter=0;
86 d_ptr->m_presenter=0;
87 }
87 }
88
88
89 /*!
89 /*!
90 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
90 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
91 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
91 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
92 the y axis).
92 the y axis).
93 */
93 */
94 void QChart::addSeries(QAbstractSeries *series, QChartAxis *axisY)
94 void QChart::addSeries(QAbstractSeries *series, QChartAxis *axisY)
95 {
95 {
96 Q_ASSERT(series);
96 Q_ASSERT(series);
97 d_ptr->m_dataset->addSeries(series, axisY);
97 d_ptr->m_dataset->addSeries(series, axisY);
98 }
98 }
99
99
100 /*!
100 /*!
101 Removes the \a series specified in a perameter from the QChartView.
101 Removes the \a series specified in a perameter from the QChartView.
102 It releses its ownership of the specified QChartSeries object.
102 It releses its ownership of the specified QChartSeries object.
103 It does not delete the pointed QChartSeries data object
103 It does not delete the pointed QChartSeries data object
104 \sa addSeries(), removeAllSeries()
104 \sa addSeries(), removeAllSeries()
105 */
105 */
106 void QChart::removeSeries(QAbstractSeries *series)
106 void QChart::removeSeries(QAbstractSeries *series)
107 {
107 {
108 Q_ASSERT(series);
108 Q_ASSERT(series);
109 d_ptr->m_dataset->removeSeries(series);
109 d_ptr->m_dataset->removeSeries(series);
110 }
110 }
111
111
112 /*!
112 /*!
113 Removes all the QChartSeries that have been added to the QChartView
113 Removes all the QChartSeries that have been added to the QChartView
114 It also deletes the pointed QChartSeries data objects
114 It also deletes the pointed QChartSeries data objects
115 \sa addSeries(), removeSeries()
115 \sa addSeries(), removeSeries()
116 */
116 */
117 void QChart::removeAllSeries()
117 void QChart::removeAllSeries()
118 {
118 {
119 d_ptr->m_dataset->removeAllSeries();
119 d_ptr->m_dataset->removeAllSeries();
120 }
120 }
121
121
122 /*!
122 /*!
123 Sets the \a brush that is used for painting the background of the chart area.
123 Sets the \a brush that is used for painting the background of the chart area.
124 */
124 */
125 void QChart::setBackgroundBrush(const QBrush& brush)
125 void QChart::setBackgroundBrush(const QBrush& brush)
126 {
126 {
127 //TODO: refactor me
127 //TODO: refactor me
128 d_ptr->m_presenter->createChartBackgroundItem();
128 d_ptr->m_presenter->createChartBackgroundItem();
129 d_ptr->m_presenter->m_backgroundItem->setBrush(brush);
129 d_ptr->m_presenter->m_backgroundItem->setBrush(brush);
130 d_ptr->m_presenter->m_backgroundItem->update();
130 d_ptr->m_presenter->m_backgroundItem->update();
131 }
131 }
132
132
133 /*!
133 /*!
134 Gets the brush that is used for painting the background of the chart area.
134 Gets the brush that is used for painting the background of the chart area.
135 */
135 */
136 QBrush QChart::backgroundBrush() const
136 QBrush QChart::backgroundBrush() const
137 {
137 {
138 //TODO: refactor me
138 //TODO: refactor me
139 if (!d_ptr->m_presenter->m_backgroundItem) return QBrush();
139 if (!d_ptr->m_presenter->m_backgroundItem) return QBrush();
140 return (d_ptr->m_presenter->m_backgroundItem)->brush();
140 return (d_ptr->m_presenter->m_backgroundItem)->brush();
141 }
141 }
142
142
143 /*!
143 /*!
144 Sets the \a pen that is used for painting the background of the chart area.
144 Sets the \a pen that is used for painting the background of the chart area.
145 */
145 */
146 void QChart::setBackgroundPen(const QPen& pen)
146 void QChart::setBackgroundPen(const QPen& pen)
147 {
147 {
148 //TODO: refactor me
148 //TODO: refactor me
149 d_ptr->m_presenter->createChartBackgroundItem();
149 d_ptr->m_presenter->createChartBackgroundItem();
150 d_ptr->m_presenter->m_backgroundItem->setPen(pen);
150 d_ptr->m_presenter->m_backgroundItem->setPen(pen);
151 d_ptr->m_presenter->m_backgroundItem->update();
151 d_ptr->m_presenter->m_backgroundItem->update();
152 }
152 }
153
153
154 /*!
154 /*!
155 Gets the pen that is used for painting the background of the chart area.
155 Gets the pen that is used for painting the background of the chart area.
156 */
156 */
157 QPen QChart::backgroundPen() const
157 QPen QChart::backgroundPen() const
158 {
158 {
159 //TODO: refactor me
159 //TODO: refactor me
160 if (!d_ptr->m_presenter->m_backgroundItem) return QPen();
160 if (!d_ptr->m_presenter->m_backgroundItem) return QPen();
161 return d_ptr->m_presenter->m_backgroundItem->pen();
161 return d_ptr->m_presenter->m_backgroundItem->pen();
162 }
162 }
163
163
164 /*!
164 /*!
165 Sets the chart \a title. The description text that is drawn above the chart.
165 Sets the chart \a title. The description text that is drawn above the chart.
166 */
166 */
167 void QChart::setTitle(const QString& title)
167 void QChart::setTitle(const QString& title)
168 {
168 {
169 //TODO: refactor me
169 //TODO: refactor me
170 d_ptr->m_presenter->createChartTitleItem();
170 d_ptr->m_presenter->createChartTitleItem();
171 d_ptr->m_presenter->m_titleItem->setText(title);
171 d_ptr->m_presenter->m_titleItem->setText(title);
172 d_ptr->m_presenter->updateLayout();
172 d_ptr->m_presenter->updateLayout();
173 }
173 }
174
174
175 /*!
175 /*!
176 Returns the chart title. The description text that is drawn above the chart.
176 Returns the chart title. The description text that is drawn above the chart.
177 */
177 */
178 QString QChart::title() const
178 QString QChart::title() const
179 {
179 {
180 //TODO: refactor me
180 //TODO: refactor me
181 if (d_ptr->m_presenter->m_titleItem)
181 if (d_ptr->m_presenter->m_titleItem)
182 return d_ptr->m_presenter->m_titleItem->text();
182 return d_ptr->m_presenter->m_titleItem->text();
183 else
183 else
184 return QString();
184 return QString();
185 }
185 }
186
186
187 /*!
187 /*!
188 Sets the \a font that is used for drawing the chart description text that is rendered above the chart.
188 Sets the \a font that is used for drawing the chart description text that is rendered above the chart.
189 */
189 */
190 void QChart::setTitleFont(const QFont& font)
190 void QChart::setTitleFont(const QFont& font)
191 {
191 {
192 //TODO: refactor me
192 //TODO: refactor me
193 d_ptr->m_presenter->createChartTitleItem();
193 d_ptr->m_presenter->createChartTitleItem();
194 d_ptr->m_presenter->m_titleItem->setFont(font);
194 d_ptr->m_presenter->m_titleItem->setFont(font);
195 d_ptr->m_presenter->updateLayout();
195 d_ptr->m_presenter->updateLayout();
196 }
196 }
197
197
198 /*!
198 /*!
199 Gets the font that is used for drawing the chart description text that is rendered above the chart.
199 Gets the font that is used for drawing the chart description text that is rendered above the chart.
200 */
200 */
201 QFont QChart::titleFont() const
201 QFont QChart::titleFont() const
202 {
202 {
203 if (d_ptr->m_presenter->m_titleItem)
203 if (d_ptr->m_presenter->m_titleItem)
204 return d_ptr->m_presenter->m_titleItem->font();
204 return d_ptr->m_presenter->m_titleItem->font();
205 else
205 else
206 return QFont();
206 return QFont();
207 }
207 }
208
208
209 /*!
209 /*!
210 Sets the \a brush used for rendering the title text.
210 Sets the \a brush used for rendering the title text.
211 */
211 */
212 void QChart::setTitleBrush(const QBrush &brush)
212 void QChart::setTitleBrush(const QBrush &brush)
213 {
213 {
214 //TODO: refactor me
214 //TODO: refactor me
215 d_ptr->m_presenter->createChartTitleItem();
215 d_ptr->m_presenter->createChartTitleItem();
216 d_ptr->m_presenter->m_titleItem->setBrush(brush);
216 d_ptr->m_presenter->m_titleItem->setBrush(brush);
217 d_ptr->m_presenter->updateLayout();
217 d_ptr->m_presenter->updateLayout();
218 }
218 }
219
219
220 /*!
220 /*!
221 Returns the brush used for rendering the title text.
221 Returns the brush used for rendering the title text.
222 */
222 */
223 QBrush QChart::titleBrush() const
223 QBrush QChart::titleBrush() const
224 {
224 {
225 //TODO: refactor me
225 //TODO: refactor me
226 if (!d_ptr->m_presenter->m_titleItem) return QBrush();
226 if (!d_ptr->m_presenter->m_titleItem) return QBrush();
227 return d_ptr->m_presenter->m_titleItem->brush();
227 return d_ptr->m_presenter->m_titleItem->brush();
228 }
228 }
229
229
230 /*!
230 /*!
231 Sets the \a theme used by the chart for rendering the graphical representation of the data
231 Sets the \a theme used by the chart for rendering the graphical representation of the data
232 \sa theme()
232 \sa theme()
233 */
233 */
234 void QChart::setTheme(QChart::ChartTheme theme)
234 void QChart::setTheme(QChart::ChartTheme theme)
235 {
235 {
236 d_ptr->m_presenter->setTheme(theme);
236 d_ptr->m_presenter->setTheme(theme);
237 }
237 }
238
238
239 /*!
239 /*!
240 Returns the theme enum used by the chart.
240 Returns the theme enum used by the chart.
241 \sa ChartTheme, setTheme()
241 \sa ChartTheme, setTheme()
242 */
242 */
243 QChart::ChartTheme QChart::theme() const
243 QChart::ChartTheme QChart::theme() const
244 {
244 {
245 return d_ptr->m_presenter->theme();
245 return d_ptr->m_presenter->theme();
246 }
246 }
247
247
248 /*!
248 /*!
249 Zooms in the view by a factor of 2
249 Zooms in the view by a factor of 2
250 */
250 */
251 void QChart::zoomIn()
251 void QChart::zoomIn()
252 {
252 {
253 d_ptr->m_presenter->zoomIn();
253 d_ptr->m_presenter->zoomIn();
254 }
254 }
255
255
256 /*!
256 /*!
257 Zooms in the view to a maximum level at which \a rect is still fully visible.
257 Zooms in the view to a maximum level at which \a rect is still fully visible.
258 */
258 */
259 void QChart::zoomIn(const QRectF& rect)
259 void QChart::zoomIn(const QRectF& rect)
260 {
260 {
261 if (!rect.isValid()) return;
261 if (!rect.isValid()) return;
262 d_ptr->m_presenter->zoomIn(rect);
262 d_ptr->m_presenter->zoomIn(rect);
263 }
263 }
264
264
265 /*!
265 /*!
266 Restores the view zoom level to the previous one.
266 Restores the view zoom level to the previous one.
267 */
267 */
268 void QChart::zoomOut()
268 void QChart::zoomOut()
269 {
269 {
270 d_ptr->m_presenter->zoomOut();
270 d_ptr->m_presenter->zoomOut();
271 }
271 }
272
272
273 /*!
273 /*!
274 Returns the pointer to the x axis object of the chart
274 Returns the pointer to the x axis object of the chart
275 */
275 */
276 QChartAxis* QChart::axisX() const
276 QChartAxis* QChart::axisX() const
277 {
277 {
278 return d_ptr->m_dataset->axisX();
278 return d_ptr->m_dataset->axisX();
279 }
279 }
280
280
281 /*!
281 /*!
282 Returns the pointer to the y axis object of the \a series
282 Returns the pointer to the y axis object of the \a series
283 If no \a series is provided then default Y axis of the chart is returned.
283 If no \a series is provided then default Y axis of the chart is returned.
284 */
284 */
285 QChartAxis* QChart::axisY(QAbstractSeries *series) const
285 QChartAxis* QChart::axisY(QAbstractSeries *series) const
286 {
286 {
287 return d_ptr->m_dataset->axisY(series);
287 return d_ptr->m_dataset->axisY(series);
288 }
288 }
289
289
290 /*!
290 /*!
291 Returns the legend object of the chart. Ownership stays in chart.
291 Returns the legend object of the chart. Ownership stays in chart.
292 */
292 */
293 QLegend* QChart::legend() const
293 QLegend* QChart::legend() const
294 {
294 {
295 return d_ptr->m_legend;
295 return d_ptr->m_legend;
296 }
296 }
297
297
298 /*!
298 /*!
299 Returns the rect that contains information about margins (distance between chart widget edge and axes).
299 Returns the rect that contains information about margins (distance between chart widget edge and axes).
300 Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
300 Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
301 */
301 */
302 QRectF QChart::margins() const
302 QRectF QChart::margins() const
303 {
303 {
304 return d_ptr->m_presenter->margins();
304 return d_ptr->m_presenter->margins();
305 }
305 }
306
306
307
307
308 /*!
308 /*!
309 Resizes and updates the chart area using the \a event data
309 Resizes and updates the chart area using the \a event data
310 */
310 */
311 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
311 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
312 {
312 {
313 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
313 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
314 QGraphicsWidget::resizeEvent(event);
314 QGraphicsWidget::resizeEvent(event);
315 d_ptr->m_presenter->setGeometry(d_ptr->m_rect);
315 d_ptr->m_presenter->setGeometry(d_ptr->m_rect);
316 }
316 }
317
317
318 /*!
318 /*!
319 Sets animation \a options for the chart
319 Sets animation \a options for the chart
320 */
320 */
321 void QChart::setAnimationOptions(AnimationOptions options)
321 void QChart::setAnimationOptions(AnimationOptions options)
322 {
322 {
323 d_ptr->m_presenter->setAnimationOptions(options);
323 d_ptr->m_presenter->setAnimationOptions(options);
324 }
324 }
325
325
326 /*!
326 /*!
327 Returns animation options for the chart
327 Returns animation options for the chart
328 */
328 */
329 QChart::AnimationOptions QChart::animationOptions() const
329 QChart::AnimationOptions QChart::animationOptions() const
330 {
330 {
331 return d_ptr->m_presenter->animationOptions();
331 return d_ptr->m_presenter->animationOptions();
332 }
332 }
333
333
334 /*!
334 /*!
335 Scrolls the visible area of the chart to the left by the distance between two x axis ticks
335 Scrolls the visible area of the chart to the left by the distance between two x axis ticks
336 */
336 */
337 void QChart::scrollLeft()
337 void QChart::scrollLeft()
338 {
338 {
339 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
339 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
340 }
340 }
341
341
342 /*!
342 /*!
343 Scrolls the visible area of the chart to the right by the distance between two x axis ticks
343 Scrolls the visible area of the chart to the right by the distance between two x axis ticks
344 */
344 */
345 void QChart::scrollRight()
345 void QChart::scrollRight()
346 {
346 {
347 d_ptr->m_presenter->scroll(d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
347 d_ptr->m_presenter->scroll(d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
348 }
348 }
349
349
350 /*!
350 /*!
351 Scrolls the visible area of the chart up by the distance between two y axis ticks
351 Scrolls the visible area of the chart up by the distance between two y axis ticks
352 */
352 */
353 void QChart::scrollUp()
353 void QChart::scrollUp()
354 {
354 {
355 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
355 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
356 }
356 }
357
357
358 /*!
358 /*!
359 Scrolls the visible area of the chart down by the distance between two y axis ticks
359 Scrolls the visible area of the chart down by the distance between two y axis ticks
360 */
360 */
361 void QChart::scrollDown()
361 void QChart::scrollDown()
362 {
362 {
363 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
363 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
364 }
364 }
365
365
366 /*!
366 /*!
367 Sets the chart background visibility state to \a visible
367 Sets the chart background visibility state to \a visible
368 */
368 */
369 void QChart::setBackgroundVisible(bool visible)
369 void QChart::setBackgroundVisible(bool visible)
370 {
370 {
371 //TODO: refactor me
371 //TODO: refactor me
372 d_ptr->m_presenter->createChartBackgroundItem();
372 d_ptr->m_presenter->createChartBackgroundItem();
373 d_ptr->m_presenter->m_backgroundItem->setVisible(visible);
373 d_ptr->m_presenter->m_backgroundItem->setVisible(visible);
374 }
374 }
375
375
376 /*!
376 /*!
377 Returns the chart's background visibility state
377 Returns the chart's background visibility state
378 */
378 */
379 bool QChart::isBackgroundVisible() const
379 bool QChart::isBackgroundVisible() const
380 {
380 {
381 //TODO: refactor me
381 //TODO: refactor me
382 if (!d_ptr->m_presenter->m_backgroundItem)
382 if (!d_ptr->m_presenter->m_backgroundItem)
383 return false;
383 return false;
384
384
385 return d_ptr->m_presenter->m_backgroundItem->isVisible();
385 return d_ptr->m_presenter->m_backgroundItem->isVisible();
386 }
386 }
387
387
388 /*!
389 Sets the background drop shadow effect state to \a enabled.
390 */
388 void QChart::setBackgroundDropShadowEnabled(bool enabled)
391 void QChart::setBackgroundDropShadowEnabled(bool enabled)
389 {
392 {
390 d_ptr->m_presenter->createChartBackgroundItem();
393 d_ptr->m_presenter->createChartBackgroundItem();
391 d_ptr->m_presenter->m_backgroundItem->setDropShadowEnabled(enabled);
394 d_ptr->m_presenter->m_backgroundItem->setDropShadowEnabled(enabled);
392 }
395 }
393
396
397 /*!
398 Returns true if the drop shadow effect is enabled for the chart background.
399 */
394 bool QChart::isBackgroundDropShadowEnabled() const
400 bool QChart::isBackgroundDropShadowEnabled() const
395 {
401 {
396 if (!d_ptr->m_presenter->m_backgroundItem)
402 if (!d_ptr->m_presenter->m_backgroundItem)
397 return false;
403 return false;
398
404
399 return d_ptr->m_presenter->m_backgroundItem->isDropShadowEnabled();
405 return d_ptr->m_presenter->m_backgroundItem->isDropShadowEnabled();
400 }
406 }
401
407
402 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
403
409
404 QChartPrivate::QChartPrivate():
410 QChartPrivate::QChartPrivate():
405 m_legend(0),
411 m_legend(0),
406 m_dataset(0),
412 m_dataset(0),
407 m_presenter(0)
413 m_presenter(0)
408 {
414 {
409
415
410 }
416 }
411
417
412 QChartPrivate::~QChartPrivate()
418 QChartPrivate::~QChartPrivate()
413 {
419 {
414
420
415 }
421 }
416
422
417 void QChartPrivate::createConnections()
423 void QChartPrivate::createConnections()
418 {
424 {
419
425
420 QObject::connect(m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),m_presenter,SLOT(handleSeriesAdded(QAbstractSeries *, Domain *)));
426 QObject::connect(m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),m_presenter,SLOT(handleSeriesAdded(QAbstractSeries *, Domain *)));
421 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),m_presenter,SLOT(handleSeriesRemoved(QAbstractSeries *)));
427 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),m_presenter,SLOT(handleSeriesRemoved(QAbstractSeries *)));
422 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
428 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
423 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),m_presenter,SLOT(handleAxisRemoved(QChartAxis*)));
429 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),m_presenter,SLOT(handleAxisRemoved(QChartAxis*)));
424 }
430 }
425
431
426 #include "moc_qchart.cpp"
432 #include "moc_qchart.cpp"
427
433
428 QTCOMMERCIALCHART_END_NAMESPACE
434 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,218 +1,218
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 "qchartview.h"
21 #include "qchartview.h"
22 #include "qchartview_p.h"
22 #include "qchartview_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include <QGraphicsScene>
24 #include <QGraphicsScene>
25 #include <QRubberBand>
25 #include <QRubberBand>
26
26
27 /*!
27 /*!
28 \enum QChartView::RubberBand
28 \enum QChartView::RubberBand
29
29
30 This enum describes the different types of rubber bands that can be used for zoom rect selection
30 This enum describes the different types of rubber bands that can be used for zoom rect selection
31
31
32 \value NoRubberBand
32 \value NoRubberBand
33 \value VerticalRubberBand
33 \value VerticalRubberBand
34 \value HorizonalRubberBand
34 \value HorizonalRubberBand
35 \value RectangleRubberBand
35 \value RectangleRubberBand
36 */
36 */
37
37
38 /*!
38 /*!
39 \class QChartView
39 \class QChartView
40 \brief Standalone charting widget.
40 \brief Standalone charting widget.
41
41
42 QChartView is a standalone widget that can display charts. It does not require separate
42 QChartView is a standalone widget that can display charts. It does not require separate
43 QGraphicsScene to work. It manages the graphical representation of different types of
43 QGraphicsScene to work. It manages the graphical representation of different types of
44 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
44 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
45 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
45 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
46
46
47 \sa QChart
47 \sa QChart
48 */
48 */
49
49
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
51
51
52 /*!
52 /*!
53 Constructs a chartView object which is a child of a\a parent.
53 Constructs a chartView object with parent \a parent to display a \a chart.
54 */
54 */
55 QChartView::QChartView(QChart *chart,QWidget *parent) :
55 QChartView::QChartView(QChart *chart,QWidget *parent) :
56 QGraphicsView(parent),
56 QGraphicsView(parent),
57 d_ptr(new QChartViewPrivate())
57 d_ptr(new QChartViewPrivate())
58 {
58 {
59 Q_ASSERT(chart);
59 Q_ASSERT(chart);
60 d_ptr->m_scene = new QGraphicsScene(this);
60 d_ptr->m_scene = new QGraphicsScene(this);
61 d_ptr->m_chart = chart;
61 d_ptr->m_chart = chart;
62 setFrameShape(QFrame::NoFrame);
62 setFrameShape(QFrame::NoFrame);
63 setBackgroundRole(QPalette::Window);
63 setBackgroundRole(QPalette::Window);
64 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
64 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
65 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
65 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
66 setScene(d_ptr->m_scene);
66 setScene(d_ptr->m_scene);
67 d_ptr->m_scene->addItem(chart);
67 d_ptr->m_scene->addItem(chart);
68 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
68 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
69 }
69 }
70
70
71
71
72 /*!
72 /*!
73 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
73 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
74 */
74 */
75 QChartView::~QChartView()
75 QChartView::~QChartView()
76 {
76 {
77 }
77 }
78
78
79 /*!
79 /*!
80 Returns the pointer to the associated chart
80 Returns the pointer to the associated chart
81 */
81 */
82 QChart* QChartView::chart() const
82 QChart* QChartView::chart() const
83 {
83 {
84 return d_ptr->m_chart;
84 return d_ptr->m_chart;
85 }
85 }
86
86
87 /*!
87 /*!
88 Sets the RubberBandPlicy to \a rubberBand. Selected policy determines the way zooming is performed.
88 Sets the RubberBandPlicy to \a rubberBand. Selected policy determines the way zooming is performed.
89 */
89 */
90 void QChartView::setRubberBand(const RubberBands& rubberBand)
90 void QChartView::setRubberBand(const RubberBands& rubberBand)
91 {
91 {
92 d_ptr->m_rubberBandFlags=rubberBand;
92 d_ptr->m_rubberBandFlags=rubberBand;
93
93
94 if (!d_ptr->m_rubberBandFlags) {
94 if (!d_ptr->m_rubberBandFlags) {
95 delete d_ptr->m_rubberBand;
95 delete d_ptr->m_rubberBand;
96 d_ptr->m_rubberBand=0;
96 d_ptr->m_rubberBand=0;
97 return;
97 return;
98 }
98 }
99
99
100 if (!d_ptr->m_rubberBand) {
100 if (!d_ptr->m_rubberBand) {
101 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
101 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
102 d_ptr->m_rubberBand->setEnabled(true);
102 d_ptr->m_rubberBand->setEnabled(true);
103 }
103 }
104 }
104 }
105
105
106 /*!
106 /*!
107 Returns the RubberBandPolicy that is currently being used by the widget.
107 Returns the RubberBandPolicy that is currently being used by the widget.
108 */
108 */
109 QChartView::RubberBands QChartView::rubberBand() const
109 QChartView::RubberBands QChartView::rubberBand() const
110 {
110 {
111 return d_ptr->m_rubberBandFlags;
111 return d_ptr->m_rubberBandFlags;
112 }
112 }
113
113
114 /*!
114 /*!
115 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
115 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
116 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
116 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
117 */
117 */
118 void QChartView::mousePressEvent(QMouseEvent *event)
118 void QChartView::mousePressEvent(QMouseEvent *event)
119 {
119 {
120 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
120 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
121
121
122 int padding = d_ptr->m_chart->margins().top();
122 int padding = d_ptr->m_chart->margins().top();
123 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
123 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
124
124
125 if (rect.contains(event->pos())) {
125 if (rect.contains(event->pos())) {
126 d_ptr->m_rubberBandOrigin = event->pos();
126 d_ptr->m_rubberBandOrigin = event->pos();
127 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
127 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
128 d_ptr->m_rubberBand->show();
128 d_ptr->m_rubberBand->show();
129 event->accept();
129 event->accept();
130 }
130 }
131 }
131 }
132 else {
132 else {
133 QGraphicsView::mousePressEvent(event);
133 QGraphicsView::mousePressEvent(event);
134 }
134 }
135 }
135 }
136
136
137 /*!
137 /*!
138 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
138 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
139 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
139 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
140 */
140 */
141 void QChartView::mouseMoveEvent(QMouseEvent *event)
141 void QChartView::mouseMoveEvent(QMouseEvent *event)
142 {
142 {
143 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
143 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
144 QRectF margins = d_ptr->m_chart->margins();
144 QRectF margins = d_ptr->m_chart->margins();
145 QRectF geometry = d_ptr->m_chart->geometry();
145 QRectF geometry = d_ptr->m_chart->geometry();
146 QRectF rect =geometry.adjusted(margins.left(),margins.top(),-margins.right(),-margins.bottom());
146 QRectF rect =geometry.adjusted(margins.left(),margins.top(),-margins.right(),-margins.bottom());
147 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
147 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
148 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
148 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
149 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
149 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
150 d_ptr->m_rubberBandOrigin.setY(rect.top());
150 d_ptr->m_rubberBandOrigin.setY(rect.top());
151 height = rect.height();
151 height = rect.height();
152 }
152 }
153 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
153 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
154 d_ptr->m_rubberBandOrigin.setX(rect.left());
154 d_ptr->m_rubberBandOrigin.setX(rect.left());
155 width= rect.width();
155 width= rect.width();
156 }
156 }
157 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(),d_ptr->m_rubberBandOrigin.y(), width,height).normalized());
157 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(),d_ptr->m_rubberBandOrigin.y(), width,height).normalized());
158 }
158 }
159 else {
159 else {
160 QGraphicsView::mouseMoveEvent(event);
160 QGraphicsView::mouseMoveEvent(event);
161 }
161 }
162 }
162 }
163
163
164 /*!
164 /*!
165 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
165 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
166 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
166 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
167 */
167 */
168 void QChartView::mouseReleaseEvent(QMouseEvent *event)
168 void QChartView::mouseReleaseEvent(QMouseEvent *event)
169 {
169 {
170 if(d_ptr->m_rubberBand) {
170 if(d_ptr->m_rubberBand) {
171 if (event->button() == Qt::LeftButton && d_ptr->m_rubberBand->isVisible()) {
171 if (event->button() == Qt::LeftButton && d_ptr->m_rubberBand->isVisible()) {
172 d_ptr->m_rubberBand->hide();
172 d_ptr->m_rubberBand->hide();
173 QRect rect = d_ptr->m_rubberBand->geometry();
173 QRect rect = d_ptr->m_rubberBand->geometry();
174 d_ptr->m_chart->zoomIn(rect);
174 d_ptr->m_chart->zoomIn(rect);
175 event->accept();
175 event->accept();
176 }
176 }
177
177
178 if(event->button()==Qt::RightButton){
178 if(event->button()==Qt::RightButton){
179 d_ptr->m_chart->zoomOut();
179 d_ptr->m_chart->zoomOut();
180 event->accept();
180 event->accept();
181 }
181 }
182 }
182 }
183 else {
183 else {
184 QGraphicsView::mouseReleaseEvent(event);
184 QGraphicsView::mouseReleaseEvent(event);
185 }
185 }
186 }
186 }
187
187
188 /*!
188 /*!
189 Resizes and updates the chart area using the \a event data
189 Resizes and updates the chart area using the \a event data
190 */
190 */
191 void QChartView::resizeEvent(QResizeEvent *event)
191 void QChartView::resizeEvent(QResizeEvent *event)
192 {
192 {
193 QGraphicsView::resizeEvent(event);
193 QGraphicsView::resizeEvent(event);
194 d_ptr->m_chart->resize(size());
194 d_ptr->m_chart->resize(size());
195 setMinimumSize(d_ptr->m_chart->minimumSize().toSize());
195 setMinimumSize(d_ptr->m_chart->minimumSize().toSize());
196 setSceneRect(d_ptr->m_chart->geometry());
196 setSceneRect(d_ptr->m_chart->geometry());
197 }
197 }
198
198
199 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
199 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
200
200
201 QChartViewPrivate::QChartViewPrivate():
201 QChartViewPrivate::QChartViewPrivate():
202 m_scene(0),
202 m_scene(0),
203 m_chart(0),
203 m_chart(0),
204 m_presenter(0),
204 m_presenter(0),
205 m_rubberBand(0),
205 m_rubberBand(0),
206 m_rubberBandFlags(QChartView::NoRubberBand)
206 m_rubberBandFlags(QChartView::NoRubberBand)
207 {
207 {
208
208
209 }
209 }
210
210
211 QChartViewPrivate::~QChartViewPrivate()
211 QChartViewPrivate::~QChartViewPrivate()
212 {
212 {
213
213
214 }
214 }
215
215
216 #include "moc_qchartview.cpp"
216 #include "moc_qchartview.cpp"
217
217
218 QTCOMMERCIALCHART_END_NAMESPACE
218 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,222 +1,220
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 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
81 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
82 Allows limiting the model mapping.
82 as a data source for y coordinate. The \a orientation parameter specifies whether the data
83 Parameter \a first specifies which element of the model should be used as a first one of the series.
83 is in columns or in rows.
84 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
84 \sa setModel()
85 then all the items following \a first item in a model are used.
86 \sa setModel(), setModelMapping()
87 */
85 */
88 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
86 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
89 {
87 {
90 Q_D(QSplineSeries);
88 Q_D(QSplineSeries);
91 QXYSeries::setModelMapping(modelX, modelY, orientation);
89 QXYSeries::setModelMapping(modelX, modelY, orientation);
92 d->calculateControlPoints();
90 d->calculateControlPoints();
93 }
91 }
94
92
95 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
96
94
97 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
95 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
98 {
96 {
99 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
97 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
100 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
98 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
101 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
102 };
100 };
103
101
104 /*!
102 /*!
105 \internal
103 \internal
106 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
104 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
107 */
105 */
108 void QSplineSeriesPrivate::calculateControlPoints()
106 void QSplineSeriesPrivate::calculateControlPoints()
109 {
107 {
110
108
111 Q_Q(QSplineSeries);
109 Q_Q(QSplineSeries);
112 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
110 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
113 // CPOL License
111 // CPOL License
114
112
115 int n = q->count() - 1;
113 int n = q->count() - 1;
116 if (n == 1)
114 if (n == 1)
117 { // Special case: Bezier curve should be a straight line.
115 { // Special case: Bezier curve should be a straight line.
118 // firstControlPoints = new Point[1];
116 // firstControlPoints = new Point[1];
119 // 3P1 = 2P0 + P3
117 // 3P1 = 2P0 + P3
120 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
118 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
121
119
122 // P2 = 2P1 P0
120 // P2 = 2P1 P0
123 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
121 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
124 return;
122 return;
125 }
123 }
126
124
127 // Calculate first Bezier control points
125 // Calculate first Bezier control points
128 // Right hand side vector
126 // Right hand side vector
129 // Set of equations for P0 to Pn points.
127 // Set of equations for P0 to Pn points.
130 //
128 //
131 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
129 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
132 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
130 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
133 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
131 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
134 // | . . . . . . . . . . . . | | ... | | ... |
132 // | . . . . . . . . . . . . | | ... | | ... |
135 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
133 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
136 // | . . . . . . . . . . . . | | ... | | ... |
134 // | . . . . . . . . . . . . | | ... | | ... |
137 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
135 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
138 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
136 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
139 //
137 //
140 QList<qreal> rhs;
138 QList<qreal> rhs;
141 rhs.append(q->x(0) + 2 * q->x(1));
139 rhs.append(q->x(0) + 2 * q->x(1));
142
140
143 // Set right hand side X values
141 // Set right hand side X values
144 for (int i = 1; i < n - 1; ++i)
142 for (int i = 1; i < n - 1; ++i)
145 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
143 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
146
144
147 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
145 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
148 // Get first control points X-values
146 // Get first control points X-values
149 QList<qreal> xControl = getFirstControlPoints(rhs);
147 QList<qreal> xControl = getFirstControlPoints(rhs);
150 rhs[0] = q->y(0) + 2 * q->y(1);
148 rhs[0] = q->y(0) + 2 * q->y(1);
151
149
152 // Set right hand side Y values
150 // Set right hand side Y values
153 for (int i = 1; i < n - 1; ++i)
151 for (int i = 1; i < n - 1; ++i)
154 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
152 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
155
153
156 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
154 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
157 // Get first control points Y-values
155 // Get first control points Y-values
158 QList<qreal> yControl = getFirstControlPoints(rhs);
156 QList<qreal> yControl = getFirstControlPoints(rhs);
159
157
160 // Fill output arrays.
158 // Fill output arrays.
161 for (int i = 0; i < n; ++i) {
159 for (int i = 0; i < n; ++i) {
162 // First control point
160 // First control point
163 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
161 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
164 // Second control point
162 // Second control point
165 if (i < n - 1)
163 if (i < n - 1)
166 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
164 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
167 else
165 else
168 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
166 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
169 }
167 }
170 }
168 }
171
169
172 /*!
170 /*!
173 \internal
171 \internal
174 */
172 */
175 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
173 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
176 {
174 {
177 QList<qreal> x; // Solution vector.
175 QList<qreal> x; // Solution vector.
178 QList<qreal> tmp; // Temp workspace.
176 QList<qreal> tmp; // Temp workspace.
179
177
180 qreal b = 2.0;
178 qreal b = 2.0;
181 x.append(rhs[0] / b);
179 x.append(rhs[0] / b);
182 tmp.append(0);
180 tmp.append(0);
183 for (int i = 1; i < rhs.size(); i++) {
181 for (int i = 1; i < rhs.size(); i++) {
184 // Decomposition and forward substitution.
182 // Decomposition and forward substitution.
185 tmp.append(1 / b);
183 tmp.append(1 / b);
186 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
184 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
187 x.append((rhs[i] - x[i - 1]) / b);
185 x.append((rhs[i] - x[i - 1]) / b);
188 }
186 }
189 for (int i = 1; i < rhs.size(); i++)
187 for (int i = 1; i < rhs.size(); i++)
190 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
188 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
191
189
192 return x;
190 return x;
193 }
191 }
194
192
195 /*!
193 /*!
196 \internal
194 \internal
197 Updates the control points, besed on currently avaiable knots.
195 Updates the control points, besed on currently avaiable knots.
198 */
196 */
199 void QSplineSeriesPrivate::updateControlPoints()
197 void QSplineSeriesPrivate::updateControlPoints()
200 {
198 {
201 Q_Q(QSplineSeries);
199 Q_Q(QSplineSeries);
202 if (q->count() > 1) {
200 if (q->count() > 1) {
203 m_controlPoints.clear();
201 m_controlPoints.clear();
204 calculateControlPoints();
202 calculateControlPoints();
205 }
203 }
206 }
204 }
207
205
208 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
206 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
209 {
207 {
210 Q_Q(QSplineSeries);
208 Q_Q(QSplineSeries);
211 SplineChartItem* spline = new SplineChartItem(q,presenter);
209 SplineChartItem* spline = new SplineChartItem(q,presenter);
212 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
210 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
213 presenter->animator()->addAnimation(spline);
211 presenter->animator()->addAnimation(spline);
214 }
212 }
215 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
213 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
216 return spline;
214 return spline;
217 }
215 }
218
216
219 #include "moc_qsplineseries.cpp"
217 #include "moc_qsplineseries.cpp"
220 #include "moc_qsplineseries_p.cpp"
218 #include "moc_qsplineseries_p.cpp"
221
219
222 QTCOMMERCIALCHART_END_NAMESPACE
220 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,465 +1,464
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 "qxyseries.h"
21 #include "qxyseries.h"
22 #include "qxyseries_p.h"
22 #include "qxyseries_p.h"
23 #include "domain_p.h"
23 #include "domain_p.h"
24 #include "legendmarker_p.h"
24 #include "legendmarker_p.h"
25 #include <QAbstractItemModel>
25 #include <QAbstractItemModel>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 /*!
29 /*!
30 \class QXYSeries
30 \class QXYSeries
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
32 */
32 */
33
33
34 /*!
34 /*!
35 \fn QPen QXYSeries::pen() const
35 \fn QPen QXYSeries::pen() const
36 \brief Returns pen used to draw points for series.
36 \brief Returns pen used to draw points for series.
37 \sa setPen()
37 \sa setPen()
38 */
38 */
39
39
40 /*!
40 /*!
41 \fn QBrush QXYSeries::brush() const
41 \fn QBrush QXYSeries::brush() const
42 \brief Returns brush used to draw points for series.
42 \brief Returns brush used to draw points for series.
43 \sa setBrush()
43 \sa setBrush()
44 */
44 */
45
45
46 /*!
46 /*!
47 \fn void QXYSeries::clicked(const QPointF& point)
47 \fn void QXYSeries::clicked(const QPointF& point)
48 \brief Signal is emitted when user clicks the \a point on chart.
48 \brief Signal is emitted when user clicks the \a point on chart.
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn void QXYSeries::selected()
52 \fn void QXYSeries::selected()
53
53
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
55 implemented by the user of QXYSeries API.
55 implemented by the user of QXYSeries API.
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
60 \brief \internal \a index
60 \brief \internal \a index
61 */
61 */
62
62
63 /*!
63 /*!
64 \fn void QXYSeriesPrivate::pointAdded(int index)
64 \fn void QXYSeriesPrivate::pointAdded(int index)
65 \brief \internal \a index
65 \brief \internal \a index
66 */
66 */
67
67
68 /*!
68 /*!
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
70 \brief \internal \a index
70 \brief \internal \a index
71 */
71 */
72
72
73 /*!
73 /*!
74 \fn void QXYSeriesPrivate::updated()
74 \fn void QXYSeriesPrivate::updated()
75 \brief \internal
75 \brief \internal
76 */
76 */
77
77
78 /*!
78 /*!
79 \internal
79 \internal
80
80
81 Constructs empty series object which is a child of \a parent.
81 Constructs empty series object which is a child of \a parent.
82 When series object is added to QChartView or QChart instance ownerships is transferred.
82 When series object is added to QChartView or QChart instance ownerships is transferred.
83 */
83 */
84 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
84 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
85 {
85 {
86
86
87 }
87 }
88 /*!
88 /*!
89 Destroys the object. Series added to QChartView or QChart instances are owned by those,
89 Destroys the object. Series added to QChartView or QChart instances are owned by those,
90 and are deleted when mentioned object are destroyed.
90 and are deleted when mentioned object are destroyed.
91 */
91 */
92 QXYSeries::~QXYSeries()
92 QXYSeries::~QXYSeries()
93 {
93 {
94 }
94 }
95
95
96 /*!
96 /*!
97 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
97 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
98 */
98 */
99 void QXYSeries::append(qreal x,qreal y)
99 void QXYSeries::append(qreal x,qreal y)
100 {
100 {
101 Q_D(QXYSeries);
101 Q_D(QXYSeries);
102 Q_ASSERT(d->m_x.size() == d->m_y.size());
102 Q_ASSERT(d->m_x.size() == d->m_y.size());
103 d->m_x<<x;
103 d->m_x<<x;
104 d->m_y<<y;
104 d->m_y<<y;
105 emit d->pointAdded(d->m_x.size()-1);
105 emit d->pointAdded(d->m_x.size()-1);
106 }
106 }
107
107
108 /*!
108 /*!
109 This is an overloaded function.
109 This is an overloaded function.
110 Adds data \a point to the series. Points are connected with lines on the chart.
110 Adds data \a point to the series. Points are connected with lines on the chart.
111 */
111 */
112 void QXYSeries::append(const QPointF &point)
112 void QXYSeries::append(const QPointF &point)
113 {
113 {
114 append(point.x(),point.y());
114 append(point.x(),point.y());
115 }
115 }
116
116
117 /*!
117 /*!
118 This is an overloaded function.
118 This is an overloaded function.
119 Adds list of data \a points to the series. Points are connected with lines on the chart.
119 Adds list of data \a points to the series. Points are connected with lines on the chart.
120 */
120 */
121 void QXYSeries::append(const QList<QPointF> points)
121 void QXYSeries::append(const QList<QPointF> points)
122 {
122 {
123 foreach(const QPointF& point , points) {
123 foreach(const QPointF& point , points) {
124 append(point.x(),point.y());
124 append(point.x(),point.y());
125 }
125 }
126 }
126 }
127
127
128 /*!
128 /*!
129 Modifies \a y value for given \a x a value.
129 Modifies \a y value for given \a x a value.
130 */
130 */
131 void QXYSeries::replace(qreal x,qreal y)
131 void QXYSeries::replace(qreal x,qreal y)
132 {
132 {
133 Q_D(QXYSeries);
133 Q_D(QXYSeries);
134 int index = d->m_x.indexOf(x);
134 int index = d->m_x.indexOf(x);
135 d->m_x[index] = x;
135 d->m_x[index] = x;
136 d->m_y[index] = y;
136 d->m_y[index] = y;
137 emit d->pointReplaced(index);
137 emit d->pointReplaced(index);
138 }
138 }
139
139
140 /*!
140 /*!
141 This is an overloaded function.
141 This is an overloaded function.
142 Replaces current y value of for given \a point x value with \a point y value.
142 Replaces current y value of for given \a point x value with \a point y value.
143 */
143 */
144 void QXYSeries::replace(const QPointF &point)
144 void QXYSeries::replace(const QPointF &point)
145 {
145 {
146 replace(point.x(),point.y());
146 replace(point.x(),point.y());
147 }
147 }
148
148
149 /*!
149 /*!
150 Removes first \a x value and related y value.
150 Removes first \a x value and related y value.
151 */
151 */
152 void QXYSeries::remove(qreal x)
152 void QXYSeries::remove(qreal x)
153 {
153 {
154 Q_D(QXYSeries);
154 Q_D(QXYSeries);
155 int index = d->m_x.indexOf(x);
155 int index = d->m_x.indexOf(x);
156
156
157 if (index == -1) return;
157 if (index == -1) return;
158
158
159 d->m_x.remove(index);
159 d->m_x.remove(index);
160 d->m_y.remove(index);
160 d->m_y.remove(index);
161
161
162 emit d->pointRemoved(index);
162 emit d->pointRemoved(index);
163 }
163 }
164
164
165 /*!
165 /*!
166 Removes current \a x and \a y value.
166 Removes current \a x and \a y value.
167 */
167 */
168 void QXYSeries::remove(qreal x,qreal y)
168 void QXYSeries::remove(qreal x,qreal y)
169 {
169 {
170 Q_D(QXYSeries);
170 Q_D(QXYSeries);
171 int index =-1;
171 int index =-1;
172 do {
172 do {
173 index = d->m_x.indexOf(x,index+1);
173 index = d->m_x.indexOf(x,index+1);
174 } while (index !=-1 && d->m_y.at(index)!=y);
174 } while (index !=-1 && d->m_y.at(index)!=y);
175
175
176 if (index==-1) return;
176 if (index==-1) return;
177
177
178 d->m_x.remove(index);
178 d->m_x.remove(index);
179 d->m_y.remove(index);
179 d->m_y.remove(index);
180 emit d->pointRemoved(index);
180 emit d->pointRemoved(index);
181 }
181 }
182
182
183 /*!
183 /*!
184 Removes current \a point x value. Note \a point y value is ignored.
184 Removes current \a point x value. Note \a point y value is ignored.
185 */
185 */
186 void QXYSeries::remove(const QPointF &point)
186 void QXYSeries::remove(const QPointF &point)
187 {
187 {
188 remove(point.x(),point.y());
188 remove(point.x(),point.y());
189 }
189 }
190
190
191 /*!
191 /*!
192 Removes all data points from the series.
192 Removes all data points from the series.
193 */
193 */
194 void QXYSeries::removeAll()
194 void QXYSeries::removeAll()
195 {
195 {
196 Q_D(QXYSeries);
196 Q_D(QXYSeries);
197 d->m_x.clear();
197 d->m_x.clear();
198 d->m_y.clear();
198 d->m_y.clear();
199 }
199 }
200
200
201 /*!
201 /*!
202 \internal \a pos
202 \internal \a pos
203 */
203 */
204 qreal QXYSeries::x(int pos) const
204 qreal QXYSeries::x(int pos) const
205 {
205 {
206 Q_D(const QXYSeries);
206 Q_D(const QXYSeries);
207 if (d->m_model) {
207 if (d->m_model) {
208 if (d->m_mapOrientation == Qt::Vertical)
208 if (d->m_mapOrientation == Qt::Vertical)
209 // consecutive data is read from model's column
209 // consecutive data is read from model's column
210 return d->m_model->data(d->m_model->index(pos, d->m_mapX), Qt::DisplayRole).toDouble();
210 return d->m_model->data(d->m_model->index(pos, d->m_mapX), Qt::DisplayRole).toDouble();
211 else
211 else
212 // consecutive data is read from model's row
212 // consecutive data is read from model's row
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos), Qt::DisplayRole).toDouble();
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos), Qt::DisplayRole).toDouble();
214 } else {
214 } else {
215 // model is not specified, return the data from series' internal data store
215 // model is not specified, return the data from series' internal data store
216 return d->m_x.at(pos);
216 return d->m_x.at(pos);
217 }
217 }
218 }
218 }
219
219
220 /*!
220 /*!
221 \internal \a pos
221 \internal \a pos
222 */
222 */
223 qreal QXYSeries::y(int pos) const
223 qreal QXYSeries::y(int pos) const
224 {
224 {
225 Q_D(const QXYSeries);
225 Q_D(const QXYSeries);
226 if (d->m_model) {
226 if (d->m_model) {
227 if (d->m_mapOrientation == Qt::Vertical)
227 if (d->m_mapOrientation == Qt::Vertical)
228 // consecutive data is read from model's column
228 // consecutive data is read from model's column
229 return d->m_model->data(d->m_model->index(pos, d->m_mapY), Qt::DisplayRole).toDouble();
229 return d->m_model->data(d->m_model->index(pos, d->m_mapY), Qt::DisplayRole).toDouble();
230 else
230 else
231 // consecutive data is read from model's row
231 // consecutive data is read from model's row
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos), Qt::DisplayRole).toDouble();
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos), Qt::DisplayRole).toDouble();
233 } else {
233 } else {
234 // model is not specified, return the data from series' internal data store
234 // model is not specified, return the data from series' internal data store
235 return d->m_y.at(pos);
235 return d->m_y.at(pos);
236 }
236 }
237 }
237 }
238
238
239 /*!
239 /*!
240 Returns number of data points within series.
240 Returns number of data points within series.
241 */
241 */
242 int QXYSeries::count() const
242 int QXYSeries::count() const
243 {
243 {
244 Q_D(const QXYSeries);
244 Q_D(const QXYSeries);
245
245
246 Q_ASSERT(d->m_x.size() == d->m_y.size());
246 Q_ASSERT(d->m_x.size() == d->m_y.size());
247
247
248 if (d->m_model) {
248 if (d->m_model) {
249 if (d->m_mapOrientation == Qt::Vertical) {
249 if (d->m_mapOrientation == Qt::Vertical) {
250 // data is in a column. Return the number of mapped items
250 // data is in a column. Return the number of mapped items
251 return d->m_model->rowCount();
251 return d->m_model->rowCount();
252 } else {
252 } else {
253 // data is in a row. Return the number of mapped items
253 // data is in a row. Return the number of mapped items
254 return d->m_model->columnCount();
254 return d->m_model->columnCount();
255 }
255 }
256 }
256 }
257
257
258 // model is not specified, return the number of points in the series internal data store
258 // model is not specified, return the number of points in the series internal data store
259 return d->m_x.size();
259 return d->m_x.size();
260 }
260 }
261
261
262 /*!
262 /*!
263 Returns the data points of the series.
263 Returns the data points of the series.
264 */
264 */
265 QList<QPointF> QXYSeries::data()
265 QList<QPointF> QXYSeries::data()
266 {
266 {
267 Q_D(QXYSeries);
267 Q_D(QXYSeries);
268 QList<QPointF> data;
268 QList<QPointF> data;
269 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
269 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
270 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
270 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
271 return data;
271 return data;
272 }
272 }
273
273
274
274
275 /*!
275 /*!
276 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
276 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
277 pen from chart theme is used.
277 pen from chart theme is used.
278 \sa QChart::setTheme()
278 \sa QChart::setTheme()
279 */
279 */
280 void QXYSeries::setPen(const QPen &pen)
280 void QXYSeries::setPen(const QPen &pen)
281 {
281 {
282 Q_D(QXYSeries);
282 Q_D(QXYSeries);
283 if (d->m_pen!=pen) {
283 if (d->m_pen!=pen) {
284 d->m_pen = pen;
284 d->m_pen = pen;
285 emit d->updated();
285 emit d->updated();
286 }
286 }
287 }
287 }
288
288
289 QPen QXYSeries::pen() const
289 QPen QXYSeries::pen() const
290 {
290 {
291 Q_D(const QXYSeries);
291 Q_D(const QXYSeries);
292 return d->m_pen;
292 return d->m_pen;
293 }
293 }
294
294
295 /*!
295 /*!
296 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
296 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
297 from chart theme setting is used.
297 from chart theme setting is used.
298 \sa QChart::setTheme()
298 \sa QChart::setTheme()
299 */
299 */
300 void QXYSeries::setBrush(const QBrush &brush)
300 void QXYSeries::setBrush(const QBrush &brush)
301 {
301 {
302 Q_D(QXYSeries);
302 Q_D(QXYSeries);
303 if (d->m_brush!=brush) {
303 if (d->m_brush!=brush) {
304 d->m_brush = brush;
304 d->m_brush = brush;
305 emit d->updated();
305 emit d->updated();
306 }
306 }
307 }
307 }
308
308
309 QBrush QXYSeries::brush() const
309 QBrush QXYSeries::brush() const
310 {
310 {
311 Q_D(const QXYSeries);
311 Q_D(const QXYSeries);
312 return d->m_brush;
312 return d->m_brush;
313 }
313 }
314
314
315
315
316 /*!
316 /*!
317 Sets if data points are \a visible and should be drawn on line.
317 Sets if data points are \a visible and should be drawn on line.
318 */
318 */
319 void QXYSeries::setPointsVisible(bool visible)
319 void QXYSeries::setPointsVisible(bool visible)
320 {
320 {
321 Q_D(QXYSeries);
321 Q_D(QXYSeries);
322 if (d->m_pointsVisible != visible){
322 if (d->m_pointsVisible != visible){
323 d->m_pointsVisible = visible;
323 d->m_pointsVisible = visible;
324 emit d->updated();
324 emit d->updated();
325 }
325 }
326 }
326 }
327
327
328 /*!
328 /*!
329 Returns true if drawing the data points of the series is enabled.
329 Returns true if drawing the data points of the series is enabled.
330 */
330 */
331 bool QXYSeries::pointsVisible() const
331 bool QXYSeries::pointsVisible() const
332 {
332 {
333 Q_D(const QXYSeries);
333 Q_D(const QXYSeries);
334 return d->m_pointsVisible;
334 return d->m_pointsVisible;
335 }
335 }
336
336
337
337
338 /*!
338 /*!
339 Stream operator for adding a data \a point to the series.
339 Stream operator for adding a data \a point to the series.
340 \sa append()
340 \sa append()
341 */
341 */
342 QXYSeries& QXYSeries::operator<< (const QPointF &point)
342 QXYSeries& QXYSeries::operator<< (const QPointF &point)
343 {
343 {
344 append(point);
344 append(point);
345 return *this;
345 return *this;
346 }
346 }
347
347
348
348
349 /*!
349 /*!
350 Stream operator for adding a list of \a points to the series.
350 Stream operator for adding a list of \a points to the series.
351 \sa append()
351 \sa append()
352 */
352 */
353
353
354 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
354 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
355 {
355 {
356 append(points);
356 append(points);
357 return *this;
357 return *this;
358 }
358 }
359
359
360 /*!
360 /*!
361 \internal
361 \internal
362 */
362 */
363 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
363 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
364 {
364 {
365 Q_UNUSED(bottomRight)
365 Q_UNUSED(bottomRight)
366 Q_D(QXYSeries);
366 Q_D(QXYSeries);
367 if (d->m_mapOrientation == Qt::Vertical) {
367 if (d->m_mapOrientation == Qt::Vertical) {
368 if (topLeft.column() == d->m_mapX || topLeft.column() == d->m_mapY)
368 if (topLeft.column() == d->m_mapX || topLeft.column() == d->m_mapY)
369 emit d->pointReplaced(topLeft.row());
369 emit d->pointReplaced(topLeft.row());
370 } else {
370 } else {
371 if (topLeft.row() == d->m_mapX || topLeft.row() == d->m_mapY)
371 if (topLeft.row() == d->m_mapX || topLeft.row() == d->m_mapY)
372 emit d->pointReplaced(topLeft.column());
372 emit d->pointReplaced(topLeft.column());
373 }
373 }
374 }
374 }
375
375
376 /*!
376 /*!
377 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
377 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
378 Sets the \a model to be used as a data source
378 Sets the \a model to be used as a data source
379 \sa setModelMapping()
379 \sa setModelMapping()
380 */
380 */
381 bool QXYSeries::setModel(QAbstractItemModel *model)
381 bool QXYSeries::setModel(QAbstractItemModel *model)
382 {
382 {
383 Q_D(QXYSeries);
383 Q_D(QXYSeries);
384 // disconnect signals from old model
384 // disconnect signals from old model
385 if (d->m_model) {
385 if (d->m_model) {
386 QObject::disconnect(d->m_model, 0, this, 0);
386 QObject::disconnect(d->m_model, 0, this, 0);
387 d->m_mapX = -1;
387 d->m_mapX = -1;
388 d->m_mapY = -1;
388 d->m_mapY = -1;
389 d->m_mapOrientation = Qt::Vertical;
389 d->m_mapOrientation = Qt::Vertical;
390 }
390 }
391
391
392 // set new model
392 // set new model
393 if (model) {
393 if (model) {
394 d->m_model = model;
394 d->m_model = model;
395 return true;
395 return true;
396 } else {
396 } else {
397 d->m_model = 0;
397 d->m_model = 0;
398 return false;
398 return false;
399 }
399 }
400 }
400 }
401
401
402 /*!
402 /*!
403 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
404 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
403 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
405 as a data source for y coordinate. The \a orientation parameter specifies whether the data
404 as a data source for y coordinate. The \a orientation parameter specifies whether the data
406 is in columns or in rows.
405 is in columns or in rows.
407 \sa setModel()
406 \sa setModel()
408 */
407 */
409 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
408 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
410 {
409 {
411 Q_D(QXYSeries);
410 Q_D(QXYSeries);
412 if (d->m_model == 0)
411 if (d->m_model == 0)
413 return;
412 return;
414 d->m_mapX = modelX;
413 d->m_mapX = modelX;
415 d->m_mapY = modelY;
414 d->m_mapY = modelY;
416 d->m_mapOrientation = orientation;
415 d->m_mapOrientation = orientation;
417 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
416 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
418 }
417 }
419
418
420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
421
420
422
421
423 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
422 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
424 m_mapX(-1),
423 m_mapX(-1),
425 m_mapY(-1),
424 m_mapY(-1),
426 m_mapOrientation( Qt::Vertical),
425 m_mapOrientation( Qt::Vertical),
427 m_pointsVisible(false)
426 m_pointsVisible(false)
428 {
427 {
429 }
428 }
430
429
431 void QXYSeriesPrivate::scaleDomain(Domain& domain)
430 void QXYSeriesPrivate::scaleDomain(Domain& domain)
432 {
431 {
433 qreal minX(domain.minX());
432 qreal minX(domain.minX());
434 qreal minY(domain.minY());
433 qreal minY(domain.minY());
435 qreal maxX(domain.maxX());
434 qreal maxX(domain.maxX());
436 qreal maxY(domain.maxY());
435 qreal maxY(domain.maxY());
437 int tickXCount(domain.tickXCount());
436 int tickXCount(domain.tickXCount());
438 int tickYCount(domain.tickYCount());
437 int tickYCount(domain.tickYCount());
439
438
440 Q_Q(QXYSeries);
439 Q_Q(QXYSeries);
441 for (int i = 0; i < q->count(); i++)
440 for (int i = 0; i < q->count(); i++)
442 {
441 {
443 qreal x = q->x(i);
442 qreal x = q->x(i);
444 qreal y = q->y(i);
443 qreal y = q->y(i);
445 minX = qMin(minX, x);
444 minX = qMin(minX, x);
446 minY = qMin(minY, y);
445 minY = qMin(minY, y);
447 maxX = qMax(maxX, x);
446 maxX = qMax(maxX, x);
448 maxY = qMax(maxY, y);
447 maxY = qMax(maxY, y);
449 }
448 }
450
449
451 domain.setRangeX(minX,maxX,tickXCount);
450 domain.setRangeX(minX,maxX,tickXCount);
452 domain.setRangeY(minY,maxY,tickYCount);
451 domain.setRangeY(minY,maxY,tickYCount);
453 }
452 }
454
453
455 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
454 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
456 {
455 {
457 Q_Q(QXYSeries);
456 Q_Q(QXYSeries);
458 QList<LegendMarker*> list;
457 QList<LegendMarker*> list;
459 return list << new XYLegendMarker(q,legend);
458 return list << new XYLegendMarker(q,legend);
460 }
459 }
461
460
462 #include "moc_qxyseries.cpp"
461 #include "moc_qxyseries.cpp"
463 #include "moc_qxyseries_p.cpp"
462 #include "moc_qxyseries_p.cpp"
464
463
465 QTCOMMERCIALCHART_END_NAMESPACE
464 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now