@@ -73,23 +73,10 void HorizontalAxis::updateGeometry() | |||
|
73 | 73 | if (!titleText.isEmpty() && titleItem()->isVisible()) { |
|
74 | 74 | availableSpace -= titlePadding() * 2.0; |
|
75 | 75 | qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").height(); |
|
76 | QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), | |
|
77 | gridRect.width(), Qt::Horizontal, titleBoundingRect); | |
|
78 | 76 | qreal titleSpace = availableSpace - minimumLabelHeight; |
|
79 | if (titleSpace < titleBoundingRect.height()) { | |
|
80 | // Need to also truncate title vertically (multiline title) | |
|
81 | bool skip = false; | |
|
82 | if (truncatedTitle.endsWith("...")) { | |
|
83 | if (truncatedTitle.size() == 3) | |
|
84 | skip = true; // Already truncated to minimum | |
|
85 | else | |
|
86 | truncatedTitle.chop(3); | |
|
87 | } | |
|
88 | if (!skip) | |
|
89 | truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0), | |
|
90 | titleSpace, Qt::Vertical, titleBoundingRect); | |
|
91 | } | |
|
92 | title->setHtml(truncatedTitle); | |
|
77 | title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), | |
|
78 | gridRect.width(), titleSpace, | |
|
79 | titleBoundingRect)); | |
|
93 | 80 | |
|
94 | 81 | titleBoundingRect = title->boundingRect(); |
|
95 | 82 | |
@@ -114,8 +101,15 void HorizontalAxis::updateGeometry() | |||
|
114 | 101 | //label text wrapping |
|
115 | 102 | QString text = labelList.at(i); |
|
116 | 103 | QRectF boundingRect; |
|
117 | labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(), | |
|
118 | availableSpace, Qt::Vertical, boundingRect)); | |
|
104 | // don't truncate empty labels | |
|
105 | if (text.isEmpty()) { | |
|
106 | labelItem->setHtml(text); | |
|
107 | } else { | |
|
108 | qreal labelWidth = axisRect.width() / layout.count() - (2 * labelPadding()); | |
|
109 | labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, | |
|
110 | axis()->labelsAngle(), labelWidth, | |
|
111 | availableSpace, boundingRect)); | |
|
112 | } | |
|
119 | 113 | |
|
120 | 114 | //label transformation origin point |
|
121 | 115 | const QRectF& rect = labelItem->boundingRect(); |
@@ -141,16 +135,18 void HorizontalAxis::updateGeometry() | |||
|
141 | 135 | const qreal delta = rightBound - leftBound; |
|
142 | 136 | // Hide label in case visible part of the category at the grid edge is too narrow |
|
143 | 137 | if (delta < boundingRect.width() |
|
144 |
&& (leftBound == gridRect.left() || rightBound == gridRect.right()) |
|
|
138 | && (leftBound == gridRect.left() || rightBound == gridRect.right()) | |
|
139 | && !intervalAxis()) { | |
|
145 | 140 | forceHide = true; |
|
146 | 141 | } else { |
|
147 | 142 | labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y()); |
|
148 | 143 | } |
|
149 | 144 | } |
|
150 | 145 | //label overlap detection - compensate one pixel for rounding errors |
|
151 | if (labelItem->pos().x() < width || forceHide || | |
|
146 | if ((labelItem->pos().x() < width || forceHide || | |
|
152 | 147 | (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) || |
|
153 |
(labelItem->pos().x() + (widthDiff / 2.0) - 1.0) > axisRect.right()) |
|
|
148 | (labelItem->pos().x() + (widthDiff / 2.0) - 1.0) > axisRect.right()) | |
|
149 | && !intervalAxis()) { | |
|
154 | 150 | labelItem->setVisible(false); |
|
155 | 151 | } else { |
|
156 | 152 | labelItem->setVisible(true); |
@@ -222,7 +222,12 void PolarChartAxisAngular::updateGeometry() | |||
|
222 | 222 | QString titleText = axis()->titleText(); |
|
223 | 223 | if (!titleText.isEmpty() && axis()->isTitleVisible()) { |
|
224 | 224 | QRectF dummyRect; |
|
225 | title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, dummyRect)); | |
|
225 | qreal availableTitleHeight = axisGeometry().height() - labelPadding() - titlePadding() * 2.0; | |
|
226 | qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").height(); | |
|
227 | availableTitleHeight -= minimumLabelHeight; | |
|
228 | title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), | |
|
229 | axisGeometry().width(), availableTitleHeight, | |
|
230 | dummyRect)); | |
|
226 | 231 | |
|
227 | 232 | QRectF titleBoundingRect = title->boundingRect(); |
|
228 | 233 | QPointF titleCenter = center - titleBoundingRect.center(); |
@@ -205,7 +205,8 void PolarChartAxisRadial::updateGeometry() | |||
|
205 | 205 | QString titleText = axis()->titleText(); |
|
206 | 206 | if (!titleText.isEmpty() && axis()->isTitleVisible()) { |
|
207 | 207 | QRectF dummyRect; |
|
208 |
title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), |
|
|
208 | title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), | |
|
209 | radius, radius, dummyRect)); | |
|
209 | 210 | |
|
210 | 211 | QRectF titleBoundingRect = title->boundingRect(); |
|
211 | 212 | QPointF titleCenter = titleBoundingRect.center(); |
@@ -74,23 +74,10 void VerticalAxis::updateGeometry() | |||
|
74 | 74 | if (!titleText.isEmpty() && titleItem()->isVisible()) { |
|
75 | 75 | availableSpace -= titlePadding() * 2.0; |
|
76 | 76 | qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width(); |
|
77 | QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), | |
|
78 | gridRect.height(), Qt::Horizontal, titleBoundingRect); | |
|
79 | 77 | qreal titleSpace = availableSpace - minimumLabelWidth; |
|
80 | if (titleSpace < titleBoundingRect.height()) { | |
|
81 | // Need to also truncate title vertically (multiline title) | |
|
82 | bool skip = false; | |
|
83 | if (truncatedTitle.endsWith("...")) { | |
|
84 | if (truncatedTitle.size() == 3) | |
|
85 | skip = true; // Already truncated to minimum | |
|
86 | else | |
|
87 | truncatedTitle.chop(3); | |
|
88 | } | |
|
89 | if (!skip) | |
|
90 | truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0), | |
|
91 | titleSpace, Qt::Vertical, titleBoundingRect); | |
|
92 | } | |
|
93 | title->setHtml(truncatedTitle); | |
|
78 | title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(90.0), | |
|
79 | titleSpace, gridRect.height(), | |
|
80 | titleBoundingRect)); | |
|
94 | 81 | |
|
95 | 82 | titleBoundingRect = title->boundingRect(); |
|
96 | 83 | |
@@ -118,8 +105,15 void VerticalAxis::updateGeometry() | |||
|
118 | 105 | //label text wrapping |
|
119 | 106 | QString text = labelList.at(i); |
|
120 | 107 | QRectF boundingRect; |
|
121 | labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(), | |
|
122 | availableSpace, Qt::Horizontal, boundingRect)); | |
|
108 | // don't truncate empty labels | |
|
109 | if (text.isEmpty()) { | |
|
110 | labelItem->setHtml(text); | |
|
111 | } else { | |
|
112 | qreal labelHeight = (axisRect.height() / layout.count()) - (2 * labelPadding()); | |
|
113 | labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, | |
|
114 | axis()->labelsAngle(), availableSpace, | |
|
115 | labelHeight, boundingRect)); | |
|
116 | } | |
|
123 | 117 | |
|
124 | 118 | //label transformation origin point |
|
125 | 119 | const QRectF &rect = labelItem->boundingRect(); |
@@ -145,7 +139,8 void VerticalAxis::updateGeometry() | |||
|
145 | 139 | const qreal delta = lowerBound - upperBound; |
|
146 | 140 | // Hide label in case visible part of the category at the grid edge is too narrow |
|
147 | 141 | if (delta < boundingRect.height() |
|
148 |
&& (lowerBound == gridRect.bottom() || upperBound == gridRect.top()) |
|
|
142 | && (lowerBound == gridRect.bottom() || upperBound == gridRect.top()) | |
|
143 | && !intervalAxis()) { | |
|
149 | 144 | forceHide = true; |
|
150 | 145 | } else { |
|
151 | 146 | labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y()); |
@@ -153,9 +148,10 void VerticalAxis::updateGeometry() | |||
|
153 | 148 | } |
|
154 | 149 | |
|
155 | 150 | //label overlap detection - compensate one pixel for rounding errors |
|
156 | if (labelItem->pos().y() + boundingRect.height() > height || forceHide || | |
|
151 | if ((labelItem->pos().y() + boundingRect.height() > height || forceHide || | |
|
157 | 152 | (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() || |
|
158 |
labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) |
|
|
153 | labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) | |
|
154 | && !intervalAxis()) { | |
|
159 | 155 | labelItem->setVisible(false); |
|
160 | 156 | } |
|
161 | 157 | else { |
@@ -410,14 +410,11 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, | |||
|
410 | 410 | |
|
411 | 411 | // boundingRect parameter returns the rotated bounding rect of the text |
|
412 | 412 | QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle, |
|
413 |
qreal max |
|
|
414 | QRectF &boundingRect) | |
|
413 | qreal maxWidth, qreal maxHeight, QRectF &boundingRect) | |
|
415 | 414 | { |
|
416 | 415 | QString truncatedString(text); |
|
417 | 416 | boundingRect = textBoundingRect(font, truncatedString, angle); |
|
418 | qreal checkDimension = ((constraintOrientation == Qt::Horizontal) | |
|
419 | ? boundingRect.width() : boundingRect.height()); | |
|
420 | if (checkDimension > maxSize) { | |
|
417 | if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) { | |
|
421 | 418 | // It can be assumed that almost any amount of string manipulation is faster |
|
422 | 419 | // than calculating one bounding rectangle, so first prepare a list of truncated strings |
|
423 | 420 | // to try. |
@@ -452,12 +449,11 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qr | |||
|
452 | 449 | int maxIndex(count - 1); |
|
453 | 450 | int bestIndex(count); |
|
454 | 451 | QRectF checkRect; |
|
452 | ||
|
455 | 453 | while (maxIndex >= minIndex) { |
|
456 | 454 | int mid = (maxIndex + minIndex) / 2; |
|
457 | 455 | checkRect = textBoundingRect(font, testStrings.at(mid), angle); |
|
458 | checkDimension = ((constraintOrientation == Qt::Horizontal) | |
|
459 | ? checkRect.width() : checkRect.height()); | |
|
460 | if (checkDimension > maxSize) { | |
|
456 | if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) { | |
|
461 | 457 | // Checked index too large, all under this are also too large |
|
462 | 458 | minIndex = mid + 1; |
|
463 | 459 | } else { |
@@ -145,8 +145,8 public: | |||
|
145 | 145 | QChart *chart() { return m_chart; } |
|
146 | 146 | |
|
147 | 147 | static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0); |
|
148 |
static QString truncatedText(const QFont &font, const QString &text, qreal angle, |
|
|
149 |
|
|
|
148 | static QString truncatedText(const QFont &font, const QString &text, qreal angle, | |
|
149 | qreal maxWidth, qreal maxHeight, QRectF &boundingRect); | |
|
150 | 150 | inline static qreal textMargin() { return qreal(0.5); } |
|
151 | 151 | private: |
|
152 | 152 | void createBackgroundItem(); |
@@ -51,7 +51,9 QString ChartTitle::text() const | |||
|
51 | 51 | void ChartTitle::setGeometry(const QRectF &rect) |
|
52 | 52 | { |
|
53 | 53 | QRectF dummyRect; |
|
54 |
QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), |
|
|
54 | QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), | |
|
55 | rect.width(), rect.height(), | |
|
56 | dummyRect)); | |
|
55 | 57 | setPos(rect.topLeft()); |
|
56 | 58 | } |
|
57 | 59 |
@@ -116,7 +116,8 void LegendMarkerItem::setGeometry(const QRectF &rect) | |||
|
116 | 116 | qreal x = m_margin + m_markerRect.width() + m_space + m_margin; |
|
117 | 117 | QRectF truncatedRect; |
|
118 | 118 | |
|
119 |
m_textItem->setHtml(ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0), |
|
|
119 | m_textItem->setHtml(ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0), | |
|
120 | width - x, rect.height(), truncatedRect)); | |
|
120 | 121 | |
|
121 | 122 | qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin); |
|
122 | 123 |
@@ -94,9 +94,11 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o | |||
|
94 | 94 | painter->setClipRect(parentItem()->boundingRect()); |
|
95 | 95 | painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color()); |
|
96 | 96 | if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) { |
|
97 | // Only one line label text is supported currently. | |
|
98 | // The height for the label is set one pixel over the font metrics. | |
|
97 | 99 | label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText, |
|
98 | 100 | qreal(0.0), m_labelTextRect.width(), |
|
99 |
|
|
|
101 | fm.height() + 1.0, labelBoundingRect); | |
|
100 | 102 | } |
|
101 | 103 | painter->drawText(m_labelTextRect, Qt::AlignCenter, label); |
|
102 | 104 | break; |
General Comments 0
You need to be logged in to leave comments.
Login now