##// END OF EJS Templates
Fix QLogValueAxis update...
Titta Heikkala -
r2759:8e20d47d8440
parent child
Show More
@@ -1,240 +1,244
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())
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 *> lines = gridItems();
46 QList<QGraphicsItem *> labels = labelItems();
45 QList<QGraphicsItem *> labels = labelItems();
47 QList<QGraphicsItem *> shades = shadeItems();
48 QList<QGraphicsItem *> arrow = arrowItems();
46 QList<QGraphicsItem *> arrow = arrowItems();
49 QGraphicsTextItem *title = titleItem();
47 QGraphicsTextItem *title = titleItem();
50
48
51 Q_ASSERT(labels.size() == labelList.size());
49 Q_ASSERT(labels.size() == labelList.size());
52 Q_ASSERT(layout.size() == labelList.size());
50 Q_ASSERT(layout.size() == labelList.size());
53
51
54 const QRectF &axisRect = axisGeometry();
52 const QRectF &axisRect = axisGeometry();
55 const QRectF &gridRect = gridGeometry();
53 const QRectF &gridRect = gridGeometry();
56
54
57 //arrow
55 //arrow
58 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(arrow.at(0));
56 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(arrow.at(0));
59
57
60 if (axis()->alignment() == Qt::AlignTop)
58 if (axis()->alignment() == Qt::AlignTop)
61 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
59 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
62 else if (axis()->alignment() == Qt::AlignBottom)
60 else if (axis()->alignment() == Qt::AlignBottom)
63 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
61 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
64
62
65 qreal width = 0;
63 qreal width = 0;
66 const QLatin1String ellipsis("...");
64 const QLatin1String ellipsis("...");
67
65
68 //title
66 //title
69 QRectF titleBoundingRect;
67 QRectF titleBoundingRect;
70 QString titleText = axis()->titleText();
68 QString titleText = axis()->titleText();
71 qreal availableSpace = axisRect.height() - labelPadding();
69 qreal availableSpace = axisRect.height() - labelPadding();
72 if (!titleText.isEmpty() && titleItem()->isVisible()) {
70 if (!titleText.isEmpty() && titleItem()->isVisible()) {
73 availableSpace -= titlePadding() * 2.0;
71 availableSpace -= titlePadding() * 2.0;
74 qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(),
72 qreal minimumLabelHeight = ChartPresenter::textBoundingRect(axis()->labelsFont(),
75 QStringLiteral("...")).height();
73 QStringLiteral("...")).height();
76 qreal titleSpace = availableSpace - minimumLabelHeight;
74 qreal titleSpace = availableSpace - minimumLabelHeight;
77 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
75 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
78 gridRect.width(), titleSpace,
76 gridRect.width(), titleSpace,
79 titleBoundingRect));
77 titleBoundingRect));
80 title->setTextWidth(titleBoundingRect.width());
78 title->setTextWidth(titleBoundingRect.width());
81
79
82 titleBoundingRect = title->boundingRect();
80 titleBoundingRect = title->boundingRect();
83
81
84 QPointF center = gridRect.center() - titleBoundingRect.center();
82 QPointF center = gridRect.center() - titleBoundingRect.center();
85 if (axis()->alignment() == Qt::AlignTop)
83 if (axis()->alignment() == Qt::AlignTop)
86 title->setPos(center.x(), axisRect.top() + titlePadding());
84 title->setPos(center.x(), axisRect.top() + titlePadding());
87 else if (axis()->alignment() == Qt::AlignBottom)
85 else if (axis()->alignment() == Qt::AlignBottom)
88 title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePadding());
86 title->setPos(center.x(), axisRect.bottom() - titleBoundingRect.height() - titlePadding());
89
87
90 availableSpace -= titleBoundingRect.height();
88 availableSpace -= titleBoundingRect.height();
91 }
89 }
92
90
91 if (layout.isEmpty() && axis()->type() == QAbstractAxis::AxisTypeLogValue)
92 return;
93
94 QList<QGraphicsItem *> lines = gridItems();
95 QList<QGraphicsItem *> shades = shadeItems();
96
93 for (int i = 0; i < layout.size(); ++i) {
97 for (int i = 0; i < layout.size(); ++i) {
94 //items
98 //items
95 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
99 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
96 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(arrow.at(i + 1));
100 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(arrow.at(i + 1));
97 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
101 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
98
102
99 //grid line
103 //grid line
100 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
104 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
101
105
102 //label text wrapping
106 //label text wrapping
103 QString text = labelList.at(i);
107 QString text = labelList.at(i);
104 QRectF boundingRect;
108 QRectF boundingRect;
105 // don't truncate empty labels
109 // don't truncate empty labels
106 if (text.isEmpty()) {
110 if (text.isEmpty()) {
107 labelItem->setHtml(text);
111 labelItem->setHtml(text);
108 } else {
112 } else {
109 qreal labelWidth = axisRect.width() / layout.count() - (2 * labelPadding());
113 qreal labelWidth = axisRect.width() / layout.count() - (2 * labelPadding());
110 QString truncatedText = ChartPresenter::truncatedText(axis()->labelsFont(), text,
114 QString truncatedText = ChartPresenter::truncatedText(axis()->labelsFont(), text,
111 axis()->labelsAngle(),
115 axis()->labelsAngle(),
112 labelWidth,
116 labelWidth,
113 availableSpace, boundingRect);
117 availableSpace, boundingRect);
114 labelItem->setTextWidth(ChartPresenter::textBoundingRect(axis()->labelsFont(),
118 labelItem->setTextWidth(ChartPresenter::textBoundingRect(axis()->labelsFont(),
115 truncatedText).width());
119 truncatedText).width());
116 labelItem->setHtml(truncatedText);
120 labelItem->setHtml(truncatedText);
117 }
121 }
118
122
119 //label transformation origin point
123 //label transformation origin point
120 const QRectF& rect = labelItem->boundingRect();
124 const QRectF& rect = labelItem->boundingRect();
121 QPointF center = rect.center();
125 QPointF center = rect.center();
122 labelItem->setTransformOriginPoint(center.x(), center.y());
126 labelItem->setTransformOriginPoint(center.x(), center.y());
123 qreal heightDiff = rect.height() - boundingRect.height();
127 qreal heightDiff = rect.height() - boundingRect.height();
124 qreal widthDiff = rect.width() - boundingRect.width();
128 qreal widthDiff = rect.width() - boundingRect.width();
125
129
126 //ticks and label position
130 //ticks and label position
127 if (axis()->alignment() == Qt::AlignTop) {
131 if (axis()->alignment() == Qt::AlignTop) {
128 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());
129 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
133 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
130 } else if (axis()->alignment() == Qt::AlignBottom) {
134 } else if (axis()->alignment() == Qt::AlignBottom) {
131 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());
132 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
136 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
133 }
137 }
134
138
135 //label in between
139 //label in between
136 bool forceHide = false;
140 bool forceHide = false;
137 if (intervalAxis() && (i + 1) != layout.size()) {
141 if (intervalAxis() && (i + 1) != layout.size()) {
138 qreal leftBound = qMax(layout[i], gridRect.left());
142 qreal leftBound = qMax(layout[i], gridRect.left());
139 qreal rightBound = qMin(layout[i + 1], gridRect.right());
143 qreal rightBound = qMin(layout[i + 1], gridRect.right());
140 const qreal delta = rightBound - leftBound;
144 const qreal delta = rightBound - leftBound;
141 // 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
142 if (delta < boundingRect.width()
146 if (delta < boundingRect.width()
143 && (leftBound == gridRect.left() || rightBound == gridRect.right())
147 && (leftBound == gridRect.left() || rightBound == gridRect.right())
144 && !intervalAxis()) {
148 && !intervalAxis()) {
145 forceHide = true;
149 forceHide = true;
146 } else {
150 } else {
147 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
151 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
148 }
152 }
149 }
153 }
150
154
151 //label overlap detection - compensate one pixel for rounding errors
155 //label overlap detection - compensate one pixel for rounding errors
152 if ((labelItem->pos().x() < width && labelItem->toPlainText() == ellipsis) || forceHide ||
156 if ((labelItem->pos().x() < width && labelItem->toPlainText() == ellipsis) || forceHide ||
153 (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) ||
157 (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) ||
154 (labelItem->pos().x() + (widthDiff / 2.0) - 1.0) > axisRect.right()) {
158 (labelItem->pos().x() + (widthDiff / 2.0) - 1.0) > axisRect.right()) {
155 labelItem->setVisible(false);
159 labelItem->setVisible(false);
156 } else {
160 } else {
157 labelItem->setVisible(true);
161 labelItem->setVisible(true);
158 width = boundingRect.width() + labelItem->pos().x();
162 width = boundingRect.width() + labelItem->pos().x();
159 }
163 }
160
164
161 //shades
165 //shades
162 QGraphicsRectItem *shadeItem = 0;
166 QGraphicsRectItem *shadeItem = 0;
163 if (i == 0)
167 if (i == 0)
164 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(0));
168 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(0));
165 else if (i % 2)
169 else if (i % 2)
166 shadeItem = static_cast<QGraphicsRectItem *>(shades.at((i / 2) + 1));
170 shadeItem = static_cast<QGraphicsRectItem *>(shades.at((i / 2) + 1));
167 if (shadeItem) {
171 if (shadeItem) {
168 qreal leftBound;
172 qreal leftBound;
169 qreal rightBound;
173 qreal rightBound;
170 if (i == 0) {
174 if (i == 0) {
171 leftBound = gridRect.left();
175 leftBound = gridRect.left();
172 rightBound = layout[0];
176 rightBound = layout[0];
173 } else {
177 } else {
174 leftBound = layout[i];
178 leftBound = layout[i];
175 if (i == layout.size() - 1)
179 if (i == layout.size() - 1)
176 rightBound = gridRect.right();
180 rightBound = gridRect.right();
177 else
181 else
178 rightBound = qMin(layout[i + 1], gridRect.right());
182 rightBound = qMin(layout[i + 1], gridRect.right());
179 }
183 }
180 shadeItem->setRect(leftBound, gridRect.top(), rightBound - leftBound,
184 shadeItem->setRect(leftBound, gridRect.top(), rightBound - leftBound,
181 gridRect.height());
185 gridRect.height());
182 if (shadeItem->rect().width() <= 0.0)
186 if (shadeItem->rect().width() <= 0.0)
183 shadeItem->setVisible(false);
187 shadeItem->setVisible(false);
184 else
188 else
185 shadeItem->setVisible(true);
189 shadeItem->setVisible(true);
186 }
190 }
187
191
188 // check if the grid line and the axis tick should be shown
192 // check if the grid line and the axis tick should be shown
189 qreal x = gridItem->line().p1().x();
193 qreal x = gridItem->line().p1().x();
190 if (x < gridRect.left() || x > gridRect.right()) {
194 if (x < gridRect.left() || x > gridRect.right()) {
191 gridItem->setVisible(false);
195 gridItem->setVisible(false);
192 tickItem->setVisible(false);
196 tickItem->setVisible(false);
193 } else {
197 } else {
194 gridItem->setVisible(true);
198 gridItem->setVisible(true);
195 tickItem->setVisible(true);
199 tickItem->setVisible(true);
196 }
200 }
197
201
198 }
202 }
199
203
200 //begin/end grid line in case labels between
204 //begin/end grid line in case labels between
201 if (intervalAxis()) {
205 if (intervalAxis()) {
202 QGraphicsLineItem *gridLine;
206 QGraphicsLineItem *gridLine;
203 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
207 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
204 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
208 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
205 gridLine->setVisible(true);
209 gridLine->setVisible(true);
206 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
210 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
207 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
211 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
208 gridLine->setVisible(true);
212 gridLine->setVisible(true);
209 }
213 }
210 }
214 }
211
215
212 QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
216 QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
213 {
217 {
214 Q_UNUSED(constraint);
218 Q_UNUSED(constraint);
215 QSizeF sh(0,0);
219 QSizeF sh(0,0);
216
220
217 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
221 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
218 return sh;
222 return sh;
219
223
220 switch (which) {
224 switch (which) {
221 case Qt::MinimumSize: {
225 case Qt::MinimumSize: {
222 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(),
226 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(),
223 QStringLiteral("..."));
227 QStringLiteral("..."));
224 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
228 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
225 break;
229 break;
226 }
230 }
227 case Qt::MaximumSize:
231 case Qt::MaximumSize:
228 case Qt::PreferredSize: {
232 case Qt::PreferredSize: {
229 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
233 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
230 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
234 sh = QSizeF(titleRect.width(), titleRect.height() + (titlePadding() * 2.0));
231 break;
235 break;
232 }
236 }
233 default:
237 default:
234 break;
238 break;
235 }
239 }
236
240
237 return sh;
241 return sh;
238 }
242 }
239
243
240 QT_CHARTS_END_NAMESPACE
244 QT_CHARTS_END_NAMESPACE
@@ -1,137 +1,135
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/chartlogvalueaxisx_p.h>
19 #include <private/chartlogvalueaxisx_p.h>
20 #include <private/chartpresenter_p.h>
20 #include <private/chartpresenter_p.h>
21 #include <QtCharts/QLogValueAxis>
21 #include <QtCharts/QLogValueAxis>
22 #include <private/abstractchartlayout_p.h>
22 #include <private/abstractchartlayout_p.h>
23 #include <QtWidgets/QGraphicsLayout>
23 #include <QtWidgets/QGraphicsLayout>
24 #include <QtCore/QtMath>
24 #include <QtCore/QtMath>
25 #include <QtCore/QDebug>
25 #include <QtCore/QDebug>
26
26
27 QT_CHARTS_BEGIN_NAMESPACE
27 QT_CHARTS_BEGIN_NAMESPACE
28
28
29 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem *item)
29 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem *item)
30 : HorizontalAxis(axis, item),
30 : HorizontalAxis(axis, item),
31 m_axis(axis)
31 m_axis(axis)
32 {
32 {
33 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal)));
33 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal)));
34 QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString)));
34 QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString)));
35 }
35 }
36
36
37 ChartLogValueAxisX::~ChartLogValueAxisX()
37 ChartLogValueAxisX::~ChartLogValueAxisX()
38 {
38 {
39 }
39 }
40
40
41 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
41 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
42 {
42 {
43 QVector<qreal> points;
43 QVector<qreal> points;
44
44
45 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
45 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
46 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
46 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
47 qreal leftEdge = logMin < logMax ? logMin : logMax;
47 qreal leftEdge = logMin < logMax ? logMin : logMax;
48 qreal ceilEdge = ceil(leftEdge);
48 qreal ceilEdge = ceil(leftEdge);
49 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
49 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
50
50
51 points.resize(tickCount + 1);
51 points.resize(tickCount);
52 const QRectF &gridRect = gridGeometry();
52 const QRectF &gridRect = gridGeometry();
53 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
53 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
54 for (int i = 0; i <= tickCount; ++i)
54 for (int i = 0; i < tickCount; ++i)
55 points[i] = (ceilEdge + qreal(i)) * deltaX - leftEdge * deltaX + gridRect.left();
55 points[i] = (ceilEdge + qreal(i)) * deltaX - leftEdge * deltaX + gridRect.left();
56
56
57 return points;
57 return points;
58 }
58 }
59
59
60 void ChartLogValueAxisX::updateGeometry()
60 void ChartLogValueAxisX::updateGeometry()
61 {
61 {
62 const QVector<qreal>& layout = ChartAxisElement::layout();
62 const QVector<qreal>& layout = ChartAxisElement::layout();
63 if (layout.isEmpty())
64 return;
65 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
63 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
66 HorizontalAxis::updateGeometry();
64 HorizontalAxis::updateGeometry();
67 }
65 }
68
66
69 void ChartLogValueAxisX::handleBaseChanged(qreal base)
67 void ChartLogValueAxisX::handleBaseChanged(qreal base)
70 {
68 {
71 Q_UNUSED(base);
69 Q_UNUSED(base);
72 QGraphicsLayoutItem::updateGeometry();
70 QGraphicsLayoutItem::updateGeometry();
73 if(presenter()) presenter()->layout()->invalidate();
71 if(presenter()) presenter()->layout()->invalidate();
74 }
72 }
75
73
76 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
74 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
77 {
75 {
78 Q_UNUSED(format);
76 Q_UNUSED(format);
79 QGraphicsLayoutItem::updateGeometry();
77 QGraphicsLayoutItem::updateGeometry();
80 if(presenter()) presenter()->layout()->invalidate();
78 if(presenter()) presenter()->layout()->invalidate();
81 }
79 }
82
80
83 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
81 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
84 {
82 {
85 Q_UNUSED(constraint)
83 Q_UNUSED(constraint)
86
84
87 QSizeF sh;
85 QSizeF sh;
88
86
89 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
87 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
90 QStringList ticksList;
88 QStringList ticksList;
91 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
89 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
92 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
90 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
93 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
91 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
94 if (m_axis->max() > m_axis->min() && tickCount > 0)
92 if (m_axis->max() > m_axis->min() && tickCount > 0)
95 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
93 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
96 else
94 else
97 ticksList.append(QStringLiteral(" "));
95 ticksList.append(QStringLiteral(" "));
98 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
96 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
99 // first and last ticks. Base width is irrelevant.
97 // first and last ticks. Base width is irrelevant.
100 qreal width = 0;
98 qreal width = 0;
101 qreal height = 0;
99 qreal height = 0;
102
100
103 switch (which) {
101 switch (which) {
104 case Qt::MinimumSize:{
102 case Qt::MinimumSize:{
105 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(),
103 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(),
106 QStringLiteral("..."),
104 QStringLiteral("..."),
107 axis()->labelsAngle());
105 axis()->labelsAngle());
108 width = boundingRect.width() / 2.0;
106 width = boundingRect.width() / 2.0;
109 height = boundingRect.height() + labelPadding() + base.height() + 1.0;
107 height = boundingRect.height() + labelPadding() + base.height() + 1.0;
110 sh = QSizeF(width, height);
108 sh = QSizeF(width, height);
111 break;
109 break;
112 }
110 }
113 case Qt::PreferredSize: {
111 case Qt::PreferredSize: {
114 qreal labelHeight = 0.0;
112 qreal labelHeight = 0.0;
115 qreal firstWidth = -1.0;
113 qreal firstWidth = -1.0;
116 foreach (const QString& s, ticksList) {
114 foreach (const QString& s, ticksList) {
117 QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle());
115 QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle());
118 labelHeight = qMax(rect.height(), labelHeight);
116 labelHeight = qMax(rect.height(), labelHeight);
119 width = rect.width();
117 width = rect.width();
120 if (firstWidth < 0.0)
118 if (firstWidth < 0.0)
121 firstWidth = width;
119 firstWidth = width;
122 }
120 }
123 height = labelHeight + labelPadding() + base.height() + 1.0;
121 height = labelHeight + labelPadding() + base.height() + 1.0;
124 width = qMax(width, firstWidth) / 2.0;
122 width = qMax(width, firstWidth) / 2.0;
125 sh = QSizeF(width, height);
123 sh = QSizeF(width, height);
126 break;
124 break;
127 }
125 }
128 default:
126 default:
129 break;
127 break;
130 }
128 }
131
129
132 return sh;
130 return sh;
133 }
131 }
134
132
135 #include "moc_chartlogvalueaxisx_p.cpp"
133 #include "moc_chartlogvalueaxisx_p.cpp"
136
134
137 QT_CHARTS_END_NAMESPACE
135 QT_CHARTS_END_NAMESPACE
@@ -1,137 +1,135
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/chartlogvalueaxisy_p.h>
19 #include <private/chartlogvalueaxisy_p.h>
20 #include <private/chartpresenter_p.h>
20 #include <private/chartpresenter_p.h>
21 #include <QtCharts/QLogValueAxis>
21 #include <QtCharts/QLogValueAxis>
22 #include <private/abstractchartlayout_p.h>
22 #include <private/abstractchartlayout_p.h>
23 #include <QtWidgets/QGraphicsLayout>
23 #include <QtWidgets/QGraphicsLayout>
24 #include <QtCore/QtMath>
24 #include <QtCore/QtMath>
25 #include <QtCore/QDebug>
25 #include <QtCore/QDebug>
26
26
27 QT_CHARTS_BEGIN_NAMESPACE
27 QT_CHARTS_BEGIN_NAMESPACE
28
28
29 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem *item)
29 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem *item)
30 : VerticalAxis(axis, item),
30 : VerticalAxis(axis, item),
31 m_axis(axis)
31 m_axis(axis)
32 {
32 {
33 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal)));
33 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal)));
34 QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString)));
34 QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString)));
35 }
35 }
36
36
37 ChartLogValueAxisY::~ChartLogValueAxisY()
37 ChartLogValueAxisY::~ChartLogValueAxisY()
38 {
38 {
39 }
39 }
40
40
41 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
41 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
42 {
42 {
43 QVector<qreal> points;
43 QVector<qreal> points;
44 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
44 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
45 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
45 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
46 qreal leftEdge = logMin < logMax ? logMin : logMax;
46 qreal leftEdge = logMin < logMax ? logMin : logMax;
47 qreal ceilEdge = ceil(leftEdge);
47 qreal ceilEdge = ceil(leftEdge);
48 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
48 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
49
49
50 points.resize(tickCount + 1);
50 points.resize(tickCount);
51 const QRectF &gridRect = gridGeometry();
51 const QRectF &gridRect = gridGeometry();
52 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
52 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
53 for (int i = 0; i <= tickCount; ++i)
53 for (int i = 0; i < tickCount; ++i)
54 points[i] = (ceilEdge + qreal(i)) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
54 points[i] = (ceilEdge + qreal(i)) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
55
55
56 return points;
56 return points;
57 }
57 }
58
58
59
59
60 void ChartLogValueAxisY::updateGeometry()
60 void ChartLogValueAxisY::updateGeometry()
61 {
61 {
62 const QVector<qreal> &layout = ChartAxisElement::layout();
62 const QVector<qreal> &layout = ChartAxisElement::layout();
63 if (layout.isEmpty())
64 return;
65 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
63 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
66 VerticalAxis::updateGeometry();
64 VerticalAxis::updateGeometry();
67 }
65 }
68
66
69 void ChartLogValueAxisY::handleBaseChanged(qreal base)
67 void ChartLogValueAxisY::handleBaseChanged(qreal base)
70 {
68 {
71 Q_UNUSED(base);
69 Q_UNUSED(base);
72 QGraphicsLayoutItem::updateGeometry();
70 QGraphicsLayoutItem::updateGeometry();
73 if(presenter()) presenter()->layout()->invalidate();
71 if(presenter()) presenter()->layout()->invalidate();
74 }
72 }
75
73
76 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
74 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
77 {
75 {
78 Q_UNUSED(format);
76 Q_UNUSED(format);
79 QGraphicsLayoutItem::updateGeometry();
77 QGraphicsLayoutItem::updateGeometry();
80 if(presenter()) presenter()->layout()->invalidate();
78 if(presenter()) presenter()->layout()->invalidate();
81 }
79 }
82
80
83 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
81 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
84 {
82 {
85 Q_UNUSED(constraint)
83 Q_UNUSED(constraint)
86
84
87 QSizeF sh;
85 QSizeF sh;
88
86
89 QSizeF base = VerticalAxis::sizeHint(which, constraint);
87 QSizeF base = VerticalAxis::sizeHint(which, constraint);
90 QStringList ticksList;
88 QStringList ticksList;
91 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
89 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
92 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
90 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
93 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
91 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
94 if (m_axis->max() > m_axis->min() && tickCount > 0)
92 if (m_axis->max() > m_axis->min() && tickCount > 0)
95 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
93 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
96 else
94 else
97 ticksList.append(QStringLiteral(" "));
95 ticksList.append(QStringLiteral(" "));
98 qreal width = 0;
96 qreal width = 0;
99 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
97 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
100 // first and last ticks. Base height is irrelevant.
98 // first and last ticks. Base height is irrelevant.
101 qreal height = 0;
99 qreal height = 0;
102
100
103 switch (which) {
101 switch (which) {
104 case Qt::MinimumSize: {
102 case Qt::MinimumSize: {
105 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(),
103 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(),
106 QStringLiteral("..."),
104 QStringLiteral("..."),
107 axis()->labelsAngle());
105 axis()->labelsAngle());
108 width = boundingRect.width() + labelPadding() + base.width() + 1.0;
106 width = boundingRect.width() + labelPadding() + base.width() + 1.0;
109 height = boundingRect.height() / 2.0;
107 height = boundingRect.height() / 2.0;
110 sh = QSizeF(width, height);
108 sh = QSizeF(width, height);
111 break;
109 break;
112 }
110 }
113 case Qt::PreferredSize: {
111 case Qt::PreferredSize: {
114 qreal labelWidth = 0.0;
112 qreal labelWidth = 0.0;
115 qreal firstHeight = -1.0;
113 qreal firstHeight = -1.0;
116 foreach (const QString& s, ticksList) {
114 foreach (const QString& s, ticksList) {
117 QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle());
115 QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle());
118 labelWidth = qMax(rect.width(), labelWidth);
116 labelWidth = qMax(rect.width(), labelWidth);
119 height = rect.height();
117 height = rect.height();
120 if (firstHeight < 0.0)
118 if (firstHeight < 0.0)
121 firstHeight = height;
119 firstHeight = height;
122 }
120 }
123 width = labelWidth + labelPadding() + base.width() + 2.0; //two pixels of tolerance
121 width = labelWidth + labelPadding() + base.width() + 2.0; //two pixels of tolerance
124 height = qMax(height, firstHeight) / 2.0;
122 height = qMax(height, firstHeight) / 2.0;
125 sh = QSizeF(width, height);
123 sh = QSizeF(width, height);
126 break;
124 break;
127 }
125 }
128 default:
126 default:
129 break;
127 break;
130 }
128 }
131
129
132 return sh;
130 return sh;
133 }
131 }
134
132
135 #include "moc_chartlogvalueaxisy_p.cpp"
133 #include "moc_chartlogvalueaxisy_p.cpp"
136
134
137 QT_CHARTS_END_NAMESPACE
135 QT_CHARTS_END_NAMESPACE
@@ -1,245 +1,248
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())
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 *> lines = gridItems();
45 QList<QGraphicsItem *> labels = labelItems();
44 QList<QGraphicsItem *> labels = labelItems();
46 QList<QGraphicsItem *> shades = shadeItems();
47 QList<QGraphicsItem *> arrow = arrowItems();
45 QList<QGraphicsItem *> arrow = arrowItems();
48 QGraphicsTextItem *title = titleItem();
46 QGraphicsTextItem *title = titleItem();
49
47
50 Q_ASSERT(labels.size() == labelList.size());
48 Q_ASSERT(labels.size() == labelList.size());
51 Q_ASSERT(layout.size() == labelList.size());
49 Q_ASSERT(layout.size() == labelList.size());
52
50
53 const QRectF &axisRect = axisGeometry();
51 const QRectF &axisRect = axisGeometry();
54 const QRectF &gridRect = gridGeometry();
52 const QRectF &gridRect = gridGeometry();
55
53
56 qreal height = axisRect.bottom();
54 qreal height = axisRect.bottom();
57
55
58
59 //arrow
56 //arrow
60 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
57 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
61
58
62 //arrow position
59 //arrow position
63 if (axis()->alignment() == Qt::AlignLeft)
60 if (axis()->alignment() == Qt::AlignLeft)
64 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
61 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
65 else if (axis()->alignment() == Qt::AlignRight)
62 else if (axis()->alignment() == Qt::AlignRight)
66 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
63 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
67
64
68 //title
65 //title
69 QRectF titleBoundingRect;
66 QRectF titleBoundingRect;
70 QString titleText = axis()->titleText();
67 QString titleText = axis()->titleText();
71 qreal availableSpace = axisRect.width() - labelPadding();
68 qreal availableSpace = axisRect.width() - labelPadding();
72 if (!titleText.isEmpty() && titleItem()->isVisible()) {
69 if (!titleText.isEmpty() && titleItem()->isVisible()) {
73 availableSpace -= titlePadding() * 2.0;
70 availableSpace -= titlePadding() * 2.0;
74 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(),
71 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(),
75 QStringLiteral("...")).width();
72 QStringLiteral("...")).width();
76 qreal titleSpace = availableSpace - minimumLabelWidth;
73 qreal titleSpace = availableSpace - minimumLabelWidth;
77 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(90.0),
74 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(90.0),
78 titleSpace, gridRect.height(),
75 titleSpace, gridRect.height(),
79 titleBoundingRect));
76 titleBoundingRect));
80 title->setTextWidth(titleBoundingRect.height());
77 title->setTextWidth(titleBoundingRect.height());
81
78
82 titleBoundingRect = title->boundingRect();
79 titleBoundingRect = title->boundingRect();
83
80
84 QPointF center = gridRect.center() - titleBoundingRect.center();
81 QPointF center = gridRect.center() - titleBoundingRect.center();
85 if (axis()->alignment() == Qt::AlignLeft)
82 if (axis()->alignment() == Qt::AlignLeft)
86 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());
87 else if (axis()->alignment() == Qt::AlignRight)
84 else if (axis()->alignment() == Qt::AlignRight)
88 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());
89
86
90 title->setTransformOriginPoint(titleBoundingRect.center());
87 title->setTransformOriginPoint(titleBoundingRect.center());
91 title->setRotation(270);
88 title->setRotation(270);
92
89
93 availableSpace -= titleBoundingRect.height();
90 availableSpace -= titleBoundingRect.height();
94 }
91 }
95
92
93 if (layout.isEmpty() && axis()->type() == QAbstractAxis::AxisTypeLogValue)
94 return;
95
96 QList<QGraphicsItem *> lines = gridItems();
97 QList<QGraphicsItem *> shades = shadeItems();
98
96 for (int i = 0; i < layout.size(); ++i) {
99 for (int i = 0; i < layout.size(); ++i) {
97 //items
100 //items
98 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
101 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
99 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
102 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
100 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
103 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
101
104
102 //grid line
105 //grid line
103 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
106 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
104
107
105 //label text wrapping
108 //label text wrapping
106 QString text = labelList.at(i);
109 QString text = labelList.at(i);
107 QRectF boundingRect;
110 QRectF boundingRect;
108 // don't truncate empty labels
111 // don't truncate empty labels
109 if (text.isEmpty()) {
112 if (text.isEmpty()) {
110 labelItem->setHtml(text);
113 labelItem->setHtml(text);
111 } else {
114 } else {
112 qreal labelHeight = (axisRect.height() / layout.count()) - (2 * labelPadding());
115 qreal labelHeight = (axisRect.height() / layout.count()) - (2 * labelPadding());
113 QString truncatedText = ChartPresenter::truncatedText(axis()->labelsFont(), text,
116 QString truncatedText = ChartPresenter::truncatedText(axis()->labelsFont(), text,
114 axis()->labelsAngle(),
117 axis()->labelsAngle(),
115 availableSpace,
118 availableSpace,
116 labelHeight, boundingRect);
119 labelHeight, boundingRect);
117 labelItem->setTextWidth(ChartPresenter::textBoundingRect(axis()->labelsFont(),
120 labelItem->setTextWidth(ChartPresenter::textBoundingRect(axis()->labelsFont(),
118 truncatedText).width());
121 truncatedText).width());
119 labelItem->setHtml(truncatedText);
122 labelItem->setHtml(truncatedText);
120 }
123 }
121
124
122 //label transformation origin point
125 //label transformation origin point
123 const QRectF &rect = labelItem->boundingRect();
126 const QRectF &rect = labelItem->boundingRect();
124 QPointF center = rect.center();
127 QPointF center = rect.center();
125 labelItem->setTransformOriginPoint(center.x(), center.y());
128 labelItem->setTransformOriginPoint(center.x(), center.y());
126 qreal widthDiff = rect.width() - boundingRect.width();
129 qreal widthDiff = rect.width() - boundingRect.width();
127 qreal heightDiff = rect.height() - boundingRect.height();
130 qreal heightDiff = rect.height() - boundingRect.height();
128
131
129 //ticks and label position
132 //ticks and label position
130 if (axis()->alignment() == Qt::AlignLeft) {
133 if (axis()->alignment() == Qt::AlignLeft) {
131 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());
132 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
135 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
133 } else if (axis()->alignment() == Qt::AlignRight) {
136 } else if (axis()->alignment() == Qt::AlignRight) {
134 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());
135 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
138 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
136 }
139 }
137
140
138 //label in between
141 //label in between
139 bool forceHide = false;
142 bool forceHide = false;
140 if (intervalAxis() && (i + 1) != layout.size()) {
143 if (intervalAxis() && (i + 1) != layout.size()) {
141 qreal lowerBound = qMin(layout[i], gridRect.bottom());
144 qreal lowerBound = qMin(layout[i], gridRect.bottom());
142 qreal upperBound = qMax(layout[i + 1], gridRect.top());
145 qreal upperBound = qMax(layout[i + 1], gridRect.top());
143 const qreal delta = lowerBound - upperBound;
146 const qreal delta = lowerBound - upperBound;
144 // 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
145 if (delta < boundingRect.height()
148 if (delta < boundingRect.height()
146 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())
149 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())
147 && !intervalAxis()) {
150 && !intervalAxis()) {
148 forceHide = true;
151 forceHide = true;
149 } else {
152 } else {
150 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
153 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
151 }
154 }
152 }
155 }
153
156
154 //label overlap detection - compensate one pixel for rounding errors
157 //label overlap detection - compensate one pixel for rounding errors
155 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
158 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
156 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
159 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
157 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
160 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
158 labelItem->setVisible(false);
161 labelItem->setVisible(false);
159 }
162 }
160 else {
163 else {
161 labelItem->setVisible(true);
164 labelItem->setVisible(true);
162 height=labelItem->pos().y();
165 height=labelItem->pos().y();
163 }
166 }
164
167
165 //shades
168 //shades
166 QGraphicsRectItem *shadeItem = 0;
169 QGraphicsRectItem *shadeItem = 0;
167 if (i == 0)
170 if (i == 0)
168 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(0));
171 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(0));
169 else if (i % 2)
172 else if (i % 2)
170 shadeItem = static_cast<QGraphicsRectItem *>(shades.at((i / 2) + 1));
173 shadeItem = static_cast<QGraphicsRectItem *>(shades.at((i / 2) + 1));
171 if (shadeItem) {
174 if (shadeItem) {
172 qreal lowerBound;
175 qreal lowerBound;
173 qreal upperBound;
176 qreal upperBound;
174 if (i == 0) {
177 if (i == 0) {
175 lowerBound = gridRect.bottom();
178 lowerBound = gridRect.bottom();
176 upperBound = layout[0];
179 upperBound = layout[0];
177 } else {
180 } else {
178 lowerBound = layout[i];
181 lowerBound = layout[i];
179 if (i == layout.size() - 1)
182 if (i == layout.size() - 1)
180 upperBound = gridRect.top();
183 upperBound = gridRect.top();
181 else
184 else
182 upperBound = qMax(layout[i + 1], gridRect.top());
185 upperBound = qMax(layout[i + 1], gridRect.top());
183
186
184 }
187 }
185 shadeItem->setRect(gridRect.left(), upperBound, gridRect.width(),
188 shadeItem->setRect(gridRect.left(), upperBound, gridRect.width(),
186 lowerBound - upperBound);
189 lowerBound - upperBound);
187 if (shadeItem->rect().height() <= 0.0)
190 if (shadeItem->rect().height() <= 0.0)
188 shadeItem->setVisible(false);
191 shadeItem->setVisible(false);
189 else
192 else
190 shadeItem->setVisible(true);
193 shadeItem->setVisible(true);
191 }
194 }
192
195
193 // check if the grid line and the axis tick should be shown
196 // check if the grid line and the axis tick should be shown
194 qreal y = gridItem->line().p1().y();
197 qreal y = gridItem->line().p1().y();
195 if ((y < gridRect.top() || y > gridRect.bottom()))
198 if ((y < gridRect.top() || y > gridRect.bottom()))
196 {
199 {
197 gridItem->setVisible(false);
200 gridItem->setVisible(false);
198 tickItem->setVisible(false);
201 tickItem->setVisible(false);
199 }else{
202 }else{
200 gridItem->setVisible(true);
203 gridItem->setVisible(true);
201 tickItem->setVisible(true);
204 tickItem->setVisible(true);
202 }
205 }
203
206
204 }
207 }
205 //begin/end grid line in case labels between
208 //begin/end grid line in case labels between
206 if (intervalAxis()) {
209 if (intervalAxis()) {
207 QGraphicsLineItem *gridLine;
210 QGraphicsLineItem *gridLine;
208 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
211 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
209 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
212 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
210 gridLine->setVisible(true);
213 gridLine->setVisible(true);
211 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
214 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
212 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
215 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
213 gridLine->setVisible(true);
216 gridLine->setVisible(true);
214 }
217 }
215 }
218 }
216
219
217 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
220 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
218 {
221 {
219 Q_UNUSED(constraint);
222 Q_UNUSED(constraint);
220 QSizeF sh(0, 0);
223 QSizeF sh(0, 0);
221
224
222 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
225 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
223 return sh;
226 return sh;
224
227
225 switch (which) {
228 switch (which) {
226 case Qt::MinimumSize: {
229 case Qt::MinimumSize: {
227 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(),
230 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(),
228 QStringLiteral("..."));
231 QStringLiteral("..."));
229 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
232 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
230 break;
233 break;
231 }
234 }
232 case Qt::MaximumSize:
235 case Qt::MaximumSize:
233 case Qt::PreferredSize: {
236 case Qt::PreferredSize: {
234 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
237 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
235 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
238 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
236 break;
239 break;
237 }
240 }
238 default:
241 default:
239 break;
242 break;
240 }
243 }
241
244
242 return sh;
245 return sh;
243 }
246 }
244
247
245 QT_CHARTS_END_NAMESPACE
248 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now