##// END OF EJS Templates
Bugfixes for spline vector allocation issues
Michal Klocek -
r1082:4c0668542a54
parent child
Show More
@@ -1,404 +1,406
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 #include "chartpresenter_p.h"
20 #include "chartpresenter_p.h"
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "qaxis.h"
23 #include "qaxis.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 #include "qabstractseries_p.h"
27 #include "qabstractseries_p.h"
28 #include "qareaseries.h"
28 #include "qareaseries.h"
29 #include "chartaxis_p.h"
29 #include "chartaxis_p.h"
30 #include "areachartitem_p.h"
30 #include "areachartitem_p.h"
31 #include "chartbackground_p.h"
31 #include "chartbackground_p.h"
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
35 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
36 m_chart(chart),
36 m_chart(chart),
37 m_animator(0),
37 m_animator(0),
38 m_dataset(dataset),
38 m_dataset(dataset),
39 m_chartTheme(0),
39 m_chartTheme(0),
40 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
40 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
41 m_options(QChart::NoAnimation),
41 m_options(QChart::NoAnimation),
42 m_minLeftMargin(0),
42 m_minLeftMargin(0),
43 m_minBottomMargin(0),
43 m_minBottomMargin(0),
44 m_backgroundItem(0),
44 m_backgroundItem(0),
45 m_titleItem(0),
45 m_titleItem(0),
46 m_marginBig(60),
46 m_marginBig(60),
47 m_marginSmall(20),
47 m_marginSmall(20),
48 m_marginTiny(10),
48 m_marginTiny(10),
49 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
49 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
50 {
50 {
51 }
51 }
52
52
53 ChartPresenter::~ChartPresenter()
53 ChartPresenter::~ChartPresenter()
54 {
54 {
55 delete m_chartTheme;
55 delete m_chartTheme;
56 }
56 }
57
57
58 void ChartPresenter::setGeometry(const QRectF& rect)
58 void ChartPresenter::setGeometry(const QRectF& rect)
59 {
59 {
60 m_rect = rect;
60 m_rect = rect;
61 Q_ASSERT(m_rect.isValid());
61 Q_ASSERT(m_rect.isValid());
62 updateLayout();
62 updateLayout();
63 }
63 }
64
64
65 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
65 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
66 {
66 {
67 switch(axis->axisType()){
67 switch(axis->axisType()){
68 case ChartAxis::X_AXIS:
68 case ChartAxis::X_AXIS:
69 {
69 {
70 if(width>m_chartRect.width()+ m_chartMargins.left()) {
70 if(width>m_chartRect.width()+ m_chartMargins.left()) {
71 m_minLeftMargin= width - m_chartRect.width();
71 m_minLeftMargin= width - m_chartRect.width();
72 updateLayout();
72 updateLayout();
73 }
73 }
74 break;
74 break;
75 }
75 }
76 case ChartAxis::Y_AXIS:
76 case ChartAxis::Y_AXIS:
77 {
77 {
78
78
79 if(m_minLeftMargin!=width){
79 if(m_minLeftMargin!=width){
80 m_minLeftMargin= width;
80 m_minLeftMargin= width;
81 updateLayout();
81 updateLayout();
82 }
82 }
83 break;
83 break;
84 }
84 }
85
85
86 }
86 }
87 }
87 }
88
88
89 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
89 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
90 {
90 {
91 switch(axis->axisType()){
91 switch(axis->axisType()){
92 case ChartAxis::X_AXIS:
92 case ChartAxis::X_AXIS:
93 {
93 {
94 if(m_minBottomMargin!=height) {
94 if(m_minBottomMargin!=height) {
95 m_minBottomMargin= height;
95 m_minBottomMargin= height;
96 updateLayout();
96 updateLayout();
97 }
97 }
98 break;
98 break;
99 }
99 }
100 case ChartAxis::Y_AXIS:
100 case ChartAxis::Y_AXIS:
101 {
101 {
102
102
103 if(height>m_chartMargins.bottom()+m_chartRect.height()){
103 if(height>m_chartMargins.bottom()+m_chartRect.height()){
104 m_minBottomMargin= height - m_chartRect.height();
104 m_minBottomMargin= height - m_chartRect.height();
105 updateLayout();
105 updateLayout();
106 }
106 }
107 break;
107 break;
108 }
108 }
109
109
110 }
110 }
111 }
111 }
112
112
113 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
113 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
114 {
114 {
115 ChartAxis* item = new ChartAxis(axis,this,axis==m_dataset->axisX()?ChartAxis::X_AXIS : ChartAxis::Y_AXIS);
115 ChartAxis* item = new ChartAxis(axis,this,axis==m_dataset->axisX()?ChartAxis::X_AXIS : ChartAxis::Y_AXIS);
116
116
117 if(m_options.testFlag(QChart::GridAxisAnimations)){
117 if(m_options.testFlag(QChart::GridAxisAnimations)){
118 m_animator->addAnimation(item);
118 m_animator->addAnimation(item);
119 }
119 }
120
120
121 if(axis==m_dataset->axisX()){
121 if(axis==m_dataset->axisX()){
122 m_chartTheme->decorate(axis,true);
122 m_chartTheme->decorate(axis,true);
123 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
123 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
124 //initialize
124 //initialize
125 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
125 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
126
126
127 }
127 }
128 else{
128 else{
129 m_chartTheme->decorate(axis,false);
129 m_chartTheme->decorate(axis,false);
130 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
130 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
131 //initialize
131 //initialize
132 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
132 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
133 }
133 }
134
134
135 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
135 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
136 //initialize
136 //initialize
137 item->handleGeometryChanged(m_chartRect);
137 item->handleGeometryChanged(m_chartRect);
138 m_axisItems.insert(axis, item);
138 m_axisItems.insert(axis, item);
139 }
139 }
140
140
141 void ChartPresenter::handleAxisRemoved(QAxis* axis)
141 void ChartPresenter::handleAxisRemoved(QAxis* axis)
142 {
142 {
143 ChartAxis* item = m_axisItems.take(axis);
143 ChartAxis* item = m_axisItems.take(axis);
144 Q_ASSERT(item);
144 Q_ASSERT(item);
145 if(m_animator) m_animator->removeAnimation(item);
145 if(m_animator) m_animator->removeAnimation(item);
146 delete item;
146 delete item;
147 }
147 }
148
148
149
149
150 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
150 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
151 {
151 {
152 Chart *item = series->d_ptr->createGraphics(this);
152 Chart *item = series->d_ptr->createGraphics(this);
153 Q_ASSERT(item);
153 Q_ASSERT(item);
154 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
154 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
155 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
155 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
156 //initialize
156 //initialize
157 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
157 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
158 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
158 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
159 m_chartItems.insert(series,item);
159 m_chartItems.insert(series,item);
160 }
160 }
161
161
162 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
162 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
163 {
163 {
164 Chart* item = m_chartItems.take(series);
164 Chart* item = m_chartItems.take(series);
165 Q_ASSERT(item);
165 Q_ASSERT(item);
166 if(m_animator) {
166 if(m_animator) {
167 //small hack to handle area animations
167 //small hack to handle area animations
168 if(series->type() == QAbstractSeries::SeriesTypeArea){
168 if(series->type() == QAbstractSeries::SeriesTypeArea){
169 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
169 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
170 AreaChartItem* area = static_cast<AreaChartItem*>(item);
170 AreaChartItem* area = static_cast<AreaChartItem*>(item);
171 m_animator->removeAnimation(area->upperLineItem());
171 m_animator->removeAnimation(area->upperLineItem());
172 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
172 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
173 }else
173 }else
174 m_animator->removeAnimation(item);
174 m_animator->removeAnimation(item);
175 }
175 }
176 delete item;
176 delete item;
177 }
177 }
178
178
179 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
179 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
180 {
180 {
181 if(m_chartTheme && m_chartTheme->id() == theme) return;
181 if(m_chartTheme && m_chartTheme->id() == theme) return;
182 delete m_chartTheme;
182 delete m_chartTheme;
183 m_chartTheme = ChartTheme::createTheme(theme);
183 m_chartTheme = ChartTheme::createTheme(theme);
184 m_chartTheme->setForced(force);
184 m_chartTheme->setForced(force);
185 m_chartTheme->decorate(m_chart);
185 m_chartTheme->decorate(m_chart);
186 m_chartTheme->decorate(m_chart->legend());
186 m_chartTheme->decorate(m_chart->legend());
187 resetAllElements();
187 resetAllElements();
188 }
188 }
189
189
190 QChart::ChartTheme ChartPresenter::theme()
190 QChart::ChartTheme ChartPresenter::theme()
191 {
191 {
192 return m_chartTheme->id();
192 return m_chartTheme->id();
193 }
193 }
194
194
195 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
195 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
196 {
196 {
197 if(m_options!=options) {
197 if(m_options!=options) {
198
198
199 m_options=options;
199 m_options=options;
200
200
201 if(m_options!=QChart::NoAnimation && !m_animator) {
201 if(m_options!=QChart::NoAnimation && !m_animator) {
202 m_animator= new ChartAnimator(this);
202 m_animator= new ChartAnimator(this);
203 }
203 }
204 resetAllElements();
204 resetAllElements();
205 }
205 }
206
206
207 }
207 }
208
208
209 void ChartPresenter::resetAllElements()
209 void ChartPresenter::resetAllElements()
210 {
210 {
211 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
211 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
212 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
212 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
213
213
214 foreach(QAxis *axis, axisList) {
214 foreach(QAxis *axis, axisList) {
215 handleAxisRemoved(axis);
215 handleAxisRemoved(axis);
216 handleAxisAdded(axis,m_dataset->domain(axis));
216 handleAxisAdded(axis,m_dataset->domain(axis));
217 }
217 }
218 foreach(QAbstractSeries *series, seriesList) {
218 foreach(QAbstractSeries *series, seriesList) {
219 handleSeriesRemoved(series);
219 handleSeriesRemoved(series);
220 handleSeriesAdded(series,m_dataset->domain(series));
220 handleSeriesAdded(series,m_dataset->domain(series));
221 // m_dataset->removeSeries(series);
221 // m_dataset->removeSeries(series);
222 // m_dataset->addSeries(series);
222 // m_dataset->addSeries(series);
223 }
223 }
224 }
224 }
225
225
226 void ChartPresenter::zoomIn()
226 void ChartPresenter::zoomIn()
227 {
227 {
228 QRectF rect = chartGeometry();
228 QRectF rect = chartGeometry();
229 rect.setWidth(rect.width()/2);
229 rect.setWidth(rect.width()/2);
230 rect.setHeight(rect.height()/2);
230 rect.setHeight(rect.height()/2);
231 rect.moveCenter(chartGeometry().center());
231 rect.moveCenter(chartGeometry().center());
232 zoomIn(rect);
232 zoomIn(rect);
233 }
233 }
234
234
235 void ChartPresenter::zoomIn(const QRectF& rect)
235 void ChartPresenter::zoomIn(const QRectF& rect)
236 {
236 {
237 QRectF r = rect.normalized();
237 QRectF r = rect.normalized();
238 r.translate(-m_chartMargins.topLeft());
238 r.translate(-m_chartMargins.topLeft());
239 if(!r.isValid()) return;
239 if(m_animator) {
240 if(m_animator) {
240
241
241 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
242 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
242 m_animator->setState(ChartAnimator::ZoomInState,point);
243 m_animator->setState(ChartAnimator::ZoomInState,point);
243 }
244 }
244 m_dataset->zoomInDomain(r,chartGeometry().size());
245 m_dataset->zoomInDomain(r,chartGeometry().size());
245 if(m_animator) {
246 if(m_animator) {
246 m_animator->setState(ChartAnimator::ShowState);
247 m_animator->setState(ChartAnimator::ShowState);
247 }
248 }
248 }
249 }
249
250
250 void ChartPresenter::zoomOut()
251 void ChartPresenter::zoomOut()
251 {
252 {
252 if(m_animator)
253 if(m_animator)
253 {
254 {
254 m_animator->setState(ChartAnimator::ZoomOutState);
255 m_animator->setState(ChartAnimator::ZoomOutState);
255 }
256 }
256
257
257 QSizeF size = chartGeometry().size();
258 QSizeF size = chartGeometry().size();
258 QRectF rect = chartGeometry();
259 QRectF rect = chartGeometry();
259 rect.translate(-m_chartMargins.topLeft());
260 rect.translate(-m_chartMargins.topLeft());
261 if(!rect.isValid()) return;
260 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
262 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
261 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
263 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
262
264
263 if(m_animator){
265 if(m_animator){
264 m_animator->setState(ChartAnimator::ShowState);
266 m_animator->setState(ChartAnimator::ShowState);
265 }
267 }
266 }
268 }
267
269
268 void ChartPresenter::scroll(int dx,int dy)
270 void ChartPresenter::scroll(int dx,int dy)
269 {
271 {
270 if(m_animator){
272 if(m_animator){
271 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
273 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
272 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
274 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
273 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
275 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
274 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
276 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
275 }
277 }
276
278
277 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
279 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
278
280
279 if(m_animator){
281 if(m_animator){
280 m_animator->setState(ChartAnimator::ShowState);
282 m_animator->setState(ChartAnimator::ShowState);
281 }
283 }
282 }
284 }
283
285
284 QChart::AnimationOptions ChartPresenter::animationOptions() const
286 QChart::AnimationOptions ChartPresenter::animationOptions() const
285 {
287 {
286 return m_options;
288 return m_options;
287 }
289 }
288
290
289 void ChartPresenter::updateLayout()
291 void ChartPresenter::updateLayout()
290 {
292 {
291 if (!m_rect.isValid()) return;
293 if (!m_rect.isValid()) return;
292
294
293 // recalculate title size
295 // recalculate title size
294
296
295 QSize titleSize;
297 QSize titleSize;
296 int titlePadding=0;
298 int titlePadding=0;
297
299
298 if (m_titleItem) {
300 if (m_titleItem) {
299 titleSize= m_titleItem->boundingRect().size().toSize();
301 titleSize= m_titleItem->boundingRect().size().toSize();
300 }
302 }
301
303
302 //defaults
304 //defaults
303 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
305 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
304 titlePadding = m_chartMargins.top()/2;
306 titlePadding = m_chartMargins.top()/2;
305
307
306 QLegend* legend = m_chart->d_ptr->m_legend;
308 QLegend* legend = m_chart->d_ptr->m_legend;
307
309
308 // recalculate legend position
310 // recalculate legend position
309 if (legend->isAttachedToChart() && legend->isEnabled()) {
311 if (legend->isAttachedToChart() && legend->isEnabled()) {
310
312
311 QRect legendRect;
313 QRect legendRect;
312
314
313 // Reserve some space for legend
315 // Reserve some space for legend
314 switch (legend->alignment()) {
316 switch (legend->alignment()) {
315
317
316 case QLegend::AlignmentTop: {
318 case QLegend::AlignmentTop: {
317 int ledgendSize = legend->minHeight();
319 int ledgendSize = legend->minHeight();
318 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
320 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
319 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
321 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
320 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
322 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
321 titlePadding = m_marginTiny + m_marginTiny;
323 titlePadding = m_marginTiny + m_marginTiny;
322 break;
324 break;
323 }
325 }
324 case QLegend::AlignmentBottom: {
326 case QLegend::AlignmentBottom: {
325 int ledgendSize = legend->minHeight();
327 int ledgendSize = legend->minHeight();
326 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
328 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
327 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
329 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
328 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
330 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
329 titlePadding = m_chartMargins.top()/2;
331 titlePadding = m_chartMargins.top()/2;
330 break;
332 break;
331 }
333 }
332 case QLegend::AlignmentLeft: {
334 case QLegend::AlignmentLeft: {
333 int ledgendSize = legend->minWidth();
335 int ledgendSize = legend->minWidth();
334 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
336 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
335 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
337 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
336 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
338 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
337 titlePadding = m_chartMargins.top()/2;
339 titlePadding = m_chartMargins.top()/2;
338 break;
340 break;
339 }
341 }
340 case QLegend::AlignmentRight: {
342 case QLegend::AlignmentRight: {
341 int ledgendSize = legend->minWidth();
343 int ledgendSize = legend->minWidth();
342 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
344 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
343 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
345 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
344 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
346 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
345 titlePadding = m_chartMargins.top()/2;
347 titlePadding = m_chartMargins.top()/2;
346 break;
348 break;
347 }
349 }
348 default: {
350 default: {
349 break;
351 break;
350 }
352 }
351 }
353 }
352 }
354 }
353
355
354 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
356 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
355 {
357 {
356 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
358 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
357 return;
359 return;
358 }
360 }
359
361
360
362
361 // recalculate title position
363 // recalculate title position
362 if (m_titleItem) {
364 if (m_titleItem) {
363 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
365 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
364 m_titleItem->setPos(center.x(),titlePadding);
366 m_titleItem->setPos(center.x(),titlePadding);
365 }
367 }
366
368
367 //recalculate background gradient
369 //recalculate background gradient
368 if (m_backgroundItem) {
370 if (m_backgroundItem) {
369 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
371 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
370 }
372 }
371
373
372
374
373 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
375 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
374
376
375 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
377 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
376
378
377 if(m_chartRect!=chartRect){
379 if(m_chartRect!=chartRect){
378 m_chartRect=chartRect;
380 m_chartRect=chartRect;
379 emit geometryChanged(m_chartRect);
381 emit geometryChanged(m_chartRect);
380 }
382 }
381
383
382
384
383 }
385 }
384
386
385 void ChartPresenter::createChartBackgroundItem()
387 void ChartPresenter::createChartBackgroundItem()
386 {
388 {
387 if (!m_backgroundItem) {
389 if (!m_backgroundItem) {
388 m_backgroundItem = new ChartBackground(rootItem());
390 m_backgroundItem = new ChartBackground(rootItem());
389 m_backgroundItem->setPen(Qt::NoPen);
391 m_backgroundItem->setPen(Qt::NoPen);
390 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
392 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
391 }
393 }
392 }
394 }
393
395
394 void ChartPresenter::createChartTitleItem()
396 void ChartPresenter::createChartTitleItem()
395 {
397 {
396 if (!m_titleItem) {
398 if (!m_titleItem) {
397 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
399 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
398 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
400 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
399 }
401 }
400 }
402 }
401
403
402 #include "moc_chartpresenter_p.cpp"
404 #include "moc_chartpresenter_p.cpp"
403
405
404 QTCOMMERCIALCHART_END_NAMESPACE
406 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,241 +1,249
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 #include <QAbstractItemModel>
27 #include <QAbstractItemModel>
28
28
29 /*!
29 /*!
30 \class QSplineSeries
30 \class QSplineSeries
31 \brief Series type used to store data needed to draw a spline.
31 \brief Series type used to store data needed to draw a spline.
32
32
33 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
34 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
35
35
36 \image examples_splinechart.png
36 \image examples_splinechart.png
37
37
38 Creating basic spline chart is simple:
38 Creating basic spline chart is simple:
39 \code
39 \code
40 QSplineSeries* series = new QSplineSeries();
40 QSplineSeries* series = new QSplineSeries();
41 series->append(0, 6);
41 series->append(0, 6);
42 series->append(2, 4);
42 series->append(2, 4);
43 ...
43 ...
44 chart->addSeries(series);
44 chart->addSeries(series);
45 \endcode
45 \endcode
46 */
46 */
47
47
48 /*!
48 /*!
49 \fn QSeriesType QSplineSeries::type() const
49 \fn QSeriesType QSplineSeries::type() const
50 Returns the type of the series
50 Returns the type of the series
51 */
51 */
52
52
53 /*!
53 /*!
54 \fn QSeriesType QSplineSeries::controlPoint(int index) const
54 \fn QSeriesType QSplineSeries::controlPoint(int index) const
55 Returns the control point specified by \a index
55 Returns the control point specified by \a index
56 */
56 */
57
57
58 QTCOMMERCIALCHART_BEGIN_NAMESPACE
58 QTCOMMERCIALCHART_BEGIN_NAMESPACE
59
59
60 /*!
60 /*!
61 Constructs empty series object which is a child of \a parent.
61 Constructs empty series object which is a child of \a parent.
62 When series object is added to QChartView or QChart instance then the ownerships is transferred.
62 When series object is added to QChartView or QChart instance then the ownerships is transferred.
63 */
63 */
64
64
65 QSplineSeries::QSplineSeries(QObject *parent) :
65 QSplineSeries::QSplineSeries(QObject *parent) :
66 QLineSeries(*new QSplineSeriesPrivate(this),parent)
66 QLineSeries(*new QSplineSeriesPrivate(this),parent)
67 {
67 {
68 }
68 }
69
69
70 QSplineSeries::~QSplineSeries()
71 {
72 Q_D(QSplineSeries);
73 if(d->m_dataset){
74 d->m_dataset->removeSeries(this);
75 }
76 }
77
70 QAbstractSeries::QSeriesType QSplineSeries::type() const
78 QAbstractSeries::QSeriesType QSplineSeries::type() const
71 {
79 {
72 return QAbstractSeries::SeriesTypeSpline;
80 return QAbstractSeries::SeriesTypeSpline;
73 }
81 }
74
82
75 QPointF QSplineSeries::controlPoint(int index) const
83 QPointF QSplineSeries::controlPoint(int index) const
76 {
84 {
77 Q_D(const QSplineSeries);
85 Q_D(const QSplineSeries);
78 return d->m_controlPoints[index];
86 return d->m_controlPoints[index];
79 }
87 }
80
88
81 /*!
89 /*!
82 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
90 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
83 as a data source for y coordinate. The \a orientation parameter specifies whether the data
91 as a data source for y coordinate. The \a orientation parameter specifies whether the data
84 is in columns or in rows.
92 is in columns or in rows.
85 \sa setModel()
93 \sa setModel()
86 */
94 */
87 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
95 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
88 {
96 {
89 Q_D(QSplineSeries);
97 Q_D(QSplineSeries);
90 QXYSeries::setModelMapping(modelX, modelY, orientation);
98 QXYSeries::setModelMapping(modelX, modelY, orientation);
91 d->updateControlPoints();
99 d->updateControlPoints();
92 }
100 }
93
101
94 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95
103
96 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
104 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
97 {
105 {
98 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
106 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
107 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
100 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
108 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
101 };
109 };
102
110
103 /*!
111 /*!
104 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
112 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
105 */
113 */
106 void QSplineSeriesPrivate::calculateControlPoints()
114 void QSplineSeriesPrivate::calculateControlPoints()
107 {
115 {
108 Q_Q(QSplineSeries);
116 Q_Q(QSplineSeries);
109
117
110 const QList<QPointF>& points = q->points();
118 const QList<QPointF>& points = q->points();
111
119
112 int n = points.count() - 1;
120 int n = points.count() - 1;
113
121
114 if (n == 1)
122 if (n == 1)
115 {
123 {
116 //for n==1
124 //for n==1
117 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
125 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
118 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
126 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
119 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
127 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
120 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
128 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
121 return;
129 return;
122 }
130 }
123
131
124 // Calculate first Bezier control points
132 // Calculate first Bezier control points
125 // Right hand side vector
133 // Right hand side vector
126 // Set of equations for P0 to Pn points.
134 // Set of equations for P0 to Pn points.
127 //
135 //
128 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
136 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
129 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
137 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
130 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
138 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
131 // | . . . . . . . . . . . . | | ... | | ... |
139 // | . . . . . . . . . . . . | | ... | | ... |
132 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
140 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
133 // | . . . . . . . . . . . . | | ... | | ... |
141 // | . . . . . . . . . . . . | | ... | | ... |
134 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
142 // | 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 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
143 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
136 //
144 //
137 QVector<qreal> vector;
145 QVector<qreal> vector;
138 vector.resize(n);
146 vector.resize(n);
139
147
140 vector[0] = points[0].x() + 2 * points[1].x();
148 vector[0] = points[0].x() + 2 * points[1].x();
141
149
142
150
143 for (int i = 1; i < n - 1; ++i){
151 for (int i = 1; i < n - 1; ++i){
144 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
152 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
145 }
153 }
146
154
147 vector[n - 1] = (8 * points[n-1].x() + points[n].x()) / 2.0;
155 vector[n - 1] = (8 * points[n-1].x() + points[n].x()) / 2.0;
148
156
149 QVector<qreal> xControl = firstControlPoints(vector);
157 QVector<qreal> xControl = firstControlPoints(vector);
150
158
151 vector[0] = points[0].y() + 2 * points[1].y();
159 vector[0] = points[0].y() + 2 * points[1].y();
152
160
153 for (int i = 1; i < n - 1; ++i) {
161 for (int i = 1; i < n - 1; ++i) {
154 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
162 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
155 }
163 }
156
164
157 vector[n - 1] = (8 * points[n-1].y() + points[n].y()) / 2.0;
165 vector[n - 1] = (8 * points[n-1].y() + points[n].y()) / 2.0;
158
166
159 QVector<qreal> yControl = firstControlPoints(vector);
167 QVector<qreal> yControl = firstControlPoints(vector);
160
168
161 for (int i = 0,j =0; i < n; ++i, ++j) {
169 for (int i = 0,j =0; i < n; ++i, ++j) {
162
170
163 m_controlPoints[j].setX(xControl[i]);
171 m_controlPoints[j].setX(xControl[i]);
164 m_controlPoints[j].setY(yControl[i]);
172 m_controlPoints[j].setY(yControl[i]);
165
173
166 j++;
174 j++;
167
175
168 if (i < n - 1){
176 if (i < n - 1){
169 m_controlPoints[j].setX(2 * points[i+1].x() - xControl[i + 1]);
177 m_controlPoints[j].setX(2 * points[i+1].x() - xControl[i + 1]);
170 m_controlPoints[j].setY(2 * points[i+1].y() - yControl[i + 1]);
178 m_controlPoints[j].setY(2 * points[i+1].y() - yControl[i + 1]);
171 }else{
179 }else{
172 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
180 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
173 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
181 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
174 }
182 }
175 }
183 }
176 }
184 }
177
185
178 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
186 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
179 {
187 {
180 QVector<qreal> result;
188 QVector<qreal> result;
181
189
182 int count = vector.count();
190 int count = vector.count();
183 result.resize(count);
191 result.resize(count);
184 result[0] = vector[0] / 2.0;
192 result[0] = vector[0] / 2.0;
185
193
186 QVector<qreal> temp;
194 QVector<qreal> temp;
187 temp.resize(count);
195 temp.resize(count);
188 temp[0] = 0;
196 temp[0] = 0;
189
197
190 qreal b = 2.0;
198 qreal b = 2.0;
191
199
192 for (int i = 1; i < count; i++) {
200 for (int i = 1; i < count; i++) {
193 temp[i] = 1 / b;
201 temp[i] = 1 / b;
194 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
202 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
195 result[i]=(vector[i] - result[i - 1]) / b;
203 result[i]=(vector[i] - result[i - 1]) / b;
196 }
204 }
197 for (int i = 1; i < count; i++)
205 for (int i = 1; i < count; i++)
198 result[count - i - 1] -= temp[count - i] * result[count - i];
206 result[count - i - 1] -= temp[count - i] * result[count - i];
199
207
200 return result;
208 return result;
201 }
209 }
202
210
203 /*!
211 /*!
204 Updates the control points, besed on currently avaiable knots.
212 Updates the control points, besed on currently avaiable knots.
205 */
213 */
206 void QSplineSeriesPrivate::updateControlPoints()
214 void QSplineSeriesPrivate::updateControlPoints()
207 {
215 {
208 Q_Q(QSplineSeries);
216 Q_Q(QSplineSeries);
209 if (q->count() > 1) {
217 if (q->count() > 1) {
210 m_controlPoints.resize(2*q->count()-2);
218 m_controlPoints.resize(2*q->count()-2);
211 calculateControlPoints();
219 calculateControlPoints();
212 }
220 }
213 }
221 }
214
222
215 void QSplineSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
223 void QSplineSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
216 {
224 {
217 updateControlPoints();
225 updateControlPoints();
218 QXYSeriesPrivate::modelDataAdded(parent, start, end);
226 QXYSeriesPrivate::modelDataAdded(parent, start, end);
219 }
227 }
220
228
221 void QSplineSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
229 void QSplineSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
222 {
230 {
223 updateControlPoints();
231 updateControlPoints();
224 QXYSeriesPrivate::modelDataRemoved(parent, start, end);
232 QXYSeriesPrivate::modelDataRemoved(parent, start, end);
225 }
233 }
226
234
227 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
235 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
228 {
236 {
229 Q_Q(QSplineSeries);
237 Q_Q(QSplineSeries);
230 SplineChartItem* spline = new SplineChartItem(q,presenter);
238 SplineChartItem* spline = new SplineChartItem(q,presenter);
231 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
239 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
232 presenter->animator()->addAnimation(spline);
240 presenter->animator()->addAnimation(spline);
233 }
241 }
234 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
242 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
235 return spline;
243 return spline;
236 }
244 }
237
245
238 #include "moc_qsplineseries.cpp"
246 #include "moc_qsplineseries.cpp"
239 #include "moc_qsplineseries_p.cpp"
247 #include "moc_qsplineseries_p.cpp"
240
248
241 QTCOMMERCIALCHART_END_NAMESPACE
249 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,54 +1,55
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 #ifndef QSPLINESERIES_H
21 #ifndef QSPLINESERIES_H
22 #define QSPLINESERIES_H
22 #define QSPLINESERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qlineseries.h>
25 #include <qlineseries.h>
26 #include <QList>
26 #include <QList>
27 #include <QPointF>
27 #include <QPointF>
28 #include <QtGlobal>
28 #include <QtGlobal>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 class QSplineSeriesPrivate;
32 class QSplineSeriesPrivate;
33
33
34 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
34 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
35 {
35 {
36 Q_OBJECT
36 Q_OBJECT
37 public:
37 public:
38
38
39 explicit QSplineSeries(QObject *parent = 0);
39 explicit QSplineSeries(QObject *parent = 0);
40 ~QSplineSeries();
40 QAbstractSeries::QSeriesType type() const;
41 QAbstractSeries::QSeriesType type() const;
41
42
42 QPointF controlPoint(int index) const;
43 QPointF controlPoint(int index) const;
43
44
44 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
45 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
45
46
46 private:
47 private:
47 Q_DECLARE_PRIVATE(QSplineSeries);
48 Q_DECLARE_PRIVATE(QSplineSeries);
48 Q_DISABLE_COPY(QSplineSeries);
49 Q_DISABLE_COPY(QSplineSeries);
49 friend class SplineChartItem;
50 friend class SplineChartItem;
50 };
51 };
51
52
52 QTCOMMERCIALCHART_END_NAMESPACE
53 QTCOMMERCIALCHART_END_NAMESPACE
53
54
54 #endif // QSPLINESERIES_H
55 #endif // QSPLINESERIES_H
@@ -1,140 +1,144
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 "splinechartitem_p.h"
21 #include "splinechartitem_p.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
24 #include "chartanimator_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QDebug>
26
27
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
29
29 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
30 XYChartItem(series, presenter),
31 XYChartItem(series, presenter),
31 m_series(series),
32 m_series(series),
32 m_pointsVisible(false)
33 m_pointsVisible(false)
33 {
34 {
34 setZValue(ChartPresenter::LineChartZValue);
35 setZValue(ChartPresenter::LineChartZValue);
35 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
36 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
36 handleUpdated();
37 handleUpdated();
37 }
38 }
38
39
39 QRectF SplineChartItem::boundingRect() const
40 QRectF SplineChartItem::boundingRect() const
40 {
41 {
41 return m_rect;
42 return m_rect;
42 }
43 }
43
44
44 QPainterPath SplineChartItem::shape() const
45 QPainterPath SplineChartItem::shape() const
45 {
46 {
46 return m_path;
47 return m_path;
47 }
48 }
48
49
49 void SplineChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
50 void SplineChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
50 {
51 {
51 QVector<QPointF> controlPoints;
52 QVector<QPointF> controlPoints;
52
53
53 controlPoints.resize(newPoints.count()*2-2);
54 if(newPoints.count()>=2){
55 controlPoints.resize(newPoints.count()*2-2);
56 }
54
57
55 for (int i = 0; i < newPoints.size() - 1; i++) {
58 for (int i = 0; i < newPoints.size() - 1; i++) {
56 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
59 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
57 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
60 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
58 }
61 }
59
62
60 if (controlPoints.count()<2) {
63 if (controlPoints.count()<2) {
61 setLayout(newPoints,controlPoints);
64 setLayout(newPoints,controlPoints);
62 return;
65 return;
63 }
66 }
64
67
65 if (animator()) {
68 if (animator()) {
66 animator()->updateLayout(this,oldPoints,newPoints,m_controlPoints,controlPoints,index);
69 animator()->updateLayout(this,oldPoints,newPoints,m_controlPoints,controlPoints,index);
67 } else {
70 } else {
68 setLayout(newPoints,controlPoints);
71 setLayout(newPoints,controlPoints);
69 }
72 }
70 }
73 }
71
74
72 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
75 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
73 {
76 {
74 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
77 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
75 }
78 }
76
79
77 void SplineChartItem::setLayout(QVector<QPointF> &points)
80 void SplineChartItem::setLayout(QVector<QPointF> &points)
78 {
81 {
79 // Dummy implementation because of a bug in Clang compiler
82 // Dummy implementation because of a bug in Clang compiler
80 XYChartItem::setLayout(points);
83 XYChartItem::setLayout(points);
81 }
84 }
82
85
83 void SplineChartItem::setLayout(QVector<QPointF> &points, QVector<QPointF> &controlPoints)
86 void SplineChartItem::setLayout(QVector<QPointF> &points, QVector<QPointF> &controlPoints)
84 {
87 {
85 if ((points.size()<2) || (controlPoints.size()<2)) {
88 if ((points.size()<2) || (controlPoints.size()<2)) {
86 XYChartItem::setLayout(points);
89 XYChartItem::setLayout(points);
87 m_controlPoints=controlPoints;
90 m_controlPoints=controlPoints;
88 return;
91 return;
89 }
92 }
90
93
91 Q_ASSERT(points.count()*2-2 == controlPoints.count());
94 Q_ASSERT(points.count()*2-2 == controlPoints.count());
92
95
93 QPainterPath splinePath(points.at(0));
96 QPainterPath splinePath(points.at(0));
94
97
95 for (int i = 0; i < points.size() - 1; i++) {
98 for (int i = 0; i < points.size() - 1; i++) {
96 const QPointF& point = points.at(i + 1);
99 const QPointF& point = points.at(i + 1);
97 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
100 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
98 }
101 }
99
102
100 prepareGeometryChange();
103 prepareGeometryChange();
101 m_path = splinePath;
104 m_path = splinePath;
102 m_rect = splinePath.boundingRect();
105 m_rect = splinePath.boundingRect();
103 XYChartItem::setLayout(points);
106 XYChartItem::setLayout(points);
104 m_controlPoints=controlPoints;
107 m_controlPoints=controlPoints;
108
105 }
109 }
106
110
107 //handlers
111 //handlers
108
112
109 void SplineChartItem::handleUpdated()
113 void SplineChartItem::handleUpdated()
110 {
114 {
111 m_pointsVisible = m_series->pointsVisible();
115 m_pointsVisible = m_series->pointsVisible();
112 m_linePen = m_series->pen();
116 m_linePen = m_series->pen();
113 m_pointPen = m_series->pen();
117 m_pointPen = m_series->pen();
114 m_pointPen.setWidthF(2*m_pointPen.width());
118 m_pointPen.setWidthF(2*m_pointPen.width());
115 update();
119 update();
116 }
120 }
117
121
118 //painter
122 //painter
119
123
120 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
124 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
121 {
125 {
122 Q_UNUSED(widget)
126 Q_UNUSED(widget)
123 Q_UNUSED(option)
127 Q_UNUSED(option)
124
128 qDebug()<<__FUNCTION__;
125 painter->save();
129 painter->save();
126 painter->setClipRect(clipRect());
130 painter->setClipRect(clipRect());
127 painter->setPen(m_linePen);
131 painter->setPen(m_linePen);
128 painter->drawPath(m_path);
132 painter->drawPath(m_path);
129 if (m_pointsVisible) {
133 if (m_pointsVisible) {
130 painter->setPen(m_pointPen);
134 painter->setPen(m_pointPen);
131 painter->drawPoints(points());
135 painter->drawPoints(points());
132 }
136 }
133 painter->restore();
137 painter->restore();
134 }
138 }
135
139
136
140
137
141
138 #include "moc_splinechartitem_p.cpp"
142 #include "moc_splinechartitem_p.cpp"
139
143
140 QTCOMMERCIALCHART_END_NAMESPACE
144 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,475 +1,474
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 /*!
52 /*!
53 \fn void QXYSeriesPrivate::pointReplaced(int index)
53 \fn void QXYSeriesPrivate::pointReplaced(int index)
54 \brief \internal \a index
54 \brief \internal \a index
55 */
55 */
56
56
57 /*!
57 /*!
58 \fn void QXYSeriesPrivate::pointAdded(int index)
58 \fn void QXYSeriesPrivate::pointAdded(int index)
59 \brief \internal \a index
59 \brief \internal \a index
60 */
60 */
61
61
62 /*!
62 /*!
63 \fn void QXYSeriesPrivate::pointRemoved(int index)
63 \fn void QXYSeriesPrivate::pointRemoved(int index)
64 \brief \internal \a index
64 \brief \internal \a index
65 */
65 */
66
66
67 /*!
67 /*!
68 \fn void QXYSeriesPrivate::updated()
68 \fn void QXYSeriesPrivate::updated()
69 \brief \internal
69 \brief \internal
70 */
70 */
71
71
72 /*!
72 /*!
73 \internal
73 \internal
74
74
75 Constructs empty series object which is a child of \a parent.
75 Constructs empty series object which is a child of \a parent.
76 When series object is added to QChartView or QChart instance ownerships is transferred.
76 When series object is added to QChartView or QChart instance ownerships is transferred.
77 */
77 */
78 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
78 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
79 {
79 {
80
80
81 }
81 }
82 /*!
82 /*!
83 Destroys the object. Series added to QChartView or QChart instances are owned by those,
83 Destroys the object. Series added to QChartView or QChart instances are owned by those,
84 and are deleted when mentioned object are destroyed.
84 and are deleted when mentioned object are destroyed.
85 */
85 */
86 QXYSeries::~QXYSeries()
86 QXYSeries::~QXYSeries()
87 {
87 {
88 }
88 }
89
89
90 /*!
90 /*!
91 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
91 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
92 */
92 */
93 void QXYSeries::append(qreal x,qreal y)
93 void QXYSeries::append(qreal x,qreal y)
94 {
94 {
95 append(QPointF(x,y));
95 append(QPointF(x,y));
96 }
96 }
97
97
98 /*!
98 /*!
99 This is an overloaded function.
99 This is an overloaded function.
100 Adds data \a point to the series. Points are connected with lines on the chart.
100 Adds data \a point to the series. Points are connected with lines on the chart.
101 */
101 */
102 void QXYSeries::append(const QPointF &point)
102 void QXYSeries::append(const QPointF &point)
103 {
103 {
104 Q_D(QXYSeries);
104 Q_D(QXYSeries);
105 d->m_points<<point;
105 d->m_points<<point;
106 emit d->pointAdded(d->m_points.count()-1);
106 emit d->pointAdded(d->m_points.count()-1);
107 }
107 }
108
108
109 /*!
109 /*!
110 This is an overloaded function.
110 This is an overloaded function.
111 Adds list of data \a points to the series. Points are connected with lines on the chart.
111 Adds list of data \a points to the series. Points are connected with lines on the chart.
112 */
112 */
113 void QXYSeries::append(const QList<QPointF> &points)
113 void QXYSeries::append(const QList<QPointF> &points)
114 {
114 {
115 foreach(const QPointF& point , points) {
115 foreach(const QPointF& point , points) {
116 append(point);
116 append(point);
117 }
117 }
118 }
118 }
119
119
120
120
121 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
121 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
122 {
122 {
123 replace(QPointF(oldX,oldY),QPointF(newX,newY));
123 replace(QPointF(oldX,oldY),QPointF(newX,newY));
124 }
124 }
125
125
126 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
126 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
127 {
127 {
128 Q_D(QXYSeries);
128 Q_D(QXYSeries);
129 int index = d->m_points.indexOf(oldPoint);
129 int index = d->m_points.indexOf(oldPoint);
130 if(index==-1) return;
130 if(index==-1) return;
131 d->m_points[index] = newPoint;
131 d->m_points[index] = newPoint;
132 emit d->pointReplaced(index);
132 emit d->pointReplaced(index);
133 }
133 }
134
134
135 /*!
135 /*!
136 Removes current \a x and \a y value.
136 Removes current \a x and \a y value.
137 */
137 */
138 void QXYSeries::remove(qreal x,qreal y)
138 void QXYSeries::remove(qreal x,qreal y)
139 {
139 {
140 remove(QPointF(x,y));
140 remove(QPointF(x,y));
141 }
141 }
142
142
143 /*!
143 /*!
144 Removes current \a point x value. Note \a point y value is ignored.
144 Removes current \a point x value. Note \a point y value is ignored.
145 */
145 */
146 void QXYSeries::remove(const QPointF &point)
146 void QXYSeries::remove(const QPointF &point)
147 {
147 {
148 Q_D(QXYSeries);
148 Q_D(QXYSeries);
149 int index = d->m_points.indexOf(point);
149 int index = d->m_points.indexOf(point);
150 if(index==-1) return;
150 if(index==-1) return;
151 d->m_points.remove(index);
151 d->m_points.remove(index);
152 emit d->pointRemoved(index);
152 emit d->pointRemoved(index);
153 }
153 }
154
154
155 /*!
155 /*!
156 Removes all data points from the series.
156 Removes all data points from the series.
157 */
157 */
158 void QXYSeries::removeAll()
158 void QXYSeries::removeAll()
159 {
159 {
160 Q_D(QXYSeries);
160 Q_D(QXYSeries);
161 foreach(const QPointF& point, d->m_points) {
161 foreach(const QPointF& point, d->m_points) {
162 remove(point);
162 remove(point);
163 }
163 }
164 }
164 }
165
165
166 /*!
166 /*!
167 \internal \a pos
167 \internal \a pos
168 */
168 */
169 QList<QPointF> QXYSeries::points() const
169 QList<QPointF> QXYSeries::points() const
170 {
170 {
171 // Q_ASSERT(false);
171 // Q_ASSERT(false);
172 Q_D(const QXYSeries);
172 Q_D(const QXYSeries);
173 if (d->m_model) {
173 if (d->m_model) {
174 QList<QPointF> result;
174 QList<QPointF> result;
175 if (d->m_mapOrientation == Qt::Vertical){
175 if (d->m_mapOrientation == Qt::Vertical){
176 // consecutive data is read from model's column
176 // consecutive data is read from model's column
177
177
178 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
178 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
179 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapX), Qt::DisplayRole).toReal();
179 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapX), Qt::DisplayRole).toReal();
180 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapY), Qt::DisplayRole).toReal();
180 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapY), Qt::DisplayRole).toReal();
181 result << QPointF(x,y);
181 result << QPointF(x,y);
182 }
182 }
183 return result;
183 return result;
184 }
184 }
185 else{
185 else{
186 // consecutive data is read from model's row
186 // consecutive data is read from model's row
187 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
187 for(int i = d->m_mapFirst; i< d->m_mapFirst + count(); ++i) {
188 qreal x = d->m_model->data(d->m_model->index(d->m_mapX, i), Qt::DisplayRole).toReal();
188 qreal x = d->m_model->data(d->m_model->index(d->m_mapX, i), Qt::DisplayRole).toReal();
189 qreal y = d->m_model->data(d->m_model->index(d->m_mapY, i), Qt::DisplayRole).toReal();
189 qreal y = d->m_model->data(d->m_model->index(d->m_mapY, i), Qt::DisplayRole).toReal();
190 result << QPointF(x,y);
190 result << QPointF(x,y);
191 }
191 }
192 return result;
192 return result;
193 }
193 }
194 } else {
194 } else {
195 // model is not specified, return the data from series' internal data store
195 // model is not specified, return the data from series' internal data store
196 return d->m_points.toList();
196 return d->m_points.toList();
197 }
197 }
198 }
198 }
199
199
200 /*!
200 /*!
201 Returns number of data points within series.
201 Returns number of data points within series.
202 */
202 */
203 int QXYSeries::count() const
203 int QXYSeries::count() const
204 {
204 {
205 Q_D(const QXYSeries);
205 Q_D(const QXYSeries);
206
206
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 // data is in a column. Return the number of mapped items if the model's column have enough items
209 // data is in a column. Return the number of mapped items if the model's column have enough items
210 // or the number of items that can be mapped
210 // or the number of items that can be mapped
211 if (d->m_mapCount != -1)
211 if (d->m_mapCount != -1)
212 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
212 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
213 else
213 else
214 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
214 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
215 } else {
215 } else {
216 // data is in a row. Return the number of mapped items if the model's row have enough items
216 // data is in a row. Return the number of mapped items if the model's row have enough items
217 // or the number of items that can be mapped
217 // or the number of items that can be mapped
218 if (d->m_mapCount != -1)
218 if (d->m_mapCount != -1)
219 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
219 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
220 else
220 else
221 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
221 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
222 }
222 }
223 }
223 }
224
224
225 // model is not specified, return the number of points in the series internal data store
225 // model is not specified, return the number of points in the series internal data store
226 return d->m_points.count();
226 return d->m_points.count();
227 }
227 }
228
228
229
229
230 /*!
230 /*!
231 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
231 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
232 pen from chart theme is used.
232 pen from chart theme is used.
233 \sa QChart::setTheme()
233 \sa QChart::setTheme()
234 */
234 */
235 void QXYSeries::setPen(const QPen &pen)
235 void QXYSeries::setPen(const QPen &pen)
236 {
236 {
237 Q_D(QXYSeries);
237 Q_D(QXYSeries);
238 if (d->m_pen!=pen) {
238 if (d->m_pen!=pen) {
239 d->m_pen = pen;
239 d->m_pen = pen;
240 emit d->updated();
240 emit d->updated();
241 }
241 }
242 }
242 }
243
243
244 QPen QXYSeries::pen() const
244 QPen QXYSeries::pen() const
245 {
245 {
246 Q_D(const QXYSeries);
246 Q_D(const QXYSeries);
247 return d->m_pen;
247 return d->m_pen;
248 }
248 }
249
249
250 /*!
250 /*!
251 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
251 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
252 from chart theme setting is used.
252 from chart theme setting is used.
253 \sa QChart::setTheme()
253 \sa QChart::setTheme()
254 */
254 */
255 void QXYSeries::setBrush(const QBrush &brush)
255 void QXYSeries::setBrush(const QBrush &brush)
256 {
256 {
257 Q_D(QXYSeries);
257 Q_D(QXYSeries);
258 if (d->m_brush!=brush) {
258 if (d->m_brush!=brush) {
259 d->m_brush = brush;
259 d->m_brush = brush;
260 emit d->updated();
260 emit d->updated();
261 }
261 }
262 }
262 }
263
263
264 QBrush QXYSeries::brush() const
264 QBrush QXYSeries::brush() const
265 {
265 {
266 Q_D(const QXYSeries);
266 Q_D(const QXYSeries);
267 return d->m_brush;
267 return d->m_brush;
268 }
268 }
269
269
270
270
271 /*!
271 /*!
272 Sets if data points are \a visible and should be drawn on line.
272 Sets if data points are \a visible and should be drawn on line.
273 */
273 */
274 void QXYSeries::setPointsVisible(bool visible)
274 void QXYSeries::setPointsVisible(bool visible)
275 {
275 {
276 Q_D(QXYSeries);
276 Q_D(QXYSeries);
277 if (d->m_pointsVisible != visible){
277 if (d->m_pointsVisible != visible){
278 d->m_pointsVisible = visible;
278 d->m_pointsVisible = visible;
279 emit d->updated();
279 emit d->updated();
280 }
280 }
281 }
281 }
282
282
283 /*!
283 /*!
284 Returns true if drawing the data points of the series is enabled.
284 Returns true if drawing the data points of the series is enabled.
285 */
285 */
286 bool QXYSeries::pointsVisible() const
286 bool QXYSeries::pointsVisible() const
287 {
287 {
288 Q_D(const QXYSeries);
288 Q_D(const QXYSeries);
289 return d->m_pointsVisible;
289 return d->m_pointsVisible;
290 }
290 }
291
291
292
292
293 /*!
293 /*!
294 Stream operator for adding a data \a point to the series.
294 Stream operator for adding a data \a point to the series.
295 \sa append()
295 \sa append()
296 */
296 */
297 QXYSeries& QXYSeries::operator<< (const QPointF &point)
297 QXYSeries& QXYSeries::operator<< (const QPointF &point)
298 {
298 {
299 append(point);
299 append(point);
300 return *this;
300 return *this;
301 }
301 }
302
302
303
303
304 /*!
304 /*!
305 Stream operator for adding a list of \a points to the series.
305 Stream operator for adding a list of \a points to the series.
306 \sa append()
306 \sa append()
307 */
307 */
308
308
309 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
309 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
310 {
310 {
311 append(points);
311 append(points);
312 return *this;
312 return *this;
313 }
313 }
314
314
315 /*!
315 /*!
316 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
316 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
317 Sets the \a model to be used as a data source
317 Sets the \a model to be used as a data source
318 \sa setModelMapping()
318 \sa setModelMapping()
319 */
319 */
320 bool QXYSeries::setModel(QAbstractItemModel *model)
320 bool QXYSeries::setModel(QAbstractItemModel *model)
321 {
321 {
322 Q_D(QXYSeries);
322 Q_D(QXYSeries);
323 // disconnect signals from old model
323 // disconnect signals from old model
324 if (d->m_model) {
324 if (d->m_model) {
325 QObject::disconnect(d->m_model, 0, this, 0);
325 QObject::disconnect(d->m_model, 0, this, 0);
326 d->m_mapX = -1;
326 d->m_mapX = -1;
327 d->m_mapY = -1;
327 d->m_mapY = -1;
328 d->m_mapFirst = 0;
328 d->m_mapFirst = 0;
329 d->m_mapCount = -1;
329 d->m_mapCount = -1;
330 d->m_mapOrientation = Qt::Vertical;
330 d->m_mapOrientation = Qt::Vertical;
331 }
331 }
332
332
333 // set new model
333 // set new model
334 if (model) {
334 if (model) {
335 d->m_model = model;
335 d->m_model = model;
336 return true;
336 return true;
337 } else {
337 } else {
338 d->m_model = 0;
338 d->m_model = 0;
339 return false;
339 return false;
340 }
340 }
341 }
341 }
342
342
343 /*!
343 /*!
344 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
344 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
345 as a data source for y coordinate. The \a orientation parameter specifies whether the data
345 as a data source for y coordinate. The \a orientation parameter specifies whether the data
346 is in columns or in rows.
346 is in columns or in rows.
347 \sa setModel()
347 \sa setModel()
348 */
348 */
349 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
349 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
350 {
350 {
351 Q_D(QXYSeries);
351 Q_D(QXYSeries);
352 if (d->m_model == 0)
352 if (d->m_model == 0)
353 return;
353 return;
354 d->m_mapX = modelX;
354 d->m_mapX = modelX;
355 d->m_mapY = modelY;
355 d->m_mapY = modelY;
356 d->m_mapOrientation = orientation;
356 d->m_mapOrientation = orientation;
357
357
358 // connect the signals from the model
358 // connect the signals from the model
359 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
359 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
360 if (d->m_mapOrientation == Qt::Vertical) {
360 if (d->m_mapOrientation == Qt::Vertical) {
361 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
361 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
362 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
362 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
363 } else {
363 } else {
364 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
364 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
365 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
365 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
366 }
366 }
367 }
367 }
368
368
369 void QXYSeries::setModelMappingRange(int first, int count)
369 void QXYSeries::setModelMappingRange(int first, int count)
370 {
370 {
371 Q_D(QXYSeries);
371 Q_D(QXYSeries);
372 d->m_mapFirst = qMax(first, 0);
372 d->m_mapFirst = qMax(first, 0);
373 d->m_mapCount = qMax(count, -1);
373 d->m_mapCount = qMax(count, -1);
374 }
374 }
375
375
376 int QXYSeries::mapX() const
376 int QXYSeries::mapX() const
377 {
377 {
378 Q_D(const QXYSeries);
378 Q_D(const QXYSeries);
379 return d->m_mapX;
379 return d->m_mapX;
380 }
380 }
381
381
382 int QXYSeries::mapY() const
382 int QXYSeries::mapY() const
383 {
383 {
384 Q_D(const QXYSeries);
384 Q_D(const QXYSeries);
385 return d->m_mapY;
385 return d->m_mapY;
386
386
387 }
387 }
388
388
389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
390
390
391
391
392 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
392 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
393 m_mapX(-1),
393 m_mapX(-1),
394 m_mapY(-1),
394 m_mapY(-1),
395 m_pointsVisible(false)
395 m_pointsVisible(false)
396 {
396 {
397 }
397 }
398
398
399 void QXYSeriesPrivate::scaleDomain(Domain& domain)
399 void QXYSeriesPrivate::scaleDomain(Domain& domain)
400 {
400 {
401 qreal minX(domain.minX());
401 qreal minX(domain.minX());
402 qreal minY(domain.minY());
402 qreal minY(domain.minY());
403 qreal maxX(domain.maxX());
403 qreal maxX(domain.maxX());
404 qreal maxY(domain.maxY());
404 qreal maxY(domain.maxY());
405 int tickXCount(domain.tickXCount());
405 int tickXCount(domain.tickXCount());
406 int tickYCount(domain.tickYCount());
406 int tickYCount(domain.tickYCount());
407
407
408 Q_Q(QXYSeries);
408 Q_Q(QXYSeries);
409
409
410 const QList<QPointF>& points = q->points();
410 const QList<QPointF>& points = q->points();
411
411
412 if(points.isEmpty()){
412 if(points.isEmpty()){
413 minX=0.0;
413 minX=0.0;
414 minY=0.0;
414 minY=0.0;
415 maxX=1.0;
415 maxX=1.0;
416 maxY=1.0;
416 maxY=1.0;
417 }
417 }
418
418
419
420 for (int i = 0; i < points.count(); i++)
419 for (int i = 0; i < points.count(); i++)
421 {
420 {
422 qreal x = points[i].x();
421 qreal x = points[i].x();
423 qreal y = points[i].y();
422 qreal y = points[i].y();
424 minX = qMin(minX, x);
423 minX = qMin(minX, x);
425 minY = qMin(minY, y);
424 minY = qMin(minY, y);
426 maxX = qMax(maxX, x);
425 maxX = qMax(maxX, x);
427 maxY = qMax(maxY, y);
426 maxY = qMax(maxY, y);
428 }
427 }
429
428
430 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
429 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
431 }
430 }
432
431
433 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
432 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
434 {
433 {
435 Q_Q(QXYSeries);
434 Q_Q(QXYSeries);
436 QList<LegendMarker*> list;
435 QList<LegendMarker*> list;
437 return list << new XYLegendMarker(q,legend);
436 return list << new XYLegendMarker(q,legend);
438 }
437 }
439
438
440 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
439 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
441 {
440 {
442 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
441 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
443 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
442 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
444 if (m_mapOrientation == Qt::Vertical) {
443 if (m_mapOrientation == Qt::Vertical) {
445 if ((column == m_mapX || column == m_mapY) // modified item is in a mapped column
444 if ((column == m_mapX || column == m_mapY) // modified item is in a mapped column
446 && row >= m_mapFirst // modfied item in not before first item
445 && row >= m_mapFirst // modfied item in not before first item
447 && (m_mapCount == -1 || row < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
446 && (m_mapCount == -1 || row < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
448 emit pointReplaced(row - m_mapFirst);
447 emit pointReplaced(row - m_mapFirst);
449 } else {
448 } else {
450 if ((row == m_mapX || row == m_mapY) // modified item is in a mapped row
449 if ((row == m_mapX || row == m_mapY) // modified item is in a mapped row
451 && column >= m_mapFirst // modfied item in not before first item
450 && column >= m_mapFirst // modfied item in not before first item
452 && (m_mapCount == -1 || column < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
451 && (m_mapCount == -1 || column < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
453 emit pointReplaced(column - m_mapFirst);
452 emit pointReplaced(column - m_mapFirst);
454 }
453 }
455 }
454 }
456 }
455 }
457 }
456 }
458
457
459
458
460 void QXYSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
459 void QXYSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
461 {
460 {
462 Q_UNUSED(parent);
461 Q_UNUSED(parent);
463 emit pointsAdded(start, end);
462 emit pointsAdded(start, end);
464 }
463 }
465
464
466 void QXYSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
465 void QXYSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
467 {
466 {
468 Q_UNUSED(parent);
467 Q_UNUSED(parent);
469 emit pointsRemoved(start, end);
468 emit pointsRemoved(start, end);
470 }
469 }
471
470
472 #include "moc_qxyseries.cpp"
471 #include "moc_qxyseries.cpp"
473 #include "moc_qxyseries_p.cpp"
472 #include "moc_qxyseries_p.cpp"
474
473
475 QTCOMMERCIALCHART_END_NAMESPACE
474 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,252 +1,252
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 "xychartitem_p.h"
21 #include "xychartitem_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartanimator_p.h"
25 #include "chartanimator_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <QGraphicsSceneMouseEvent>
27 #include <QGraphicsSceneMouseEvent>
28 #include <QAbstractItemModel>
28 #include <QAbstractItemModel>
29
29
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 //TODO: optimize : remove points which are not visible
33 //TODO: optimize : remove points which are not visible
34
34
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
36 m_minX(0),
36 m_minX(0),
37 m_maxX(0),
37 m_maxX(0),
38 m_minY(0),
38 m_minY(0),
39 m_maxY(0),
39 m_maxY(0),
40 m_series(series)
40 m_series(series)
41 {
41 {
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
48 }
48 }
49
49
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
51 {
51 {
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
54 qreal x = (point.x() - m_minX)* deltaX;
54 qreal x = (point.x() - m_minX)* deltaX;
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
56 return QPointF(x,y);
56 return QPointF(x,y);
57 }
57 }
58
58
59
59
60 QPointF XYChartItem::calculateGeometryPoint(int index) const
60 QPointF XYChartItem::calculateGeometryPoint(int index) const
61 {
61 {
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
64 const QList<QPointF>& vector = m_series->points();
64 const QList<QPointF>& vector = m_series->points();
65 qreal x = (vector[index].x() - m_minX)* deltaX;
65 qreal x = (vector[index].x() - m_minX)* deltaX;
66 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
66 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
67 return QPointF(x,y);
67 return QPointF(x,y);
68 }
68 }
69
69
70 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
70 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
71 {
71 {
72 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
72 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
73 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
73 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
74
74
75 QVector<QPointF> result;
75 QVector<QPointF> result;
76 result.resize(m_series->count());
76 result.resize(m_series->count());
77 const QList<QPointF>& vector = m_series->points();
77 const QList<QPointF>& vector = m_series->points();
78 for (int i = 0; i < m_series->count(); ++i) {
78 for (int i = 0; i < m_series->count(); ++i) {
79 qreal x = (vector[i].x() - m_minX)* deltaX;
79 qreal x = (vector[i].x() - m_minX)* deltaX;
80 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
80 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
81 result[i].setX(x);
81 result[i].setX(x);
82 result[i].setY(y);
82 result[i].setY(y);
83 }
83 }
84 return result;
84 return result;
85 }
85 }
86
86
87 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
87 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
88 {
88 {
89 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
89 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
90 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
90 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
91 qreal x = point.x()/deltaX +m_minX;
91 qreal x = point.x()/deltaX +m_minX;
92 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
92 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
93 return QPointF(x,y);
93 return QPointF(x,y);
94 }
94 }
95
95
96 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
96 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
97 {
97 {
98 if (animator()) {
98 if (animator()) {
99 animator()->updateLayout(this,oldPoints,newPoints,index);
99 animator()->updateLayout(this,oldPoints,newPoints,index);
100 } else {
100 } else {
101 setLayout(newPoints);
101 setLayout(newPoints);
102 }
102 }
103 }
103 }
104
104
105 void XYChartItem::setLayout(QVector<QPointF> &points)
105 void XYChartItem::setLayout(QVector<QPointF> &points)
106 {
106 {
107 m_points = points;
107 m_points = points;
108 update();
108 update();
109 }
109 }
110
110
111 //handlers
111 //handlers
112
112
113 void XYChartItem::handlePointAdded(int index)
113 void XYChartItem::handlePointAdded(int index)
114 {
114 {
115 if (m_series->model() == 0) {
115 if (m_series->model() == 0) {
116 Q_ASSERT(index<m_series->count());
116 Q_ASSERT(index<m_series->count());
117 Q_ASSERT(index>=0);
117 Q_ASSERT(index>=0);
118 }
118 }
119 QVector<QPointF> points = m_points;
119 QVector<QPointF> points = m_points;
120 QPointF point;
120 QPointF point;
121 point = calculateGeometryPoint(index);
121 point = calculateGeometryPoint(index);
122 points.insert(index, point);
122 points.insert(index, point);
123 updateLayout(m_points, points, index);
123 updateLayout(m_points, points, index);
124 update();
124 update();
125 }
125 }
126
126
127 void XYChartItem::handlePointsAdded(int start, int end)
127 void XYChartItem::handlePointsAdded(int start, int end)
128 {
128 {
129 if (m_series->model() == 0) {
129 if (m_series->model() == 0) {
130 for (int i = start; i <= end; i++)
130 for (int i = start; i <= end; i++)
131 handlePointAdded(i);
131 handlePointAdded(i);
132 } else if (m_series->mapCount() != -1 && start >= m_series->mapFirst() + m_series->mapCount()) {
132 } else if (m_series->mapCount() != -1 && start >= m_series->mapFirst() + m_series->mapCount()) {
133 return;
133 return;
134 } else {
134 } else {
135 int addedCount = end - start + 1;
135 int addedCount = end - start + 1;
136 if (m_series->mapCount() != -1 && addedCount > m_series->mapCount())
136 if (m_series->mapCount() != -1 && addedCount > m_series->mapCount())
137 addedCount = m_series->mapCount();
137 addedCount = m_series->mapCount();
138 int first = qMax(start, m_series->mapFirst()); // get the index of the first item that will be added
138 int first = qMax(start, m_series->mapFirst()); // get the index of the first item that will be added
139 int last = qMin(first + addedCount - 1, m_series->count() + m_series->mapFirst() - 1); // get the index of the last item that will be added
139 int last = qMin(first + addedCount - 1, m_series->count() + m_series->mapFirst() - 1); // get the index of the last item that will be added
140 for (int i = first; i <= last; i++) {
140 for (int i = first; i <= last; i++) {
141 handlePointAdded(i - m_series->mapFirst());
141 handlePointAdded(i - m_series->mapFirst());
142 }
142 }
143 // the map is limited therefore the items that are now outside the map
143 // the map is limited therefore the items that are now outside the map
144 // need to be removed from the drawn points
144 // need to be removed from the drawn points
145 if (m_series->mapCount() != -1 && m_points.size() > m_series->mapCount())
145 if (m_series->mapCount() != -1 && m_points.size() > m_series->mapCount())
146 for (int i = m_points.size() - 1; i >= m_series->mapCount(); i--)
146 for (int i = m_points.size() - 1; i >= m_series->mapCount(); i--)
147 handlePointRemoved(i);
147 handlePointRemoved(i);
148 }
148 }
149 }
149 }
150
150
151 void XYChartItem::handlePointRemoved(int index)
151 void XYChartItem::handlePointRemoved(int index)
152 {
152 {
153 if (m_series->model() == 0) {
153 if (m_series->model() == 0) {
154 Q_ASSERT(index<m_series->count() + 1);
154 Q_ASSERT(index<m_series->count() + 1);
155 Q_ASSERT(index>=0);
155 Q_ASSERT(index>=0);
156 }
156 }
157 QVector<QPointF> points = m_points;
157 QVector<QPointF> points = m_points;
158 points.remove(index);
158 points.remove(index);
159 updateLayout(m_points, points, index);
159 updateLayout(m_points, points, index);
160 update();
160 update();
161 }
161 }
162
162
163 void XYChartItem::handlePointsRemoved(int start, int end)
163 void XYChartItem::handlePointsRemoved(int start, int end)
164 {
164 {
165 Q_UNUSED(start)
165 Q_UNUSED(start)
166 Q_UNUSED(end)
166 Q_UNUSED(end)
167 if (m_series->model() == 0) {
167 if (m_series->model() == 0) {
168 for (int i = end; i >= start; i--)
168 for (int i = end; i >= start; i--)
169 handlePointRemoved(i);
169 handlePointRemoved(i);
170 } else {
170 } else {
171 // series uses model as a data source
171 // series uses model as a data source
172 int mapFirst = m_series->mapFirst();
172 int mapFirst = m_series->mapFirst();
173 int mapCount = m_series->mapCount();
173 int mapCount = m_series->mapCount();
174 int removedCount = end - start + 1;
174 int removedCount = end - start + 1;
175 if (mapCount != -1 && start >= mapFirst + mapCount) {
175 if (mapCount != -1 && start >= mapFirst + mapCount) {
176 return;
176 return;
177 } else {
177 } else {
178 int toRemove = qMin(m_points.size(), removedCount); // first find how many items can actually be removed
178 int toRemove = qMin(m_points.size(), removedCount); // first find how many items can actually be removed
179 int first = qMax(start, mapFirst); // get the index of the first item that will be removed.
179 int first = qMax(start, mapFirst); // get the index of the first item that will be removed.
180 int last = qMin(first + toRemove - 1, m_points.size() + mapFirst - 1); // get the index of the last item that will be removed.
180 int last = qMin(first + toRemove - 1, m_points.size() + mapFirst - 1); // get the index of the last item that will be removed.
181 for (int i = last; i >= first; i--) {
181 for (int i = last; i >= first; i--) {
182 handlePointRemoved(i - mapFirst);
182 handlePointRemoved(i - mapFirst);
183
183
184 }
184 }
185 if (mapCount != -1) {
185 if (mapCount != -1) {
186 int itemsAvailable; // check how many are available to be added
186 int itemsAvailable; // check how many are available to be added
187 if (m_series->mapOrientation() == Qt::Vertical)
187 if (m_series->mapOrientation() == Qt::Vertical)
188 itemsAvailable = m_series->model()->rowCount() - mapFirst - m_points.size();
188 itemsAvailable = m_series->model()->rowCount() - mapFirst - m_points.size();
189 else
189 else
190 itemsAvailable = m_series->model()->columnCount() - mapFirst - m_points.size();
190 itemsAvailable = m_series->model()->columnCount() - mapFirst - m_points.size();
191 int toBeAdded = qMin(itemsAvailable, mapCount - m_points.size()); // add not more items than there is space left to be filled.
191 int toBeAdded = qMin(itemsAvailable, mapCount - m_points.size()); // add not more items than there is space left to be filled.
192 int currentSize = m_points.size();
192 int currentSize = m_points.size();
193 if (toBeAdded > 0)
193 if (toBeAdded > 0)
194 for (int i = m_points.size(); i < currentSize + toBeAdded; i++) {
194 for (int i = m_points.size(); i < currentSize + toBeAdded; i++) {
195 handlePointAdded(i);
195 handlePointAdded(i);
196 }
196 }
197 }
197 }
198 }
198 }
199 }
199 }
200
200
201 }
201 }
202
202
203 void XYChartItem::handlePointReplaced(int index)
203 void XYChartItem::handlePointReplaced(int index)
204 {
204 {
205 Q_ASSERT(index<m_series->count());
205 Q_ASSERT(index<m_series->count());
206 Q_ASSERT(index>=0);
206 Q_ASSERT(index>=0);
207 QPointF point = calculateGeometryPoint(index);
207 QPointF point = calculateGeometryPoint(index);
208 QVector<QPointF> points = m_points;
208 QVector<QPointF> points = m_points;
209 points.replace(index,point);
209 points.replace(index,point);
210 updateLayout(m_points,points,index);
210 updateLayout(m_points,points,index);
211 update();
211 update();
212 }
212 }
213
213
214 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
214 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
215 {
215 {
216 m_minX=minX;
216 m_minX=minX;
217 m_maxX=maxX;
217 m_maxX=maxX;
218 m_minY=minY;
218 m_minY=minY;
219 m_maxY=maxY;
219 m_maxY=maxY;
220 if (isEmpty()) return;
220 if (isEmpty()) return;
221 QVector<QPointF> points = calculateGeometryPoints();
221 QVector<QPointF> points = calculateGeometryPoints();
222 updateLayout(m_points,points);
222 updateLayout(m_points,points);
223 update();
223 update();
224 }
224 }
225
225
226 void XYChartItem::handleGeometryChanged(const QRectF &rect)
226 void XYChartItem::handleGeometryChanged(const QRectF &rect)
227 {
227 {
228 Q_ASSERT(rect.isValid());
228 Q_ASSERT(rect.isValid());
229 m_size=rect.size();
229 m_size=rect.size();
230 m_clipRect=rect.translated(-rect.topLeft());
230 m_clipRect=rect.translated(-rect.topLeft());
231 setPos(rect.topLeft());
231 setPos(rect.topLeft());
232
232
233 if (isEmpty()) return;
233 if (isEmpty()) return;
234 QVector<QPointF> points = calculateGeometryPoints();
234 QVector<QPointF> points = calculateGeometryPoints();
235 updateLayout(m_points,points);
235 updateLayout(m_points,points);
236 update();
236 update();
237 }
237 }
238
238
239
239
240 bool XYChartItem::isEmpty()
240 bool XYChartItem::isEmpty()
241 {
241 {
242 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
242 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
243 }
243 }
244
244
245 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
245 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
246 {
246 {
247 emit clicked(calculateDomainPoint(event->pos()));
247 emit clicked(calculateDomainPoint(event->pos()));
248 }
248 }
249
249
250 #include "moc_xychartitem_p.cpp"
250 #include "moc_xychartitem_p.cpp"
251
251
252 QTCOMMERCIALCHART_END_NAMESPACE
252 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,572 +1,568
1 #include <QtTest/QtTest>
1 #include <QtTest/QtTest>
2 #include <qchartview.h>
2 #include <qchartview.h>
3 #include <qlineseries.h>
3 #include <qlineseries.h>
4 #include <qareaseries.h>
4 #include <qareaseries.h>
5 #include <qscatterseries.h>
5 #include <qscatterseries.h>
6 #include <qsplineseries.h>
6 #include <qsplineseries.h>
7 #include <qpieseries.h>
7 #include <qpieseries.h>
8 #include <qbarseries.h>
8 #include <qbarseries.h>
9 #include <qpercentbarseries.h>
9 #include <qpercentbarseries.h>
10 #include <qstackedbarseries.h>
10 #include <qstackedbarseries.h>
11
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
13
14 Q_DECLARE_METATYPE(QAxis *)
14 Q_DECLARE_METATYPE(QAxis *)
15 Q_DECLARE_METATYPE(QAbstractSeries *)
15 Q_DECLARE_METATYPE(QAbstractSeries *)
16 Q_DECLARE_METATYPE(QChart::AnimationOption)
16 Q_DECLARE_METATYPE(QChart::AnimationOption)
17 Q_DECLARE_METATYPE(QBrush)
17 Q_DECLARE_METATYPE(QBrush)
18 Q_DECLARE_METATYPE(QPen)
18 Q_DECLARE_METATYPE(QPen)
19 Q_DECLARE_METATYPE(QChart::ChartTheme)
19 Q_DECLARE_METATYPE(QChart::ChartTheme)
20
20
21 class tst_QChart : public QObject
21 class tst_QChart : public QObject
22 {
22 {
23 Q_OBJECT
23 Q_OBJECT
24
24
25 public slots:
25 public slots:
26 void initTestCase();
26 void initTestCase();
27 void cleanupTestCase();
27 void cleanupTestCase();
28 void init();
28 void init();
29 void cleanup();
29 void cleanup();
30
30
31 private slots:
31 private slots:
32 void qchart_data();
32 void qchart_data();
33 void qchart();
33 void qchart();
34
34
35 void addSeries_data();
35 void addSeries_data();
36 void addSeries();
36 void addSeries();
37 void animationOptions_data();
37 void animationOptions_data();
38 void animationOptions();
38 void animationOptions();
39 void axisX_data();
39 void axisX_data();
40 void axisX();
40 void axisX();
41 void axisY_data();
41 void axisY_data();
42 void axisY();
42 void axisY();
43 void backgroundBrush_data();
43 void backgroundBrush_data();
44 void backgroundBrush();
44 void backgroundBrush();
45 void backgroundPen_data();
45 void backgroundPen_data();
46 void backgroundPen();
46 void backgroundPen();
47 void isBackgroundVisible_data();
47 void isBackgroundVisible_data();
48 void isBackgroundVisible();
48 void isBackgroundVisible();
49 void legend_data();
49 void legend_data();
50 void legend();
50 void legend();
51 void margins_data();
51 void margins_data();
52 void margins();
52 void margins();
53 void removeAllSeries_data();
53 void removeAllSeries_data();
54 void removeAllSeries();
54 void removeAllSeries();
55 void removeSeries_data();
55 void removeSeries_data();
56 void removeSeries();
56 void removeSeries();
57 void scrollDown_data();
57 void scrollDown_data();
58 void scrollDown();
58 void scrollDown();
59 void scrollLeft_data();
59 void scrollLeft_data();
60 void scrollLeft();
60 void scrollLeft();
61 void scrollRight_data();
61 void scrollRight_data();
62 void scrollRight();
62 void scrollRight();
63 void scrollUp_data();
63 void scrollUp_data();
64 void scrollUp();
64 void scrollUp();
65 void theme_data();
65 void theme_data();
66 void theme();
66 void theme();
67 void title_data();
67 void title_data();
68 void title();
68 void title();
69 void titleBrush_data();
69 void titleBrush_data();
70 void titleBrush();
70 void titleBrush();
71 void titleFont_data();
71 void titleFont_data();
72 void titleFont();
72 void titleFont();
73 void zoomIn_data();
73 void zoomIn_data();
74 void zoomIn();
74 void zoomIn();
75 void zoomOut_data();
75 void zoomOut_data();
76 void zoomOut();
76 void zoomOut();
77
77
78 private:
78 private:
79 void createTestData();
79 void createTestData();
80
80
81 private:
81 private:
82 QChartView* m_view;
82 QChartView* m_view;
83 QChart* m_chart;
83 QChart* m_chart;
84 };
84 };
85
85
86 void tst_QChart::initTestCase()
86 void tst_QChart::initTestCase()
87 {
87 {
88
88
89 }
89 }
90
90
91 void tst_QChart::cleanupTestCase()
91 void tst_QChart::cleanupTestCase()
92 {
92 {
93
93
94 }
94 }
95
95
96 void tst_QChart::init()
96 void tst_QChart::init()
97 {
97 {
98 m_view = new QChartView(new QChart());
98 m_view = new QChartView(new QChart());
99 m_chart = m_view->chart();
99 m_chart = m_view->chart();
100 }
100 }
101
101
102 void tst_QChart::createTestData()
102 void tst_QChart::createTestData()
103 {
103 {
104 QLineSeries* series0 = new QLineSeries(this);
104 QLineSeries* series0 = new QLineSeries(this);
105 *series0 << QPointF(0, 0) << QPointF(100, 100);
105 *series0 << QPointF(0, 0) << QPointF(100, 100);
106 m_chart->addSeries(series0);
106 m_chart->addSeries(series0);
107 m_view->show();
107 m_view->show();
108 QTest::qWaitForWindowShown(m_view);
108 QTest::qWaitForWindowShown(m_view);
109 }
109 }
110
110
111 void tst_QChart::cleanup()
111 void tst_QChart::cleanup()
112 {
112 {
113 delete m_view;
113 delete m_view;
114 m_view = 0;
114 m_view = 0;
115 m_chart = 0;
115 m_chart = 0;
116 }
116 }
117
117
118 void tst_QChart::qchart_data()
118 void tst_QChart::qchart_data()
119 {
119 {
120 }
120 }
121
121
122 void tst_QChart::qchart()
122 void tst_QChart::qchart()
123 {
123 {
124 QVERIFY(m_chart);
124 QVERIFY(m_chart);
125 QVERIFY(m_chart->legend());
125 QVERIFY(m_chart->legend());
126 QVERIFY(!m_chart->legend()->isVisible());
126 QVERIFY(!m_chart->legend()->isVisible());
127
127
128 QCOMPARE(m_chart->animationOptions(), QChart::NoAnimation);
128 QCOMPARE(m_chart->animationOptions(), QChart::NoAnimation);
129 QVERIFY(m_chart->axisX());
129 QVERIFY(m_chart->axisX());
130 QVERIFY(m_chart->axisY());
130 QVERIFY(m_chart->axisY());
131 QVERIFY(m_chart->backgroundBrush()!=QBrush());
131 QVERIFY(m_chart->backgroundBrush()!=QBrush());
132 QVERIFY(m_chart->backgroundPen()!=QPen());
132 QVERIFY(m_chart->backgroundPen()!=QPen());
133 QCOMPARE(m_chart->isBackgroundVisible(), true);
133 QCOMPARE(m_chart->isBackgroundVisible(), true);
134
134
135 QVERIFY(m_chart->margins().top()>0);
135 QVERIFY(m_chart->margins().top()>0);
136 QVERIFY(m_chart->margins().left()>0);
136 QVERIFY(m_chart->margins().left()>0);
137 QVERIFY(m_chart->margins().right()>0);
137 QVERIFY(m_chart->margins().right()>0);
138 QVERIFY(m_chart->margins().bottom()>0);
138 QVERIFY(m_chart->margins().bottom()>0);
139
139
140 QCOMPARE(m_chart->theme(), QChart::ChartThemeLight);
140 QCOMPARE(m_chart->theme(), QChart::ChartThemeLight);
141 QCOMPARE(m_chart->title(), QString());
141 QCOMPARE(m_chart->title(), QString());
142
142
143 //QCOMPARE(m_chart->titleBrush(),QBrush());
143 //QCOMPARE(m_chart->titleBrush(),QBrush());
144 //QCOMPARE(m_chart->titleFont(),QFont());
144 //QCOMPARE(m_chart->titleFont(),QFont());
145
145
146 m_chart->removeAllSeries();
146 m_chart->removeAllSeries();
147 m_chart->scrollDown();
147 m_chart->scrollDown();
148 m_chart->scrollLeft();
148 m_chart->scrollLeft();
149 m_chart->scrollRight();
149 m_chart->scrollRight();
150 m_chart->scrollUp();
150 m_chart->scrollUp();
151
151
152 m_chart->zoomIn();
152 m_chart->zoomIn();
153 m_chart->zoomIn(QRectF());
153 m_chart->zoomIn(QRectF());
154 m_chart->zoomOut();
154 m_chart->zoomOut();
155 }
155 }
156
156
157 void tst_QChart::addSeries_data()
157 void tst_QChart::addSeries_data()
158 {
158 {
159 QTest::addColumn<QAbstractSeries *>("series");
159 QTest::addColumn<QAbstractSeries *>("series");
160 QTest::addColumn<QAxis *>("axis");
160 QTest::addColumn<QAxis *>("axis");
161
161
162 QAbstractSeries* series0 = new QLineSeries(this);
162 QAbstractSeries* series0 = new QLineSeries(this);
163 QAbstractSeries* series1 = new QAreaSeries(static_cast<QLineSeries*>(series0));
163 QAbstractSeries* series1 = new QAreaSeries(static_cast<QLineSeries*>(series0));
164 QAbstractSeries* series2 = new QScatterSeries(this);
164 QAbstractSeries* series2 = new QScatterSeries(this);
165 QAbstractSeries* series3 = new QSplineSeries(this);
165 QAbstractSeries* series3 = new QSplineSeries(this);
166 QAbstractSeries* series4 = new QPieSeries(this);
166 QAbstractSeries* series4 = new QPieSeries(this);
167 QAbstractSeries* series5 = new QBarSeries(QBarCategories(),this);
167 QAbstractSeries* series5 = new QBarSeries(QBarCategories(),this);
168 QAbstractSeries* series6 = new QPercentBarSeries(QBarCategories(),this);
168 QAbstractSeries* series6 = new QPercentBarSeries(QBarCategories(),this);
169 QAbstractSeries* series7 = new QStackedBarSeries(QBarCategories(),this);
169 QAbstractSeries* series7 = new QStackedBarSeries(QBarCategories(),this);
170
170
171 QAxis* axis = new QAxis(this);
171 QAxis* axis = new QAxis(this);
172
172
173 QTest::newRow("default axis: lineSeries") << series0 << (QAxis*) 0;
173 QTest::newRow("default axis: lineSeries") << series0 << (QAxis*) 0;
174 QTest::newRow("axis0: lineSeries") << series0 << axis;
174 QTest::newRow("axis0: lineSeries") << series0 << axis;
175 QTest::newRow("default axis: areaSeries") << series1 << (QAxis*) 0;
175 QTest::newRow("default axis: areaSeries") << series1 << (QAxis*) 0;
176 QTest::newRow("axis: areaSeries") << series1 << axis;
176 QTest::newRow("axis: areaSeries") << series1 << axis;
177 QTest::newRow("default axis: scatterSeries") << series2 << (QAxis*) 0;
177 QTest::newRow("default axis: scatterSeries") << series2 << (QAxis*) 0;
178 QTest::newRow("axis1: scatterSeries") << series2 << axis;
178 QTest::newRow("axis1: scatterSeries") << series2 << axis;
179 QTest::newRow("default axis: splineSeries") << series3 << (QAxis*) 0;
179 QTest::newRow("default axis: splineSeries") << series3 << (QAxis*) 0;
180 QTest::newRow("axis: splineSeries") << series3 << axis;
180 QTest::newRow("axis: splineSeries") << series3 << axis;
181 QTest::newRow("default axis: pieSeries") << series4 << (QAxis*) 0;
181 QTest::newRow("default axis: pieSeries") << series4 << (QAxis*) 0;
182 QTest::newRow("axis: pieSeries") << series4 << axis;
182 QTest::newRow("axis: pieSeries") << series4 << axis;
183 QTest::newRow("default axis: barSeries") << series5 << (QAxis*) 0;
183 QTest::newRow("default axis: barSeries") << series5 << (QAxis*) 0;
184 QTest::newRow("axis: barSeries") << series5 << axis;
184 QTest::newRow("axis: barSeries") << series5 << axis;
185 QTest::newRow("default axis: percentBarSeries") << series6 << (QAxis*) 0;
185 QTest::newRow("default axis: percentBarSeries") << series6 << (QAxis*) 0;
186 QTest::newRow("axis: barSeries") << series6 << axis;
186 QTest::newRow("axis: barSeries") << series6 << axis;
187 QTest::newRow("default axis: stackedBarSeries") << series7 << (QAxis*) 0;
187 QTest::newRow("default axis: stackedBarSeries") << series7 << (QAxis*) 0;
188 QTest::newRow("axis: barSeries") << series7 << axis;
188 QTest::newRow("axis: barSeries") << series7 << axis;
189
189
190 }
190 }
191
191
192 void tst_QChart::addSeries()
192 void tst_QChart::addSeries()
193 {
193 {
194 QFETCH(QAbstractSeries *, series);
194 QFETCH(QAbstractSeries *, series);
195 QFETCH(QAxis *, axis);
195 QFETCH(QAxis *, axis);
196 m_view->show();
196 m_view->show();
197 QTest::qWaitForWindowShown(m_view);
197 QTest::qWaitForWindowShown(m_view);
198 if(!axis) axis = m_chart->axisY();
198 if(!axis) axis = m_chart->axisY();
199 m_chart->addSeries(series,axis);
199 m_chart->addSeries(series,axis);
200 QCOMPARE(m_chart->axisY(series),axis);
200 QCOMPARE(m_chart->axisY(series),axis);
201 m_chart->removeSeries(series);
201 m_chart->removeSeries(series);
202
202
203 }
203 }
204
204
205 void tst_QChart::animationOptions_data()
205 void tst_QChart::animationOptions_data()
206 {
206 {
207 QTest::addColumn<QChart::AnimationOption>("animationOptions");
207 QTest::addColumn<QChart::AnimationOption>("animationOptions");
208 QTest::newRow("AllAnimations") << QChart::AllAnimations;
208 QTest::newRow("AllAnimations") << QChart::AllAnimations;
209 QTest::newRow("NoAnimation") << QChart::NoAnimation;
209 QTest::newRow("NoAnimation") << QChart::NoAnimation;
210 QTest::newRow("GridAxisAnimations") << QChart::GridAxisAnimations;
210 QTest::newRow("GridAxisAnimations") << QChart::GridAxisAnimations;
211 QTest::newRow("SeriesAnimations") << QChart::SeriesAnimations;
211 QTest::newRow("SeriesAnimations") << QChart::SeriesAnimations;
212 }
212 }
213
213
214 void tst_QChart::animationOptions()
214 void tst_QChart::animationOptions()
215 {
215 {
216 createTestData();
216 createTestData();
217 QFETCH(QChart::AnimationOption, animationOptions);
217 QFETCH(QChart::AnimationOption, animationOptions);
218 m_chart->setAnimationOptions(animationOptions);
218 m_chart->setAnimationOptions(animationOptions);
219 QCOMPARE(m_chart->animationOptions(), animationOptions);
219 QCOMPARE(m_chart->animationOptions(), animationOptions);
220 }
220 }
221
221
222 void tst_QChart::axisX_data()
222 void tst_QChart::axisX_data()
223 {
223 {
224
224
225 }
225 }
226
226
227 void tst_QChart::axisX()
227 void tst_QChart::axisX()
228 {
228 {
229 QVERIFY(m_chart->axisX());
229 QVERIFY(m_chart->axisX());
230 QAxis* axis = m_chart->axisX();
230 QAxis* axis = m_chart->axisX();
231 createTestData();
231 createTestData();
232 //it should be the same axis
232 //it should be the same axis
233 QCOMPARE(axis,m_chart->axisX());
233 QCOMPARE(axis,m_chart->axisX());
234 }
234 }
235
235
236 void tst_QChart::axisY_data()
236 void tst_QChart::axisY_data()
237 {
237 {
238 QTest::addColumn<QAxis*>("axis0");
238 QTest::addColumn<QAxis*>("axis0");
239 QTest::addColumn<QAxis*>("axis1");
239 QTest::addColumn<QAxis*>("axis1");
240 QTest::addColumn<QAxis*>("axis2");
240 QTest::addColumn<QAxis*>("axis2");
241 QTest::newRow("1 defualt, 2 optional") << (QAxis*)0 << new QAxis() << new QAxis();
241 QTest::newRow("1 defualt, 2 optional") << (QAxis*)0 << new QAxis() << new QAxis();
242 QTest::newRow("3 optional") << new QAxis() << new QAxis() << new QAxis();
242 QTest::newRow("3 optional") << new QAxis() << new QAxis() << new QAxis();
243 }
243 }
244
244
245
245
246 void tst_QChart::axisY()
246 void tst_QChart::axisY()
247 {
247 {
248 QFETCH(QAxis*, axis0);
248 QFETCH(QAxis*, axis0);
249 QFETCH(QAxis*, axis1);
249 QFETCH(QAxis*, axis1);
250 QFETCH(QAxis*, axis2);
250 QFETCH(QAxis*, axis2);
251
251
252 QAxis* defaultAxisY = m_chart->axisY();
252 QAxis* defaultAxisY = m_chart->axisY();
253
253
254 QVERIFY2(defaultAxisY, "Missing axisY.");
254 QVERIFY2(defaultAxisY, "Missing axisY.");
255
255
256 QLineSeries* series0 = new QLineSeries();
256 QLineSeries* series0 = new QLineSeries();
257 m_chart->addSeries(series0, axis0);
257 m_chart->addSeries(series0, axis0);
258
258
259 QLineSeries* series1 = new QLineSeries();
259 QLineSeries* series1 = new QLineSeries();
260 m_chart->addSeries(series1, axis1);
260 m_chart->addSeries(series1, axis1);
261
261
262 QLineSeries* series2 = new QLineSeries();
262 QLineSeries* series2 = new QLineSeries();
263 m_chart->addSeries(series2, axis2);
263 m_chart->addSeries(series2, axis2);
264
264
265 if (!axis0)
265 if (!axis0)
266 axis0 = defaultAxisY;
266 axis0 = defaultAxisY;
267 if (!axis1)
267 if (!axis1)
268 axis1 = defaultAxisY;
268 axis1 = defaultAxisY;
269 if (!axis2)
269 if (!axis2)
270 axis2 = defaultAxisY;
270 axis2 = defaultAxisY;
271
271
272 QVERIFY(m_chart->axisY(series0) == axis0);
272 QVERIFY(m_chart->axisY(series0) == axis0);
273 QVERIFY(m_chart->axisY(series1) == axis1);
273 QVERIFY(m_chart->axisY(series1) == axis1);
274 QVERIFY(m_chart->axisY(series2) == axis2);
274 QVERIFY(m_chart->axisY(series2) == axis2);
275 }
275 }
276
276
277 void tst_QChart::backgroundBrush_data()
277 void tst_QChart::backgroundBrush_data()
278 {
278 {
279 QTest::addColumn<QBrush>("backgroundBrush");
279 QTest::addColumn<QBrush>("backgroundBrush");
280 QTest::newRow("null") << QBrush();
280 QTest::newRow("null") << QBrush();
281 QTest::newRow("blue") << QBrush(Qt::blue);
281 QTest::newRow("blue") << QBrush(Qt::blue);
282 QTest::newRow("white") << QBrush(Qt::white);
282 QTest::newRow("white") << QBrush(Qt::white);
283 QTest::newRow("black") << QBrush(Qt::black);
283 QTest::newRow("black") << QBrush(Qt::black);
284 }
284 }
285
285
286 void tst_QChart::backgroundBrush()
286 void tst_QChart::backgroundBrush()
287 {
287 {
288 QFETCH(QBrush, backgroundBrush);
288 QFETCH(QBrush, backgroundBrush);
289 m_chart->setBackgroundBrush(backgroundBrush);
289 m_chart->setBackgroundBrush(backgroundBrush);
290 QCOMPARE(m_chart->backgroundBrush(), backgroundBrush);
290 QCOMPARE(m_chart->backgroundBrush(), backgroundBrush);
291 }
291 }
292
292
293 void tst_QChart::backgroundPen_data()
293 void tst_QChart::backgroundPen_data()
294 {
294 {
295 QTest::addColumn<QPen>("backgroundPen");
295 QTest::addColumn<QPen>("backgroundPen");
296 QTest::newRow("null") << QPen();
296 QTest::newRow("null") << QPen();
297 QTest::newRow("blue") << QPen(Qt::blue);
297 QTest::newRow("blue") << QPen(Qt::blue);
298 QTest::newRow("white") << QPen(Qt::white);
298 QTest::newRow("white") << QPen(Qt::white);
299 QTest::newRow("black") << QPen(Qt::black);
299 QTest::newRow("black") << QPen(Qt::black);
300 }
300 }
301
301
302
302
303 void tst_QChart::backgroundPen()
303 void tst_QChart::backgroundPen()
304 {
304 {
305 QFETCH(QPen, backgroundPen);
305 QFETCH(QPen, backgroundPen);
306 m_chart->setBackgroundPen(backgroundPen);
306 m_chart->setBackgroundPen(backgroundPen);
307 QCOMPARE(m_chart->backgroundPen(), backgroundPen);
307 QCOMPARE(m_chart->backgroundPen(), backgroundPen);
308 }
308 }
309
309
310 void tst_QChart::isBackgroundVisible_data()
310 void tst_QChart::isBackgroundVisible_data()
311 {
311 {
312 QTest::addColumn<bool>("isBackgroundVisible");
312 QTest::addColumn<bool>("isBackgroundVisible");
313 QTest::newRow("true") << true;
313 QTest::newRow("true") << true;
314 QTest::newRow("false") << false;
314 QTest::newRow("false") << false;
315 }
315 }
316
316
317 void tst_QChart::isBackgroundVisible()
317 void tst_QChart::isBackgroundVisible()
318 {
318 {
319 QFETCH(bool, isBackgroundVisible);
319 QFETCH(bool, isBackgroundVisible);
320 m_chart->setBackgroundVisible(isBackgroundVisible);
320 m_chart->setBackgroundVisible(isBackgroundVisible);
321 QCOMPARE(m_chart->isBackgroundVisible(), isBackgroundVisible);
321 QCOMPARE(m_chart->isBackgroundVisible(), isBackgroundVisible);
322
323 }
322 }
324
323
325 void tst_QChart::legend_data()
324 void tst_QChart::legend_data()
326 {
325 {
327
326
328 }
327 }
329
328
330 void tst_QChart::legend()
329 void tst_QChart::legend()
331 {
330 {
332 QVERIFY(m_chart->legend());
331 QVERIFY(m_chart->legend());
333 }
332 }
334
333
335 void tst_QChart::margins_data()
334 void tst_QChart::margins_data()
336 {
335 {
337
336
338 }
337 }
339
338
340 void tst_QChart::margins()
339 void tst_QChart::margins()
341 {QTest::addColumn<int>("seriesCount");
340 {
342 QTest::newRow("0") << 0;
343 QTest::newRow("-1") << -1;
344 createTestData();
341 createTestData();
345 QRectF rect = m_chart->geometry();
342 QRectF rect = m_chart->geometry();
346
343
347 QVERIFY(m_chart->margins().top()+m_chart->margins().bottom() < rect.height());
344 QVERIFY(m_chart->margins().top()+m_chart->margins().bottom() < rect.height());
348 QVERIFY(m_chart->margins().left()+m_chart->margins().right() < rect.width());
345 QVERIFY(m_chart->margins().left()+m_chart->margins().right() < rect.width());
349
350 }
346 }
351
347
352 void tst_QChart::removeAllSeries_data()
348 void tst_QChart::removeAllSeries_data()
353 {
349 {
354
350
355 }
351 }
356
352
357 void tst_QChart::removeAllSeries()
353 void tst_QChart::removeAllSeries()
358 {
354 {
359 QLineSeries* series0 = new QLineSeries(this);
355 QLineSeries* series0 = new QLineSeries(this);
360 QLineSeries* series1 = new QLineSeries(this);
356 QLineSeries* series1 = new QLineSeries(this);
361 QLineSeries* series2 = new QLineSeries(this);
357 QLineSeries* series2 = new QLineSeries(this);
362
358
363 m_chart->addSeries(series0);
359 m_chart->addSeries(series0);
364 m_chart->addSeries(series1);
360 m_chart->addSeries(series1);
365 m_chart->addSeries(series2);
361 m_chart->addSeries(series2);
366 m_view->show();
362 m_view->show();
367 QTest::qWaitForWindowShown(m_view);
363 QTest::qWaitForWindowShown(m_view);
368
364
369 QVERIFY(m_chart->axisY(series0)!=0);
365 QVERIFY(m_chart->axisY(series0)!=0);
370 QVERIFY(m_chart->axisY(series1)!=0);
366 QVERIFY(m_chart->axisY(series1)!=0);
371 QVERIFY(m_chart->axisY(series2)!=0);
367 QVERIFY(m_chart->axisY(series2)!=0);
372
368
373 m_chart->removeAllSeries();
369 m_chart->removeAllSeries();
374
370
375 QVERIFY(m_chart->axisY(series0)==0);
371 QVERIFY(m_chart->axisY(series0)==0);
376 QVERIFY(m_chart->axisY(series1)==0);
372 QVERIFY(m_chart->axisY(series1)==0);
377 QVERIFY(m_chart->axisY(series2)==0);
373 QVERIFY(m_chart->axisY(series2)==0);
378 }
374 }
379
375
380 void tst_QChart::removeSeries_data()
376 void tst_QChart::removeSeries_data()
381 {
377 {
382 addSeries_data();
378 addSeries_data();
383 }
379 }
384
380
385 void tst_QChart::removeSeries()
381 void tst_QChart::removeSeries()
386 {
382 {
387 QFETCH(QAbstractSeries *, series);
383 QFETCH(QAbstractSeries *, series);
388 QFETCH(QAxis *, axis);
384 QFETCH(QAxis *, axis);
389 m_view->show();
385 m_view->show();
390 QTest::qWaitForWindowShown(m_view);
386 QTest::qWaitForWindowShown(m_view);
391 if(!axis) axis = m_chart->axisY();
387 if(!axis) axis = m_chart->axisY();
392 m_chart->addSeries(series,axis);
388 m_chart->addSeries(series,axis);
393 QCOMPARE(m_chart->axisY(series),axis);
389 QCOMPARE(m_chart->axisY(series),axis);
394 m_chart->removeSeries(series);
390 m_chart->removeSeries(series);
395 QVERIFY(m_chart->axisY(series)==0);
391 QVERIFY(m_chart->axisY(series)==0);
396 }
392 }
397
393
398 void tst_QChart::scrollDown_data()
394 void tst_QChart::scrollDown_data()
399 {
395 {
400
396
401 }
397 }
402
398
403 void tst_QChart::scrollDown()
399 void tst_QChart::scrollDown()
404 {
400 {
405 createTestData();
401 createTestData();
406 qreal min = m_chart->axisY()->min();
402 qreal min = m_chart->axisY()->min();
407 m_chart->scrollDown();
403 m_chart->scrollDown();
408 QVERIFY(m_chart->axisY()->min()<min);
404 QVERIFY(m_chart->axisY()->min()<min);
409 }
405 }
410
406
411 void tst_QChart::scrollLeft_data()
407 void tst_QChart::scrollLeft_data()
412 {
408 {
413
409
414 }
410 }
415
411
416 void tst_QChart::scrollLeft()
412 void tst_QChart::scrollLeft()
417 {
413 {
418 createTestData();
414 createTestData();
419 qreal min = m_chart->axisX()->min();
415 qreal min = m_chart->axisX()->min();
420 m_chart->scrollLeft();
416 m_chart->scrollLeft();
421 QVERIFY(m_chart->axisX()->min()<min);
417 QVERIFY(m_chart->axisX()->min()<min);
422 }
418 }
423
419
424 void tst_QChart::scrollRight_data()
420 void tst_QChart::scrollRight_data()
425 {
421 {
426
422
427 }
423 }
428
424
429 void tst_QChart::scrollRight()
425 void tst_QChart::scrollRight()
430 {
426 {
431 createTestData();
427 createTestData();
432 qreal min = m_chart->axisX()->min();
428 qreal min = m_chart->axisX()->min();
433 m_chart->scrollRight();
429 m_chart->scrollRight();
434 QVERIFY(m_chart->axisX()->min()>min);
430 QVERIFY(m_chart->axisX()->min()>min);
435 }
431 }
436
432
437 void tst_QChart::scrollUp_data()
433 void tst_QChart::scrollUp_data()
438 {
434 {
439
435
440 }
436 }
441
437
442 void tst_QChart::scrollUp()
438 void tst_QChart::scrollUp()
443 {
439 {
444 createTestData();
440 createTestData();
445 qreal min = m_chart->axisY()->min();
441 qreal min = m_chart->axisY()->min();
446 m_chart->scrollUp();
442 m_chart->scrollUp();
447 QVERIFY(m_chart->axisY()->min()>min);
443 QVERIFY(m_chart->axisY()->min()>min);
448 }
444 }
449
445
450 void tst_QChart::theme_data()
446 void tst_QChart::theme_data()
451 {
447 {
452 QTest::addColumn<QChart::ChartTheme>("theme");
448 QTest::addColumn<QChart::ChartTheme>("theme");
453 QTest::newRow("ChartThemeBlueCerulean") << QChart::ChartThemeBlueCerulean;
449 QTest::newRow("ChartThemeBlueCerulean") << QChart::ChartThemeBlueCerulean;
454 QTest::newRow("ChartThemeBlueIcy") << QChart::ChartThemeBlueIcy;
450 QTest::newRow("ChartThemeBlueIcy") << QChart::ChartThemeBlueIcy;
455 QTest::newRow("ChartThemeBlueNcs") << QChart::ChartThemeBlueNcs;
451 QTest::newRow("ChartThemeBlueNcs") << QChart::ChartThemeBlueNcs;
456 QTest::newRow("ChartThemeBrownSand") << QChart::ChartThemeBrownSand;
452 QTest::newRow("ChartThemeBrownSand") << QChart::ChartThemeBrownSand;
457 QTest::newRow("ChartThemeDark") << QChart::ChartThemeDark;
453 QTest::newRow("ChartThemeDark") << QChart::ChartThemeDark;
458 QTest::newRow("hartThemeHighContrast") << QChart::ChartThemeHighContrast;
454 QTest::newRow("hartThemeHighContrast") << QChart::ChartThemeHighContrast;
459 QTest::newRow("ChartThemeLight") << QChart::ChartThemeLight;
455 QTest::newRow("ChartThemeLight") << QChart::ChartThemeLight;
460 }
456 }
461
457
462 void tst_QChart::theme()
458 void tst_QChart::theme()
463 {
459 {
464 QFETCH(QChart::ChartTheme, theme);
460 QFETCH(QChart::ChartTheme, theme);
465 createTestData();
461 createTestData();
466 m_chart->setTheme(theme);
462 m_chart->setTheme(theme);
467 QVERIFY(m_chart->theme()==theme);
463 QVERIFY(m_chart->theme()==theme);
468 }
464 }
469
465
470 void tst_QChart::title_data()
466 void tst_QChart::title_data()
471 {
467 {
472 QTest::addColumn<QString>("title");
468 QTest::addColumn<QString>("title");
473 QTest::newRow("null") << QString();
469 QTest::newRow("null") << QString();
474 QTest::newRow("foo") << QString("foo");
470 QTest::newRow("foo") << QString("foo");
475 }
471 }
476
472
477 void tst_QChart::title()
473 void tst_QChart::title()
478 {
474 {
479 QFETCH(QString, title);
475 QFETCH(QString, title);
480 m_chart->setTitle(title);
476 m_chart->setTitle(title);
481 QCOMPARE(m_chart->title(), title);
477 QCOMPARE(m_chart->title(), title);
482 }
478 }
483
479
484 void tst_QChart::titleBrush_data()
480 void tst_QChart::titleBrush_data()
485 {
481 {
486 QTest::addColumn<QBrush>("titleBrush");
482 QTest::addColumn<QBrush>("titleBrush");
487 QTest::newRow("null") << QBrush();
483 QTest::newRow("null") << QBrush();
488 QTest::newRow("blue") << QBrush(Qt::blue);
484 QTest::newRow("blue") << QBrush(Qt::blue);
489 QTest::newRow("white") << QBrush(Qt::white);
485 QTest::newRow("white") << QBrush(Qt::white);
490 QTest::newRow("black") << QBrush(Qt::black);
486 QTest::newRow("black") << QBrush(Qt::black);
491 }
487 }
492
488
493 void tst_QChart::titleBrush()
489 void tst_QChart::titleBrush()
494 {
490 {
495 QFETCH(QBrush, titleBrush);
491 QFETCH(QBrush, titleBrush);
496 m_chart->setTitleBrush(titleBrush);
492 m_chart->setTitleBrush(titleBrush);
497 QCOMPARE(m_chart->titleBrush(), titleBrush);
493 QCOMPARE(m_chart->titleBrush(), titleBrush);
498 }
494 }
499
495
500 void tst_QChart::titleFont_data()
496 void tst_QChart::titleFont_data()
501 {
497 {
502 QTest::addColumn<QFont>("titleFont");
498 QTest::addColumn<QFont>("titleFont");
503 QTest::newRow("null") << QFont();
499 QTest::newRow("null") << QFont();
504 QTest::newRow("courier") << QFont("Courier", 8, QFont::Bold, true);
500 QTest::newRow("courier") << QFont("Courier", 8, QFont::Bold, true);
505 }
501 }
506
502
507 void tst_QChart::titleFont()
503 void tst_QChart::titleFont()
508 {
504 {
509 QFETCH(QFont, titleFont);
505 QFETCH(QFont, titleFont);
510 m_chart->setTitleFont(titleFont);
506 m_chart->setTitleFont(titleFont);
511 QCOMPARE(m_chart->titleFont(), titleFont);
507 QCOMPARE(m_chart->titleFont(), titleFont);
512 }
508 }
513
509
514 void tst_QChart::zoomIn_data()
510 void tst_QChart::zoomIn_data()
515 {
511 {
516 QTest::addColumn<QRectF>("rect");
512 QTest::addColumn<QRectF>("rect");
517 QTest::newRow("null") << QRectF();
513 QTest::newRow("null") << QRectF();
518 QTest::newRow("100x100") << QRectF(10,10,100,100);
514 QTest::newRow("100x100") << QRectF(10,10,100,100);
519 QTest::newRow("200x200") << QRectF(10,10,200,200);
515 QTest::newRow("200x200") << QRectF(10,10,200,200);
520 }
516 }
521
517
522
518
523 void tst_QChart::zoomIn()
519 void tst_QChart::zoomIn()
524 {
520 {
525 QFETCH(QRectF, rect);
521 QFETCH(QRectF, rect);
526 createTestData();
522 createTestData();
527 QRectF marigns = m_chart->margins();
523 QRectF marigns = m_chart->margins();
528 rect.adjust(marigns.left(),marigns.top(),-marigns.right(),-marigns.bottom());
524 rect.adjust(marigns.left(),marigns.top(),-marigns.right(),-marigns.bottom());
529 qreal minX = m_chart->axisX()->min();
525 qreal minX = m_chart->axisX()->min();
530 qreal minY = m_chart->axisY()->min();
526 qreal minY = m_chart->axisY()->min();
531 qreal maxX = m_chart->axisX()->max();
527 qreal maxX = m_chart->axisX()->max();
532 qreal maxY = m_chart->axisY()->max();
528 qreal maxY = m_chart->axisY()->max();
533 m_chart->zoomIn(rect);
529 m_chart->zoomIn(rect);
534 if(rect.isValid()){
530 if(rect.isValid()){
535 QVERIFY(minX<m_chart->axisX()->min());
531 QVERIFY(minX<m_chart->axisX()->min());
536 QVERIFY(maxX>m_chart->axisX()->max());
532 QVERIFY(maxX>m_chart->axisX()->max());
537 QVERIFY(minY<m_chart->axisY()->min());
533 QVERIFY(minY<m_chart->axisY()->min());
538 QVERIFY(maxY>m_chart->axisY()->max());
534 QVERIFY(maxY>m_chart->axisY()->max());
539 }
535 }
540 }
536 }
541
537
542 void tst_QChart::zoomOut_data()
538 void tst_QChart::zoomOut_data()
543 {
539 {
544
540
545 }
541 }
546
542
547 void tst_QChart::zoomOut()
543 void tst_QChart::zoomOut()
548 {
544 {
549 createTestData();
545 createTestData();
550 qreal minX = m_chart->axisX()->min();
546 qreal minX = m_chart->axisX()->min();
551 qreal minY = m_chart->axisY()->min();
547 qreal minY = m_chart->axisY()->min();
552 qreal maxX = m_chart->axisX()->max();
548 qreal maxX = m_chart->axisX()->max();
553 qreal maxY = m_chart->axisY()->max();
549 qreal maxY = m_chart->axisY()->max();
554
550
555 m_chart->zoomIn();
551 m_chart->zoomIn();
556
552
557 QVERIFY(minX<m_chart->axisX()->min());
553 QVERIFY(minX<m_chart->axisX()->min());
558 QVERIFY(maxX>m_chart->axisX()->max());
554 QVERIFY(maxX>m_chart->axisX()->max());
559 QVERIFY(minY<m_chart->axisY()->min());
555 QVERIFY(minY<m_chart->axisY()->min());
560 QVERIFY(maxY>m_chart->axisY()->max());
556 QVERIFY(maxY>m_chart->axisY()->max());
561
557
562 m_chart->zoomOut();
558 m_chart->zoomOut();
563
559
564 QVERIFY(minX==m_chart->axisX()->min());
560 QVERIFY(minX==m_chart->axisX()->min());
565 QVERIFY(maxX==m_chart->axisX()->max());
561 QVERIFY(maxX==m_chart->axisX()->max());
566 QVERIFY(minY==m_chart->axisY()->min());
562 QVERIFY(minY==m_chart->axisY()->min());
567 QVERIFY(maxY==m_chart->axisY()->max());
563 QVERIFY(maxY==m_chart->axisY()->max());
568 }
564 }
569
565
570 QTEST_MAIN(tst_QChart)
566 QTEST_MAIN(tst_QChart)
571 #include "tst_qchart.moc"
567 #include "tst_qchart.moc"
572
568
General Comments 0
You need to be logged in to leave comments. Login now