##// 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 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
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 emit minimumMarginsChanged();
249 emit minimumMarginsChanged();
250 emit plotAreaChanged(m_chart->plotArea());
250 emit plotAreaChanged(m_chart->plotArea());
251 }
251 }
@@ -501,6 +501,7 qreal DeclarativeChart::topMargin()
501
501
502 qreal DeclarativeChart::bottomMargin()
502 qreal DeclarativeChart::bottomMargin()
503 {
503 {
504
504 qWarning() << "ChartView.bottomMargin is deprecated. Use minimumMargins and plotArea instead.";
505 qWarning() << "ChartView.bottomMargin is deprecated. Use minimumMargins and plotArea instead.";
505 return m_chart->plotArea().bottom();
506 return m_chart->plotArea().bottom();
506 }
507 }
@@ -20,6 +20,7
20
20
21 #include "axisanimation_p.h"
21 #include "axisanimation_p.h"
22 #include "chartaxis_p.h"
22 #include "chartaxis_p.h"
23 #include "chartpresenter_p.h"
23 #include <QTimer>
24 #include <QTimer>
24 #include <QDebug>
25 #include <QDebug>
25
26
@@ -61,7 +62,7 void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayo
61
62
62 switch (m_type) {
63 switch (m_type) {
63 case ZoomOutAnimation: {
64 case ZoomOutAnimation: {
64 QRectF rect = m_axis->geometry();
65 QRectF rect = m_axis->presenter()->chartsGeometry();
65 oldLayout.resize(newLayout.count());
66 oldLayout.resize(newLayout.count());
66
67
67 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
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 break;
95 break;
95 default: {
96 default: {
96 oldLayout.resize(newLayout.count());
97 oldLayout.resize(newLayout.count());
97 QRectF rect = m_axis->geometry();
98 QRectF rect = m_axis->presenter()->chartsGeometry();
98 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
99 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
99 oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
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 Q_ASSERT(vector.count() != 0);
132 Q_ASSERT(vector.count() != 0);
132 m_axis->setLayout(vector);
133 m_axis->setLayout(vector);
133 m_axis->updateGeometry();
134 m_axis->updateGeometry();
134 m_axis->checkLayout();
135 }
135 }
136
136
137 }
137 }
@@ -21,6 +21,7
21 #include "chartbarcategoryaxisx_p.h"
21 #include "chartbarcategoryaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoryaxis_p.h"
23 #include "qbarcategoryaxis_p.h"
24 #include <QFontMetrics>
24 #include <QDebug>
25 #include <QDebug>
25 #include <qmath.h>
26 #include <qmath.h>
26
27
@@ -47,23 +48,25 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
47 QVector<qreal> points;
48 QVector<qreal> points;
48 points.resize(count+2);
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 qreal offset =-m_min-0.5;
54 qreal offset =-m_min-0.5;
52
55
53 if(delta<1) return points;
56 if(delta<1) return points;
54
57
55 if(offset<=0) {
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 else {
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();
65 points[0] = rect.left();
63 points[count+1] = m_rect.right();
66 points[count+1] = rect.right();
64
67
65 for (int i = 0; i < count; ++i) {
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 points[i+1] = x;
70 points[i+1] = x;
68 }
71 }
69 return points;
72 return points;
@@ -72,9 +75,10 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
72 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
75 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
73 {
76 {
74 QStringList result;
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 for (int i = 0;i < layout.count()-1; ++i) {
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 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
82 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
79 result << m_categoriesAxis->categories().at(x);
83 result << m_categoriesAxis->categories().at(x);
80 }
84 }
@@ -92,9 +96,6 void ChartBarCategoryAxisX::updateGeometry()
92 {
96 {
93 const QVector<qreal>& layout = ChartAxis::layout();
97 const QVector<qreal>& layout = ChartAxis::layout();
94
98
95 m_minWidth = 0;
96 m_minHeight = 0;
97
98 if(layout.isEmpty()) return;
99 if(layout.isEmpty()) return;
99
100
100 QStringList ticksList = createCategoryLabels(layout);
101 QStringList ticksList = createCategoryLabels(layout);
@@ -107,15 +108,17 void ChartBarCategoryAxisX::updateGeometry()
107 Q_ASSERT(labels.size() == ticksList.size());
108 Q_ASSERT(labels.size() == ticksList.size());
108 Q_ASSERT(layout.size() == ticksList.size());
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 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
119 for (int i = 0; i < layout.size(); ++i) {
117 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
122 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
120 labelItem->setText(ticksList.at(i));
123 labelItem->setText(ticksList.at(i));
121 const QRectF& rect = labelItem->boundingRect();
124 const QRectF& rect = labelItem->boundingRect();
@@ -123,12 +126,12 void ChartBarCategoryAxisX::updateGeometry()
123 labelItem->setTransformOriginPoint(center.x(), center.y());
126 labelItem->setTransformOriginPoint(center.x(), center.y());
124
127
125 if(i==0){
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 }else{
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 labelItem->setVisible(false);
135 labelItem->setVisible(false);
133 }
136 }
134 else {
137 else {
@@ -136,15 +139,12 void ChartBarCategoryAxisX::updateGeometry()
136 width=rect.width()+labelItem->pos().x();
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 if ((i+1)%2 && i>1) {
142 if ((i+1)%2 && i>1) {
143 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
200 QTCOMMERCIALCHART_END_NAMESPACE
@@ -45,7 +45,7 public:
45 ~ChartBarCategoryAxisX();
45 ~ChartBarCategoryAxisX();
46
46
47 AxisType axisType() const { return X_AXIS;}
47 AxisType axisType() const { return X_AXIS;}
48
48 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
49 protected:
49 protected:
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
51 void updateGeometry();
51 void updateGeometry();
@@ -22,6 +22,7
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qbarcategoryaxis_p.h"
23 #include "qbarcategoryaxis_p.h"
24 #include <qmath.h>
24 #include <qmath.h>
25 #include <QFontMetrics>
25 #include <QDebug>
26 #include <QDebug>
26
27
27 static int label_padding = 5;
28 static int label_padding = 5;
@@ -46,23 +47,25 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
46 QVector<qreal> points;
47 QVector<qreal> points;
47 points.resize(count+2);
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 qreal offset = - m_min - 0.5;
53 qreal offset = - m_min - 0.5;
51
54
52 if(delta<1) return points;
55 if(delta<1) return points;
53
56
54 if(offset<=0) {
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 else {
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();
64 points[0] = rect.bottom();
62 points[count+1] = m_rect.top();
65 points[count+1] = rect.top();
63
66
64 for (int i = 0; i < count; ++i) {
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 points[i+1] = y;
69 points[i+1] = y;
67 }
70 }
68 return points;
71 return points;
@@ -71,9 +74,10 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
71 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
74 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
72 {
75 {
73 QStringList result;
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 for (int i = 0;i < layout.count()-1; ++i) {
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 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
81 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
78 result << m_categoriesAxis->categories().at(x);
82 result << m_categoriesAxis->categories().at(x);
79 }
83 }
@@ -90,9 +94,6 void ChartBarCategoryAxisY::updateGeometry()
90 {
94 {
91 const QVector<qreal>& layout = ChartAxis::layout();
95 const QVector<qreal>& layout = ChartAxis::layout();
92
96
93 m_minWidth = 0;
94 m_minHeight = 0;
95
96 if(layout.isEmpty()) return;
97 if(layout.isEmpty()) return;
97
98
98 QStringList ticksList = createCategoryLabels(layout);
99 QStringList ticksList = createCategoryLabels(layout);
@@ -105,15 +106,17 void ChartBarCategoryAxisY::updateGeometry()
105 Q_ASSERT(labels.size() == ticksList.size());
106 Q_ASSERT(labels.size() == ticksList.size());
106 Q_ASSERT(layout.size() == ticksList.size());
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 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
117 for (int i = 0; i < layout.size(); ++i) {
115 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
120 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
118 labelItem->setText(ticksList.at(i));
121 labelItem->setText(ticksList.at(i));
119 const QRectF& rect = labelItem->boundingRect();
122 const QRectF& rect = labelItem->boundingRect();
@@ -121,13 +124,13 void ChartBarCategoryAxisY::updateGeometry()
121 labelItem->setTransformOriginPoint(center.x(), center.y());
124 labelItem->setTransformOriginPoint(center.x(), center.y());
122
125
123 if(i==0) {
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 else {
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 labelItem->setVisible(false);
134 labelItem->setVisible(false);
132 }
135 }
133 else {
136 else {
@@ -135,15 +138,12 void ChartBarCategoryAxisY::updateGeometry()
135 height=labelItem->pos().y();
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 if ((i+1)%2 && i>1) {
141 if ((i+1)%2 && i>1) {
142 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
202 QTCOMMERCIALCHART_END_NAMESPACE
@@ -45,7 +45,7 public:
45 ~ChartBarCategoryAxisY();
45 ~ChartBarCategoryAxisY();
46
46
47 AxisType axisType() const { return Y_AXIS;}
47 AxisType axisType() const { return Y_AXIS;}
48
48 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
49 protected:
49 protected:
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
51 void updateGeometry();
51 void updateGeometry();
@@ -47,16 +47,18 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
47 if (tickCount < 2)
47 if (tickCount < 2)
48 return points;
48 return points;
49
49
50 QRectF rect = presenter()->chartsGeometry();
51
50 qreal range = axis->max() - axis->min();
52 qreal range = axis->max() - axis->min();
51 if (range > 0) {
53 if (range > 0) {
52 points.resize(tickCount);
54 points.resize(tickCount);
53 qreal scale = m_rect.width() / range;
55 qreal scale = rect.width() / range;
54 for (int i = 0; i < tickCount; ++i)
56 for (int i = 0; i < tickCount; ++i)
55 if (i < tickCount - 1) {
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 points[i] = x;
59 points[i] = x;
58 } else {
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 points[i] = x;
62 points[i] = x;
61 }
63 }
62 }
64 }
@@ -67,9 +69,6 void ChartCategoryAxisX::updateGeometry()
67 {
69 {
68 const QVector<qreal>& layout = ChartAxis::layout();
70 const QVector<qreal>& layout = ChartAxis::layout();
69
71
70 m_minWidth = 0;
71 m_minHeight = 0;
72
73 if(layout.isEmpty()) return;
72 if(layout.isEmpty()) return;
74
73
75 QCategoryAxis *categoryAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
74 QCategoryAxis *categoryAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
@@ -85,13 +84,14 void ChartCategoryAxisX::updateGeometry()
85 labels.at(i)->setVisible(false);
84 labels.at(i)->setVisible(false);
86 }
85 }
87
86
87 QRectF chartRect = presenter()->chartsGeometry();
88 // axis base line
88 // axis base line
89
89 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
93 for (int i = 0; i < layout.size(); ++i) {
93
94
94 // label items
95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
96 if (i < ticksList.count()) {
96 if (i < ticksList.count()) {
97 labelItem->setText(ticksList.at(i));
97 labelItem->setText(ticksList.at(i));
@@ -99,43 +99,42 void ChartCategoryAxisX::updateGeometry()
99 const QRectF& rect = labelItem->boundingRect();
99 const QRectF& rect = labelItem->boundingRect();
100 QPointF center = rect.center();
100 QPointF center = rect.center();
101 labelItem->setTransformOriginPoint(center.x(), center.y());
101 labelItem->setTransformOriginPoint(center.x(), center.y());
102
102 if (i < layout.size() - 1) {
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 } else {
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 // check if the label should be shown
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 labelItem->setVisible(false);
111 labelItem->setVisible(false);
111 else
112 else
112 labelItem->setVisible(true);
113 labelItem->setVisible(true);
113
114
114 m_minWidth += rect.width();
115 m_minHeight = qMax(rect.height()+ label_padding, m_minHeight);
116
117 if ((i + 1) % 2 && i > 1) {
115 if ((i + 1) % 2 && i > 1) {
118 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i / 2 - 1));
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 // grid lines and axis line ticks
120 // grid lines and axis line ticks
123 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
121 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
124 lineItem->setPos(layout[i], m_rect.top());
122 lineItem->setPos(layout[i], chartRect.top());
125 lineItem->setLine(0, 0, 0, m_rect.height());
123 lineItem->setLine(0, 0, 0, chartRect.height());
126
124
127 QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 tickLineItem->setLine(0, 0, 0, 5);
127 tickLineItem->setLine(0, 0, 0, 5);
130
128
131 // check if the grid line and the axis tick should be shown
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 lineItem->setVisible(false);
131 lineItem->setVisible(false);
134 tickLineItem->setVisible(false);
132 tickLineItem->setVisible(false);
135 } else {
133 } else {
136 lineItem->setVisible(true);
134 lineItem->setVisible(true);
137 tickLineItem->setVisible(true);
135 tickLineItem->setVisible(true);
138 }
136 }
137
139 }
138 }
140
139
141 }
140 }
@@ -146,4 +145,43 void ChartCategoryAxisX::handleAxisUpdated()
146 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
187 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartCategoryAxisX();
44 ~ChartCategoryAxisX();
45
45
46 AxisType axisType() const { return X_AXIS;}
46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 QVector<qreal> calculateLayout() const;
49 QVector<qreal> calculateLayout() const;
50 void updateGeometry();
50 void updateGeometry();
@@ -47,16 +47,18 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
47 if (tickCount < 2)
47 if (tickCount < 2)
48 return points;
48 return points;
49
49
50 QRectF rect = presenter()->chartsGeometry();
51
50 qreal range = axis->max() - axis->min();
52 qreal range = axis->max() - axis->min();
51 if (range > 0) {
53 if (range > 0) {
52 points.resize(tickCount);
54 points.resize(tickCount);
53 qreal scale = m_rect.height() / range;
55 qreal scale = rect.height() / range;
54 for (int i = 0; i < tickCount; ++i)
56 for (int i = 0; i < tickCount; ++i)
55 if (i < tickCount - 1) {
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 points[i] = y;
59 points[i] = y;
58 } else {
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 points[i] = y;
62 points[i] = y;
61 }
63 }
62 }
64 }
@@ -67,8 +69,6 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
67 void ChartCategoryAxisY::updateGeometry()
69 void ChartCategoryAxisY::updateGeometry()
68 {
70 {
69 const QVector<qreal> &layout = ChartAxis::layout();
71 const QVector<qreal> &layout = ChartAxis::layout();
70 m_minWidth = 0;
71 m_minHeight = 0;
72
72
73 if(layout.isEmpty()) {
73 if(layout.isEmpty()) {
74 return;
74 return;
@@ -88,9 +88,11 void ChartCategoryAxisY::updateGeometry()
88 labels.at(i)->setVisible(false);
88 labels.at(i)->setVisible(false);
89 }
89 }
90
90
91 QRectF chartRect = presenter()->chartsGeometry();
92
91 // axis base line
93 // axis base line
92 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
97 for (int i = 0; i < layout.size(); ++i) {
96
98
@@ -104,13 +106,14 void ChartCategoryAxisY::updateGeometry()
104 QPointF center = rect.center();
106 QPointF center = rect.center();
105 labelItem->setTransformOriginPoint(center.x(), center.y());
107 labelItem->setTransformOriginPoint(center.x(), center.y());
106
108
109
107 if (i < layout.size() - 1)
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 else
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 // check if the label should be shown
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 labelItem->setVisible(false);
117 labelItem->setVisible(false);
115 else
118 else
116 labelItem->setVisible(true);
119 labelItem->setVisible(true);
@@ -123,31 +126,29 void ChartCategoryAxisY::updateGeometry()
123 // height=labelItem->pos().y();
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 if ((i+1)%2 && i>1) {
129 if ((i+1)%2 && i>1) {
130 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 // grid lines and axis line ticks
134 // grid lines and axis line ticks
135 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
135 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
136 lineItem->setPos(m_rect.left(), layout[i]);
136 lineItem->setPos(chartRect.left(), layout[i]);
137 lineItem->setLine(0, 0, m_rect.width(), 0);
137 lineItem->setLine(0, 0, chartRect.width(), 0);
138
138
139 QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 tickLineItem->setLine(-5, 0, 0, 0);
141 tickLineItem->setLine(-5, 0, 0, 0);
142
142
143 // check if the grid line and the axis tick should be shown
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 lineItem->setVisible(false);
145 lineItem->setVisible(false);
146 tickLineItem->setVisible(false);
146 tickLineItem->setVisible(false);
147 } else {
147 } else {
148 lineItem->setVisible(true);
148 lineItem->setVisible(true);
149 tickLineItem->setVisible(true);
149 tickLineItem->setVisible(true);
150 }
150 }
151
151 }
152 }
152
153
153 }
154 }
@@ -158,4 +159,43 void ChartCategoryAxisY::handleAxisUpdated()
158 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
201 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartCategoryAxisY();
44 ~ChartCategoryAxisY();
45
45
46 AxisType axisType() const { return Y_AXIS;}
46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 QVector<qreal> calculateLayout() const;
49 QVector<qreal> calculateLayout() const;
50 void updateGeometry();
50 void updateGeometry();
@@ -27,6 +27,7
27 #include <QDateTime>
27 #include <QDateTime>
28 #include <QValueAxis>
28 #include <QValueAxis>
29 #include <QGraphicsLayout>
29 #include <QGraphicsLayout>
30 #include <QFontMetrics>
30
31
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
33
@@ -37,11 +38,10 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : ChartEleme
37 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
38 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
38 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
39 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
39 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
40 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
41 m_title(new QGraphicsSimpleTextItem(presenter->rootItem())),
40 m_min(0),
42 m_min(0),
41 m_max(0),
43 m_max(0),
42 m_animation(0),
44 m_animation(0)
43 m_minWidth(0),
44 m_minHeight(0)
45 {
45 {
46 //initial initialization
46 //initial initialization
47 m_arrow->setZValue(ChartPresenter::AxisZValue);
47 m_arrow->setZValue(ChartPresenter::AxisZValue);
@@ -139,7 +139,6 void ChartAxis::updateLayout(QVector<qreal> &layout)
139 else {
139 else {
140 setLayout(layout);
140 setLayout(layout);
141 updateGeometry();
141 updateGeometry();
142 checkLayout();
143 }
142 }
144 }
143 }
145
144
@@ -231,7 +230,15 void ChartAxis::setLabelsFont(const QFont &font)
231 foreach(QGraphicsItem* item , m_labels->childItems()) {
230 foreach(QGraphicsItem* item , m_labels->childItems()) {
232 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
231 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
233 }
232 }
233 if(m_font!=font) {
234 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 void ChartAxis::setShadesBrush(const QBrush &brush)
244 void ChartAxis::setShadesBrush(const QBrush &brush)
@@ -264,7 +271,7 void ChartAxis::setGridPen(const QPen &pen)
264
271
265 bool ChartAxis::isEmpty()
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 void ChartAxis::handleDomainUpdated()
277 void ChartAxis::handleDomainUpdated()
@@ -289,8 +296,20 void ChartAxis::handleDomainUpdated()
289 m_max = max;
296 m_max = max;
290
297
291 if (!isEmpty()) {
298 if (!isEmpty()) {
299
292 QVector<qreal> layout = calculateLayout();
300 QVector<qreal> layout = calculateLayout();
293 updateLayout(layout);
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 setGridPen(m_chartAxis->gridLinePen());
333 setGridPen(m_chartAxis->gridLinePen());
315 setShadesPen(m_chartAxis->shadesPen());
334 setShadesPen(m_chartAxis->shadesPen());
316 setShadesBrush(m_chartAxis->shadesBrush());
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 void ChartAxis::hide()
349 void ChartAxis::hide()
@@ -325,42 +354,64 void ChartAxis::hide()
325 setShadesVisibility(false);
354 setShadesVisibility(false);
326 }
355 }
327
356
328 void ChartAxis::handleGeometryChanged(const QRectF &rect)
357 void ChartAxis::setGeometry(const QRectF &rect)
329 {
330 if(m_rect != rect)
331 {
358 {
359
332 m_rect = rect;
360 m_rect = rect;
361
333 if (isEmpty()) return;
362 if (isEmpty()) return;
334 QVector<qreal> layout = calculateLayout();
335 updateLayout(layout);
336 }
337 }
338
363
364 if(!m_titleText.isNull()) {
365 QFontMetrics fn(m_title->font());
366
367 int size(0);
368
369 QRectF chartRect = presenter()->chartsGeometry();
339
370
340 qreal ChartAxis::minimumWidth()
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)
341 {
377 {
342 if(m_minWidth == 0) updateGeometry();
378 QString string = m_titleText + "...";
343 return m_minWidth;
379 while (fn.boundingRect(string).width() > size && string.length() > 3)
380 string.remove(string.length() - 4, 1);
381 m_title->setText(string);
344 }
382 }
383 else
384 m_title->setText(m_titleText);
345
385
346 qreal ChartAxis::minimumHeight()
386 QPointF center = chartRect.center() - m_title->boundingRect().center();
347 {
387 if(orientation()==Qt::Horizontal) {
348 if(m_minHeight == 0) updateGeometry();
388 m_title->setPos(center.x(),m_rect.bottom()-m_title->boundingRect().height());
349 return m_minHeight;
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 }
350 }
395 }
351
396
397 QVector<qreal> layout = calculateLayout();
398 updateLayout(layout);
399
400 }
352
401
353 void ChartAxis::axisSelected()
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 Q_ASSERT(max>min);
410 Q_ASSERT(max>min);
362 Q_ASSERT(ticks>1);
411 Q_ASSERT(ticks>1);
363
412
413 QStringList labels;
414
364 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
415 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
365 n++;
416 n++;
366
417
@@ -381,17 +432,54 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int
381 labels << QString().sprintf(array, value);
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()) {
441 return m_chartAxis->orientation();
389 presenter()->layout()->invalidate();
390 }
442 }
391
443
392 if(m_minHeight > m_rect.height()) {
444 bool ChartAxis::isVisible()
393 presenter()->layout()->invalidate();
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());
394 }
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;
480 }
481
482 return sh;
395 }
483 }
396
484
397 #include "moc_chartaxis_p.cpp"
485 #include "moc_chartaxis_p.cpp"
@@ -34,6 +34,7
34 #include "chartelement_p.h"
34 #include "chartelement_p.h"
35 #include "axisanimation_p.h"
35 #include "axisanimation_p.h"
36 #include <QGraphicsItem>
36 #include <QGraphicsItem>
37 #include <QGraphicsLayoutItem>
37 #include <QFont>
38 #include <QFont>
38
39
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -41,9 +42,10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 class QAbstractAxis;
42 class QAbstractAxis;
42 class ChartPresenter;
43 class ChartPresenter;
43
44
44 class ChartAxis : public ChartElement
45 class ChartAxis : public ChartElement, public QGraphicsLayoutItem
45 {
46 {
46 Q_OBJECT
47 Q_OBJECT
48 Q_INTERFACES(QGraphicsLayoutItem)
47 public:
49 public:
48 enum AxisType{ X_AXIS,Y_AXIS };
50 enum AxisType{ X_AXIS,Y_AXIS };
49
51
@@ -81,29 +83,38 public:
81 void setLabelsBrush(const QBrush &brush);
83 void setLabelsBrush(const QBrush &brush);
82 void setLabelsFont(const QFont &font);
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 void setLayout(QVector<qreal> &layout);
92 void setLayout(QVector<qreal> &layout);
85 QVector<qreal> layout() const { return m_layoutVector; }
93 QVector<qreal> layout() const { return m_layoutVector; }
86
94
87 void setAnimation(AxisAnimation* animation);
95 void setAnimation(AxisAnimation* animation);
88 ChartAnimation* animation() const { return m_animation; };
96 ChartAnimation* animation() const { return m_animation; };
89
97
90 QRectF geometry() const { return m_rect; }
98 Qt::Orientation orientation() const;
91
92 qreal minimumWidth();
93 qreal minimumHeight();
94
99
100 bool isVisible();
95 void hide();
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 protected:
108 protected:
98 virtual void updateGeometry() = 0;
109 virtual void updateGeometry() = 0;
99 virtual QVector<qreal> calculateLayout() const = 0;
110 virtual QVector<qreal> calculateLayout() const = 0;
100 void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
111 QStringList createNumberLabels(qreal min, qreal max,int ticks) const;
101 void checkLayout();
112
102
113
103 public Q_SLOTS:
114 public Q_SLOTS:
104 virtual void handleAxisUpdated();
115 virtual void handleAxisUpdated();
105 virtual void handleDomainUpdated();
116 virtual void handleDomainUpdated();
106 void handleGeometryChanged(const QRectF &size);
117
107
118
108 private:
119 private:
109 inline bool isEmpty();
120 inline bool isEmpty();
@@ -114,19 +125,20 private:
114
125
115 protected:
126 protected:
116 QAbstractAxis* m_chartAxis;
127 QAbstractAxis* m_chartAxis;
117 QRectF m_rect;
118 int m_labelsAngle;
128 int m_labelsAngle;
129 //TODO: to be removed
130 QRectF m_rect;
119 QScopedPointer<QGraphicsItemGroup> m_grid;
131 QScopedPointer<QGraphicsItemGroup> m_grid;
120 QScopedPointer<QGraphicsItemGroup> m_shades;
132 QScopedPointer<QGraphicsItemGroup> m_shades;
121 QScopedPointer<QGraphicsItemGroup> m_labels;
133 QScopedPointer<QGraphicsItemGroup> m_labels;
122 QScopedPointer<QGraphicsItemGroup> m_arrow;
134 QScopedPointer<QGraphicsItemGroup> m_arrow;
135 QGraphicsSimpleTextItem* m_title;
123 QVector<qreal> m_layoutVector;
136 QVector<qreal> m_layoutVector;
124 qreal m_min;
137 qreal m_min;
125 qreal m_max;
138 qreal m_max;
126 AxisAnimation *m_animation;
139 AxisAnimation *m_animation;
127 qreal m_minWidth;
128 qreal m_minHeight;
129 QFont m_font;
140 QFont m_font;
141 QString m_titleText;
130
142
131 friend class AxisAnimation;
143 friend class AxisAnimation;
132 friend class AxisItem;
144 friend class AxisItem;
@@ -61,10 +61,10 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
61
61
62 QVector<qreal> points;
62 QVector<qreal> points;
63 points.resize(m_tickCount);
63 points.resize(m_tickCount);
64
64 QRectF rect = presenter()->chartsGeometry();
65 const qreal deltaX = m_rect.width()/(m_tickCount-1);
65 const qreal deltaX = rect.width()/(m_tickCount-1);
66 for (int i = 0; i < m_tickCount; ++i) {
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 points[i] = x;
68 points[i] = x;
69 }
69 }
70 return points;
70 return points;
@@ -74,9 +74,6 void ChartDateTimeAxisX::updateGeometry()
74 {
74 {
75 const QVector<qreal>& layout = ChartAxis::layout();
75 const QVector<qreal>& layout = ChartAxis::layout();
76
76
77 m_minWidth = 0;
78 m_minHeight = 0;
79
80 if(layout.isEmpty()) return;
77 if(layout.isEmpty()) return;
81
78
82 QStringList ticksList;
79 QStringList ticksList;
@@ -91,19 +88,21 void ChartDateTimeAxisX::updateGeometry()
91 Q_ASSERT(labels.size() == ticksList.size());
88 Q_ASSERT(labels.size() == ticksList.size());
92 Q_ASSERT(layout.size() == ticksList.size());
89 Q_ASSERT(layout.size() == ticksList.size());
93
90
91 QRectF chartRect = presenter()->chartsGeometry();
92
94 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 qreal width = 0;
96 qreal width = 0;
98 for (int i = 0; i < layout.size(); ++i) {
97 for (int i = 0; i < layout.size(); ++i) {
99 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
100 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
102 labelItem->setText(ticksList.at(i));
101 labelItem->setText(ticksList.at(i));
103 const QRectF& rect = labelItem->boundingRect();
102 const QRectF& rect = labelItem->boundingRect();
104 QPointF center = rect.center();
103 QPointF center = rect.center();
105 labelItem->setTransformOriginPoint(center.x(), center.y());
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 if(labelItem->pos().x()<=width){
107 if(labelItem->pos().x()<=width){
109 labelItem->setVisible(false);
108 labelItem->setVisible(false);
@@ -113,15 +112,13 void ChartDateTimeAxisX::updateGeometry()
113 lineItem->setVisible(true);
112 lineItem->setVisible(true);
114 width=rect.width()+labelItem->pos().x();
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 if ((i+1)%2 && i>1) {
116 if ((i+1)%2 && i>1) {
120 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
170 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartDateTimeAxisX();
44 ~ChartDateTimeAxisX();
45
45
46 AxisType axisType() const { return X_AXIS;}
46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
50 void handleAxisUpdated();
50 void handleAxisUpdated();
@@ -61,10 +61,10 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
61
61
62 QVector<qreal> points;
62 QVector<qreal> points;
63 points.resize(m_tickCount);
63 points.resize(m_tickCount);
64
64 QRectF rect = presenter()->chartsGeometry();
65 const qreal deltaY = m_rect.height()/(m_tickCount-1);
65 const qreal deltaY = rect.height()/(m_tickCount-1);
66 for (int i = 0; i < m_tickCount; ++i) {
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 points[i] = y;
68 points[i] = y;
69 }
69 }
70
70
@@ -74,8 +74,6 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
74 void ChartDateTimeAxisY::updateGeometry()
74 void ChartDateTimeAxisY::updateGeometry()
75 {
75 {
76 const QVector<qreal> &layout = ChartAxis::layout();
76 const QVector<qreal> &layout = ChartAxis::layout();
77 m_minWidth = 0;
78 m_minHeight = 0;
79
77
80 if(layout.isEmpty()) return;
78 if(layout.isEmpty()) return;
81
79
@@ -91,14 +89,16 void ChartDateTimeAxisY::updateGeometry()
91 Q_ASSERT(labels.size() == ticksList.size());
89 Q_ASSERT(labels.size() == ticksList.size());
92 Q_ASSERT(layout.size() == ticksList.size());
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 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
99 for (int i = 0; i < layout.size(); ++i) {
100 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
102 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
103
103
104 labelItem->setText(ticksList.at(i));
104 labelItem->setText(ticksList.at(i));
@@ -106,7 +106,7 void ChartDateTimeAxisY::updateGeometry()
106
106
107 QPointF center = rect.center();
107 QPointF center = rect.center();
108 labelItem->setTransformOriginPoint(center.x(), center.y());
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 if(labelItem->pos().y()+rect.height()>height) {
111 if(labelItem->pos().y()+rect.height()>height) {
112 labelItem->setVisible(false);
112 labelItem->setVisible(false);
@@ -118,15 +118,12 void ChartDateTimeAxisY::updateGeometry()
118 height=labelItem->pos().y();
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 if ((i+1)%2 && i>1) {
121 if ((i+1)%2 && i>1) {
125 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
175 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartDateTimeAxisY();
44 ~ChartDateTimeAxisY();
45
45
46 AxisType axisType() const { return Y_AXIS;}
46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
49 void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
@@ -458,6 +458,90 QColor QAbstractAxis::labelsColor() const
458 return d_ptr->m_labelsBrush.color();
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 void QAbstractAxis::setShadesVisible(bool visible)
545 void QAbstractAxis::setShadesVisible(bool visible)
462 {
546 {
463 if (d_ptr->m_shadesVisible != visible) {
547 if (d_ptr->m_shadesVisible != visible) {
@@ -98,6 +98,19 public:
98 void setLabelsColor(QColor color);
98 void setLabelsColor(QColor color);
99 QColor labelsColor() const;
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 //shades handling
114 //shades handling
102 bool shadesVisible() const;
115 bool shadesVisible() const;
103 void setShadesVisible(bool visible = true);
116 void setShadesVisible(bool visible = true);
@@ -94,6 +94,12 private:
94 QFont m_labelsFont;
94 QFont m_labelsFont;
95 int m_labelsAngle;
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 bool m_shadesVisible;
103 bool m_shadesVisible;
98 QPen m_shadesPen;
104 QPen m_shadesPen;
99 QBrush m_shadesBrush;
105 QBrush m_shadesBrush;
@@ -25,6 +25,7
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28
29
29 static int label_padding = 5;
30 static int label_padding = 5;
30
31
@@ -46,9 +47,11 QVector<qreal> ChartValueAxisX::calculateLayout() const
46 QVector<qreal> points;
47 QVector<qreal> points;
47 points.resize(m_tickCount);
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 for (int i = 0; i < m_tickCount; ++i) {
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 points[i] = x;
55 points[i] = x;
53 }
56 }
54 return points;
57 return points;
@@ -58,14 +61,9 void ChartValueAxisX::updateGeometry()
58 {
61 {
59 const QVector<qreal>& layout = ChartAxis::layout();
62 const QVector<qreal>& layout = ChartAxis::layout();
60
63
61 m_minWidth = 0;
62 m_minHeight = 0;
63
64 if(layout.isEmpty()) return;
64 if(layout.isEmpty()) return;
65
65
66 QStringList ticksList;
66 QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
67
68 createNumberLabels(ticksList,m_min,m_max,layout.size());
69
67
70 QList<QGraphicsItem *> lines = m_grid->childItems();
68 QList<QGraphicsItem *> lines = m_grid->childItems();
71 QList<QGraphicsItem *> labels = m_labels->childItems();
69 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,21 +73,24 void ChartValueAxisX::updateGeometry()
75 Q_ASSERT(labels.size() == ticksList.size());
73 Q_ASSERT(labels.size() == ticksList.size());
76 Q_ASSERT(layout.size() == ticksList.size());
74 Q_ASSERT(layout.size() == ticksList.size());
77
75
76 QRectF chartRrect = presenter()->chartsGeometry();
77
78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 qreal width = 0;
81 qreal width = 0;
82 for (int i = 0; i < layout.size(); ++i) {
82 for (int i = 0; i < layout.size(); ++i) {
83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 labelItem->setText(ticksList.at(i));
86 labelItem->setText(ticksList.at(i));
87 const QRectF& rect = labelItem->boundingRect();
87 const QRectF& rect = labelItem->boundingRect();
88 QPointF center = rect.center();
88 QPointF center = rect.center();
89 labelItem->setTransformOriginPoint(center.x(), center.y());
89 labelItem->setTransformOriginPoint(center.x(), center.y());
90 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
90 labelItem->setPos(layout[i] - center.x(), chartRrect.bottom() + label_padding);
91
91 if(labelItem->pos().x() <= width ||
92 if(labelItem->pos().x()<=width){
92 labelItem->pos().x() < m_rect.left() ||
93 labelItem->pos().x() + rect.width() > m_rect.right()){
93 labelItem->setVisible(false);
94 labelItem->setVisible(false);
94 lineItem->setVisible(false);
95 lineItem->setVisible(false);
95 }else{
96 }else{
@@ -97,17 +98,14 void ChartValueAxisX::updateGeometry()
97 lineItem->setVisible(true);
98 lineItem->setVisible(true);
98 width=rect.width()+labelItem->pos().x();
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 if ((i+1)%2 && i>1) {
102 if ((i+1)%2 && i>1) {
104 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 void ChartValueAxisX::handleAxisUpdated()
111 void ChartValueAxisX::handleAxisUpdated()
@@ -118,4 +116,45 void ChartValueAxisX::handleAxisUpdated()
118 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
160 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartValueAxisX();
44 ~ChartValueAxisX();
45
45
46 AxisType axisType() const { return X_AXIS;}
46 AxisType axisType() const { return X_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 void handleAxisUpdated();
49 void handleAxisUpdated();
50 QVector<qreal> calculateLayout() const;
50 QVector<qreal> calculateLayout() const;
@@ -25,6 +25,7
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28
29
29 static int label_padding = 5;
30 static int label_padding = 5;
30
31
@@ -46,9 +47,11 QVector<qreal> ChartValueAxisY::calculateLayout() const
46 QVector<qreal> points;
47 QVector<qreal> points;
47 points.resize(m_tickCount);
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 for (int i = 0; i < m_tickCount; ++i) {
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 points[i] = y;
55 points[i] = y;
53 }
56 }
54
57
@@ -58,14 +61,10 QVector<qreal> ChartValueAxisY::calculateLayout() const
58 void ChartValueAxisY::updateGeometry()
61 void ChartValueAxisY::updateGeometry()
59 {
62 {
60 const QVector<qreal> &layout = ChartAxis::layout();
63 const QVector<qreal> &layout = ChartAxis::layout();
61 m_minWidth = 0;
62 m_minHeight = 0;
63
64
64 if(layout.isEmpty()) return;
65 if(layout.isEmpty()) return;
65
66
66 QStringList ticksList;
67 QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
67
68 createNumberLabels(ticksList,m_min,m_max,layout.size());
69
68
70 QList<QGraphicsItem *> lines = m_grid->childItems();
69 QList<QGraphicsItem *> lines = m_grid->childItems();
71 QList<QGraphicsItem *> labels = m_labels->childItems();
70 QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,44 +74,55 void ChartValueAxisY::updateGeometry()
75 Q_ASSERT(labels.size() == ticksList.size());
74 Q_ASSERT(labels.size() == ticksList.size());
76 Q_ASSERT(layout.size() == ticksList.size());
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 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
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 for (int i = 0; i < layout.size(); ++i) {
86 for (int i = 0; i < layout.size(); ++i) {
84 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
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 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
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 const QRectF& rect = labelItem->boundingRect();
103 const QRectF& rect = labelItem->boundingRect();
90
104
91 QPointF center = rect.center();
105 QPointF center = rect.center();
92 labelItem->setTransformOriginPoint(center.x(), center.y());
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 labelItem->setVisible(false);
111 labelItem->setVisible(false);
97 lineItem->setVisible(false);
112 lineItem->setVisible(false);
98 }
113 }else{
99 else {
100 labelItem->setVisible(true);
114 labelItem->setVisible(true);
101 lineItem->setVisible(true);
115 lineItem->setVisible(true);
102 height=labelItem->pos().y();
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 if ((i+1)%2 && i>1) {
119 if ((i+1)%2 && i>1) {
109 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
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 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
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 void ChartValueAxisY::handleAxisUpdated()
128 void ChartValueAxisY::handleAxisUpdated()
@@ -123,5 +133,43 void ChartValueAxisY::handleAxisUpdated()
123 ChartAxis::handleAxisUpdated();
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 QTCOMMERCIALCHART_END_NAMESPACE
175 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 public:
44 ~ChartValueAxisY();
44 ~ChartValueAxisY();
45
45
46 AxisType axisType() const { return Y_AXIS;}
46 AxisType axisType() const { return Y_AXIS;}
47
47 QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
48 protected:
48 protected:
49 QVector<qreal> calculateLayout() const;
49 QVector<qreal> calculateLayout() const;
50 void updateGeometry();
50 void updateGeometry();
@@ -50,7 +50,6 public:
50 protected:
50 protected:
51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52
52
53
54 private:
53 private:
55 int roundness(qreal size) const;
54 int roundness(qreal size) const;
56
55
@@ -22,17 +22,20
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlegend_p.h"
23 #include "qlegend_p.h"
24 #include "chartaxis_p.h"
24 #include "chartaxis_p.h"
25 #include "charttitle_p.h"
26 #include "chartbackground_p.h"
27 #include "layoutdebuger_p.h"
28 #include "legendmarker_p.h"
25 #include <QDebug>
29 #include <QDebug>
26
30
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
32
33 static const qreal golden_ratio = 0.25;
34
29 ChartLayout::ChartLayout(ChartPresenter* presenter):
35 ChartLayout::ChartLayout(ChartPresenter* presenter):
30 m_presenter(presenter),
36 m_presenter(presenter),
31 m_marginBig(60),
37 m_margins(20,20,20,20),
32 m_marginSmall(20),
38 m_minChartRect(0,0,200,200)
33 m_marginTiny(10),
34 m_chartMargins(m_marginBig,m_marginBig,m_marginBig,m_marginBig),
35 m_intialized(false)
36 {
39 {
37
40
38 }
41 }
@@ -44,85 +47,146 ChartLayout::~ChartLayout()
44
47
45 void ChartLayout::setGeometry(const QRectF& rect)
48 void ChartLayout::setGeometry(const QRectF& rect)
46 {
49 {
50 Q_ASSERT(rect.isValid());
51
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();
56
57 QRectF contentGeometry = calculateBackgroundGeometry(rect,background);
58
59 contentGeometry = calculateContentGeometry(contentGeometry);
60
61 if (title && title->isVisible()) {
62 contentGeometry = calculateTitleGeometry(contentGeometry,title);
63 }
64
65 if (legend->isAttachedToChart() && legend->isVisible()) {
66 contentGeometry = calculateLegendGeometry(contentGeometry,legend);
67 }
47
68
48 if (!rect.isValid()) return;
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());
83 }
84 #endif
49
85
50 QGraphicsLayout::setGeometry(rect);
86 QGraphicsLayout::setGeometry(rect);
87 }
51
88
52 if(!m_intialized){
89 QRectF ChartLayout::calculateContentGeometry(const QRectF& geometry) const
53 m_presenter->setGeometry(rect);
90 {
54 m_intialized=true;
91 return geometry.adjusted(m_margins.left(),m_margins.top(),-m_margins.right(),-m_margins.bottom());
55 }
92 }
56
93
57 // check title size
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 }
58
98
59 QSize titleSize = QSize(0,0);
60
99
61 if (m_presenter->titleItem()) {
100 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const
62 titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
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;
63 }
107 }
64
108
65 qreal axisHeight = 0;
109 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF& minimum) const
66 qreal axisWidth = 0;
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 // check axis size
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();
133 qreal width = qMin(vertical.width(),geometry.width() * golden_ratio);
78 Q_ASSERT(legend);
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;
139 foreach(ChartAxis* axis , axes) {
85 chartMargins.setLeft(qMax(m_chartMargins.left(),int(axisWidth + 2*m_marginTiny)));
140 axis->setGeometry(geometry);
86 chartMargins.setBottom(qMax(m_chartMargins.bottom(),int(axisHeight + 2* m_marginTiny)));
141 }
87
142
143 return rect;
144 }
88
145
89 // recalculate legend position
146 QRectF ChartLayout::calculateAxisMinimum(const QRectF& minimum, const QList<ChartAxis*>& axes) const
90 if ((legend->isAttachedToChart() && legend->isVisible())) {
147 {
148 QSizeF vertical(0,0);
149 QSizeF horizontal(0,0);
150
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 }
161
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;
91
167
92 // Reserve some space for legend
93 switch (legend->alignment()) {
168 switch (legend->alignment()) {
94
169
95 case Qt::AlignTop: {
170 case Qt::AlignTop: {
96
171 legendRect = QRectF(geometry.topLeft(),QSizeF(geometry.width(),size.height()));
97 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
172 result = geometry.adjusted(0,legendRect.height(),0,0);
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;
102 break;
173 break;
103 }
174 }
104 case Qt::AlignBottom: {
175 case Qt::AlignBottom: {
105 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
176 legendRect = QRectF(QPointF(geometry.left(),geometry.bottom()-size.height()),QSizeF(geometry.width(),size.height()));
106 int bottomMargin = m_marginTiny + legendSize.height() + m_marginTiny + axisHeight;
177 result = geometry.adjusted(0,0,0,-legendRect.height());
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;
110 break;
178 break;
111 }
179 }
112 case Qt::AlignLeft: {
180 case Qt::AlignLeft: {
113 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
181 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
114 int leftPadding = m_marginTiny + legendSize.width() + m_marginTiny + axisWidth;
182 legendRect = QRectF(geometry.topLeft(),QSizeF(width,geometry.height()));
115 chartMargins = QMargins(leftPadding,chartMargins.top(),chartMargins.right(),chartMargins.bottom());
183 result = geometry.adjusted(width,0,0,0);
116 m_legendMargins = QMargins(m_marginTiny + m_marginSmall,chartMargins.top(),rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom());
117 titlePadding = chartMargins.top()/2;
118 break;
184 break;
119 }
185 }
120 case Qt::AlignRight: {
186 case Qt::AlignRight: {
121 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
187 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
122 int rightPadding = m_marginTiny + legendSize.width() + m_marginTiny;
188 legendRect = QRectF(QPointF(geometry.right()-width,geometry.top()),QSizeF(width,geometry.height()));
123 chartMargins = QMargins(chartMargins.left(),chartMargins.top(),rightPadding,chartMargins.bottom());
189 result = geometry.adjusted(0,0,-width,0);
124 m_legendMargins = QMargins(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top(),m_marginTiny + m_marginSmall,chartMargins.bottom());
125 titlePadding = chartMargins.top()/2;
126 break;
190 break;
127 }
191 }
128 default: {
192 default: {
@@ -130,51 +194,66 void ChartLayout::setGeometry(const QRectF& rect)
130 }
194 }
131 }
195 }
132
196
133 legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
197 legend->setGeometry(legendRect);
134 }
135
198
136 // recalculate title position
199 return result;
137 if (m_presenter->titleItem()) {
138 QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
139 m_presenter->titleItem()->setPos(center.x(),titlePadding);
140 }
200 }
141
201
142 //recalculate background gradient
202 QRectF ChartLayout::calculateLegendMinimum(const QRectF& geometry,QLegend* legend) const
143 if (m_presenter->backgroundItem()) {
203 {
144 m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
204 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize,QSizeF(-1,-1));
205 return geometry.adjusted(0,0,minSize.width(),minSize.height());
145 }
206 }
146
207
147 QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
208 QRectF ChartLayout::calculateTitleGeometry(const QRectF& geometry,ChartTitle* title) const
148
209 {
149 if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
210 title->setGeometry(geometry);
150 m_presenter->setGeometry(chartRect);
211 QPointF center = geometry.center() - title->boundingRect().center();
151 }else if(chartRect.size().isEmpty()){
212 title->setPos(center.x(),title->pos().y());
152 m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
213 return geometry.adjusted(0,title->boundingRect().height(),0,0);
153 }
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 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
222 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
158 {
223 {
159 Q_UNUSED(constraint);
224 Q_UNUSED(constraint);
160 if(which == Qt::MinimumSize)
225 if(which == Qt::MinimumSize){
161 return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
226 QList<ChartAxis*> axes = m_presenter->axisItems();
162 else
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 return QSize(-1,-1);
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){
243 if(m_margins != margins){
170 m_chartMargins = margins;
244 m_margins = margins;
171 updateGeometry();
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 QTCOMMERCIALCHART_END_NAMESPACE
259 QTCOMMERCIALCHART_END_NAMESPACE
@@ -27,6 +27,10
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 class ChartPresenter;
29 class ChartPresenter;
30 class ChartTitle;
31 class QLegend;
32 class ChartAxis;
33 class ChartBackground;
30
34
31 class ChartLayout : public QGraphicsLayout
35 class ChartLayout : public QGraphicsLayout
32 {
36 {
@@ -35,10 +39,11 public:
35 ChartLayout(ChartPresenter* presenter);
39 ChartLayout(ChartPresenter* presenter);
36 virtual ~ChartLayout();
40 virtual ~ChartLayout();
37
41
38 void setMinimumMargins(const QMargins& margins);
42 void setMargins(const QMargins& margins);
39 QMargins minimumMargins() const;
43 QMargins margins() const;
40
44
41 void setGeometry(const QRectF& rect);
45 void setGeometry(const QRectF& rect);
46 void adjustChartGeometry();
42
47
43 protected:
48 protected:
44 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
49 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
@@ -47,15 +52,22 protected:
47 void removeAt(int){};
52 void removeAt(int){};
48
53
49 private:
54 private:
50 ChartPresenter* m_presenter;
55 QRectF calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const;
51 int m_marginBig;
56 QRectF calculateContentGeometry(const QRectF& geometry) const;
52 int m_marginSmall;
57 QRectF calculateTitleGeometry(const QRectF& geometry, ChartTitle* title) const;
53 int m_marginTiny;
58 QRectF calculateChartGeometry(const QRectF& geometry,const QList<ChartAxis*>& axes) const;
54 QMargins m_chartMargins;
59 QRectF calculateLegendGeometry(const QRectF& geometry, QLegend* legend) const;
55 QMargins m_legendMargins;
60 QRectF calculateBackgroundMinimum(const QRectF& minimum) const;
56 bool m_intialized;
61 QRectF calculateContentMinimum(const QRectF& minimum) const;
57
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 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -28,11 +28,9
28 #include "qabstractseries_p.h"
28 #include "qabstractseries_p.h"
29 #include "qareaseries.h"
29 #include "qareaseries.h"
30 #include "chartaxis_p.h"
30 #include "chartaxis_p.h"
31 //#include "chartaxisx_p.h"
32 //#include "chartaxisy_p.h"
33 #include "areachartitem_p.h"
34 #include "chartbackground_p.h"
31 #include "chartbackground_p.h"
35 #include "chartlayout_p.h"
32 #include "chartlayout_p.h"
33 #include "charttitle_p.h"
36 #include <QTimer>
34 #include <QTimer>
37
35
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -44,8 +42,8 m_chartTheme(0),
44 m_options(QChart::NoAnimation),
42 m_options(QChart::NoAnimation),
45 m_state(ShowState),
43 m_state(ShowState),
46 m_layout(new ChartLayout(this)),
44 m_layout(new ChartLayout(this)),
47 m_backgroundItem(0),
45 m_background(0),
48 m_titleItem(0)
46 m_title(0)
49 {
47 {
50
48
51 }
49 }
@@ -55,17 +53,24 ChartPresenter::~ChartPresenter()
55 delete m_chartTheme;
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 Q_ASSERT(rect.isValid());
58 Q_ASSERT(rect.isValid());
62
59
63 if(m_rect!=rect) {
60 if(m_chartsRect!=rect) {
64 m_rect=rect;
61 m_chartsRect=rect;
65 emit geometryChanged(m_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 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
74 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
70 {
75 {
71 ChartAxis* item = axis->d_ptr->createGraphics(this);
76 ChartAxis* item = axis->d_ptr->createGraphics(this);
@@ -84,7 +89,7 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
84 m_chartTheme->decorate(axis);
89 m_chartTheme->decorate(axis);
85 axis->d_ptr->setDirty(false);
90 axis->d_ptr->setDirty(false);
86 axis->d_ptr->emitUpdated();
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 m_axisItems.insert(axis, item);
94 m_axisItems.insert(axis, item);
90 selectVisibleAxis();
95 selectVisibleAxis();
@@ -113,7 +118,7 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
113 //initialize
118 //initialize
114 item->handleDomainUpdated();
119 item->handleDomainUpdated();
115
120
116 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
121 if(m_chartsRect.isValid()) item->handleGeometryChanged(m_chartsRect);
117 m_chartItems.insert(series,item);
122 m_chartItems.insert(series,item);
118 }
123 }
119
124
@@ -222,27 +227,29 void ChartPresenter::resetAllElements()
222 handleSeriesRemoved(series);
227 handleSeriesRemoved(series);
223 handleSeriesAdded(series,domain);
228 handleSeriesAdded(series,domain);
224 }
229 }
230
231 layout()->invalidate();
225 }
232 }
226
233
227 void ChartPresenter::zoomIn(qreal factor)
234 void ChartPresenter::zoomIn(qreal factor)
228 {
235 {
229 QRectF rect = geometry();
236 QRectF rect = chartsGeometry();
230 rect.setWidth(rect.width()/factor);
237 rect.setWidth(rect.width()/factor);
231 rect.setHeight(rect.height()/factor);
238 rect.setHeight(rect.height()/factor);
232 rect.moveCenter(geometry().center());
239 rect.moveCenter(chartsGeometry().center());
233 zoomIn(rect);
240 zoomIn(rect);
234 }
241 }
235
242
236 void ChartPresenter::zoomIn(const QRectF& rect)
243 void ChartPresenter::zoomIn(const QRectF& rect)
237 {
244 {
238 QRectF r = rect.normalized();
245 QRectF r = rect.normalized();
239 r.translate(-geometry().topLeft());
246 r.translate(-chartsGeometry().topLeft());
240 if (!r.isValid())
247 if (!r.isValid())
241 return;
248 return;
242
249
243 m_state = ZoomInState;
250 m_state = ZoomInState;
244 m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
251 m_statePoint = QPointF(r.center().x()/chartsGeometry().width(),r.center().y()/chartsGeometry().height());
245 m_dataset->zoomInDomain(r,geometry().size());
252 m_dataset->zoomInDomain(r,chartsGeometry().size());
246 m_state = ShowState;
253 m_state = ShowState;
247 }
254 }
248
255
@@ -251,14 +258,14 void ChartPresenter::zoomOut(qreal factor)
251 m_state = ZoomOutState;
258 m_state = ZoomOutState;
252
259
253 QRectF chartRect;
260 QRectF chartRect;
254 chartRect.setSize(geometry().size());
261 chartRect.setSize(chartsGeometry().size());
255
262
256 QRectF rect;
263 QRectF rect;
257 rect.setSize(chartRect.size()/factor);
264 rect.setSize(chartRect.size()/factor);
258 rect.moveCenter(chartRect.center());
265 rect.moveCenter(chartRect.center());
259 if (!rect.isValid())
266 if (!rect.isValid())
260 return;
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 m_dataset->zoomOutDomain(rect, chartRect.size());
269 m_dataset->zoomOutDomain(rect, chartRect.size());
263 m_state = ShowState;
270 m_state = ShowState;
264 }
271 }
@@ -270,7 +277,7 void ChartPresenter::scroll(qreal dx,qreal dy)
270 if(dy<0) m_state=ScrollUpState;
277 if(dy<0) m_state=ScrollUpState;
271 if(dy>0) m_state=ScrollDownState;
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 m_state = ShowState;
281 m_state = ShowState;
275 }
282 }
276
283
@@ -281,18 +288,18 QChart::AnimationOptions ChartPresenter::animationOptions() const
281
288
282 void ChartPresenter::createBackgroundItem()
289 void ChartPresenter::createBackgroundItem()
283 {
290 {
284 if (!m_backgroundItem) {
291 if (!m_background) {
285 m_backgroundItem = new ChartBackground(rootItem());
292 m_background = new ChartBackground(rootItem());
286 m_backgroundItem->setPen(Qt::NoPen);
293 m_background->setPen(Qt::NoPen);
287 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
294 m_background->setZValue(ChartPresenter::BackgroundZValue);
288 }
295 }
289 }
296 }
290
297
291 void ChartPresenter::createTitleItem()
298 void ChartPresenter::createTitleItem()
292 {
299 {
293 if (!m_titleItem) {
300 if (!m_title) {
294 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
301 m_title = new ChartTitle(rootItem());
295 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
302 m_title->setZValue(ChartPresenter::BackgroundZValue);
296 }
303 }
297 }
304 }
298
305
@@ -313,104 +320,94 void ChartPresenter::startAnimation(ChartAnimation* animation)
313 QTimer::singleShot(0, animation, SLOT(start()));
320 QTimer::singleShot(0, animation, SLOT(start()));
314 }
321 }
315
322
316 QGraphicsRectItem* ChartPresenter::backgroundItem()
317 {
318 return m_backgroundItem;
319 }
320
321 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
323 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
322 {
324 {
323 createBackgroundItem();
325 createBackgroundItem();
324 m_backgroundItem->setBrush(brush);
326 m_background->setBrush(brush);
325 m_layout->invalidate();
327 m_layout->invalidate();
326 }
328 }
327
329
328 QBrush ChartPresenter::backgroundBrush() const
330 QBrush ChartPresenter::backgroundBrush() const
329 {
331 {
330 if (!m_backgroundItem) return QBrush();
332 if (!m_background) return QBrush();
331 return m_backgroundItem->brush();
333 return m_background->brush();
332 }
334 }
333
335
334 void ChartPresenter::setBackgroundPen(const QPen& pen)
336 void ChartPresenter::setBackgroundPen(const QPen& pen)
335 {
337 {
336 createBackgroundItem();
338 createBackgroundItem();
337 m_backgroundItem->setPen(pen);
339 m_background->setPen(pen);
338 m_layout->invalidate();
340 m_layout->invalidate();
339 }
341 }
340
342
341 QPen ChartPresenter::backgroundPen() const
343 QPen ChartPresenter::backgroundPen() const
342 {
344 {
343 if (!m_backgroundItem) return QPen();
345 if (!m_background) return QPen();
344 return m_backgroundItem->pen();
346 return m_background->pen();
345 }
346
347 QGraphicsItem* ChartPresenter::titleItem()
348 {
349 return m_titleItem;
350 }
347 }
351
348
352 void ChartPresenter::setTitle(const QString& title)
349 void ChartPresenter::setTitle(const QString& title)
353 {
350 {
354 createTitleItem();
351 createTitleItem();
355 m_titleItem->setText(title);
352 m_title->setText(title);
356 m_layout->invalidate();
353 m_layout->invalidate();
357 }
354 }
358
355
359 QString ChartPresenter::title() const
356 QString ChartPresenter::title() const
360 {
357 {
361 if (!m_titleItem) return QString();
358 if (!m_title) return QString();
362 return m_titleItem->text();
359 return m_title->text();
363 }
360 }
364
361
365 void ChartPresenter::setTitleFont(const QFont& font)
362 void ChartPresenter::setTitleFont(const QFont& font)
366 {
363 {
367 createTitleItem();
364 createTitleItem();
368 m_titleItem->setFont(font);
365 m_title->setFont(font);
369 m_layout->invalidate();
366 m_layout->invalidate();
370 }
367 }
371
368
372 QFont ChartPresenter::titleFont() const
369 QFont ChartPresenter::titleFont() const
373 {
370 {
374 if (!m_titleItem) return QFont();
371 if (!m_title) return QFont();
375 return m_titleItem->font();
372 return m_title->font();
376 }
373 }
377
374
378 void ChartPresenter::setTitleBrush(const QBrush &brush)
375 void ChartPresenter::setTitleBrush(const QBrush &brush)
379 {
376 {
380 createTitleItem();
377 createTitleItem();
381 m_titleItem->setBrush(brush);
378 m_title->setBrush(brush);
382 m_layout->invalidate();
379 m_layout->invalidate();
383 }
380 }
384
381
385 QBrush ChartPresenter::titleBrush() const
382 QBrush ChartPresenter::titleBrush() const
386 {
383 {
387 if (!m_titleItem) return QBrush();
384 if (!m_title) return QBrush();
388 return m_titleItem->brush();
385 return m_title->brush();
389 }
386 }
390
387
391 void ChartPresenter::setBackgroundVisible(bool visible)
388 void ChartPresenter::setBackgroundVisible(bool visible)
392 {
389 {
393 createBackgroundItem();
390 createBackgroundItem();
394 m_backgroundItem->setVisible(visible);
391 m_background->setVisible(visible);
395 }
392 }
396
393
397
394
398 bool ChartPresenter::isBackgroundVisible() const
395 bool ChartPresenter::isBackgroundVisible() const
399 {
396 {
400 if (!m_backgroundItem) return false;
397 if (!m_background) return false;
401 return m_backgroundItem->isVisible();
398 return m_background->isVisible();
402 }
399 }
403
400
404 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
401 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
405 {
402 {
406 createBackgroundItem();
403 createBackgroundItem();
407 m_backgroundItem->setDropShadowEnabled(enabled);
404 m_background->setDropShadowEnabled(enabled);
408 }
405 }
409
406
410 bool ChartPresenter::isBackgroundDropShadowEnabled() const
407 bool ChartPresenter::isBackgroundDropShadowEnabled() const
411 {
408 {
412 if (!m_backgroundItem) return false;
409 if (!m_background) return false;
413 return m_backgroundItem->isDropShadowEnabled();
410 return m_background->isDropShadowEnabled();
414 }
411 }
415
412
416
413
@@ -419,14 +416,14 QGraphicsLayout* ChartPresenter::layout()
419 return m_layout;
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 QLegend* ChartPresenter::legend()
429 QLegend* ChartPresenter::legend()
@@ -434,14 +431,24 QLegend* ChartPresenter::legend()
434 return m_chart->legend();
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 QList<ChartAxis*> ChartPresenter::axisItems() const
444 QList<ChartAxis*> ChartPresenter::axisItems() const
438 {
445 {
439 return m_axisItems.values();
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 #include "moc_chartpresenter_p.cpp"
454 #include "moc_chartpresenter_p.cpp"
@@ -45,6 +45,7 class ChartAxis;
45 class ChartTheme;
45 class ChartTheme;
46 class ChartAnimator;
46 class ChartAnimator;
47 class ChartBackground;
47 class ChartBackground;
48 class ChartTitle;
48 class ChartAnimation;
49 class ChartAnimation;
49 class ChartLayout;
50 class ChartLayout;
50
51
@@ -83,8 +84,8 public:
83 ChartTheme *chartTheme() const { return m_chartTheme; }
84 ChartTheme *chartTheme() const { return m_chartTheme; }
84 ChartDataSet *dataSet() const { return m_dataset; }
85 ChartDataSet *dataSet() const { return m_dataset; }
85 QGraphicsItem* rootItem() const { return m_chart; }
86 QGraphicsItem* rootItem() const { return m_chart; }
86 QGraphicsRectItem* backgroundItem();
87 ChartBackground* backgroundElement();
87 QGraphicsItem* titleItem();
88 ChartTitle* titleElement();
88 QList<ChartAxis*> axisItems() const;
89 QList<ChartAxis*> axisItems() const;
89
90
90 QLegend* legend();
91 QLegend* legend();
@@ -123,8 +124,8 public:
123 void zoomOut(qreal factor);
124 void zoomOut(qreal factor);
124 void scroll(qreal dx,qreal dy);
125 void scroll(qreal dx,qreal dy);
125
126
126 void setGeometry(const QRectF& rect);
127 void setChartsGeometry(const QRectF& rect);
127 QRectF geometry() { return m_rect; }
128 QRectF chartsGeometry() const;
128
129
129 void startAnimation(ChartAnimation* animation);
130 void startAnimation(ChartAnimation* animation);
130 State state() const { return m_state; }
131 State state() const { return m_state; }
@@ -132,8 +133,8 public:
132
133
133 void resetAllElements();
134 void resetAllElements();
134
135
135 void setMinimumMargins(const QMargins& margins);
136 void setMargins(const QMargins& margins);
136 QMargins minimumMargins() const;
137 QMargins margins() const;
137 QGraphicsLayout* layout();
138 QGraphicsLayout* layout();
138
139
139 private:
140 private:
@@ -162,14 +163,14 private:
162 ChartTheme *m_chartTheme;
163 ChartTheme *m_chartTheme;
163 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
164 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
164 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
165 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
165 QRectF m_rect;
166 QRectF m_chartsRect;
166 QChart::AnimationOptions m_options;
167 QChart::AnimationOptions m_options;
167 State m_state;
168 State m_state;
168 QPointF m_statePoint;
169 QPointF m_statePoint;
169 QList<ChartAnimation*> m_animations;
170 QList<ChartAnimation*> m_animations;
170 ChartLayout* m_layout;
171 ChartLayout* m_layout;
171 ChartBackground* m_backgroundItem;
172 ChartBackground* m_background;
172 QGraphicsSimpleTextItem* m_titleItem;
173 ChartTitle* m_title;
173 };
174 };
174
175
175 QTCOMMERCIALCHART_END_NAMESPACE
176 QTCOMMERCIALCHART_END_NAMESPACE
@@ -178,7 +178,6 void Domain::handleAxisUpdated()
178 }else if(axis->orientation()==Qt::Vertical){
178 }else if(axis->orientation()==Qt::Vertical){
179 setRangeY(axis->min(),axis->max());
179 setRangeY(axis->min(),axis->max());
180 }
180 }
181
182 }
181 }
183
182
184 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2)
183 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2)
@@ -22,6 +22,7
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "legendmarker_p.h"
23 #include "legendmarker_p.h"
24 #include "qlegend_p.h"
24 #include "qlegend_p.h"
25 #include <QDebug>
25
26
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28
@@ -58,6 +59,9 void LegendLayout::setOffset(qreal x, qreal y)
58 }
59 }
59
60
60 QRectF boundingRect = geometry();
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 // Limit offset between m_minOffset and m_maxOffset
66 // Limit offset between m_minOffset and m_maxOffset
63 if (scrollHorizontal) {
67 if (scrollHorizontal) {
@@ -112,16 +116,20 void LegendLayout::setAttachedGeometry(const QRectF& rect)
112 m_width=0;
116 m_width=0;
113 m_height=0;
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 switch(m_legend->alignment()) {
124 switch(m_legend->alignment()) {
116
125
117 case Qt::AlignTop:
126 case Qt::AlignTop:
118
119 case Qt::AlignBottom: {
127 case Qt::AlignBottom: {
120 QPointF point(0,0);
128 QPointF point(0,0);
121 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
129 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
122 if (marker->isVisible()) {
130 if (marker->isVisible()) {
123 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
131 marker->setGeometry(geometry);
124 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
132 marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
125 const QRectF& rect = marker->boundingRect();
133 const QRectF& rect = marker->boundingRect();
126 size = size.expandedTo(rect.size());
134 size = size.expandedTo(rect.size());
127 qreal w = rect.width();
135 qreal w = rect.width();
@@ -129,12 +137,12 void LegendLayout::setAttachedGeometry(const QRectF& rect)
129 point.setX(point.x() + w);
137 point.setX(point.x() + w);
130 }
138 }
131 }
139 }
132 if(m_width<rect.width()) {
140 if(m_width<geometry.width()) {
133 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
141 m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
134
142
135 }
143 }
136 else {
144 else {
137 m_legend->d_ptr->items()->setPos(rect.topLeft());
145 m_legend->d_ptr->items()->setPos(geometry.topLeft());
138 }
146 }
139 m_height=size.height();
147 m_height=size.height();
140 }
148 }
@@ -144,7 +152,7 void LegendLayout::setAttachedGeometry(const QRectF& rect)
144 QPointF point(0,0);
152 QPointF point(0,0);
145 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
153 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
146 if (marker->isVisible()) {
154 if (marker->isVisible()) {
147 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
155 marker->setGeometry(geometry);
148 marker->setPos(point);
156 marker->setPos(point);
149 const QRectF& rect = marker->boundingRect();
157 const QRectF& rect = marker->boundingRect();
150 qreal h = rect.height();
158 qreal h = rect.height();
@@ -153,21 +161,22 void LegendLayout::setAttachedGeometry(const QRectF& rect)
153 point.setY(point.y() + h);
161 point.setY(point.y() + h);
154 }
162 }
155 }
163 }
156 if(m_height<rect.height()) {
164 if(m_height<geometry.height()) {
157 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
165 m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
158 }
166 }
159 else {
167 else {
160 m_legend->d_ptr->items()->setPos(rect.topLeft());
168 m_legend->d_ptr->items()->setPos(geometry.topLeft());
161 }
169 }
162 m_width=size.width();
170 m_width=size.width();
163 }
171 }
164 break;
172 break;
165 }
173 }
166
174
167 m_minOffsetX = 0;
175
168 m_minOffsetY = 0;
176 m_minOffsetX = -left;
169 m_maxOffsetX = m_width - rect.width();
177 m_minOffsetY = - top;
170 m_maxOffsetY = m_height - rect.height();
178 m_maxOffsetX = m_width - geometry.width() - right;
179 m_maxOffsetY = m_height - geometry.height() - bottom;
171 }
180 }
172
181
173 void LegendLayout::setDettachedGeometry(const QRectF& rect)
182 void LegendLayout::setDettachedGeometry(const QRectF& rect)
@@ -182,6 +191,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
182 m_offsetX=0;
191 m_offsetX=0;
183 m_offsetY=0;
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 QSizeF size(0,0);
198 QSizeF size(0,0);
186
199
187 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
200 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
@@ -190,13 +203,13 void LegendLayout::setDettachedGeometry(const QRectF& rect)
190
203
191 switch (m_legend->alignment()) {
204 switch (m_legend->alignment()) {
192 case Qt::AlignTop: {
205 case Qt::AlignTop: {
193 QPointF point = rect.topLeft();
206 QPointF point(0,0);
194 m_width = 0;
207 m_width = 0;
195 m_height = 0;
208 m_height = 0;
196 for (int i=0; i<markers.count(); i++) {
209 for (int i=0; i<markers.count(); i++) {
197 LegendMarker *marker = markers.at(i);
210 LegendMarker *marker = markers.at(i);
198 if (marker->isVisible()) {
211 if (marker->isVisible()) {
199 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
212 marker->setGeometry(geometry);
200 marker->setPos(point.x(),point.y());
213 marker->setPos(point.x(),point.y());
201 const QRectF& boundingRect = marker->boundingRect();
214 const QRectF& boundingRect = marker->boundingRect();
202 qreal w = boundingRect.width();
215 qreal w = boundingRect.width();
@@ -204,9 +217,9 void LegendLayout::setDettachedGeometry(const QRectF& rect)
204 m_width = qMax(m_width,w);
217 m_width = qMax(m_width,w);
205 m_height = qMax(m_height,h);
218 m_height = qMax(m_height,h);
206 point.setX(point.x() + w);
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 // Next item would go off rect.
221 // Next item would go off rect.
209 point.setX(rect.topLeft().x());
222 point.setX(0);
210 point.setY(point.y() + h);
223 point.setY(point.y() + h);
211 if (i+1 < markers.count()) {
224 if (i+1 < markers.count()) {
212 m_height += h;
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;
232 m_minOffsetX = -left;
220 m_minOffsetY = 0;
233 m_minOffsetY = -top;
221 m_maxOffsetX = m_width - rect.width();
234 m_maxOffsetX = m_width - geometry.width() - right;
222 m_maxOffsetY = m_height - rect.height();
235 m_maxOffsetY = m_height - geometry.height() - bottom;
223 }
236 }
224 break;
237 break;
225 case Qt::AlignBottom: {
238 case Qt::AlignBottom: {
226 QPointF point = rect.bottomLeft();
239 QPointF point(0,geometry.height());
227 m_width = 0;
240 m_width = 0;
228 m_height = 0;
241 m_height = 0;
229 for (int i=0; i<markers.count(); i++) {
242 for (int i=0; i<markers.count(); i++) {
230 LegendMarker *marker = markers.at(i);
243 LegendMarker *marker = markers.at(i);
231 if (marker->isVisible()) {
244 if (marker->isVisible()) {
232 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
245 marker->setGeometry(geometry);
233 const QRectF& boundingRect = marker->boundingRect();
246 const QRectF& boundingRect = marker->boundingRect();
234 qreal w = boundingRect.width();
247 qreal w = boundingRect.width();
235 qreal h = boundingRect.height();
248 qreal h = boundingRect.height();
@@ -237,9 +250,9 void LegendLayout::setDettachedGeometry(const QRectF& rect)
237 m_height = qMax(m_height,h);
250 m_height = qMax(m_height,h);
238 marker->setPos(point.x(),point.y() - h);
251 marker->setPos(point.x(),point.y() - h);
239 point.setX(point.x() + w);
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 // Next item would go off rect.
254 // Next item would go off rect.
242 point.setX(rect.bottomLeft().x());
255 point.setX(0);
243 point.setY(point.y() - h);
256 point.setY(point.y() - h);
244 if (i+1 < markers.count()) {
257 if (i+1 < markers.count()) {
245 m_height += h;
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;
265 m_minOffsetX = -left;
253 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
266 m_minOffsetY = -m_height + geometry.height() - top;
254 m_maxOffsetX = m_width - rect.width();
267 m_maxOffsetX = m_width - geometry.width() - right;
255 m_maxOffsetY = 0;
268 m_maxOffsetY = -bottom;
256 }
269 }
257 break;
270 break;
258 case Qt::AlignLeft: {
271 case Qt::AlignLeft: {
259 QPointF point = rect.topLeft();
272 QPointF point(0,0);
260 m_width = 0;
273 m_width = 0;
261 m_height = 0;
274 m_height = 0;
262 qreal maxWidth = 0;
275 qreal maxWidth = 0;
263 for (int i=0; i<markers.count(); i++) {
276 for (int i=0; i<markers.count(); i++) {
264 LegendMarker *marker = markers.at(i);
277 LegendMarker *marker = markers.at(i);
265 if (marker->isVisible()) {
278 if (marker->isVisible()) {
266 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
279 marker->setGeometry(geometry);
267 const QRectF& boundingRect = marker->boundingRect();
280 const QRectF& boundingRect = marker->boundingRect();
268 qreal w = boundingRect.width();
281 qreal w = boundingRect.width();
269 qreal h = boundingRect.height();
282 qreal h = boundingRect.height();
@@ -271,10 +284,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
271 maxWidth = qMax(maxWidth,w);
284 maxWidth = qMax(maxWidth,w);
272 marker->setPos(point.x(),point.y());
285 marker->setPos(point.x(),point.y());
273 point.setY(point.y() + h);
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 // Next item would go off rect.
288 // Next item would go off rect.
276 point.setX(point.x() + maxWidth);
289 point.setX(point.x() + maxWidth);
277 point.setY(rect.topLeft().y());
290 point.setY(0);
278 if (i+1 < markers.count()) {
291 if (i+1 < markers.count()) {
279 m_width += maxWidth;
292 m_width += maxWidth;
280 maxWidth = 0;
293 maxWidth = 0;
@@ -283,23 +296,23 void LegendLayout::setDettachedGeometry(const QRectF& rect)
283 }
296 }
284 }
297 }
285 m_width += maxWidth;
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;
301 m_minOffsetX = -left;
289 m_minOffsetY = 0;
302 m_minOffsetY = -top;
290 m_maxOffsetX = m_width - rect.width();
303 m_maxOffsetX = m_width - geometry.width() - right;
291 m_maxOffsetY = m_height - rect.height();
304 m_maxOffsetY = m_height - geometry.height() - bottom;
292 }
305 }
293 break;
306 break;
294 case Qt::AlignRight: {
307 case Qt::AlignRight: {
295 QPointF point = rect.topRight();
308 QPointF point(geometry.width(),0);
296 m_width = 0;
309 m_width = 0;
297 m_height = 0;
310 m_height = 0;
298 qreal maxWidth = 0;
311 qreal maxWidth = 0;
299 for (int i=0; i<markers.count(); i++) {
312 for (int i=0; i<markers.count(); i++) {
300 LegendMarker *marker = markers.at(i);
313 LegendMarker *marker = markers.at(i);
301 if (marker->isVisible()) {
314 if (marker->isVisible()) {
302 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
315 marker->setGeometry(geometry);
303 const QRectF& boundingRect = marker->boundingRect();
316 const QRectF& boundingRect = marker->boundingRect();
304 qreal w = boundingRect.width();
317 qreal w = boundingRect.width();
305 qreal h = boundingRect.height();
318 qreal h = boundingRect.height();
@@ -307,10 +320,10 void LegendLayout::setDettachedGeometry(const QRectF& rect)
307 maxWidth = qMax(maxWidth,w);
320 maxWidth = qMax(maxWidth,w);
308 marker->setPos(point.x() - w,point.y());
321 marker->setPos(point.x() - w,point.y());
309 point.setY(point.y() + h);
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 // Next item would go off rect.
324 // Next item would go off rect.
312 point.setX(point.x() - maxWidth);
325 point.setX(point.x() - maxWidth);
313 point.setY(rect.topLeft().y());
326 point.setY(0);
314 if (i+1 < markers.count()) {
327 if (i+1 < markers.count()) {
315 m_width += maxWidth;
328 m_width += maxWidth;
316 maxWidth = 0;
329 maxWidth = 0;
@@ -319,12 +332,12 void LegendLayout::setDettachedGeometry(const QRectF& rect)
319 }
332 }
320 }
333 }
321 m_width += maxWidth;
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());
337 m_minOffsetX = - m_width + geometry.width() - left;
325 m_minOffsetY = 0;
338 m_minOffsetY = -top;
326 m_maxOffsetX = 0;
339 m_maxOffsetX = - right;
327 m_maxOffsetY = m_height - rect.height();
340 m_maxOffsetY = m_height - geometry.height() - bottom;
328 }
341 }
329 break;
342 break;
330 default:
343 default:
@@ -339,8 +352,6 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) c
339 qreal left, top, right, bottom;
352 qreal left, top, right, bottom;
340 getContentsMargins(&left, &top, &right, &bottom);
353 getContentsMargins(&left, &top, &right, &bottom);
341
354
342 if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
343
344 if(constraint.isValid()) {
355 if(constraint.isValid()) {
345 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
356 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
346 size = size.expandedTo(marker->effectiveSizeHint(which));
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 size += QSize(left + right, top + bottom);
385 size += QSize(left + right, top + bottom);
375
376 return size;
386 return size;
377
378
379 }
387 }
380
388
381 QTCOMMERCIALCHART_END_NAMESPACE
389 QTCOMMERCIALCHART_END_NAMESPACE
@@ -44,7 +44,7 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
44 m_legend(legend),
44 m_legend(legend),
45 m_textItem(new QGraphicsSimpleTextItem(this)),
45 m_textItem(new QGraphicsSimpleTextItem(this)),
46 m_rectItem(new QGraphicsRectItem(this)),
46 m_rectItem(new QGraphicsRectItem(this)),
47 m_margin(2),
47 m_margin(4),
48 m_space(4)
48 m_space(4)
49 {
49 {
50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
@@ -86,12 +86,13 QFont LegendMarker::font() const
86
86
87 void LegendMarker::setLabel(const QString label)
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 QString LegendMarker::label() const
93 QString LegendMarker::label() const
93 {
94 {
94 return m_textItem->text();
95 return m_text;
95 }
96 }
96
97
97 QRectF LegendMarker::boundingRect() const
98 QRectF LegendMarker::boundingRect() const
@@ -112,14 +113,31 QBrush LegendMarker::labelBrush() const
112
113
113 void LegendMarker::setGeometry(const QRectF& rect)
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 const QRectF& textRect = m_textItem->boundingRect();
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 m_rectItem->setRect(m_markerRect);
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 prepareGeometryChange();
139 prepareGeometryChange();
122 m_boundingRect = rect;
140 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
123 }
141 }
124
142
125 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
143 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -129,7 +147,6 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
129 Q_UNUSED(painter)
147 Q_UNUSED(painter)
130 }
148 }
131
149
132
133 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
150 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
134 {
151 {
135 Q_UNUSED(constraint)
152 Q_UNUSED(constraint)
@@ -139,10 +156,10 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
139
156
140 switch (which) {
157 switch (which) {
141 case Qt::MinimumSize:
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 break;
160 break;
144 case Qt::PreferredSize:
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 break;
163 break;
147 default:
164 default:
148 break;
165 break;
@@ -154,7 +171,7 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
154 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
171 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
155 {
172 {
156 QGraphicsObject::mousePressEvent(event);
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 QGraphicsRectItem *m_rectItem;
96 QGraphicsRectItem *m_rectItem;
97 qreal m_margin;
97 qreal m_margin;
98 qreal m_space;
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 Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget.
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 Returns the rect that contains information about margins (distance between chart widget edge and axes).
382 Returns the rect that contains information about margins (distance between chart widget edge and axes).
383 Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
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 QRectF QChart::plotArea() const
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 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
43 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
44 Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
44 Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
45 Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions)
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 Q_ENUMS(ChartTheme)
47 Q_ENUMS(ChartTheme)
48 Q_ENUMS(AnimationOption)
48 Q_ENUMS(AnimationOption)
49
49
@@ -114,8 +114,8 public:
114
114
115 QLegend* legend() const;
115 QLegend* legend() const;
116
116
117 void setMinimumMargins(const QMargins& margins);
117 void setMargins(const QMargins& margins);
118 QMargins minimumMargins() const;
118 QMargins margins() const;
119
119
120 QRectF plotArea() const;
120 QRectF plotArea() const;
121
121
@@ -38,7 +38,8 SOURCES += \
38 $$PWD/chartbackground.cpp \
38 $$PWD/chartbackground.cpp \
39 $$PWD/chartelement.cpp \
39 $$PWD/chartelement.cpp \
40 $$PWD/scroller.cpp \
40 $$PWD/scroller.cpp \
41 $$PWD/chartlayout.cpp
41 $$PWD/chartlayout.cpp \
42 $$PWD/charttitle.cpp
42 PRIVATE_HEADERS += \
43 PRIVATE_HEADERS += \
43 $$PWD/chartdataset_p.h \
44 $$PWD/chartdataset_p.h \
44 $$PWD/chartitem_p.h \
45 $$PWD/chartitem_p.h \
@@ -52,8 +53,8 PRIVATE_HEADERS += \
52 $$PWD/qchartview_p.h \
53 $$PWD/qchartview_p.h \
53 $$PWD/scroller_p.h \
54 $$PWD/scroller_p.h \
54 $$PWD/qabstractseries_p.h \
55 $$PWD/qabstractseries_p.h \
55 $$PWD/chartlayout_p.h
56 $$PWD/chartlayout_p.h \
56
57 $$PWD/charttitle_p.h
57 PUBLIC_HEADERS += \
58 PUBLIC_HEADERS += \
58 $$PWD/qchart.h \
59 $$PWD/qchart.h \
59 $$PWD/qchartglobal.h \
60 $$PWD/qchartglobal.h \
General Comments 0
You need to be logged in to leave comments. Login now