##// END OF EJS Templates
Fix checking for labels out of axis grid....
Miikka Heikkinen -
r2570:ac7068d4fd37
parent child
Show More
@@ -1,223 +1,223
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "horizontalaxis_p.h"
21 #include "horizontalaxis_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include <qmath.h>
24 #include <qmath.h>
25 #include <QDebug>
25 #include <QDebug>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 HorizontalAxis::HorizontalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
29 HorizontalAxis::HorizontalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
30 : CartesianChartAxis(axis, item, intervalAxis)
30 : CartesianChartAxis(axis, item, intervalAxis)
31 {
31 {
32 }
32 }
33
33
34 HorizontalAxis::~HorizontalAxis()
34 HorizontalAxis::~HorizontalAxis()
35 {
35 {
36 }
36 }
37
37
38 void HorizontalAxis::updateGeometry()
38 void HorizontalAxis::updateGeometry()
39 {
39 {
40 const QVector<qreal> &layout = ChartAxisElement::layout();
40 const QVector<qreal> &layout = ChartAxisElement::layout();
41
41
42 if (layout.isEmpty())
42 if (layout.isEmpty())
43 return;
43 return;
44
44
45 QStringList labelList = labels();
45 QStringList labelList = labels();
46
46
47 QList<QGraphicsItem *> lines = gridItems();
47 QList<QGraphicsItem *> lines = gridItems();
48 QList<QGraphicsItem *> labels = labelItems();
48 QList<QGraphicsItem *> labels = labelItems();
49 QList<QGraphicsItem *> shades = shadeItems();
49 QList<QGraphicsItem *> shades = shadeItems();
50 QList<QGraphicsItem *> arrow = arrowItems();
50 QList<QGraphicsItem *> arrow = arrowItems();
51 QGraphicsTextItem *title = titleItem();
51 QGraphicsTextItem *title = titleItem();
52
52
53 Q_ASSERT(labels.size() == labelList.size());
53 Q_ASSERT(labels.size() == labelList.size());
54 Q_ASSERT(layout.size() == labelList.size());
54 Q_ASSERT(layout.size() == labelList.size());
55
55
56 const QRectF &axisRect = axisGeometry();
56 const QRectF &axisRect = axisGeometry();
57 const QRectF &gridRect = gridGeometry();
57 const QRectF &gridRect = gridGeometry();
58
58
59 //arrow
59 //arrow
60 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(arrow.at(0));
60 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(arrow.at(0));
61
61
62 if (axis()->alignment() == Qt::AlignTop)
62 if (axis()->alignment() == Qt::AlignTop)
63 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
63 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
64 else if (axis()->alignment() == Qt::AlignBottom)
64 else if (axis()->alignment() == Qt::AlignBottom)
65 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
65 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
66
66
67 qreal width = 0;
67 qreal width = 0;
68
68
69 //title
69 //title
70 QRectF titleBoundingRect;
70 QRectF titleBoundingRect;
71 QString titleText = axis()->titleText();
71 QString titleText = axis()->titleText();
72 qreal availableSpace = axisRect.height() - labelPadding();
72 qreal availableSpace = axisRect.height() - labelPadding();
73 if (!titleText.isEmpty() && titleItem()->isVisible()) {
73 if (!titleText.isEmpty() && titleItem()->isVisible()) {
74 availableSpace -= titlePadding() * 2.0;
74 availableSpace -= titlePadding() * 2.0;
75 qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").height();
75 qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").height();
76 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
76 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
77 gridRect.width(), Qt::Horizontal, titleBoundingRect);
77 gridRect.width(), Qt::Horizontal, titleBoundingRect);
78 qreal titleSpace = availableSpace - minimumLabelHeight;
78 qreal titleSpace = availableSpace - minimumLabelHeight;
79 if (titleSpace < titleBoundingRect.height()) {
79 if (titleSpace < titleBoundingRect.height()) {
80 // Need to also truncate title vertically (multiline title)
80 // Need to also truncate title vertically (multiline title)
81 bool skip = false;
81 bool skip = false;
82 if (truncatedTitle.endsWith("...")) {
82 if (truncatedTitle.endsWith("...")) {
83 if (truncatedTitle.size() == 3)
83 if (truncatedTitle.size() == 3)
84 skip = true; // Already truncated to minimum
84 skip = true; // Already truncated to minimum
85 else
85 else
86 truncatedTitle.chop(3);
86 truncatedTitle.chop(3);
87 }
87 }
88 if (!skip)
88 if (!skip)
89 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
89 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
90 titleSpace, Qt::Vertical, titleBoundingRect);
90 titleSpace, Qt::Vertical, titleBoundingRect);
91 }
91 }
92 title->setHtml(truncatedTitle);
92 title->setHtml(truncatedTitle);
93
93
94 titleBoundingRect = title->boundingRect();
94 titleBoundingRect = title->boundingRect();
95
95
96 QPointF center = gridRect.center() - titleBoundingRect.center();
96 QPointF center = gridRect.center() - titleBoundingRect.center();
97 if (axis()->alignment() == Qt::AlignTop)
97 if (axis()->alignment() == Qt::AlignTop)
98 title->setPos(center.x(), axisRect.top() + titlePadding());
98 title->setPos(center.x(), axisRect.top() + titlePadding());
99 else if (axis()->alignment() == Qt::AlignBottom)
99 else if (axis()->alignment() == Qt::AlignBottom)
100 title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePadding());
100 title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePadding());
101
101
102 availableSpace -= titleBoundingRect.height();
102 availableSpace -= titleBoundingRect.height();
103 }
103 }
104
104
105 for (int i = 0; i < layout.size(); ++i) {
105 for (int i = 0; i < layout.size(); ++i) {
106 //items
106 //items
107 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
107 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
108 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(arrow.at(i + 1));
108 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(arrow.at(i + 1));
109 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
109 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
110
110
111 //grid line
111 //grid line
112 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
112 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
113
113
114 //label text wrapping
114 //label text wrapping
115 QString text = labelList.at(i);
115 QString text = labelList.at(i);
116 QRectF boundingRect;
116 QRectF boundingRect;
117 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
117 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
118 availableSpace, Qt::Vertical, boundingRect));
118 availableSpace, Qt::Vertical, boundingRect));
119
119
120 //label transformation origin point
120 //label transformation origin point
121 const QRectF& rect = labelItem->boundingRect();
121 const QRectF& rect = labelItem->boundingRect();
122 QPointF center = rect.center();
122 QPointF center = rect.center();
123 labelItem->setTransformOriginPoint(center.x(), center.y());
123 labelItem->setTransformOriginPoint(center.x(), center.y());
124 qreal heightDiff = rect.height() - boundingRect.height();
124 qreal heightDiff = rect.height() - boundingRect.height();
125 qreal widthDiff = rect.width() - boundingRect.width();
125
126
126 //ticks and label position
127 //ticks and label position
127 if (axis()->alignment() == Qt::AlignTop) {
128 if (axis()->alignment() == Qt::AlignTop) {
128 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2.0) - labelPadding());
129 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2.0) - labelPadding());
129 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
130 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
130 } else if (axis()->alignment() == Qt::AlignBottom) {
131 } else if (axis()->alignment() == Qt::AlignBottom) {
131 labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0) + labelPadding());
132 labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0) + labelPadding());
132 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
133 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
133 }
134 }
134
135
135 //label in between
136 //label in between
136 bool forceHide = false;
137 bool forceHide = false;
137 if (intervalAxis() && (i + 1) != layout.size()) {
138 if (intervalAxis() && (i + 1) != layout.size()) {
138 qreal leftBound = qMax(layout[i], gridRect.left());
139 qreal leftBound = qMax(layout[i], gridRect.left());
139 qreal rightBound = qMin(layout[i + 1], gridRect.right());
140 qreal rightBound = qMin(layout[i + 1], gridRect.right());
140 const qreal delta = rightBound - leftBound;
141 const qreal delta = rightBound - leftBound;
141 // Hide label in case visible part of the category at the grid edge is too narrow
142 // Hide label in case visible part of the category at the grid edge is too narrow
142 if (delta < boundingRect.width()
143 if (delta < boundingRect.width()
143 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
144 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
144 forceHide = true;
145 forceHide = true;
145 } else {
146 } else {
146 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
147 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
147 }
148 }
148 }
149 }
149
150 //label overlap detection - compensate one pixel for rounding errors
150 //label overlap detection - compensate one pixel for rounding errors
151 if (labelItem->pos().x() < width || forceHide ||
151 if (labelItem->pos().x() < width || forceHide ||
152 labelItem->pos().x() < (axisRect.left() - 1.0) ||
152 (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) ||
153 (labelItem->pos().x() + boundingRect.width() - 1.0) > axisRect.right()){
153 (labelItem->pos().x() + (widthDiff / 2.0) - 1.0) > axisRect.right()){
154 labelItem->setVisible(false);
154 labelItem->setVisible(false);
155 } else {
155 } else {
156 labelItem->setVisible(true);
156 labelItem->setVisible(true);
157 width = boundingRect.width() + labelItem->pos().x();
157 width = boundingRect.width() + labelItem->pos().x();
158 }
158 }
159
159
160 //shades
160 //shades
161 if ((i + 1) % 2 && i > 1) {
161 if ((i + 1) % 2 && i > 1) {
162 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
162 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
163 qreal leftBound = qMax(layout[i - 1], gridRect.left());
163 qreal leftBound = qMax(layout[i - 1], gridRect.left());
164 qreal rightBound = qMin(layout[i], gridRect.right());
164 qreal rightBound = qMin(layout[i], gridRect.right());
165 rectItem->setRect(leftBound, gridRect.top(), rightBound - leftBound, gridRect.height());
165 rectItem->setRect(leftBound, gridRect.top(), rightBound - leftBound, gridRect.height());
166 if (rectItem->rect().width() <= 0.0)
166 if (rectItem->rect().width() <= 0.0)
167 rectItem->setVisible(false);
167 rectItem->setVisible(false);
168 else
168 else
169 rectItem->setVisible(true);
169 rectItem->setVisible(true);
170 }
170 }
171
171
172 // check if the grid line and the axis tick should be shown
172 // check if the grid line and the axis tick should be shown
173 qreal x = gridItem->line().p1().x();
173 qreal x = gridItem->line().p1().x();
174 if (x < gridRect.left() || x > gridRect.right()) {
174 if (x < gridRect.left() || x > gridRect.right()) {
175 gridItem->setVisible(false);
175 gridItem->setVisible(false);
176 tickItem->setVisible(false);
176 tickItem->setVisible(false);
177 } else {
177 } else {
178 gridItem->setVisible(true);
178 gridItem->setVisible(true);
179 tickItem->setVisible(true);
179 tickItem->setVisible(true);
180 }
180 }
181
181
182 }
182 }
183
183
184 //begin/end grid line in case labels between
184 //begin/end grid line in case labels between
185 if (intervalAxis()) {
185 if (intervalAxis()) {
186 QGraphicsLineItem *gridLine;
186 QGraphicsLineItem *gridLine;
187 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
187 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
188 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
188 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
189 gridLine->setVisible(true);
189 gridLine->setVisible(true);
190 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
190 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
191 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
191 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
192 gridLine->setVisible(true);
192 gridLine->setVisible(true);
193 }
193 }
194 }
194 }
195
195
196 QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
196 QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
197 {
197 {
198 Q_UNUSED(constraint);
198 Q_UNUSED(constraint);
199 QSizeF sh(0,0);
199 QSizeF sh(0,0);
200
200
201 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
201 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
202 return sh;
202 return sh;
203
203
204 switch (which) {
204 switch (which) {
205 case Qt::MinimumSize: {
205 case Qt::MinimumSize: {
206 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
206 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
207 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
207 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
208 break;
208 break;
209 }
209 }
210 case Qt::MaximumSize:
210 case Qt::MaximumSize:
211 case Qt::PreferredSize: {
211 case Qt::PreferredSize: {
212 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
212 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
213 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
213 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
214 break;
214 break;
215 }
215 }
216 default:
216 default:
217 break;
217 break;
218 }
218 }
219
219
220 return sh;
220 return sh;
221 }
221 }
222
222
223 QTCOMMERCIALCHART_END_NAMESPACE
223 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,228 +1,229
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "verticalaxis_p.h"
21 #include "verticalaxis_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include <QDebug>
24 #include <QDebug>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
29 : CartesianChartAxis(axis, item, intervalAxis)
29 : CartesianChartAxis(axis, item, intervalAxis)
30 {
30 {
31 }
31 }
32
32
33 VerticalAxis::~VerticalAxis()
33 VerticalAxis::~VerticalAxis()
34 {
34 {
35 }
35 }
36
36
37 void VerticalAxis::updateGeometry()
37 void VerticalAxis::updateGeometry()
38 {
38 {
39 const QVector<qreal> &layout = ChartAxisElement::layout();
39 const QVector<qreal> &layout = ChartAxisElement::layout();
40
40
41 if (layout.isEmpty())
41 if (layout.isEmpty())
42 return;
42 return;
43
43
44 QStringList labelList = labels();
44 QStringList labelList = labels();
45
45
46 QList<QGraphicsItem *> lines = gridItems();
46 QList<QGraphicsItem *> lines = gridItems();
47 QList<QGraphicsItem *> labels = labelItems();
47 QList<QGraphicsItem *> labels = labelItems();
48 QList<QGraphicsItem *> shades = shadeItems();
48 QList<QGraphicsItem *> shades = shadeItems();
49 QList<QGraphicsItem *> arrow = arrowItems();
49 QList<QGraphicsItem *> arrow = arrowItems();
50 QGraphicsTextItem *title = titleItem();
50 QGraphicsTextItem *title = titleItem();
51
51
52 Q_ASSERT(labels.size() == labelList.size());
52 Q_ASSERT(labels.size() == labelList.size());
53 Q_ASSERT(layout.size() == labelList.size());
53 Q_ASSERT(layout.size() == labelList.size());
54
54
55 const QRectF &axisRect = axisGeometry();
55 const QRectF &axisRect = axisGeometry();
56 const QRectF &gridRect = gridGeometry();
56 const QRectF &gridRect = gridGeometry();
57
57
58 qreal height = axisRect.bottom();
58 qreal height = axisRect.bottom();
59
59
60
60
61 //arrow
61 //arrow
62 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
62 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
63
63
64 //arrow position
64 //arrow position
65 if (axis()->alignment() == Qt::AlignLeft)
65 if (axis()->alignment() == Qt::AlignLeft)
66 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
66 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
67 else if (axis()->alignment() == Qt::AlignRight)
67 else if (axis()->alignment() == Qt::AlignRight)
68 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
68 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
69
69
70 //title
70 //title
71 QRectF titleBoundingRect;
71 QRectF titleBoundingRect;
72 QString titleText = axis()->titleText();
72 QString titleText = axis()->titleText();
73 qreal availableSpace = axisRect.width() - labelPadding();
73 qreal availableSpace = axisRect.width() - labelPadding();
74 if (!titleText.isEmpty() && titleItem()->isVisible()) {
74 if (!titleText.isEmpty() && titleItem()->isVisible()) {
75 availableSpace -= titlePadding() * 2.0;
75 availableSpace -= titlePadding() * 2.0;
76 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width();
76 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width();
77 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
77 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
78 gridRect.height(), Qt::Horizontal, titleBoundingRect);
78 gridRect.height(), Qt::Horizontal, titleBoundingRect);
79 qreal titleSpace = availableSpace - minimumLabelWidth;
79 qreal titleSpace = availableSpace - minimumLabelWidth;
80 if (titleSpace < titleBoundingRect.width()) {
80 if (titleSpace < titleBoundingRect.width()) {
81 // Need to also truncate title vertically (multiline title)
81 // Need to also truncate title vertically (multiline title)
82 bool skip = false;
82 bool skip = false;
83 if (truncatedTitle.endsWith("...")) {
83 if (truncatedTitle.endsWith("...")) {
84 if (truncatedTitle.size() == 3)
84 if (truncatedTitle.size() == 3)
85 skip = true; // Already truncated to minimum
85 skip = true; // Already truncated to minimum
86 else
86 else
87 truncatedTitle.chop(3);
87 truncatedTitle.chop(3);
88 }
88 }
89 if (!skip)
89 if (!skip)
90 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
90 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
91 titleSpace, Qt::Vertical, titleBoundingRect);
91 titleSpace, Qt::Vertical, titleBoundingRect);
92 }
92 }
93 title->setHtml(truncatedTitle);
93 title->setHtml(truncatedTitle);
94
94
95 titleBoundingRect = title->boundingRect();
95 titleBoundingRect = title->boundingRect();
96
96
97 QPointF center = gridRect.center() - titleBoundingRect.center();
97 QPointF center = gridRect.center() - titleBoundingRect.center();
98 if (axis()->alignment() == Qt::AlignLeft)
98 if (axis()->alignment() == Qt::AlignLeft)
99 title->setPos(axisRect.left() - titleBoundingRect.width() / 2.0 + titleBoundingRect.height() / 2.0 + titlePadding(), center.y());
99 title->setPos(axisRect.left() - titleBoundingRect.width() / 2.0 + titleBoundingRect.height() / 2.0 + titlePadding(), center.y());
100 else if (axis()->alignment() == Qt::AlignRight)
100 else if (axis()->alignment() == Qt::AlignRight)
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2.0 - titleBoundingRect.height() / 2.0 - titlePadding(), center.y());
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2.0 - titleBoundingRect.height() / 2.0 - titlePadding(), center.y());
102
102
103 title->setTransformOriginPoint(titleBoundingRect.center());
103 title->setTransformOriginPoint(titleBoundingRect.center());
104 title->setRotation(270);
104 title->setRotation(270);
105
105
106 availableSpace -= titleBoundingRect.height();
106 availableSpace -= titleBoundingRect.height();
107 }
107 }
108
108
109 for (int i = 0; i < layout.size(); ++i) {
109 for (int i = 0; i < layout.size(); ++i) {
110 //items
110 //items
111 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
111 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
112 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
112 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
113 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
113 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
114
114
115 //grid line
115 //grid line
116 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
116 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
117
117
118 //label text wrapping
118 //label text wrapping
119 QString text = labelList.at(i);
119 QString text = labelList.at(i);
120 QRectF boundingRect;
120 QRectF boundingRect;
121 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
121 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
122 availableSpace, Qt::Horizontal, boundingRect));
122 availableSpace, Qt::Horizontal, boundingRect));
123
123
124 //label transformation origin point
124 //label transformation origin point
125 const QRectF &rect = labelItem->boundingRect();
125 const QRectF &rect = labelItem->boundingRect();
126 QPointF center = rect.center();
126 QPointF center = rect.center();
127 labelItem->setTransformOriginPoint(center.x(), center.y());
127 labelItem->setTransformOriginPoint(center.x(), center.y());
128 qreal widthDiff = rect.width() - boundingRect.width();
128 qreal widthDiff = rect.width() - boundingRect.width();
129 qreal heightDiff = rect.height() - boundingRect.height();
129
130
130 //ticks and label position
131 //ticks and label position
131 if (axis()->alignment() == Qt::AlignLeft) {
132 if (axis()->alignment() == Qt::AlignLeft) {
132 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y());
133 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y());
133 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
134 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
134 } else if (axis()->alignment() == Qt::AlignRight) {
135 } else if (axis()->alignment() == Qt::AlignRight) {
135 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y());
136 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y());
136 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
137 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
137 }
138 }
138
139
139 //label in between
140 //label in between
140 bool forceHide = false;
141 bool forceHide = false;
141 if (intervalAxis() && (i + 1) != layout.size()) {
142 if (intervalAxis() && (i + 1) != layout.size()) {
142 qreal lowerBound = qMin(layout[i], gridRect.bottom());
143 qreal lowerBound = qMin(layout[i], gridRect.bottom());
143 qreal upperBound = qMax(layout[i + 1], gridRect.top());
144 qreal upperBound = qMax(layout[i + 1], gridRect.top());
144 const qreal delta = lowerBound - upperBound;
145 const qreal delta = lowerBound - upperBound;
145 // Hide label in case visible part of the category at the grid edge is too narrow
146 // Hide label in case visible part of the category at the grid edge is too narrow
146 if (delta < boundingRect.height()
147 if (delta < boundingRect.height()
147 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
148 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
148 forceHide = true;
149 forceHide = true;
149 } else {
150 } else {
150 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
151 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
151 }
152 }
152 }
153 }
153
154
154 //label overlap detection - compensate one pixel for rounding errors
155 //label overlap detection - compensate one pixel for rounding errors
155 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
156 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
156 (labelItem->pos().y() + (boundingRect.height() / 2.0) - 1.0) > axisRect.bottom() ||
157 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
157 labelItem->pos().y() + (boundingRect.height() / 2.0) < (axisRect.top() - 1.0)) {
158 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
158 labelItem->setVisible(false);
159 labelItem->setVisible(false);
159 }
160 }
160 else {
161 else {
161 labelItem->setVisible(true);
162 labelItem->setVisible(true);
162 height=labelItem->pos().y();
163 height=labelItem->pos().y();
163 }
164 }
164
165
165 //shades
166 //shades
166 if ((i + 1) % 2 && i > 1) {
167 if ((i + 1) % 2 && i > 1) {
167 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
168 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
168 qreal lowerBound = qMin(layout[i - 1], gridRect.bottom());
169 qreal lowerBound = qMin(layout[i - 1], gridRect.bottom());
169 qreal upperBound = qMax(layout[i], gridRect.top());
170 qreal upperBound = qMax(layout[i], gridRect.top());
170 rectItem->setRect(gridRect.left(), upperBound, gridRect.width(), lowerBound - upperBound);
171 rectItem->setRect(gridRect.left(), upperBound, gridRect.width(), lowerBound - upperBound);
171 if (rectItem->rect().height() <= 0.0)
172 if (rectItem->rect().height() <= 0.0)
172 rectItem->setVisible(false);
173 rectItem->setVisible(false);
173 else
174 else
174 rectItem->setVisible(true);
175 rectItem->setVisible(true);
175 }
176 }
176
177
177 // check if the grid line and the axis tick should be shown
178 // check if the grid line and the axis tick should be shown
178 qreal y = gridItem->line().p1().y();
179 qreal y = gridItem->line().p1().y();
179 if ((y < gridRect.top() || y > gridRect.bottom()))
180 if ((y < gridRect.top() || y > gridRect.bottom()))
180 {
181 {
181 gridItem->setVisible(false);
182 gridItem->setVisible(false);
182 tickItem->setVisible(false);
183 tickItem->setVisible(false);
183 }else{
184 }else{
184 gridItem->setVisible(true);
185 gridItem->setVisible(true);
185 tickItem->setVisible(true);
186 tickItem->setVisible(true);
186 }
187 }
187
188
188 }
189 }
189 //begin/end grid line in case labels between
190 //begin/end grid line in case labels between
190 if (intervalAxis()) {
191 if (intervalAxis()) {
191 QGraphicsLineItem *gridLine;
192 QGraphicsLineItem *gridLine;
192 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
193 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
193 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
194 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
194 gridLine->setVisible(true);
195 gridLine->setVisible(true);
195 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
196 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
196 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
197 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
197 gridLine->setVisible(true);
198 gridLine->setVisible(true);
198 }
199 }
199 }
200 }
200
201
201 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
202 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
202 {
203 {
203 Q_UNUSED(constraint);
204 Q_UNUSED(constraint);
204 QSizeF sh(0, 0);
205 QSizeF sh(0, 0);
205
206
206 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
207 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
207 return sh;
208 return sh;
208
209
209 switch (which) {
210 switch (which) {
210 case Qt::MinimumSize: {
211 case Qt::MinimumSize: {
211 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
212 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
212 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
213 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
213 break;
214 break;
214 }
215 }
215 case Qt::MaximumSize:
216 case Qt::MaximumSize:
216 case Qt::PreferredSize: {
217 case Qt::PreferredSize: {
217 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
218 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
218 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
219 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
219 break;
220 break;
220 }
221 }
221 default:
222 default:
222 break;
223 break;
223 }
224 }
224
225
225 return sh;
226 return sh;
226 }
227 }
227
228
228 QTCOMMERCIALCHART_END_NAMESPACE
229 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now