##// END OF EJS Templates
Bugfixes for unnesery geometry changes
Michal Klocek -
r869:21fb1e963c66
parent child
Show More
@@ -1,532 +1,536
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "qchartaxis.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 //series
29 29 #include "qbarseries.h"
30 30 #include "qstackedbarseries.h"
31 31 #include "qpercentbarseries.h"
32 32 #include "qlineseries.h"
33 33 #include "qareaseries.h"
34 34 #include "qpieseries.h"
35 35 #include "qscatterseries.h"
36 36 #include "qsplineseries.h"
37 37 //items
38 38 #include "axisitem_p.h"
39 39 #include "areachartitem_p.h"
40 40 #include "barchartitem_p.h"
41 41 #include "stackedbarchartitem_p.h"
42 42 #include "percentbarchartitem_p.h"
43 43 #include "linechartitem_p.h"
44 44 #include "piechartitem_p.h"
45 45 #include "scatterchartitem_p.h"
46 46 #include "splinechartitem_p.h"
47 47
48 48 QTCOMMERCIALCHART_BEGIN_NAMESPACE
49 49
50 50 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
51 51 m_chart(chart),
52 52 m_animator(0),
53 53 m_dataset(dataset),
54 54 m_chartTheme(0),
55 55 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
56 56 m_options(QChart::NoAnimation),
57 57 m_themeForce(false),
58 58 m_minLeftMargin(0),
59 59 m_minBottomMargin(0),
60 60 m_backgroundItem(0),
61 61 m_titleItem(0),
62 62 m_marginBig(60),
63 63 m_marginSmall(20),
64 64 m_marginTiny(10),
65 65 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
66 66 {
67 67 createConnections();
68 68 }
69 69
70 70 ChartPresenter::~ChartPresenter()
71 71 {
72 72 delete m_chartTheme;
73 73 }
74 74
75 75 void ChartPresenter::createConnections()
76 76 {
77 77 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
78 78 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
79 79 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
80 80 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
81 81 }
82 82
83 83 void ChartPresenter::setGeometry(const QRectF& rect)
84 84 {
85 85 m_rect = rect;
86 86 Q_ASSERT(m_rect.isValid());
87 87 updateLayout();
88 88 }
89 89
90 90 void ChartPresenter::setMinimumMarginWidth(Axis* axis, qreal width)
91 91 {
92 92 switch(axis->axisType()){
93 93 case Axis::X_AXIS:
94 94 {
95 95 if(width>m_chartRect.width()+ m_chartMargins.left()) {
96 96 m_minLeftMargin= width - m_chartRect.width();
97 97 updateLayout();
98 98 }
99 99 break;
100 100 }
101 101 case Axis::Y_AXIS:
102 102 {
103 103
104 104 if(m_minLeftMargin!=width){
105 105 m_minLeftMargin= width;
106 106 updateLayout();
107 107 }
108 108 break;
109 109 }
110 110
111 111 }
112 112 }
113 113
114 114 void ChartPresenter::setMinimumMarginHeight(Axis* axis, qreal height)
115 115 {
116 116 switch(axis->axisType()){
117 117 case Axis::X_AXIS:
118 118 {
119 119 if(m_minBottomMargin!=height) {
120 120 m_minBottomMargin= height;
121 121 updateLayout();
122 122 }
123 123 break;
124 124 }
125 125 case Axis::Y_AXIS:
126 126 {
127 127
128 128 if(height>m_chartMargins.bottom()+m_chartRect.height()){
129 129 m_minBottomMargin= height - m_chartRect.height();
130 130 updateLayout();
131 131 }
132 132 break;
133 133 }
134 134
135 135 }
136 136 }
137 137
138 138 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
139 139 {
140 140 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
141 141
142 142 if(m_options.testFlag(QChart::GridAxisAnimations)){
143 143 m_animator->addAnimation(item);
144 144 }
145 145
146 146 if(axis==m_dataset->axisX()){
147 147 m_chartTheme->decorate(axis,true,m_themeForce);
148 148 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
149 149 //initialize
150 150 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
151 151
152 152 }
153 153 else{
154 154 m_chartTheme->decorate(axis,false,m_themeForce);
155 155 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
156 156 //initialize
157 157 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
158 158 }
159 159
160 160 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
161 161 //initialize
162 162 item->handleGeometryChanged(m_chartRect);
163 163 m_axisItems.insert(axis, item);
164 164 }
165 165
166 166 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
167 167 {
168 168 Axis* item = m_axisItems.take(axis);
169 169 Q_ASSERT(item);
170 170 if(m_animator) m_animator->removeAnimation(item);
171 171 delete item;
172 172 }
173 173
174 174
175 175 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
176 176 {
177 177 Chart *item = 0 ;
178 178
179 179 switch(series->type())
180 180 {
181 181 case QSeries::SeriesTypeLine: {
182 182
183 183 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
184 184 LineChartItem* line = new LineChartItem(lineSeries,this);
185 185 if(m_options.testFlag(QChart::SeriesAnimations)) {
186 186 m_animator->addAnimation(line);
187 187 }
188 188 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
189 189 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
190 190 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
191 191 item = line;
192 192 break;
193 193 }
194 194
195 195 case QSeries::SeriesTypeArea: {
196 196
197 197 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
198 198 AreaChartItem* area = new AreaChartItem(areaSeries,this);
199 199 if(m_options.testFlag(QChart::SeriesAnimations)) {
200 200 m_animator->addAnimation(area->upperLineItem());
201 201 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
202 202 }
203 203 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
204 204 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
205 205 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
206 206 item=area;
207 207 break;
208 208 }
209 209
210 210 case QSeries::SeriesTypeBar: {
211 211 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
212 212 BarChartItem* bar = new BarChartItem(barSeries,this);
213 213 if(m_options.testFlag(QChart::SeriesAnimations)) {
214 214 m_animator->addAnimation(bar);
215 215 }
216 216 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
217 217 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
218 218 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
219 219 item=bar;
220 220 break;
221 221 }
222 222
223 223 case QSeries::SeriesTypeStackedBar: {
224 224 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
225 225 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
226 226 if(m_options.testFlag(QChart::SeriesAnimations)) {
227 227 m_animator->addAnimation(bar);
228 228 }
229 229 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
230 230 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
231 231 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
232 232 item=bar;
233 233 break;
234 234 }
235 235
236 236 case QSeries::SeriesTypePercentBar: {
237 237 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
238 238 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
239 239 if(m_options.testFlag(QChart::SeriesAnimations)) {
240 240 m_animator->addAnimation(bar);
241 241 }
242 242 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
243 243 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
244 244 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
245 245 item=bar;
246 246 break;
247 247 }
248 248
249 249 case QSeries::SeriesTypeScatter: {
250
250 251 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
251 252 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
252 253 if(m_options.testFlag(QChart::SeriesAnimations)) {
253 254 m_animator->addAnimation(scatter);
254 255 }
255 256 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
256 257 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
257 258 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
258 259 item = scatter;
259 260 break;
260 261 }
261 262
262 263 case QSeries::SeriesTypePie: {
263 264 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
264 265 PieChartItem* pie = new PieChartItem(pieSeries, this);
265 266 if(m_options.testFlag(QChart::SeriesAnimations)) {
266 267 m_animator->addAnimation(pie);
267 268 }
268 269 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
269 270 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
270 271 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
271 272 // Hide all from background when there is only piechart
272 273 // TODO: refactor this ugly code... should be one setting for this
273 274 if (m_chartItems.count() == 0) {
274 275 m_chart->axisX()->hide();
275 276 m_chart->axisY()->hide();
276 277 }
277 278 item=pie;
278 279 break;
279 280 }
280 281
281 282 case QSeries::SeriesTypeSpline: {
282 283 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
283 284 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
284 285 if(m_options.testFlag(QChart::SeriesAnimations)) {
285 286 m_animator->addAnimation(spline);
286 287 }
287 288 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
288 289 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
289 290 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
290 291 item=spline;
291 292 break;
292 293 }
293 294 default: {
294 295 qDebug()<< "Series type" << series->type() << "not implemented.";
295 296 break;
296 297 }
297 298 }
298 299
299 300 //initialize
300 301 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
301 302 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
302 303 m_chartItems.insert(series,item);
303 304 }
304 305
305 306 void ChartPresenter::handleSeriesRemoved(QSeries* series)
306 307 {
307 308 Chart* item = m_chartItems.take(series);
308 309 Q_ASSERT(item);
309 310 if(m_animator) {
310 311 //small hack to handle area animations
311 312 if(series->type()==QSeries::SeriesTypeArea){
312 313 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
313 314 AreaChartItem* area = static_cast<AreaChartItem*>(item);
314 315 m_animator->removeAnimation(area->upperLineItem());
315 316 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
316 317 }else
317 318 m_animator->removeAnimation(item);
318 319 }
319 320 delete item;
320 321 }
321 322
322 323 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
323 324 {
324 325 if(m_chartTheme && m_chartTheme->id() == theme) return;
325 326 delete m_chartTheme;
326 327 m_themeForce = force;
327 328 m_chartTheme = ChartTheme::createTheme(theme);
328 329 m_chartTheme->decorate(m_chart,m_themeForce);
329 330 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
330 331 resetAllElements();
331 332 }
332 333
333 334 QChart::ChartTheme ChartPresenter::theme()
334 335 {
335 336 return m_chartTheme->id();
336 337 }
337 338
338 339 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
339 340 {
340 341 if(m_options!=options) {
341 342
342 343 m_options=options;
343 344
344 345 if(m_options!=QChart::NoAnimation && !m_animator) {
345 346 m_animator= new ChartAnimator(this);
346
347 347 }
348 348 resetAllElements();
349 349 }
350 350
351 351 }
352 352
353 353 void ChartPresenter::resetAllElements()
354 354 {
355 355 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
356 356 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
357 357
358 358 foreach(QChartAxis* axis, axisList) {
359 359 handleAxisRemoved(axis);
360 360 handleAxisAdded(axis,m_dataset->domain(axis));
361 361 }
362 362 foreach(QSeries* series, seriesList) {
363 363 handleSeriesRemoved(series);
364 364 handleSeriesAdded(series,m_dataset->domain(series));
365 365 }
366 366 }
367 367
368 368 void ChartPresenter::zoomIn()
369 369 {
370 370 QRectF rect = chartGeometry();
371 371 rect.setWidth(rect.width()/2);
372 372 rect.setHeight(rect.height()/2);
373 373 rect.moveCenter(chartGeometry().center());
374 374 zoomIn(rect);
375 375 }
376 376
377 377 void ChartPresenter::zoomIn(const QRectF& rect)
378 378 {
379 379 QRectF r = rect.normalized();
380 380 r.translate(-m_chartMargins.topLeft());
381 381 if(m_animator) {
382 382
383 383 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
384 384 m_animator->setState(ChartAnimator::ZoomInState,point);
385 385 }
386 386 m_dataset->zoomInDomain(r,chartGeometry().size());
387 387 if(m_animator) {
388 388 m_animator->setState(ChartAnimator::ShowState);
389 389 }
390 390 }
391 391
392 392 void ChartPresenter::zoomOut()
393 393 {
394 394 if(m_animator)
395 395 {
396 396 m_animator->setState(ChartAnimator::ZoomOutState);
397 397 }
398 398
399 399 QSizeF size = chartGeometry().size();
400 400 QRectF rect = chartGeometry();
401 401 rect.translate(-m_chartMargins.topLeft());
402 402 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
403 403 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
404 404
405 405 if(m_animator){
406 406 m_animator->setState(ChartAnimator::ShowState);
407 407 }
408 408 }
409 409
410 410 void ChartPresenter::scroll(int dx,int dy)
411 411 {
412 412 if(m_animator){
413 413 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
414 414 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
415 415 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
416 416 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
417 417 }
418 418
419 419 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
420 420
421 421 if(m_animator){
422 422 m_animator->setState(ChartAnimator::ShowState);
423 423 }
424 424 }
425 425
426 426 QChart::AnimationOptions ChartPresenter::animationOptions() const
427 427 {
428 428 return m_options;
429 429 }
430 430
431 431 void ChartPresenter::updateLayout()
432 432 {
433 433 if (!m_rect.isValid()) return;
434 434
435 435 // recalculate title size
436 436
437 437 QSize titleSize;
438 438 int titlePadding=0;
439 439
440 440 if (m_titleItem) {
441 441 titleSize= m_titleItem->boundingRect().size().toSize();
442 442 }
443 443
444 444 //defaults
445 445 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));
446 446 titlePadding = m_chartMargins.top()/2;
447 447
448 448 QLegend* legend = m_chart->d_ptr->m_legend;
449 449
450 450 // recalculate legend position
451 451 if (legend->isAttachedToChart() && legend->isEnabled()) {
452 452
453 453 QRect legendRect;
454 454
455 455 // Reserve some space for legend
456 456 switch (legend->alignment()) {
457 457
458 458 case QLegend::AlignmentTop: {
459 459 int ledgendSize = legend->minHeight();
460 460 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
461 461 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
462 462 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
463 463 titlePadding = m_marginTiny + m_marginTiny;
464 464 break;
465 465 }
466 466 case QLegend::AlignmentBottom: {
467 467 int ledgendSize = legend->minHeight();
468 468 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
469 469 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
470 470 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
471 471 titlePadding = m_chartMargins.top()/2;
472 472 break;
473 473 }
474 474 case QLegend::AlignmentLeft: {
475 475 int ledgendSize = legend->minWidht();
476 476 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
477 477 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
478 478 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
479 479 titlePadding = m_chartMargins.top()/2;
480 480 break;
481 481 }
482 482 case QLegend::AlignmentRight: {
483 483 int ledgendSize = legend->minWidht();
484 484 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
485 485 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
486 486 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
487 487 titlePadding = m_chartMargins.top()/2;
488 488 break;
489 489 }
490 490 default: {
491 491 break;
492 492 }
493 493 }
494 494 }
495 495
496 496 // recalculate title position
497 497 if (m_titleItem) {
498 498 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
499 499 m_titleItem->setPos(center.x(),titlePadding);
500 500 }
501 501
502 502 //recalculate background gradient
503 503 if (m_backgroundItem) {
504 504 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
505 505 }
506 506
507 m_chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
507 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
508
509 if(m_chartRect!=chartRect){
510 m_chartRect=chartRect;
511 emit geometryChanged(m_chartRect);
512 }
508 513
509 emit geometryChanged(m_chartRect);
510 514 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
511 515 }
512 516
513 517 void ChartPresenter::createChartBackgroundItem()
514 518 {
515 519 if (!m_backgroundItem) {
516 520 m_backgroundItem = new ChartBackground(rootItem());
517 521 m_backgroundItem->setPen(Qt::NoPen);
518 522 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
519 523 }
520 524 }
521 525
522 526 void ChartPresenter::createChartTitleItem()
523 527 {
524 528 if (!m_titleItem) {
525 529 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
526 530 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
527 531 }
528 532 }
529 533
530 534 #include "moc_chartpresenter_p.cpp"
531 535
532 536 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,189 +1,189
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "scatterchartitem_p.h"
22 22 #include "qscatterseries.h"
23 23 #include "chartpresenter_p.h"
24 24 #include <QPainter>
25 25 #include <QGraphicsScene>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
30 30 XYChartItem(series,presenter),
31 31 m_series(series),
32 32 m_items(this),
33 33 m_shape(QScatterSeries::MarkerShapeRectangle),
34 34 m_size(15)
35 35
36 36 {
37 37 QObject::connect(m_series,SIGNAL(updated()), this, SLOT(handleUpdated()));
38 38
39 39 setZValue(ChartPresenter::ScatterSeriesZValue);
40 40 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
41 41
42 42 handleUpdated();
43 43
44 44 m_items.setHandlesChildEvents(false);
45 45
46 46 // TODO: how to draw a drop shadow?
47 47 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
48 48 // dropShadow->setOffset(2.0);
49 49 // dropShadow->setBlurRadius(2.0);
50 50 // setGraphicsEffect(dropShadow);
51 51 }
52 52
53 53
54 54 QRectF ScatterChartItem::boundingRect() const
55 55 {
56 56 return m_rect;
57 57 }
58 58
59 59 void ScatterChartItem::createPoints(int count)
60 60 {
61 61 for (int i = 0; i < count; ++i) {
62 62
63 63 QGraphicsItem *item = 0;
64 64
65 65 switch (m_shape) {
66 66 case QScatterSeries::MarkerShapeCircle:{
67 67 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size);
68 68 const QRectF& rect = i->boundingRect();
69 69 i->setPos(-rect.width()/2,-rect.height()/2);
70 70 item = new Marker(i,this);
71 71 break;
72 72 }
73 73 case QScatterSeries::MarkerShapeRectangle:{
74 74 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size);
75 75 i->setPos(-m_size/2,-m_size/2);
76 76 item = new Marker(i,this);
77 77 break;
78 78 }
79 79 default:
80 80 qWarning()<<"Unsupported marker type";
81 81 break;
82 82
83 83 }
84 84 m_items.addToGroup(item);
85 85 }
86 86 }
87 87
88 88 void ScatterChartItem::deletePoints(int count)
89 89 {
90 90 QList<QGraphicsItem *> items = m_items.childItems();
91 91
92 92 for (int i = 0; i < count; ++i) {
93 93 delete(items.takeLast());
94 94 }
95 95 }
96 96
97 97 void ScatterChartItem::markerSelected(Marker *marker)
98 98 {
99 99 emit XYChartItem::clicked(QPointF(m_series->x(marker->index()), m_series->y(marker->index())));
100 100 }
101 101
102 102 void ScatterChartItem::setLayout(QVector<QPointF>& points)
103 103 {
104 104 if(points.size()==0)
105 105 {
106 106 XYChartItem::setLayout(points);
107 107 return;
108 108 }
109 109
110 int diff = XYChartItem::points().size() - points.size();
110 int diff = m_items.childItems().size() - points.size();
111 111
112 112 if(diff>0) {
113 113 deletePoints(diff);
114 114 }
115 115 else if(diff<0) {
116 116 createPoints(-diff);
117 117 }
118 118
119 119 if(diff!=0) handleUpdated();
120 120
121 121 QList<QGraphicsItem*> items = m_items.childItems();
122 122
123 123 for (int i = 0; i < points.size(); i++) {
124 124 Marker* item = static_cast<Marker*>(items.at(i));
125 125 const QPointF& point = points.at(i);
126 126 const QRectF& rect = item->boundingRect();
127 127 item->setIndex(i);
128 128 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
129 129 if(!clipRect().contains(point)) {
130 130 item->setVisible(false);
131 131 }
132 132 else {
133 133 item->setVisible(true);
134 134 }
135 135 }
136 136
137 137 prepareGeometryChange();
138 138 m_rect = clipRect();
139 139 XYChartItem::setLayout(points);
140 140 }
141 141
142 142
143 143 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
144 144 {
145 145 Q_UNUSED(painter)
146 146 Q_UNUSED(option)
147 147 Q_UNUSED(widget)
148 148 }
149 149
150 150 void ScatterChartItem::setPen(const QPen& pen)
151 151 {
152 152 foreach(QGraphicsItem* item , m_items.childItems()) {
153 153 static_cast<Marker*>(item)->setPen(pen);
154 154 }
155 155 }
156 156
157 157 void ScatterChartItem::setBrush(const QBrush& brush)
158 158 {
159 159 foreach(QGraphicsItem* item , m_items.childItems()) {
160 160 static_cast<Marker*>(item)->setBrush(brush);
161 161 }
162 162 }
163 163
164 164 void ScatterChartItem::handleUpdated()
165 165 {
166 166
167 167 int count = m_items.childItems().count();
168 168
169 169 if(count==0) return;
170 170
171 171 bool recreate = m_size != m_series->size() || m_shape != m_series->shape();
172 172
173 173 //TODO: only rewrite on size change
174 174
175 175 m_size = m_series->size();
176 176 m_shape = m_series->shape();
177 177
178 178 if(recreate){
179 179 deletePoints(count);
180 180 createPoints(count);
181 181 }
182 182
183 183 setPen(m_series->pen());
184 184 setBrush(m_series->brush());
185 185 }
186 186
187 187 #include "moc_scatterchartitem_p.cpp"
188 188
189 189 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now