##// END OF EJS Templates
Fix vanishing labels for first and last ticks....
Miikka Heikkinen -
r2443:5b27b7b1d72a RC2_1.2.1
parent child
Show More
@@ -1,145 +1,142
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartbarcategoryaxisx_p.h"
21 #include "chartbarcategoryaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoryaxis_p.h"
23 #include "qbarcategoryaxis_p.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QFontMetrics>
25 #include <QFontMetrics>
26 #include <QDebug>
26 #include <QDebug>
27 #include <qmath.h>
27 #include <qmath.h>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, QGraphicsItem* item)
31 ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, QGraphicsItem* item)
32 : HorizontalAxis(axis, item, true),
32 : HorizontalAxis(axis, item, true),
33 m_categoriesAxis(axis)
33 m_categoriesAxis(axis)
34 {
34 {
35 QObject::connect(m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
35 QObject::connect(m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
36 handleCategoriesChanged();
36 handleCategoriesChanged();
37 }
37 }
38
38
39 ChartBarCategoryAxisX::~ChartBarCategoryAxisX()
39 ChartBarCategoryAxisX::~ChartBarCategoryAxisX()
40 {
40 {
41 }
41 }
42
42
43 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
43 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
44 {
44 {
45 QVector<qreal> points;
45 QVector<qreal> points;
46 const QRectF& gridRect = gridGeometry();
46 const QRectF& gridRect = gridGeometry();
47 qreal range = max() - min();
47 qreal range = max() - min();
48 const qreal delta = gridRect.width() / range;
48 const qreal delta = gridRect.width() / range;
49
49
50 if (delta < 2)
50 if (delta < 2)
51 return points;
51 return points;
52
52
53 qreal adjustedMin = min() + 0.5;
53 qreal adjustedMin = min() + 0.5;
54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
55
55
56 int count = qFloor(range);
56 int count = qFloor(range);
57 if (count < 1)
57 if (count < 1)
58 return points;
58 return points;
59
59
60 points.resize(count + 2);
60 points.resize(count + 2);
61
61
62 for (int i = 0; i < count + 2; ++i)
62 for (int i = 0; i < count + 2; ++i)
63 points[i] = offset + (i * delta) + gridRect.left();
63 points[i] = offset + (i * delta) + gridRect.left();
64
64
65 return points;
65 return points;
66 }
66 }
67
67
68 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
68 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
69 {
69 {
70 QStringList result ;
70 QStringList result ;
71 const QRectF &gridRect = gridGeometry();
71 const QRectF &gridRect = gridGeometry();
72 qreal d = (max() - min()) / gridRect.width();
72 qreal d = (max() - min()) / gridRect.width();
73
73
74 for (int i = 0; i < layout.count() - 1; ++i) {
74 for (int i = 0; i < layout.count() - 1; ++i) {
75 qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5));
75 qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5));
76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
77 result << m_categoriesAxis->categories().at(x);
77 result << m_categoriesAxis->categories().at(x);
78 } else {
78 } else {
79 // No label for x coordinate
79 // No label for x coordinate
80 result << "";
80 result << "";
81 }
81 }
82 }
82 }
83 result << "";
83 result << "";
84 return result;
84 return result;
85 }
85 }
86
86
87
87
88 void ChartBarCategoryAxisX::updateGeometry()
88 void ChartBarCategoryAxisX::updateGeometry()
89 {
89 {
90 const QVector<qreal>& layout = ChartAxis::layout();
90 const QVector<qreal>& layout = ChartAxis::layout();
91 if (layout.isEmpty())
91 if (layout.isEmpty())
92 return;
92 return;
93 setLabels(createCategoryLabels(layout));
93 setLabels(createCategoryLabels(layout));
94 HorizontalAxis::updateGeometry();
94 HorizontalAxis::updateGeometry();
95 }
95 }
96
96
97 void ChartBarCategoryAxisX::handleCategoriesChanged()
97 void ChartBarCategoryAxisX::handleCategoriesChanged()
98 {
98 {
99 QGraphicsLayoutItem::updateGeometry();
99 QGraphicsLayoutItem::updateGeometry();
100 if(presenter()) presenter()->layout()->invalidate();
100 if(presenter()) presenter()->layout()->invalidate();
101 }
101 }
102
102
103 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
103 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
104 {
104 {
105 Q_UNUSED(constraint)
105 Q_UNUSED(constraint)
106
106
107 QFontMetrics fn(font());
107 QFontMetrics fn(font());
108 QSizeF sh;
108 QSizeF sh;
109 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
109 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
110 QStringList ticksList = m_categoriesAxis->categories();
110 QStringList ticksList = m_categoriesAxis->categories();
111
111
112 qreal width=0;
112 qreal width = 0; // Width is irrelevant for X axes with interval labels
113 qreal height=0;
113 qreal height = 0;
114
114
115 switch (which) {
115 switch (which) {
116 case Qt::MinimumSize: {
116 case Qt::MinimumSize: {
117 QRectF boundingRect = labelBoundingRect(fn, "...");
117 QRectF boundingRect = labelBoundingRect(fn, "...");
118 width = qMax(boundingRect.width(), base.width());
119 height = boundingRect.height() + labelPadding();
118 height = boundingRect.height() + labelPadding();
120 height += base.height();
119 height += base.height();
121 sh = QSizeF(width, height);
120 sh = QSizeF(width, height);
122 break;
121 break;
123 }
122 }
124 case Qt::PreferredSize:{
123 case Qt::PreferredSize:{
125 int labelHeight = 0;
124 int labelHeight = 0;
126 foreach (const QString& s, ticksList) {
125 foreach (const QString& s, ticksList) {
127 QRect rect = labelBoundingRect(fn, s);
126 QRect rect = labelBoundingRect(fn, s);
128 labelHeight = qMax(rect.height(), labelHeight);
127 labelHeight = qMax(rect.height(), labelHeight);
129 width += rect.width();
130 }
128 }
131 height = labelHeight + labelPadding();
129 height = labelHeight + labelPadding();
132 height += base.height();
130 height += base.height();
133 width = qMax(width, base.width());
134 sh = QSizeF(width, height);
131 sh = QSizeF(width, height);
135 break;
132 break;
136 }
133 }
137 default:
134 default:
138 break;
135 break;
139 }
136 }
140 return sh;
137 return sh;
141 }
138 }
142
139
143 #include "moc_chartbarcategoryaxisx_p.cpp"
140 #include "moc_chartbarcategoryaxisx_p.cpp"
144
141
145 QTCOMMERCIALCHART_END_NAMESPACE
142 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,147 +1,144
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartbarcategoryaxisy_p.h"
21 #include "chartbarcategoryaxisy_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoryaxis_p.h"
23 #include "qbarcategoryaxis_p.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <qmath.h>
25 #include <qmath.h>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <QDebug>
27 #include <QDebug>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, QGraphicsItem* item)
31 ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, QGraphicsItem* item)
32 : VerticalAxis(axis, item, true),
32 : VerticalAxis(axis, item, true),
33 m_categoriesAxis(axis)
33 m_categoriesAxis(axis)
34 {
34 {
35 QObject::connect( m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
35 QObject::connect( m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged()));
36 handleCategoriesChanged();
36 handleCategoriesChanged();
37 }
37 }
38
38
39 ChartBarCategoryAxisY::~ChartBarCategoryAxisY()
39 ChartBarCategoryAxisY::~ChartBarCategoryAxisY()
40 {
40 {
41 }
41 }
42
42
43 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
43 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
44 {
44 {
45 QVector<qreal> points;
45 QVector<qreal> points;
46 const QRectF& gridRect = gridGeometry();
46 const QRectF& gridRect = gridGeometry();
47 qreal range = max() - min();
47 qreal range = max() - min();
48 const qreal delta = gridRect.height() / range;
48 const qreal delta = gridRect.height() / range;
49
49
50 if (delta < 2)
50 if (delta < 2)
51 return points;
51 return points;
52
52
53 qreal adjustedMin = min() + 0.5;
53 qreal adjustedMin = min() + 0.5;
54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
54 qreal offset = (ceil(adjustedMin) - adjustedMin) * delta;
55
55
56 int count = qFloor(range);
56 int count = qFloor(range);
57 if (count < 1)
57 if (count < 1)
58 return points;
58 return points;
59
59
60 points.resize(count + 2);
60 points.resize(count + 2);
61
61
62 for (int i = 0; i < count + 2; ++i)
62 for (int i = 0; i < count + 2; ++i)
63 points[i] = gridRect.bottom() - (i * delta) - offset;
63 points[i] = gridRect.bottom() - (i * delta) - offset;
64
64
65 return points;
65 return points;
66 }
66 }
67
67
68 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
68 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
69 {
69 {
70 QStringList result;
70 QStringList result;
71 const QRectF &gridRect = gridGeometry();
71 const QRectF &gridRect = gridGeometry();
72 qreal d = (max() - min()) / gridRect.height();
72 qreal d = (max() - min()) / gridRect.height();
73
73
74 for (int i = 0; i < layout.count() - 1; ++i) {
74 for (int i = 0; i < layout.count() - 1; ++i) {
75 qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5));
75 qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5));
76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
77 result << m_categoriesAxis->categories().at(x);
77 result << m_categoriesAxis->categories().at(x);
78 } else {
78 } else {
79 // No label for x coordinate
79 // No label for x coordinate
80 result << "";
80 result << "";
81 }
81 }
82 }
82 }
83 result << "";
83 result << "";
84 return result;
84 return result;
85 }
85 }
86
86
87 void ChartBarCategoryAxisY::updateGeometry()
87 void ChartBarCategoryAxisY::updateGeometry()
88 {
88 {
89 const QVector<qreal>& layout = ChartAxis::layout();
89 const QVector<qreal>& layout = ChartAxis::layout();
90 if (layout.isEmpty())
90 if (layout.isEmpty())
91 return;
91 return;
92 setLabels(createCategoryLabels(layout));
92 setLabels(createCategoryLabels(layout));
93 VerticalAxis::updateGeometry();
93 VerticalAxis::updateGeometry();
94 }
94 }
95
95
96 void ChartBarCategoryAxisY::handleCategoriesChanged()
96 void ChartBarCategoryAxisY::handleCategoriesChanged()
97 {
97 {
98 QGraphicsLayoutItem::updateGeometry();
98 QGraphicsLayoutItem::updateGeometry();
99 if(presenter()) presenter()->layout()->invalidate();
99 if(presenter()) presenter()->layout()->invalidate();
100 }
100 }
101
101
102 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
102 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
103 {
103 {
104 Q_UNUSED(constraint)
104 Q_UNUSED(constraint)
105
105
106 QFontMetrics fn(font());
106 QFontMetrics fn(font());
107 QSizeF sh;
107 QSizeF sh;
108 QSizeF base = VerticalAxis::sizeHint(which, constraint);
108 QSizeF base = VerticalAxis::sizeHint(which, constraint);
109 QStringList ticksList = m_categoriesAxis->categories();
109 QStringList ticksList = m_categoriesAxis->categories();
110 qreal width=0;
110 qreal width = 0;
111 qreal height=0;
111 qreal height = 0; // Height is irrelevant for Y axes with interval labels
112
112
113 switch (which) {
113 switch (which) {
114 case Qt::MinimumSize: {
114 case Qt::MinimumSize: {
115 QRectF boundingRect = labelBoundingRect(fn, "...");
115 QRectF boundingRect = labelBoundingRect(fn, "...");
116 width = boundingRect.width() + labelPadding();
116 width = boundingRect.width() + labelPadding();
117 width += base.width();
117 width += base.width();
118 if (base.width() > 0)
118 if (base.width() > 0)
119 width += labelPadding();
119 width += labelPadding();
120 height = qMax(boundingRect.height(), base.height());
121 sh = QSizeF(width, height);
120 sh = QSizeF(width, height);
122 break;
121 break;
123 }
122 }
124 case Qt::PreferredSize:{
123 case Qt::PreferredSize:{
125 int labelWidth = 0;
124 int labelWidth = 0;
126 foreach (const QString& s, ticksList) {
125 foreach (const QString& s, ticksList) {
127 QRect rect = labelBoundingRect(fn, s);
126 QRect rect = labelBoundingRect(fn, s);
128 labelWidth = qMax(rect.width(), labelWidth);
127 labelWidth = qMax(rect.width(), labelWidth);
129 height += rect.height();
130 }
128 }
131 width = labelWidth + labelPadding() + 1;
129 width = labelWidth + labelPadding() + 1;
132 width += base.width();
130 width += base.width();
133 if (base.width() > 0)
131 if (base.width() > 0)
134 width += labelPadding();
132 width += labelPadding();
135 height = qMax(height, base.height());
136 sh = QSizeF(width, height);
133 sh = QSizeF(width, height);
137 break;
134 break;
138 }
135 }
139 default:
136 default:
140 break;
137 break;
141 }
138 }
142 return sh;
139 return sh;
143 }
140 }
144
141
145 #include "moc_chartbarcategoryaxisy_p.cpp"
142 #include "moc_chartbarcategoryaxisy_p.cpp"
146
143
147 QTCOMMERCIALCHART_END_NAMESPACE
144 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,119 +1,116
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartcategoryaxisx_p.h"
21 #include "chartcategoryaxisx_p.h"
22 #include "qcategoryaxis.h"
22 #include "qcategoryaxis.h"
23 #include "qabstractaxis.h"
23 #include "qabstractaxis.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 ChartCategoryAxisX::ChartCategoryAxisX(QCategoryAxis *axis, QGraphicsItem* item)
31 ChartCategoryAxisX::ChartCategoryAxisX(QCategoryAxis *axis, QGraphicsItem* item)
32 : HorizontalAxis(axis, item, true),
32 : HorizontalAxis(axis, item, true),
33 m_axis(axis)
33 m_axis(axis)
34 {
34 {
35 }
35 }
36
36
37 ChartCategoryAxisX::~ChartCategoryAxisX()
37 ChartCategoryAxisX::~ChartCategoryAxisX()
38 {
38 {
39 }
39 }
40
40
41 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
41 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
42 {
42 {
43 int tickCount = m_axis->categoriesLabels().count() + 1;
43 int tickCount = m_axis->categoriesLabels().count() + 1;
44 QVector<qreal> points;
44 QVector<qreal> points;
45
45
46 if (tickCount < 2)
46 if (tickCount < 2)
47 return points;
47 return points;
48
48
49 const QRectF &gridRect = gridGeometry();
49 const QRectF &gridRect = gridGeometry();
50 qreal range = max() - min();
50 qreal range = max() - min();
51 if (range > 0) {
51 if (range > 0) {
52 points.resize(tickCount);
52 points.resize(tickCount);
53 qreal scale = gridRect.width() / range;
53 qreal scale = gridRect.width() / range;
54 for (int i = 0; i < tickCount; ++i) {
54 for (int i = 0; i < tickCount; ++i) {
55 if (i < tickCount - 1) {
55 if (i < tickCount - 1) {
56 qreal x = (m_axis->startValue(m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.left();
56 qreal x = (m_axis->startValue(m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.left();
57 points[i] = x;
57 points[i] = x;
58 } else {
58 } else {
59 qreal x = (m_axis->endValue(m_axis->categoriesLabels().at(i - 1)) - min()) * scale + gridRect.left();
59 qreal x = (m_axis->endValue(m_axis->categoriesLabels().at(i - 1)) - min()) * scale + gridRect.left();
60 points[i] = x;
60 points[i] = x;
61 }
61 }
62 }
62 }
63 }
63 }
64
64
65 return points;
65 return points;
66 }
66 }
67
67
68 void ChartCategoryAxisX::updateGeometry()
68 void ChartCategoryAxisX::updateGeometry()
69 {
69 {
70 setLabels(m_axis->categoriesLabels() << "");
70 setLabels(m_axis->categoriesLabels() << "");
71 HorizontalAxis::updateGeometry();
71 HorizontalAxis::updateGeometry();
72 }
72 }
73
73
74 void ChartCategoryAxisX::handleAxisUpdated()
74 void ChartCategoryAxisX::handleAxisUpdated()
75 {
75 {
76 updateGeometry();
76 updateGeometry();
77 }
77 }
78
78
79 QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
79 QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
80 {
80 {
81 Q_UNUSED(constraint)
81 Q_UNUSED(constraint)
82
82
83 QFontMetrics fn(font());
83 QFontMetrics fn(font());
84 QSizeF sh;
84 QSizeF sh;
85 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
85 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
86 QStringList ticksList = m_axis->categoriesLabels();
86 QStringList ticksList = m_axis->categoriesLabels();
87 qreal width = 0;
87 qreal width = 0; // Width is irrelevant for X axes with interval labels
88 qreal height = 0;
88 qreal height = 0;
89
89
90 switch (which) {
90 switch (which) {
91 case Qt::MinimumSize: {
91 case Qt::MinimumSize: {
92 QRectF boundingRect = labelBoundingRect(fn, "...");
92 QRectF boundingRect = labelBoundingRect(fn, "...");
93 width = qMax(boundingRect.width(), base.width());
94 height = boundingRect.height() + labelPadding();
93 height = boundingRect.height() + labelPadding();
95 height += base.height();
94 height += base.height();
96 sh = QSizeF(width, height);
95 sh = QSizeF(width, height);
97 break;
96 break;
98 }
97 }
99 case Qt::PreferredSize: {
98 case Qt::PreferredSize: {
100 int labelHeight = 0;
99 int labelHeight = 0;
101 foreach (const QString& s, ticksList) {
100 foreach (const QString& s, ticksList) {
102 QRect rect = labelBoundingRect(fn, s);
101 QRect rect = labelBoundingRect(fn, s);
103 labelHeight = qMax(rect.height(), labelHeight);
102 labelHeight = qMax(rect.height(), labelHeight);
104 width += rect.width();
105 }
103 }
106 height = labelHeight + labelPadding();
104 height = labelHeight + labelPadding();
107 height += base.height();
105 height += base.height();
108 width = qMax(width, base.width());
109 sh = QSizeF(width, height);
106 sh = QSizeF(width, height);
110 break;
107 break;
111 }
108 }
112 default:
109 default:
113 break;
110 break;
114 }
111 }
115
112
116 return sh;
113 return sh;
117 }
114 }
118
115
119 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,119 +1,116
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartcategoryaxisy_p.h"
21 #include "chartcategoryaxisy_p.h"
22 #include "qcategoryaxis.h"
22 #include "qcategoryaxis.h"
23 #include "qabstractaxis.h"
23 #include "qabstractaxis.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartCategoryAxisY::ChartCategoryAxisY(QCategoryAxis *axis, QGraphicsItem* item)
32 ChartCategoryAxisY::ChartCategoryAxisY(QCategoryAxis *axis, QGraphicsItem* item)
33 : VerticalAxis(axis, item, true),
33 : VerticalAxis(axis, item, true),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 }
36 }
37
37
38 ChartCategoryAxisY::~ChartCategoryAxisY()
38 ChartCategoryAxisY::~ChartCategoryAxisY()
39 {
39 {
40 }
40 }
41
41
42 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
42 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
43 {
43 {
44 int tickCount = m_axis->categoriesLabels().count() + 1;
44 int tickCount = m_axis->categoriesLabels().count() + 1;
45 QVector<qreal> points;
45 QVector<qreal> points;
46
46
47 if (tickCount < 2)
47 if (tickCount < 2)
48 return points;
48 return points;
49
49
50 const QRectF &gridRect = gridGeometry();
50 const QRectF &gridRect = gridGeometry();
51 qreal range = max() - min();
51 qreal range = max() - min();
52 if (range > 0) {
52 if (range > 0) {
53 points.resize(tickCount);
53 points.resize(tickCount);
54 qreal scale = gridRect.height() / range;
54 qreal scale = gridRect.height() / range;
55 for (int i = 0; i < tickCount; ++i) {
55 for (int i = 0; i < tickCount; ++i) {
56 if (i < tickCount - 1) {
56 if (i < tickCount - 1) {
57 qreal y = -(m_axis->startValue(m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.bottom();
57 qreal y = -(m_axis->startValue(m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.bottom();
58 points[i] = y;
58 points[i] = y;
59 } else {
59 } else {
60 qreal y = -(m_axis->endValue(m_axis->categoriesLabels().at(i - 1)) - min()) * scale + gridRect.bottom();
60 qreal y = -(m_axis->endValue(m_axis->categoriesLabels().at(i - 1)) - min()) * scale + gridRect.bottom();
61 points[i] = y;
61 points[i] = y;
62 }
62 }
63 }
63 }
64 }
64 }
65
65
66 return points;
66 return points;
67 }
67 }
68
68
69 void ChartCategoryAxisY::updateGeometry()
69 void ChartCategoryAxisY::updateGeometry()
70 {
70 {
71 setLabels(m_axis->categoriesLabels() << "");
71 setLabels(m_axis->categoriesLabels() << "");
72 VerticalAxis::updateGeometry();
72 VerticalAxis::updateGeometry();
73 }
73 }
74
74
75 void ChartCategoryAxisY::handleAxisUpdated()
75 void ChartCategoryAxisY::handleAxisUpdated()
76 {
76 {
77 updateGeometry();
77 updateGeometry();
78 }
78 }
79
79
80 QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
80 QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
81 {
81 {
82 Q_UNUSED(constraint)
82 Q_UNUSED(constraint)
83
83
84 QFontMetrics fn(font());
84 QFontMetrics fn(font());
85 QSizeF sh;
85 QSizeF sh;
86 QSizeF base = VerticalAxis::sizeHint(which, constraint);
86 QSizeF base = VerticalAxis::sizeHint(which, constraint);
87 QStringList ticksList = m_axis->categoriesLabels();
87 QStringList ticksList = m_axis->categoriesLabels();
88 qreal width = 0;
88 qreal width = 0;
89 qreal height = 0;
89 qreal height = 0; // Height is irrelevant for Y axes with interval labels
90
90
91 switch (which) {
91 switch (which) {
92 case Qt::MinimumSize: {
92 case Qt::MinimumSize: {
93 QRectF boundingRect = labelBoundingRect(fn, "...");
93 QRectF boundingRect = labelBoundingRect(fn, "...");
94 width = boundingRect.width() + labelPadding();
94 width = boundingRect.width() + labelPadding();
95 width += base.width();
95 width += base.width();
96 height = qMax(boundingRect.height(), base.height());
97 sh = QSizeF(width, height);
96 sh = QSizeF(width, height);
98 break;
97 break;
99 }
98 }
100 case Qt::PreferredSize: {
99 case Qt::PreferredSize: {
101 int labelWidth = 0;
100 int labelWidth = 0;
102 foreach (const QString& s, ticksList) {
101 foreach (const QString& s, ticksList) {
103 QRect rect = labelBoundingRect(fn, s);
102 QRect rect = labelBoundingRect(fn, s);
104 labelWidth = qMax(rect.width(), labelWidth);
103 labelWidth = qMax(rect.width(), labelWidth);
105 height += rect.height();
106 }
104 }
107 width = labelWidth + labelPadding() + 1;
105 width = labelWidth + labelPadding() + 1;
108 width += base.width();
106 width += base.width();
109 height = qMax(height, base.height());
110 sh = QSizeF(width, height);
107 sh = QSizeF(width, height);
111 break;
108 break;
112 }
109 }
113 default:
110 default:
114 break;
111 break;
115 }
112 }
116 return sh;
113 return sh;
117 }
114 }
118
115
119 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,131 +1,135
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartdatetimeaxisx_p.h"
21 #include "chartdatetimeaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qdatetimeaxis.h"
23 #include "qdatetimeaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QDateTime>
26 #include <QDateTime>
27 #include <QFontMetrics>
27 #include <QFontMetrics>
28 #include <qmath.h>
28 #include <qmath.h>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartDateTimeAxisX::ChartDateTimeAxisX(QDateTimeAxis *axis, QGraphicsItem* item)
32 ChartDateTimeAxisX::ChartDateTimeAxisX(QDateTimeAxis *axis, QGraphicsItem* item)
33 : HorizontalAxis(axis, item),
33 : HorizontalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
38 }
38 }
39
39
40 ChartDateTimeAxisX::~ChartDateTimeAxisX()
40 ChartDateTimeAxisX::~ChartDateTimeAxisX()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
44 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
45 {
45 {
46 int tickCount = m_axis->tickCount();
46 int tickCount = m_axis->tickCount();
47
47
48 Q_ASSERT(tickCount >= 2);
48 Q_ASSERT(tickCount >= 2);
49
49
50 QVector<qreal> points;
50 QVector<qreal> points;
51 points.resize(tickCount);
51 points.resize(tickCount);
52 const QRectF &gridRect = gridGeometry();
52 const QRectF &gridRect = gridGeometry();
53 const qreal deltaX = gridRect.width() / (tickCount - 1);
53 const qreal deltaX = gridRect.width() / (tickCount - 1);
54 for (int i = 0; i < tickCount; ++i) {
54 for (int i = 0; i < tickCount; ++i) {
55 int x = i * deltaX + gridRect.left();
55 int x = i * deltaX + gridRect.left();
56 points[i] = x;
56 points[i] = x;
57 }
57 }
58 return points;
58 return points;
59 }
59 }
60
60
61 void ChartDateTimeAxisX::updateGeometry()
61 void ChartDateTimeAxisX::updateGeometry()
62 {
62 {
63 const QVector<qreal>& layout = ChartAxis::layout();
63 const QVector<qreal>& layout = ChartAxis::layout();
64 if (layout.isEmpty())
64 if (layout.isEmpty())
65 return;
65 return;
66 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
66 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
67 HorizontalAxis::updateGeometry();
67 HorizontalAxis::updateGeometry();
68 }
68 }
69
69
70 void ChartDateTimeAxisX::handleTickCountChanged(int tick)
70 void ChartDateTimeAxisX::handleTickCountChanged(int tick)
71 {
71 {
72 Q_UNUSED(tick)
72 Q_UNUSED(tick)
73 QGraphicsLayoutItem::updateGeometry();
73 QGraphicsLayoutItem::updateGeometry();
74 if(presenter()) presenter()->layout()->invalidate();
74 if(presenter()) presenter()->layout()->invalidate();
75 }
75 }
76
76
77 void ChartDateTimeAxisX::handleFormatChanged(const QString &format)
77 void ChartDateTimeAxisX::handleFormatChanged(const QString &format)
78 {
78 {
79 Q_UNUSED(format);
79 Q_UNUSED(format);
80 QGraphicsLayoutItem::updateGeometry();
80 QGraphicsLayoutItem::updateGeometry();
81 if(presenter()) presenter()->layout()->invalidate();
81 if(presenter()) presenter()->layout()->invalidate();
82 }
82 }
83
83
84 QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
84 QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
85 {
85 {
86 Q_UNUSED(constraint)
86 Q_UNUSED(constraint)
87
87
88 QFontMetrics fn(font());
88 QFontMetrics fn(font());
89 QSizeF sh;
89 QSizeF sh;
90
90
91 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
91 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
92 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
92 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
93 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
94 // first and last ticks. Base width is irrelevant.
93 qreal width = 0;
95 qreal width = 0;
94 qreal height = 0;
96 qreal height = 0;
95
97
96 if(ticksList.empty()){
98 if (ticksList.empty())
97 return sh;
99 return sh;
98 }
99
100
100 switch (which) {
101 switch (which) {
101 case Qt::MinimumSize:{
102 case Qt::MinimumSize:{
102 QRectF boundingRect = labelBoundingRect(fn, "...");
103 QRectF boundingRect = labelBoundingRect(fn, "...");
103 width = qMax(boundingRect.width(), base.width());
104 width = boundingRect.width() / 2.0;
104 height = boundingRect.height() + labelPadding();
105 height = boundingRect.height() + labelPadding();
105 height += base.height();
106 height += base.height();
106 sh = QSizeF(width, height);
107 sh = QSizeF(width, height);
107 break;
108 break;
108 }
109 }
109 case Qt::PreferredSize: {
110 case Qt::PreferredSize: {
110 int labelHeight = 0;
111 int labelHeight = 0;
112 int firstWidth = -1;
111 foreach (const QString& s, ticksList) {
113 foreach (const QString& s, ticksList) {
112 QRect rect = labelBoundingRect(fn, s);
114 QRect rect = labelBoundingRect(fn, s);
113 labelHeight = qMax(rect.height(), labelHeight);
115 labelHeight = qMax(rect.height(), labelHeight);
114 width += rect.width();
116 width = rect.width();
117 if (firstWidth < 0)
118 firstWidth = width;
115 }
119 }
116 height = labelHeight + labelPadding();
120 height = labelHeight + labelPadding();
117 height += base.height();
121 height += base.height();
118 width = qMax(width, base.width());
122 width = qMax(width, qreal(firstWidth)) / 2.0;
119 sh = QSizeF(width, height);
123 sh = QSizeF(width, height);
120 break;
124 break;
121 }
125 }
122 default:
126 default:
123 break;
127 break;
124 }
128 }
125
129
126 return sh;
130 return sh;
127 }
131 }
128
132
129 #include "moc_chartdatetimeaxisx_p.cpp"
133 #include "moc_chartdatetimeaxisx_p.cpp"
130
134
131 QTCOMMERCIALCHART_END_NAMESPACE
135 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,133 +1,136
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartdatetimeaxisy_p.h"
21 #include "chartdatetimeaxisy_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qdatetimeaxis.h"
23 #include "qdatetimeaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <QDateTime>
27 #include <QDateTime>
28 #include <qmath.h>
28 #include <qmath.h>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartDateTimeAxisY::ChartDateTimeAxisY(QDateTimeAxis *axis, QGraphicsItem* item)
32 ChartDateTimeAxisY::ChartDateTimeAxisY(QDateTimeAxis *axis, QGraphicsItem* item)
33 : VerticalAxis(axis, item),
33 : VerticalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
36 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(formatChanged(QString)),this, SLOT(handleFormatChanged(QString)));
38 }
38 }
39
39
40 ChartDateTimeAxisY::~ChartDateTimeAxisY()
40 ChartDateTimeAxisY::~ChartDateTimeAxisY()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
44 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
45 {
45 {
46 int tickCount = m_axis->tickCount();
46 int tickCount = m_axis->tickCount();
47
47
48 Q_ASSERT(tickCount >= 2);
48 Q_ASSERT(tickCount >= 2);
49
49
50 QVector<qreal> points;
50 QVector<qreal> points;
51 points.resize(tickCount);
51 points.resize(tickCount);
52 const QRectF &gridRect = gridGeometry();
52 const QRectF &gridRect = gridGeometry();
53 const qreal deltaY = gridRect.height() / (tickCount - 1);
53 const qreal deltaY = gridRect.height() / (tickCount - 1);
54 for (int i = 0; i < tickCount; ++i) {
54 for (int i = 0; i < tickCount; ++i) {
55 int y = i * -deltaY + gridRect.bottom();
55 int y = i * -deltaY + gridRect.bottom();
56 points[i] = y;
56 points[i] = y;
57 }
57 }
58
58
59 return points;
59 return points;
60 }
60 }
61
61
62 void ChartDateTimeAxisY::updateGeometry()
62 void ChartDateTimeAxisY::updateGeometry()
63 {
63 {
64 const QVector<qreal> &layout = ChartAxis::layout();
64 const QVector<qreal> &layout = ChartAxis::layout();
65 if (layout.isEmpty())
65 if (layout.isEmpty())
66 return;
66 return;
67 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
67 setLabels(createDateTimeLabels(min(),max(), layout.size(),m_axis->format()));
68 VerticalAxis::updateGeometry();
68 VerticalAxis::updateGeometry();
69 }
69 }
70
70
71 void ChartDateTimeAxisY::handleTickCountChanged(int tick)
71 void ChartDateTimeAxisY::handleTickCountChanged(int tick)
72 {
72 {
73 Q_UNUSED(tick)
73 Q_UNUSED(tick)
74 QGraphicsLayoutItem::updateGeometry();
74 QGraphicsLayoutItem::updateGeometry();
75 if(presenter()) presenter()->layout()->invalidate();
75 if(presenter()) presenter()->layout()->invalidate();
76 }
76 }
77
77
78 void ChartDateTimeAxisY::handleFormatChanged(const QString &format)
78 void ChartDateTimeAxisY::handleFormatChanged(const QString &format)
79 {
79 {
80 Q_UNUSED(format);
80 Q_UNUSED(format);
81 QGraphicsLayoutItem::updateGeometry();
81 QGraphicsLayoutItem::updateGeometry();
82 if(presenter()) presenter()->layout()->invalidate();
82 if(presenter()) presenter()->layout()->invalidate();
83 }
83 }
84
84
85 QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
85 QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 {
86 {
87 Q_UNUSED(constraint)
87 Q_UNUSED(constraint)
88
88
89 QFontMetrics fn(font());
89 QFontMetrics fn(font());
90 QSizeF sh;
90 QSizeF sh;
91
91
92 QSizeF base = VerticalAxis::sizeHint(which, constraint);
92 QSizeF base = VerticalAxis::sizeHint(which, constraint);
93 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
93 QStringList ticksList = createDateTimeLabels(min(),max(),m_axis->tickCount(),m_axis->format());
94 qreal width = 0;
94 qreal width = 0;
95 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
96 // first and last ticks. Base height is irrelevant.
95 qreal height = 0;
97 qreal height = 0;
96
98
97
99 if (ticksList.empty())
98 if(ticksList.empty()){
99 return sh;
100 return sh;
100 }
101
101
102 switch (which) {
102 switch (which) {
103 case Qt::MinimumSize: {
103 case Qt::MinimumSize: {
104 QRectF boundingRect = labelBoundingRect(fn, "...");
104 QRectF boundingRect = labelBoundingRect(fn, "...");
105 width = boundingRect.width() + labelPadding();
105 width = boundingRect.width() + labelPadding();
106 width += base.width();
106 width += base.width();
107 height = qMax(boundingRect.height(), base.height());
107 height = boundingRect.height() / 2.0;
108 sh = QSizeF(width, height);
108 sh = QSizeF(width, height);
109 break;
109 break;
110 }
110 }
111 case Qt::PreferredSize: {
111 case Qt::PreferredSize: {
112 int labelWidth = 0;
112 int labelWidth = 0;
113 int firstHeight = -1;
113 foreach (const QString& s, ticksList) {
114 foreach (const QString& s, ticksList) {
114 QRect rect = labelBoundingRect(fn, s);
115 QRect rect = labelBoundingRect(fn, s);
115 labelWidth = qMax(rect.width(), labelWidth);
116 labelWidth = qMax(rect.width(), labelWidth);
116 height += rect.height();
117 height = rect.height();
118 if (firstHeight < 0)
119 firstHeight = height;
117 }
120 }
118 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
121 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
119 width += base.width();
122 width += base.width();
120 height = qMax(height, base.height());
123 height = qMax(height, qreal(firstHeight)) / 2.0;
121 sh = QSizeF(width, height);
124 sh = QSizeF(width, height);
122 break;
125 break;
123 }
126 }
124 default:
127 default:
125 break;
128 break;
126 }
129 }
127
130
128 return sh;
131 return sh;
129 }
132 }
130
133
131 #include "moc_chartdatetimeaxisy_p.cpp"
134 #include "moc_chartdatetimeaxisy_p.cpp"
132
135
133 QTCOMMERCIALCHART_END_NAMESPACE
136 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,137 +1,141
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartlogvalueaxisx_p.h"
21 #include "chartlogvalueaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem* item)
32 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem* item)
33 : HorizontalAxis(axis, item),
33 : HorizontalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis,SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
36 QObject::connect(m_axis,SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
38 }
38 }
39
39
40 ChartLogValueAxisX::~ChartLogValueAxisX()
40 ChartLogValueAxisX::~ChartLogValueAxisX()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
44 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
45 {
45 {
46 QVector<qreal> points;
46 QVector<qreal> points;
47
47
48 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
48 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
49 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
49 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
50 qreal leftEdge = logMin < logMax ? logMin : logMax;
50 qreal leftEdge = logMin < logMax ? logMin : logMax;
51 qreal ceilEdge = ceil(leftEdge);
51 qreal ceilEdge = ceil(leftEdge);
52 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
52 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
53
53
54 points.resize(tickCount);
54 points.resize(tickCount);
55 const QRectF &gridRect = gridGeometry();
55 const QRectF &gridRect = gridGeometry();
56 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
56 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
57 for (int i = 0; i < tickCount; ++i)
57 for (int i = 0; i < tickCount; ++i)
58 points[i] = (ceilEdge + i) * deltaX - leftEdge * deltaX + gridRect.left();
58 points[i] = (ceilEdge + i) * deltaX - leftEdge * deltaX + gridRect.left();
59
59
60 return points;
60 return points;
61 }
61 }
62
62
63 void ChartLogValueAxisX::updateGeometry()
63 void ChartLogValueAxisX::updateGeometry()
64 {
64 {
65 const QVector<qreal>& layout = ChartAxis::layout();
65 const QVector<qreal>& layout = ChartAxis::layout();
66 if (layout.isEmpty())
66 if (layout.isEmpty())
67 return;
67 return;
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
69 HorizontalAxis::updateGeometry();
69 HorizontalAxis::updateGeometry();
70 }
70 }
71
71
72 void ChartLogValueAxisX::handleBaseChanged(qreal base)
72 void ChartLogValueAxisX::handleBaseChanged(qreal base)
73 {
73 {
74 Q_UNUSED(base);
74 Q_UNUSED(base);
75 QGraphicsLayoutItem::updateGeometry();
75 QGraphicsLayoutItem::updateGeometry();
76 if(presenter()) presenter()->layout()->invalidate();
76 if(presenter()) presenter()->layout()->invalidate();
77 }
77 }
78
78
79 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
79 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
80 {
80 {
81 Q_UNUSED(format);
81 Q_UNUSED(format);
82 QGraphicsLayoutItem::updateGeometry();
82 QGraphicsLayoutItem::updateGeometry();
83 if(presenter()) presenter()->layout()->invalidate();
83 if(presenter()) presenter()->layout()->invalidate();
84 }
84 }
85
85
86 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
87 {
87 {
88 Q_UNUSED(constraint)
88 Q_UNUSED(constraint)
89
89
90 QFontMetrics fn(font());
90 QFontMetrics fn(font());
91 QSizeF sh;
91 QSizeF sh;
92
92
93 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
93 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
94 QStringList ticksList;
94 QStringList ticksList;
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
100 else
100 else
101 ticksList.append(QString(" "));
101 ticksList.append(QString(" "));
102 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
103 // first and last ticks. Base width is irrelevant.
102 qreal width = 0;
104 qreal width = 0;
103 qreal height = 0;
105 qreal height = 0;
104
106
105
106 switch (which) {
107 switch (which) {
107 case Qt::MinimumSize:{
108 case Qt::MinimumSize:{
108 QRectF boundingRect = labelBoundingRect(fn, "...");
109 QRectF boundingRect = labelBoundingRect(fn, "...");
109 width = qMax(boundingRect.width(), base.width());
110 width = boundingRect.width() / 2.0;
110 height = boundingRect.height() + labelPadding();
111 height = boundingRect.height() + labelPadding();
111 height += base.height();
112 height += base.height();
112 sh = QSizeF(width, height);
113 sh = QSizeF(width, height);
113 break;
114 break;
114 }
115 }
115 case Qt::PreferredSize: {
116 case Qt::PreferredSize: {
116 int labelHeight = 0;
117 int labelHeight = 0;
118 int firstWidth = -1;
117 foreach (const QString& s, ticksList) {
119 foreach (const QString& s, ticksList) {
118 QRect rect = labelBoundingRect(fn, s);
120 QRect rect = labelBoundingRect(fn, s);
119 labelHeight = qMax(rect.height(), labelHeight);
121 labelHeight = qMax(rect.height(), labelHeight);
120 width += rect.width();
122 width = rect.width();
123 if (firstWidth < 0)
124 firstWidth = width;
121 }
125 }
122 height = labelHeight + labelPadding();
126 height = labelHeight + labelPadding();
123 height += base.height();
127 height += base.height();
124 width = qMax(width, base.width());
128 width = qMax(width, qreal(firstWidth)) / 2.0;
125 sh = QSizeF(width, height);
129 sh = QSizeF(width, height);
126 break;
130 break;
127 }
131 }
128 default:
132 default:
129 break;
133 break;
130 }
134 }
131
135
132 return sh;
136 return sh;
133 }
137 }
134
138
135 #include "moc_chartlogvalueaxisx_p.cpp"
139 #include "moc_chartlogvalueaxisx_p.cpp"
136
140
137 QTCOMMERCIALCHART_END_NAMESPACE
141 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,136 +1,141
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartlogvalueaxisy_p.h"
21 #include "chartlogvalueaxisy_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem* item)
32 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem* item)
33 : VerticalAxis(axis, item),
33 : VerticalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
36 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
38 }
38 }
39
39
40 ChartLogValueAxisY::~ChartLogValueAxisY()
40 ChartLogValueAxisY::~ChartLogValueAxisY()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
44 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
45 {
45 {
46 QVector<qreal> points;
46 QVector<qreal> points;
47 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
47 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
48 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
48 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
49 qreal leftEdge = logMin < logMax ? logMin : logMax;
49 qreal leftEdge = logMin < logMax ? logMin : logMax;
50 qreal ceilEdge = ceil(leftEdge);
50 qreal ceilEdge = ceil(leftEdge);
51 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
51 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
52
52
53 points.resize(tickCount);
53 points.resize(tickCount);
54 const QRectF &gridRect = gridGeometry();
54 const QRectF &gridRect = gridGeometry();
55 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
55 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
56 for (int i = 0; i < tickCount; ++i)
56 for (int i = 0; i < tickCount; ++i)
57 points[i] = (ceilEdge + i) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
57 points[i] = (ceilEdge + i) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
58
58
59 return points;
59 return points;
60 }
60 }
61
61
62
62
63 void ChartLogValueAxisY::updateGeometry()
63 void ChartLogValueAxisY::updateGeometry()
64 {
64 {
65 const QVector<qreal> &layout = ChartAxis::layout();
65 const QVector<qreal> &layout = ChartAxis::layout();
66 if (layout.isEmpty())
66 if (layout.isEmpty())
67 return;
67 return;
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
69 VerticalAxis::updateGeometry();
69 VerticalAxis::updateGeometry();
70 }
70 }
71
71
72 void ChartLogValueAxisY::handleBaseChanged(qreal base)
72 void ChartLogValueAxisY::handleBaseChanged(qreal base)
73 {
73 {
74 Q_UNUSED(base);
74 Q_UNUSED(base);
75 QGraphicsLayoutItem::updateGeometry();
75 QGraphicsLayoutItem::updateGeometry();
76 if(presenter()) presenter()->layout()->invalidate();
76 if(presenter()) presenter()->layout()->invalidate();
77 }
77 }
78
78
79 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
79 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
80 {
80 {
81 Q_UNUSED(format);
81 Q_UNUSED(format);
82 QGraphicsLayoutItem::updateGeometry();
82 QGraphicsLayoutItem::updateGeometry();
83 if(presenter()) presenter()->layout()->invalidate();
83 if(presenter()) presenter()->layout()->invalidate();
84 }
84 }
85
85
86 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
87 {
87 {
88 Q_UNUSED(constraint)
88 Q_UNUSED(constraint)
89
89
90 QFontMetrics fn(font());
90 QFontMetrics fn(font());
91 QSizeF sh;
91 QSizeF sh;
92
92
93 QSizeF base = VerticalAxis::sizeHint(which, constraint);
93 QSizeF base = VerticalAxis::sizeHint(which, constraint);
94 QStringList ticksList;
94 QStringList ticksList;
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
100 else
100 else
101 ticksList.append(QString(" "));
101 ticksList.append(QString(" "));
102 qreal width = 0;
102 qreal width = 0;
103 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
104 // first and last ticks. Base height is irrelevant.
103 qreal height = 0;
105 qreal height = 0;
104
106
105 switch (which) {
107 switch (which) {
106 case Qt::MinimumSize: {
108 case Qt::MinimumSize: {
107 QRectF boundingRect = labelBoundingRect(fn, "...");
109 QRectF boundingRect = labelBoundingRect(fn, "...");
108 width = boundingRect.width() + labelPadding();
110 width = boundingRect.width() + labelPadding();
109 width += base.width();
111 width += base.width();
110 height = qMax(boundingRect.height(), base.height());
112 height = boundingRect.height() / 2.0;
111 sh = QSizeF(width, height);
113 sh = QSizeF(width, height);
112 break;
114 break;
113 }
115 }
114 case Qt::PreferredSize: {
116 case Qt::PreferredSize: {
115 int labelWidth = 0;
117 int labelWidth = 0;
118 int firstHeight = -1;
116 foreach (const QString& s, ticksList) {
119 foreach (const QString& s, ticksList) {
117 QRect rect = labelBoundingRect(fn, s);
120 QRect rect = labelBoundingRect(fn, s);
118 labelWidth = qMax(rect.width(), labelWidth);
121 labelWidth = qMax(rect.width(), labelWidth);
119 height += rect.height();
122 height = rect.height();
123 if (firstHeight < 0)
124 firstHeight = height;
120 }
125 }
121 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
126 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
122 width += base.width();
127 width += base.width();
123 height = qMax(height, base.height());
128 height = qMax(height, qreal(firstHeight)) / 2.0;
124 sh = QSizeF(width, height);
129 sh = QSizeF(width, height);
125 break;
130 break;
126 }
131 }
127 default:
132 default:
128 break;
133 break;
129 }
134 }
130
135
131 return sh;
136 return sh;
132 }
137 }
133
138
134 #include "moc_chartlogvalueaxisy_p.cpp"
139 #include "moc_chartlogvalueaxisy_p.cpp"
135
140
136 QTCOMMERCIALCHART_END_NAMESPACE
141 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,129 +1,133
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartvalueaxisx_p.h"
21 #include "chartvalueaxisx_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "qvalueaxis.h"
24 #include "qvalueaxis.h"
25 #include "chartlayout_p.h"
25 #include "chartlayout_p.h"
26 #include <QGraphicsLayout>
26 #include <QGraphicsLayout>
27 #include <QFontMetrics>
27 #include <QFontMetrics>
28 #include <qmath.h>
28 #include <qmath.h>
29 #include <QDebug>
29 #include <QDebug>
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 ChartValueAxisX::ChartValueAxisX(QValueAxis *axis, QGraphicsItem* item )
34 ChartValueAxisX::ChartValueAxisX(QValueAxis *axis, QGraphicsItem* item )
35 : HorizontalAxis(axis, item),
35 : HorizontalAxis(axis, item),
36 m_axis(axis)
36 m_axis(axis)
37 {
37 {
38 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
38 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
39 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
39 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
40 }
40 }
41
41
42 ChartValueAxisX::~ChartValueAxisX()
42 ChartValueAxisX::~ChartValueAxisX()
43 {
43 {
44 }
44 }
45
45
46 QVector<qreal> ChartValueAxisX::calculateLayout() const
46 QVector<qreal> ChartValueAxisX::calculateLayout() const
47 {
47 {
48 int tickCount = m_axis->tickCount();
48 int tickCount = m_axis->tickCount();
49
49
50 Q_ASSERT(tickCount >= 2);
50 Q_ASSERT(tickCount >= 2);
51
51
52 QVector<qreal> points;
52 QVector<qreal> points;
53 points.resize(tickCount);
53 points.resize(tickCount);
54
54
55 const QRectF &gridRect = gridGeometry();
55 const QRectF &gridRect = gridGeometry();
56 const qreal deltaX = gridRect.width() / (tickCount - 1);
56 const qreal deltaX = gridRect.width() / (tickCount - 1);
57 for (int i = 0; i < tickCount; ++i) {
57 for (int i = 0; i < tickCount; ++i) {
58 points[i] = i * deltaX + gridRect.left();
58 points[i] = i * deltaX + gridRect.left();
59 }
59 }
60 return points;
60 return points;
61 }
61 }
62
62
63 void ChartValueAxisX::updateGeometry()
63 void ChartValueAxisX::updateGeometry()
64 {
64 {
65 const QVector<qreal>& layout = ChartAxis::layout();
65 const QVector<qreal>& layout = ChartAxis::layout();
66 if (layout.isEmpty())
66 if (layout.isEmpty())
67 return;
67 return;
68 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
68 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
69 HorizontalAxis::updateGeometry();
69 HorizontalAxis::updateGeometry();
70 }
70 }
71
71
72 void ChartValueAxisX::handleTickCountChanged(int tick)
72 void ChartValueAxisX::handleTickCountChanged(int tick)
73 {
73 {
74 Q_UNUSED(tick);
74 Q_UNUSED(tick);
75 QGraphicsLayoutItem::updateGeometry();
75 QGraphicsLayoutItem::updateGeometry();
76 if(presenter()) presenter()->layout()->invalidate();
76 if(presenter()) presenter()->layout()->invalidate();
77 }
77 }
78
78
79 void ChartValueAxisX::handleLabelFormatChanged(const QString &format)
79 void ChartValueAxisX::handleLabelFormatChanged(const QString &format)
80 {
80 {
81 Q_UNUSED(format);
81 Q_UNUSED(format);
82 QGraphicsLayoutItem::updateGeometry();
82 QGraphicsLayoutItem::updateGeometry();
83 if(presenter()) presenter()->layout()->invalidate();
83 if(presenter()) presenter()->layout()->invalidate();
84 }
84 }
85
85
86 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
87 {
87 {
88 Q_UNUSED(constraint)
88 Q_UNUSED(constraint)
89
89
90 QFontMetrics fn(font());
90 QFontMetrics fn(font());
91 QSizeF sh;
91 QSizeF sh;
92
92
93 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
93 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
94 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
94 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
95 // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past
96 // first and last ticks. Base width is irrelevant.
95 qreal width = 0;
97 qreal width = 0;
96 qreal height = 0;
98 qreal height = 0;
97
99
98
99 switch (which) {
100 switch (which) {
100 case Qt::MinimumSize: {
101 case Qt::MinimumSize: {
101 QRectF boundingRect = labelBoundingRect(fn, "...");
102 QRectF boundingRect = labelBoundingRect(fn, "...");
102 width = qMax(boundingRect.width(), base.width());
103 width = boundingRect.width() / 2.0;
103 height = boundingRect.height() + labelPadding();
104 height = boundingRect.height() + labelPadding();
104 height += base.height();
105 height += base.height();
105 sh = QSizeF(width, height);
106 sh = QSizeF(width, height);
106 break;
107 break;
107 }
108 }
108 case Qt::PreferredSize: {
109 case Qt::PreferredSize: {
109 int labelHeight = 0;
110 int labelHeight = 0;
111 int firstWidth = -1;
110 foreach (const QString& s, ticksList) {
112 foreach (const QString& s, ticksList) {
111 QRect rect = labelBoundingRect(fn, s);
113 QRect rect = labelBoundingRect(fn, s);
112 labelHeight = qMax(rect.height(), labelHeight);
114 labelHeight = qMax(rect.height(), labelHeight);
113 width += rect.width();
115 width = rect.width();
116 if (firstWidth < 0)
117 firstWidth = width;
114 }
118 }
115 height = labelHeight + labelPadding();
119 height = labelHeight + labelPadding();
116 height += base.height();
120 height += base.height();
117 width = qMax(width, base.width());
121 width = qMax(width, qreal(firstWidth)) / 2.0;
118 sh = QSizeF(width, height);
122 sh = QSizeF(width, height);
119 break;
123 break;
120 }
124 }
121 default:
125 default:
122 break;
126 break;
123 }
127 }
124 return sh;
128 return sh;
125 }
129 }
126
130
127 #include "moc_chartvalueaxisx_p.cpp"
131 #include "moc_chartvalueaxisx_p.cpp"
128
132
129 QTCOMMERCIALCHART_END_NAMESPACE
133 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,128 +1,133
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartvalueaxisy_p.h"
21 #include "chartvalueaxisy_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "qvalueaxis.h"
24 #include "qvalueaxis.h"
25 #include "chartlayout_p.h"
25 #include "chartlayout_p.h"
26 #include <QGraphicsLayout>
26 #include <QGraphicsLayout>
27 #include <QFontMetrics>
27 #include <QFontMetrics>
28 #include <qmath.h>
28 #include <qmath.h>
29 #include <QDebug>
29 #include <QDebug>
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 ChartValueAxisY::ChartValueAxisY(QValueAxis *axis, QGraphicsItem* item)
33 ChartValueAxisY::ChartValueAxisY(QValueAxis *axis, QGraphicsItem* item)
34 : VerticalAxis(axis, item),
34 : VerticalAxis(axis, item),
35 m_axis(axis)
35 m_axis(axis)
36 {
36 {
37 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
37 QObject::connect(m_axis,SIGNAL(tickCountChanged(int)),this, SLOT(handleTickCountChanged(int)));
38 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
38 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
39 }
39 }
40
40
41 ChartValueAxisY::~ChartValueAxisY()
41 ChartValueAxisY::~ChartValueAxisY()
42 {
42 {
43 }
43 }
44
44
45 QVector<qreal> ChartValueAxisY::calculateLayout() const
45 QVector<qreal> ChartValueAxisY::calculateLayout() const
46 {
46 {
47 int tickCount = m_axis->tickCount();
47 int tickCount = m_axis->tickCount();
48
48
49 Q_ASSERT(tickCount >= 2);
49 Q_ASSERT(tickCount >= 2);
50
50
51 QVector<qreal> points;
51 QVector<qreal> points;
52 points.resize(tickCount);
52 points.resize(tickCount);
53
53
54 const QRectF &gridRect = gridGeometry();
54 const QRectF &gridRect = gridGeometry();
55
55
56 const qreal deltaY = gridRect.height() / (tickCount - 1);
56 const qreal deltaY = gridRect.height() / (tickCount - 1);
57 for (int i = 0; i < tickCount; ++i) {
57 for (int i = 0; i < tickCount; ++i) {
58 points[i] = i * -deltaY + gridRect.bottom();
58 points[i] = i * -deltaY + gridRect.bottom();
59 }
59 }
60
60
61 return points;
61 return points;
62 }
62 }
63
63
64 void ChartValueAxisY::updateGeometry()
64 void ChartValueAxisY::updateGeometry()
65 {
65 {
66 const QVector<qreal> &layout = ChartAxis::layout();
66 const QVector<qreal> &layout = ChartAxis::layout();
67 if (layout.isEmpty())
67 if (layout.isEmpty())
68 return;
68 return;
69 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
69 setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat()));
70 VerticalAxis::updateGeometry();
70 VerticalAxis::updateGeometry();
71 }
71 }
72
72
73 void ChartValueAxisY::handleTickCountChanged(int tick)
73 void ChartValueAxisY::handleTickCountChanged(int tick)
74 {
74 {
75 Q_UNUSED(tick);
75 Q_UNUSED(tick);
76 QGraphicsLayoutItem::updateGeometry();
76 QGraphicsLayoutItem::updateGeometry();
77 if(presenter()) presenter()->layout()->invalidate();
77 if(presenter()) presenter()->layout()->invalidate();
78 }
78 }
79
79
80 void ChartValueAxisY::handleLabelFormatChanged(const QString &format)
80 void ChartValueAxisY::handleLabelFormatChanged(const QString &format)
81 {
81 {
82 Q_UNUSED(format);
82 Q_UNUSED(format);
83 QGraphicsLayoutItem::updateGeometry();
83 QGraphicsLayoutItem::updateGeometry();
84 if(presenter()) presenter()->layout()->invalidate();
84 if(presenter()) presenter()->layout()->invalidate();
85 }
85 }
86
86
87 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
87 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
88 {
88 {
89 Q_UNUSED(constraint)
89 Q_UNUSED(constraint)
90
90
91 QFontMetrics fn(font());
91 QFontMetrics fn(font());
92 QSizeF sh;
92 QSizeF sh;
93 QSizeF base = VerticalAxis::sizeHint(which, constraint);
93 QSizeF base = VerticalAxis::sizeHint(which, constraint);
94 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
94 QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat());
95 qreal width = 0;
95 qreal width = 0;
96 // Height of vertical axis sizeHint indicates the maximum distance labels can extend past
97 // first and last ticks. Base height is irrelevant.
96 qreal height = 0;
98 qreal height = 0;
97
99
98 switch (which) {
100 switch (which) {
99 case Qt::MinimumSize: {
101 case Qt::MinimumSize: {
100 QRectF boundingRect = labelBoundingRect(fn, "...");
102 QRectF boundingRect = labelBoundingRect(fn, "...");
101 width = boundingRect.width() + labelPadding();
103 width = boundingRect.width() + labelPadding();
102 width += base.width();
104 width += base.width();
103 height = qMax(boundingRect.height(), base.height());
105 height = boundingRect.height() / 2.0;
104 sh = QSizeF(width, height);
106 sh = QSizeF(width, height);
105 break;
107 break;
106 }
108 }
107 case Qt::PreferredSize: {
109 case Qt::PreferredSize: {
108 int labelWidth = 0;
110 int labelWidth = 0;
111 int firstHeight = -1;
109 foreach (const QString& s, ticksList) {
112 foreach (const QString& s, ticksList) {
110 QRect rect = labelBoundingRect(fn, s);
113 QRect rect = labelBoundingRect(fn, s);
111 labelWidth = qMax(rect.width(), labelWidth);
114 labelWidth = qMax(rect.width(), labelWidth);
112 height += rect.height();
115 height = rect.height();
116 if (firstHeight < 0)
117 firstHeight = height;
113 }
118 }
114 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
119 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
115 width += base.width();
120 width += base.width();
116 height = qMax(height, base.height());
121 height = qMax(height, qreal(firstHeight)) / 2.0;
117 sh = QSizeF(width, height);
122 sh = QSizeF(width, height);
118 break;
123 break;
119 }
124 }
120 default:
125 default:
121 break;
126 break;
122 }
127 }
123 return sh;
128 return sh;
124 }
129 }
125
130
126 #include "moc_chartvalueaxisy_p.cpp"
131 #include "moc_chartvalueaxisy_p.cpp"
127
132
128 QTCOMMERCIALCHART_END_NAMESPACE
133 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,221 +1,221
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "verticalaxis_p.h"
21 #include "verticalaxis_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include <QFontMetrics>
23 #include <QFontMetrics>
24 #include <QDebug>
24 #include <QDebug>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem* item, bool intervalAxis)
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem* item, bool intervalAxis)
29 : ChartAxis(axis, item, intervalAxis)
29 : ChartAxis(axis, item, intervalAxis)
30 {
30 {
31
31
32 }
32 }
33
33
34 VerticalAxis::~VerticalAxis()
34 VerticalAxis::~VerticalAxis()
35 {
35 {
36
36
37 }
37 }
38
38
39 void VerticalAxis::updateGeometry()
39 void VerticalAxis::updateGeometry()
40 {
40 {
41 const QVector<qreal> &layout = ChartAxis::layout();
41 const QVector<qreal> &layout = ChartAxis::layout();
42
42
43 if (layout.isEmpty())
43 if (layout.isEmpty())
44 return;
44 return;
45
45
46 QStringList labelList = labels();
46 QStringList labelList = labels();
47
47
48 QList<QGraphicsItem *> lines = lineItems();
48 QList<QGraphicsItem *> lines = lineItems();
49 QList<QGraphicsItem *> labels = labelItems();
49 QList<QGraphicsItem *> labels = labelItems();
50 QList<QGraphicsItem *> shades = shadeItems();
50 QList<QGraphicsItem *> shades = shadeItems();
51 QList<QGraphicsItem *> axis = arrowItems();
51 QList<QGraphicsItem *> axis = arrowItems();
52 QGraphicsSimpleTextItem* title = titleItem();
52 QGraphicsSimpleTextItem* title = titleItem();
53
53
54 Q_ASSERT(labels.size() == labelList.size());
54 Q_ASSERT(labels.size() == labelList.size());
55 Q_ASSERT(layout.size() == labelList.size());
55 Q_ASSERT(layout.size() == labelList.size());
56
56
57 const QRectF &axisRect = axisGeometry();
57 const QRectF &axisRect = axisGeometry();
58 const QRectF &gridRect = gridGeometry();
58 const QRectF &gridRect = gridGeometry();
59
59
60 qreal height = axisRect.bottom();
60 qreal height = axisRect.bottom();
61
61
62
62
63 //arrow
63 //arrow
64 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(axis.at(0));
64 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(axis.at(0));
65
65
66 //arrow position
66 //arrow position
67 if (alignment()==Qt::AlignLeft)
67 if (alignment()==Qt::AlignLeft)
68 arrowItem->setLine( axisRect.right() , gridRect.top(), axisRect.right(), gridRect.bottom());
68 arrowItem->setLine( axisRect.right() , gridRect.top(), axisRect.right(), gridRect.bottom());
69 else if(alignment()==Qt::AlignRight)
69 else if(alignment()==Qt::AlignRight)
70 arrowItem->setLine( axisRect.left() , gridRect.top(), axisRect.left(), gridRect.bottom());
70 arrowItem->setLine( axisRect.left() , gridRect.top(), axisRect.left(), gridRect.bottom());
71
71
72 QFontMetrics fn(font());
72 QFontMetrics fn(font());
73
73
74 //title
74 //title
75 int titlePad = 0;
75 int titlePad = 0;
76 QRectF titleBoundingRect;
76 QRectF titleBoundingRect;
77 if (!titleText().isEmpty() && titleItem()->isVisible()) {
77 if (!titleText().isEmpty() && titleItem()->isVisible()) {
78 QFontMetrics fn(title->font());
78 QFontMetrics fn(title->font());
79 int size(0);
79 int size(0);
80 size = gridRect.height();
80 size = gridRect.height();
81 QString titleText = this->titleText();
81 QString titleText = this->titleText();
82
82
83 if (fn.boundingRect(titleText).width() > size) {
83 if (fn.boundingRect(titleText).width() > size) {
84 QString string = titleText + "...";
84 QString string = titleText + "...";
85 while (fn.boundingRect(string).width() > size && string.length() > 3)
85 while (fn.boundingRect(string).width() > size && string.length() > 3)
86 string.remove(string.length() - 4, 1);
86 string.remove(string.length() - 4, 1);
87 title->setText(string);
87 title->setText(string);
88 }
88 }
89 else {
89 else {
90 title->setText(titleText);
90 title->setText(titleText);
91 }
91 }
92
92
93 titlePad = titlePadding();
93 titlePad = titlePadding();
94 titleBoundingRect = title->boundingRect();
94 titleBoundingRect = title->boundingRect();
95
95
96 QPointF center = gridRect.center() - titleBoundingRect.center();
96 QPointF center = gridRect.center() - titleBoundingRect.center();
97 if (alignment() == Qt::AlignLeft) {
97 if (alignment() == Qt::AlignLeft) {
98 title->setPos(axisRect.left() - titleBoundingRect.width() / 2 + titleBoundingRect.height() / 2 + titlePad, center.y());
98 title->setPos(axisRect.left() - titleBoundingRect.width() / 2 + titleBoundingRect.height() / 2 + titlePad, center.y());
99 }
99 }
100 else if (alignment() == Qt::AlignRight) {
100 else if (alignment() == Qt::AlignRight) {
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2 - titleBoundingRect.height() / 2 - titlePad, center.y());
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2 - titleBoundingRect.height() / 2 - titlePad, center.y());
102 }
102 }
103 title->setTransformOriginPoint(titleBoundingRect.center());
103 title->setTransformOriginPoint(titleBoundingRect.center());
104 title->setRotation(270);
104 title->setRotation(270);
105 }
105 }
106
106
107 for (int i = 0; i < layout.size(); ++i) {
107 for (int i = 0; i < layout.size(); ++i) {
108
108
109 //items
109 //items
110 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
110 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
111 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(axis.at(i + 1));
111 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(axis.at(i + 1));
112 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
112 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
113
113
114 //grid line
114 //grid line
115 gridItem->setLine(gridRect.left() , layout[i], gridRect.right(), layout[i]);
115 gridItem->setLine(gridRect.left() , layout[i], gridRect.right(), layout[i]);
116
116
117 //label text wrapping
117 //label text wrapping
118 QString text = labelList.at(i);
118 QString text = labelList.at(i);
119 QRectF boundingRect = labelBoundingRect(fn, text);
119 QRectF boundingRect = labelBoundingRect(fn, text);
120
120
121 qreal size = axisRect.right() - axisRect.left() - labelPadding() - titleBoundingRect.height() - (titlePad * 2);
121 qreal size = axisRect.right() - axisRect.left() - labelPadding() - titleBoundingRect.height() - (titlePad * 2);
122 if (boundingRect.width() > size) {
122 if (boundingRect.width() > size) {
123 QString label = text + "...";
123 QString label = text + "...";
124 while (boundingRect.width() > size && label.length() > 3) {
124 while (boundingRect.width() > size && label.length() > 3) {
125 label.remove(label.length() - 4, 1);
125 label.remove(label.length() - 4, 1);
126 boundingRect = labelBoundingRect(fn, label);
126 boundingRect = labelBoundingRect(fn, label);
127 }
127 }
128 labelItem->setText(label);
128 labelItem->setText(label);
129 } else {
129 } else {
130 labelItem->setText(text);
130 labelItem->setText(text);
131 }
131 }
132
132
133 //label transformation origin point
133 //label transformation origin point
134 const QRectF &rect = labelItem->boundingRect();
134 const QRectF &rect = labelItem->boundingRect();
135
135
136 QPointF center = rect.center();
136 QPointF center = rect.center();
137 labelItem->setTransformOriginPoint(center.x(), center.y());
137 labelItem->setTransformOriginPoint(center.x(), center.y());
138 int widthDiff = rect.width() - boundingRect.width();
138 int widthDiff = rect.width() - boundingRect.width();
139
139
140 //ticks and label position
140 //ticks and label position
141 if (alignment() == Qt::AlignLeft) {
141 if (alignment() == Qt::AlignLeft) {
142 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y());
142 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y());
143 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
143 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
144 } else if (alignment() == Qt::AlignRight) {
144 } else if (alignment() == Qt::AlignRight) {
145 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y());
145 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y());
146 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
146 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
147 }
147 }
148
148
149 //label in beetwen
149 //label in beetwen
150 if(intervalAxis()&& i+1!=layout.size()) {
150 if(intervalAxis()&& i+1!=layout.size()) {
151 const qreal delta = (layout[i+1] - layout[i])/2;
151 const qreal delta = (layout[i+1] - layout[i])/2;
152 labelItem->setPos(labelItem->pos().x() , layout[i] + delta - center.y());
152 labelItem->setPos(labelItem->pos().x() , layout[i] + delta - center.y());
153 }
153 }
154
154
155 //label overlap detection
155 //label overlap detection
156 if(labelItem->pos().y() + boundingRect.height() > height ||
156 if(labelItem->pos().y() + boundingRect.height() > height ||
157 labelItem->pos().y() + boundingRect.height()/2 > gridRect.bottom() ||
157 labelItem->pos().y() + boundingRect.height()/2 > axisRect.bottom() ||
158 labelItem->pos().y() + boundingRect.height()/2 < gridRect.top()) {
158 labelItem->pos().y() + boundingRect.height()/2 < axisRect.top()) {
159 labelItem->setVisible(false);
159 labelItem->setVisible(false);
160 }
160 }
161 else {
161 else {
162 labelItem->setVisible(true);
162 labelItem->setVisible(true);
163 height=labelItem->pos().y();
163 height=labelItem->pos().y();
164 }
164 }
165
165
166 //shades
166 //shades
167 if ((i + 1) % 2 && i > 1) {
167 if ((i + 1) % 2 && i > 1) {
168 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
168 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
169 rectItem->setRect(gridRect.left(), layout[i], gridRect.width(), layout[i - 1] - layout[i]);
169 rectItem->setRect(gridRect.left(), layout[i], gridRect.width(), layout[i - 1] - layout[i]);
170 }
170 }
171
171
172 // check if the grid line and the axis tick should be shown
172 // check if the grid line and the axis tick should be shown
173 qreal y = gridItem->line().p1().y();
173 qreal y = gridItem->line().p1().y();
174 if ((y < gridRect.top() || y > gridRect.bottom()))
174 if ((y < gridRect.top() || y > gridRect.bottom()))
175 {
175 {
176 gridItem->setVisible(false);
176 gridItem->setVisible(false);
177 tickItem->setVisible(false);
177 tickItem->setVisible(false);
178 }else{
178 }else{
179 gridItem->setVisible(true);
179 gridItem->setVisible(true);
180 tickItem->setVisible(true);
180 tickItem->setVisible(true);
181 }
181 }
182
182
183 }
183 }
184 //begin/end grid line in case labels between
184 //begin/end grid line in case labels between
185 if (intervalAxis()) {
185 if (intervalAxis()) {
186 QGraphicsLineItem *gridLine;
186 QGraphicsLineItem *gridLine;
187 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
187 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
188 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
188 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
189 gridLine->setVisible(true);
189 gridLine->setVisible(true);
190 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
190 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
191 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
191 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
192 gridLine->setVisible(true);
192 gridLine->setVisible(true);
193 }
193 }
194 }
194 }
195
195
196 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
196 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
197 {
197 {
198
198
199 Q_UNUSED(constraint);
199 Q_UNUSED(constraint);
200 QFontMetrics fn(titleFont());
200 QFontMetrics fn(titleFont());
201 QSizeF sh(0,0);
201 QSizeF sh(0,0);
202
202
203 if (titleText().isEmpty() || !titleItem()->isVisible())
203 if (titleText().isEmpty() || !titleItem()->isVisible())
204 return sh;
204 return sh;
205
205
206 switch (which) {
206 switch (which) {
207 case Qt::MinimumSize:
207 case Qt::MinimumSize:
208 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect("...").width());
208 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect("...").width());
209 break;
209 break;
210 case Qt::MaximumSize:
210 case Qt::MaximumSize:
211 case Qt::PreferredSize:
211 case Qt::PreferredSize:
212 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect(axis()->titleText()).width());
212 sh = QSizeF(fn.height() + (titlePadding() * 2), fn.boundingRect(axis()->titleText()).width());
213 break;
213 break;
214 default:
214 default:
215 break;
215 break;
216 }
216 }
217
217
218 return sh;
218 return sh;
219 }
219 }
220
220
221 QTCOMMERCIALCHART_END_NAMESPACE
221 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,392 +1,402
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartlayout_p.h"
21 #include "chartlayout_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlegend_p.h"
23 #include "qlegend_p.h"
24 #include "chartaxis_p.h"
24 #include "chartaxis_p.h"
25 #include "charttitle_p.h"
25 #include "charttitle_p.h"
26 #include "chartbackground_p.h"
26 #include "chartbackground_p.h"
27 #include <QDebug>
27 #include <QDebug>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 static const qreal maxAxisPortion = 0.4;
31 static const qreal maxAxisPortion = 0.4;
32
32
33 ChartLayout::ChartLayout(ChartPresenter *presenter)
33 ChartLayout::ChartLayout(ChartPresenter *presenter)
34 : m_presenter(presenter),
34 : m_presenter(presenter),
35 m_margins(20, 20, 20, 20),
35 m_margins(20, 20, 20, 20),
36 m_minChartRect(0, 0, 200, 200)
36 m_minChartRect(0, 0, 200, 200)
37 {
37 {
38
38
39 }
39 }
40
40
41 ChartLayout::~ChartLayout()
41 ChartLayout::~ChartLayout()
42 {
42 {
43
43
44 }
44 }
45
45
46 void ChartLayout::setGeometry(const QRectF &rect)
46 void ChartLayout::setGeometry(const QRectF &rect)
47 {
47 {
48 if (!rect.isValid())
48 if (!rect.isValid())
49 return;
49 return;
50
50
51 QList<ChartAxis *> axes = m_presenter->axisItems();
51 QList<ChartAxis *> axes = m_presenter->axisItems();
52 ChartTitle *title = m_presenter->titleElement();
52 ChartTitle *title = m_presenter->titleElement();
53 QLegend *legend = m_presenter->legend();
53 QLegend *legend = m_presenter->legend();
54 ChartBackground *background = m_presenter->backgroundElement();
54 ChartBackground *background = m_presenter->backgroundElement();
55
55
56 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
56 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
57
57
58 contentGeometry = calculateContentGeometry(contentGeometry);
58 contentGeometry = calculateContentGeometry(contentGeometry);
59
59
60 if (title && title->isVisible())
60 if (title && title->isVisible())
61 contentGeometry = calculateTitleGeometry(contentGeometry, title);
61 contentGeometry = calculateTitleGeometry(contentGeometry, title);
62
62
63 if (legend->isAttachedToChart() && legend->isVisible())
63 if (legend->isAttachedToChart() && legend->isVisible())
64 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
64 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
65
65
66 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
66 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
67
67
68 m_presenter->setGeometry(contentGeometry);
68 m_presenter->setGeometry(contentGeometry);
69
69
70 QGraphicsLayout::setGeometry(rect);
70 QGraphicsLayout::setGeometry(rect);
71 }
71 }
72
72
73 QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const
73 QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const
74 {
74 {
75 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
75 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
76 }
76 }
77
77
78 QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const
78 QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const
79 {
79 {
80 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
80 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
81 }
81 }
82
82
83
83
84 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
84 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
85 {
85 {
86 qreal left, top, right, bottom;
86 qreal left, top, right, bottom;
87 getContentsMargins(&left, &top, &right, &bottom);
87 getContentsMargins(&left, &top, &right, &bottom);
88 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
88 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
89 if (background)
89 if (background)
90 background->setRect(backgroundGeometry);
90 background->setRect(backgroundGeometry);
91 return backgroundGeometry;
91 return backgroundGeometry;
92 }
92 }
93
93
94 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
94 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
95 {
95 {
96 qreal left, top, right, bottom;
96 qreal left, top, right, bottom;
97 getContentsMargins(&left, &top, &right, &bottom);
97 getContentsMargins(&left, &top, &right, &bottom);
98 return minimum.adjusted(0, 0, left + right, top + bottom);
98 return minimum.adjusted(0, 0, left + right, top + bottom);
99 }
99 }
100
100
101
101
102 QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const
102 QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const
103 {
103 {
104 QSizeF left(0,0);
104 QSizeF left(0,0);
105 QSizeF minLeft(0,0);
105 QSizeF minLeft(0,0);
106 QSizeF right(0,0);
106 QSizeF right(0,0);
107 QSizeF minRight(0,0);
107 QSizeF minRight(0,0);
108 QSizeF bottom(0,0);
108 QSizeF bottom(0,0);
109 QSizeF minBottom(0,0);
109 QSizeF minBottom(0,0);
110 QSizeF top(0,0);
110 QSizeF top(0,0);
111 QSizeF minTop(0,0);
111 QSizeF minTop(0,0);
112 QSizeF labelExtents(0,0);
112 int leftCount = 0;
113 int leftCount = 0;
113 int rightCount = 0;
114 int rightCount = 0;
114 int topCount = 0;
115 int topCount = 0;
115 int bottomCount = 0;
116 int bottomCount = 0;
116
117
117 foreach (ChartAxis *axis , axes) {
118 foreach (ChartAxis *axis , axes) {
118
119
119 if (!axis->isVisible())
120 if (!axis->isVisible())
120 continue;
121 continue;
121
122
122
123 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
123 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
124 //this is used to get single thick font size
124 //this is used to get single thick font size
125 QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize);
125 QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize);
126
126
127 switch (axis->alignment()) {
127 switch (axis->alignment()) {
128 case Qt::AlignLeft:
128 case Qt::AlignLeft:
129 left.setWidth(left.width()+size.width());
129 left.setWidth(left.width()+size.width());
130 left.setHeight(qMax(left.height(),size.height()));
130 left.setHeight(qMax(left.height(),size.height()));
131 minLeft.setWidth(minLeft.width()+minSize.width());
131 minLeft.setWidth(minLeft.width()+minSize.width());
132 minLeft.setHeight(qMax(minLeft.height(),minSize.height()));
132 minLeft.setHeight(qMax(minLeft.height(),minSize.height()));
133 labelExtents.setHeight(qMax(size.height(), labelExtents.height()));
133 leftCount++;
134 leftCount++;
134 break;
135 break;
135 case Qt::AlignRight:
136 case Qt::AlignRight:
136 right.setWidth(right.width()+size.width());
137 right.setWidth(right.width()+size.width());
137 right.setHeight(qMax(right.height(),size.height()));
138 right.setHeight(qMax(right.height(),size.height()));
138 minRight.setWidth(minRight.width()+minSize.width());
139 minRight.setWidth(minRight.width()+minSize.width());
139 minRight.setHeight(qMax(minRight.height(),minSize.height()));
140 minRight.setHeight(qMax(minRight.height(),minSize.height()));
141 labelExtents.setHeight(qMax(size.height(), labelExtents.height()));
140 rightCount++;
142 rightCount++;
141 break;
143 break;
142 case Qt::AlignTop:
144 case Qt::AlignTop:
143 top.setWidth(qMax(top.width(),size.width()));
145 top.setWidth(qMax(top.width(),size.width()));
144 top.setHeight(top.height()+size.height());
146 top.setHeight(top.height()+size.height());
145 minTop.setWidth(qMax(minTop.width(),minSize.width()));
147 minTop.setWidth(qMax(minTop.width(),minSize.width()));
146 minTop.setHeight(minTop.height()+minSize.height());
148 minTop.setHeight(minTop.height()+minSize.height());
149 labelExtents.setWidth(qMax(size.width(), labelExtents.width()));
147 topCount++;
150 topCount++;
148 break;
151 break;
149 case Qt::AlignBottom:
152 case Qt::AlignBottom:
150 bottom.setWidth(qMax(bottom.width(), size.width()));
153 bottom.setWidth(qMax(bottom.width(), size.width()));
151 bottom.setHeight(bottom.height() + size.height());
154 bottom.setHeight(bottom.height() + size.height());
152 minBottom.setWidth(qMax(minBottom.width(),minSize.width()));
155 minBottom.setWidth(qMax(minBottom.width(),minSize.width()));
153 minBottom.setHeight(minBottom.height() + minSize.height());
156 minBottom.setHeight(minBottom.height() + minSize.height());
157 labelExtents.setWidth(qMax(size.width(), labelExtents.width()));
154 bottomCount++;
158 bottomCount++;
155 break;
159 break;
156 default:
160 default:
157 qWarning()<<"Axis is without alignment !";
161 qWarning()<<"Axis is without alignment !";
158 break;
162 break;
159 }
163 }
160 }
164 }
161
165
162 int totalVerticalAxes = leftCount + rightCount;
166 int totalVerticalAxes = leftCount + rightCount;
163 qreal leftSqueezeRatio = 1.0;
167 qreal leftSqueezeRatio = 1.0;
164 qreal rightSqueezeRatio = 1.0;
168 qreal rightSqueezeRatio = 1.0;
165 qreal vratio = 0;
169 qreal vratio = 0;
166
170
167 if (totalVerticalAxes > 0)
171 if (totalVerticalAxes > 0)
168 vratio = (maxAxisPortion * geometry.width()) / totalVerticalAxes;
172 vratio = (maxAxisPortion * geometry.width()) / totalVerticalAxes;
169
173
170 if (leftCount > 0) {
174 if (leftCount > 0) {
171 int maxWidth = vratio * leftCount;
175 int maxWidth = vratio * leftCount;
172 if (left.width() > maxWidth) {
176 if (left.width() > maxWidth) {
173 leftSqueezeRatio = maxWidth / left.width();
177 leftSqueezeRatio = maxWidth / left.width();
174 left.setWidth(maxWidth);
178 left.setWidth(maxWidth);
175 }
179 }
176 }
180 }
177 if (rightCount > 0) {
181 if (rightCount > 0) {
178 int maxWidth = vratio * rightCount;
182 int maxWidth = vratio * rightCount;
179 if (right.width() > maxWidth) {
183 if (right.width() > maxWidth) {
180 rightSqueezeRatio = maxWidth / right.width();
184 rightSqueezeRatio = maxWidth / right.width();
181 right.setWidth(maxWidth);
185 right.setWidth(maxWidth);
182 }
186 }
183 }
187 }
184
188
185 int totalHorizontalAxes = topCount + bottomCount;
189 int totalHorizontalAxes = topCount + bottomCount;
186 qreal topSqueezeRatio = 1.0;
190 qreal topSqueezeRatio = 1.0;
187 qreal bottomSqueezeRatio = 1.0;
191 qreal bottomSqueezeRatio = 1.0;
188 qreal hratio = 0;
192 qreal hratio = 0;
189
193
190 if (totalHorizontalAxes > 0)
194 if (totalHorizontalAxes > 0)
191 hratio = (maxAxisPortion * geometry.height()) / totalHorizontalAxes;
195 hratio = (maxAxisPortion * geometry.height()) / totalHorizontalAxes;
192
196
193 if (topCount > 0) {
197 if (topCount > 0) {
194 int maxHeight = hratio * topCount;
198 int maxHeight = hratio * topCount;
195 if (top.height() > maxHeight) {
199 if (top.height() > maxHeight) {
196 topSqueezeRatio = maxHeight / top.height();
200 topSqueezeRatio = maxHeight / top.height();
197 top.setHeight(maxHeight);
201 top.setHeight(maxHeight);
198 }
202 }
199 }
203 }
200 if (bottomCount > 0) {
204 if (bottomCount > 0) {
201 int maxHeight = hratio * bottomCount;
205 int maxHeight = hratio * bottomCount;
202 if (bottom.height() > maxHeight) {
206 if (bottom.height() > maxHeight) {
203 bottomSqueezeRatio = maxHeight / bottom.height();
207 bottomSqueezeRatio = maxHeight / bottom.height();
204 bottom.setHeight(maxHeight);
208 bottom.setHeight(maxHeight);
205 }
209 }
206 }
210 }
207
211
208 qreal minHeight = qMax(minLeft.height(),minRight.height()) + 1;
212 qreal minHeight = qMax(minLeft.height(),minRight.height()) + 1;
209 qreal minWidth = qMax(minTop.width(),minBottom.width()) + 1;
213 qreal minWidth = qMax(minTop.width(),minBottom.width()) + 1;
210
214
215 // Ensure that there is enough space for first and last tick labels.
216 left.setWidth(qMax(labelExtents.width(), left.width()));
217 right.setWidth(qMax(labelExtents.width(), right.width()));
218 top.setHeight(qMax(labelExtents.height(), top.height()));
219 bottom.setHeight(qMax(labelExtents.height(), bottom.height()));
220
211 QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2));
221 QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2));
212
222
213 qreal leftOffset = 0;
223 qreal leftOffset = 0;
214 qreal rightOffset = 0;
224 qreal rightOffset = 0;
215 qreal topOffset = 0;
225 qreal topOffset = 0;
216 qreal bottomOffset = 0;
226 qreal bottomOffset = 0;
217
227
218 foreach(ChartElement *axisElement , axes) {
228 foreach(ChartElement *axisElement , axes) {
219 ChartAxis* axis = qobject_cast<ChartAxis*>(axisElement);
229 ChartAxis* axis = qobject_cast<ChartAxis*>(axisElement);
220
230
221 if (!axis->isVisible())
231 if (!axis->isVisible())
222 continue;
232 continue;
223
233
224 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
234 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
225
235
226 switch(axis->alignment()){
236 switch(axis->alignment()){
227 case Qt::AlignLeft:{
237 case Qt::AlignLeft:{
228 qreal width = size.width();
238 qreal width = size.width();
229 if (leftSqueezeRatio < 1.0)
239 if (leftSqueezeRatio < 1.0)
230 width *= leftSqueezeRatio;
240 width *= leftSqueezeRatio;
231 leftOffset+=width;
241 leftOffset+=width;
232 axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect);
242 axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect);
233 break;
243 break;
234 }
244 }
235 case Qt::AlignRight:{
245 case Qt::AlignRight:{
236 qreal width = size.width();
246 qreal width = size.width();
237 if (rightSqueezeRatio < 1.0)
247 if (rightSqueezeRatio < 1.0)
238 width *= rightSqueezeRatio;
248 width *= rightSqueezeRatio;
239 axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect);
249 axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect);
240 rightOffset+=width;
250 rightOffset+=width;
241 break;
251 break;
242 }
252 }
243 case Qt::AlignTop: {
253 case Qt::AlignTop: {
244 qreal height = size.height();
254 qreal height = size.height();
245 if (topSqueezeRatio < 1.0)
255 if (topSqueezeRatio < 1.0)
246 height *= topSqueezeRatio;
256 height *= topSqueezeRatio;
247 axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - height, geometry.width(), height), chartRect);
257 axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - height, geometry.width(), height), chartRect);
248 topOffset += height;
258 topOffset += height;
249 break;
259 break;
250 }
260 }
251 case Qt::AlignBottom:
261 case Qt::AlignBottom:
252 qreal height = size.height();
262 qreal height = size.height();
253 if (bottomSqueezeRatio < 1.0)
263 if (bottomSqueezeRatio < 1.0)
254 height *= bottomSqueezeRatio;
264 height *= bottomSqueezeRatio;
255 axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), height), chartRect);
265 axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), height), chartRect);
256 bottomOffset += height;
266 bottomOffset += height;
257 break;
267 break;
258 }
268 }
259 }
269 }
260
270
261 return chartRect;
271 return chartRect;
262 }
272 }
263
273
264 QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const
274 QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const
265 {
275 {
266 QSizeF left;
276 QSizeF left;
267 QSizeF right;
277 QSizeF right;
268 QSizeF bottom;
278 QSizeF bottom;
269 QSizeF top;
279 QSizeF top;
270
280
271 foreach (ChartAxis *axis, axes) {
281 foreach (ChartAxis *axis, axes) {
272
282
273 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
283 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
274
284
275 if (!axis->isVisible())
285 if (!axis->isVisible())
276 continue;
286 continue;
277
287
278 switch (axis->alignment()) {
288 switch (axis->alignment()) {
279 case Qt::AlignLeft:
289 case Qt::AlignLeft:
280 left.setWidth(left.width() + size.width());
290 left.setWidth(left.width() + size.width());
281 left.setHeight(qMax(left.height() * 2, size.height()));
291 left.setHeight(qMax(left.height() * 2, size.height()));
282 break;
292 break;
283 case Qt::AlignRight:
293 case Qt::AlignRight:
284 right.setWidth(right.width() + size.width());
294 right.setWidth(right.width() + size.width());
285 right.setHeight(qMax(right.height() * 2, size.height()));
295 right.setHeight(qMax(right.height() * 2, size.height()));
286 break;
296 break;
287 case Qt::AlignTop:
297 case Qt::AlignTop:
288 top.setWidth(qMax(top.width(), size.width()));
298 top.setWidth(qMax(top.width(), size.width()));
289 top.setHeight(top.height() + size.height());
299 top.setHeight(top.height() + size.height());
290 break;
300 break;
291 case Qt::AlignBottom:
301 case Qt::AlignBottom:
292 bottom.setWidth(qMax(bottom.width(), size.width()));
302 bottom.setWidth(qMax(bottom.width(), size.width()));
293 bottom.setHeight(bottom.height() + size.height());
303 bottom.setHeight(bottom.height() + size.height());
294 break;
304 break;
295 }
305 }
296 }
306 }
297 return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height()));
307 return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height()));
298 }
308 }
299
309
300 QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
310 QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
301 {
311 {
302 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
312 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
303 QRectF legendRect;
313 QRectF legendRect;
304 QRectF result;
314 QRectF result;
305
315
306 switch (legend->alignment()) {
316 switch (legend->alignment()) {
307 case Qt::AlignTop: {
317 case Qt::AlignTop: {
308 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
318 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
309 result = geometry.adjusted(0, legendRect.height(), 0, 0);
319 result = geometry.adjusted(0, legendRect.height(), 0, 0);
310 break;
320 break;
311 }
321 }
312 case Qt::AlignBottom: {
322 case Qt::AlignBottom: {
313 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
323 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
314 result = geometry.adjusted(0, 0, 0, -legendRect.height());
324 result = geometry.adjusted(0, 0, 0, -legendRect.height());
315 break;
325 break;
316 }
326 }
317 case Qt::AlignLeft: {
327 case Qt::AlignLeft: {
318 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
328 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
319 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
329 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
320 result = geometry.adjusted(width, 0, 0, 0);
330 result = geometry.adjusted(width, 0, 0, 0);
321 break;
331 break;
322 }
332 }
323 case Qt::AlignRight: {
333 case Qt::AlignRight: {
324 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
334 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
325 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
335 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
326 result = geometry.adjusted(0, 0, -width, 0);
336 result = geometry.adjusted(0, 0, -width, 0);
327 break;
337 break;
328 }
338 }
329 default: {
339 default: {
330 legendRect = QRectF(0, 0, 0, 0);
340 legendRect = QRectF(0, 0, 0, 0);
331 result = geometry;
341 result = geometry;
332 break;
342 break;
333 }
343 }
334 }
344 }
335
345
336 legend->setGeometry(legendRect);
346 legend->setGeometry(legendRect);
337
347
338 return result;
348 return result;
339 }
349 }
340
350
341 QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
351 QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
342 {
352 {
343 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
353 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
344 return geometry.adjusted(0, 0, minSize.width(), minSize.height());
354 return geometry.adjusted(0, 0, minSize.width(), minSize.height());
345 }
355 }
346
356
347 QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
357 QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
348 {
358 {
349 title->setGeometry(geometry);
359 title->setGeometry(geometry);
350 QPointF center = geometry.center() - title->boundingRect().center();
360 QPointF center = geometry.center() - title->boundingRect().center();
351 title->setPos(center.x(),title->pos().y());
361 title->setPos(center.x(),title->pos().y());
352 return geometry.adjusted(0,title->boundingRect().height()+1,0,0);
362 return geometry.adjusted(0,title->boundingRect().height()+1,0,0);
353 }
363 }
354
364
355 QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
365 QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
356 {
366 {
357 QSizeF min = title->sizeHint(Qt::MinimumSize);
367 QSizeF min = title->sizeHint(Qt::MinimumSize);
358 return minimum.adjusted(0, 0, min.width(), min.height());
368 return minimum.adjusted(0, 0, min.width(), min.height());
359 }
369 }
360
370
361 QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
371 QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
362 {
372 {
363 Q_UNUSED(constraint);
373 Q_UNUSED(constraint);
364 if (which == Qt::MinimumSize) {
374 if (which == Qt::MinimumSize) {
365 QList<ChartAxis *> axes = m_presenter->axisItems();
375 QList<ChartAxis *> axes = m_presenter->axisItems();
366 ChartTitle *title = m_presenter->titleElement();
376 ChartTitle *title = m_presenter->titleElement();
367 QLegend *legend = m_presenter->legend();
377 QLegend *legend = m_presenter->legend();
368 QRectF minimumRect(0, 0, 0, 0);
378 QRectF minimumRect(0, 0, 0, 0);
369 minimumRect = calculateBackgroundMinimum(minimumRect);
379 minimumRect = calculateBackgroundMinimum(minimumRect);
370 minimumRect = calculateContentMinimum(minimumRect);
380 minimumRect = calculateContentMinimum(minimumRect);
371 minimumRect = calculateTitleMinimum(minimumRect, title);
381 minimumRect = calculateTitleMinimum(minimumRect, title);
372 minimumRect = calculateLegendMinimum(minimumRect, legend);
382 minimumRect = calculateLegendMinimum(minimumRect, legend);
373 minimumRect = calculateAxisMinimum(minimumRect, axes);
383 minimumRect = calculateAxisMinimum(minimumRect, axes);
374 return minimumRect.united(m_minChartRect).size().toSize();
384 return minimumRect.united(m_minChartRect).size().toSize();
375 }
385 }
376 return QSize(-1, -1);
386 return QSize(-1, -1);
377 }
387 }
378
388
379 void ChartLayout::setMargins(const QMargins &margins)
389 void ChartLayout::setMargins(const QMargins &margins)
380 {
390 {
381 if (m_margins != margins) {
391 if (m_margins != margins) {
382 m_margins = margins;
392 m_margins = margins;
383 updateGeometry();
393 updateGeometry();
384 }
394 }
385 }
395 }
386
396
387 QMargins ChartLayout::margins() const
397 QMargins ChartLayout::margins() const
388 {
398 {
389 return m_margins;
399 return m_margins;
390 }
400 }
391
401
392 QTCOMMERCIALCHART_END_NAMESPACE
402 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now