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