From 18da5db7d538ee00893c67618d6b46548828313f 2013-05-30 07:57:48 From: Miikka Heikkinen Date: 2013-05-30 07:57:48 Subject: [PATCH] Fix multiline axis titles truncation Multiline titles were not truncating in both dimensions. Change-Id: I497f64473fce8de8f0026f0fb0a73b964422ecec Reviewed-by: Tomi Korpipää --- diff --git a/src/axis/chartaxiselement_p.h b/src/axis/chartaxiselement_p.h index 46dac33..f7730c3 100644 --- a/src/axis/chartaxiselement_p.h +++ b/src/axis/chartaxiselement_p.h @@ -59,8 +59,8 @@ public: QAbstractAxis *axis() const { return m_axis; } void setLayout(QVector &layout) { m_layout = layout; } QVector &layout() { return m_layout; } // Modifiable reference - int labelPadding() const { return 5; } - int titlePadding() const { return 3; } + inline qreal labelPadding() const { return qreal(5.0); } + inline qreal titlePadding() const { return qreal(3.0); } void setLabels(const QStringList &labels) { m_labelsList = labels; } QStringList labels() const { return m_labelsList; } diff --git a/src/axis/horizontalaxis.cpp b/src/axis/horizontalaxis.cpp index 2f00150..a185d4a 100644 --- a/src/axis/horizontalaxis.cpp +++ b/src/axis/horizontalaxis.cpp @@ -67,21 +67,39 @@ void HorizontalAxis::updateGeometry() qreal width = 0; //title - int titlePad = 0; QRectF titleBoundingRect; QString titleText = axis()->titleText(); + qreal availableSpace = axisRect.height() - labelPadding(); if (!titleText.isEmpty() && titleItem()->isVisible()) { - title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), gridRect.width(), Qt::Horizontal, QRectF())); + availableSpace -= titlePadding() * 2.0; + qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").height(); + QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), + gridRect.width(), Qt::Horizontal, titleBoundingRect); + qreal titleSpace = availableSpace - minimumLabelHeight; + if (titleSpace < titleBoundingRect.height()) { + // Need to also truncate title vertically (multiline title) + bool skip = false; + if (truncatedTitle.endsWith("...")) { + if (truncatedTitle.size() == 3) + skip = true; // Already truncated to minimum + else + truncatedTitle.chop(3); + } + if (!skip) + truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0), + titleSpace, Qt::Vertical, titleBoundingRect); + } + title->setHtml(truncatedTitle); - titlePad = titlePadding(); titleBoundingRect = title->boundingRect(); QPointF center = gridRect.center() - titleBoundingRect.center(); - if (axis()->alignment() == Qt::AlignTop) { - title->setPos(center.x(), axisRect.top() + titlePad); - } else if (axis()->alignment() == Qt::AlignBottom) { - title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePad); - } + if (axis()->alignment() == Qt::AlignTop) + title->setPos(center.x(), axisRect.top() + titlePadding()); + else if (axis()->alignment() == Qt::AlignBottom) + title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePadding()); + + availableSpace -= titleBoundingRect.height(); } for (int i = 0; i < layout.size(); ++i) { @@ -96,22 +114,21 @@ void HorizontalAxis::updateGeometry() //label text wrapping QString text = labelList.at(i); QRectF boundingRect; - qreal size = axisRect.bottom() - axisRect.top() - labelPadding() - titleBoundingRect.height() - (titlePad * 2); labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(), - size, Qt::Vertical, boundingRect)); + availableSpace, Qt::Vertical, boundingRect)); //label transformation origin point const QRectF& rect = labelItem->boundingRect(); QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); - int heightDiff = rect.height() - boundingRect.height(); + qreal heightDiff = rect.height() - boundingRect.height(); //ticks and label position if (axis()->alignment() == Qt::AlignTop) { - labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2) - labelPadding()); + labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2.0) - labelPadding()); tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding()); } else if (axis()->alignment() == Qt::AlignBottom) { - labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2) + labelPadding()); + labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0) + labelPadding()); tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding()); } @@ -187,13 +204,13 @@ QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) co switch (which) { case Qt::MinimumSize: { QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "..."); - sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2)); + sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0)); break; } case Qt::MaximumSize: case Qt::PreferredSize: { QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText()); - sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2)); + sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0)); break; } default: diff --git a/src/axis/polarchartaxisangular.cpp b/src/axis/polarchartaxisangular.cpp index 23aeede..4e0173f 100644 --- a/src/axis/polarchartaxisangular.cpp +++ b/src/axis/polarchartaxisangular.cpp @@ -223,7 +223,7 @@ void PolarChartAxisAngular::updateGeometry() QRectF titleBoundingRect = title->boundingRect(); QPointF titleCenter = center - titleBoundingRect.center(); - title->setPos(titleCenter.x(), axisGeometry().top() - qreal(titlePadding()) * 2.0 - titleBoundingRect.height() - labelHeight); + title->setPos(titleCenter.x(), axisGeometry().top() - titlePadding() * 2.0 - titleBoundingRect.height() - labelHeight); } } diff --git a/src/axis/polarchartaxisradial.cpp b/src/axis/polarchartaxisradial.cpp index 0a38e06..f28e114 100644 --- a/src/axis/polarchartaxisradial.cpp +++ b/src/axis/polarchartaxisradial.cpp @@ -209,7 +209,7 @@ void PolarChartAxisRadial::updateGeometry() QPointF titleCenter = titleBoundingRect.center(); QPointF arrowCenter = axisLine->boundingRect().center(); QPointF titleCenterDiff = arrowCenter - titleCenter; - title->setPos(titleCenterDiff.x() - qreal(titlePadding()) - (titleBoundingRect.height() / 2.0), titleCenterDiff.y()); + title->setPos(titleCenterDiff.x() - titlePadding() - (titleBoundingRect.height() / 2.0), titleCenterDiff.y()); title->setTransformOriginPoint(titleCenter); title->setRotation(270.0); } diff --git a/src/axis/verticalaxis.cpp b/src/axis/verticalaxis.cpp index 38b2d98..084a0bb 100644 --- a/src/axis/verticalaxis.cpp +++ b/src/axis/verticalaxis.cpp @@ -68,24 +68,42 @@ void VerticalAxis::updateGeometry() arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom()); //title - int titlePad = 0; QRectF titleBoundingRect; QString titleText = axis()->titleText(); + qreal availableSpace = axisRect.width() - labelPadding(); if (!titleText.isEmpty() && titleItem()->isVisible()) { - title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), gridRect.height(), Qt::Horizontal, QRectF())); + availableSpace -= titlePadding() * 2.0; + qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width(); + QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), + gridRect.height(), Qt::Horizontal, titleBoundingRect); + qreal titleSpace = availableSpace - minimumLabelWidth; + if (titleSpace < titleBoundingRect.width()) { + // Need to also truncate title vertically (multiline title) + bool skip = false; + if (truncatedTitle.endsWith("...")) { + if (truncatedTitle.size() == 3) + skip = true; // Already truncated to minimum + else + truncatedTitle.chop(3); + } + if (!skip) + truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0), + titleSpace, Qt::Vertical, titleBoundingRect); + } + title->setHtml(truncatedTitle); - titlePad = titlePadding(); titleBoundingRect = title->boundingRect(); QPointF center = gridRect.center() - titleBoundingRect.center(); - if (axis()->alignment() == Qt::AlignLeft) { - title->setPos(axisRect.left() - titleBoundingRect.width() / 2 + titleBoundingRect.height() / 2 + titlePad, center.y()); - } - else if (axis()->alignment() == Qt::AlignRight) { - title->setPos(axisRect.right() - titleBoundingRect.width() / 2 - titleBoundingRect.height() / 2 - titlePad, center.y()); - } + if (axis()->alignment() == Qt::AlignLeft) + title->setPos(axisRect.left() - titleBoundingRect.width() / 2.0 + titleBoundingRect.height() / 2.0 + titlePadding(), center.y()); + else if (axis()->alignment() == Qt::AlignRight) + title->setPos(axisRect.right() - titleBoundingRect.width() / 2.0 - titleBoundingRect.height() / 2.0 - titlePadding(), center.y()); + title->setTransformOriginPoint(titleBoundingRect.center()); title->setRotation(270); + + availableSpace -= titleBoundingRect.height(); } for (int i = 0; i < layout.size(); ++i) { @@ -100,22 +118,21 @@ void VerticalAxis::updateGeometry() //label text wrapping QString text = labelList.at(i); QRectF boundingRect; - qreal size = axisRect.right() - axisRect.left() - labelPadding() - titleBoundingRect.height() - (titlePad * 2); labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(), - size, Qt::Horizontal, boundingRect)); + availableSpace, Qt::Horizontal, boundingRect)); //label transformation origin point const QRectF &rect = labelItem->boundingRect(); QPointF center = rect.center(); labelItem->setTransformOriginPoint(center.x(), center.y()); - int widthDiff = rect.width() - boundingRect.width(); + qreal widthDiff = rect.width() - boundingRect.width(); //ticks and label position if (axis()->alignment() == Qt::AlignLeft) { - labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y()); + labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y()); tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]); } else if (axis()->alignment() == Qt::AlignRight) { - labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y()); + labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y()); tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]); } @@ -192,13 +209,13 @@ QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) cons switch (which) { case Qt::MinimumSize: { QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "..."); - sh = QSizeF(titleRect.height() + (titlePadding() * 2), titleRect.width()); + sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width()); break; } case Qt::MaximumSize: case Qt::PreferredSize: { QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText()); - sh = QSizeF(titleRect.height() + (titlePadding() * 2), titleRect.width()); + sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width()); break; } default: