@@ -1,347 +1,394 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2012 Digia Plc |
|
3 | ** Copyright (C) 2012 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
8 | ** |
|
8 | ** | |
9 | ** $QT_BEGIN_LICENSE$ |
|
9 | ** $QT_BEGIN_LICENSE$ | |
10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
12 | ** Software or, alternatively, in accordance with the terms contained in |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
13 | ** a written agreement between you and Digia. |
|
13 | ** a written agreement between you and Digia. | |
14 | ** |
|
14 | ** | |
15 | ** If you have questions regarding the use of this file, please use |
|
15 | ** If you have questions regarding the use of this file, please use | |
16 | ** contact form at http://qt.digia.com |
|
16 | ** contact form at http://qt.digia.com | |
17 | ** $QT_END_LICENSE$ |
|
17 | ** $QT_END_LICENSE$ | |
18 | ** |
|
18 | ** | |
19 | ****************************************************************************/ |
|
19 | ****************************************************************************/ | |
20 |
|
20 | |||
21 | #include "chartlayout_p.h" |
|
21 | #include "chartlayout_p.h" | |
22 | #include "chartpresenter_p.h" |
|
22 | #include "chartpresenter_p.h" | |
23 | #include "qlegend_p.h" |
|
23 | #include "qlegend_p.h" | |
24 | #include "chartaxis_p.h" |
|
24 | #include "chartaxis_p.h" | |
25 | #include "charttitle_p.h" |
|
25 | #include "charttitle_p.h" | |
26 | #include "chartbackground_p.h" |
|
26 | #include "chartbackground_p.h" | |
27 | #include <QDebug> |
|
27 | #include <QDebug> | |
28 |
|
28 | |||
29 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
29 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
30 |
|
30 | |||
31 |
static const qreal |
|
31 | static const qreal maxAxisPortion = 0.4; | |
32 |
|
32 | |||
33 | ChartLayout::ChartLayout(ChartPresenter *presenter) |
|
33 | ChartLayout::ChartLayout(ChartPresenter *presenter) | |
34 | : m_presenter(presenter), |
|
34 | : m_presenter(presenter), | |
35 | m_margins(20, 20, 20, 20), |
|
35 | m_margins(20, 20, 20, 20), | |
36 | m_minChartRect(0, 0, 200, 200) |
|
36 | m_minChartRect(0, 0, 200, 200) | |
37 | { |
|
37 | { | |
38 |
|
38 | |||
39 | } |
|
39 | } | |
40 |
|
40 | |||
41 | ChartLayout::~ChartLayout() |
|
41 | ChartLayout::~ChartLayout() | |
42 | { |
|
42 | { | |
43 |
|
43 | |||
44 | } |
|
44 | } | |
45 |
|
45 | |||
46 | void ChartLayout::setGeometry(const QRectF &rect) |
|
46 | void ChartLayout::setGeometry(const QRectF &rect) | |
47 | { |
|
47 | { | |
48 | if (!rect.isValid()) |
|
48 | if (!rect.isValid()) | |
49 | return; |
|
49 | return; | |
50 |
|
50 | |||
51 | QList<ChartAxis *> axes = m_presenter->axisItems(); |
|
51 | QList<ChartAxis *> axes = m_presenter->axisItems(); | |
52 | ChartTitle *title = m_presenter->titleElement(); |
|
52 | ChartTitle *title = m_presenter->titleElement(); | |
53 | QLegend *legend = m_presenter->legend(); |
|
53 | QLegend *legend = m_presenter->legend(); | |
54 | ChartBackground *background = m_presenter->backgroundElement(); |
|
54 | ChartBackground *background = m_presenter->backgroundElement(); | |
55 |
|
55 | |||
56 | QRectF contentGeometry = calculateBackgroundGeometry(rect, background); |
|
56 | QRectF contentGeometry = calculateBackgroundGeometry(rect, background); | |
57 |
|
57 | |||
58 | contentGeometry = calculateContentGeometry(contentGeometry); |
|
58 | contentGeometry = calculateContentGeometry(contentGeometry); | |
59 |
|
59 | |||
60 | if (title && title->isVisible()) |
|
60 | if (title && title->isVisible()) | |
61 | contentGeometry = calculateTitleGeometry(contentGeometry, title); |
|
61 | contentGeometry = calculateTitleGeometry(contentGeometry, title); | |
62 |
|
62 | |||
63 | if (legend->isAttachedToChart() && legend->isVisible()) |
|
63 | if (legend->isAttachedToChart() && legend->isVisible()) | |
64 | contentGeometry = calculateLegendGeometry(contentGeometry, legend); |
|
64 | contentGeometry = calculateLegendGeometry(contentGeometry, legend); | |
65 |
|
65 | |||
66 | contentGeometry = calculateAxisGeometry(contentGeometry, axes); |
|
66 | contentGeometry = calculateAxisGeometry(contentGeometry, axes); | |
67 |
|
67 | |||
68 | m_presenter->setGeometry(contentGeometry); |
|
68 | m_presenter->setGeometry(contentGeometry); | |
69 |
|
69 | |||
70 | QGraphicsLayout::setGeometry(rect); |
|
70 | QGraphicsLayout::setGeometry(rect); | |
71 | } |
|
71 | } | |
72 |
|
72 | |||
73 | QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const |
|
73 | QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const | |
74 | { |
|
74 | { | |
75 | return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom()); |
|
75 | return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom()); | |
76 | } |
|
76 | } | |
77 |
|
77 | |||
78 | QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const |
|
78 | QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const | |
79 | { |
|
79 | { | |
80 | return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom()); |
|
80 | return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom()); | |
81 | } |
|
81 | } | |
82 |
|
82 | |||
83 |
|
83 | |||
84 | QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const |
|
84 | QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const | |
85 | { |
|
85 | { | |
86 | qreal left, top, right, bottom; |
|
86 | qreal left, top, right, bottom; | |
87 | getContentsMargins(&left, &top, &right, &bottom); |
|
87 | getContentsMargins(&left, &top, &right, &bottom); | |
88 | QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom); |
|
88 | QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom); | |
89 | if (background) |
|
89 | if (background) | |
90 | background->setRect(backgroundGeometry); |
|
90 | background->setRect(backgroundGeometry); | |
91 | return backgroundGeometry; |
|
91 | return backgroundGeometry; | |
92 | } |
|
92 | } | |
93 |
|
93 | |||
94 | QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const |
|
94 | QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const | |
95 | { |
|
95 | { | |
96 | qreal left, top, right, bottom; |
|
96 | qreal left, top, right, bottom; | |
97 | getContentsMargins(&left, &top, &right, &bottom); |
|
97 | getContentsMargins(&left, &top, &right, &bottom); | |
98 | return minimum.adjusted(0, 0, left + right, top + bottom); |
|
98 | return minimum.adjusted(0, 0, left + right, top + bottom); | |
99 | } |
|
99 | } | |
100 |
|
100 | |||
101 |
|
101 | |||
102 | QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const |
|
102 | QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const | |
103 | { |
|
103 | { | |
104 | QSizeF left(0,0); |
|
104 | QSizeF left(0,0); | |
105 | QSizeF minLeft(0,0); |
|
105 | QSizeF minLeft(0,0); | |
106 | QSizeF right(0,0); |
|
106 | QSizeF right(0,0); | |
107 | QSizeF minRight(0,0); |
|
107 | QSizeF minRight(0,0); | |
108 | QSizeF bottom(0,0); |
|
108 | QSizeF bottom(0,0); | |
109 | QSizeF minBottom(0,0); |
|
109 | QSizeF minBottom(0,0); | |
110 | QSizeF top(0,0); |
|
110 | QSizeF top(0,0); | |
111 | QSizeF minTop(0,0); |
|
111 | QSizeF minTop(0,0); | |
112 | int leftCount = 0; |
|
112 | int leftCount = 0; | |
113 | int rightCount = 0; |
|
113 | int rightCount = 0; | |
114 | int topCount = 0; |
|
114 | int topCount = 0; | |
115 | int bottomCount = 0; |
|
115 | int bottomCount = 0; | |
116 |
|
116 | |||
117 | foreach (ChartAxis *axis , axes) { |
|
117 | foreach (ChartAxis *axis , axes) { | |
118 |
|
118 | |||
119 | if (!axis->isVisible()) |
|
119 | if (!axis->isVisible()) | |
120 | continue; |
|
120 | continue; | |
121 |
|
121 | |||
122 |
|
122 | |||
123 | QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize); |
|
123 | QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize); | |
124 | //this is used to get single thick font size |
|
124 | //this is used to get single thick font size | |
125 | QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize); |
|
125 | QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize); | |
126 |
|
126 | |||
127 | switch (axis->alignment()) { |
|
127 | switch (axis->alignment()) { | |
128 | case Qt::AlignLeft: |
|
128 | case Qt::AlignLeft: | |
129 | left.setWidth(left.width()+size.width()); |
|
129 | left.setWidth(left.width()+size.width()); | |
130 | left.setHeight(qMax(left.height(),size.height())); |
|
130 | left.setHeight(qMax(left.height(),size.height())); | |
131 | minLeft.setWidth(minLeft.width()+minSize.width()); |
|
131 | minLeft.setWidth(minLeft.width()+minSize.width()); | |
132 | minLeft.setHeight(qMax(minLeft.height(),minSize.height())); |
|
132 | minLeft.setHeight(qMax(minLeft.height(),minSize.height())); | |
133 | leftCount++; |
|
133 | leftCount++; | |
134 | break; |
|
134 | break; | |
135 | case Qt::AlignRight: |
|
135 | case Qt::AlignRight: | |
136 | right.setWidth(right.width()+size.width()); |
|
136 | right.setWidth(right.width()+size.width()); | |
137 | right.setHeight(qMax(right.height(),size.height())); |
|
137 | right.setHeight(qMax(right.height(),size.height())); | |
138 | minRight.setWidth(minRight.width()+minSize.width()); |
|
138 | minRight.setWidth(minRight.width()+minSize.width()); | |
139 | minRight.setHeight(qMax(minRight.height(),minSize.height())); |
|
139 | minRight.setHeight(qMax(minRight.height(),minSize.height())); | |
140 | rightCount++; |
|
140 | rightCount++; | |
141 | break; |
|
141 | break; | |
142 | case Qt::AlignTop: |
|
142 | case Qt::AlignTop: | |
143 | top.setWidth(qMax(top.width(),size.width())); |
|
143 | top.setWidth(qMax(top.width(),size.width())); | |
144 | top.setHeight(top.height()+size.height()); |
|
144 | top.setHeight(top.height()+size.height()); | |
145 | minTop.setWidth(qMax(minTop.width(),minSize.width())); |
|
145 | minTop.setWidth(qMax(minTop.width(),minSize.width())); | |
146 | minTop.setHeight(minTop.height()+minSize.height()); |
|
146 | minTop.setHeight(minTop.height()+minSize.height()); | |
147 | topCount++; |
|
147 | topCount++; | |
148 | break; |
|
148 | break; | |
149 | case Qt::AlignBottom: |
|
149 | case Qt::AlignBottom: | |
150 | bottom.setWidth(qMax(bottom.width(), size.width())); |
|
150 | bottom.setWidth(qMax(bottom.width(), size.width())); | |
151 | bottom.setHeight(bottom.height() + size.height()); |
|
151 | bottom.setHeight(bottom.height() + size.height()); | |
152 | minBottom.setWidth(qMax(minBottom.width(),minSize.width())); |
|
152 | minBottom.setWidth(qMax(minBottom.width(),minSize.width())); | |
153 | minBottom.setHeight(minBottom.height() + minSize.height()); |
|
153 | minBottom.setHeight(minBottom.height() + minSize.height()); | |
154 | bottomCount++; |
|
154 | bottomCount++; | |
155 | break; |
|
155 | break; | |
156 | default: |
|
156 | default: | |
157 | qWarning()<<"Axis is without alignment !"; |
|
157 | qWarning()<<"Axis is without alignment !"; | |
158 | break; |
|
158 | break; | |
159 | } |
|
159 | } | |
160 | } |
|
160 | } | |
161 |
|
161 | |||
162 |
int |
|
162 | int totalVerticalAxes = leftCount + rightCount; | |
163 |
qreal |
|
163 | qreal leftSqueezeRatio = 1.0; | |
164 | if(horizontal>0) |
|
164 | qreal rightSqueezeRatio = 1.0; | |
165 | hratio = (golden_ratio*geometry.width())/horizontal; |
|
165 | qreal vratio = 0; | |
166 |
|
166 | |||
167 | if(leftCount>0) |
|
167 | if (totalVerticalAxes > 0) | |
168 | left.setWidth(qMin(left.width(),hratio*leftCount)); |
|
168 | vratio = (maxAxisPortion * geometry.width()) / totalVerticalAxes; | |
169 | if(rightCount>0) |
|
169 | ||
170 | right.setWidth(qMin(right.width(),hratio*rightCount)); |
|
170 | if (leftCount > 0) { | |
|
171 | int maxWidth = vratio * leftCount; | |||
|
172 | if (left.width() > maxWidth) { | |||
|
173 | leftSqueezeRatio = maxWidth / left.width(); | |||
|
174 | left.setWidth(maxWidth); | |||
|
175 | } | |||
|
176 | } | |||
|
177 | if (rightCount > 0) { | |||
|
178 | int maxWidth = vratio * rightCount; | |||
|
179 | if (right.width() > maxWidth) { | |||
|
180 | rightSqueezeRatio = maxWidth / right.width(); | |||
|
181 | right.setWidth(maxWidth); | |||
|
182 | } | |||
|
183 | } | |||
|
184 | ||||
|
185 | int totalHorizontalAxes = topCount + bottomCount; | |||
|
186 | qreal topSqueezeRatio = 1.0; | |||
|
187 | qreal bottomSqueezeRatio = 1.0; | |||
|
188 | qreal hratio = 0; | |||
|
189 | ||||
|
190 | if (totalHorizontalAxes > 0) | |||
|
191 | hratio = (maxAxisPortion * geometry.height()) / totalHorizontalAxes; | |||
|
192 | ||||
|
193 | if (topCount > 0) { | |||
|
194 | int maxHeight = hratio * topCount; | |||
|
195 | if (top.height() > maxHeight) { | |||
|
196 | topSqueezeRatio = maxHeight / top.height(); | |||
|
197 | top.setHeight(maxHeight); | |||
|
198 | } | |||
|
199 | } | |||
|
200 | if (bottomCount > 0) { | |||
|
201 | int maxHeight = hratio * bottomCount; | |||
|
202 | if (bottom.height() > maxHeight) { | |||
|
203 | bottomSqueezeRatio = maxHeight / bottom.height(); | |||
|
204 | bottom.setHeight(maxHeight); | |||
|
205 | } | |||
|
206 | } | |||
171 |
|
207 | |||
172 | qreal minHeight = qMax(minLeft.height(),minRight.height()) + 1; |
|
208 | qreal minHeight = qMax(minLeft.height(),minRight.height()) + 1; | |
173 | qreal minWidth = qMax(minTop.width(),minBottom.width()) + 1; |
|
209 | qreal minWidth = qMax(minTop.width(),minBottom.width()) + 1; | |
174 |
|
210 | |||
175 | QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2)); |
|
211 | QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2)); | |
176 |
|
212 | |||
177 | qreal leftOffset = 0; |
|
213 | qreal leftOffset = 0; | |
178 | qreal rightOffset = 0; |
|
214 | qreal rightOffset = 0; | |
179 | qreal topOffset = 0; |
|
215 | qreal topOffset = 0; | |
180 | qreal bottomOffset = 0; |
|
216 | qreal bottomOffset = 0; | |
181 |
|
217 | |||
182 | foreach(ChartElement *axisElement , axes) { |
|
218 | foreach(ChartElement *axisElement , axes) { | |
183 |
|
219 | |||
184 | //TODO fixme |
|
220 | //TODO fixme | |
185 | ChartAxis* axis = qobject_cast<ChartAxis*>(axisElement); |
|
221 | ChartAxis* axis = qobject_cast<ChartAxis*>(axisElement); | |
186 |
|
222 | |||
187 | if (!axis->isVisible()) |
|
223 | if (!axis->isVisible()) | |
188 | continue; |
|
224 | continue; | |
189 |
|
225 | |||
190 | QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize); |
|
226 | QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize); | |
191 |
|
227 | |||
192 | switch(axis->alignment()){ |
|
228 | switch(axis->alignment()){ | |
193 | case Qt::AlignLeft:{ |
|
229 | case Qt::AlignLeft:{ | |
194 |
qreal width = |
|
230 | qreal width = size.width(); | |
|
231 | if (leftSqueezeRatio < 1.0) | |||
|
232 | width *= leftSqueezeRatio; | |||
195 | leftOffset+=width; |
|
233 | leftOffset+=width; | |
196 | axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect); |
|
234 | axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect); | |
197 | break; |
|
235 | break; | |
198 | } |
|
236 | } | |
199 | case Qt::AlignRight:{ |
|
237 | case Qt::AlignRight:{ | |
200 |
qreal width = |
|
238 | qreal width = size.width(); | |
|
239 | if (rightSqueezeRatio < 1.0) | |||
|
240 | width *= rightSqueezeRatio; | |||
201 | axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect); |
|
241 | axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect); | |
202 | rightOffset+=width; |
|
242 | rightOffset+=width; | |
203 | break; |
|
243 | break; | |
204 | } |
|
244 | } | |
205 | case Qt::AlignTop: |
|
245 | case Qt::AlignTop: { | |
206 | axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - size.height(), geometry.width(), size.height()), chartRect); |
|
246 | qreal height = size.height(); | |
207 | topOffset += size.height(); |
|
247 | if (topSqueezeRatio < 1.0) | |
|
248 | height *= topSqueezeRatio; | |||
|
249 | axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - height, geometry.width(), height), chartRect); | |||
|
250 | topOffset += height; | |||
208 | break; |
|
251 | break; | |
|
252 | } | |||
209 | case Qt::AlignBottom: |
|
253 | case Qt::AlignBottom: | |
210 | axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), size.height()), chartRect); |
|
254 | qreal height = size.height(); | |
211 | bottomOffset += size.height(); |
|
255 | if (bottomSqueezeRatio < 1.0) | |
|
256 | height *= bottomSqueezeRatio; | |||
|
257 | axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), height), chartRect); | |||
|
258 | bottomOffset += height; | |||
212 | break; |
|
259 | break; | |
213 | } |
|
260 | } | |
214 | } |
|
261 | } | |
215 |
|
262 | |||
216 | return chartRect; |
|
263 | return chartRect; | |
217 | } |
|
264 | } | |
218 |
|
265 | |||
219 | QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const |
|
266 | QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const | |
220 | { |
|
267 | { | |
221 | QSizeF left; |
|
268 | QSizeF left; | |
222 | QSizeF right; |
|
269 | QSizeF right; | |
223 | QSizeF bottom; |
|
270 | QSizeF bottom; | |
224 | QSizeF top; |
|
271 | QSizeF top; | |
225 |
|
272 | |||
226 | foreach (ChartAxis *axis, axes) { |
|
273 | foreach (ChartAxis *axis, axes) { | |
227 |
|
274 | |||
228 | QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize); |
|
275 | QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize); | |
229 |
|
276 | |||
230 | if (!axis->isVisible()) |
|
277 | if (!axis->isVisible()) | |
231 | continue; |
|
278 | continue; | |
232 |
|
279 | |||
233 | switch (axis->alignment()) { |
|
280 | switch (axis->alignment()) { | |
234 | case Qt::AlignLeft: |
|
281 | case Qt::AlignLeft: | |
235 | left.setWidth(left.width() + size.width()); |
|
282 | left.setWidth(left.width() + size.width()); | |
236 | left.setHeight(qMax(left.height() * 2, size.height())); |
|
283 | left.setHeight(qMax(left.height() * 2, size.height())); | |
237 | break; |
|
284 | break; | |
238 | case Qt::AlignRight: |
|
285 | case Qt::AlignRight: | |
239 | right.setWidth(right.width() + size.width()); |
|
286 | right.setWidth(right.width() + size.width()); | |
240 | right.setHeight(qMax(right.height() * 2, size.height())); |
|
287 | right.setHeight(qMax(right.height() * 2, size.height())); | |
241 | break; |
|
288 | break; | |
242 | case Qt::AlignTop: |
|
289 | case Qt::AlignTop: | |
243 | top.setWidth(qMax(top.width(), size.width())); |
|
290 | top.setWidth(qMax(top.width(), size.width())); | |
244 | top.setHeight(top.height() + size.height()); |
|
291 | top.setHeight(top.height() + size.height()); | |
245 | break; |
|
292 | break; | |
246 | case Qt::AlignBottom: |
|
293 | case Qt::AlignBottom: | |
247 | bottom.setWidth(qMax(bottom.width(), size.width())); |
|
294 | bottom.setWidth(qMax(bottom.width(), size.width())); | |
248 | bottom.setHeight(bottom.height() + size.height()); |
|
295 | bottom.setHeight(bottom.height() + size.height()); | |
249 | break; |
|
296 | break; | |
250 | } |
|
297 | } | |
251 | } |
|
298 | } | |
252 | return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height())); |
|
299 | return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height())); | |
253 | } |
|
300 | } | |
254 |
|
301 | |||
255 | QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const |
|
302 | QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const | |
256 | { |
|
303 | { | |
257 | QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); |
|
304 | QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); | |
258 | QRectF legendRect; |
|
305 | QRectF legendRect; | |
259 | QRectF result; |
|
306 | QRectF result; | |
260 |
|
307 | |||
261 | switch (legend->alignment()) { |
|
308 | switch (legend->alignment()) { | |
262 | case Qt::AlignTop: { |
|
309 | case Qt::AlignTop: { | |
263 | legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height())); |
|
310 | legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height())); | |
264 | result = geometry.adjusted(0, legendRect.height(), 0, 0); |
|
311 | result = geometry.adjusted(0, legendRect.height(), 0, 0); | |
265 | break; |
|
312 | break; | |
266 | } |
|
313 | } | |
267 | case Qt::AlignBottom: { |
|
314 | case Qt::AlignBottom: { | |
268 | legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height())); |
|
315 | legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height())); | |
269 | result = geometry.adjusted(0, 0, 0, -legendRect.height()); |
|
316 | result = geometry.adjusted(0, 0, 0, -legendRect.height()); | |
270 | break; |
|
317 | break; | |
271 | } |
|
318 | } | |
272 | case Qt::AlignLeft: { |
|
319 | case Qt::AlignLeft: { | |
273 |
qreal width = qMin(size.width(), geometry.width() * |
|
320 | qreal width = qMin(size.width(), geometry.width() * maxAxisPortion); | |
274 | legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height())); |
|
321 | legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height())); | |
275 | result = geometry.adjusted(width, 0, 0, 0); |
|
322 | result = geometry.adjusted(width, 0, 0, 0); | |
276 | break; |
|
323 | break; | |
277 | } |
|
324 | } | |
278 | case Qt::AlignRight: { |
|
325 | case Qt::AlignRight: { | |
279 |
qreal width = qMin(size.width(), geometry.width() * |
|
326 | qreal width = qMin(size.width(), geometry.width() * maxAxisPortion); | |
280 | legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height())); |
|
327 | legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height())); | |
281 | result = geometry.adjusted(0, 0, -width, 0); |
|
328 | result = geometry.adjusted(0, 0, -width, 0); | |
282 | break; |
|
329 | break; | |
283 | } |
|
330 | } | |
284 | default: { |
|
331 | default: { | |
285 | legendRect = QRectF(0, 0, 0, 0); |
|
332 | legendRect = QRectF(0, 0, 0, 0); | |
286 | result = geometry; |
|
333 | result = geometry; | |
287 | break; |
|
334 | break; | |
288 | } |
|
335 | } | |
289 | } |
|
336 | } | |
290 |
|
337 | |||
291 | legend->setGeometry(legendRect); |
|
338 | legend->setGeometry(legendRect); | |
292 |
|
339 | |||
293 | return result; |
|
340 | return result; | |
294 | } |
|
341 | } | |
295 |
|
342 | |||
296 | QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const |
|
343 | QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const | |
297 | { |
|
344 | { | |
298 | QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)); |
|
345 | QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)); | |
299 | return geometry.adjusted(0, 0, minSize.width(), minSize.height()); |
|
346 | return geometry.adjusted(0, 0, minSize.width(), minSize.height()); | |
300 | } |
|
347 | } | |
301 |
|
348 | |||
302 | QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const |
|
349 | QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const | |
303 | { |
|
350 | { | |
304 | title->setGeometry(geometry); |
|
351 | title->setGeometry(geometry); | |
305 | QPointF center = geometry.center() - title->boundingRect().center(); |
|
352 | QPointF center = geometry.center() - title->boundingRect().center(); | |
306 | title->setPos(center.x(),title->pos().y()); |
|
353 | title->setPos(center.x(),title->pos().y()); | |
307 | return geometry.adjusted(0,title->boundingRect().height()+1,0,0); |
|
354 | return geometry.adjusted(0,title->boundingRect().height()+1,0,0); | |
308 | } |
|
355 | } | |
309 |
|
356 | |||
310 | QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const |
|
357 | QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const | |
311 | { |
|
358 | { | |
312 | QSizeF min = title->sizeHint(Qt::MinimumSize); |
|
359 | QSizeF min = title->sizeHint(Qt::MinimumSize); | |
313 | return minimum.adjusted(0, 0, min.width(), min.height()); |
|
360 | return minimum.adjusted(0, 0, min.width(), min.height()); | |
314 | } |
|
361 | } | |
315 |
|
362 | |||
316 | QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
363 | QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const | |
317 | { |
|
364 | { | |
318 | Q_UNUSED(constraint); |
|
365 | Q_UNUSED(constraint); | |
319 | if (which == Qt::MinimumSize) { |
|
366 | if (which == Qt::MinimumSize) { | |
320 | QList<ChartAxis *> axes = m_presenter->axisItems(); |
|
367 | QList<ChartAxis *> axes = m_presenter->axisItems(); | |
321 | ChartTitle *title = m_presenter->titleElement(); |
|
368 | ChartTitle *title = m_presenter->titleElement(); | |
322 | QLegend *legend = m_presenter->legend(); |
|
369 | QLegend *legend = m_presenter->legend(); | |
323 | QRectF minimumRect(0, 0, 0, 0); |
|
370 | QRectF minimumRect(0, 0, 0, 0); | |
324 | minimumRect = calculateBackgroundMinimum(minimumRect); |
|
371 | minimumRect = calculateBackgroundMinimum(minimumRect); | |
325 | minimumRect = calculateContentMinimum(minimumRect); |
|
372 | minimumRect = calculateContentMinimum(minimumRect); | |
326 | minimumRect = calculateTitleMinimum(minimumRect, title); |
|
373 | minimumRect = calculateTitleMinimum(minimumRect, title); | |
327 | minimumRect = calculateLegendMinimum(minimumRect, legend); |
|
374 | minimumRect = calculateLegendMinimum(minimumRect, legend); | |
328 | minimumRect = calculateAxisMinimum(minimumRect, axes); |
|
375 | minimumRect = calculateAxisMinimum(minimumRect, axes); | |
329 | return minimumRect.united(m_minChartRect).size().toSize(); |
|
376 | return minimumRect.united(m_minChartRect).size().toSize(); | |
330 | } |
|
377 | } | |
331 | return QSize(-1, -1); |
|
378 | return QSize(-1, -1); | |
332 | } |
|
379 | } | |
333 |
|
380 | |||
334 | void ChartLayout::setMargins(const QMargins &margins) |
|
381 | void ChartLayout::setMargins(const QMargins &margins) | |
335 | { |
|
382 | { | |
336 | if (m_margins != margins) { |
|
383 | if (m_margins != margins) { | |
337 | m_margins = margins; |
|
384 | m_margins = margins; | |
338 | updateGeometry(); |
|
385 | updateGeometry(); | |
339 | } |
|
386 | } | |
340 | } |
|
387 | } | |
341 |
|
388 | |||
342 | QMargins ChartLayout::margins() const |
|
389 | QMargins ChartLayout::margins() const | |
343 | { |
|
390 | { | |
344 | return m_margins; |
|
391 | return m_margins; | |
345 | } |
|
392 | } | |
346 |
|
393 | |||
347 | QTCOMMERCIALCHART_END_NAMESPACE |
|
394 | QTCOMMERCIALCHART_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now