##// END OF EJS Templates
Add minimum size back to chartview and qchart
Michal Klocek -
r913:d1751eb423f7
parent child
Show More
@@ -1,529 +1,537
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 }
68 68
69 69 ChartPresenter::~ChartPresenter()
70 70 {
71 71 delete m_chartTheme;
72 72 }
73 73
74 74 void ChartPresenter::setGeometry(const QRectF& rect)
75 75 {
76 76 m_rect = rect;
77 77 Q_ASSERT(m_rect.isValid());
78 78 updateLayout();
79 79 }
80 80
81 81 void ChartPresenter::setMinimumMarginWidth(Axis* axis, qreal width)
82 82 {
83 83 switch(axis->axisType()){
84 84 case Axis::X_AXIS:
85 85 {
86 86 if(width>m_chartRect.width()+ m_chartMargins.left()) {
87 87 m_minLeftMargin= width - m_chartRect.width();
88 88 updateLayout();
89 89 }
90 90 break;
91 91 }
92 92 case Axis::Y_AXIS:
93 93 {
94 94
95 95 if(m_minLeftMargin!=width){
96 96 m_minLeftMargin= width;
97 97 updateLayout();
98 98 }
99 99 break;
100 100 }
101 101
102 102 }
103 103 }
104 104
105 105 void ChartPresenter::setMinimumMarginHeight(Axis* axis, qreal height)
106 106 {
107 107 switch(axis->axisType()){
108 108 case Axis::X_AXIS:
109 109 {
110 110 if(m_minBottomMargin!=height) {
111 111 m_minBottomMargin= height;
112 112 updateLayout();
113 113 }
114 114 break;
115 115 }
116 116 case Axis::Y_AXIS:
117 117 {
118 118
119 119 if(height>m_chartMargins.bottom()+m_chartRect.height()){
120 120 m_minBottomMargin= height - m_chartRect.height();
121 121 updateLayout();
122 122 }
123 123 break;
124 124 }
125 125
126 126 }
127 127 }
128 128
129 129 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
130 130 {
131 131 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
132 132
133 133 if(m_options.testFlag(QChart::GridAxisAnimations)){
134 134 m_animator->addAnimation(item);
135 135 }
136 136
137 137 if(axis==m_dataset->axisX()){
138 138 m_chartTheme->decorate(axis,true,m_themeForce);
139 139 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
140 140 //initialize
141 141 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
142 142
143 143 }
144 144 else{
145 145 m_chartTheme->decorate(axis,false,m_themeForce);
146 146 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
147 147 //initialize
148 148 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
149 149 }
150 150
151 151 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
152 152 //initialize
153 153 item->handleGeometryChanged(m_chartRect);
154 154 m_axisItems.insert(axis, item);
155 155 }
156 156
157 157 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
158 158 {
159 159 Axis* item = m_axisItems.take(axis);
160 160 Q_ASSERT(item);
161 161 if(m_animator) m_animator->removeAnimation(item);
162 162 delete item;
163 163 }
164 164
165 165
166 166 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
167 167 {
168 168 Chart *item = 0 ;
169 169
170 170 switch(series->type())
171 171 {
172 172 case QSeries::SeriesTypeLine: {
173 173
174 174 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
175 175 LineChartItem* line = new LineChartItem(lineSeries,this);
176 176 if(m_options.testFlag(QChart::SeriesAnimations)) {
177 177 m_animator->addAnimation(line);
178 178 }
179 179 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series),m_themeForce);
180 180 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
181 181 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
182 182 item = line;
183 183 break;
184 184 }
185 185
186 186 case QSeries::SeriesTypeArea: {
187 187
188 188 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
189 189 AreaChartItem* area = new AreaChartItem(areaSeries,this);
190 190 if(m_options.testFlag(QChart::SeriesAnimations)) {
191 191 m_animator->addAnimation(area->upperLineItem());
192 192 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
193 193 }
194 194 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series),m_themeForce);
195 195 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
196 196 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
197 197 item=area;
198 198 break;
199 199 }
200 200
201 201 case QSeries::SeriesTypeBar: {
202 202 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
203 203 BarChartItem* bar = new BarChartItem(barSeries,this);
204 204 if(m_options.testFlag(QChart::SeriesAnimations)) {
205 205 m_animator->addAnimation(bar);
206 206 }
207 207 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries),m_themeForce);
208 208 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
209 209 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
210 210 item=bar;
211 211 break;
212 212 }
213 213
214 214 case QSeries::SeriesTypeStackedBar: {
215 215 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
216 216 StackedBarChartItem* bar = new StackedBarChartItem(stackedBarSeries,this);
217 217 if(m_options.testFlag(QChart::SeriesAnimations)) {
218 218 m_animator->addAnimation(bar);
219 219 }
220 220 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries),m_themeForce);
221 221 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
222 222 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
223 223 item=bar;
224 224 break;
225 225 }
226 226
227 227 case QSeries::SeriesTypePercentBar: {
228 228 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
229 229 PercentBarChartItem* bar = new PercentBarChartItem(percentBarSeries,this);
230 230 if(m_options.testFlag(QChart::SeriesAnimations)) {
231 231 m_animator->addAnimation(bar);
232 232 }
233 233 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries),m_themeForce);
234 234 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
235 235 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
236 236 item=bar;
237 237 break;
238 238 }
239 239
240 240 case QSeries::SeriesTypeScatter: {
241 241
242 242 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
243 243 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries,this);
244 244 if(m_options.testFlag(QChart::SeriesAnimations)) {
245 245 m_animator->addAnimation(scatter);
246 246 }
247 247 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series),m_themeForce);
248 248 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
249 249 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
250 250 item = scatter;
251 251 break;
252 252 }
253 253
254 254 case QSeries::SeriesTypePie: {
255 255 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
256 256 PieChartItem* pie = new PieChartItem(pieSeries, this);
257 257 if(m_options.testFlag(QChart::SeriesAnimations)) {
258 258 m_animator->addAnimation(pie);
259 259 }
260 260 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series),m_themeForce);
261 261 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
262 262 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
263 263 // Hide all from background when there is only piechart
264 264 // TODO: refactor this ugly code... should be one setting for this
265 265 if (m_chartItems.count() == 0) {
266 266 m_chart->axisX()->hide();
267 267 m_chart->axisY()->hide();
268 268 }
269 269 item=pie;
270 270 break;
271 271 }
272 272
273 273 case QSeries::SeriesTypeSpline: {
274 274 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
275 275 SplineChartItem* spline = new SplineChartItem(splineSeries, this);
276 276 if(m_options.testFlag(QChart::SeriesAnimations)) {
277 277 m_animator->addAnimation(spline);
278 278 }
279 279 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series),m_themeForce);
280 280 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
281 281 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
282 282 item=spline;
283 283 break;
284 284 }
285 285 default: {
286 286 qDebug()<< "Series type" << series->type() << "not implemented.";
287 287 break;
288 288 }
289 289 }
290 290
291 291 //initialize
292 292 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
293 293 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
294 294 m_chartItems.insert(series,item);
295 295 }
296 296
297 297 void ChartPresenter::handleSeriesRemoved(QSeries* series)
298 298 {
299 299 Chart* item = m_chartItems.take(series);
300 300 Q_ASSERT(item);
301 301 if(m_animator) {
302 302 //small hack to handle area animations
303 303 if(series->type()==QSeries::SeriesTypeArea){
304 304 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
305 305 AreaChartItem* area = static_cast<AreaChartItem*>(item);
306 306 m_animator->removeAnimation(area->upperLineItem());
307 307 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
308 308 }else
309 309 m_animator->removeAnimation(item);
310 310 }
311 311 delete item;
312 312 }
313 313
314 314 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
315 315 {
316 316 if(m_chartTheme && m_chartTheme->id() == theme) return;
317 317 delete m_chartTheme;
318 318 m_themeForce = force;
319 319 m_chartTheme = ChartTheme::createTheme(theme);
320 320 m_chartTheme->decorate(m_chart,m_themeForce);
321 321 m_chartTheme->decorate(m_chart->legend(),m_themeForce);
322 322 resetAllElements();
323 323 }
324 324
325 325 QChart::ChartTheme ChartPresenter::theme()
326 326 {
327 327 return m_chartTheme->id();
328 328 }
329 329
330 330 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
331 331 {
332 332 if(m_options!=options) {
333 333
334 334 m_options=options;
335 335
336 336 if(m_options!=QChart::NoAnimation && !m_animator) {
337 337 m_animator= new ChartAnimator(this);
338 338 }
339 339 resetAllElements();
340 340 }
341 341
342 342 }
343 343
344 344 void ChartPresenter::resetAllElements()
345 345 {
346 346 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
347 347 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
348 348
349 349 foreach(QChartAxis* axis, axisList) {
350 350 handleAxisRemoved(axis);
351 351 handleAxisAdded(axis,m_dataset->domain(axis));
352 352 }
353 353 foreach(QSeries* series, seriesList) {
354 354 handleSeriesRemoved(series);
355 355 handleSeriesAdded(series,m_dataset->domain(series));
356 356 }
357 357 }
358 358
359 359 void ChartPresenter::zoomIn()
360 360 {
361 361 QRectF rect = chartGeometry();
362 362 rect.setWidth(rect.width()/2);
363 363 rect.setHeight(rect.height()/2);
364 364 rect.moveCenter(chartGeometry().center());
365 365 zoomIn(rect);
366 366 }
367 367
368 368 void ChartPresenter::zoomIn(const QRectF& rect)
369 369 {
370 370 QRectF r = rect.normalized();
371 371 r.translate(-m_chartMargins.topLeft());
372 372 if(m_animator) {
373 373
374 374 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
375 375 m_animator->setState(ChartAnimator::ZoomInState,point);
376 376 }
377 377 m_dataset->zoomInDomain(r,chartGeometry().size());
378 378 if(m_animator) {
379 379 m_animator->setState(ChartAnimator::ShowState);
380 380 }
381 381 }
382 382
383 383 void ChartPresenter::zoomOut()
384 384 {
385 385 if(m_animator)
386 386 {
387 387 m_animator->setState(ChartAnimator::ZoomOutState);
388 388 }
389 389
390 390 QSizeF size = chartGeometry().size();
391 391 QRectF rect = chartGeometry();
392 392 rect.translate(-m_chartMargins.topLeft());
393 393 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
394 394 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
395 395
396 396 if(m_animator){
397 397 m_animator->setState(ChartAnimator::ShowState);
398 398 }
399 399 }
400 400
401 401 void ChartPresenter::scroll(int dx,int dy)
402 402 {
403 403 if(m_animator){
404 404 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
405 405 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
406 406 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
407 407 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
408 408 }
409 409
410 410 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
411 411
412 412 if(m_animator){
413 413 m_animator->setState(ChartAnimator::ShowState);
414 414 }
415 415 }
416 416
417 417 QChart::AnimationOptions ChartPresenter::animationOptions() const
418 418 {
419 419 return m_options;
420 420 }
421 421
422 422 void ChartPresenter::updateLayout()
423 423 {
424 424 if (!m_rect.isValid()) return;
425 425
426 426 // recalculate title size
427 427
428 428 QSize titleSize;
429 429 int titlePadding=0;
430 430
431 431 if (m_titleItem) {
432 432 titleSize= m_titleItem->boundingRect().size().toSize();
433 433 }
434 434
435 435 //defaults
436 436 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));
437 437 titlePadding = m_chartMargins.top()/2;
438 438
439 439 QLegend* legend = m_chart->d_ptr->m_legend;
440 440
441 441 // recalculate legend position
442 442 if (legend->isAttachedToChart() && legend->isEnabled()) {
443 443
444 444 QRect legendRect;
445 445
446 446 // Reserve some space for legend
447 447 switch (legend->alignment()) {
448 448
449 449 case QLegend::AlignmentTop: {
450 450 int ledgendSize = legend->minHeight();
451 451 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
452 452 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
453 453 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
454 454 titlePadding = m_marginTiny + m_marginTiny;
455 455 break;
456 456 }
457 457 case QLegend::AlignmentBottom: {
458 458 int ledgendSize = legend->minHeight();
459 459 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
460 460 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
461 461 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
462 462 titlePadding = m_chartMargins.top()/2;
463 463 break;
464 464 }
465 465 case QLegend::AlignmentLeft: {
466 466 int ledgendSize = legend->minWidth();
467 467 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
468 468 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
469 469 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
470 470 titlePadding = m_chartMargins.top()/2;
471 471 break;
472 472 }
473 473 case QLegend::AlignmentRight: {
474 474 int ledgendSize = legend->minWidth();
475 475 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
476 476 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
477 477 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
478 478 titlePadding = m_chartMargins.top()/2;
479 479 break;
480 480 }
481 481 default: {
482 482 break;
483 483 }
484 484 }
485 485 }
486 486
487 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
488 {
489 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
490 return;
491 }
492
493
487 494 // recalculate title position
488 495 if (m_titleItem) {
489 496 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
490 497 m_titleItem->setPos(center.x(),titlePadding);
491 498 }
492 499
493 500 //recalculate background gradient
494 501 if (m_backgroundItem) {
495 502 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
496 503 }
497 504
505
498 506 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
499 507
500 508 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
501 509
502 510 if(m_chartRect!=chartRect){
503 511 m_chartRect=chartRect;
504 512 emit geometryChanged(m_chartRect);
505 513 }
506 514
507 515
508 516 }
509 517
510 518 void ChartPresenter::createChartBackgroundItem()
511 519 {
512 520 if (!m_backgroundItem) {
513 521 m_backgroundItem = new ChartBackground(rootItem());
514 522 m_backgroundItem->setPen(Qt::NoPen);
515 523 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
516 524 }
517 525 }
518 526
519 527 void ChartPresenter::createChartTitleItem()
520 528 {
521 529 if (!m_titleItem) {
522 530 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
523 531 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
524 532 }
525 533 }
526 534
527 535 #include "moc_chartpresenter_p.cpp"
528 536
529 537 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,249 +1,250
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 "qchartview.h"
22 22 #include "qchart_p.h"
23 23 #include "qchartview_p.h"
24 24 #include <QGraphicsScene>
25 25 #include <QRubberBand>
26 26
27 27
28 28 /*!
29 29 \enum QChartView::RubberBandPolicy
30 30
31 31 This enum describes the different types of rubber bands that can be used for zoom rect selection
32 32
33 33 \value NoRubberBand
34 34 \value VerticalRubberBand
35 35 \value HorizonalRubberBand
36 36 \value RectangleRubberBand
37 37 */
38 38
39 39 /*!
40 40 \class QChartView
41 41 \brief Standalone charting widget.
42 42
43 43 QChartView is a standalone widget that can display charts. It does not require separate
44 44 QGraphicsScene to work. It manages the graphical representation of different types of
45 45 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
46 46 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
47 47
48 48 \sa QChart
49 49 */
50 50
51 51 QTCOMMERCIALCHART_BEGIN_NAMESPACE
52 52
53 53 /*!
54 54 Constructs a chartView object which is a child of a\a parent.
55 55 */
56 56 QChartView::QChartView(QChart *chart,QWidget *parent) :
57 57 QGraphicsView(parent),
58 58 d_ptr(new QChartViewPrivate())
59 59 {
60 60 Q_ASSERT(chart);
61 61 d_ptr->m_scene = new QGraphicsScene(this);
62 62 d_ptr->m_chart = chart;
63 63 setFrameShape(QFrame::NoFrame);
64 64 setBackgroundRole(QPalette::Window);
65 65 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
66 66 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
67 67 setScene(d_ptr->m_scene);
68 68 d_ptr->m_scene->addItem(chart);
69 69 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
70 70 }
71 71
72 72
73 73 /*!
74 74 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
75 75 */
76 76 QChartView::~QChartView()
77 77 {
78 78 }
79 79
80 80 /*!
81 81 Returns the pointer to the associated chart
82 82 */
83 83 QChart* QChartView::chart() const
84 84 {
85 85 return d_ptr->m_chart;
86 86 }
87 87
88 88 /*!
89 89 Sets the RubberBandPlicy to \a rubberBand. Selected policy determines the way zooming is performed.
90 90 */
91 91 void QChartView::setRubberBand(const RubberBands& rubberBand)
92 92 {
93 93 d_ptr->m_rubberBandFlags=rubberBand;
94 94
95 95 if (!d_ptr->m_rubberBandFlags) {
96 96 delete d_ptr->m_rubberBand;
97 97 d_ptr->m_rubberBand=0;
98 98 return;
99 99 }
100 100
101 101 if (!d_ptr->m_rubberBand) {
102 102 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
103 103 d_ptr->m_rubberBand->setEnabled(true);
104 104 }
105 105 }
106 106
107 107 /*!
108 108 Returns the RubberBandPolicy that is currently being used by the widget.
109 109 */
110 110 QChartView::RubberBands QChartView::rubberBand() const
111 111 {
112 112 return d_ptr->m_rubberBandFlags;
113 113 }
114 114
115 115 /*!
116 116 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
117 117 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
118 118 */
119 119 void QChartView::mousePressEvent(QMouseEvent *event)
120 120 {
121 121 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
122 122
123 123 int padding = d_ptr->m_chart->margins().top();
124 124 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
125 125
126 126 if (rect.contains(event->pos())) {
127 127 d_ptr->m_rubberBandOrigin = event->pos();
128 128 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
129 129 d_ptr->m_rubberBand->show();
130 130 event->accept();
131 131 }
132 132 }
133 133 else {
134 134 QGraphicsView::mousePressEvent(event);
135 135 }
136 136 }
137 137
138 138 /*!
139 139 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
140 140 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
141 141 */
142 142 void QChartView::mouseMoveEvent(QMouseEvent *event)
143 143 {
144 144 if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
145 145 QRectF margins = d_ptr->m_chart->margins();
146 146 QRectF geometry = d_ptr->m_chart->geometry();
147 147 QRectF rect =geometry.adjusted(margins.left(),margins.top(),-margins.right(),-margins.bottom());
148 148 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
149 149 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
150 150 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
151 151 d_ptr->m_rubberBandOrigin.setY(rect.top());
152 152 height = rect.height();
153 153 }
154 154 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
155 155 d_ptr->m_rubberBandOrigin.setX(rect.left());
156 156 width= rect.width();
157 157 }
158 158 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(),d_ptr->m_rubberBandOrigin.y(), width,height).normalized());
159 159 }
160 160 else {
161 161 QGraphicsView::mouseMoveEvent(event);
162 162 }
163 163 }
164 164
165 165 /*!
166 166 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
167 167 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
168 168 */
169 169 void QChartView::mouseReleaseEvent(QMouseEvent *event)
170 170 {
171 171 if(d_ptr->m_rubberBand) {
172 172 if (event->button() == Qt::LeftButton && d_ptr->m_rubberBand->isVisible()) {
173 173 d_ptr->m_rubberBand->hide();
174 174 QRect rect = d_ptr->m_rubberBand->geometry();
175 175 d_ptr->m_chart->zoomIn(rect);
176 176 event->accept();
177 177 }
178 178
179 179 if(event->button()==Qt::RightButton){
180 180 d_ptr->m_chart->zoomOut();
181 181 event->accept();
182 182 }
183 183 }
184 184 else {
185 185 QGraphicsView::mouseReleaseEvent(event);
186 186 }
187 187 }
188 188
189 189 /*!
190 190 Pressing + and - keys performs zoomIn() and zoomOut() respectivly.
191 191 In other \a event is passed to the QGraphicsView::keyPressEvent() implementation
192 192 */
193 193 void QChartView::keyPressEvent(QKeyEvent *event)
194 194 {
195 195 switch (event->key()) {
196 196 case Qt::Key_Plus:
197 197 d_ptr->m_chart->zoomIn();
198 198 break;
199 199 case Qt::Key_Minus:
200 200 d_ptr->m_chart->zoomOut();
201 201 break;
202 202 case Qt::Key_Left:
203 203 d_ptr->m_chart->scrollLeft();
204 204 break;
205 205 case Qt::Key_Right:
206 206 d_ptr->m_chart->scrollRight();
207 207 break;
208 208 case Qt::Key_Up:
209 209 d_ptr->m_chart->scrollUp();
210 210 break;
211 211 case Qt::Key_Down:
212 212 d_ptr->m_chart->scrollDown();
213 213 break;
214 214 default:
215 215 QGraphicsView::keyPressEvent(event);
216 216 break;
217 217 }
218 218 }
219 219
220 220 /*!
221 221 Resizes and updates the chart area using the \a event data
222 222 */
223 223 void QChartView::resizeEvent(QResizeEvent *event)
224 224 {
225 225 QGraphicsView::resizeEvent(event);
226 226 d_ptr->m_chart->resize(size());
227 setMinimumSize(d_ptr->m_chart->minimumSize().toSize());
227 228 setSceneRect(d_ptr->m_chart->geometry());
228 229 }
229 230
230 231 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
231 232
232 233 QChartViewPrivate::QChartViewPrivate():
233 234 m_scene(0),
234 235 m_chart(0),
235 236 m_presenter(0),
236 237 m_rubberBand(0),
237 238 m_rubberBandFlags(QChartView::NoRubberBand)
238 239 {
239 240
240 241 }
241 242
242 243 QChartViewPrivate::~QChartViewPrivate()
243 244 {
244 245
245 246 }
246 247
247 248 #include "moc_qchartview.cpp"
248 249
249 250 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now