##// END OF EJS Templates
Refactors layout...
Michal Klocek -
r1965:8d7d66e44a18
parent child
Show More
@@ -0,0 +1,94
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "charttitle_p.h"
22 #include <QFont>
23 #include <QFontMetrics>
24 #include <QDebug>
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28 ChartTitle::ChartTitle(QGraphicsItem* parent):QGraphicsSimpleTextItem(parent)
29 {
30
31 }
32
33 ChartTitle::~ChartTitle()
34 {
35
36 }
37
38 void ChartTitle::setText(const QString &text)
39 {
40 m_text=text;
41 }
42
43 QString ChartTitle::text() const
44 {
45 return m_text;
46 }
47
48 void ChartTitle::setGeometry(const QRectF &rect)
49 {
50 QFontMetrics fn(font());
51
52 int width = rect.width();
53
54 if (fn.boundingRect(m_text).width() > width)
55 {
56 QString string = m_text + "...";
57 while (fn.boundingRect(string).width() > width && string.length() > 3)
58 string.remove(string.length() - 4, 1);
59 QGraphicsSimpleTextItem::setText(string);
60 }
61 else
62 QGraphicsSimpleTextItem::setText(m_text);
63
64 setPos(rect.topLeft());
65 }
66
67
68 QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
69 {
70 Q_UNUSED(constraint);
71 QFontMetrics fn (font ());
72 QSizeF sh;
73
74 switch(which) {
75 case Qt::MinimumSize:
76 sh = QSizeF(fn.boundingRect ("...").width(),fn.height());
77 break;
78 case Qt::PreferredSize:
79 sh = QSizeF(fn.boundingRect(m_text).width(),fn.height());
80 break;
81 case Qt::MaximumSize:
82 sh = QSizeF(fn.boundingRect(m_text).width(),fn.height());
83 break;
84 case Qt::MinimumDescent:
85 sh = QSizeF(0, fn.descent ());
86 break;
87 default:
88 break;
89 }
90
91 return sh;
92 }
93
94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,53
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 // W A R N I N G
22 // -------------
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
27 //
28 // We mean it.
29
30 #ifndef CHARTTITLE_P_H_
31 #define CHARTTITLE_P_H_
32
33 #include "qchartglobal.h"
34 #include <QGraphicsSimpleTextItem>
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
38 class ChartTitle : public QGraphicsSimpleTextItem
39 {
40 public:
41 ChartTitle(QGraphicsItem* parent = 0);
42 ~ChartTitle();
43 QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
44 void setText(const QString &text);
45 QString text() const;
46 void setGeometry(const QRectF &rect);
47 private:
48 QString m_text;
49 };
50
51 QTCOMMERCIALCHART_END_NAMESPACE
52
53 #endif /* CHARTTITLE_P_H_ */
@@ -245,7 +245,7 DeclarativeChart::DeclarativeChart(QDeclarativeItem *parent)
245 245
246 246 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
247 247 {
248 m_chart->setMinimumMargins(QMargins(left, top, right, bottom));
248 m_chart->setMargins(QMargins(left, top, right, bottom));
249 249 emit minimumMarginsChanged();
250 250 emit plotAreaChanged(m_chart->plotArea());
251 251 }
@@ -501,6 +501,7 qreal DeclarativeChart::topMargin()
501 501
502 502 qreal DeclarativeChart::bottomMargin()
503 503 {
504
504 505 qWarning() << "ChartView.bottomMargin is deprecated. Use minimumMargins and plotArea instead.";
505 506 return m_chart->plotArea().bottom();
506 507 }
@@ -20,6 +20,7
20 20
21 21 #include "axisanimation_p.h"
22 22 #include "chartaxis_p.h"
23 #include "chartpresenter_p.h"
23 24 #include <QTimer>
24 25 #include <QDebug>
25 26
@@ -61,7 +62,7 void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayo
61 62
62 63 switch (m_type) {
63 64 case ZoomOutAnimation: {
64 QRectF rect = m_axis->geometry();
65 QRectF rect = m_axis->presenter()->chartsGeometry();
65 66 oldLayout.resize(newLayout.count());
66 67
67 68 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
@@ -94,7 +95,7 void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayo
94 95 break;
95 96 default: {
96 97 oldLayout.resize(newLayout.count());
97 QRectF rect = m_axis->geometry();
98 QRectF rect = m_axis->presenter()->chartsGeometry();
98 99 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
99 100 oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
100 101 }
@@ -131,7 +132,6 void AxisAnimation::updateCurrentValue (const QVariant &value )
131 132 Q_ASSERT(vector.count() != 0);
132 133 m_axis->setLayout(vector);
133 134 m_axis->updateGeometry();
134 m_axis->checkLayout();
135 135 }
136 136
137 137 }
@@ -21,6 +21,7
21 21 #include "chartbarcategoryaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 #include <QFontMetrics>
24 25 #include <QDebug>
25 26 #include <qmath.h>
26 27
@@ -47,23 +48,25 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
47 48 QVector<qreal> points;
48 49 points.resize(count+2);
49 50
50 const qreal delta = m_rect.width()/(count);
51 QRectF rect = presenter()->chartsGeometry();
52
53 const qreal delta = rect.width()/(count);
51 54 qreal offset =-m_min-0.5;
52 55
53 56 if(delta<1) return points;
54 57
55 58 if(offset<=0) {
56 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta) + delta;
59 offset = int(offset * rect.width()/(m_max - m_min))%int(delta) + delta;
57 60 }
58 61 else {
59 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta);
62 offset = int(offset * rect.width()/(m_max - m_min))%int(delta);
60 63 }
61 64
62 points[0] = m_rect.left();
63 points[count+1] = m_rect.right();
65 points[0] = rect.left();
66 points[count+1] = rect.right();
64 67
65 68 for (int i = 0; i < count; ++i) {
66 qreal x = offset + i * delta + m_rect.left();
69 qreal x = offset + i * delta + rect.left();
67 70 points[i+1] = x;
68 71 }
69 72 return points;
@@ -72,9 +75,10 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
72 75 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
73 76 {
74 77 QStringList result;
75 qreal d = (m_max - m_min)/m_rect.width();
78 QRectF rect = presenter()->chartsGeometry();
79 qreal d = (m_max - m_min)/rect.width();
76 80 for (int i = 0;i < layout.count()-1; ++i) {
77 qreal x = qFloor((((layout[i+1] + layout[i])/2-m_rect.left())*d + m_min+0.5));
81 qreal x = qFloor((((layout[i+1] + layout[i])/2-rect.left())*d + m_min+0.5));
78 82 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
79 83 result << m_categoriesAxis->categories().at(x);
80 84 }
@@ -92,9 +96,6 void ChartBarCategoryAxisX::updateGeometry()
92 96 {
93 97 const QVector<qreal>& layout = ChartAxis::layout();
94 98
95 m_minWidth = 0;
96 m_minHeight = 0;
97
98 99 if(layout.isEmpty()) return;
99 100
100 101 QStringList ticksList = createCategoryLabels(layout);
@@ -107,15 +108,17 void ChartBarCategoryAxisX::updateGeometry()
107 108 Q_ASSERT(labels.size() == ticksList.size());
108 109 Q_ASSERT(layout.size() == ticksList.size());
109 110
110 const qreal delta = m_rect.width()/(m_categoriesAxis->d_ptr->count());
111 QRectF chartRect = presenter()->chartsGeometry();
112
113 const qreal delta = chartRect.width()/(m_categoriesAxis->d_ptr->count());
111 114
112 115 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
113 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
116 lineItem->setLine( chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
114 117
115 qreal width = m_rect.left();
118 qreal width = chartRect.left();
116 119 for (int i = 0; i < layout.size(); ++i) {
117 120 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
118 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
121 lineItem->setLine(layout[i], chartRect.top(), layout[i], chartRect.bottom());
119 122 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
120 123 labelItem->setText(ticksList.at(i));
121 124 const QRectF& rect = labelItem->boundingRect();
@@ -123,12 +126,12 void ChartBarCategoryAxisX::updateGeometry()
123 126 labelItem->setTransformOriginPoint(center.x(), center.y());
124 127
125 128 if(i==0){
126 labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), m_rect.bottom() + label_padding);
129 labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), chartRect.bottom() + label_padding);
127 130 }else{
128 labelItem->setPos(layout[i] + (delta)/2 - center.x(), m_rect.bottom() + label_padding);
131 labelItem->setPos(layout[i] + (delta)/2 - center.x(), chartRect.bottom() + label_padding);
129 132 }
130 133
131 if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) {
134 if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()> chartRect.right()) {
132 135 labelItem->setVisible(false);
133 136 }
134 137 else {
@@ -136,15 +139,12 void ChartBarCategoryAxisX::updateGeometry()
136 139 width=rect.width()+labelItem->pos().x();
137 140 }
138 141
139 m_minWidth+=rect.width();
140 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
141
142 142 if ((i+1)%2 && i>1) {
143 143 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
144 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
144 rectItem->setRect(layout[i-1], chartRect.top(),layout[i]-layout[i-1], chartRect.height());
145 145 }
146 146 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
147 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
147 lineItem->setLine(layout[i], chartRect.bottom(),layout[i], chartRect.bottom()+5);
148 148 }
149 149 }
150 150
@@ -158,4 +158,43 void ChartBarCategoryAxisX::handleAxisUpdated()
158 158 ChartAxis::handleAxisUpdated();
159 159 }
160 160
161 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
162 {
163 Q_UNUSED(constraint)
164
165 QFontMetrics fn(m_font);
166 QSizeF sh;
167 QSizeF base = ChartAxis::sizeHint(which, constraint);
168 QStringList ticksList = createCategoryLabels(ChartAxis::layout());
169 qreal width=0;
170 qreal height=0;
171
172 switch (which) {
173 case Qt::MinimumSize:
174 width = fn.boundingRect("...").width();
175 height = fn.height()+label_padding;
176 width=qMax(width,base.width());
177 height+=base.height();
178 sh = QSizeF(width,height);
179 break;
180 case Qt::PreferredSize:{
181
182 for (int i = 0; i < ticksList.size(); ++i)
183 {
184 QRectF rect = fn.boundingRect(ticksList.at(i));
185 width+=rect.width();
186 height=qMax(rect.height()+label_padding,height);
187 }
188 width=qMax(width,base.width());
189 height+=base.height();
190 sh = QSizeF(width,height);
191 break;
192 }
193 default:
194 break;
195 }
196
197 return sh;
198 }
199
161 200 QTCOMMERCIALCHART_END_NAMESPACE
@@ -45,7 +45,7 public:
45 45 ~ChartBarCategoryAxisX();
46 46
47 47 AxisType axisType() const { return X_AXIS;}
48
48 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
49 49 protected:
50 50 QVector<qreal> calculateLayout() const;
51 51 void updateGeometry();
@@ -22,6 +22,7
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include <qmath.h>
25 #include <QFontMetrics>
25 26 #include <QDebug>
26 27
27 28 static int label_padding = 5;
@@ -46,23 +47,25 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
46 47 QVector<qreal> points;
47 48 points.resize(count+2);
48 49
49 const qreal delta = m_rect.height()/(count);
50 QRectF rect = presenter()->chartsGeometry();
51
52 const qreal delta = rect.height()/(count);
50 53 qreal offset = - m_min - 0.5;
51 54
52 55 if(delta<1) return points;
53 56
54 57 if(offset<=0) {
55 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta) + delta;
58 offset = int(offset * rect.height()/(m_max - m_min))%int(delta) + delta;
56 59 }
57 60 else {
58 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta);
61 offset = int(offset * rect.height()/(m_max - m_min))%int(delta);
59 62 }
60 63
61 points[0] = m_rect.bottom();
62 points[count+1] = m_rect.top();
64 points[0] = rect.bottom();
65 points[count+1] = rect.top();
63 66
64 67 for (int i = 0; i < count; ++i) {
65 int y = m_rect.bottom() - i * delta - offset;
68 int y = rect.bottom() - i * delta - offset;
66 69 points[i+1] = y;
67 70 }
68 71 return points;
@@ -71,9 +74,10 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
71 74 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
72 75 {
73 76 QStringList result;
74 qreal d = (m_max - m_min)/m_rect.height();
77 QRectF rect = presenter()->chartsGeometry();
78 qreal d = (m_max - m_min)/rect.height();
75 79 for (int i = 0;i < layout.count()-1; ++i) {
76 qreal x = qFloor(((m_rect.height()- (layout[i+1] + layout[i])/2 + m_rect.top())*d + m_min+0.5));
80 qreal x = qFloor(((rect.height()- (layout[i+1] + layout[i])/2 + rect.top())*d + m_min+0.5));
77 81 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
78 82 result << m_categoriesAxis->categories().at(x);
79 83 }
@@ -90,9 +94,6 void ChartBarCategoryAxisY::updateGeometry()
90 94 {
91 95 const QVector<qreal>& layout = ChartAxis::layout();
92 96
93 m_minWidth = 0;
94 m_minHeight = 0;
95
96 97 if(layout.isEmpty()) return;
97 98
98 99 QStringList ticksList = createCategoryLabels(layout);
@@ -105,15 +106,17 void ChartBarCategoryAxisY::updateGeometry()
105 106 Q_ASSERT(labels.size() == ticksList.size());
106 107 Q_ASSERT(layout.size() == ticksList.size());
107 108
108 const qreal delta = m_rect.height()/(m_categoriesAxis->d_ptr->count());
109 QRectF chartRect = presenter()->chartsGeometry();
110
111 const qreal delta = chartRect.height()/(m_categoriesAxis->d_ptr->count());
109 112
110 113 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
111 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
114 lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
112 115
113 qreal height = m_rect.bottom();
116 qreal height = chartRect.bottom();
114 117 for (int i = 0; i < layout.size(); ++i) {
115 118 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
116 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
119 lineItem->setLine(chartRect.left() , layout[i], chartRect.right(), layout[i]);
117 120 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
118 121 labelItem->setText(ticksList.at(i));
119 122 const QRectF& rect = labelItem->boundingRect();
@@ -121,13 +124,13 void ChartBarCategoryAxisY::updateGeometry()
121 124 labelItem->setTransformOriginPoint(center.x(), center.y());
122 125
123 126 if(i==0) {
124 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
127 labelItem->setPos(chartRect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
125 128 }
126 129 else {
127 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
130 labelItem->setPos(chartRect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
128 131 }
129 132
130 if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) {
133 if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < chartRect.top()) {
131 134 labelItem->setVisible(false);
132 135 }
133 136 else {
@@ -135,15 +138,12 void ChartBarCategoryAxisY::updateGeometry()
135 138 height=labelItem->pos().y();
136 139 }
137 140
138 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
139 m_minHeight+=rect.height();
140
141 141 if ((i+1)%2 && i>1) {
142 142 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
143 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
143 rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
144 144 }
145 145 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
146 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
146 lineItem->setLine(chartRect.left()-5,layout[i],chartRect.left(),layout[i]);
147 147 }
148 148 }
149 149
@@ -160,4 +160,43 void ChartBarCategoryAxisY::handleAxisUpdated()
160 160 ChartAxis::handleAxisUpdated();
161 161 }
162 162
163 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
164 {
165 Q_UNUSED(constraint)
166
167 QFontMetrics fn(m_font);
168 QSizeF sh;
169 QSizeF base = ChartAxis::sizeHint(which, constraint);
170 QStringList ticksList = createCategoryLabels(ChartAxis::layout());
171 qreal width=0;
172 qreal height=0;
173
174 switch (which) {
175 case Qt::MinimumSize:
176 width = fn.boundingRect("...").width() + label_padding;
177 height = fn.height();
178 width+=base.width();
179 height=qMax(height,base.height());
180 sh = QSizeF(width,height);
181 break;
182 case Qt::PreferredSize:{
183
184 for (int i = 0; i < ticksList.size(); ++i)
185 {
186 QRectF rect = fn.boundingRect(ticksList.at(i));
187 height+=rect.height();
188 width=qMax(rect.width()+label_padding,width);
189 }
190 height=qMax(height,base.height());
191 width+=base.width();
192 sh = QSizeF(width,height);
193 break;
194 }
195 default:
196 break;
197 }
198
199 return sh;
200 }
201
163 202 QTCOMMERCIALCHART_END_NAMESPACE
@@ -45,7 +45,7 public:
45 45 ~ChartBarCategoryAxisY();
46 46
47 47 AxisType axisType() const { return Y_AXIS;}
48
48 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
49 49 protected:
50 50 QVector<qreal> calculateLayout() const;
51 51 void updateGeometry();
@@ -47,16 +47,18 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
47 47 if (tickCount < 2)
48 48 return points;
49 49
50 QRectF rect = presenter()->chartsGeometry();
51
50 52 qreal range = axis->max() - axis->min();
51 53 if (range > 0) {
52 54 points.resize(tickCount);
53 qreal scale = m_rect.width() / range;
55 qreal scale = rect.width() / range;
54 56 for (int i = 0; i < tickCount; ++i)
55 57 if (i < tickCount - 1) {
56 int x = (axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + m_rect.left();
58 int x = (axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + rect.left();
57 59 points[i] = x;
58 60 } else {
59 int x = (axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + m_rect.left();
61 int x = (axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + rect.left();
60 62 points[i] = x;
61 63 }
62 64 }
@@ -67,9 +69,6 void ChartCategoryAxisX::updateGeometry()
67 69 {
68 70 const QVector<qreal>& layout = ChartAxis::layout();
69 71
70 m_minWidth = 0;
71 m_minHeight = 0;
72
73 72 if(layout.isEmpty()) return;
74 73
75 74 QCategoryAxis *categoryAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
@@ -85,13 +84,14 void ChartCategoryAxisX::updateGeometry()
85 84 labels.at(i)->setVisible(false);
86 85 }
87 86
87 QRectF chartRect = presenter()->chartsGeometry();
88 88 // axis base line
89
89 90 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
90 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
91 lineItem->setLine(chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
91 92
92 93 for (int i = 0; i < layout.size(); ++i) {
93 94
94 // label items
95 95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
96 96 if (i < ticksList.count()) {
97 97 labelItem->setText(ticksList.at(i));
@@ -99,43 +99,42 void ChartCategoryAxisX::updateGeometry()
99 99 const QRectF& rect = labelItem->boundingRect();
100 100 QPointF center = rect.center();
101 101 labelItem->setTransformOriginPoint(center.x(), center.y());
102
102 103 if (i < layout.size() - 1) {
103 labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), m_rect.bottom() + label_padding);
104 labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), chartRect.bottom() + label_padding);
104 105 } else {
105 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
106 labelItem->setPos(layout[i] - center.x(), chartRect.bottom() + label_padding);
106 107 }
107 108
108 109 // check if the label should be shown
109 if (labelItem->pos().x() + center.x() < m_rect.left() || labelItem->pos().x() + center.x() > m_rect.right())
110 if (labelItem->pos().x() + center.x() < chartRect.left() || labelItem->pos().x() + center.x() > chartRect.right())
110 111 labelItem->setVisible(false);
111 112 else
112 113 labelItem->setVisible(true);
113 114
114 m_minWidth += rect.width();
115 m_minHeight = qMax(rect.height()+ label_padding, m_minHeight);
116
117 115 if ((i + 1) % 2 && i > 1) {
118 116 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i / 2 - 1));
119 rectItem->setRect(layout[i - 1],m_rect.top(),layout[i]-layout[i - 1],m_rect.height());
117 rectItem->setRect(layout[i - 1],chartRect.top(),layout[i]-layout[i - 1],chartRect.height());
120 118 }
121 119
122 120 // grid lines and axis line ticks
123 121 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
124 lineItem->setPos(layout[i], m_rect.top());
125 lineItem->setLine(0, 0, 0, m_rect.height());
122 lineItem->setPos(layout[i], chartRect.top());
123 lineItem->setLine(0, 0, 0, chartRect.height());
126 124
127 125 QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
128 tickLineItem->setPos(layout[i], m_rect.bottom());
126 tickLineItem->setPos(layout[i], chartRect.bottom());
129 127 tickLineItem->setLine(0, 0, 0, 5);
130 128
131 129 // check if the grid line and the axis tick should be shown
132 if (lineItem->pos().x() < m_rect.left() || lineItem->pos().x() > m_rect.right()) {
130 if (lineItem->pos().x() < chartRect.left() || lineItem->pos().x() > chartRect.right()) {
133 131 lineItem->setVisible(false);
134 132 tickLineItem->setVisible(false);
135 133 } else {
136 134 lineItem->setVisible(true);
137 135 tickLineItem->setVisible(true);
138 136 }
137
139 138 }
140 139
141 140 }
@@ -146,4 +145,43 void ChartCategoryAxisX::handleAxisUpdated()
146 145 ChartAxis::handleAxisUpdated();
147 146 }
148 147
148 QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
149 {
150 Q_UNUSED(constraint)
151
152 QFontMetrics fn(m_font);
153 QSizeF sh;
154 QSizeF base = ChartAxis::sizeHint(which, constraint);
155 QStringList ticksList ; //TODO:
156 qreal width=0;
157 qreal height=0;
158
159 switch (which) {
160 case Qt::MinimumSize:
161 width = fn.boundingRect("...").width();
162 height = fn.height() + label_padding;
163 width=qMax(width,base.width());
164 height+=base.height();
165 sh = QSizeF(width,height);
166 break;
167 case Qt::PreferredSize: {
168
169 for (int i = 0; i < ticksList.size(); ++i)
170 {
171 QRectF rect = fn.boundingRect(ticksList.at(i));
172 width+=rect.width();
173 height=qMax(rect.height()+label_padding,height);
174 }
175 width=qMax(width,base.width());
176 height+=base.height();
177 sh = QSizeF(width,height);
178 break;
179 }
180 default:
181 break;
182 }
183
184 return sh;
185 }
186
149 187 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartCategoryAxisX();
45 45
46 46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 QVector<qreal> calculateLayout() const;
50 50 void updateGeometry();
@@ -47,16 +47,18 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
47 47 if (tickCount < 2)
48 48 return points;
49 49
50 QRectF rect = presenter()->chartsGeometry();
51
50 52 qreal range = axis->max() - axis->min();
51 53 if (range > 0) {
52 54 points.resize(tickCount);
53 qreal scale = m_rect.height() / range;
55 qreal scale = rect.height() / range;
54 56 for (int i = 0; i < tickCount; ++i)
55 57 if (i < tickCount - 1) {
56 int y = -(axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + m_rect.bottom();
58 int y = -(axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + rect.bottom();
57 59 points[i] = y;
58 60 } else {
59 int y = -(axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + m_rect.bottom();
61 int y = -(axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + rect.bottom();
60 62 points[i] = y;
61 63 }
62 64 }
@@ -67,8 +69,6 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
67 69 void ChartCategoryAxisY::updateGeometry()
68 70 {
69 71 const QVector<qreal> &layout = ChartAxis::layout();
70 m_minWidth = 0;
71 m_minHeight = 0;
72 72
73 73 if(layout.isEmpty()) {
74 74 return;
@@ -88,9 +88,11 void ChartCategoryAxisY::updateGeometry()
88 88 labels.at(i)->setVisible(false);
89 89 }
90 90
91 QRectF chartRect = presenter()->chartsGeometry();
92
91 93 // axis base line
92 94 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
93 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
95 lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
94 96
95 97 for (int i = 0; i < layout.size(); ++i) {
96 98
@@ -104,13 +106,14 void ChartCategoryAxisY::updateGeometry()
104 106 QPointF center = rect.center();
105 107 labelItem->setTransformOriginPoint(center.x(), center.y());
106 108
109
107 110 if (i < layout.size() - 1)
108 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
111 labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
109 112 else
110 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
113 labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
111 114
112 115 // check if the label should be shown
113 if (labelItem->pos().y() + center.y() < m_rect.top() || labelItem->pos().y() + center.y() > m_rect.bottom())
116 if (labelItem->pos().y() + center.y() < chartRect.top() || labelItem->pos().y() + center.y() > chartRect.bottom())
114 117 labelItem->setVisible(false);
115 118 else
116 119 labelItem->setVisible(true);
@@ -123,31 +126,29 void ChartCategoryAxisY::updateGeometry()
123 126 // height=labelItem->pos().y();
124 127 // }
125 128
126 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
127 m_minHeight+=rect.height();
128
129 129 if ((i+1)%2 && i>1) {
130 130 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
131 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
131 rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
132 132 }
133 133
134 134 // grid lines and axis line ticks
135 135 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
136 lineItem->setPos(m_rect.left(), layout[i]);
137 lineItem->setLine(0, 0, m_rect.width(), 0);
136 lineItem->setPos(chartRect.left(), layout[i]);
137 lineItem->setLine(0, 0, chartRect.width(), 0);
138 138
139 139 QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
140 tickLineItem->setPos(m_rect.left(), layout[i]);
140 tickLineItem->setPos(chartRect.left(), layout[i]);
141 141 tickLineItem->setLine(-5, 0, 0, 0);
142 142
143 143 // check if the grid line and the axis tick should be shown
144 if (lineItem->pos().y() < m_rect.top() || lineItem->pos().y() > m_rect.bottom()) {
144 if (lineItem->pos().y() < chartRect.top() || lineItem->pos().y() > chartRect.bottom()) {
145 145 lineItem->setVisible(false);
146 146 tickLineItem->setVisible(false);
147 147 } else {
148 148 lineItem->setVisible(true);
149 149 tickLineItem->setVisible(true);
150 150 }
151
151 152 }
152 153
153 154 }
@@ -158,4 +159,43 void ChartCategoryAxisY::handleAxisUpdated()
158 159 ChartAxis::handleAxisUpdated();
159 160 }
160 161
162 QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
163 {
164 Q_UNUSED(constraint)
165
166 QFontMetrics fn(m_font);
167 QSizeF sh;
168 QSizeF base = ChartAxis::sizeHint(which, constraint);
169 QStringList ticksList; //TODO::
170 qreal width=0;
171 qreal height=0;
172
173 switch (which) {
174 case Qt::MinimumSize:
175 width = fn.boundingRect("...").width()+label_padding;
176 height = fn.height();
177 width=qMax(width,base.width());
178 height+=base.height();
179 sh = QSizeF(width,height);
180 break;
181 case Qt::PreferredSize:{
182
183 for (int i = 0; i < ticksList.size(); ++i)
184 {
185 QRectF rect = fn.boundingRect(ticksList.at(i));
186 height+=rect.height();
187 width=qMax(rect.width()+label_padding,width);
188 }
189 height=qMax(height,base.height());
190 width+=base.width();
191 sh = QSizeF(width,height);
192 break;
193 }
194 default:
195 break;
196 }
197
198 return sh;
199 }
200
161 201 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartCategoryAxisY();
45 45
46 46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 QVector<qreal> calculateLayout() const;
50 50 void updateGeometry();
@@ -27,6 +27,7
27 27 #include <QDateTime>
28 28 #include <QValueAxis>
29 29 #include <QGraphicsLayout>
30 #include <QFontMetrics>
30 31
31 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 33
@@ -37,11 +38,10 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : ChartEleme
37 38 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
38 39 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
39 40 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
41 m_title(new QGraphicsSimpleTextItem(presenter->rootItem())),
40 42 m_min(0),
41 43 m_max(0),
42 m_animation(0),
43 m_minWidth(0),
44 m_minHeight(0)
44 m_animation(0)
45 45 {
46 46 //initial initialization
47 47 m_arrow->setZValue(ChartPresenter::AxisZValue);
@@ -139,7 +139,6 void ChartAxis::updateLayout(QVector<qreal> &layout)
139 139 else {
140 140 setLayout(layout);
141 141 updateGeometry();
142 checkLayout();
143 142 }
144 143 }
145 144
@@ -231,7 +230,15 void ChartAxis::setLabelsFont(const QFont &font)
231 230 foreach(QGraphicsItem* item , m_labels->childItems()) {
232 231 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
233 232 }
234 m_font = font;
233 if(m_font!=font) {
234 m_font = font;
235 foreach(QGraphicsItem* item , m_labels->childItems()) {
236 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
237 }
238 QGraphicsLayoutItem::updateGeometry();
239 presenter()->layout()->invalidate();
240
241 }
235 242 }
236 243
237 244 void ChartAxis::setShadesBrush(const QBrush &brush)
@@ -264,7 +271,7 void ChartAxis::setGridPen(const QPen &pen)
264 271
265 272 bool ChartAxis::isEmpty()
266 273 {
267 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
274 return !m_rect.isValid() || presenter()->chartsGeometry().isEmpty() || qFuzzyIsNull(m_min - m_max);
268 275 }
269 276
270 277 void ChartAxis::handleDomainUpdated()
@@ -289,8 +296,20 void ChartAxis::handleDomainUpdated()
289 296 m_max = max;
290 297
291 298 if (!isEmpty()) {
299
292 300 QVector<qreal> layout = calculateLayout();
293 301 updateLayout(layout);
302 QSizeF before = effectiveSizeHint(Qt::MinimumSize);
303
304 QSizeF after= sizeHint(Qt::MinimumSize);
305
306 if(before!=after) {
307 QGraphicsLayoutItem::updateGeometry();
308 //we don't want to call invalidate on layout, since it will change minimum size of component,
309 //which we would like to avoid since it causes nasty flips when scrolling or zooming,
310 //instead recalculate layout and use plotArea for extra space.
311 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
312 }
294 313 }
295 314 }
296 315 }
@@ -314,7 +333,17 void ChartAxis::handleAxisUpdated()
314 333 setGridPen(m_chartAxis->gridLinePen());
315 334 setShadesPen(m_chartAxis->shadesPen());
316 335 setShadesBrush(m_chartAxis->shadesBrush());
336 setTitleText(m_chartAxis->title());
337 }
317 338
339 void ChartAxis::setTitleText(const QString& title)
340 {
341 if(m_titleText!=title) {
342 m_titleText = title;
343 m_rect = QRect();
344 QGraphicsLayoutItem::updateGeometry();
345 presenter()->layout()->invalidate();
346 }
318 347 }
319 348
320 349 void ChartAxis::hide()
@@ -325,42 +354,64 void ChartAxis::hide()
325 354 setShadesVisibility(false);
326 355 }
327 356
328 void ChartAxis::handleGeometryChanged(const QRectF &rect)
357 void ChartAxis::setGeometry(const QRectF &rect)
329 358 {
330 if(m_rect != rect)
331 {
359
332 360 m_rect = rect;
361
333 362 if (isEmpty()) return;
363
364 if(!m_titleText.isNull()) {
365 QFontMetrics fn(m_title->font());
366
367 int size(0);
368
369 QRectF chartRect = presenter()->chartsGeometry();
370
371 if(orientation()==Qt::Horizontal)
372 size = chartRect.width();
373 else if(orientation()==Qt::Vertical)
374 size = chartRect.height();
375
376 if (fn.boundingRect(m_titleText).width() > size)
377 {
378 QString string = m_titleText + "...";
379 while (fn.boundingRect(string).width() > size && string.length() > 3)
380 string.remove(string.length() - 4, 1);
381 m_title->setText(string);
382 }
383 else
384 m_title->setText(m_titleText);
385
386 QPointF center = chartRect.center() - m_title->boundingRect().center();
387 if(orientation()==Qt::Horizontal) {
388 m_title->setPos(center.x(),m_rect.bottom()-m_title->boundingRect().height());
389 }
390 else if(orientation()==Qt::Vertical) {
391 m_title->setTransformOriginPoint(m_title->boundingRect().center());
392 m_title->setRotation(270);
393 m_title->setPos(m_rect.left()- m_title->boundingRect().width()/2+m_title->boundingRect().height()/2,center.y());
394 }
395 }
396
334 397 QVector<qreal> layout = calculateLayout();
335 398 updateLayout(layout);
336 }
337 }
338
339 399
340 qreal ChartAxis::minimumWidth()
341 {
342 if(m_minWidth == 0) updateGeometry();
343 return m_minWidth;
344 400 }
345 401
346 qreal ChartAxis::minimumHeight()
347 {
348 if(m_minHeight == 0) updateGeometry();
349 return m_minHeight;
350 }
351
352
353 402 void ChartAxis::axisSelected()
354 403 {
355 qDebug()<<"TODO: axis clicked";
404 //TODO: axis clicked;
356 405 }
357 406
358 407
359 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
408 QStringList ChartAxis::createNumberLabels(qreal min, qreal max, int ticks) const
360 409 {
361 410 Q_ASSERT(max>min);
362 411 Q_ASSERT(ticks>1);
363 412
413 QStringList labels;
414
364 415 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
365 416 n++;
366 417
@@ -381,17 +432,54 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int
381 432 labels << QString().sprintf(array, value);
382 433 }
383 434 }
435
436 return labels;
384 437 }
385 438
386 void ChartAxis::checkLayout()
439 Qt::Orientation ChartAxis::orientation() const
387 440 {
388 if(m_minWidth > m_rect.width()) {
389 presenter()->layout()->invalidate();
390 }
441 return m_chartAxis->orientation();
442 }
391 443
392 if(m_minHeight > m_rect.height()) {
393 presenter()->layout()->invalidate();
444 bool ChartAxis::isVisible()
445 {
446 return m_chartAxis->isVisible();
447 }
448
449 QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
450 {
451
452 Q_UNUSED(constraint);
453 QFontMetrics fn(m_title->font());
454 QSizeF sh;
455
456 if(m_titleText.isNull()) return sh;
457
458 switch(which) {
459 case Qt::MinimumSize:
460 if(orientation()==Qt::Horizontal) {
461 sh = QSizeF(fn.boundingRect ("...").width(),fn.height());
462 }
463 else if(orientation()==Qt::Vertical) {
464 sh = QSizeF(fn.height(),fn.boundingRect ("...").width());
465 }
466
467 break;
468 case Qt::MaximumSize:
469 case Qt::PreferredSize:
470 if(orientation()==Qt::Horizontal) {
471 sh = QSizeF(fn.boundingRect(m_chartAxis->title()).width(),fn.height());
472 }
473 else if(orientation()==Qt::Vertical) {
474 sh = QSizeF(fn.height(),fn.boundingRect(m_chartAxis->title()).width());
475 }
476
477 break;
478 default:
479 break;
394 480 }
481
482 return sh;
395 483 }
396 484
397 485 #include "moc_chartaxis_p.cpp"
@@ -34,6 +34,7
34 34 #include "chartelement_p.h"
35 35 #include "axisanimation_p.h"
36 36 #include <QGraphicsItem>
37 #include <QGraphicsLayoutItem>
37 38 #include <QFont>
38 39
39 40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -41,9 +42,10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 42 class QAbstractAxis;
42 43 class ChartPresenter;
43 44
44 class ChartAxis : public ChartElement
45 class ChartAxis : public ChartElement, public QGraphicsLayoutItem
45 46 {
46 47 Q_OBJECT
48 Q_INTERFACES(QGraphicsLayoutItem)
47 49 public:
48 50 enum AxisType{ X_AXIS,Y_AXIS };
49 51
@@ -81,29 +83,38 public:
81 83 void setLabelsBrush(const QBrush &brush);
82 84 void setLabelsFont(const QFont &font);
83 85
86 void setTitlePen(const QPen &pen);
87 void setTitleBrush(const QBrush &brush);
88 void setTitleFont(const QFont &font);
89 void setTitleText(const QString& title);
90
91
84 92 void setLayout(QVector<qreal> &layout);
85 93 QVector<qreal> layout() const { return m_layoutVector; }
86 94
87 95 void setAnimation(AxisAnimation* animation);
88 96 ChartAnimation* animation() const { return m_animation; };
89 97
90 QRectF geometry() const { return m_rect; }
91
92 qreal minimumWidth();
93 qreal minimumHeight();
98 Qt::Orientation orientation() const;
94 99
100 bool isVisible();
95 101 void hide();
96 102
103 void setGeometry(const QRectF &size);
104 QRectF geometry() const { return m_rect; }
105
106 virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const;
107
97 108 protected:
98 109 virtual void updateGeometry() = 0;
99 110 virtual QVector<qreal> calculateLayout() const = 0;
100 void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
101 void checkLayout();
111 QStringList createNumberLabels(qreal min, qreal max,int ticks) const;
112
102 113
103 114 public Q_SLOTS:
104 115 virtual void handleAxisUpdated();
105 116 virtual void handleDomainUpdated();
106 void handleGeometryChanged(const QRectF &size);
117
107 118
108 119 private:
109 120 inline bool isEmpty();
@@ -114,19 +125,20 private:
114 125
115 126 protected:
116 127 QAbstractAxis* m_chartAxis;
117 QRectF m_rect;
118 128 int m_labelsAngle;
129 //TODO: to be removed
130 QRectF m_rect;
119 131 QScopedPointer<QGraphicsItemGroup> m_grid;
120 132 QScopedPointer<QGraphicsItemGroup> m_shades;
121 133 QScopedPointer<QGraphicsItemGroup> m_labels;
122 134 QScopedPointer<QGraphicsItemGroup> m_arrow;
135 QGraphicsSimpleTextItem* m_title;
123 136 QVector<qreal> m_layoutVector;
124 137 qreal m_min;
125 138 qreal m_max;
126 139 AxisAnimation *m_animation;
127 qreal m_minWidth;
128 qreal m_minHeight;
129 140 QFont m_font;
141 QString m_titleText;
130 142
131 143 friend class AxisAnimation;
132 144 friend class AxisItem;
@@ -61,10 +61,10 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
61 61
62 62 QVector<qreal> points;
63 63 points.resize(m_tickCount);
64
65 const qreal deltaX = m_rect.width()/(m_tickCount-1);
64 QRectF rect = presenter()->chartsGeometry();
65 const qreal deltaX = rect.width()/(m_tickCount-1);
66 66 for (int i = 0; i < m_tickCount; ++i) {
67 int x = i * deltaX + m_rect.left();
67 int x = i * deltaX + rect.left();
68 68 points[i] = x;
69 69 }
70 70 return points;
@@ -74,9 +74,6 void ChartDateTimeAxisX::updateGeometry()
74 74 {
75 75 const QVector<qreal>& layout = ChartAxis::layout();
76 76
77 m_minWidth = 0;
78 m_minHeight = 0;
79
80 77 if(layout.isEmpty()) return;
81 78
82 79 QStringList ticksList;
@@ -91,19 +88,21 void ChartDateTimeAxisX::updateGeometry()
91 88 Q_ASSERT(labels.size() == ticksList.size());
92 89 Q_ASSERT(layout.size() == ticksList.size());
93 90
91 QRectF chartRect = presenter()->chartsGeometry();
92
94 93 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
95 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
94 lineItem->setLine(chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
96 95
97 96 qreal width = 0;
98 97 for (int i = 0; i < layout.size(); ++i) {
99 98 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
100 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
99 lineItem->setLine(layout[i], chartRect.top(), layout[i], chartRect.bottom());
101 100 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
102 101 labelItem->setText(ticksList.at(i));
103 102 const QRectF& rect = labelItem->boundingRect();
104 103 QPointF center = rect.center();
105 104 labelItem->setTransformOriginPoint(center.x(), center.y());
106 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
105 labelItem->setPos(layout[i] - center.x(), chartRect.bottom() + label_padding);
107 106
108 107 if(labelItem->pos().x()<=width){
109 108 labelItem->setVisible(false);
@@ -113,15 +112,13 void ChartDateTimeAxisX::updateGeometry()
113 112 lineItem->setVisible(true);
114 113 width=rect.width()+labelItem->pos().x();
115 114 }
116 m_minWidth+=rect.width();
117 m_minHeight=qMax(rect.height(),m_minHeight);
118 115
119 116 if ((i+1)%2 && i>1) {
120 117 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
121 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
118 rectItem->setRect(layout[i-1],chartRect.top(),layout[i]-layout[i-1],chartRect.height());
122 119 }
123 120 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
124 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
121 lineItem->setLine(layout[i],chartRect.bottom(),layout[i],chartRect.bottom()+5);
125 122 }
126 123 }
127 124
@@ -133,4 +130,41 void ChartDateTimeAxisX::handleAxisUpdated()
133 130 ChartAxis::handleAxisUpdated();
134 131 }
135 132
133 QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
134 {
135 Q_UNUSED(constraint)
136
137 QFontMetrics fn(m_font);
138 QSizeF sh;
139
140 switch (which) {
141 case Qt::MinimumSize:
142 sh = QSizeF(fn.boundingRect("...").width(),fn.height());
143 break;
144 case Qt::PreferredSize:{
145
146 const QVector<qreal>& layout = ChartAxis::layout();
147 if(layout.isEmpty()) break;
148 QStringList ticksList;
149
150
151 qreal width=0;
152 qreal height=0;
153
154 for (int i = 0; i < ticksList.size(); ++i)
155 {
156 QRectF rect = fn.boundingRect(ticksList.at(i));
157 width+=rect.width();
158 height+=qMax(rect.height()+label_padding,height);
159 }
160 sh = QSizeF(width,height);
161 break;
162 }
163 default:
164 break;
165 }
166
167 return sh;
168 }
169
136 170 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartDateTimeAxisX();
45 45
46 46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
50 50 void handleAxisUpdated();
@@ -61,10 +61,10 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
61 61
62 62 QVector<qreal> points;
63 63 points.resize(m_tickCount);
64
65 const qreal deltaY = m_rect.height()/(m_tickCount-1);
64 QRectF rect = presenter()->chartsGeometry();
65 const qreal deltaY = rect.height()/(m_tickCount-1);
66 66 for (int i = 0; i < m_tickCount; ++i) {
67 int y = i * -deltaY + m_rect.bottom();
67 int y = i * -deltaY + rect.bottom();
68 68 points[i] = y;
69 69 }
70 70
@@ -74,8 +74,6 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
74 74 void ChartDateTimeAxisY::updateGeometry()
75 75 {
76 76 const QVector<qreal> &layout = ChartAxis::layout();
77 m_minWidth = 0;
78 m_minHeight = 0;
79 77
80 78 if(layout.isEmpty()) return;
81 79
@@ -91,14 +89,16 void ChartDateTimeAxisY::updateGeometry()
91 89 Q_ASSERT(labels.size() == ticksList.size());
92 90 Q_ASSERT(layout.size() == ticksList.size());
93 91
94 qreal height = 2*m_rect.bottom();
92 QRectF chartRect = presenter()->chartsGeometry();
93
94 qreal height = chartRect.bottom();
95 95
96 96 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
97 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
97 lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
98 98
99 99 for (int i = 0; i < layout.size(); ++i) {
100 100 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
101 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
101 lineItem->setLine(chartRect.left() , layout[i], chartRect.right(), layout[i]);
102 102 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
103 103
104 104 labelItem->setText(ticksList.at(i));
@@ -106,7 +106,7 void ChartDateTimeAxisY::updateGeometry()
106 106
107 107 QPointF center = rect.center();
108 108 labelItem->setTransformOriginPoint(center.x(), center.y());
109 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
109 labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
110 110
111 111 if(labelItem->pos().y()+rect.height()>height) {
112 112 labelItem->setVisible(false);
@@ -118,15 +118,12 void ChartDateTimeAxisY::updateGeometry()
118 118 height=labelItem->pos().y();
119 119 }
120 120
121 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
122 m_minHeight+=rect.height();
123
124 121 if ((i+1)%2 && i>1) {
125 122 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
126 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
123 rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
127 124 }
128 125 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
129 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
126 lineItem->setLine(chartRect.left()-5,layout[i],chartRect.left(),layout[i]);
130 127 }
131 128 }
132 129
@@ -138,5 +135,41 void ChartDateTimeAxisY::handleAxisUpdated()
138 135 ChartAxis::handleAxisUpdated();
139 136 }
140 137
138 QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
139 {
140 Q_UNUSED(constraint)
141
142 QFontMetrics fn(m_font);
143 QSizeF sh;
144
145 switch (which) {
146 case Qt::MinimumSize:
147 sh = QSizeF(fn.boundingRect("...").width(),fn.height());
148 break;
149 case Qt::PreferredSize:{
150
151 const QVector<qreal>& layout = ChartAxis::layout();
152 if(layout.isEmpty()) break;
153 QStringList ticksList;
154
155
156 qreal width=0;
157 qreal height=0;
158
159 for (int i = 0; i < ticksList.size(); ++i)
160 {
161 QRectF rect = fn.boundingRect(ticksList.at(i));
162 width+=rect.width();
163 height+=qMax(rect.height()+label_padding,height);
164 }
165 sh = QSizeF(width,height);
166 break;
167 }
168 default:
169 break;
170 }
171
172 return sh;
173 }
141 174
142 175 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartDateTimeAxisY();
45 45
46 46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
50 50 QVector<qreal> calculateLayout() const;
@@ -458,6 +458,90 QColor QAbstractAxis::labelsColor() const
458 458 return d_ptr->m_labelsBrush.color();
459 459 }
460 460
461 void QAbstractAxis::setTitleVisible(bool visible)
462 {
463 if (d_ptr->m_titleVisible != visible) {
464 d_ptr->m_titleVisible = visible;
465 d_ptr->emitUpdated();
466 }
467 }
468
469 bool QAbstractAxis::titleVisible() const
470 {
471 return d_ptr->m_titleVisible;
472 }
473
474 /*!
475 Sets \a pen used to draw title.
476 */
477 void QAbstractAxis::setTitlePen(const QPen &pen)
478 {
479 if (d_ptr->m_titlePen != pen) {
480 d_ptr->m_titlePen = pen;
481 d_ptr->emitUpdated();
482 }
483 }
484
485 /*!
486 Returns the pen used to title.
487 */
488 QPen QAbstractAxis::titlePen() const
489 {
490 return d_ptr->m_titlePen;
491 }
492
493 /*!
494 Sets \a brush used to draw title.
495 */
496 void QAbstractAxis::setTitleBrush(const QBrush &brush)
497 {
498 if (d_ptr->m_titleBrush != brush) {
499 d_ptr->m_titleBrush = brush;
500 d_ptr->emitUpdated();
501 }
502 }
503
504 /*!
505 Returns brush used to draw title.
506 */
507 QBrush QAbstractAxis::titleBrush() const
508 {
509 return d_ptr->m_titleBrush;
510 }
511
512 /*!
513 Sets \a font used to draw title.
514 */
515 void QAbstractAxis::setTitleFont(const QFont &font)
516 {
517 if (d_ptr->m_titleFont != font) {
518 d_ptr->m_titleFont = font;
519 d_ptr->emitUpdated();
520 }
521 }
522
523 /*!
524 Returns font used to draw title.
525 */
526 QFont QAbstractAxis::titleFont() const
527 {
528 return d_ptr->m_titleFont;
529 }
530
531 void QAbstractAxis::setTitle(const QString& title)
532 {
533 if (d_ptr->m_title != title) {
534 d_ptr->m_title = title;
535 d_ptr->emitUpdated();
536 }
537 }
538
539 QString QAbstractAxis::title() const
540 {
541 return d_ptr->m_title;
542 }
543
544
461 545 void QAbstractAxis::setShadesVisible(bool visible)
462 546 {
463 547 if (d_ptr->m_shadesVisible != visible) {
@@ -98,6 +98,19 public:
98 98 void setLabelsColor(QColor color);
99 99 QColor labelsColor() const;
100 100
101 //title handling
102 bool titleVisible() const;
103 void setTitleVisible(bool visible = true);
104 void setTitlePen(const QPen &pen);
105 QPen titlePen() const;
106 void setTitleBrush(const QBrush &brush);
107 QBrush titleBrush() const;
108 void setTitleFont(const QFont &font);
109 QFont titleFont() const;
110 void setTitle(const QString& title);
111 QString title() const;
112
113
101 114 //shades handling
102 115 bool shadesVisible() const;
103 116 void setShadesVisible(bool visible = true);
@@ -94,6 +94,12 private:
94 94 QFont m_labelsFont;
95 95 int m_labelsAngle;
96 96
97 bool m_titleVisible;
98 QPen m_titlePen;
99 QBrush m_titleBrush;
100 QFont m_titleFont;
101 QString m_title;
102
97 103 bool m_shadesVisible;
98 104 QPen m_shadesPen;
99 105 QBrush m_shadesBrush;
@@ -25,6 +25,7
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 #include <QDebug>
28 29
29 30 static int label_padding = 5;
30 31
@@ -46,9 +47,11 QVector<qreal> ChartValueAxisX::calculateLayout() const
46 47 QVector<qreal> points;
47 48 points.resize(m_tickCount);
48 49
49 const qreal deltaX = m_rect.width()/(m_tickCount-1);
50 QRectF rect = presenter()->chartsGeometry();
51
52 const qreal deltaX = rect.width()/(m_tickCount-1);
50 53 for (int i = 0; i < m_tickCount; ++i) {
51 int x = i * deltaX + m_rect.left();
54 int x = i * deltaX + rect.left();
52 55 points[i] = x;
53 56 }
54 57 return points;
@@ -58,14 +61,9 void ChartValueAxisX::updateGeometry()
58 61 {
59 62 const QVector<qreal>& layout = ChartAxis::layout();
60 63
61 m_minWidth = 0;
62 m_minHeight = 0;
63
64 64 if(layout.isEmpty()) return;
65 65
66 QStringList ticksList;
67
68 createNumberLabels(ticksList,m_min,m_max,layout.size());
66 QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
69 67
70 68 QList<QGraphicsItem *> lines = m_grid->childItems();
71 69 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,21 +73,24 void ChartValueAxisX::updateGeometry()
75 73 Q_ASSERT(labels.size() == ticksList.size());
76 74 Q_ASSERT(layout.size() == ticksList.size());
77 75
76 QRectF chartRrect = presenter()->chartsGeometry();
77
78 78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
79 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
79 lineItem->setLine(chartRrect.left(), chartRrect.bottom(), chartRrect.right(), chartRrect.bottom());
80 80
81 81 qreal width = 0;
82 82 for (int i = 0; i < layout.size(); ++i) {
83 83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
84 lineItem->setLine(layout[i], chartRrect.top(), layout[i], chartRrect.bottom());
85 85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 86 labelItem->setText(ticksList.at(i));
87 87 const QRectF& rect = labelItem->boundingRect();
88 88 QPointF center = rect.center();
89 89 labelItem->setTransformOriginPoint(center.x(), center.y());
90 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
91
92 if(labelItem->pos().x()<=width){
90 labelItem->setPos(layout[i] - center.x(), chartRrect.bottom() + label_padding);
91 if(labelItem->pos().x() <= width ||
92 labelItem->pos().x() < m_rect.left() ||
93 labelItem->pos().x() + rect.width() > m_rect.right()){
93 94 labelItem->setVisible(false);
94 95 lineItem->setVisible(false);
95 96 }else{
@@ -97,17 +98,14 void ChartValueAxisX::updateGeometry()
97 98 lineItem->setVisible(true);
98 99 width=rect.width()+labelItem->pos().x();
99 100 }
100 m_minWidth+=rect.width();
101 m_minHeight=qMax(rect.height(),m_minHeight);
102 101
103 102 if ((i+1)%2 && i>1) {
104 103 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
105 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
104 rectItem->setRect(layout[i-1],chartRrect.top(),layout[i]-layout[i-1],chartRrect.height());
106 105 }
107 106 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
108 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
107 lineItem->setLine(layout[i],chartRrect.bottom(),layout[i],chartRrect.bottom()+5);
109 108 }
110
111 109 }
112 110
113 111 void ChartValueAxisX::handleAxisUpdated()
@@ -118,4 +116,45 void ChartValueAxisX::handleAxisUpdated()
118 116 ChartAxis::handleAxisUpdated();
119 117 }
120 118
119 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
120 {
121 Q_UNUSED(constraint)
122
123 QFontMetrics fn(m_font);
124 QSizeF sh;
125
126 QSizeF base = ChartAxis::sizeHint(which, constraint);
127 QStringList ticksList = createNumberLabels(m_min,m_max,m_tickCount);
128 qreal width=0;
129 qreal height=0;
130
131 switch (which) {
132 case Qt::MinimumSize:{
133 int count = qMax(ticksList.last().count(),ticksList.first().count());
134 width=fn.averageCharWidth()*count;
135 height=fn.height()+label_padding;
136 width=qMax(width,base.width());
137 height+=base.height();
138 sh = QSizeF(width,height);
139 break;
140 }
141 case Qt::PreferredSize:{
142 for (int i = 0; i < ticksList.size(); ++i)
143 {
144 width+=fn.averageCharWidth()*ticksList.at(i).count();
145
146 }
147 height=fn.height()+label_padding;
148 width=qMax(width,base.width());
149 height+=base.height();
150 sh = QSizeF(width,height);
151 break;
152 }
153 default:
154 break;
155 }
156
157 return sh;
158 }
159
121 160 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartValueAxisX();
45 45
46 46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 void handleAxisUpdated();
50 50 QVector<qreal> calculateLayout() const;
@@ -25,6 +25,7
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 #include <QDebug>
28 29
29 30 static int label_padding = 5;
30 31
@@ -46,9 +47,11 QVector<qreal> ChartValueAxisY::calculateLayout() const
46 47 QVector<qreal> points;
47 48 points.resize(m_tickCount);
48 49
49 const qreal deltaY = m_rect.height()/(m_tickCount-1);
50 QRectF rect = presenter()->chartsGeometry();
51
52 const qreal deltaY = rect.height()/(m_tickCount-1);
50 53 for (int i = 0; i < m_tickCount; ++i) {
51 int y = i * -deltaY + m_rect.bottom();
54 int y = i * -deltaY + rect.bottom();
52 55 points[i] = y;
53 56 }
54 57
@@ -58,14 +61,10 QVector<qreal> ChartValueAxisY::calculateLayout() const
58 61 void ChartValueAxisY::updateGeometry()
59 62 {
60 63 const QVector<qreal> &layout = ChartAxis::layout();
61 m_minWidth = 0;
62 m_minHeight = 0;
63 64
64 65 if(layout.isEmpty()) return;
65 66
66 QStringList ticksList;
67
68 createNumberLabels(ticksList,m_min,m_max,layout.size());
67 QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
69 68
70 69 QList<QGraphicsItem *> lines = m_grid->childItems();
71 70 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,44 +74,55 void ChartValueAxisY::updateGeometry()
75 74 Q_ASSERT(labels.size() == ticksList.size());
76 75 Q_ASSERT(layout.size() == ticksList.size());
77 76
78 qreal height = 2*m_rect.bottom();
77 QRectF chartRect = presenter()->chartsGeometry();
78
79 qreal height = m_rect.bottom();
79 80
80 81 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
81 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
82 lineItem->setLine( chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
83
84 QFontMetrics fn(m_font);
82 85
83 86 for (int i = 0; i < layout.size(); ++i) {
84 87 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
85 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
88 lineItem->setLine( chartRect.left() , layout[i], chartRect.right(), layout[i]);
86 89 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
87 90
88 labelItem->setText(ticksList.at(i));
91 QString text = ticksList.at(i);
92
93 if (fn.boundingRect(text).width() > chartRect.left() - m_rect.left() - label_padding )
94 {
95 QString label = text + "...";
96 while (fn.boundingRect(label).width() > chartRect.left() - m_rect.left() - label_padding && label.length() > 3)
97 label.remove(label.length() - 4, 1);
98 labelItem->setText(label);
99 }else{
100 labelItem->setText(text);
101 }
102
89 103 const QRectF& rect = labelItem->boundingRect();
90 104
91 105 QPointF center = rect.center();
92 106 labelItem->setTransformOriginPoint(center.x(), center.y());
93 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
107 labelItem->setPos( chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
94 108
95 if(labelItem->pos().y()+rect.height()>height) {
109 if(labelItem->pos().y() + rect.height() > height ||
110 labelItem->pos().y() < m_rect.top()) {
96 111 labelItem->setVisible(false);
97 112 lineItem->setVisible(false);
98 }
99 else {
113 }else{
100 114 labelItem->setVisible(true);
101 115 lineItem->setVisible(true);
102 116 height=labelItem->pos().y();
103 117 }
104 118
105 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
106 m_minHeight+=rect.height();
107
108 119 if ((i+1)%2 && i>1) {
109 120 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
110 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
121 rectItem->setRect( chartRect.left(),layout[i], chartRect.width(),layout[i-1]-layout[i]);
111 122 }
112 123 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
113 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
124 lineItem->setLine( chartRect.left()-5,layout[i], chartRect.left(),layout[i]);
114 125 }
115
116 126 }
117 127
118 128 void ChartValueAxisY::handleAxisUpdated()
@@ -123,5 +133,43 void ChartValueAxisY::handleAxisUpdated()
123 133 ChartAxis::handleAxisUpdated();
124 134 }
125 135
136 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
137 {
138 Q_UNUSED(constraint)
139
140 QFontMetrics fn(m_font);
141 QSizeF sh;
142 QSizeF base = ChartAxis::sizeHint(which, constraint);
143 QStringList ticksList = createNumberLabels(m_min,m_max,m_tickCount);
144 qreal width=0;
145 qreal height=0;
146
147 switch (which) {
148 case Qt::MinimumSize: {
149 int count = qMax(ticksList.first().count() , ticksList.last().count());
150 width=fn.averageCharWidth()*count+label_padding;
151 height=fn.height();
152 height=qMax(height,base.height());
153 width+=base.width();
154 sh = QSizeF(width,height);
155 break;
156 }
157 case Qt::PreferredSize:
158 {
159 for (int i = 0; i < ticksList.size(); ++i)
160 {
161 width=qMax(qreal(fn.averageCharWidth()*ticksList.at(i).count())+label_padding,width);
162 height+=fn.height();
163 }
164 height=qMax(height,base.height());
165 width+=base.width();
166 sh = QSizeF(width,height);
167 break;
168 }
169 default:
170 break;
171 }
172 return sh;
173 }
126 174
127 175 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 44 ~ChartValueAxisY();
45 45
46 46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 48 protected:
49 49 QVector<qreal> calculateLayout() const;
50 50 void updateGeometry();
@@ -50,7 +50,6 public:
50 50 protected:
51 51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 52
53
54 53 private:
55 54 int roundness(qreal size) const;
56 55
@@ -22,17 +22,20
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxis_p.h"
25 #include "charttitle_p.h"
26 #include "chartbackground_p.h"
27 #include "layoutdebuger_p.h"
28 #include "legendmarker_p.h"
25 29 #include <QDebug>
26 30
27 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 32
33 static const qreal golden_ratio = 0.25;
34
29 35 ChartLayout::ChartLayout(ChartPresenter* presenter):
30 36 m_presenter(presenter),
31 m_marginBig(60),
32 m_marginSmall(20),
33 m_marginTiny(10),
34 m_chartMargins(m_marginBig,m_marginBig,m_marginBig,m_marginBig),
35 m_intialized(false)
37 m_margins(20,20,20,20),
38 m_minChartRect(0,0,200,200)
36 39 {
37 40
38 41 }
@@ -44,137 +47,213 ChartLayout::~ChartLayout()
44 47
45 48 void ChartLayout::setGeometry(const QRectF& rect)
46 49 {
50 Q_ASSERT(rect.isValid());
47 51
48 if (!rect.isValid()) return;
52 QList<ChartAxis*> axes = m_presenter->axisItems();
53 ChartTitle* title = m_presenter->titleElement();
54 QLegend* legend = m_presenter->legend();
55 ChartBackground* background = m_presenter->backgroundElement();
49 56
50 QGraphicsLayout::setGeometry(rect);
57 QRectF contentGeometry = calculateBackgroundGeometry(rect,background);
51 58
52 if(!m_intialized){
53 m_presenter->setGeometry(rect);
54 m_intialized=true;
55 }
59 contentGeometry = calculateContentGeometry(contentGeometry);
56 60
57 // check title size
61 if (title && title->isVisible()) {
62 contentGeometry = calculateTitleGeometry(contentGeometry,title);
63 }
58 64
59 QSize titleSize = QSize(0,0);
65 if (legend->isAttachedToChart() && legend->isVisible()) {
66 contentGeometry = calculateLegendGeometry(contentGeometry,legend);
67 }
60 68
61 if (m_presenter->titleItem()) {
62 titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
69 calculateChartGeometry(contentGeometry,axes);
70
71 //TODO remove me
72 #ifdef SHOW_LAYOUT
73 LayoutDebuger* debuger = LayoutDebuger::instance();
74 debuger->reset();
75 debuger->setPen(QPen(Qt::red));
76 debuger->add(backgroundGeometry,m_presenter->rootItem());
77 debuger->add(titleGeometry,m_presenter->rootItem());
78 debuger->add(legendGeometry ,m_presenter->rootItem());
79 debuger->add(axisGeometry ,m_presenter->rootItem());
80 debuger->add(geometry,m_presenter->rootItem());
81 foreach(LegendMarker* marker,legend->d_ptr->markers()){
82 debuger->add(marker->mapRectToScene(marker->boundingRect()),m_presenter->rootItem());
63 83 }
84 #endif
85
86 QGraphicsLayout::setGeometry(rect);
87 }
88
89 QRectF ChartLayout::calculateContentGeometry(const QRectF& geometry) const
90 {
91 return geometry.adjusted(m_margins.left(),m_margins.top(),-m_margins.right(),-m_margins.bottom());
92 }
93
94 QRectF ChartLayout::calculateContentMinimum(const QRectF& minimum) const
95 {
96 return minimum.adjusted(0,0,m_margins.left()+m_margins.right(),m_margins.top() + m_margins.bottom());
97 }
64 98
65 qreal axisHeight = 0;
66 qreal axisWidth = 0;
99
100 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const
101 {
102 qreal left, top, right, bottom;
103 getContentsMargins(&left, &top, &right, &bottom);
104 QRectF backgroundGeometry = geometry.adjusted(left,top,-right,-bottom);
105 if(background) background->setRect(backgroundGeometry);
106 return backgroundGeometry;
107 }
108
109 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF& minimum) const
110 {
111 qreal left, top, right, bottom;
112 getContentsMargins(&left, &top, &right, &bottom);
113 return minimum.adjusted(0,0,left + right,top+bottom);
114 }
115
116 QRectF ChartLayout::calculateChartGeometry(const QRectF& geometry, const QList<ChartAxis*>& axes) const
117 {
118
119 QSizeF vertical(0,0);
120 QSizeF horizontal(0,0);
67 121
68 122 // check axis size
123 foreach(ChartAxis* axis , axes) {
124 if(axis->orientation()==Qt::Vertical && axis->isVisible()) {
125 vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
126 }
127 else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
128 horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
129 }
69 130
70 foreach (ChartAxis* axis,m_presenter->axisItems()){
71 if(axis->axisType() == ChartAxis::X_AXIS)
72 axisHeight = qMax(axis->minimumHeight(),axisHeight);
73 else
74 axisWidth = qMax(axis->minimumWidth(),axisWidth);
75 131 }
76 132
77 QLegend* legend = m_presenter->legend();
78 Q_ASSERT(legend);
133 qreal width = qMin(vertical.width(),geometry.width() * golden_ratio);
79 134
80 qreal titlePadding = m_chartMargins.top()/2;
135 QRectF rect = geometry.adjusted(width,vertical.height()/2,-horizontal.width()/2,-horizontal.height());
81 136
82 QMargins chartMargins = m_chartMargins;
137 m_presenter->setChartsGeometry(rect);
83 138
84 //TODO multiple axis handling;
85 chartMargins.setLeft(qMax(m_chartMargins.left(),int(axisWidth + 2*m_marginTiny)));
86 chartMargins.setBottom(qMax(m_chartMargins.bottom(),int(axisHeight + 2* m_marginTiny)));
139 foreach(ChartAxis* axis , axes) {
140 axis->setGeometry(geometry);
141 }
87 142
143 return rect;
144 }
88 145
89 // recalculate legend position
90 if ((legend->isAttachedToChart() && legend->isVisible())) {
146 QRectF ChartLayout::calculateAxisMinimum(const QRectF& minimum, const QList<ChartAxis*>& axes) const
147 {
148 QSizeF vertical(0,0);
149 QSizeF horizontal(0,0);
91 150
92 // Reserve some space for legend
93 switch (legend->alignment()) {
151 // check axis size
152 foreach(ChartAxis* axis , axes) {
153 if(axis->orientation()==Qt::Vertical && axis->isVisible()){
154 vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
155 }else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
156 horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
157 }
158 }
159 return minimum.adjusted(0,0,horizontal.width()+vertical.width(),horizontal.height() + vertical.height());
160 }
94 161
95 case Qt::AlignTop: {
162 QRectF ChartLayout::calculateLegendGeometry(const QRectF& geometry,QLegend* legend) const
163 {
164 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,-1));
165 QRectF legendRect;
166 QRectF result;
96 167
97 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
98 int topMargin = 2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny;
99 chartMargins = QMargins(chartMargins.left(),topMargin,chartMargins.right(),chartMargins.bottom());
100 m_legendMargins = QMargins(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny),chartMargins.right(),rect.height()-topMargin + m_marginTiny);
101 titlePadding = m_marginTiny + m_marginTiny;
168 switch (legend->alignment()) {
169
170 case Qt::AlignTop: {
171 legendRect = QRectF(geometry.topLeft(),QSizeF(geometry.width(),size.height()));
172 result = geometry.adjusted(0,legendRect.height(),0,0);
102 173 break;
103 174 }
104 175 case Qt::AlignBottom: {
105 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
106 int bottomMargin = m_marginTiny + legendSize.height() + m_marginTiny + axisHeight;
107 chartMargins = QMargins(chartMargins.left(),chartMargins.top(),chartMargins.right(),bottomMargin);
108 m_legendMargins = QMargins(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight,chartMargins.right(),m_marginTiny + m_marginSmall);
109 titlePadding = chartMargins.top()/2;
176 legendRect = QRectF(QPointF(geometry.left(),geometry.bottom()-size.height()),QSizeF(geometry.width(),size.height()));
177 result = geometry.adjusted(0,0,0,-legendRect.height());
110 178 break;
111 179 }
112 180 case Qt::AlignLeft: {
113 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
114 int leftPadding = m_marginTiny + legendSize.width() + m_marginTiny + axisWidth;
115 chartMargins = QMargins(leftPadding,chartMargins.top(),chartMargins.right(),chartMargins.bottom());
116 m_legendMargins = QMargins(m_marginTiny + m_marginSmall,chartMargins.top(),rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom());
117 titlePadding = chartMargins.top()/2;
181 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
182 legendRect = QRectF(geometry.topLeft(),QSizeF(width,geometry.height()));
183 result = geometry.adjusted(width,0,0,0);
118 184 break;
119 185 }
120 186 case Qt::AlignRight: {
121 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
122 int rightPadding = m_marginTiny + legendSize.width() + m_marginTiny;
123 chartMargins = QMargins(chartMargins.left(),chartMargins.top(),rightPadding,chartMargins.bottom());
124 m_legendMargins = QMargins(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top(),m_marginTiny + m_marginSmall,chartMargins.bottom());
125 titlePadding = chartMargins.top()/2;
187 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
188 legendRect = QRectF(QPointF(geometry.right()-width,geometry.top()),QSizeF(width,geometry.height()));
189 result = geometry.adjusted(0,0,-width,0);
126 190 break;
127 191 }
128 192 default: {
129 193 break;
130 194 }
131 }
132
133 legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
134 195 }
135 196
136 // recalculate title position
137 if (m_presenter->titleItem()) {
138 QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
139 m_presenter->titleItem()->setPos(center.x(),titlePadding);
140 }
197 legend->setGeometry(legendRect);
141 198
142 //recalculate background gradient
143 if (m_presenter->backgroundItem()) {
144 m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
145 }
199 return result;
200 }
146 201
147 QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
202 QRectF ChartLayout::calculateLegendMinimum(const QRectF& geometry,QLegend* legend) const
203 {
204 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize,QSizeF(-1,-1));
205 return geometry.adjusted(0,0,minSize.width(),minSize.height());
206 }
148 207
149 if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
150 m_presenter->setGeometry(chartRect);
151 }else if(chartRect.size().isEmpty()){
152 m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
153 }
208 QRectF ChartLayout::calculateTitleGeometry(const QRectF& geometry,ChartTitle* title) const
209 {
210 title->setGeometry(geometry);
211 QPointF center = geometry.center() - title->boundingRect().center();
212 title->setPos(center.x(),title->pos().y());
213 return geometry.adjusted(0,title->boundingRect().height(),0,0);
154 214 }
155 215
216 QRectF ChartLayout::calculateTitleMinimum(const QRectF& minimum,ChartTitle* title) const
217 {
218 QSizeF min = title->sizeHint(Qt::MinimumSize);
219 return minimum.adjusted(0,0,min.width(),min.height());
220 }
156 221
157 222 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
158 223 {
159 224 Q_UNUSED(constraint);
160 if(which == Qt::MinimumSize)
161 return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
162 else
225 if(which == Qt::MinimumSize){
226 QList<ChartAxis*> axes = m_presenter->axisItems();
227 ChartTitle* title = m_presenter->titleElement();
228 QLegend* legend = m_presenter->legend();
229 QRectF minimumRect(0,0,0,0);
230 minimumRect = calculateBackgroundMinimum(minimumRect);
231 minimumRect = calculateContentMinimum(minimumRect);
232 minimumRect = calculateTitleMinimum(minimumRect,title);
233 minimumRect = calculateLegendMinimum(minimumRect,legend);
234 minimumRect = calculateAxisMinimum(minimumRect,axes);
235 return minimumRect.united(m_minChartRect).size().toSize();
236 }else
163 237 return QSize(-1,-1);
164 238 }
165 239
166 void ChartLayout::setMinimumMargins(const QMargins& margins)
240 void ChartLayout::setMargins(const QMargins& margins)
167 241 {
168 242
169 if(m_chartMargins != margins){
170 m_chartMargins = margins;
243 if(m_margins != margins){
244 m_margins = margins;
171 245 updateGeometry();
172 246 }
173 247 }
174 248
175 QMargins ChartLayout::minimumMargins() const
249 QMargins ChartLayout::margins() const
250 {
251 return m_margins;
252 }
253
254 void ChartLayout::adjustChartGeometry()
176 255 {
177 return m_chartMargins;
256 setGeometry(geometry());
178 257 }
179 258
180 259 QTCOMMERCIALCHART_END_NAMESPACE
@@ -27,6 +27,10
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class ChartPresenter;
30 class ChartTitle;
31 class QLegend;
32 class ChartAxis;
33 class ChartBackground;
30 34
31 35 class ChartLayout : public QGraphicsLayout
32 36 {
@@ -35,10 +39,11 public:
35 39 ChartLayout(ChartPresenter* presenter);
36 40 virtual ~ChartLayout();
37 41
38 void setMinimumMargins(const QMargins& margins);
39 QMargins minimumMargins() const;
42 void setMargins(const QMargins& margins);
43 QMargins margins() const;
40 44
41 45 void setGeometry(const QRectF& rect);
46 void adjustChartGeometry();
42 47
43 48 protected:
44 49 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
@@ -47,15 +52,22 protected:
47 52 void removeAt(int){};
48 53
49 54 private:
50 ChartPresenter* m_presenter;
51 int m_marginBig;
52 int m_marginSmall;
53 int m_marginTiny;
54 QMargins m_chartMargins;
55 QMargins m_legendMargins;
56 bool m_intialized;
57
55 QRectF calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const;
56 QRectF calculateContentGeometry(const QRectF& geometry) const;
57 QRectF calculateTitleGeometry(const QRectF& geometry, ChartTitle* title) const;
58 QRectF calculateChartGeometry(const QRectF& geometry,const QList<ChartAxis*>& axes) const;
59 QRectF calculateLegendGeometry(const QRectF& geometry, QLegend* legend) const;
60 QRectF calculateBackgroundMinimum(const QRectF& minimum) const;
61 QRectF calculateContentMinimum(const QRectF& minimum) const;
62 QRectF calculateTitleMinimum(const QRectF& minimum,ChartTitle* title) const;
63 QRectF calculateAxisMinimum(const QRectF& minimum,const QList<ChartAxis*>& axes) const;
64 QRectF calculateLegendMinimum(const QRectF& minimum,QLegend* legend) const;
58 65
66 private:
67 ChartPresenter* m_presenter;
68 QMargins m_margins;
69 QRectF m_minChartRect;
70 QRectF m_minAxisRect;
59 71 };
60 72
61 73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -28,11 +28,9
28 28 #include "qabstractseries_p.h"
29 29 #include "qareaseries.h"
30 30 #include "chartaxis_p.h"
31 //#include "chartaxisx_p.h"
32 //#include "chartaxisy_p.h"
33 #include "areachartitem_p.h"
34 31 #include "chartbackground_p.h"
35 32 #include "chartlayout_p.h"
33 #include "charttitle_p.h"
36 34 #include <QTimer>
37 35
38 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -44,8 +42,8 m_chartTheme(0),
44 42 m_options(QChart::NoAnimation),
45 43 m_state(ShowState),
46 44 m_layout(new ChartLayout(this)),
47 m_backgroundItem(0),
48 m_titleItem(0)
45 m_background(0),
46 m_title(0)
49 47 {
50 48
51 49 }
@@ -55,17 +53,24 ChartPresenter::~ChartPresenter()
55 53 delete m_chartTheme;
56 54 }
57 55
58 void ChartPresenter::setGeometry(const QRectF& rect)
56 void ChartPresenter::setChartsGeometry(const QRectF& rect)
59 57 {
60
61 58 Q_ASSERT(rect.isValid());
62 59
63 if(m_rect!=rect) {
64 m_rect=rect;
65 emit geometryChanged(m_rect);
60 if(m_chartsRect!=rect) {
61 m_chartsRect=rect;
62 foreach(ChartElement* chart, m_chartItems)
63 {
64 chart->handleGeometryChanged(rect);
65 }
66 66 }
67 67 }
68 68
69 QRectF ChartPresenter::chartsGeometry() const
70 {
71 return m_chartsRect;
72 }
73
69 74 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
70 75 {
71 76 ChartAxis* item = axis->d_ptr->createGraphics(this);
@@ -84,7 +89,7 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
84 89 m_chartTheme->decorate(axis);
85 90 axis->d_ptr->setDirty(false);
86 91 axis->d_ptr->emitUpdated();
87 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
92 if(m_chartsRect.isValid()) item->handleGeometryChanged(m_chartsRect);
88 93
89 94 m_axisItems.insert(axis, item);
90 95 selectVisibleAxis();
@@ -113,7 +118,7 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
113 118 //initialize
114 119 item->handleDomainUpdated();
115 120
116 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
121 if(m_chartsRect.isValid()) item->handleGeometryChanged(m_chartsRect);
117 122 m_chartItems.insert(series,item);
118 123 }
119 124
@@ -222,27 +227,29 void ChartPresenter::resetAllElements()
222 227 handleSeriesRemoved(series);
223 228 handleSeriesAdded(series,domain);
224 229 }
230
231 layout()->invalidate();
225 232 }
226 233
227 234 void ChartPresenter::zoomIn(qreal factor)
228 235 {
229 QRectF rect = geometry();
236 QRectF rect = chartsGeometry();
230 237 rect.setWidth(rect.width()/factor);
231 238 rect.setHeight(rect.height()/factor);
232 rect.moveCenter(geometry().center());
239 rect.moveCenter(chartsGeometry().center());
233 240 zoomIn(rect);
234 241 }
235 242
236 243 void ChartPresenter::zoomIn(const QRectF& rect)
237 244 {
238 245 QRectF r = rect.normalized();
239 r.translate(-geometry().topLeft());
246 r.translate(-chartsGeometry().topLeft());
240 247 if (!r.isValid())
241 248 return;
242 249
243 250 m_state = ZoomInState;
244 m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
245 m_dataset->zoomInDomain(r,geometry().size());
251 m_statePoint = QPointF(r.center().x()/chartsGeometry().width(),r.center().y()/chartsGeometry().height());
252 m_dataset->zoomInDomain(r,chartsGeometry().size());
246 253 m_state = ShowState;
247 254 }
248 255
@@ -251,14 +258,14 void ChartPresenter::zoomOut(qreal factor)
251 258 m_state = ZoomOutState;
252 259
253 260 QRectF chartRect;
254 chartRect.setSize(geometry().size());
261 chartRect.setSize(chartsGeometry().size());
255 262
256 263 QRectF rect;
257 264 rect.setSize(chartRect.size()/factor);
258 265 rect.moveCenter(chartRect.center());
259 266 if (!rect.isValid())
260 267 return;
261 m_statePoint = QPointF(rect.center().x()/geometry().width(),rect.center().y()/geometry().height());
268 m_statePoint = QPointF(rect.center().x()/chartsGeometry().width(),rect.center().y()/chartsGeometry().height());
262 269 m_dataset->zoomOutDomain(rect, chartRect.size());
263 270 m_state = ShowState;
264 271 }
@@ -270,7 +277,7 void ChartPresenter::scroll(qreal dx,qreal dy)
270 277 if(dy<0) m_state=ScrollUpState;
271 278 if(dy>0) m_state=ScrollDownState;
272 279
273 m_dataset->scrollDomain(dx,dy,geometry().size());
280 m_dataset->scrollDomain(dx,dy,chartsGeometry().size());
274 281 m_state = ShowState;
275 282 }
276 283
@@ -281,18 +288,18 QChart::AnimationOptions ChartPresenter::animationOptions() const
281 288
282 289 void ChartPresenter::createBackgroundItem()
283 290 {
284 if (!m_backgroundItem) {
285 m_backgroundItem = new ChartBackground(rootItem());
286 m_backgroundItem->setPen(Qt::NoPen);
287 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
291 if (!m_background) {
292 m_background = new ChartBackground(rootItem());
293 m_background->setPen(Qt::NoPen);
294 m_background->setZValue(ChartPresenter::BackgroundZValue);
288 295 }
289 296 }
290 297
291 298 void ChartPresenter::createTitleItem()
292 299 {
293 if (!m_titleItem) {
294 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
295 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
300 if (!m_title) {
301 m_title = new ChartTitle(rootItem());
302 m_title->setZValue(ChartPresenter::BackgroundZValue);
296 303 }
297 304 }
298 305
@@ -313,104 +320,94 void ChartPresenter::startAnimation(ChartAnimation* animation)
313 320 QTimer::singleShot(0, animation, SLOT(start()));
314 321 }
315 322
316 QGraphicsRectItem* ChartPresenter::backgroundItem()
317 {
318 return m_backgroundItem;
319 }
320
321 323 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
322 324 {
323 325 createBackgroundItem();
324 m_backgroundItem->setBrush(brush);
326 m_background->setBrush(brush);
325 327 m_layout->invalidate();
326 328 }
327 329
328 330 QBrush ChartPresenter::backgroundBrush() const
329 331 {
330 if (!m_backgroundItem) return QBrush();
331 return m_backgroundItem->brush();
332 if (!m_background) return QBrush();
333 return m_background->brush();
332 334 }
333 335
334 336 void ChartPresenter::setBackgroundPen(const QPen& pen)
335 337 {
336 338 createBackgroundItem();
337 m_backgroundItem->setPen(pen);
339 m_background->setPen(pen);
338 340 m_layout->invalidate();
339 341 }
340 342
341 343 QPen ChartPresenter::backgroundPen() const
342 344 {
343 if (!m_backgroundItem) return QPen();
344 return m_backgroundItem->pen();
345 }
346
347 QGraphicsItem* ChartPresenter::titleItem()
348 {
349 return m_titleItem;
345 if (!m_background) return QPen();
346 return m_background->pen();
350 347 }
351 348
352 349 void ChartPresenter::setTitle(const QString& title)
353 350 {
354 351 createTitleItem();
355 m_titleItem->setText(title);
352 m_title->setText(title);
356 353 m_layout->invalidate();
357 354 }
358 355
359 356 QString ChartPresenter::title() const
360 357 {
361 if (!m_titleItem) return QString();
362 return m_titleItem->text();
358 if (!m_title) return QString();
359 return m_title->text();
363 360 }
364 361
365 362 void ChartPresenter::setTitleFont(const QFont& font)
366 363 {
367 364 createTitleItem();
368 m_titleItem->setFont(font);
365 m_title->setFont(font);
369 366 m_layout->invalidate();
370 367 }
371 368
372 369 QFont ChartPresenter::titleFont() const
373 370 {
374 if (!m_titleItem) return QFont();
375 return m_titleItem->font();
371 if (!m_title) return QFont();
372 return m_title->font();
376 373 }
377 374
378 375 void ChartPresenter::setTitleBrush(const QBrush &brush)
379 376 {
380 377 createTitleItem();
381 m_titleItem->setBrush(brush);
378 m_title->setBrush(brush);
382 379 m_layout->invalidate();
383 380 }
384 381
385 382 QBrush ChartPresenter::titleBrush() const
386 383 {
387 if (!m_titleItem) return QBrush();
388 return m_titleItem->brush();
384 if (!m_title) return QBrush();
385 return m_title->brush();
389 386 }
390 387
391 388 void ChartPresenter::setBackgroundVisible(bool visible)
392 389 {
393 390 createBackgroundItem();
394 m_backgroundItem->setVisible(visible);
391 m_background->setVisible(visible);
395 392 }
396 393
397 394
398 395 bool ChartPresenter::isBackgroundVisible() const
399 396 {
400 if (!m_backgroundItem) return false;
401 return m_backgroundItem->isVisible();
397 if (!m_background) return false;
398 return m_background->isVisible();
402 399 }
403 400
404 401 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
405 402 {
406 403 createBackgroundItem();
407 m_backgroundItem->setDropShadowEnabled(enabled);
404 m_background->setDropShadowEnabled(enabled);
408 405 }
409 406
410 407 bool ChartPresenter::isBackgroundDropShadowEnabled() const
411 408 {
412 if (!m_backgroundItem) return false;
413 return m_backgroundItem->isDropShadowEnabled();
409 if (!m_background) return false;
410 return m_background->isDropShadowEnabled();
414 411 }
415 412
416 413
@@ -419,14 +416,14 QGraphicsLayout* ChartPresenter::layout()
419 416 return m_layout;
420 417 }
421 418
422 void ChartPresenter::setMinimumMargins(const QMargins& margins)
419 void ChartPresenter::setMargins(const QMargins& margins)
423 420 {
424 m_layout->setMinimumMargins(margins);
421 m_layout->setMargins(margins);
425 422 }
426 423
427 QMargins ChartPresenter::minimumMargins() const
424 QMargins ChartPresenter::margins() const
428 425 {
429 return m_layout->minimumMargins();
426 return m_layout->margins();
430 427 }
431 428
432 429 QLegend* ChartPresenter::legend()
@@ -434,14 +431,24 QLegend* ChartPresenter::legend()
434 431 return m_chart->legend();
435 432 }
436 433
434 void ChartPresenter::setVisible(bool visible)
435 {
436 m_chart->setVisible(visible);
437 }
438
439 ChartBackground* ChartPresenter::backgroundElement()
440 {
441 return m_background;
442 }
443
437 444 QList<ChartAxis*> ChartPresenter::axisItems() const
438 445 {
439 446 return m_axisItems.values();
440 447 }
441 448
442 void ChartPresenter::setVisible(bool visible)
449 ChartTitle* ChartPresenter::titleElement()
443 450 {
444 m_chart->setVisible(visible);
451 return m_title;
445 452 }
446 453
447 454 #include "moc_chartpresenter_p.cpp"
@@ -45,6 +45,7 class ChartAxis;
45 45 class ChartTheme;
46 46 class ChartAnimator;
47 47 class ChartBackground;
48 class ChartTitle;
48 49 class ChartAnimation;
49 50 class ChartLayout;
50 51
@@ -83,8 +84,8 public:
83 84 ChartTheme *chartTheme() const { return m_chartTheme; }
84 85 ChartDataSet *dataSet() const { return m_dataset; }
85 86 QGraphicsItem* rootItem() const { return m_chart; }
86 QGraphicsRectItem* backgroundItem();
87 QGraphicsItem* titleItem();
87 ChartBackground* backgroundElement();
88 ChartTitle* titleElement();
88 89 QList<ChartAxis*> axisItems() const;
89 90
90 91 QLegend* legend();
@@ -123,8 +124,8 public:
123 124 void zoomOut(qreal factor);
124 125 void scroll(qreal dx,qreal dy);
125 126
126 void setGeometry(const QRectF& rect);
127 QRectF geometry() { return m_rect; }
127 void setChartsGeometry(const QRectF& rect);
128 QRectF chartsGeometry() const;
128 129
129 130 void startAnimation(ChartAnimation* animation);
130 131 State state() const { return m_state; }
@@ -132,8 +133,8 public:
132 133
133 134 void resetAllElements();
134 135
135 void setMinimumMargins(const QMargins& margins);
136 QMargins minimumMargins() const;
136 void setMargins(const QMargins& margins);
137 QMargins margins() const;
137 138 QGraphicsLayout* layout();
138 139
139 140 private:
@@ -162,14 +163,14 private:
162 163 ChartTheme *m_chartTheme;
163 164 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
164 165 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
165 QRectF m_rect;
166 QRectF m_chartsRect;
166 167 QChart::AnimationOptions m_options;
167 168 State m_state;
168 169 QPointF m_statePoint;
169 170 QList<ChartAnimation*> m_animations;
170 171 ChartLayout* m_layout;
171 ChartBackground* m_backgroundItem;
172 QGraphicsSimpleTextItem* m_titleItem;
172 ChartBackground* m_background;
173 ChartTitle* m_title;
173 174 };
174 175
175 176 QTCOMMERCIALCHART_END_NAMESPACE
@@ -178,7 +178,6 void Domain::handleAxisUpdated()
178 178 }else if(axis->orientation()==Qt::Vertical){
179 179 setRangeY(axis->min(),axis->max());
180 180 }
181
182 181 }
183 182
184 183 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2)
@@ -22,6 +22,7
22 22 #include "chartpresenter_p.h"
23 23 #include "legendmarker_p.h"
24 24 #include "qlegend_p.h"
25 #include <QDebug>
25 26
26 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 28
@@ -58,6 +59,9 void LegendLayout::setOffset(qreal x, qreal y)
58 59 }
59 60
60 61 QRectF boundingRect = geometry();
62 qreal left, top, right, bottom;
63 getContentsMargins(&left, &top, &right, &bottom);
64 boundingRect.adjust(left,top,-right,-bottom);
61 65
62 66 // Limit offset between m_minOffset and m_maxOffset
63 67 if (scrollHorizontal) {
@@ -112,16 +116,20 void LegendLayout::setAttachedGeometry(const QRectF& rect)
112 116 m_width=0;
113 117 m_height=0;
114 118
119 qreal left, top, right, bottom;
120 getContentsMargins(&left, &top, &right, &bottom);
121
122 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
123
115 124 switch(m_legend->alignment()) {
116 125
117 126 case Qt::AlignTop:
118
119 127 case Qt::AlignBottom: {
120 128 QPointF point(0,0);
121 129 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
122 130 if (marker->isVisible()) {
123 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
124 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
131 marker->setGeometry(geometry);
132 marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
125 133 const QRectF& rect = marker->boundingRect();
126 134 size = size.expandedTo(rect.size());
127 135 qreal w = rect.width();
@@ -129,12 +137,12 void LegendLayout::setAttachedGeometry(const QRectF& rect)
129 137 point.setX(point.x() + w);
130 138 }
131 139 }
132 if(m_width<rect.width()) {
133 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
140 if(m_width<geometry.width()) {
141 m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
134 142
135 143 }
136 144 else {
137 m_legend->d_ptr->items()->setPos(rect.topLeft());
145 m_legend->d_ptr->items()->setPos(geometry.topLeft());
138 146 }
139 147 m_height=size.height();
140 148 }
@@ -144,7 +152,7 void LegendLayout::setAttachedGeometry(const QRectF& rect)
144 152 QPointF point(0,0);
145 153 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
146 154 if (marker->isVisible()) {
147 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
155 marker->setGeometry(geometry);
148 156 marker->setPos(point);
149 157 const QRectF& rect = marker->boundingRect();
150 158 qreal h = rect.height();
@@ -153,21 +161,22 void LegendLayout::setAttachedGeometry(const QRectF& rect)
153 161 point.setY(point.y() + h);
154 162 }
155 163 }
156 if(m_height<rect.height()) {
157 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
164 if(m_height<geometry.height()) {
165 m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
158 166 }
159 167 else {
160 m_legend->d_ptr->items()->setPos(rect.topLeft());
168 m_legend->d_ptr->items()->setPos(geometry.topLeft());
161 169 }
162 170 m_width=size.width();
163 171 }
164 172 break;
165 173 }
166 174
167 m_minOffsetX = 0;
168 m_minOffsetY = 0;
169 m_maxOffsetX = m_width - rect.width();
170 m_maxOffsetY = m_height - rect.height();
175
176 m_minOffsetX = -left;
177 m_minOffsetY = - top;
178 m_maxOffsetX = m_width - geometry.width() - right;
179 m_maxOffsetY = m_height - geometry.height() - bottom;
171 180 }
172 181
173 182 void LegendLayout::setDettachedGeometry(const QRectF& rect)
@@ -182,6 +191,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
182 191 m_offsetX=0;
183 192 m_offsetY=0;
184 193
194 qreal left, top, right, bottom;
195 getContentsMargins(&left, &top, &right, &bottom);
196 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
197
185 198 QSizeF size(0,0);
186 199
187 200 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
@@ -190,13 +203,13 void LegendLayout::setDettachedGeometry(const QRectF& rect)
190 203
191 204 switch (m_legend->alignment()) {
192 205 case Qt::AlignTop: {
193 QPointF point = rect.topLeft();
206 QPointF point(0,0);
194 207 m_width = 0;
195 208 m_height = 0;
196 209 for (int i=0; i<markers.count(); i++) {
197 210 LegendMarker *marker = markers.at(i);
198 211 if (marker->isVisible()) {
199 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
212 marker->setGeometry(geometry);
200 213 marker->setPos(point.x(),point.y());
201 214 const QRectF& boundingRect = marker->boundingRect();
202 215 qreal w = boundingRect.width();
@@ -204,9 +217,9 void LegendLayout::setDettachedGeometry(const QRectF& rect)
204 217 m_width = qMax(m_width,w);
205 218 m_height = qMax(m_height,h);
206 219 point.setX(point.x() + w);
207 if (point.x() + w > rect.topLeft().x() + rect.width()) {
220 if (point.x() + w > geometry.left() + geometry.width() - right) {
208 221 // Next item would go off rect.
209 point.setX(rect.topLeft().x());
222 point.setX(0);
210 223 point.setY(point.y() + h);
211 224 if (i+1 < markers.count()) {
212 225 m_height += h;
@@ -214,22 +227,22 void LegendLayout::setDettachedGeometry(const QRectF& rect)
214 227 }
215 228 }
216 229 }
217 m_legend->d_ptr->items()->setPos(rect.topLeft());
230 m_legend->d_ptr->items()->setPos(geometry.topLeft());
218 231
219 m_minOffsetX = 0;
220 m_minOffsetY = 0;
221 m_maxOffsetX = m_width - rect.width();
222 m_maxOffsetY = m_height - rect.height();
232 m_minOffsetX = -left;
233 m_minOffsetY = -top;
234 m_maxOffsetX = m_width - geometry.width() - right;
235 m_maxOffsetY = m_height - geometry.height() - bottom;
223 236 }
224 237 break;
225 238 case Qt::AlignBottom: {
226 QPointF point = rect.bottomLeft();
239 QPointF point(0,geometry.height());
227 240 m_width = 0;
228 241 m_height = 0;
229 242 for (int i=0; i<markers.count(); i++) {
230 243 LegendMarker *marker = markers.at(i);
231 244 if (marker->isVisible()) {
232 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
245 marker->setGeometry(geometry);
233 246 const QRectF& boundingRect = marker->boundingRect();
234 247 qreal w = boundingRect.width();
235 248 qreal h = boundingRect.height();
@@ -237,9 +250,9 void LegendLayout::setDettachedGeometry(const QRectF& rect)
237 250 m_height = qMax(m_height,h);
238 251 marker->setPos(point.x(),point.y() - h);
239 252 point.setX(point.x() + w);
240 if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
253 if (point.x() + w > geometry.left() + geometry.width() - right) {
241 254 // Next item would go off rect.
242 point.setX(rect.bottomLeft().x());
255 point.setX(0);
243 256 point.setY(point.y() - h);
244 257 if (i+1 < markers.count()) {
245 258 m_height += h;
@@ -247,23 +260,23 void LegendLayout::setDettachedGeometry(const QRectF& rect)
247 260 }
248 261 }
249 262 }
250 m_legend->d_ptr->items()->setPos(rect.topLeft());
263 m_legend->d_ptr->items()->setPos(geometry.topLeft());
251 264
252 m_minOffsetX = 0;
253 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
254 m_maxOffsetX = m_width - rect.width();
255 m_maxOffsetY = 0;
265 m_minOffsetX = -left;
266 m_minOffsetY = -m_height + geometry.height() - top;
267 m_maxOffsetX = m_width - geometry.width() - right;
268 m_maxOffsetY = -bottom;
256 269 }
257 270 break;
258 271 case Qt::AlignLeft: {
259 QPointF point = rect.topLeft();
272 QPointF point(0,0);
260 273 m_width = 0;
261 274 m_height = 0;
262 275 qreal maxWidth = 0;
263 276 for (int i=0; i<markers.count(); i++) {
264 277 LegendMarker *marker = markers.at(i);
265 278 if (marker->isVisible()) {
266 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
279 marker->setGeometry(geometry);
267 280 const QRectF& boundingRect = marker->boundingRect();
268 281 qreal w = boundingRect.width();
269 282 qreal h = boundingRect.height();
@@ -271,10 +284,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
271 284 maxWidth = qMax(maxWidth,w);
272 285 marker->setPos(point.x(),point.y());
273 286 point.setY(point.y() + h);
274 if (point.y() + h > rect.topLeft().y() + rect.height()) {
287 if (point.y() + h > geometry.bottom() - bottom) {
275 288 // Next item would go off rect.
276 289 point.setX(point.x() + maxWidth);
277 point.setY(rect.topLeft().y());
290 point.setY(0);
278 291 if (i+1 < markers.count()) {
279 292 m_width += maxWidth;
280 293 maxWidth = 0;
@@ -283,23 +296,23 void LegendLayout::setDettachedGeometry(const QRectF& rect)
283 296 }
284 297 }
285 298 m_width += maxWidth;
286 m_legend->d_ptr->items()->setPos(rect.topLeft());
299 m_legend->d_ptr->items()->setPos(geometry.topLeft());
287 300
288 m_minOffsetX = 0;
289 m_minOffsetY = 0;
290 m_maxOffsetX = m_width - rect.width();
291 m_maxOffsetY = m_height - rect.height();
301 m_minOffsetX = -left;
302 m_minOffsetY = -top;
303 m_maxOffsetX = m_width - geometry.width() - right;
304 m_maxOffsetY = m_height - geometry.height() - bottom;
292 305 }
293 306 break;
294 307 case Qt::AlignRight: {
295 QPointF point = rect.topRight();
308 QPointF point(geometry.width(),0);
296 309 m_width = 0;
297 310 m_height = 0;
298 311 qreal maxWidth = 0;
299 312 for (int i=0; i<markers.count(); i++) {
300 313 LegendMarker *marker = markers.at(i);
301 314 if (marker->isVisible()) {
302 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
315 marker->setGeometry(geometry);
303 316 const QRectF& boundingRect = marker->boundingRect();
304 317 qreal w = boundingRect.width();
305 318 qreal h = boundingRect.height();
@@ -307,10 +320,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
307 320 maxWidth = qMax(maxWidth,w);
308 321 marker->setPos(point.x() - w,point.y());
309 322 point.setY(point.y() + h);
310 if (point.y() + h > rect.topLeft().y() + rect.height()) {
323 if (point.y() + h > geometry.bottom()-bottom) {
311 324 // Next item would go off rect.
312 325 point.setX(point.x() - maxWidth);
313 point.setY(rect.topLeft().y());
326 point.setY(0);
314 327 if (i+1 < markers.count()) {
315 328 m_width += maxWidth;
316 329 maxWidth = 0;
@@ -319,12 +332,12 void LegendLayout::setDettachedGeometry(const QRectF& rect)
319 332 }
320 333 }
321 334 m_width += maxWidth;
322 m_legend->d_ptr->items()->setPos(rect.topLeft());
335 m_legend->d_ptr->items()->setPos(geometry.topLeft());
323 336
324 m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
325 m_minOffsetY = 0;
326 m_maxOffsetX = 0;
327 m_maxOffsetY = m_height - rect.height();
337 m_minOffsetX = - m_width + geometry.width() - left;
338 m_minOffsetY = -top;
339 m_maxOffsetX = - right;
340 m_maxOffsetY = m_height - geometry.height() - bottom;
328 341 }
329 342 break;
330 343 default:
@@ -339,8 +352,6 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) c
339 352 qreal left, top, right, bottom;
340 353 getContentsMargins(&left, &top, &right, &bottom);
341 354
342 if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
343
344 355 if(constraint.isValid()) {
345 356 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
346 357 size = size.expandedTo(marker->effectiveSizeHint(which));
@@ -372,10 +383,7 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) c
372 383 }
373 384 }
374 385 size += QSize(left + right, top + bottom);
375
376 386 return size;
377
378
379 387 }
380 388
381 389 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
44 44 m_legend(legend),
45 45 m_textItem(new QGraphicsSimpleTextItem(this)),
46 46 m_rectItem(new QGraphicsRectItem(this)),
47 m_margin(2),
47 m_margin(4),
48 48 m_space(4)
49 49 {
50 50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
@@ -86,12 +86,13 QFont LegendMarker::font() const
86 86
87 87 void LegendMarker::setLabel(const QString label)
88 88 {
89 m_textItem->setText(label);
89 m_text = label;
90 updateGeometry();
90 91 }
91 92
92 93 QString LegendMarker::label() const
93 94 {
94 return m_textItem->text();
95 return m_text;
95 96 }
96 97
97 98 QRectF LegendMarker::boundingRect() const
@@ -112,14 +113,31 QBrush LegendMarker::labelBrush() const
112 113
113 114 void LegendMarker::setGeometry(const QRectF& rect)
114 115 {
116 QFontMetrics fn (font());
117
118 int width = rect.width();
119 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
120 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
121
122 if (fn.boundingRect(m_text).width() + x > width)
123 {
124 QString string = m_text + "...";
125 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
126 string.remove(string.length() - 4, 1);
127 m_textItem->setText(string);
128 }
129 else
130 m_textItem->setText(m_text);
131
115 132 const QRectF& textRect = m_textItem->boundingRect();
116 133
117 m_textItem->setPos(m_markerRect.width() + m_space + m_margin,rect.height()/2 - textRect.height()/2);
134
135 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
118 136 m_rectItem->setRect(m_markerRect);
119 m_rectItem->setPos(m_margin,rect.height()/2 - m_markerRect.height()/2);
137 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
120 138
121 139 prepareGeometryChange();
122 m_boundingRect = rect;
140 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
123 141 }
124 142
125 143 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -129,7 +147,6 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
129 147 Q_UNUSED(painter)
130 148 }
131 149
132
133 150 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
134 151 {
135 152 Q_UNUSED(constraint)
@@ -139,10 +156,10 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
139 156
140 157 switch (which) {
141 158 case Qt::MinimumSize:
142 sh = QSizeF(fn.boundingRect("...").width(),fn.height());
159 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
143 160 break;
144 161 case Qt::PreferredSize:
145 sh = QSizeF(fn.boundingRect(m_textItem->text()).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
162 sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
146 163 break;
147 164 default:
148 165 break;
@@ -154,7 +171,7 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
154 171 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
155 172 {
156 173 QGraphicsObject::mousePressEvent(event);
157 qDebug()<<"Not implemented"; //TODO: selected signal removed for now
174 //TODO: selected signal removed for now
158 175 }
159 176
160 177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -96,6 +96,7 protected:
96 96 QGraphicsRectItem *m_rectItem;
97 97 qreal m_margin;
98 98 qreal m_space;
99 QString m_text;
99 100
100 101 };
101 102
@@ -373,18 +373,18 QLegend* QChart::legend() const
373 373 /*!
374 374 Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget.
375 375 */
376 void QChart::setMinimumMargins(const QMargins& margins)
376 void QChart::setMargins(const QMargins& margins)
377 377 {
378 d_ptr->m_presenter->setMinimumMargins(margins);
378 d_ptr->m_presenter->setMargins(margins);
379 379 }
380 380
381 381 /*!
382 382 Returns the rect that contains information about margins (distance between chart widget edge and axes).
383 383 Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
384 384 */
385 QMargins QChart::minimumMargins() const
385 QMargins QChart::margins() const
386 386 {
387 return d_ptr->m_presenter->minimumMargins();
387 return d_ptr->m_presenter->margins();
388 388 }
389 389
390 390 /*!
@@ -393,7 +393,7 QMargins QChart::minimumMargins() const
393 393 */
394 394 QRectF QChart::plotArea() const
395 395 {
396 return d_ptr->m_presenter->geometry();
396 return d_ptr->m_presenter->chartsGeometry();
397 397 }
398 398
399 399 ///*!
@@ -43,7 +43,7 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
43 43 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
44 44 Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
45 45 Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions)
46 Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
46 Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
47 47 Q_ENUMS(ChartTheme)
48 48 Q_ENUMS(AnimationOption)
49 49
@@ -114,8 +114,8 public:
114 114
115 115 QLegend* legend() const;
116 116
117 void setMinimumMargins(const QMargins& margins);
118 QMargins minimumMargins() const;
117 void setMargins(const QMargins& margins);
118 QMargins margins() const;
119 119
120 120 QRectF plotArea() const;
121 121
@@ -38,7 +38,8 SOURCES += \
38 38 $$PWD/chartbackground.cpp \
39 39 $$PWD/chartelement.cpp \
40 40 $$PWD/scroller.cpp \
41 $$PWD/chartlayout.cpp
41 $$PWD/chartlayout.cpp \
42 $$PWD/charttitle.cpp
42 43 PRIVATE_HEADERS += \
43 44 $$PWD/chartdataset_p.h \
44 45 $$PWD/chartitem_p.h \
@@ -52,8 +53,8 PRIVATE_HEADERS += \
52 53 $$PWD/qchartview_p.h \
53 54 $$PWD/scroller_p.h \
54 55 $$PWD/qabstractseries_p.h \
55 $$PWD/chartlayout_p.h
56
56 $$PWD/chartlayout_p.h \
57 $$PWD/charttitle_p.h
57 58 PUBLIC_HEADERS += \
58 59 $$PWD/qchart.h \
59 60 $$PWD/qchartglobal.h \
General Comments 0
You need to be logged in to leave comments. Login now