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