##// END OF EJS Templates
Fix label angle setting for axis before axis is added to chart....
Miikka Heikkinen -
r2410:47bf654423ee
parent child
Show More
@@ -1,532 +1,532
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 "chartaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartlayout_p.h"
26 26 #include "abstractdomain_p.h"
27 27 #include <qmath.h>
28 28 #include <QDateTime>
29 29 #include <QValueAxis>
30 30 #include <QLogValueAxis>
31 31 #include <QGraphicsLayout>
32 32 #include <QFontMetrics>
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 ChartAxis::ChartAxis(QAbstractAxis *axis, QGraphicsItem* item , bool intervalAxis)
37 37 : ChartElement(item),
38 38 m_axis(axis),
39 m_labelsAngle(0),
39 m_labelsAngle(axis->labelsAngle()),
40 40 m_grid(new QGraphicsItemGroup(item)),
41 41 m_arrow(new QGraphicsItemGroup(item)),
42 42 m_shades(new QGraphicsItemGroup(item)),
43 43 m_labels(new QGraphicsItemGroup(item)),
44 44 m_title(new QGraphicsSimpleTextItem(item)),
45 45 m_animation(0),
46 46 m_labelPadding(5),
47 47 m_intervalAxis(intervalAxis)
48 48 {
49 49 Q_ASSERT(item);
50 50 //initial initialization
51 51 m_arrow->setHandlesChildEvents(false);
52 52 m_arrow->setZValue(ChartPresenter::AxisZValue);
53 53 m_labels->setZValue(ChartPresenter::AxisZValue);
54 54 m_shades->setZValue(ChartPresenter::ShadesZValue);
55 55 m_grid->setZValue(ChartPresenter::GridZValue);
56 56 m_title->setZValue(ChartPresenter::GridZValue);
57 57 handleVisibleChanged(m_axis->isVisible());
58 58 connectSlots();
59 59
60 60 setFlag(QGraphicsItem::ItemHasNoContents,true);
61 61 }
62 62
63 63 void ChartAxis::connectSlots()
64 64 {
65 65 QObject::connect(m_axis,SIGNAL(visibleChanged(bool)),this,SLOT(handleVisibleChanged(bool)));
66 66 QObject::connect(m_axis,SIGNAL(lineVisibleChanged(bool)),this,SLOT(handleArrowVisibleChanged(bool)));
67 67 QObject::connect(m_axis,SIGNAL(gridVisibleChanged(bool)),this,SLOT(handleGridVisibleChanged(bool)));
68 68 QObject::connect(m_axis,SIGNAL(labelsVisibleChanged(bool)),this,SLOT(handleLabelsVisibleChanged(bool)));
69 69 QObject::connect(m_axis,SIGNAL(shadesVisibleChanged(bool)),this,SLOT(handleShadesVisibleChanged(bool)));
70 70 QObject::connect(m_axis,SIGNAL(labelsAngleChanged(int)),this,SLOT(handleLabelsAngleChanged(int)));
71 71 QObject::connect(m_axis,SIGNAL(linePenChanged(const QPen&)),this,SLOT(handleArrowPenChanged(const QPen&)));
72 72 QObject::connect(m_axis,SIGNAL(labelsPenChanged(const QPen&)),this,SLOT(handleLabelsPenChanged(const QPen&)));
73 73 QObject::connect(m_axis,SIGNAL(labelsBrushChanged(const QBrush&)),this,SLOT(handleLabelsBrushChanged(const QBrush&)));
74 74 QObject::connect(m_axis,SIGNAL(labelsFontChanged(const QFont&)),this,SLOT(handleLabelsFontChanged(const QFont&)));
75 75 QObject::connect(m_axis,SIGNAL(gridLinePenChanged(const QPen&)),this,SLOT(handleGridPenChanged(const QPen&)));
76 76 QObject::connect(m_axis,SIGNAL(shadesPenChanged(const QPen&)),this,SLOT(handleShadesPenChanged(const QPen&)));
77 77 QObject::connect(m_axis,SIGNAL(shadesBrushChanged(const QBrush&)),this,SLOT(handleShadesBrushChanged(const QBrush&)));
78 78 QObject::connect(m_axis,SIGNAL(titleTextChanged(const QString&)),this,SLOT(handleTitleTextChanged(const QString&)));
79 79 QObject::connect(m_axis,SIGNAL(titleFontChanged(const QFont&)),this,SLOT(handleTitleFontChanged(const QFont&)));
80 80 QObject::connect(m_axis,SIGNAL(titlePenChanged(const QPen&)),this,SLOT(handleTitlePenChanged(const QPen&)));
81 81 QObject::connect(m_axis,SIGNAL(titleBrushChanged(const QBrush&)),this,SLOT(handleTitleBrushChanged(const QBrush&)));
82 82 QObject::connect(m_axis,SIGNAL(titleVisibleChanged(bool)),this,SLOT(handleTitleVisibleChanged(bool)));
83 83 QObject::connect(m_axis->d_ptr.data(),SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(handleRangeChanged(qreal,qreal)));
84 84 }
85 85
86 86 ChartAxis::~ChartAxis()
87 87 {
88 88 }
89 89
90 90 void ChartAxis::setAnimation(AxisAnimation *animation)
91 91 {
92 92 m_animation = animation;
93 93 }
94 94
95 95 void ChartAxis::setLayout(QVector<qreal> &layout)
96 96 {
97 97 m_layoutVector = layout;
98 98 }
99 99
100 100 void ChartAxis::createItems(int count)
101 101 {
102 102 if (m_arrow->childItems().size() == 0){
103 103 QGraphicsLineItem* arrow = new ArrowItem(this, this);
104 104 arrow->setPen(m_axis->linePen());
105 105 m_arrow->addToGroup(arrow);
106 106 }
107 107
108 108 if (m_intervalAxis && m_grid->childItems().size() == 0) {
109 109 for (int i = 0 ; i < 2 ; i ++){
110 110 QGraphicsLineItem* item = new QGraphicsLineItem(this);
111 111 item->setPen(m_axis->gridLinePen());
112 112 m_grid->addToGroup(item);
113 113 }
114 114 }
115 115
116 116 for (int i = 0; i < count; ++i) {
117 117 QGraphicsLineItem* arrow = new QGraphicsLineItem(this);
118 118 arrow->setPen(m_axis->linePen());
119 119 QGraphicsLineItem* grid = new QGraphicsLineItem(this);
120 120 grid->setPen(m_axis->gridLinePen());
121 121 QGraphicsSimpleTextItem* label = new QGraphicsSimpleTextItem(this);
122 122 label->setFont(m_axis->labelsFont());
123 123 label->setPen(m_axis->labelsPen());
124 124 label->setBrush(m_axis->labelsBrush());
125 125 label->setRotation(m_labelsAngle);
126 126 m_arrow->addToGroup(arrow);
127 127 m_grid->addToGroup(grid);
128 128 m_labels->addToGroup(label);
129 129
130 130 if ((m_grid->childItems().size()) % 2 && m_grid->childItems().size() > 2){
131 131 QGraphicsRectItem* shades = new QGraphicsRectItem(this);
132 132 shades->setPen(m_axis->shadesPen());
133 133 shades->setBrush(m_axis->shadesBrush());
134 134 m_shades->addToGroup(shades);
135 135 }
136 136 }
137 137
138 138 }
139 139
140 140 void ChartAxis::deleteItems(int count)
141 141 {
142 142 QList<QGraphicsItem *> lines = m_grid->childItems();
143 143 QList<QGraphicsItem *> labels = m_labels->childItems();
144 144 QList<QGraphicsItem *> shades = m_shades->childItems();
145 145 QList<QGraphicsItem *> axis = m_arrow->childItems();
146 146
147 147 for (int i = 0; i < count; ++i) {
148 148 if (lines.size() % 2 && lines.size() > 1)
149 149 delete(shades.takeLast());
150 150 delete(lines.takeLast());
151 151 delete(labels.takeLast());
152 152 delete(axis.takeLast());
153 153 }
154 154 }
155 155
156 156 void ChartAxis::updateLayout(QVector<qreal> &layout)
157 157 {
158 158 int diff = m_layoutVector.size() - layout.size();
159 159
160 160 if (diff > 0)
161 161 deleteItems(diff);
162 162 else if (diff < 0)
163 163 createItems(-diff);
164 164
165 165 if (m_animation) {
166 166 switch (presenter()->state()) {
167 167 case ChartPresenter::ZoomInState:
168 168 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
169 169 m_animation->setAnimationPoint(presenter()->statePoint());
170 170 break;
171 171 case ChartPresenter::ZoomOutState:
172 172 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
173 173 m_animation->setAnimationPoint(presenter()->statePoint());
174 174 break;
175 175 case ChartPresenter::ScrollUpState:
176 176 case ChartPresenter::ScrollLeftState:
177 177 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
178 178 break;
179 179 case ChartPresenter::ScrollDownState:
180 180 case ChartPresenter::ScrollRightState:
181 181 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
182 182 break;
183 183 case ChartPresenter::ShowState:
184 184 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
185 185 break;
186 186 }
187 187 m_animation->setValues(m_layoutVector, layout);
188 188 presenter()->startAnimation(m_animation);
189 189 } else {
190 190 setLayout(layout);
191 191 updateGeometry();
192 192 }
193 193 }
194 194
195 195 void ChartAxis::setLabelPadding(int padding)
196 196 {
197 197 m_labelPadding = padding;
198 198 }
199 199
200 200 bool ChartAxis::isEmpty()
201 201 {
202 202 return m_axisRect.isEmpty() || m_gridRect.isEmpty() || qFuzzyCompare(min(),max());
203 203 }
204 204
205 205 void ChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
206 206 {
207 207 m_gridRect = grid;
208 208 m_axisRect = axis;
209 209
210 210 if (isEmpty())
211 211 return;
212 212
213 213 QVector<qreal> layout = calculateLayout();
214 214 updateLayout(layout);
215 215 }
216 216
217 217 qreal ChartAxis::min() const
218 218 {
219 219 return m_axis->d_ptr->min();
220 220 }
221 221
222 222 qreal ChartAxis::max() const
223 223 {
224 224 return m_axis->d_ptr->max();
225 225 }
226 226
227 227 QFont ChartAxis::font() const
228 228 {
229 229 return m_axis->labelsFont();
230 230 }
231 231
232 232 QFont ChartAxis::titleFont() const
233 233 {
234 234 return m_axis->titleFont();
235 235 }
236 236
237 237 QString ChartAxis::titleText() const
238 238 {
239 239 return m_axis->titleText();
240 240 }
241 241
242 242 void ChartAxis::axisSelected()
243 243 {
244 244 emit clicked();
245 245 }
246 246
247 247 Qt::Orientation ChartAxis::orientation() const
248 248 {
249 249 return m_axis->orientation();
250 250 }
251 251
252 252 Qt::Alignment ChartAxis::alignment() const
253 253 {
254 254 return m_axis->alignment();
255 255 }
256 256
257 257 void ChartAxis::setLabels(const QStringList &labels)
258 258 {
259 259 m_labelsList = labels;
260 260 }
261 261
262 262 QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
263 263 {
264 264 Q_UNUSED(which);
265 265 Q_UNUSED(constraint);
266 266 return QSizeF();
267 267 }
268 268
269 269 //handlers
270 270
271 271 void ChartAxis::handleArrowVisibleChanged(bool visible)
272 272 {
273 273 m_arrow->setVisible(visible);
274 274 }
275 275
276 276 void ChartAxis::handleGridVisibleChanged(bool visible)
277 277 {
278 278 m_grid->setVisible(visible);
279 279 }
280 280
281 281 void ChartAxis::handleLabelsVisibleChanged(bool visible)
282 282 {
283 283 m_labels->setVisible(visible);
284 284 }
285 285
286 286 void ChartAxis::handleShadesVisibleChanged(bool visible)
287 287 {
288 288 m_shades->setVisible(visible);
289 289 }
290 290
291 291 void ChartAxis::handleTitleVisibleChanged(bool visible)
292 292 {
293 293 m_title->setVisible(visible);
294 294 presenter()->layout()->invalidate();
295 295 }
296 296
297 297 void ChartAxis::handleLabelsAngleChanged(int angle)
298 298 {
299 299 foreach (QGraphicsItem *item, m_labels->childItems())
300 300 item->setRotation(angle);
301 301
302 302 m_labelsAngle = angle;
303 303 }
304 304
305 305 void ChartAxis::handleLabelsPenChanged(const QPen &pen)
306 306 {
307 307 foreach (QGraphicsItem *item , m_labels->childItems())
308 308 static_cast<QGraphicsSimpleTextItem *>(item)->setPen(pen);
309 309 }
310 310
311 311 void ChartAxis::handleLabelsBrushChanged(const QBrush &brush)
312 312 {
313 313 foreach (QGraphicsItem *item , m_labels->childItems())
314 314 static_cast<QGraphicsSimpleTextItem *>(item)->setBrush(brush);
315 315 }
316 316
317 317 void ChartAxis::handleLabelsFontChanged(const QFont &font)
318 318 {
319 319 foreach (QGraphicsItem *item , m_labels->childItems())
320 320 static_cast<QGraphicsSimpleTextItem *>(item)->setFont(font);
321 321 QGraphicsLayoutItem::updateGeometry();
322 322 presenter()->layout()->invalidate();
323 323 }
324 324
325 325 void ChartAxis::handleShadesBrushChanged(const QBrush &brush)
326 326 {
327 327 foreach (QGraphicsItem *item , m_shades->childItems())
328 328 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
329 329 }
330 330
331 331 void ChartAxis::handleShadesPenChanged(const QPen &pen)
332 332 {
333 333 foreach (QGraphicsItem *item , m_shades->childItems())
334 334 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
335 335 }
336 336
337 337 void ChartAxis::handleArrowPenChanged(const QPen &pen)
338 338 {
339 339 foreach (QGraphicsItem *item , m_arrow->childItems())
340 340 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
341 341 }
342 342
343 343 void ChartAxis::handleGridPenChanged(const QPen &pen)
344 344 {
345 345 foreach (QGraphicsItem *item , m_grid->childItems())
346 346 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
347 347 }
348 348
349 349 void ChartAxis::handleTitleTextChanged(const QString &title)
350 350 {
351 351 Q_UNUSED(title)
352 352 QGraphicsLayoutItem::updateGeometry();
353 353 presenter()->layout()->invalidate();
354 354 }
355 355
356 356
357 357 void ChartAxis::handleTitlePenChanged(const QPen &pen)
358 358 {
359 359 m_title->setPen(pen);
360 360 }
361 361
362 362 void ChartAxis::handleTitleBrushChanged(const QBrush &brush)
363 363 {
364 364 m_title->setBrush(brush);
365 365 }
366 366
367 367 void ChartAxis::handleTitleFontChanged(const QFont &font)
368 368 {
369 369 if(m_title->font() != font){
370 370 m_title->setFont(font);
371 371 QGraphicsLayoutItem::updateGeometry();
372 372 presenter()->layout()->invalidate();
373 373 }
374 374 }
375 375
376 376 void ChartAxis::handleVisibleChanged(bool visible)
377 377 {
378 378 setVisible(visible);
379 379 if(!visible) {
380 380 m_grid->setVisible(visible);
381 381 m_arrow->setVisible(visible);
382 382 m_shades->setVisible(visible);
383 383 m_labels->setVisible(visible);
384 384 m_title->setVisible(visible);
385 385 }else {
386 386 m_grid->setVisible(m_axis->isGridLineVisible());
387 387 m_arrow->setVisible(m_axis->isLineVisible());
388 388 m_shades->setVisible(m_axis->shadesVisible());
389 389 m_labels->setVisible(m_axis->labelsVisible());
390 390 m_title->setVisible(m_axis->isTitleVisible());
391 391 }
392 392
393 393 if(presenter()) presenter()->layout()->invalidate();
394 394 }
395 395
396 396 void ChartAxis::handleRangeChanged(qreal min, qreal max)
397 397 {
398 398 Q_UNUSED(min);
399 399 Q_UNUSED(max);
400 400
401 401 if (!isEmpty()) {
402 402
403 403 QVector<qreal> layout = calculateLayout();
404 404 updateLayout(layout);
405 405 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
406 406 QSizeF after = sizeHint(Qt::PreferredSize);
407 407
408 408 if (before != after) {
409 409 QGraphicsLayoutItem::updateGeometry();
410 410 //we don't want to call invalidate on layout, since it will change minimum size of component,
411 411 //which we would like to avoid since it causes nasty flips when scrolling or zooming,
412 412 //instead recalculate layout and use plotArea for extra space.
413 413 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
414 414 }
415 415 }
416 416
417 417 }
418 418
419 419 //helpers
420 420
421 421 QStringList ChartAxis::createValueLabels(qreal min, qreal max, int ticks,const QString& format)
422 422 {
423 423 //TODO: Q_ASSERT(m_max > m_min);
424 424 //TODO: Q_ASSERT(ticks > 1);
425 425
426 426 QStringList labels;
427 427
428 428 if(max <= min || ticks < 1){
429 429 return labels;
430 430 }
431 431
432 432 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
433 433 n++;
434 434
435 435 if (format.isNull()) {
436 436 for (int i = 0; i < ticks; i++) {
437 437 qreal value = min + (i * (max - min) / (ticks - 1));
438 438 labels << QString::number(value, 'f', n);
439 439 }
440 440 } else {
441 441 QByteArray array = format.toLatin1();
442 442 for (int i = 0; i < ticks; i++) {
443 443 qreal value = min + (i * (max - min) / (ticks - 1));
444 444 if (format.contains("d")
445 445 || format.contains("i")
446 446 || format.contains("c"))
447 447 labels << QString().sprintf(array, (qint64)value);
448 448 else if (format.contains("u")
449 449 || format.contains("o")
450 450 || format.contains("x", Qt::CaseInsensitive))
451 451 labels << QString().sprintf(array, (quint64)value);
452 452 else if (format.contains("f", Qt::CaseInsensitive)
453 453 || format.contains("e", Qt::CaseInsensitive)
454 454 || format.contains("g", Qt::CaseInsensitive))
455 455 labels << QString().sprintf(array, value);
456 456 else
457 457 labels << QString();
458 458 }
459 459 }
460 460
461 461 return labels;
462 462 }
463 463
464 464 QStringList ChartAxis::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString& format)
465 465 {
466 466 // Q_ASSERT(m_max > m_min);
467 467 // Q_ASSERT(ticks > 1);
468 468
469 469 QStringList labels;
470 470
471 471 int n = 0;
472 472 if (ticks > 1)
473 473 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
474 474 n++;
475 475
476 476 int firstTick;
477 477 if (base > 1)
478 478 firstTick = ceil(log10(min) / log10(base));
479 479 else
480 480 firstTick = ceil(log10(max) / log10(base));
481 481
482 482 if (format.isNull()) {
483 483 for (int i = firstTick; i < ticks + firstTick; i++) {
484 484 qreal value = qPow(base, i);
485 485 labels << QString::number(value, 'f', n);
486 486 }
487 487 } else {
488 488 QByteArray array = format.toLatin1();
489 489 for (int i = firstTick; i < ticks + firstTick; i++) {
490 490 qreal value = qPow(base, i);
491 491 if (format.contains("d")
492 492 || format.contains("i")
493 493 || format.contains("c"))
494 494 labels << QString().sprintf(array, (qint64)value);
495 495 else if (format.contains("u")
496 496 || format.contains("o")
497 497 || format.contains("x", Qt::CaseInsensitive))
498 498 labels << QString().sprintf(array, (quint64)value);
499 499 else if (format.contains("f", Qt::CaseInsensitive)
500 500 || format.contains("e", Qt::CaseInsensitive)
501 501 || format.contains("g", Qt::CaseInsensitive))
502 502 labels << QString().sprintf(array, value);
503 503 else
504 504 labels << QString();
505 505 }
506 506 }
507 507
508 508 return labels;
509 509 }
510 510
511 511 QStringList ChartAxis::createDateTimeLabels(qreal min, qreal max,int ticks,const QString& format)
512 512 {
513 513 //TODO: Q_ASSERT(m_max > m_min);
514 514 //TODO: Q_ASSERT(ticks > 1);
515 515 QStringList labels;
516 516
517 517 if(max <= min || ticks < 1) {
518 518 return labels;
519 519 }
520 520
521 521 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
522 522 n++;
523 523 for (int i = 0; i < ticks; i++) {
524 524 qreal value = min + (i * (max - min) / (ticks - 1));
525 525 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
526 526 }
527 527 return labels;
528 528 }
529 529
530 530 #include "moc_chartaxis_p.cpp"
531 531
532 532 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now