##// END OF EJS Templates
Add Polar chart support...
Add Polar chart support This commit also heavily refactors things as polar chart needs separate implementation of various classes that previously only needed one, such as ChartAxis and ChartLayout. Task-number: QTRD-1757 Change-Id: I3d3db23920314987ceef3ae92879960b833b7136 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>

File last commit:

r2483:f494279b6366
r2483:f494279b6366
Show More
verticalaxis.cpp
232 lines | 8.6 KiB | text/x-c | CppLexer
/ src / axis / verticalaxis.cpp
Michal Klocek
Refactors axis updateGeometry handling...
r2111 /****************************************************************************
**
Miikka Heikkinen
Fixed the copyright year 2012 -> 2013
r2432 ** Copyright (C) 2013 Digia Plc
Michal Klocek
Refactors axis updateGeometry handling...
r2111 ** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the Qt Commercial Charts Add-on.
**
** $QT_BEGIN_LICENSE$
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
** $QT_END_LICENSE$
**
****************************************************************************/
#include "verticalaxis_p.h"
#include "qabstractaxis.h"
#include <QFontMetrics>
Michal Klocek
Adds title support for mulitaxis...
r2139 #include <QDebug>
Michal Klocek
Refactors axis updateGeometry handling...
r2111
QTCOMMERCIALCHART_BEGIN_NAMESPACE
Miikka Heikkinen
Add Polar chart support...
r2483 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
: CartesianChartAxis(axis, item, intervalAxis)
Michal Klocek
Refactors axis updateGeometry handling...
r2111 {
}
VerticalAxis::~VerticalAxis()
{
}
void VerticalAxis::updateGeometry()
{
Miikka Heikkinen
Add Polar chart support...
r2483 const QVector<qreal> &layout = ChartAxisElement::layout();
Michal Klocek
Refactors axis updateGeometry handling...
r2111
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (layout.isEmpty())
return;
Michal Klocek
Refactors axis updateGeometry handling...
r2111
QStringList labelList = labels();
Miikka Heikkinen
Add Polar chart support...
r2483 QList<QGraphicsItem *> lines = gridItems();
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QList<QGraphicsItem *> labels = labelItems();
QList<QGraphicsItem *> shades = shadeItems();
Miikka Heikkinen
Add Polar chart support...
r2483 QList<QGraphicsItem *> arrow = arrowItems();
QGraphicsSimpleTextItem *title = titleItem();
Michal Klocek
Refactors axis updateGeometry handling...
r2111
Q_ASSERT(labels.size() == labelList.size());
Q_ASSERT(layout.size() == labelList.size());
Jani Honkonen
src folder: another massive victory for coding style police
r2131 const QRectF &axisRect = axisGeometry();
const QRectF &gridRect = gridGeometry();
Michal Klocek
Refactors axis updateGeometry handling...
r2111
qreal height = axisRect.bottom();
Michal Klocek
Updates axis drawing code...
r2133 //arrow
Miikka Heikkinen
Add Polar chart support...
r2483 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
Michal Klocek
Updates axis drawing code...
r2133
//arrow position
Miikka Heikkinen
Add Polar chart support...
r2483 if (axis()->alignment() == Qt::AlignLeft)
arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
else if (axis()->alignment() == Qt::AlignRight)
arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
Michal Klocek
Refactors axis updateGeometry handling...
r2111
Miikka Heikkinen
Add Polar chart support...
r2483 QFontMetrics fn(axis()->labelsFont());
Michal Klocek
Refactors axis updateGeometry handling...
r2111
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 //title
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 int titlePad = 0;
QRectF titleBoundingRect;
Miikka Heikkinen
Add Polar chart support...
r2483 QString titleText = axis()->titleText();
if (!titleText.isEmpty() && titleItem()->isVisible()) {
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 QFontMetrics fn(title->font());
int size(0);
size = gridRect.height();
if (fn.boundingRect(titleText).width() > size) {
QString string = titleText + "...";
while (fn.boundingRect(string).width() > size && string.length() > 3)
Miikka Heikkinen
Add Polar chart support...
r2483 string.remove(string.length() - 4, 1);
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 title->setText(string);
Miikka Heikkinen
Add Polar chart support...
r2483 } else {
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 title->setText(titleText);
}
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 titlePad = titlePadding();
titleBoundingRect = title->boundingRect();
QPointF center = gridRect.center() - titleBoundingRect.center();
Miikka Heikkinen
Add Polar chart support...
r2483 if (axis()->alignment() == Qt::AlignLeft) {
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 title->setPos(axisRect.left() - titleBoundingRect.width() / 2 + titleBoundingRect.height() / 2 + titlePad, center.y());
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 }
Miikka Heikkinen
Add Polar chart support...
r2483 else if (axis()->alignment() == Qt::AlignRight) {
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 title->setPos(axisRect.right() - titleBoundingRect.width() / 2 - titleBoundingRect.height() / 2 - titlePad, center.y());
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 }
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 title->setTransformOriginPoint(titleBoundingRect.center());
Michal Klocek
Adds consider title boundary for axis label wrapping
r2148 title->setRotation(270);
}
Michal Klocek
Refactors axis updateGeometry handling...
r2111 for (int i = 0; i < layout.size(); ++i) {
Michal Klocek
Updates axis drawing code...
r2133 //items
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
Miikka Heikkinen
Add Polar chart support...
r2483 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
Michal Klocek
Refactors axis updateGeometry handling...
r2111
//grid line
Miikka Heikkinen
Add Polar chart support...
r2483 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
Michal Klocek
Refactors axis updateGeometry handling...
r2111
Michal Klocek
Updates axis drawing code...
r2133 //label text wrapping
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QString text = labelList.at(i);
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 QRectF boundingRect = labelBoundingRect(fn, text);
Miikka Heikkinen
Fix axis geometry when there is no axis title...
r2415 qreal size = axisRect.right() - axisRect.left() - labelPadding() - titleBoundingRect.height() - (titlePad * 2);
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 if (boundingRect.width() > size) {
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QString label = text + "...";
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 while (boundingRect.width() > size && label.length() > 3) {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 label.remove(label.length() - 4, 1);
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 boundingRect = labelBoundingRect(fn, label);
}
Michal Klocek
Refactors axis updateGeometry handling...
r2111 labelItem->setText(label);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 } else {
Michal Klocek
Refactors axis updateGeometry handling...
r2111 labelItem->setText(text);
}
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412
Michal Klocek
Updates axis drawing code...
r2133 //label transformation origin point
Jani Honkonen
src folder: another massive victory for coding style police
r2131 const QRectF &rect = labelItem->boundingRect();
Michal Klocek
Updates axis drawing code...
r2133
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 int widthDiff = rect.width() - boundingRect.width();
Michal Klocek
Refactors axis updateGeometry handling...
r2111
//ticks and label position
Miikka Heikkinen
Add Polar chart support...
r2483 if (axis()->alignment() == Qt::AlignLeft) {
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y());
Jani Honkonen
src folder: another massive victory for coding style police
r2131 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
Miikka Heikkinen
Add Polar chart support...
r2483 } else if (axis()->alignment() == Qt::AlignRight) {
Miikka Heikkinen
Fix axis sizehints when labels are angled...
r2412 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y());
Jani Honkonen
src folder: another massive victory for coding style police
r2131 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
Michal Klocek
Updates axis drawing code...
r2133
Miikka Heikkinen
Fix category axis label positioning....
r2446 //label in between
bool forceHide = false;
if (intervalAxis() && (i + 1) != layout.size()) {
qreal lowerBound = qMin(layout[i], gridRect.bottom());
qreal upperBound = qMax(layout[i + 1], gridRect.top());
const qreal delta = lowerBound - upperBound;
// Hide label in case visible part of the category at the grid edge is too narrow
if (delta < boundingRect.height()
&& (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
forceHide = true;
} else {
labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
}
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
Miikka Heikkinen
Compensate for rounding errors when determining label visibility...
r2445 //label overlap detection - compensate one pixel for rounding errors
Miikka Heikkinen
Fix category axis label positioning....
r2446 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
Miikka Heikkinen
Compensate for rounding errors when determining label visibility...
r2445 (labelItem->pos().y() + (boundingRect.height() / 2.0) - 1.0) > axisRect.bottom() ||
labelItem->pos().y() + (boundingRect.height() / 2.0) < (axisRect.top() - 1.0)) {
Michal Klocek
Refactors axis updateGeometry handling...
r2111 labelItem->setVisible(false);
Michal Klocek
Updates axis drawing code...
r2133 }
else {
Michal Klocek
Refactors axis updateGeometry handling...
r2111 labelItem->setVisible(true);
Michal Klocek
Updates axis drawing code...
r2133 height=labelItem->pos().y();
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
//shades
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if ((i + 1) % 2 && i > 1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
Miikka Heikkinen
Prevent drawing shades off-chart...
r2448 qreal lowerBound = qMin(layout[i - 1], gridRect.bottom());
qreal upperBound = qMax(layout[i], gridRect.top());
rectItem->setRect(gridRect.left(), upperBound, gridRect.width(), lowerBound - upperBound);
if (rectItem->rect().height() <= 0.0)
rectItem->setVisible(false);
else
rectItem->setVisible(true);
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
// check if the grid line and the axis tick should be shown
qreal y = gridItem->line().p1().y();
Michal Klocek
Updates axis drawing code...
r2133 if ((y < gridRect.top() || y > gridRect.bottom()))
{
Michal Klocek
Refactors axis updateGeometry handling...
r2111 gridItem->setVisible(false);
tickItem->setVisible(false);
Michal Klocek
Updates axis drawing code...
r2133 }else{
gridItem->setVisible(true);
tickItem->setVisible(true);
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
}
//begin/end grid line in case labels between
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (intervalAxis()) {
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QGraphicsLineItem *gridLine;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
Michal Klocek
Refactors axis updateGeometry handling...
r2111 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
Michal Klocek
Updates axis drawing code...
r2133 gridLine->setVisible(true);
Miikka Heikkinen
Add Polar chart support...
r2483 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
Michal Klocek
Refactors axis updateGeometry handling...
r2111 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
Michal Klocek
Updates axis drawing code...
r2133 gridLine->setVisible(true);
Michal Klocek
Refactors axis updateGeometry handling...
r2111 }
}
Michal Klocek
Refactors ChartAxis...
r2138 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
Q_UNUSED(constraint);
Miikka Heikkinen
Add Polar chart support...
r2483 QFontMetrics fn(axis()->titleFont());
QSizeF sh(0, 0);
Michal Klocek
Refactors ChartAxis...
r2138
Miikka Heikkinen
Add Polar chart support...
r2483 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
Michal Klocek
Refactors ChartAxis...
r2138 return sh;
switch (which) {
case Qt::MinimumSize:
Miikka Heikkinen
Add padding for axis title...
r2413 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect("...").width());
Michal Klocek
Refactors ChartAxis...
r2138 break;
case Qt::MaximumSize:
case Qt::PreferredSize:
Miikka Heikkinen
Add padding for axis title...
r2413 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect(axis()->titleText()).width());
Michal Klocek
Refactors ChartAxis...
r2138 break;
default:
break;
}
return sh;
}
Michal Klocek
Refactors axis updateGeometry handling...
r2111 QTCOMMERCIALCHART_END_NAMESPACE