##// END OF EJS Templates
Fix int-qreal rounding errors in axislayout calculations...
Miikka Heikkinen -
r2447:ba792163ba0e
parent child
Show More
@@ -1,142 +1,142
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include "chartlayout_p.h"
25 25 #include <QFontMetrics>
26 26 #include <QDebug>
27 27 #include <qmath.h>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, QGraphicsItem* item)
32 32 : HorizontalAxis(axis, item, true),
33 33 m_categoriesAxis(axis)
34 34 {
35 35 QObject::connect(m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
36 36 handleCategoriesChanged();
37 37 }
38 38
39 39 ChartBarCategoryAxisX::~ChartBarCategoryAxisX()
40 40 {
41 41 }
42 42
43 43 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
44 44 {
45 45 QVector<qreal> points;
46 46 const QRectF& gridRect = gridGeometry();
47 47 qreal range = max() - min();
48 48 const qreal delta = gridRect.width() / range;
49 49
50 50 if (delta < 2)
51 51 return points;
52 52
53 53 qreal adjustedMin = min() + 0.5;
54 54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
55 55
56 56 int count = qFloor(range);
57 57 if (count < 1)
58 58 return points;
59 59
60 60 points.resize(count + 2);
61 61
62 62 for (int i = 0; i < count + 2; ++i)
63 points[i] = offset + (i * delta) + gridRect.left();
63 points[i] = offset + (qreal(i) * delta) + gridRect.left();
64 64
65 65 return points;
66 66 }
67 67
68 68 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
69 69 {
70 70 QStringList result ;
71 71 const QRectF &gridRect = gridGeometry();
72 72 qreal d = (max() - min()) / gridRect.width();
73 73
74 74 for (int i = 0; i < layout.count() - 1; ++i) {
75 75 qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5));
76 76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
77 77 result << m_categoriesAxis->categories().at(x);
78 78 } else {
79 79 // No label for x coordinate
80 80 result << "";
81 81 }
82 82 }
83 83 result << "";
84 84 return result;
85 85 }
86 86
87 87
88 88 void ChartBarCategoryAxisX::updateGeometry()
89 89 {
90 90 const QVector<qreal>& layout = ChartAxis::layout();
91 91 if (layout.isEmpty())
92 92 return;
93 93 setLabels(createCategoryLabels(layout));
94 94 HorizontalAxis::updateGeometry();
95 95 }
96 96
97 97 void ChartBarCategoryAxisX::handleCategoriesChanged()
98 98 {
99 99 QGraphicsLayoutItem::updateGeometry();
100 100 if(presenter()) presenter()->layout()->invalidate();
101 101 }
102 102
103 103 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
104 104 {
105 105 Q_UNUSED(constraint)
106 106
107 107 QFontMetrics fn(font());
108 108 QSizeF sh;
109 109 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
110 110 QStringList ticksList = m_categoriesAxis->categories();
111 111
112 112 qreal width = 0; // Width is irrelevant for X axes with interval labels
113 113 qreal height = 0;
114 114
115 115 switch (which) {
116 116 case Qt::MinimumSize: {
117 117 QRectF boundingRect = labelBoundingRect(fn, "...");
118 118 height = boundingRect.height() + labelPadding();
119 119 height += base.height();
120 120 sh = QSizeF(width, height);
121 121 break;
122 122 }
123 123 case Qt::PreferredSize:{
124 124 int labelHeight = 0;
125 125 foreach (const QString& s, ticksList) {
126 126 QRect rect = labelBoundingRect(fn, s);
127 127 labelHeight = qMax(rect.height(), labelHeight);
128 128 }
129 129 height = labelHeight + labelPadding();
130 130 height += base.height();
131 131 sh = QSizeF(width, height);
132 132 break;
133 133 }
134 134 default:
135 135 break;
136 136 }
137 137 return sh;
138 138 }
139 139
140 140 #include "moc_chartbarcategoryaxisx_p.cpp"
141 141
142 142 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,144 +1,144
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include "chartlayout_p.h"
25 25 #include <qmath.h>
26 26 #include <QFontMetrics>
27 27 #include <QDebug>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, QGraphicsItem* item)
32 32 : VerticalAxis(axis, item, true),
33 33 m_categoriesAxis(axis)
34 34 {
35 35 QObject::connect( m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
36 36 handleCategoriesChanged();
37 37 }
38 38
39 39 ChartBarCategoryAxisY::~ChartBarCategoryAxisY()
40 40 {
41 41 }
42 42
43 43 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
44 44 {
45 45 QVector<qreal> points;
46 46 const QRectF& gridRect = gridGeometry();
47 47 qreal range = max() - min();
48 48 const qreal delta = gridRect.height() / range;
49 49
50 50 if (delta < 2)
51 51 return points;
52 52
53 53 qreal adjustedMin = min() + 0.5;
54 54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
55 55
56 56 int count = qFloor(range);
57 57 if (count < 1)
58 58 return points;
59 59
60 60 points.resize(count + 2);
61 61
62 62 for (int i = 0; i < count + 2; ++i)
63 points[i] = gridRect.bottom() - (i * delta) - offset;
63 points[i] = gridRect.bottom() - (qreal(i) * delta) - offset;
64 64
65 65 return points;
66 66 }
67 67
68 68 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
69 69 {
70 70 QStringList result;
71 71 const QRectF &gridRect = gridGeometry();
72 72 qreal d = (max() - min()) / gridRect.height();
73 73
74 74 for (int i = 0; i < layout.count() - 1; ++i) {
75 75 qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5));
76 76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
77 77 result << m_categoriesAxis->categories().at(x);
78 78 } else {
79 79 // No label for x coordinate
80 80 result << "";
81 81 }
82 82 }
83 83 result << "";
84 84 return result;
85 85 }
86 86
87 87 void ChartBarCategoryAxisY::updateGeometry()
88 88 {
89 89 const QVector<qreal>& layout = ChartAxis::layout();
90 90 if (layout.isEmpty())
91 91 return;
92 92 setLabels(createCategoryLabels(layout));
93 93 VerticalAxis::updateGeometry();
94 94 }
95 95
96 96 void ChartBarCategoryAxisY::handleCategoriesChanged()
97 97 {
98 98 QGraphicsLayoutItem::updateGeometry();
99 99 if(presenter()) presenter()->layout()->invalidate();
100 100 }
101 101
102 102 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
103 103 {
104 104 Q_UNUSED(constraint)
105 105
106 106 QFontMetrics fn(font());
107 107 QSizeF sh;
108 108 QSizeF base = VerticalAxis::sizeHint(which, constraint);
109 109 QStringList ticksList = m_categoriesAxis->categories();
110 110 qreal width = 0;
111 111 qreal height = 0; // Height is irrelevant for Y axes with interval labels
112 112
113 113 switch (which) {
114 114 case Qt::MinimumSize: {
115 115 QRectF boundingRect = labelBoundingRect(fn, "...");
116 116 width = boundingRect.width() + labelPadding();
117 117 width += base.width();
118 118 if (base.width() > 0)
119 119 width += labelPadding();
120 120 sh = QSizeF(width, height);
121 121 break;
122 122 }
123 123 case Qt::PreferredSize:{
124 124 int labelWidth = 0;
125 125 foreach (const QString& s, ticksList) {
126 126 QRect rect = labelBoundingRect(fn, s);
127 127 labelWidth = qMax(rect.width(), labelWidth);
128 128 }
129 129 width = labelWidth + labelPadding() + 1;
130 130 width += base.width();
131 131 if (base.width() > 0)
132 132 width += labelPadding();
133 133 sh = QSizeF(width, height);
134 134 break;
135 135 }
136 136 default:
137 137 break;
138 138 }
139 139 return sh;
140 140 }
141 141
142 142 #include "moc_chartbarcategoryaxisy_p.cpp"
143 143
144 144 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,135 +1,133
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdatetimeaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qdatetimeaxis.h"
24 24 #include "chartlayout_p.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QDateTime>
27 27 #include <QFontMetrics>
28 28 #include <qmath.h>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 ChartDateTimeAxisX::ChartDateTimeAxisX(QDateTimeAxis *axis, QGraphicsItem* item)
33 33 : HorizontalAxis(axis, item),
34 34 m_axis(axis)
35 35 {
36 36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
37 37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
38 38 }
39 39
40 40 ChartDateTimeAxisX::~ChartDateTimeAxisX()
41 41 {
42 42 }
43 43
44 44 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
45 45 {
46 46 int tickCount = m_axis->tickCount();
47 47
48 48 Q_ASSERT(tickCount >= 2);
49 49
50 50 QVector<qreal> points;
51 51 points.resize(tickCount);
52 52 const QRectF &gridRect = gridGeometry();
53 const qreal deltaX = gridRect.width() / (tickCount - 1);
54 for (int i = 0; i < tickCount; ++i) {
55 int x = i * deltaX + gridRect.left();
56 points[i] = x;
57 }
53 const qreal deltaX = gridRect.width() / (qreal(tickCount) - 1.0);
54 for (int i = 0; i < tickCount; ++i)
55 points[i] = qreal(i) * deltaX + gridRect.left();
58 56 return points;
59 57 }
60 58
61 59 void ChartDateTimeAxisX::updateGeometry()
62 60 {
63 61 const QVector<qreal>& layout = ChartAxis::layout();
64 62 if (layout.isEmpty())
65 63 return;
66 64 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
67 65 HorizontalAxis::updateGeometry();
68 66 }
69 67
70 68 void ChartDateTimeAxisX::handleTickCountChanged(int tick)
71 69 {
72 70 Q_UNUSED(tick)
73 71 QGraphicsLayoutItem::updateGeometry();
74 72 if(presenter()) presenter()->layout()->invalidate();
75 73 }
76 74
77 75 void ChartDateTimeAxisX::handleFormatChanged(const QString &format)
78 76 {
79 77 Q_UNUSED(format);
80 78 QGraphicsLayoutItem::updateGeometry();
81 79 if(presenter()) presenter()->layout()->invalidate();
82 80 }
83 81
84 82 QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
85 83 {
86 84 Q_UNUSED(constraint)
87 85
88 86 QFontMetrics fn(font());
89 87 QSizeF sh;
90 88
91 89 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
92 90 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
93 91 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
94 92 // first and last ticks. Base width is irrelevant.
95 93 qreal width = 0;
96 94 qreal height = 0;
97 95
98 96 if (ticksList.empty())
99 97 return sh;
100 98
101 99 switch (which) {
102 100 case Qt::MinimumSize:{
103 101 QRectF boundingRect = labelBoundingRect(fn, "...");
104 102 width = boundingRect.width() / 2.0;
105 103 height = boundingRect.height() + labelPadding();
106 104 height += base.height();
107 105 sh = QSizeF(width, height);
108 106 break;
109 107 }
110 108 case Qt::PreferredSize: {
111 109 int labelHeight = 0;
112 110 int firstWidth = -1;
113 111 foreach (const QString& s, ticksList) {
114 112 QRect rect = labelBoundingRect(fn, s);
115 113 labelHeight = qMax(rect.height(), labelHeight);
116 114 width = rect.width();
117 115 if (firstWidth < 0)
118 116 firstWidth = width;
119 117 }
120 118 height = labelHeight + labelPadding();
121 119 height += base.height();
122 120 width = qMax(width, qreal(firstWidth)) / 2.0;
123 121 sh = QSizeF(width, height);
124 122 break;
125 123 }
126 124 default:
127 125 break;
128 126 }
129 127
130 128 return sh;
131 129 }
132 130
133 131 #include "moc_chartdatetimeaxisx_p.cpp"
134 132
135 133 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,136 +1,134
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdatetimeaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qdatetimeaxis.h"
24 24 #include "chartlayout_p.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <QDateTime>
28 28 #include <qmath.h>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 ChartDateTimeAxisY::ChartDateTimeAxisY(QDateTimeAxis *axis, QGraphicsItem* item)
33 33 : VerticalAxis(axis, item),
34 34 m_axis(axis)
35 35 {
36 36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
37 37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
38 38 }
39 39
40 40 ChartDateTimeAxisY::~ChartDateTimeAxisY()
41 41 {
42 42 }
43 43
44 44 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
45 45 {
46 46 int tickCount = m_axis->tickCount();
47 47
48 48 Q_ASSERT(tickCount >= 2);
49 49
50 50 QVector<qreal> points;
51 51 points.resize(tickCount);
52 52 const QRectF &gridRect = gridGeometry();
53 const qreal deltaY = gridRect.height() / (tickCount - 1);
54 for (int i = 0; i < tickCount; ++i) {
55 int y = i * -deltaY + gridRect.bottom();
56 points[i] = y;
57 }
53 const qreal deltaY = gridRect.height() / (qreal(tickCount) - 1.0);
54 for (int i = 0; i < tickCount; ++i)
55 points[i] = qreal(i) * -deltaY + gridRect.bottom();
58 56
59 57 return points;
60 58 }
61 59
62 60 void ChartDateTimeAxisY::updateGeometry()
63 61 {
64 62 const QVector<qreal> &layout = ChartAxis::layout();
65 63 if (layout.isEmpty())
66 64 return;
67 65 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
68 66 VerticalAxis::updateGeometry();
69 67 }
70 68
71 69 void ChartDateTimeAxisY::handleTickCountChanged(int tick)
72 70 {
73 71 Q_UNUSED(tick)
74 72 QGraphicsLayoutItem::updateGeometry();
75 73 if(presenter()) presenter()->layout()->invalidate();
76 74 }
77 75
78 76 void ChartDateTimeAxisY::handleFormatChanged(const QString &format)
79 77 {
80 78 Q_UNUSED(format);
81 79 QGraphicsLayoutItem::updateGeometry();
82 80 if(presenter()) presenter()->layout()->invalidate();
83 81 }
84 82
85 83 QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 84 {
87 85 Q_UNUSED(constraint)
88 86
89 87 QFontMetrics fn(font());
90 88 QSizeF sh;
91 89
92 90 QSizeF base = VerticalAxis::sizeHint(which, constraint);
93 91 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
94 92 qreal width = 0;
95 93 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
96 94 // first and last ticks. Base height is irrelevant.
97 95 qreal height = 0;
98 96
99 97 if (ticksList.empty())
100 98 return sh;
101 99
102 100 switch (which) {
103 101 case Qt::MinimumSize: {
104 102 QRectF boundingRect = labelBoundingRect(fn, "...");
105 103 width = boundingRect.width() + labelPadding();
106 104 width += base.width();
107 105 height = boundingRect.height() / 2.0;
108 106 sh = QSizeF(width, height);
109 107 break;
110 108 }
111 109 case Qt::PreferredSize: {
112 110 int labelWidth = 0;
113 111 int firstHeight = -1;
114 112 foreach (const QString& s, ticksList) {
115 113 QRect rect = labelBoundingRect(fn, s);
116 114 labelWidth = qMax(rect.width(), labelWidth);
117 115 height = rect.height();
118 116 if (firstHeight < 0)
119 117 firstHeight = height;
120 118 }
121 119 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
122 120 width += base.width();
123 121 height = qMax(height, qreal(firstHeight)) / 2.0;
124 122 sh = QSizeF(width, height);
125 123 break;
126 124 }
127 125 default:
128 126 break;
129 127 }
130 128
131 129 return sh;
132 130 }
133 131
134 132 #include "moc_chartdatetimeaxisy_p.cpp"
135 133
136 134 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,133 +1,132
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisx_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "chartlayout_p.h"
26 26 #include <QGraphicsLayout>
27 27 #include <QFontMetrics>
28 28 #include <qmath.h>
29 29 #include <QDebug>
30 30
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 ChartValueAxisX::ChartValueAxisX(QValueAxis *axis, QGraphicsItem* item )
35 35 : HorizontalAxis(axis, item),
36 36 m_axis(axis)
37 37 {
38 38 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
39 39 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
40 40 }
41 41
42 42 ChartValueAxisX::~ChartValueAxisX()
43 43 {
44 44 }
45 45
46 46 QVector<qreal> ChartValueAxisX::calculateLayout() const
47 47 {
48 48 int tickCount = m_axis->tickCount();
49 49
50 50 Q_ASSERT(tickCount >= 2);
51 51
52 52 QVector<qreal> points;
53 53 points.resize(tickCount);
54 54
55 55 const QRectF &gridRect = gridGeometry();
56 const qreal deltaX = gridRect.width() / (tickCount - 1);
57 for (int i = 0; i < tickCount; ++i) {
58 points[i] = i * deltaX + gridRect.left();
59 }
56 const qreal deltaX = gridRect.width() / (qreal(tickCount) - 1.0);
57 for (int i = 0; i < tickCount; ++i)
58 points[i] = qreal(i) * deltaX + gridRect.left();
60 59 return points;
61 60 }
62 61
63 62 void ChartValueAxisX::updateGeometry()
64 63 {
65 64 const QVector<qreal>& layout = ChartAxis::layout();
66 65 if (layout.isEmpty())
67 66 return;
68 67 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
69 68 HorizontalAxis::updateGeometry();
70 69 }
71 70
72 71 void ChartValueAxisX::handleTickCountChanged(int tick)
73 72 {
74 73 Q_UNUSED(tick);
75 74 QGraphicsLayoutItem::updateGeometry();
76 75 if(presenter()) presenter()->layout()->invalidate();
77 76 }
78 77
79 78 void ChartValueAxisX::handleLabelFormatChanged(const QString &format)
80 79 {
81 80 Q_UNUSED(format);
82 81 QGraphicsLayoutItem::updateGeometry();
83 82 if(presenter()) presenter()->layout()->invalidate();
84 83 }
85 84
86 85 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
87 86 {
88 87 Q_UNUSED(constraint)
89 88
90 89 QFontMetrics fn(font());
91 90 QSizeF sh;
92 91
93 92 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
94 93 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
95 94 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
96 95 // first and last ticks. Base width is irrelevant.
97 96 qreal width = 0;
98 97 qreal height = 0;
99 98
100 99 switch (which) {
101 100 case Qt::MinimumSize: {
102 101 QRectF boundingRect = labelBoundingRect(fn, "...");
103 102 width = boundingRect.width() / 2.0;
104 103 height = boundingRect.height() + labelPadding();
105 104 height += base.height();
106 105 sh = QSizeF(width, height);
107 106 break;
108 107 }
109 108 case Qt::PreferredSize: {
110 109 int labelHeight = 0;
111 110 int firstWidth = -1;
112 111 foreach (const QString& s, ticksList) {
113 112 QRect rect = labelBoundingRect(fn, s);
114 113 labelHeight = qMax(rect.height(), labelHeight);
115 114 width = rect.width();
116 115 if (firstWidth < 0)
117 116 firstWidth = width;
118 117 }
119 118 height = labelHeight + labelPadding();
120 119 height += base.height();
121 120 width = qMax(width, qreal(firstWidth)) / 2.0;
122 121 sh = QSizeF(width, height);
123 122 break;
124 123 }
125 124 default:
126 125 break;
127 126 }
128 127 return sh;
129 128 }
130 129
131 130 #include "moc_chartvalueaxisx_p.cpp"
132 131
133 132 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,133 +1,132
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisy_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "chartlayout_p.h"
26 26 #include <QGraphicsLayout>
27 27 #include <QFontMetrics>
28 28 #include <qmath.h>
29 29 #include <QDebug>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartValueAxisY::ChartValueAxisY(QValueAxis *axis, QGraphicsItem* item)
34 34 : VerticalAxis(axis, item),
35 35 m_axis(axis)
36 36 {
37 37 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
38 38 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
39 39 }
40 40
41 41 ChartValueAxisY::~ChartValueAxisY()
42 42 {
43 43 }
44 44
45 45 QVector<qreal> ChartValueAxisY::calculateLayout() const
46 46 {
47 47 int tickCount = m_axis->tickCount();
48 48
49 49 Q_ASSERT(tickCount >= 2);
50 50
51 51 QVector<qreal> points;
52 52 points.resize(tickCount);
53 53
54 54 const QRectF &gridRect = gridGeometry();
55 55
56 const qreal deltaY = gridRect.height() / (tickCount - 1);
57 for (int i = 0; i < tickCount; ++i) {
58 points[i] = i * -deltaY + gridRect.bottom();
59 }
56 const qreal deltaY = gridRect.height() / (qreal(tickCount) - 1.0);
57 for (int i = 0; i < tickCount; ++i)
58 points[i] = qreal(i) * -deltaY + gridRect.bottom();
60 59
61 60 return points;
62 61 }
63 62
64 63 void ChartValueAxisY::updateGeometry()
65 64 {
66 65 const QVector<qreal> &layout = ChartAxis::layout();
67 66 if (layout.isEmpty())
68 67 return;
69 68 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
70 69 VerticalAxis::updateGeometry();
71 70 }
72 71
73 72 void ChartValueAxisY::handleTickCountChanged(int tick)
74 73 {
75 74 Q_UNUSED(tick);
76 75 QGraphicsLayoutItem::updateGeometry();
77 76 if(presenter()) presenter()->layout()->invalidate();
78 77 }
79 78
80 79 void ChartValueAxisY::handleLabelFormatChanged(const QString &format)
81 80 {
82 81 Q_UNUSED(format);
83 82 QGraphicsLayoutItem::updateGeometry();
84 83 if(presenter()) presenter()->layout()->invalidate();
85 84 }
86 85
87 86 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
88 87 {
89 88 Q_UNUSED(constraint)
90 89
91 90 QFontMetrics fn(font());
92 91 QSizeF sh;
93 92 QSizeF base = VerticalAxis::sizeHint(which, constraint);
94 93 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
95 94 qreal width = 0;
96 95 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
97 96 // first and last ticks. Base height is irrelevant.
98 97 qreal height = 0;
99 98
100 99 switch (which) {
101 100 case Qt::MinimumSize: {
102 101 QRectF boundingRect = labelBoundingRect(fn, "...");
103 102 width = boundingRect.width() + labelPadding();
104 103 width += base.width();
105 104 height = boundingRect.height() / 2.0;
106 105 sh = QSizeF(width, height);
107 106 break;
108 107 }
109 108 case Qt::PreferredSize: {
110 109 int labelWidth = 0;
111 110 int firstHeight = -1;
112 111 foreach (const QString& s, ticksList) {
113 112 QRect rect = labelBoundingRect(fn, s);
114 113 labelWidth = qMax(rect.width(), labelWidth);
115 114 height = rect.height();
116 115 if (firstHeight < 0)
117 116 firstHeight = height;
118 117 }
119 118 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
120 119 width += base.width();
121 120 height = qMax(height, qreal(firstHeight)) / 2.0;
122 121 sh = QSizeF(width, height);
123 122 break;
124 123 }
125 124 default:
126 125 break;
127 126 }
128 127 return sh;
129 128 }
130 129
131 130 #include "moc_chartvalueaxisy_p.cpp"
132 131
133 132 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now