##// END OF EJS Templates
Adds consider title boundary for axis label wrapping
Michal Klocek -
r2148:b2d455450b59
parent child
Show More
@@ -1,211 +1,210
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "horizontalaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include <QFontMetrics>
24 24 #include <qmath.h>
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 HorizontalAxis::HorizontalAxis(QAbstractAxis *axis, ChartPresenter *presenter, bool intervalAxis)
30 30 : ChartAxis(axis, presenter, intervalAxis)
31 31 {
32 32 }
33 33
34 34 HorizontalAxis::~HorizontalAxis()
35 35 {
36 36 }
37 37
38 38 void HorizontalAxis::updateGeometry()
39 39 {
40 40 const QVector<qreal>& layout = ChartAxis::layout();
41 41
42 42 if (layout.isEmpty())
43 43 return;
44 44
45 45 QStringList labelList = labels();
46 46
47 47 QList<QGraphicsItem *> lines = lineItems();
48 48 QList<QGraphicsItem *> labels = labelItems();
49 49 QList<QGraphicsItem *> shades = shadeItems();
50 50 QList<QGraphicsItem *> axis = arrowItems();
51 51 QGraphicsSimpleTextItem* title = titleItem();
52 52
53 53 Q_ASSERT(labels.size() == labelList.size());
54 54 Q_ASSERT(layout.size() == labelList.size());
55 55
56 56 const QRectF &axisRect = axisGeometry();
57 57 const QRectF &gridRect = gridGeometry();
58 58
59 59 //arrow
60 60 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(axis.at(0));
61 61
62 62 if (alignment() == Qt::AlignTop)
63 63 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
64 64 else if (alignment() == Qt::AlignBottom)
65 65 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
66 66
67 67 qreal width = 0;
68 68 QFontMetrics fn(font());
69 69
70 //title
71
72 if (!titleText().isNull()) {
73 QFontMetrics fn(title->font());
74
75 int size(0);
76
77 size = gridRect.width();
78 QString titleText = this->titleText();
79
80 if (fn.boundingRect(titleText).width() > size) {
81 QString string = titleText + "...";
82 while (fn.boundingRect(string).width() > size && string.length() > 3)
83 string.remove(string.length() - 4, 1);
84 title->setText(string);
85 } else {
86 title->setText(titleText);
87 }
88
89 QPointF center = gridRect.center() - title->boundingRect().center();
90 if (alignment() == Qt::AlignTop) {
91 title->setPos(center.x(), axisRect.top());
92 } else if (alignment() == Qt::AlignBottom) {
93 title->setPos(center.x(), axisRect.bottom() - title->boundingRect().height());
94 }
95 }
96
70 97 for (int i = 0; i < layout.size(); ++i) {
71 98
72 99 //items
73 100 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
74 101 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(axis.at(i + 1));
75 102 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
76 103
77 104 //grid line
78 105 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
79 106
80 107 //label text wrapping
81 108 if(intervalAxis()&& i+1!=layout.size()) {
82 109 //wrapping in case of interval axis
83 110 const qreal delta = layout[i+1] - layout[i];
84 111 QString text = labelList.at(i);
85 112 if (fn.boundingRect(text).width() + 1 > delta )
86 113 {
87 114 QString label = text + "...";
88 115 while (fn.boundingRect(label).width() >= delta && label.length() > 3)
89 116 label.remove(label.length() - 4, 1);
90 117 labelItem->setText(label);
91 118 }
92 119 else {
93 120 labelItem->setText(text);
94 121 }
95 122 }else{
96 123 labelItem->setText(labelList.at(i));
97 124 }
98 125
99 126 //label transformation origin point
100 127 const QRectF& rect = labelItem->boundingRect();
101 128 QPointF center = rect.center();
102 129 labelItem->setTransformOriginPoint(center.x(), center.y());
103 130
104 131 //ticks and label position
105 132 if (alignment() == Qt::AlignTop) {
106 133 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() - labelPadding());
107 134 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
108 135 } else if (alignment() == Qt::AlignBottom) {
109 136 labelItem->setPos(layout[i] - center.x(), axisRect.top() + labelPadding());
110 137 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
111 138 }
112 139
113 140 //label in beetwen
114 141 if(intervalAxis()&& i+1!=layout.size()) {
115 142 const qreal delta = (layout[i+1] - layout[i])/2;
116 143 labelItem->setPos(layout[i] + delta - center.x(), labelItem->pos().y());
117 144 }
118 145
119 146 //label overlap detection
120 147 if(labelItem->pos().x() < width ||
121 148 labelItem->pos().x() < axisRect.left() ||
122 149 labelItem->pos().x() + rect.width() > axisRect.right()) {
123 150 labelItem->setVisible(false);
124 151 } else {
125 152 labelItem->setVisible(true);
126 153 width=rect.width()+labelItem->pos().x();
127 154 }
128 155
129 156 //shades
130 157 if ((i + 1) % 2 && i > 1) {
131 158 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
132 159 rectItem->setRect(layout[i - 1], gridRect.top(), layout[i] - layout[i - 1], gridRect.height());
133 160 }
134 161
135 162 // check if the grid line and the axis tick should be shown
136 163 qreal x = gridItem->line().p1().x();
137 164 if (x < gridRect.left() || x > gridRect.right()) {
138 165 gridItem->setVisible(false);
139 166 tickItem->setVisible(false);
140 167 }else{
141 168 gridItem->setVisible(true);
142 169 tickItem->setVisible(true);
143 170 }
144 171
145 172 }
146 173
147 174 //begin/end grid line in case labels between
148 175 if (intervalAxis()) {
149 176 QGraphicsLineItem *gridLine;
150 177 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
151 178 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
152 179 gridLine->setVisible(true);
153 180 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
154 181 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
155 182 gridLine->setVisible(true);
156 183 }
157
158 //title
159
160 if (!titleText().isNull()) {
161 QFontMetrics fn(title->font());
162
163 int size(0);
164
165 size = gridRect.width();
166 QString titleText = this->titleText();
167
168 if (fn.boundingRect(titleText).width() > size) {
169 QString string = titleText + "...";
170 while (fn.boundingRect(string).width() > size && string.length() > 3)
171 string.remove(string.length() - 4, 1);
172 title->setText(string);
173 } else {
174 title->setText(titleText);
175 }
176
177 QPointF center = gridRect.center() - title->boundingRect().center();
178 if (alignment() == Qt::AlignTop) {
179 title->setPos(center.x(), axisRect.top());
180 } else if (alignment() == Qt::AlignBottom) {
181 title->setPos(center.x(), axisRect.bottom() - title->boundingRect().height());
182 }
183 }
184
185 184 }
186 185
187 186 QSizeF HorizontalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
188 187 {
189 188 Q_UNUSED(constraint);
190 189 QFontMetrics fn(titleFont());
191 190 QSizeF sh;
192 191
193 192 if (titleText().isNull())
194 193 return sh;
195 194
196 195 switch (which) {
197 196 case Qt::MinimumSize:
198 197 sh = QSizeF(fn.boundingRect("...").width(), fn.height());
199 198 break;
200 199 case Qt::MaximumSize:
201 200 case Qt::PreferredSize:
202 201 sh = QSizeF(fn.boundingRect(axis()->title()).width(), fn.height());
203 202 break;
204 203 default:
205 204 break;
206 205 }
207 206
208 207 return sh;
209 208 }
210 209
211 210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,209 +1,212
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "verticalaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include <QFontMetrics>
24 24 #include <QDebug>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, ChartPresenter *presenter, bool intervalAxis)
29 29 : ChartAxis(axis, presenter, intervalAxis)
30 30 {
31 31
32 32 }
33 33
34 34 VerticalAxis::~VerticalAxis()
35 35 {
36 36
37 37 }
38 38
39 39 void VerticalAxis::updateGeometry()
40 40 {
41 41 const QVector<qreal> &layout = ChartAxis::layout();
42 42
43 43 if (layout.isEmpty())
44 44 return;
45 45
46 46 QStringList labelList = labels();
47 47
48 48 QList<QGraphicsItem *> lines = lineItems();
49 49 QList<QGraphicsItem *> labels = labelItems();
50 50 QList<QGraphicsItem *> shades = shadeItems();
51 51 QList<QGraphicsItem *> axis = arrowItems();
52 52 QGraphicsSimpleTextItem* title = titleItem();
53 53
54 54 Q_ASSERT(labels.size() == labelList.size());
55 55 Q_ASSERT(layout.size() == labelList.size());
56 56
57 57 const QRectF &axisRect = axisGeometry();
58 58 const QRectF &gridRect = gridGeometry();
59 59
60 60 qreal height = axisRect.bottom();
61 61
62 62
63 63 //arrow
64 64 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(axis.at(0));
65 65
66 66 //arrow position
67 67 if (alignment()==Qt::AlignLeft)
68 68 arrowItem->setLine( axisRect.right() , gridRect.top(), axisRect.right(), gridRect.bottom());
69 69 else if(alignment()==Qt::AlignRight)
70 70 arrowItem->setLine( axisRect.left() , gridRect.top(), axisRect.left(), gridRect.bottom());
71 71
72 72 QFontMetrics fn(font());
73 73
74 //title
75
76 if (!titleText().isNull()) {
77 QFontMetrics fn(title->font());
78
79 int size(0);
80 size = gridRect.height();
81 QString titleText = this->titleText();
82
83 if (fn.boundingRect(titleText).width() > size) {
84 QString string = titleText + "...";
85 while (fn.boundingRect(string).width() > size && string.length() > 3)
86 string.remove(string.length() - 4, 1);
87 title->setText(string);
88 }
89 else {
90 title->setText(titleText);
91 }
92
93 QPointF center = gridRect.center() - title->boundingRect().center();
94 if (alignment() == Qt::AlignLeft) {
95 title->setPos(axisRect.left() - title->boundingRect().width()/2 + title->boundingRect().height()/2 , center.y());
96 }
97 else if (alignment() == Qt::AlignRight) {
98 title->setPos(axisRect.right()- title->boundingRect().width()/2 - title->boundingRect().height()/2, center.y());
99 }
100 title->setTransformOriginPoint(title->boundingRect().center());
101 title->setRotation(270);
102 }
103
74 104 for (int i = 0; i < layout.size(); ++i) {
75 105
76 106 //items
77 107 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
78 108 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(axis.at(i + 1));
79 109 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
80 110
81 111 //grid line
82 112 gridItem->setLine(gridRect.left() , layout[i], gridRect.right(), layout[i]);
83 113
84 114 //label text wrapping
85 115 QString text = labelList.at(i);
86 if (fn.boundingRect(text).width() > axisRect.right() - axisRect.left() - labelPadding()) {
116 qreal size = axisRect.right() - axisRect.left() - labelPadding() - title->boundingRect().height();
117 if (fn.boundingRect(text).width() > size) {
87 118 QString label = text + "...";
88 while (fn.boundingRect(label).width() > axisRect.right() - axisRect.left() - labelPadding() && label.length() > 3)
119 while (fn.boundingRect(label).width() > size && label.length() > 3)
89 120 label.remove(label.length() - 4, 1);
90 121 labelItem->setText(label);
91 122 } else {
92 123 labelItem->setText(text);
93 124 }
94 125 //label transformation origin point
95 126 const QRectF &rect = labelItem->boundingRect();
96 127
97 128 QPointF center = rect.center();
98 129 labelItem->setTransformOriginPoint(center.x(), center.y());
99 130
100 131 //ticks and label position
101 132 if (alignment() == Qt::AlignLeft) {
102 133 labelItem->setPos(axisRect.right() - rect.width() - labelPadding() , layout[i] - center.y());
103 134 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
104 135 } else if (alignment() == Qt::AlignRight) {
105 136 labelItem->setPos(axisRect.left() + labelPadding() , layout[i] - center.y());
106 137 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
107 138 }
108 139
109 140 //label in beetwen
110 141 if(intervalAxis()&& i+1!=layout.size()) {
111 142 const qreal delta = (layout[i+1] - layout[i])/2;
112 143 labelItem->setPos(labelItem->pos().x() , layout[i] + delta - center.y());
113 144 }
114 145
115 146 //label overlap detection
116 147 if(labelItem->pos().y() + rect.height() > height ||
117 148 labelItem->pos().y() + rect.height()/2 > gridRect.bottom() ||
118 149 labelItem->pos().y() + rect.height()/2 < gridRect.top()) {
119 150 labelItem->setVisible(false);
120 151 }
121 152 else {
122 153 labelItem->setVisible(true);
123 154 height=labelItem->pos().y();
124 155 }
125 156
126 157 //shades
127 158 if ((i + 1) % 2 && i > 1) {
128 159 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
129 160 rectItem->setRect(gridRect.left(), layout[i], gridRect.width(), layout[i - 1] - layout[i]);
130 161 }
131 162
132 163 // check if the grid line and the axis tick should be shown
133 164 qreal y = gridItem->line().p1().y();
134 165 if ((y < gridRect.top() || y > gridRect.bottom()))
135 166 {
136 167 gridItem->setVisible(false);
137 168 tickItem->setVisible(false);
138 169 }else{
139 170 gridItem->setVisible(true);
140 171 tickItem->setVisible(true);
141 172 }
142 173
143 174 }
144 175 //begin/end grid line in case labels between
145 176 if (intervalAxis()) {
146 177 QGraphicsLineItem *gridLine;
147 178 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
148 179 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
149 180 gridLine->setVisible(true);
150 181 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
151 182 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
152 183 gridLine->setVisible(true);
153 184 }
154
155 //title
156
157 if (!titleText().isNull()) {
158 QFontMetrics fn(title->font());
159
160 int size(0);
161 size = gridRect.height();
162 QString titleText = this->titleText();
163
164 if (fn.boundingRect(titleText).width() > size) {
165 QString string = titleText + "...";
166 while (fn.boundingRect(string).width() > size && string.length() > 3)
167 string.remove(string.length() - 4, 1);
168 title->setText(string);
169 } else {
170 title->setText(titleText);
171 }
172
173 QPointF center = gridRect.center() - title->boundingRect().center();
174 if (alignment() == Qt::AlignLeft) {
175 title->setPos(axisRect.left() - title->boundingRect().width()/2 + title->boundingRect().height()/2 , center.y());
176 }else if (alignment() == Qt::AlignRight) {
177 title->setPos(axisRect.right()- title->boundingRect().width()/2 - title->boundingRect().height()/2, center.y());
178 }
179 title->setTransformOriginPoint(title->boundingRect().center());
180 title->setRotation(270);
181 }
182 185 }
183 186
184 187 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
185 188 {
186 189
187 190 Q_UNUSED(constraint);
188 191 QFontMetrics fn(titleFont());
189 192 QSizeF sh;
190 193
191 194 if (titleText().isNull())
192 195 return sh;
193 196
194 197 switch (which) {
195 198 case Qt::MinimumSize:
196 199 sh = QSizeF(fn.height(), fn.boundingRect("...").width());
197 200 break;
198 201 case Qt::MaximumSize:
199 202 case Qt::PreferredSize:
200 203 sh = QSizeF(fn.height(), fn.boundingRect(axis()->title()).width());
201 204 break;
202 205 default:
203 206 break;
204 207 }
205 208
206 209 return sh;
207 210 }
208 211
209 212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,351 +1,351
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxis_p.h"
25 25 #include "charttitle_p.h"
26 26 #include "chartbackground_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include <QDebug>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 static const qreal golden_ratio = 0.8;//0.4;
32 static const qreal golden_ratio = 0.4;
33 33
34 34 ChartLayout::ChartLayout(ChartPresenter *presenter)
35 35 : m_presenter(presenter),
36 36 m_margins(20, 20, 20, 20),
37 37 m_minChartRect(0, 0, 200, 200)
38 38 {
39 39
40 40 }
41 41
42 42 ChartLayout::~ChartLayout()
43 43 {
44 44
45 45 }
46 46
47 47 void ChartLayout::setGeometry(const QRectF &rect)
48 48 {
49 49 if (!rect.isValid())
50 50 return;
51 51
52 52 QList<ChartAxis *> axes = m_presenter->axisItems();
53 53 QList<ChartElement *> charts = m_presenter->chartItems();
54 54 ChartTitle *title = m_presenter->titleElement();
55 55 QLegend *legend = m_presenter->legend();
56 56 ChartBackground *background = m_presenter->backgroundElement();
57 57
58 58 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
59 59
60 60 contentGeometry = calculateContentGeometry(contentGeometry);
61 61
62 62 if (title && title->isVisible())
63 63 contentGeometry = calculateTitleGeometry(contentGeometry, title);
64 64
65 65 if (legend->isAttachedToChart() && legend->isVisible())
66 66 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
67 67
68 68 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
69 69
70 70 m_chartsRect = calculateChartsGeometry(contentGeometry, charts);
71 71
72 72 QGraphicsLayout::setGeometry(rect);
73 73 }
74 74
75 75 QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const
76 76 {
77 77 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
78 78 }
79 79
80 80 QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const
81 81 {
82 82 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
83 83 }
84 84
85 85
86 86 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
87 87 {
88 88 qreal left, top, right, bottom;
89 89 getContentsMargins(&left, &top, &right, &bottom);
90 90 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
91 91 if (background)
92 92 background->setRect(backgroundGeometry);
93 93 return backgroundGeometry;
94 94 }
95 95
96 96 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
97 97 {
98 98 qreal left, top, right, bottom;
99 99 getContentsMargins(&left, &top, &right, &bottom);
100 100 return minimum.adjusted(0, 0, left + right, top + bottom);
101 101 }
102 102
103 103
104 104 QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const
105 105 {
106 106 QSizeF left(0,0);
107 107 QSizeF minLeft(0,0);
108 108 QSizeF right(0,0);
109 109 QSizeF minRight(0,0);
110 110 QSizeF bottom(0,0);
111 111 QSizeF minBottom(0,0);
112 112 QSizeF top(0,0);
113 113 QSizeF minTop(0,0);
114 114 int leftCount = 0;
115 115 int rightCount = 0;
116 116 int topCount = 0;
117 117 int bottomCount = 0;
118 118
119 119 foreach (ChartAxis *axis , axes) {
120 120
121 121 if (!axis->isVisible())
122 122 continue;
123 123
124 124 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
125 125 //this is used to get single thick font size
126 126 QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize);
127 127
128 128 switch (axis->alignment()) {
129 129 case Qt::AlignLeft:
130 130 left.setWidth(left.width()+size.width());
131 131 left.setHeight(qMax(left.height(),size.height()));
132 132 minLeft.setWidth(minLeft.width()+minSize.width());
133 133 minLeft.setHeight(qMax(minLeft.height(),minSize.height()));
134 134 leftCount++;
135 135 break;
136 136 case Qt::AlignRight:
137 137 right.setWidth(right.width()+size.width());
138 138 right.setHeight(qMax(right.height(),size.height()));
139 139 minRight.setWidth(minRight.width()+minSize.width());
140 140 minRight.setHeight(qMax(minRight.height(),minSize.height()));
141 141 rightCount++;
142 142 break;
143 143 case Qt::AlignTop:
144 144 top.setWidth(qMax(top.width(),size.width()));
145 145 top.setHeight(top.height()+size.height());
146 146 minTop.setWidth(qMax(minTop.width(),minSize.width()));
147 147 minTop.setHeight(minTop.height()+minSize.height());
148 148 topCount++;
149 149 break;
150 150 case Qt::AlignBottom:
151 151 bottom.setWidth(qMax(bottom.width(), size.width()));
152 152 bottom.setHeight(bottom.height() + size.height());
153 153 minBottom.setWidth(qMax(minBottom.width(),minSize.width()));
154 154 minBottom.setHeight(minBottom.height() + minSize.height());
155 155 bottomCount++;
156 156 break;
157 157 }
158 158 }
159 159
160 160 int horizontal = leftCount + rightCount;
161 161 qreal hratio = 0 ;
162 162 if(horizontal>0)
163 163 hratio = (golden_ratio*geometry.width())/horizontal;
164 164
165 165 if(leftCount>0)
166 166 left.setWidth(qMin(left.width(),hratio*leftCount));
167 167 if(rightCount>0)
168 168 right.setWidth(qMin(right.width(),hratio*rightCount));
169 169
170 170 qreal minHeight = qMax(minLeft.height(),minRight.height());
171 171 qreal minWidth = qMax(minTop.width(),minBottom.width());
172 172
173 173 QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2));
174 174
175 175 qreal leftOffset = 0;
176 176 qreal rightOffset = 0;
177 177 qreal topOffset = 0;
178 178 qreal bottomOffset = 0;
179 179
180 180 foreach(ChartAxis* axis , axes) {
181 181
182 182 if (!axis->isVisible())
183 183 continue;
184 184
185 185 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
186 186
187 187 switch(axis->alignment()){
188 188 case Qt::AlignLeft:{
189 189 qreal width = qMin(size.width(),(left.width()/leftCount));
190 190 leftOffset+=width;
191 191 axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect);
192 192 break;
193 193 }
194 194 case Qt::AlignRight:{
195 195 qreal width = qMin(size.width(),(right.width()/rightCount));
196 196 axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect);
197 197 rightOffset+=width;
198 198 break;
199 199 }
200 200 case Qt::AlignTop:
201 201 axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - size.height(), geometry.width(), size.height()), chartRect);
202 202 topOffset += size.height();
203 203 break;
204 204 case Qt::AlignBottom:
205 205 axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), size.height()), chartRect);
206 206 bottomOffset += size.height();
207 207 break;
208 208 }
209 209 }
210 210
211 211 return chartRect;
212 212 }
213 213
214 214 QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const
215 215 {
216 216 QSizeF left;
217 217 QSizeF right;
218 218 QSizeF bottom;
219 219 QSizeF top;
220 220
221 221 foreach (ChartAxis *axis , axes) {
222 222
223 223 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
224 224
225 225 if (!axis->isVisible())
226 226 continue;
227 227
228 228 switch (axis->alignment()) {
229 229 case Qt::AlignLeft:
230 230 left.setWidth(left.width() + size.width());
231 231 left.setHeight(qMax(left.height() * 2, size.height()));
232 232 break;
233 233 case Qt::AlignRight:
234 234 right.setWidth(right.width() + size.width());
235 235 right.setHeight(qMax(right.height() * 2, size.height()));
236 236 break;
237 237 case Qt::AlignTop:
238 238 top.setWidth(qMax(top.width(), size.width()));
239 239 top.setHeight(top.height() + size.height());
240 240 break;
241 241 case Qt::AlignBottom:
242 242 bottom.setWidth(qMax(bottom.width(), size.width()));
243 243 bottom.setHeight(bottom.height() + size.height());
244 244 break;
245 245 }
246 246 }
247 247 return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height()));
248 248 }
249 249
250 250 QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
251 251 {
252 252 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
253 253 QRectF legendRect;
254 254 QRectF result;
255 255
256 256 switch (legend->alignment()) {
257 257 case Qt::AlignTop: {
258 258 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
259 259 result = geometry.adjusted(0, legendRect.height(), 0, 0);
260 260 break;
261 261 }
262 262 case Qt::AlignBottom: {
263 263 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
264 264 result = geometry.adjusted(0, 0, 0, -legendRect.height());
265 265 break;
266 266 }
267 267 case Qt::AlignLeft: {
268 268 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
269 269 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
270 270 result = geometry.adjusted(width, 0, 0, 0);
271 271 break;
272 272 }
273 273 case Qt::AlignRight: {
274 274 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
275 275 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
276 276 result = geometry.adjusted(0, 0, -width, 0);
277 277 break;
278 278 }
279 279 default: {
280 280 legendRect = QRectF(0, 0, 0, 0);
281 281 result = geometry;
282 282 break;
283 283 }
284 284 }
285 285
286 286 legend->setGeometry(legendRect);
287 287
288 288 return result;
289 289 }
290 290
291 291
292 292 QRectF ChartLayout::calculateChartsGeometry(const QRectF &geometry, const QList<ChartElement *>& charts) const
293 293 {
294 294 Q_ASSERT(geometry.isValid());
295 295 foreach (ChartElement *chart, charts)
296 296 chart->handleGeometryChanged(geometry);
297 297 return geometry;
298 298 }
299 299
300 300 QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
301 301 {
302 302 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
303 303 return geometry.adjusted(0, 0, minSize.width(), minSize.height());
304 304 }
305 305
306 306 QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
307 307 {
308 308 title->setGeometry(geometry);
309 309 QPointF center = geometry.center() - title->boundingRect().center();
310 310 title->setPos(center.x(),title->pos().y());
311 311 return geometry.adjusted(0,title->boundingRect().height()+1,0,0);
312 312 }
313 313
314 314 QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
315 315 {
316 316 QSizeF min = title->sizeHint(Qt::MinimumSize);
317 317 return minimum.adjusted(0, 0, min.width(), min.height());
318 318 }
319 319
320 320 QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
321 321 {
322 322 Q_UNUSED(constraint);
323 323 if (which == Qt::MinimumSize) {
324 324 QList<ChartAxis *> axes = m_presenter->axisItems();
325 325 ChartTitle *title = m_presenter->titleElement();
326 326 QLegend *legend = m_presenter->legend();
327 327 QRectF minimumRect(0, 0, 0, 0);
328 328 minimumRect = calculateBackgroundMinimum(minimumRect);
329 329 minimumRect = calculateContentMinimum(minimumRect);
330 330 minimumRect = calculateTitleMinimum(minimumRect, title);
331 331 minimumRect = calculateLegendMinimum(minimumRect, legend);
332 332 minimumRect = calculateAxisMinimum(minimumRect, axes);
333 333 return minimumRect.united(m_minChartRect).size().toSize();
334 334 }
335 335 return QSize(-1, -1);
336 336 }
337 337
338 338 void ChartLayout::setMargins(const QMargins &margins)
339 339 {
340 340 if (m_margins != margins) {
341 341 m_margins = margins;
342 342 updateGeometry();
343 343 }
344 344 }
345 345
346 346 QMargins ChartLayout::margins() const
347 347 {
348 348 return m_margins;
349 349 }
350 350
351 351 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now