##// END OF EJS Templates
Bugfix: Adding/removing slices erased users colors....
Jani Honkonen -
r1093:54b5044db4a6
parent child
Show More
@@ -1,406 +1,411
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 #include "chartpresenter_p.h"
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "qaxis.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include "qabstractseries_p.h"
28 28 #include "qareaseries.h"
29 29 #include "chartaxis_p.h"
30 30 #include "areachartitem_p.h"
31 31 #include "chartbackground_p.h"
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
36 36 m_chart(chart),
37 37 m_animator(0),
38 38 m_dataset(dataset),
39 39 m_chartTheme(0),
40 40 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
41 41 m_options(QChart::NoAnimation),
42 42 m_minLeftMargin(0),
43 43 m_minBottomMargin(0),
44 44 m_backgroundItem(0),
45 45 m_titleItem(0),
46 46 m_marginBig(60),
47 47 m_marginSmall(20),
48 48 m_marginTiny(10),
49 49 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
50 50 {
51 51 }
52 52
53 53 ChartPresenter::~ChartPresenter()
54 54 {
55 55 delete m_chartTheme;
56 56 }
57 57
58 58 void ChartPresenter::setGeometry(const QRectF& rect)
59 59 {
60 60 m_rect = rect;
61 61 Q_ASSERT(m_rect.isValid());
62 62 updateLayout();
63 63 }
64 64
65 65 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
66 66 {
67 67 switch(axis->axisType()){
68 68 case ChartAxis::X_AXIS:
69 69 {
70 70 if(width>m_chartRect.width()+ m_chartMargins.left()) {
71 71 m_minLeftMargin= width - m_chartRect.width();
72 72 updateLayout();
73 73 }
74 74 break;
75 75 }
76 76 case ChartAxis::Y_AXIS:
77 77 {
78 78
79 79 if(m_minLeftMargin!=width){
80 80 m_minLeftMargin= width;
81 81 updateLayout();
82 82 }
83 83 break;
84 84 }
85 85
86 86 }
87 87 }
88 88
89 89 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
90 90 {
91 91 switch(axis->axisType()){
92 92 case ChartAxis::X_AXIS:
93 93 {
94 94 if(m_minBottomMargin!=height) {
95 95 m_minBottomMargin= height;
96 96 updateLayout();
97 97 }
98 98 break;
99 99 }
100 100 case ChartAxis::Y_AXIS:
101 101 {
102 102
103 103 if(height>m_chartMargins.bottom()+m_chartRect.height()){
104 104 m_minBottomMargin= height - m_chartRect.height();
105 105 updateLayout();
106 106 }
107 107 break;
108 108 }
109 109
110 110 }
111 111 }
112 112
113 113 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
114 114 {
115 115 ChartAxis* item = new ChartAxis(axis,this,axis==m_dataset->axisX()?ChartAxis::X_AXIS : ChartAxis::Y_AXIS);
116 116
117 117 if(m_options.testFlag(QChart::GridAxisAnimations)){
118 118 m_animator->addAnimation(item);
119 119 }
120 120
121 121 if(axis==m_dataset->axisX()){
122 122 m_chartTheme->decorate(axis,true);
123 123 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
124 124 //initialize
125 125 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
126 126
127 127 }
128 128 else{
129 129 m_chartTheme->decorate(axis,false);
130 130 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
131 131 //initialize
132 132 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
133 133 }
134 134
135 135 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
136 136 //initialize
137 137 item->handleGeometryChanged(m_chartRect);
138 138 m_axisItems.insert(axis, item);
139 139 }
140 140
141 141 void ChartPresenter::handleAxisRemoved(QAxis* axis)
142 142 {
143 143 ChartAxis* item = m_axisItems.take(axis);
144 144 Q_ASSERT(item);
145 145 if(m_animator) m_animator->removeAnimation(item);
146 146 delete item;
147 147 }
148 148
149 149
150 150 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
151 151 {
152 152 Chart *item = series->d_ptr->createGraphics(this);
153 153 Q_ASSERT(item);
154 154 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
155 155 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
156 156 //initialize
157 157 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
158 158 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
159 159 m_chartItems.insert(series,item);
160 160 }
161 161
162 162 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
163 163 {
164 164 Chart* item = m_chartItems.take(series);
165 165 Q_ASSERT(item);
166 166 if(m_animator) {
167 167 //small hack to handle area animations
168 168 if(series->type() == QAbstractSeries::SeriesTypeArea){
169 169 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
170 170 AreaChartItem* area = static_cast<AreaChartItem*>(item);
171 171 m_animator->removeAnimation(area->upperLineItem());
172 172 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
173 173 }else
174 174 m_animator->removeAnimation(item);
175 175 }
176 176 delete item;
177 177 }
178 178
179 179 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
180 180 {
181 181 if(m_chartTheme && m_chartTheme->id() == theme) return;
182 182 delete m_chartTheme;
183 183 m_chartTheme = ChartTheme::createTheme(theme);
184 184 m_chartTheme->setForced(force);
185 185 m_chartTheme->decorate(m_chart);
186 186 m_chartTheme->decorate(m_chart->legend());
187 187 resetAllElements();
188
189 // We do not want "force" to stay on.
190 // Bar/pie are calling decorate when adding/removing slices/bars which means
191 // that to preserve users colors "force" must not be on.
192 m_chartTheme->setForced(false);
188 193 }
189 194
190 195 QChart::ChartTheme ChartPresenter::theme()
191 196 {
192 197 return m_chartTheme->id();
193 198 }
194 199
195 200 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
196 201 {
197 202 if(m_options!=options) {
198 203
199 204 m_options=options;
200 205
201 206 if(m_options!=QChart::NoAnimation && !m_animator) {
202 207 m_animator= new ChartAnimator(this);
203 208 }
204 209 resetAllElements();
205 210 }
206 211
207 212 }
208 213
209 214 void ChartPresenter::resetAllElements()
210 215 {
211 216 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
212 217 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
213 218
214 219 foreach(QAxis *axis, axisList) {
215 220 handleAxisRemoved(axis);
216 221 handleAxisAdded(axis,m_dataset->domain(axis));
217 222 }
218 223 foreach(QAbstractSeries *series, seriesList) {
219 224 handleSeriesRemoved(series);
220 225 handleSeriesAdded(series,m_dataset->domain(series));
221 226 // m_dataset->removeSeries(series);
222 227 // m_dataset->addSeries(series);
223 228 }
224 229 }
225 230
226 231 void ChartPresenter::zoomIn()
227 232 {
228 233 QRectF rect = chartGeometry();
229 234 rect.setWidth(rect.width()/2);
230 235 rect.setHeight(rect.height()/2);
231 236 rect.moveCenter(chartGeometry().center());
232 237 zoomIn(rect);
233 238 }
234 239
235 240 void ChartPresenter::zoomIn(const QRectF& rect)
236 241 {
237 242 QRectF r = rect.normalized();
238 243 r.translate(-m_chartMargins.topLeft());
239 244 if(!r.isValid()) return;
240 245 if(m_animator) {
241 246
242 247 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
243 248 m_animator->setState(ChartAnimator::ZoomInState,point);
244 249 }
245 250 m_dataset->zoomInDomain(r,chartGeometry().size());
246 251 if(m_animator) {
247 252 m_animator->setState(ChartAnimator::ShowState);
248 253 }
249 254 }
250 255
251 256 void ChartPresenter::zoomOut()
252 257 {
253 258 if(m_animator)
254 259 {
255 260 m_animator->setState(ChartAnimator::ZoomOutState);
256 261 }
257 262
258 263 QSizeF size = chartGeometry().size();
259 264 QRectF rect = chartGeometry();
260 265 rect.translate(-m_chartMargins.topLeft());
261 266 if(!rect.isValid()) return;
262 267 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
263 268 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
264 269
265 270 if(m_animator){
266 271 m_animator->setState(ChartAnimator::ShowState);
267 272 }
268 273 }
269 274
270 275 void ChartPresenter::scroll(int dx,int dy)
271 276 {
272 277 if(m_animator){
273 278 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
274 279 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
275 280 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
276 281 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
277 282 }
278 283
279 284 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
280 285
281 286 if(m_animator){
282 287 m_animator->setState(ChartAnimator::ShowState);
283 288 }
284 289 }
285 290
286 291 QChart::AnimationOptions ChartPresenter::animationOptions() const
287 292 {
288 293 return m_options;
289 294 }
290 295
291 296 void ChartPresenter::updateLayout()
292 297 {
293 298 if (!m_rect.isValid()) return;
294 299
295 300 // recalculate title size
296 301
297 302 QSize titleSize;
298 303 int titlePadding=0;
299 304
300 305 if (m_titleItem) {
301 306 titleSize= m_titleItem->boundingRect().size().toSize();
302 307 }
303 308
304 309 //defaults
305 310 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));
306 311 titlePadding = m_chartMargins.top()/2;
307 312
308 313 QLegend* legend = m_chart->d_ptr->m_legend;
309 314
310 315 // recalculate legend position
311 316 if (legend->isAttachedToChart() && legend->isEnabled()) {
312 317
313 318 QRect legendRect;
314 319
315 320 // Reserve some space for legend
316 321 switch (legend->alignment()) {
317 322
318 323 case QLegend::AlignmentTop: {
319 324 int ledgendSize = legend->minHeight();
320 325 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
321 326 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
322 327 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
323 328 titlePadding = m_marginTiny + m_marginTiny;
324 329 break;
325 330 }
326 331 case QLegend::AlignmentBottom: {
327 332 int ledgendSize = legend->minHeight();
328 333 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
329 334 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
330 335 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
331 336 titlePadding = m_chartMargins.top()/2;
332 337 break;
333 338 }
334 339 case QLegend::AlignmentLeft: {
335 340 int ledgendSize = legend->minWidth();
336 341 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
337 342 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
338 343 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
339 344 titlePadding = m_chartMargins.top()/2;
340 345 break;
341 346 }
342 347 case QLegend::AlignmentRight: {
343 348 int ledgendSize = legend->minWidth();
344 349 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
345 350 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
346 351 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
347 352 titlePadding = m_chartMargins.top()/2;
348 353 break;
349 354 }
350 355 default: {
351 356 break;
352 357 }
353 358 }
354 359 }
355 360
356 361 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
357 362 {
358 363 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
359 364 return;
360 365 }
361 366
362 367
363 368 // recalculate title position
364 369 if (m_titleItem) {
365 370 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
366 371 m_titleItem->setPos(center.x(),titlePadding);
367 372 }
368 373
369 374 //recalculate background gradient
370 375 if (m_backgroundItem) {
371 376 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
372 377 }
373 378
374 379
375 380 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
376 381
377 382 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
378 383
379 384 if(m_chartRect!=chartRect){
380 385 m_chartRect=chartRect;
381 386 emit geometryChanged(m_chartRect);
382 387 }
383 388
384 389
385 390 }
386 391
387 392 void ChartPresenter::createChartBackgroundItem()
388 393 {
389 394 if (!m_backgroundItem) {
390 395 m_backgroundItem = new ChartBackground(rootItem());
391 396 m_backgroundItem->setPen(Qt::NoPen);
392 397 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
393 398 }
394 399 }
395 400
396 401 void ChartPresenter::createChartTitleItem()
397 402 {
398 403 if (!m_titleItem) {
399 404 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
400 405 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
401 406 }
402 407 }
403 408
404 409 #include "moc_chartpresenter_p.cpp"
405 410
406 411 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now