##// END OF EJS Templates
Refactors layout managment...
Michal Klocek -
r1534:d9bcc3bd9d82
parent child
Show More
@@ -0,0 +1,144
1 #include "chartlayout_p.h"
2 #include "chartpresenter_p.h"
3 #include "chartaxis_p.h"
4 #include <QDebug>
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
7 ChartLayout::ChartLayout(ChartPresenter* presenter):
8 m_presenter(presenter),
9 m_marginBig(60),
10 m_marginSmall(20),
11 m_marginTiny(10),
12 m_chartMargins(QPointF(m_marginBig,m_marginBig),QPointF(m_marginBig,m_marginBig))
13 {
14
15 }
16
17 ChartLayout::~ChartLayout()
18 {
19
20 }
21
22 void ChartLayout::setGeometry(const QRectF& rect)
23 {
24 if (!rect.isValid()) return;
25
26 QGraphicsLayout::setGeometry(rect);
27
28 // check title size
29
30 QSize titleSize = QSize(0,0);
31
32 if (m_presenter->titleItem()) {
33 titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
34 }
35
36 qreal axisHeight = 0;
37 qreal axisWidth = 0;
38
39 // check axis size
40
41 foreach (ChartAxis* axis,m_presenter->axisItems()){
42 if(axis->axisType() == ChartAxis::X_AXIS)
43 axisHeight = qMax(axis->minimumHeight(),axisHeight);
44 else
45 axisWidth = qMax(axis->minimumWidth(),axisWidth);
46 }
47
48 QLegend* legend = m_presenter->legend();
49
50 qreal titlePadding = m_chartMargins.top()/2;
51
52 QRectF chartMargins = m_chartMargins;
53
54 // recalculate legend position
55 if (legend != 0 && legend->isVisible() && legend->isAttachedToChart()) {
56
57 // Reserve some space for legend
58 switch (legend->alignment()) {
59
60 case Qt::AlignTop: {
61 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
62 int topMargin = 2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny;
63 chartMargins = QRect(QPoint(m_chartMargins.left(),topMargin),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
64 m_legendMargins = QRect(QPoint(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny)),QPoint(chartMargins.right(),rect.height()-topMargin + m_marginTiny));
65 titlePadding = m_marginTiny + m_marginTiny;
66 break;
67 }
68 case Qt::AlignBottom: {
69 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
70 int bottomMargin = m_marginTiny + m_marginSmall + legendSize.height() + m_marginTiny + axisHeight;
71 chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomMargin));
72 m_legendMargins = QRect(QPoint(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight),QPoint(chartMargins.right(),m_marginTiny + m_marginSmall));
73 titlePadding = chartMargins.top()/2;
74 break;
75 }
76 case Qt::AlignLeft: {
77 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
78 int leftPadding = m_marginTiny + m_marginSmall + legendSize.width() + m_marginTiny + axisWidth;
79 chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
80 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,chartMargins.top()),QPoint(rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom()));
81 titlePadding = chartMargins.top()/2;
82 break;
83 }
84 case Qt::AlignRight: {
85 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
86 int rightPadding = m_marginTiny + m_marginSmall + legendSize.width() + m_marginTiny;
87 chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
88 m_legendMargins = QRect(QPoint(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,chartMargins.bottom()));
89 titlePadding = chartMargins.top()/2;
90 break;
91 }
92 default: {
93 break;
94 }
95 }
96
97 legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
98 }
99
100 // recalculate title position
101 if (m_presenter->titleItem()) {
102 QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
103 m_presenter->titleItem()->setPos(center.x(),titlePadding);
104 }
105
106 //recalculate background gradient
107 if (m_presenter->backgroundItem()) {
108 m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
109 }
110
111 QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
112
113 if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
114 m_presenter->setGeometry(chartRect);
115 }else if(chartRect.size().isEmpty()){
116 m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
117 }
118
119 }
120
121
122 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
123 {
124 Q_UNUSED(constraint);
125 if(which == Qt::MinimumSize)
126 return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
127 else
128 return QSize(-1,-1);
129 }
130
131 void ChartLayout::setMarginsMinimum(const QRectF& margins)
132 {
133 if(m_chartMargins != margins){
134 m_chartMargins = margins;
135 updateGeometry();
136 }
137 }
138
139 QRectF ChartLayout::margins() const
140 {
141 return m_chartMargins;
142 }
143
144 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,43
1 #ifndef CHARTLAYOUT_H_
2 #define CHARTLAYOUT_H_
3 #include <QGraphicsLayout>
4 #include "qchartglobal.h"
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8 class ChartPresenter;
9
10 class ChartLayout : public QGraphicsLayout
11 {
12 public:
13
14 ChartLayout(ChartPresenter* presenter);
15 virtual ~ChartLayout();
16
17 void setMarginsMinimum(const QRectF& margins);
18 QRectF margins() const;
19
20 void setGeometry(const QRectF& rect);
21
22 protected:
23 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
24 int count() const { return 0; }
25 QGraphicsLayoutItem* itemAt(int) const { return 0; };
26 void removeAt(int){};
27
28 private:
29 ChartPresenter* m_presenter;
30 int m_marginBig;
31 int m_marginSmall;
32 int m_marginTiny;
33
34 QRectF m_chartMargins;
35 QRectF m_legendMargins;
36
37
38
39 };
40
41 QTCOMMERCIALCHART_END_NAMESPACE
42
43 #endif
@@ -0,0 +1,348
1 #include "legendlayout_p.h"
2 #include "chartpresenter_p.h"
3 #include "legendmarker_p.h"
4 #include "qlegend_p.h"
5 #include <QDebug>
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8 LegendLayout::LegendLayout(QLegend* legend):
9 m_legend(legend)
10 {
11
12 }
13
14 LegendLayout::~LegendLayout()
15 {
16
17 }
18
19 void LegendLayout::setOffset(qreal x, qreal y)
20 {
21 bool scrollHorizontal = true;
22 switch(m_legend->alignment()) {
23 case Qt::AlignTop:
24 case Qt::AlignBottom: {
25 scrollHorizontal = true;
26 break;
27 }
28 case Qt::AlignLeft:
29 case Qt::AlignRight: {
30 scrollHorizontal = false;
31 break;
32 }
33 }
34
35 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
36 if (!m_legend->isAttachedToChart()) {
37 scrollHorizontal = !scrollHorizontal;
38 }
39
40 QRectF boundingRect = geometry();
41
42 // Limit offset between m_minOffset and m_maxOffset
43 if (scrollHorizontal) {
44 if(m_width<=boundingRect.width()) return;
45
46 if (x != m_offsetX) {
47 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
48 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
49 }
50 }
51 else {
52 if(m_height<=boundingRect.height()) return;
53
54 if (y != m_offsetY) {
55 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
56 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
57 }
58 }
59 }
60
61 QPointF LegendLayout::offset() const
62 {
63 return QPointF(m_offsetX,m_offsetY);
64 }
65
66 void LegendLayout::setGeometry(const QRectF& rect)
67 {
68 if (!rect.isValid()) return;
69
70 QGraphicsLayout::setGeometry(rect);
71
72 if(m_legend->isAttachedToChart()) {
73 setAttachedGeometry(rect);
74 }
75 else {
76 setDettachedGeometry(rect);
77 }
78 }
79
80 void LegendLayout::setAttachedGeometry(const QRectF& rect)
81 {
82
83 m_offsetX=0;
84 m_offsetY=0;
85
86 QSizeF size(0,0);
87
88 if( m_legend->d_ptr->markers().isEmpty()) return;
89
90 m_width=0;
91 m_height=0;
92
93 switch(m_legend->alignment()) {
94
95 case Qt::AlignTop:
96
97 case Qt::AlignBottom: {
98 QPointF point(0,0);
99 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
100 if (marker->isVisible()) {
101 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
102 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
103 const QRectF& rect = marker->boundingRect();
104 size = size.expandedTo(rect.size());
105 qreal w = rect.width();
106 m_width+=w;
107 point.setX(point.x() + w);
108 }
109 }
110 if(m_width<rect.width()) {
111 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
112
113 }
114 else {
115 m_legend->d_ptr->items()->setPos(rect.topLeft());
116 }
117 m_height=size.height();
118 }
119 break;
120 case Qt::AlignLeft:
121 case Qt::AlignRight: {
122 QPointF point(0,0);
123 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
124 if (marker->isVisible()) {
125 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
126 marker->setPos(point);
127 const QRectF& rect = marker->boundingRect();
128 qreal h = rect.height();
129 size = size.expandedTo(rect.size());
130 m_height+=h;
131 point.setY(point.y() + h);
132 }
133 }
134 if(m_height<rect.height()) {
135 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
136 }
137 else {
138 m_legend->d_ptr->items()->setPos(rect.topLeft());
139 }
140 m_width=size.width();
141 }
142 break;
143 }
144
145 m_minOffsetX = 0;
146 m_minOffsetY = 0;
147 m_maxOffsetX = m_width - rect.width();
148 m_maxOffsetY = m_height - rect.height();
149 }
150
151 void LegendLayout::setDettachedGeometry(const QRectF& rect)
152 {
153 // Detached layout is different.
154 // In detached mode legend may have multiple rows and columns, so layout calculations
155 // differ a log from attached mode.
156 // Also the scrolling logic is bit different.
157
158 m_offsetX=0;
159 m_offsetY=0;
160
161 QSizeF size(0,0);
162
163 if( m_legend->d_ptr->markers().isEmpty()) return;
164
165 QList<QGraphicsItem *> items = m_legend->d_ptr->items()->childItems();
166
167 switch (m_legend->alignment()) {
168 case Qt::AlignTop: {
169 QPointF point = rect.topLeft();
170 m_width = 0;
171 m_height = 0;
172 for (int i=0; i<items.count(); i++) {
173 QGraphicsItem *item = items.at(i);
174 if (item->isVisible()) {
175 const QRectF& boundingRect = item->boundingRect();
176 qreal w = boundingRect.width();
177 qreal h = boundingRect.height();
178 m_width = qMax(m_width,w);
179 m_height = qMax(m_height,h);
180 item->setPos(point.x(),point.y());
181 point.setX(point.x() + w);
182 if (point.x() + w > rect.topLeft().x() + rect.width()) {
183 // Next item would go off rect.
184 point.setX(rect.topLeft().x());
185 point.setY(point.y() + h);
186 if (i+1 < items.count()) {
187 m_height += h;
188 }
189 }
190 }
191 }
192 m_legend->d_ptr->items()->setPos(rect.topLeft());
193
194 m_minOffsetX = 0;
195 m_minOffsetY = 0;
196 m_maxOffsetX = m_width - rect.width();
197 m_maxOffsetY = m_height - rect.height();
198 }
199 break;
200 case Qt::AlignBottom: {
201 QPointF point = rect.bottomLeft();
202 m_width = 0;
203 m_height = 0;
204 for (int i=0; i<items.count(); i++) {
205 QGraphicsItem *item = items.at(i);
206 if (item->isVisible()) {
207 const QRectF& boundingRect = item->boundingRect();
208 qreal w = boundingRect.width();
209 qreal h = boundingRect.height();
210 m_width = qMax(m_width,w);
211 m_height = qMax(m_height,h);
212 item->setPos(point.x(),point.y() - h);
213 point.setX(point.x() + w);
214 if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
215 // Next item would go off rect.
216 point.setX(rect.bottomLeft().x());
217 point.setY(point.y() - h);
218 if (i+1 < items.count()) {
219 m_height += h;
220 }
221 }
222 }
223 }
224 m_legend->d_ptr->items()->setPos(rect.topLeft());
225
226 m_minOffsetX = 0;
227 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
228 m_maxOffsetX = m_width - rect.width();
229 m_maxOffsetY = 0;
230 }
231 break;
232 case Qt::AlignLeft: {
233 QPointF point = rect.topLeft();
234 m_width = 0;
235 m_height = 0;
236 qreal maxWidth = 0;
237 for (int i=0; i<items.count(); i++) {
238 QGraphicsItem *item = items.at(i);
239 if (item->isVisible()) {
240 const QRectF& boundingRect = item->boundingRect();
241 qreal w = boundingRect.width();
242 qreal h = boundingRect.height();
243 m_height = qMax(m_height,h);
244 maxWidth = qMax(maxWidth,w);
245 item->setPos(point.x(),point.y());
246 point.setY(point.y() + h);
247 if (point.y() + h > rect.topLeft().y() + rect.height()) {
248 // Next item would go off rect.
249 point.setX(point.x() + maxWidth);
250 point.setY(rect.topLeft().y());
251 if (i+1 < items.count()) {
252 m_width += maxWidth;
253 maxWidth = 0;
254 }
255 }
256 }
257 }
258 m_width += maxWidth;
259 m_legend->d_ptr->items()->setPos(rect.topLeft());
260
261 m_minOffsetX = 0;
262 m_minOffsetY = 0;
263 m_maxOffsetX = m_width - rect.width();
264 m_maxOffsetY = m_height - rect.height();
265 }
266 break;
267 case Qt::AlignRight: {
268 QPointF point = rect.topRight();
269 m_width = 0;
270 m_height = 0;
271 qreal maxWidth = 0;
272 for (int i=0; i<items.count(); i++) {
273 QGraphicsItem *item = items.at(i);
274 if (item->isVisible()) {
275 const QRectF& boundingRect = item->boundingRect();
276 qreal w = boundingRect.width();
277 qreal h = boundingRect.height();
278 m_height = qMax(m_height,h);
279 maxWidth = qMax(maxWidth,w);
280 item->setPos(point.x() - w,point.y());
281 point.setY(point.y() + h);
282 if (point.y() + h > rect.topLeft().y() + rect.height()) {
283 // Next item would go off rect.
284 point.setX(point.x() - maxWidth);
285 point.setY(rect.topLeft().y());
286 if (i+1 < items.count()) {
287 m_width += maxWidth;
288 maxWidth = 0;
289 }
290 }
291 }
292 }
293 m_width += maxWidth;
294 m_legend->d_ptr->items()->setPos(rect.topLeft());
295
296 m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
297 m_minOffsetY = 0;
298 m_maxOffsetX = 0;
299 m_maxOffsetY = m_height - rect.height();
300 }
301 break;
302 default:
303 break;
304 }
305
306 }
307
308 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
309 {
310 QSizeF size(0, 0);
311 qreal left, top, right, bottom;
312 getContentsMargins(&left, &top, &right, &bottom);
313
314 if(constraint.isValid()) {
315 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
316 size = size.expandedTo(marker->effectiveSizeHint(which));
317 }
318 size = size.boundedTo(constraint);
319 }
320 else if (constraint.width() >= 0) {
321 qreal width = 0;
322 qreal height = 0;
323 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
324 width+=marker->effectiveSizeHint(which).width();
325 height=qMax(height,marker->effectiveSizeHint(which).height());
326 }
327
328 size = QSizeF(qMin(constraint.width(),width), height);
329 }
330 else if (constraint.height() >= 0) {
331 qreal width = 0;
332 qreal height = 0;
333 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
334 width=qMax(width,marker->effectiveSizeHint(which).width());
335 height+=height,marker->effectiveSizeHint(which).height();
336 }
337 size = QSizeF(width,qMin(constraint.height(),height));
338 }
339 else {
340 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
341 size = size.expandedTo(marker->effectiveSizeHint(which));
342 }
343 }
344 size += QSize(left + right, top + bottom);
345 return size;
346 }
347
348 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,50
1 #ifndef LEGENDLAYOUT_H_
2 #define LEGENDLAYOUT_H_
3 #include <QGraphicsLayout>
4 #include "qchartglobal.h"
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8 class QLegend;
9
10 class LegendLayout : public QGraphicsLayout
11 {
12 public:
13
14 LegendLayout(QLegend* legend);
15 virtual ~LegendLayout();
16
17 void setGeometry(const QRectF& rect);
18
19 void setOffset(qreal x, qreal y);
20 QPointF offset() const;
21
22 protected:
23 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
24 int count() const { return 0; }
25 QGraphicsLayoutItem* itemAt(int) const { return 0; };
26 void removeAt(int){};
27
28 private:
29 void setAttachedGeometry(const QRectF& rect);
30 void setDettachedGeometry(const QRectF& rect);
31
32 private:
33 QLegend* m_legend;
34 int m_marginBig;
35 int m_marginSmall;
36 int m_marginTiny;
37 qreal m_offsetX;
38 qreal m_offsetY;
39 qreal m_minOffsetX;
40 qreal m_minOffsetY;
41 qreal m_maxOffsetX;
42 qreal m_maxOffsetY;
43 qreal m_width;
44 qreal m_height;
45
46 };
47
48 QTCOMMERCIALCHART_END_NAMESPACE
49
50 #endif
@@ -252,10 +252,10 void MainWidget::fontSizeChanged()
252 void MainWidget::updateLegendLayout()
252 void MainWidget::updateLegendLayout()
253 {
253 {
254 //![4]
254 //![4]
255 m_chart->legend()->setGeometry(m_legendPosX->value()
255 m_chart->legend()->setGeometry(QRectF(m_legendPosX->value()
256 ,m_legendPosY->value()
256 ,m_legendPosY->value()
257 ,m_legendWidth->value()
257 ,m_legendWidth->value()
258 ,m_legendHeight->value());
258 ,m_legendHeight->value()));
259 m_chart->legend()->update();
259 m_chart->legend()->update();
260 //![4]
260 //![4]
261 }
261 }
@@ -40,7 +40,9 ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter) : Chart(presenter),
40 m_min(0),
40 m_min(0),
41 m_max(0),
41 m_max(0),
42 m_ticksCount(0),
42 m_ticksCount(0),
43 m_animation(0)
43 m_animation(0),
44 m_minWidth(0),
45 m_minHeight(0)
44 {
46 {
45 //initial initialization
47 //initial initialization
46 m_axis->setZValue(ChartPresenter::AxisZValue);
48 m_axis->setZValue(ChartPresenter::AxisZValue);
@@ -52,6 +54,9 ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter) : Chart(presenter),
52 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
54 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
53 QObject::connect(m_chartAxis->categories()->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
55 QObject::connect(m_chartAxis->categories()->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
54
56
57 QGraphicsSimpleTextItem item;
58 m_font = item.font();
59
55 handleAxisUpdated();
60 handleAxisUpdated();
56 }
61 }
57
62
@@ -243,6 +248,7 void ChartAxis::setLabelsFont(const QFont &font)
243 foreach(QGraphicsItem* item , m_labels->childItems()) {
248 foreach(QGraphicsItem* item , m_labels->childItems()) {
244 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
249 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
245 }
250 }
251 m_font = font;
246 }
252 }
247
253
248 void ChartAxis::setShadesBrush(const QBrush &brush)
254 void ChartAxis::setShadesBrush(const QBrush &brush)
@@ -351,6 +357,20 void ChartAxis::handleGeometryChanged(const QRectF &rect)
351 }
357 }
352 }
358 }
353
359
360
361 qreal ChartAxis::minimumWidth()
362 {
363 if(m_minWidth == 0) updateGeometry();
364 return m_minWidth;
365 }
366
367 qreal ChartAxis::minimumHeight()
368 {
369 if(m_minHeight == 0) updateGeometry();
370 return m_minHeight;
371 }
372
373
354 void ChartAxis::axisSelected()
374 void ChartAxis::axisSelected()
355 {
375 {
356 qDebug()<<"TODO: axis clicked";
376 qDebug()<<"TODO: axis clicked";
@@ -34,6 +34,7
34 #include "chart_p.h"
34 #include "chart_p.h"
35 #include "axisanimation_p.h"
35 #include "axisanimation_p.h"
36 #include <QGraphicsItem>
36 #include <QGraphicsItem>
37 #include <QFont>
37
38
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
40
@@ -84,6 +85,9 public:
84
85
85 QRectF geometry() const { return m_rect; }
86 QRectF geometry() const { return m_rect; }
86
87
88 qreal minimumWidth();
89 qreal minimumHeight();
90
87 protected:
91 protected:
88 virtual void updateGeometry() = 0;
92 virtual void updateGeometry() = 0;
89 virtual QVector<qreal> calculateLayout() const = 0;
93 virtual QVector<qreal> calculateLayout() const = 0;
@@ -115,6 +119,9 protected:
115 qreal m_max;
119 qreal m_max;
116 int m_ticksCount;
120 int m_ticksCount;
117 AxisAnimation *m_animation;
121 AxisAnimation *m_animation;
122 qreal m_minWidth;
123 qreal m_minHeight;
124 QFont m_font;
118
125
119 friend class AxisAnimation;
126 friend class AxisAnimation;
120 friend class AxisItem;
127 friend class AxisItem;
@@ -24,6 +24,9
24 #include "qaxiscategories_p.h"
24 #include "qaxiscategories_p.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27 #include <QGraphicsLayout>
28 #include <QDebug>
29 #include <QFontMetrics>
27
30
28 static int label_padding = 5;
31 static int label_padding = 5;
29
32
@@ -56,6 +59,11 void ChartAxisX::updateGeometry()
56 {
59 {
57 const QVector<qreal>& layout = ChartAxis::layout();
60 const QVector<qreal>& layout = ChartAxis::layout();
58
61
62 m_minWidth = 0;
63 m_minHeight = 0;
64
65 if(layout.isEmpty()) return;
66
59 QStringList ticksList;
67 QStringList ticksList;
60
68
61 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
69 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
@@ -68,12 +76,10 void ChartAxisX::updateGeometry()
68 Q_ASSERT(labels.size() == ticksList.size());
76 Q_ASSERT(labels.size() == ticksList.size());
69 Q_ASSERT(layout.size() == ticksList.size());
77 Q_ASSERT(layout.size() == ticksList.size());
70
78
71 qreal minWidth = 0;
72 qreal minHeight = 0;
73
74 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
79 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
75 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
80 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
76
81
82 qreal width = 0;
77 for (int i = 0; i < layout.size(); ++i) {
83 for (int i = 0; i < layout.size(); ++i) {
78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
79 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
85 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
@@ -81,20 +87,29 void ChartAxisX::updateGeometry()
81 if (!categories || i<1) {
87 if (!categories || i<1) {
82 labelItem->setText(ticksList.at(i));
88 labelItem->setText(ticksList.at(i));
83 const QRectF& rect = labelItem->boundingRect();
89 const QRectF& rect = labelItem->boundingRect();
84 minWidth+=rect.width();
85 minHeight=qMax(rect.height(),minHeight);
86 QPointF center = rect.center();
90 QPointF center = rect.center();
87 labelItem->setTransformOriginPoint(center.x(), center.y());
91 labelItem->setTransformOriginPoint(center.x(), center.y());
88 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
92 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
93
94 if(labelItem->pos().x()<=width){
95 labelItem->setVisible(false);
96 lineItem->setVisible(false);
97 }else{
98 labelItem->setVisible(true);
99 lineItem->setVisible(true);
100 width=rect.width()+labelItem->pos().x();
101 }
102 m_minWidth+=rect.width();
103 m_minHeight=qMax(rect.height(),m_minHeight);
89 }
104 }
90 else {
105 else {
91 labelItem->setText(ticksList.at(i));
106 labelItem->setText(ticksList.at(i));
92 const QRectF& rect = labelItem->boundingRect();
107 const QRectF& rect = labelItem->boundingRect();
93 minWidth+=rect.width();
94 minHeight=qMax(rect.height()+label_padding,minHeight);
95 QPointF center = rect.center();
108 QPointF center = rect.center();
96 labelItem->setTransformOriginPoint(center.x(), center.y());
109 labelItem->setTransformOriginPoint(center.x(), center.y());
97 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
110 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
111 m_minWidth+=rect.width();
112 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
98 }
113 }
99
114
100 if ((i+1)%2 && i>1) {
115 if ((i+1)%2 && i>1) {
@@ -104,9 +119,6 void ChartAxisX::updateGeometry()
104 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
119 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
105 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
120 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
106 }
121 }
107
108 presenter()->setMinimumMarginWidth(this,minWidth);
109 presenter()->setMinimumMarginHeight(this,minHeight);
110 }
122 }
111
123
112 QTCOMMERCIALCHART_END_NAMESPACE
124 QTCOMMERCIALCHART_END_NAMESPACE
@@ -24,7 +24,9
24 #include "qaxiscategories_p.h"
24 #include "qaxiscategories_p.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27 #include <QGraphicsLayout>
28 #include <QFontMetrics>
29 #include <QDebug>
28
30
29 static int label_padding = 5;
31 static int label_padding = 5;
30
32
@@ -57,6 +59,10 QVector<qreal> ChartAxisY::calculateLayout() const
57 void ChartAxisY::updateGeometry()
59 void ChartAxisY::updateGeometry()
58 {
60 {
59 const QVector<qreal> &layout = ChartAxis::layout();
61 const QVector<qreal> &layout = ChartAxis::layout();
62 m_minWidth = 0;
63 m_minHeight = 0;
64
65 if(layout.isEmpty()) return;
60
66
61 QStringList ticksList;
67 QStringList ticksList;
62
68
@@ -70,8 +76,7 void ChartAxisY::updateGeometry()
70 Q_ASSERT(labels.size() == ticksList.size());
76 Q_ASSERT(labels.size() == ticksList.size());
71 Q_ASSERT(layout.size() == ticksList.size());
77 Q_ASSERT(layout.size() == ticksList.size());
72
78
73 qreal minWidth = 0;
79 qreal height = 2*m_rect.bottom();
74 qreal minHeight = 0;
75
80
76 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
81 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
77 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
82 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
@@ -84,17 +89,29 void ChartAxisY::updateGeometry()
84 if (!categories || i<1) {
89 if (!categories || i<1) {
85 labelItem->setText(ticksList.at(i));
90 labelItem->setText(ticksList.at(i));
86 const QRectF& rect = labelItem->boundingRect();
91 const QRectF& rect = labelItem->boundingRect();
87 minWidth=qMax(rect.width()+label_padding,minWidth);
92
88 minHeight+=rect.height();
89 QPointF center = rect.center();
93 QPointF center = rect.center();
90 labelItem->setTransformOriginPoint(center.x(), center.y());
94 labelItem->setTransformOriginPoint(center.x(), center.y());
91 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
95 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
96
97 if(labelItem->pos().y()+rect.height()>height) {
98 labelItem->setVisible(false);
99 lineItem->setVisible(false);
100 }
101 else {
102 labelItem->setVisible(true);
103 lineItem->setVisible(true);
104 height=labelItem->pos().y();
105 }
106
107 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
108 m_minHeight+=rect.height();
92 }
109 }
93 else {
110 else {
94 labelItem->setText(ticksList.at(i));
111 labelItem->setText(ticksList.at(i));
95 const QRectF& rect = labelItem->boundingRect();
112 const QRectF& rect = labelItem->boundingRect();
96 minWidth=qMax(rect.width(),minWidth);
113 m_minWidth=qMax(rect.width(),m_minWidth);
97 minHeight+=rect.height();
114 m_minHeight+=rect.height();
98 QPointF center = rect.center();
115 QPointF center = rect.center();
99 labelItem->setTransformOriginPoint(center.x(), center.y());
116 labelItem->setTransformOriginPoint(center.x(), center.y());
100 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
117 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
@@ -107,10 +124,7 void ChartAxisY::updateGeometry()
107 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
124 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
108 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
125 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
109 }
126 }
110
111 presenter()->setMinimumMarginWidth(this,minWidth);
112 presenter()->setMinimumMarginHeight(this,minHeight);
113
114 }
127 }
115
128
129
116 QTCOMMERCIALCHART_END_NAMESPACE
130 QTCOMMERCIALCHART_END_NAMESPACE
@@ -48,6 +48,7 public:
48 protected:
48 protected:
49 QVector<qreal> calculateLayout() const;
49 QVector<qreal> calculateLayout() const;
50 void updateGeometry();
50 void updateGeometry();
51
51 };
52 };
52
53
53 QTCOMMERCIALCHART_END_NAMESPACE
54 QTCOMMERCIALCHART_END_NAMESPACE
@@ -32,6 +32,7
32 #include "chartaxisy_p.h"
32 #include "chartaxisy_p.h"
33 #include "areachartitem_p.h"
33 #include "areachartitem_p.h"
34 #include "chartbackground_p.h"
34 #include "chartbackground_p.h"
35 #include "chartlayout_p.h"
35 #include <QTimer>
36 #include <QTimer>
36
37
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -41,17 +42,11 m_chart(chart),
41 m_animator(0),
42 m_animator(0),
42 m_dataset(dataset),
43 m_dataset(dataset),
43 m_chartTheme(0),
44 m_chartTheme(0),
44 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
45 m_options(QChart::NoAnimation),
45 m_options(QChart::NoAnimation),
46 m_minLeftMargin(0),
47 m_minBottomMargin(0),
48 m_state(ShowState),
46 m_state(ShowState),
47 m_layout(new ChartLayout(this)),
49 m_backgroundItem(0),
48 m_backgroundItem(0),
50 m_titleItem(0),
49 m_titleItem(0)
51 m_marginBig(60),
52 m_marginSmall(20),
53 m_marginTiny(10),
54 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
55 {
50 {
56
51
57 }
52 }
@@ -63,56 +58,12 ChartPresenter::~ChartPresenter()
63
58
64 void ChartPresenter::setGeometry(const QRectF& rect)
59 void ChartPresenter::setGeometry(const QRectF& rect)
65 {
60 {
66 m_rect = rect;
67 Q_ASSERT(m_rect.isValid());
68 updateLayout();
69 }
70
71 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
72 {
73 switch(axis->axisType()){
74 case ChartAxis::X_AXIS:
75 {
76 if(width>m_chartRect.width()+ m_chartMargins.left()) {
77 m_minLeftMargin= width - m_chartRect.width();
78 updateLayout();
79 }
80 break;
81 }
82 case ChartAxis::Y_AXIS:
83 {
84
61
85 if(m_minLeftMargin!=width){
62 Q_ASSERT(rect.isValid());
86 m_minLeftMargin= width;
87 updateLayout();
88 }
89 break;
90 }
91
92 }
93 }
94
95 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
96 {
97 switch(axis->axisType()){
98 case ChartAxis::X_AXIS:
99 {
100 if(m_minBottomMargin!=height) {
101 m_minBottomMargin= height;
102 updateLayout();
103 }
104 break;
105 }
106 case ChartAxis::Y_AXIS:
107 {
108
109 if(height>m_chartMargins.bottom()+m_chartRect.height()){
110 m_minBottomMargin= height - m_chartRect.height();
111 updateLayout();
112 }
113 break;
114 }
115
63
64 if(m_rect!=rect) {
65 m_rect=rect;
66 emit geometryChanged(m_rect);
116 }
67 }
117 }
68 }
118
69
@@ -147,7 +98,7 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
147
98
148 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
99 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
149 //initialize
100 //initialize
150 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
101 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
151 m_axisItems.insert(axis, item);
102 m_axisItems.insert(axis, item);
152 }
103 }
153
104
@@ -168,7 +119,7 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
168 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
119 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
169 //initialize
120 //initialize
170 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
121 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
171 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
122 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
172 m_chartItems.insert(series,item);
123 m_chartItems.insert(series,item);
173 }
124 }
174
125
@@ -243,23 +194,23 void ChartPresenter::resetAllElements()
243
194
244 void ChartPresenter::zoomIn(qreal factor)
195 void ChartPresenter::zoomIn(qreal factor)
245 {
196 {
246 QRectF rect = chartGeometry();
197 QRectF rect = geometry();
247 rect.setWidth(rect.width()/factor);
198 rect.setWidth(rect.width()/factor);
248 rect.setHeight(rect.height()/factor);
199 rect.setHeight(rect.height()/factor);
249 rect.moveCenter(chartGeometry().center());
200 rect.moveCenter(geometry().center());
250 zoomIn(rect);
201 zoomIn(rect);
251 }
202 }
252
203
253 void ChartPresenter::zoomIn(const QRectF& rect)
204 void ChartPresenter::zoomIn(const QRectF& rect)
254 {
205 {
255 QRectF r = rect.normalized();
206 QRectF r = rect.normalized();
256 r.translate(-m_chartMargins.topLeft());
207 r.translate(-geometry().topLeft());
257 if (!r.isValid())
208 if (!r.isValid())
258 return;
209 return;
259
210
260 m_state = ZoomInState;
211 m_state = ZoomInState;
261 m_statePoint = QPointF(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
212 m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
262 m_dataset->zoomInDomain(r,chartGeometry().size());
213 m_dataset->zoomInDomain(r,geometry().size());
263 m_state = ShowState;
214 m_state = ShowState;
264 }
215 }
265
216
@@ -268,14 +219,14 void ChartPresenter::zoomOut(qreal factor)
268 m_state = ZoomOutState;
219 m_state = ZoomOutState;
269
220
270 QRectF chartRect;
221 QRectF chartRect;
271 chartRect.setSize(chartGeometry().size());
222 chartRect.setSize(geometry().size());
272
223
273 QRectF rect;
224 QRectF rect;
274 rect.setSize(chartRect.size()/factor);
225 rect.setSize(chartRect.size()/factor);
275 rect.moveCenter(chartRect.center());
226 rect.moveCenter(chartRect.center());
276 if (!rect.isValid())
227 if (!rect.isValid())
277 return;
228 return;
278 m_statePoint = QPointF(rect.center().x()/chartGeometry().width(),rect.center().y()/chartGeometry().height());
229 m_statePoint = QPointF(rect.center().x()/geometry().width(),rect.center().y()/geometry().height());
279 m_dataset->zoomOutDomain(rect, chartRect.size());
230 m_dataset->zoomOutDomain(rect, chartRect.size());
280 m_state = ShowState;
231 m_state = ShowState;
281 }
232 }
@@ -287,7 +238,7 void ChartPresenter::scroll(qreal dx,qreal dy)
287 if(dy<0) m_state=ScrollUpState;
238 if(dy<0) m_state=ScrollUpState;
288 if(dy>0) m_state=ScrollDownState;
239 if(dy>0) m_state=ScrollDownState;
289
240
290 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
241 m_dataset->scrollDomain(dx,dy,geometry().size());
291 m_state = ShowState;
242 m_state = ShowState;
292 }
243 }
293
244
@@ -296,136 +247,170 QChart::AnimationOptions ChartPresenter::animationOptions() const
296 return m_options;
247 return m_options;
297 }
248 }
298
249
299 void ChartPresenter::updateLayout()
250 void ChartPresenter::createBackgroundItem()
300 {
251 {
301 if (!m_rect.isValid()) return;
252 if (!m_backgroundItem) {
253 m_backgroundItem = new ChartBackground(rootItem());
254 m_backgroundItem->setPen(Qt::NoPen);
255 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
256 }
257 }
302
258
303 QRectF oldChargMargins = m_chartMargins;
259 void ChartPresenter::createTitleItem()
260 {
261 if (!m_titleItem) {
262 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
263 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
264 }
265 }
304
266
305 // recalculate title size
306
267
307 QSize titleSize;
268 void ChartPresenter::handleAnimationFinished()
308 int titlePadding=0;
269 {
270 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
271 if(m_animations.empty()) emit animationsFinished();
272 }
309
273
310 if (m_titleItem) {
274 void ChartPresenter::startAnimation(ChartAnimation* animation)
311 titleSize= m_titleItem->boundingRect().size().toSize();
275 {
276 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
277 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
278 if(!m_animations.isEmpty()){
279 m_animations.append(animation);
312 }
280 }
281 QTimer::singleShot(0, animation, SLOT(start()));
282 }
313
283
314 //defaults
284 QGraphicsRectItem* ChartPresenter::backgroundItem()
315 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
285 {
316 titlePadding = m_chartMargins.top()/2;
286 return m_backgroundItem;
287 }
317
288
318 QLegend* legend = m_chart->d_ptr->m_legend;
289 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
290 {
291 createBackgroundItem();
292 m_backgroundItem->setBrush(brush);
293 m_layout->invalidate();
294 }
319
295
320 // recalculate legend position
296 QBrush ChartPresenter::backgroundBrush() const
321 if (legend != 0 && legend->isAttachedToChart() && legend->isEnabled()) {
297 {
298 if (!m_backgroundItem) return QBrush();
299 return m_backgroundItem->brush();
300 }
322
301
323 // Reserve some space for legend
302 void ChartPresenter::setBackgroundPen(const QPen& pen)
324 switch (legend->alignment()) {
303 {
304 createBackgroundItem();
305 m_backgroundItem->setPen(pen);
306 m_layout->invalidate();
307 }
325
308
326 case Qt::AlignTop: {
309 QPen ChartPresenter::backgroundPen() const
327 int ledgendSize = legend->minHeight();
310 {
328 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
311 if (!m_backgroundItem) return QPen();
329 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
312 return m_backgroundItem->pen();
330 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
313 }
331 titlePadding = m_marginTiny + m_marginTiny;
332 break;
333 }
334 case Qt::AlignBottom: {
335 int ledgendSize = legend->minHeight();
336 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
337 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
338 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
339 titlePadding = m_chartMargins.top()/2;
340 break;
341 }
342 case Qt::AlignLeft: {
343 int ledgendSize = legend->minWidth();
344 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
345 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
346 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
347 titlePadding = m_chartMargins.top()/2;
348 break;
349 }
350 case Qt::AlignRight: {
351 int ledgendSize = legend->minWidth();
352 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
353 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
354 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
355 titlePadding = m_chartMargins.top()/2;
356 break;
357 }
358 default: {
359 break;
360 }
361 }
362 }
363
314
364 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
315 QGraphicsItem* ChartPresenter::titleItem()
365 {
316 {
366 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
317 return m_titleItem;
367 return;
318 }
368 }
369
319
320 void ChartPresenter::setTitle(const QString& title)
321 {
322 createTitleItem();
323 m_titleItem->setText(title);
324 m_layout->invalidate();
325 }
370
326
371 // recalculate title position
327 QString ChartPresenter::title() const
372 if (m_titleItem) {
328 {
373 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
329 if (!m_titleItem) return QString();
374 m_titleItem->setPos(center.x(),titlePadding);
330 return m_titleItem->text();
375 }
331 }
376
332
377 //recalculate background gradient
333 void ChartPresenter::setTitleFont(const QFont& font)
378 if (m_backgroundItem) {
334 {
379 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
335 createTitleItem();
380 }
336 m_titleItem->setFont(font);
337 m_layout->invalidate();
338 }
381
339
340 QFont ChartPresenter::titleFont() const
341 {
342 if (!m_titleItem) return QFont();
343 return m_titleItem->font();
344 }
382
345
383 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
346 void ChartPresenter::setTitleBrush(const QBrush &brush)
347 {
348 createTitleItem();
349 m_titleItem->setBrush(brush);
350 m_layout->invalidate();
351 }
384
352
385 if (legend != 0 && legend->isAttachedToChart() && legend->isEnabled()) {
353 QBrush ChartPresenter::titleBrush() const
386 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
354 {
387 }
355 if (!m_titleItem) return QBrush();
356 return m_titleItem->brush();
357 }
358
359 void ChartPresenter::setBackgroundVisible(bool visible)
360 {
361 createBackgroundItem();
362 m_backgroundItem->setVisible(visible);
363 }
388
364
389 if(m_chartRect!=chartRect && chartRect.isValid()){
390 m_chartRect=chartRect;
391 emit geometryChanged(m_chartRect);
392 }
393
365
394 if (oldChargMargins != m_chartMargins)
366 bool ChartPresenter::isBackgroundVisible() const
395 emit marginsChanged(m_chartMargins);
367 {
368 if (!m_backgroundItem) return false;
369 return m_backgroundItem->isVisible();
396 }
370 }
397
371
398 void ChartPresenter::createChartBackgroundItem()
372 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
399 {
373 {
400 if (!m_backgroundItem) {
374 createBackgroundItem();
401 m_backgroundItem = new ChartBackground(rootItem());
375 m_backgroundItem->setDropShadowEnabled(enabled);
402 m_backgroundItem->setPen(Qt::NoPen);
403 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
404 }
405 }
376 }
406
377
407 void ChartPresenter::createChartTitleItem()
378 bool ChartPresenter::isBackgroundDropShadowEnabled() const
408 {
379 {
409 if (!m_titleItem) {
380 if (!m_backgroundItem) return false;
410 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
381 return m_backgroundItem->isDropShadowEnabled();
411 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
412 }
413 }
382 }
414
383
415 void ChartPresenter::handleAnimationFinished()
384
385 QGraphicsLayout* ChartPresenter::layout()
416 {
386 {
417 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
387 return m_layout;
418 if(m_animations.empty()) emit animationsFinished();
419 }
388 }
420
389
421 void ChartPresenter::startAnimation(ChartAnimation* animation)
390 void ChartPresenter::setMarginsMinimum(const QRectF& margins)
422 {
391 {
423 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
392 Q_UNUSED(margins);
424 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
393 // m_layout->setMarginsMinimum(margins);
425 if(!m_animations.isEmpty()){
394 }
426 m_animations.append(animation);
395
427 }
396 QRectF ChartPresenter::margins() const
428 QTimer::singleShot(0, animation, SLOT(start()));
397 {
398 return QRectF();//m_layout->margins();
399 }
400
401 QLegend* ChartPresenter::legend()
402 {
403 return m_chart->legend();
404 }
405
406 QList<ChartAxis*> ChartPresenter::axisItems() const
407 {
408 return m_axisItems.values();
409 }
410
411 void ChartPresenter::setVisible(bool visible)
412 {
413 m_chart->setVisible(visible);
429 }
414 }
430
415
431 #include "moc_chartpresenter_p.cpp"
416 #include "moc_chartpresenter_p.cpp"
@@ -45,6 +45,7 class ChartTheme;
45 class ChartAnimator;
45 class ChartAnimator;
46 class ChartBackground;
46 class ChartBackground;
47 class ChartAnimation;
47 class ChartAnimation;
48 class ChartLayout;
48
49
49 class ChartPresenter: public QObject
50 class ChartPresenter: public QObject
50 {
51 {
@@ -80,6 +81,34 public:
80 ChartTheme *chartTheme() const { return m_chartTheme; }
81 ChartTheme *chartTheme() const { return m_chartTheme; }
81 ChartDataSet *dataSet() const { return m_dataset; }
82 ChartDataSet *dataSet() const { return m_dataset; }
82 QGraphicsItem* rootItem() const { return m_chart; }
83 QGraphicsItem* rootItem() const { return m_chart; }
84 QGraphicsRectItem* backgroundItem();
85 QGraphicsItem* titleItem();
86 QList<ChartAxis*> axisItems() const;
87
88 QLegend* legend();
89
90 void setBackgroundBrush(const QBrush& brush);
91 QBrush backgroundBrush() const;
92
93 void setBackgroundPen(const QPen& pen);
94 QPen backgroundPen() const;
95
96 void setTitle(const QString& title);
97 QString title() const;
98
99 void setTitleFont(const QFont& font);
100 QFont titleFont() const;
101
102 void setTitleBrush(const QBrush &brush);
103 QBrush titleBrush() const;
104
105 void setBackgroundVisible(bool visible);
106 bool isBackgroundVisible() const;
107
108 void setBackgroundDropShadowEnabled(bool enabled);
109 bool isBackgroundDropShadowEnabled() const;
110
111 void setVisible(bool visible);
83
112
84 void setTheme(QChart::ChartTheme theme,bool force = true);
113 void setTheme(QChart::ChartTheme theme,bool force = true);
85 QChart::ChartTheme theme();
114 QChart::ChartTheme theme();
@@ -93,28 +122,27 public:
93 void scroll(qreal dx,qreal dy);
122 void scroll(qreal dx,qreal dy);
94
123
95 void setGeometry(const QRectF& rect);
124 void setGeometry(const QRectF& rect);
96 QRectF chartGeometry() const { return m_chartRect; }
125 QRectF geometry() { return m_rect; }
97
98 void setMinimumMarginHeight(ChartAxis* axis, qreal height);
99 void setMinimumMarginWidth(ChartAxis* axis, qreal width);
100 qreal minimumLeftMargin() const { return m_minLeftMargin; }
101 qreal minimumBottomMargin() const { return m_minBottomMargin; }
102
126
103 void startAnimation(ChartAnimation* animation);
127 void startAnimation(ChartAnimation* animation);
104 State state() const { return m_state; }
128 State state() const { return m_state; }
105 QPointF statePoint() const { return m_statePoint; }
129 QPointF statePoint() const { return m_statePoint; }
106 public: //TODO: fix me
130
107 void resetAllElements();
131 void resetAllElements();
108 void createChartBackgroundItem();
132
109 void createChartTitleItem();
133 void setMarginsMinimum(const QRectF& margins);
110 QRectF margins() const { return m_chartMargins;}
134 QRectF margins() const;
135 QGraphicsLayout* layout();
136
137 private:
138 void createBackgroundItem();
139 void createTitleItem();
111
140
112 public Q_SLOTS:
141 public Q_SLOTS:
113 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
142 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
114 void handleSeriesRemoved(QAbstractSeries* series);
143 void handleSeriesRemoved(QAbstractSeries* series);
115 void handleAxisAdded(QAxis* axis,Domain* domain);
144 void handleAxisAdded(QAxis* axis,Domain* domain);
116 void handleAxisRemoved(QAxis* axis);
145 void handleAxisRemoved(QAxis* axis);
117 void updateLayout();
118
146
119 private Q_SLOTS:
147 private Q_SLOTS:
120 void handleAnimationFinished();
148 void handleAnimationFinished();
@@ -132,22 +160,13 private:
132 QMap<QAbstractSeries *, Chart *> m_chartItems;
160 QMap<QAbstractSeries *, Chart *> m_chartItems;
133 QMap<QAxis *, ChartAxis *> m_axisItems;
161 QMap<QAxis *, ChartAxis *> m_axisItems;
134 QRectF m_rect;
162 QRectF m_rect;
135 QRectF m_chartRect;
136 QChart::AnimationOptions m_options;
163 QChart::AnimationOptions m_options;
137 qreal m_minLeftMargin;
138 qreal m_minBottomMargin;
139 State m_state;
164 State m_state;
140 QPointF m_statePoint;
165 QPointF m_statePoint;
141 QList<ChartAnimation*> m_animations;
166 QList<ChartAnimation*> m_animations;
142
167 ChartLayout* m_layout;
143 public: //TODO: fixme
144 ChartBackground* m_backgroundItem;
168 ChartBackground* m_backgroundItem;
145 QGraphicsSimpleTextItem* m_titleItem;
169 QGraphicsSimpleTextItem* m_titleItem;
146 int m_marginBig;
147 int m_marginSmall;
148 int m_marginTiny;
149 QRectF m_chartMargins;
150 QRectF m_legendMargins;
151 };
170 };
152
171
153 QTCOMMERCIALCHART_END_NAMESPACE
172 QTCOMMERCIALCHART_END_NAMESPACE
@@ -3,12 +3,14 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/qlegend.cpp \
5 $$PWD/qlegend.cpp \
6 $$PWD/legendmarker.cpp
6 $$PWD/legendmarker.cpp \
7 $$PWD/legendlayout.cpp
7
8
8 PRIVATE_HEADERS += \
9 PRIVATE_HEADERS += \
9 $$PWD/legendmarker_p.h \
10 $$PWD/legendmarker_p.h \
10 $$PWD/legendscroller_p.h \
11 $$PWD/legendscroller_p.h \
11 $$PWD/qlegend_p.h
12 $$PWD/qlegend_p.h \
13 $$PWD/legendlayout_p.h
12
14
13
15
14 PUBLIC_HEADERS += \
16 PUBLIC_HEADERS += \
@@ -43,17 +43,18 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
43 m_boundingRect(0,0,0,0),
43 m_boundingRect(0,0,0,0),
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),
48 m_space(4)
47 {
49 {
48 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
49 m_rectItem->setRect(m_markerRect);
51 m_rectItem->setRect(m_markerRect);
50 updateLayout();
51 }
52 }
52
53
53 void LegendMarker::setPen(const QPen &pen)
54 void LegendMarker::setPen(const QPen &pen)
54 {
55 {
55 m_rectItem->setPen(pen);
56 m_rectItem->setPen(pen);
56 updateLayout();
57 m_textItem->setPen(pen);
57 }
58 }
58
59
59 QPen LegendMarker::pen() const
60 QPen LegendMarker::pen() const
@@ -74,7 +75,6 QBrush LegendMarker::brush() const
74 void LegendMarker::setFont(const QFont &font)
75 void LegendMarker::setFont(const QFont &font)
75 {
76 {
76 m_textItem->setFont(font);
77 m_textItem->setFont(font);
77 updateLayout();
78 }
78 }
79
79
80 QFont LegendMarker::font() const
80 QFont LegendMarker::font() const
@@ -85,23 +85,21 QFont LegendMarker::font() const
85 void LegendMarker::setLabel(const QString label)
85 void LegendMarker::setLabel(const QString label)
86 {
86 {
87 m_textItem->setText(label);
87 m_textItem->setText(label);
88 updateLayout();
89 }
88 }
90
89
91 void LegendMarker::setSize(const QSize& size)
90 QString LegendMarker::label() const
92 {
91 {
93 m_markerRect = QRectF(0,0,size.width(),size.height());
92 return m_textItem->text();
94 }
93 }
95
94
96 QString LegendMarker::label() const
95 QRectF LegendMarker::boundingRect() const
97 {
96 {
98 return m_textItem->text();
97 return m_boundingRect;
99 }
98 }
100
99
101 void LegendMarker::setLabelBrush(const QBrush &brush)
100 void LegendMarker::setLabelBrush(const QBrush &brush)
102 {
101 {
103 m_textItem->setBrush(brush);
102 m_textItem->setBrush(brush);
104 updateLayout();
105 }
103 }
106
104
107 QBrush LegendMarker::labelBrush() const
105 QBrush LegendMarker::labelBrush() const
@@ -109,6 +107,18 QBrush LegendMarker::labelBrush() const
109 return m_textItem->brush();
107 return m_textItem->brush();
110 }
108 }
111
109
110
111 void LegendMarker::setGeometry(const QRectF& rect)
112 {
113 const QRectF& textRect = m_textItem->boundingRect();
114
115 m_textItem->setPos(m_markerRect.width() + m_space + m_margin,rect.height()/2 - textRect.height()/2);
116 m_rectItem->setPos(m_margin,rect.height()/2 - m_markerRect.height()/2);
117
118 prepareGeometryChange();
119 m_boundingRect = rect;
120 }
121
112 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
122 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
113 {
123 {
114 Q_UNUSED(option)
124 Q_UNUSED(option)
@@ -116,23 +126,26 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
116 Q_UNUSED(painter)
126 Q_UNUSED(painter)
117 }
127 }
118
128
119 QRectF LegendMarker::boundingRect() const
120 {
121 return m_boundingRect;
122 }
123
129
124 void LegendMarker::updateLayout()
130 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
125 {
131 {
132 Q_UNUSED(constraint)
126
133
127 static const qreal margin = 2;
134 QFontMetrics fn(m_textItem->font());
128 static const qreal space = 4;
135 QSizeF sh;
129
136
130 const QRectF& textRect = m_textItem->boundingRect();
137 switch (which) {
131 prepareGeometryChange();
138 case Qt::MinimumSize:
132 m_boundingRect = QRectF(0,0,m_markerRect.width() + 2*margin + space + textRect.width(),qMax(m_markerRect.height()+2*margin,textRect.height()+2*margin));
139 sh = QSizeF(fn.boundingRect("...").width(),fn.height());
133 m_textItem->setPos(m_markerRect.width() + space + margin,m_boundingRect.height()/2 - textRect.height()/2);
140 break;
134 m_rectItem->setPos(margin,m_boundingRect.height()/2 - m_markerRect.height()/2);
141 case Qt::PreferredSize:
142 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));
143 break;
144 default:
145 break;
146 }
135
147
148 return sh;
136 }
149 }
137
150
138 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
151 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
@@ -35,6 +35,7
35 #include <QBrush>
35 #include <QBrush>
36 #include <QPen>
36 #include <QPen>
37 #include <QGraphicsSimpleTextItem>
37 #include <QGraphicsSimpleTextItem>
38 #include <QGraphicsLayoutItem>
38
39
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40
41
@@ -47,35 +48,37 class QPieSlice;
47 class QLegend;
48 class QLegend;
48 class QPieSeries;
49 class QPieSeries;
49
50
50 class LegendMarker : public QGraphicsObject
51 class LegendMarker : public QGraphicsObject, public QGraphicsLayoutItem
51 {
52 {
52 Q_OBJECT
53 Q_OBJECT
53
54 Q_INTERFACES(QGraphicsLayoutItem)
54 public:
55 public:
55 explicit LegendMarker(QAbstractSeries *m_series, QLegend *parent);
56 explicit LegendMarker(QAbstractSeries *m_series, QLegend *parent);
56
57
57 void setPen(const QPen &pen);
58 void setPen(const QPen &pen);
58 QPen pen() const;
59 QPen pen() const;
60
59 void setBrush(const QBrush &brush);
61 void setBrush(const QBrush &brush);
60 QBrush brush() const;
62 QBrush brush() const;
61
63
62 void setFont(const QFont &font);
64 void setFont(const QFont &font);
63 QFont font() const;
65 QFont font() const;
64
66
65 void setSize(const QSize& size);
66
67 void setLabel(const QString label);
67 void setLabel(const QString label);
68 QString label() const;
68 QString label() const;
69
69 void setLabelBrush(const QBrush &brush);
70 void setLabelBrush(const QBrush &brush);
70 QBrush labelBrush() const;
71 QBrush labelBrush() const;
71
72
72 QAbstractSeries *series() const { return m_series;}
73 QAbstractSeries *series() const { return m_series;}
73
74
74 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
75 void setGeometry(const QRectF& rect);
75
76
76 QRectF boundingRect() const;
77 QRectF boundingRect() const;
77
78
78 void updateLayout();
79 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
80
81 QSizeF sizeHint (Qt::SizeHint which, const QSizeF& constraint) const;
79
82
80 protected:
83 protected:
81 // From QGraphicsObject
84 // From QGraphicsObject
@@ -91,6 +94,8 protected:
91 QLegend* m_legend;
94 QLegend* m_legend;
92 QGraphicsSimpleTextItem *m_textItem;
95 QGraphicsSimpleTextItem *m_textItem;
93 QGraphicsRectItem *m_rectItem;
96 QGraphicsRectItem *m_rectItem;
97 qreal m_margin;
98 qreal m_space;
94
99
95 };
100 };
96
101
@@ -23,7 +23,7
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26 #include "legendlayout_p.h"
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
@@ -41,7 +41,7
41 #include <QPainter>
41 #include <QPainter>
42 #include <QPen>
42 #include <QPen>
43 #include <QTimer>
43 #include <QTimer>
44
44 #include <QGraphicsLayout>
45 #include <QGraphicsSceneEvent>
45 #include <QGraphicsSceneEvent>
46
46
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -190,6 +190,7 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
190 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
190 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
191 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
191 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
192 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
192 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
193 setLayout(d_ptr->m_layout);
193 }
194 }
194
195
195 /*!
196 /*!
@@ -212,16 +213,10 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
212 painter->setPen(d_ptr->m_pen);
213 painter->setPen(d_ptr->m_pen);
213 painter->setBrush(d_ptr->m_brush);
214 painter->setBrush(d_ptr->m_brush);
214 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
215 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
215 }
216
216
217 /*!
218 \internal
219 */
220 QRectF QLegend::boundingRect() const
221 {
222 return d_ptr->m_rect;
223 }
217 }
224
218
219
225 /*!
220 /*!
226 Sets the \a brush of legend. Brush affects the background of legend.
221 Sets the \a brush of legend. Brush affects the background of legend.
227 */
222 */
@@ -277,6 +272,23 QPen QLegend::pen() const
277 return d_ptr->m_pen;
272 return d_ptr->m_pen;
278 }
273 }
279
274
275 void QLegend::setFont(const QFont &font)
276 {
277 if (d_ptr->m_font != font) {
278 d_ptr->m_font = font;
279
280 foreach (LegendMarker *marker, d_ptr->markers()) {
281 marker->setFont(d_ptr->m_font);
282 }
283 emit fontChanged(font);
284 }
285 }
286
287 QFont QLegend::font() const
288 {
289 return d_ptr->m_font;
290 }
291
280 void QLegend::setBorderColor(QColor color)
292 void QLegend::setBorderColor(QColor color)
281 {
293 {
282 QPen p = d_ptr->m_pen;
294 QPen p = d_ptr->m_pen;
@@ -292,26 +304,18 QColor QLegend::borderColor()
292 return d_ptr->m_pen.color();
304 return d_ptr->m_pen.color();
293 }
305 }
294
306
295 void QLegend::setFont(const QFont &font)
296 {
297 if (d_ptr->m_font != font) {
298 d_ptr->setFont(font);
299 emit fontChanged(font);
300 }
301 }
302
303 QFont QLegend::font() const
304 {
305 return d_ptr->m_font;
306 }
307
308 /*!
307 /*!
309 Set brush used to draw labels to \a brush.
308 Set brush used to draw labels to \a brush.
310 */
309 */
311 void QLegend::setLabelBrush(const QBrush &brush)
310 void QLegend::setLabelBrush(const QBrush &brush)
312 {
311 {
313 if (d_ptr->m_labelBrush != brush) {
312 if (d_ptr->m_labelBrush != brush) {
314 d_ptr->setLabelBrush(brush);
313
314 d_ptr->m_labelBrush = brush;
315
316 foreach (LegendMarker *marker, d_ptr->markers()) {
317 marker->setLabelBrush(d_ptr->m_labelBrush);
318 }
315 emit labelBrushChanged(brush);
319 emit labelBrushChanged(brush);
316 }
320 }
317 }
321 }
@@ -340,11 +344,17 QColor QLegend::labelColor() const
340 return d_ptr->m_labelBrush.color();
344 return d_ptr->m_labelBrush.color();
341 }
345 }
342
346
347
343 void QLegend::setAlignment(Qt::Alignment alignment)
348 void QLegend::setAlignment(Qt::Alignment alignment)
344 {
349 {
345 if(d_ptr->m_alignment!=alignment) {
350 if(d_ptr->m_alignment!=alignment) {
346 d_ptr->m_alignment = alignment;
351 d_ptr->m_alignment = alignment;
347 d_ptr->updateLayout();
352 updateGeometry();
353 if(isAttachedToChart()){
354 d_ptr->m_presenter->layout()->invalidate();
355 }else{
356 layout()->invalidate();
357 }
348 }
358 }
349 }
359 }
350
360
@@ -359,6 +369,9 Qt::Alignment QLegend::alignment() const
359 void QLegend::detachFromChart()
369 void QLegend::detachFromChart()
360 {
370 {
361 d_ptr->m_attachedToChart = false;
371 d_ptr->m_attachedToChart = false;
372 d_ptr->m_layout->invalidate();
373 setParent(0);
374
362 }
375 }
363
376
364 /*!
377 /*!
@@ -366,7 +379,9 void QLegend::detachFromChart()
366 */
379 */
367 void QLegend::attachToChart()
380 void QLegend::attachToChart()
368 {
381 {
369 d_ptr->attachToChart();
382 d_ptr->m_attachedToChart = true;
383 d_ptr->m_layout->invalidate();
384 setParent(d_ptr->m_chart);
370 }
385 }
371
386
372 /*!
387 /*!
@@ -400,24 +415,10 bool QLegend::isBackgroundVisible() const
400 /*!
415 /*!
401 \internal \a event see QGraphicsWidget for details
416 \internal \a event see QGraphicsWidget for details
402 */
417 */
403 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
404 {
405 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
406 QGraphicsWidget::resizeEvent(event);
407 if(d_ptr->m_rect != rect) {
408 d_ptr->m_rect = rect;
409 d_ptr->updateLayout();
410 }
411 }
412
413 /*!
414 \internal \a event see QGraphicsWidget for details
415 */
416 void QLegend::hideEvent(QHideEvent *event)
418 void QLegend::hideEvent(QHideEvent *event)
417 {
419 {
418 QGraphicsWidget::hideEvent(event);
420 QGraphicsWidget::hideEvent(event);
419 setEnabled(false);
421 d_ptr->m_presenter->layout()->invalidate();
420 d_ptr->updateLayout();
421 }
422 }
422
423
423 /*!
424 /*!
@@ -426,18 +427,7 void QLegend::hideEvent(QHideEvent *event)
426 void QLegend::showEvent(QShowEvent *event)
427 void QLegend::showEvent(QShowEvent *event)
427 {
428 {
428 QGraphicsWidget::showEvent(event);
429 QGraphicsWidget::showEvent(event);
429 setEnabled(true);
430 d_ptr->m_presenter->layout()->invalidate();
430 d_ptr->updateLayout();
431 }
432
433 qreal QLegend::minWidth() const
434 {
435 return d_ptr->m_minWidth;
436 }
437
438 qreal QLegend::minHeight() const
439 {
440 return d_ptr->m_minHeight;
441 }
431 }
442
432
443 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
433 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -445,18 +435,13 qreal QLegend::minHeight() const
445 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
435 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
446 q_ptr(q),
436 q_ptr(q),
447 m_presenter(presenter),
437 m_presenter(presenter),
438 m_layout(new LegendLayout(q)),
448 m_chart(chart),
439 m_chart(chart),
449 m_markers(new QGraphicsItemGroup(q)),
440 m_items(new QGraphicsItemGroup(q)),
450 m_alignment(Qt::AlignTop),
441 m_alignment(Qt::AlignTop),
451 m_brush(QBrush()),
442 m_brush(QBrush()),
452 m_pen(QPen()),
443 m_pen(QPen()),
453 m_labelBrush(QBrush()),
444 m_labelBrush(QBrush()),
454 m_offsetX(0),
455 m_offsetY(0),
456 m_minWidth(0),
457 m_minHeight(0),
458 m_width(0),
459 m_height(0),
460 m_diameter(5),
445 m_diameter(5),
461 m_attachedToChart(true),
446 m_attachedToChart(true),
462 m_backgroundVisible(false)
447 m_backgroundVisible(false)
@@ -471,290 +456,12 QLegendPrivate::~QLegendPrivate()
471
456
472 void QLegendPrivate::setOffset(qreal x, qreal y)
457 void QLegendPrivate::setOffset(qreal x, qreal y)
473 {
458 {
474 bool scrollHorizontal = true;
459 m_layout->setOffset(x,y);
475 switch(m_alignment) {
476 case Qt::AlignTop:
477 case Qt::AlignBottom: {
478 scrollHorizontal = true;
479 break;
480 }
481 case Qt::AlignLeft:
482 case Qt::AlignRight: {
483 scrollHorizontal = false;
484 break;
485 }
486 }
487
488 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
489 if (!m_attachedToChart) {
490 scrollHorizontal = !scrollHorizontal;
491 }
492
493 // Limit offset between m_minOffset and m_maxOffset
494 if (scrollHorizontal) {
495 if(m_width<=m_rect.width()) return;
496
497 if (x != m_offsetX) {
498 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
499 m_markers->setPos(-m_offsetX,m_rect.top());
500 }
501 } else {
502 if(m_height<=m_rect.height()) return;
503
504 if (y != m_offsetY) {
505 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
506 m_markers->setPos(m_rect.left(),-m_offsetY);
507 }
508 }
509 }
460 }
510
461
511 QPointF QLegendPrivate::offset() const
462 QPointF QLegendPrivate::offset() const
512 {
463 {
513 return QPointF(m_offsetX,m_offsetY);
464 return m_layout->offset();
514 }
515
516 void QLegendPrivate::updateLayout()
517 {
518 if (!m_attachedToChart) {
519 updateDetachedLayout();
520 return;
521 }
522
523 m_offsetX=0;
524 QList<QGraphicsItem *> items = m_markers->childItems();
525
526 if(items.isEmpty()) return;
527
528 m_minWidth=0;
529 m_minHeight=0;
530
531 switch(m_alignment) {
532
533 case Qt::AlignTop:
534 case Qt::AlignBottom: {
535 QPointF point = m_rect.topLeft();
536 m_width = 0;
537 foreach (QGraphicsItem *item, items) {
538 if (item->isVisible()) {
539 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
540 const QRectF& rect = item->boundingRect();
541 qreal w = rect.width();
542 m_minWidth=qMax(m_minWidth,w);
543 m_minHeight=qMax(m_minHeight,rect.height());
544 m_width+=w;
545 point.setX(point.x() + w);
546 }
547 }
548 if(m_width<m_rect.width()) {
549 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
550 }
551 else {
552 m_markers->setPos(m_rect.topLeft());
553 }
554 m_height=m_minHeight;
555 }
556 break;
557 case Qt::AlignLeft:
558 case Qt::AlignRight: {
559 QPointF point = m_rect.topLeft();
560 m_height = 0;
561 foreach (QGraphicsItem *item, items) {
562 if (item->isVisible()) {
563 item->setPos(point);
564 const QRectF& rect = item->boundingRect();
565 qreal h = rect.height();
566 m_minWidth=qMax(m_minWidth,rect.width());
567 m_minHeight=qMax(m_minHeight,h);
568 m_height+=h;
569 point.setY(point.y() + h);
570 }
571 }
572 if(m_height<m_rect.height()) {
573 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
574 }
575 else {
576 m_markers->setPos(m_rect.topLeft());
577 }
578 m_width=m_minWidth;
579 }
580 break;
581 }
582
583 m_minOffsetX = 0;
584 m_minOffsetY = 0;
585 m_maxOffsetX = m_width - m_rect.width();
586 m_maxOffsetY = m_height - m_rect.height();
587
588 m_presenter->updateLayout();
589 }
590
591 void QLegendPrivate::updateDetachedLayout()
592 {
593 // Detached layout is different.
594 // In detached mode legend may have multiple rows and columns, so layout calculations
595 // differ a log from attached mode.
596 // Also the scrolling logic is bit different.
597 m_offsetX=0;
598 m_offsetY=0;
599 QList<QGraphicsItem *> items = m_markers->childItems();
600
601 if(items.isEmpty()) return;
602
603 m_minWidth = 0;
604 m_minHeight = 0;
605
606 switch (m_alignment) {
607 case Qt::AlignTop: {
608 QPointF point = m_rect.topLeft();
609 m_width = 0;
610 m_height = 0;
611 for (int i=0; i<items.count(); i++) {
612 QGraphicsItem *item = items.at(i);
613 if (item->isVisible()) {
614 const QRectF& rect = item->boundingRect();
615 qreal w = rect.width();
616 qreal h = rect.height();
617 m_minWidth = qMax(m_minWidth,w);
618 m_minHeight = qMax(m_minHeight,rect.height());
619 m_height = qMax(m_height,h);
620 item->setPos(point.x(),point.y());
621 point.setX(point.x() + w);
622 if (point.x() + w > m_rect.topLeft().x() + m_rect.width()) {
623 // Next item would go off rect.
624 point.setX(m_rect.topLeft().x());
625 point.setY(point.y() + h);
626 if (i+1 < items.count()) {
627 m_height += h;
628 }
629 }
630 }
631 }
632 m_markers->setPos(m_rect.topLeft());
633 m_width = m_minWidth;
634
635 m_minOffsetX = 0;
636 m_minOffsetY = 0;
637 m_maxOffsetX = m_width - m_rect.width();
638 m_maxOffsetY = m_height - m_rect.height();
639 }
640 break;
641 case Qt::AlignBottom: {
642 QPointF point = m_rect.bottomLeft();
643 m_width = 0;
644 m_height = 0;
645 for (int i=0; i<items.count(); i++) {
646 QGraphicsItem *item = items.at(i);
647 if (item->isVisible()) {
648 const QRectF& rect = item->boundingRect();
649 qreal w = rect.width();
650 qreal h = rect.height();
651 m_minWidth = qMax(m_minWidth,w);
652 m_minHeight = qMax(m_minHeight,rect.height());
653 m_height = qMax(m_height,h);
654 item->setPos(point.x(),point.y() - h);
655 point.setX(point.x() + w);
656 if (point.x() + w > m_rect.bottomLeft().x() + m_rect.width()) {
657 // Next item would go off rect.
658 point.setX(m_rect.bottomLeft().x());
659 point.setY(point.y() - h);
660 if (i+1 < items.count()) {
661 m_height += h;
662 }
663 }
664 }
665 }
666 m_markers->setPos(m_rect.topLeft());
667 m_width = m_minWidth;
668
669 m_minOffsetX = 0;
670 m_minOffsetY = qMin(m_rect.topLeft().y(), m_rect.topLeft().y() - m_height + m_rect.height());
671 m_maxOffsetX = m_width - m_rect.width();
672 m_maxOffsetY = 0;
673 }
674 break;
675 case Qt::AlignLeft: {
676 QPointF point = m_rect.topLeft();
677 m_width = 0;
678 m_height = 0;
679 qreal maxWidth = 0;
680 for (int i=0; i<items.count(); i++) {
681 QGraphicsItem *item = items.at(i);
682 if (item->isVisible()) {
683 const QRectF& rect = item->boundingRect();
684 qreal w = rect.width();
685 qreal h = rect.height();
686 m_minWidth = qMax(m_minWidth,rect.width());
687 m_minHeight = qMax(m_minHeight,h);
688 maxWidth = qMax(maxWidth,w);
689 item->setPos(point.x(),point.y());
690 point.setY(point.y() + h);
691 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
692 // Next item would go off rect.
693 point.setX(point.x() + maxWidth);
694 point.setY(m_rect.topLeft().y());
695 if (i+1 < items.count()) {
696 m_width += maxWidth;
697 maxWidth = 0;
698 }
699 }
700 }
701 }
702 m_width += maxWidth;
703 m_markers->setPos(m_rect.topLeft());
704 m_height = m_minHeight;
705
706 m_minOffsetX = 0;
707 m_minOffsetY = 0;
708 m_maxOffsetX = m_width - m_rect.width();
709 m_maxOffsetY = m_height - m_rect.height();
710 }
711 break;
712 case Qt::AlignRight: {
713 QPointF point = m_rect.topRight();
714 m_width = 0;
715 m_height = 0;
716 qreal maxWidth = 0;
717 for (int i=0; i<items.count(); i++) {
718 QGraphicsItem *item = items.at(i);
719 if (item->isVisible()) {
720 const QRectF& rect = item->boundingRect();
721 qreal w = rect.width();
722 qreal h = rect.height();
723 m_minWidth = qMax(m_minWidth,rect.width());
724 m_minHeight = qMax(m_minHeight,h);
725 maxWidth = qMax(maxWidth,w);
726 item->setPos(point.x() - w,point.y());
727 point.setY(point.y() + h);
728 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
729 // Next item would go off rect.
730 point.setX(point.x() - maxWidth);
731 point.setY(m_rect.topLeft().y());
732 if (i+1 < items.count()) {
733 m_width += maxWidth;
734 maxWidth = 0;
735 }
736 }
737 }
738 }
739 m_width += maxWidth;
740 m_markers->setPos(m_rect.topLeft());
741 m_height = m_minHeight;
742
743 m_minOffsetX = qMin(m_rect.topLeft().x(), m_rect.topLeft().x() - m_width + m_rect.width());
744 m_minOffsetY = 0;
745 m_maxOffsetX = 0;
746 m_maxOffsetY = m_height - m_rect.height();
747 }
748 break;
749 default:
750 break;
751 }
752 }
753
754 void QLegendPrivate::attachToChart()
755 {
756 m_attachedToChart = true;
757 q_ptr->setParent(m_chart);
758 }
465 }
759
466
760 int QLegendPrivate::roundness(qreal size)
467 int QLegendPrivate::roundness(qreal size)
@@ -762,39 +469,17 int QLegendPrivate::roundness(qreal size)
762 return 100*m_diameter/int(size);
469 return 100*m_diameter/int(size);
763 }
470 }
764
471
765 void QLegendPrivate::setFont(const QFont &font)
766 {
767 m_font = font;
768 QList<QGraphicsItem *> items = m_markers->childItems();
769
770 foreach (QGraphicsItem *markers, items) {
771 LegendMarker *marker = static_cast<LegendMarker*>(markers);
772 marker->setFont(m_font);
773 }
774 updateLayout();
775 }
776
777 void QLegendPrivate::setLabelBrush(const QBrush &brush)
778 {
779 m_labelBrush = brush;
780 QList<QGraphicsItem *> items = m_markers->childItems();
781
782 foreach (QGraphicsItem *markers, items) {
783 LegendMarker *marker = static_cast<LegendMarker*>(markers);
784 marker->setLabelBrush(m_labelBrush);
785 }
786 updateLayout();
787 }
788
789 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
472 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
790 {
473 {
791 Q_UNUSED(domain)
474 Q_UNUSED(domain)
792
475
793 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
476 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
477
794 foreach(LegendMarker* marker, markers) {
478 foreach(LegendMarker* marker, markers) {
795 marker->setFont(m_font);
479 marker->setFont(m_font);
796 marker->setLabelBrush(m_labelBrush);
480 marker->setLabelBrush(m_labelBrush);
797 m_markers->addToGroup(marker);
481 m_items->addToGroup(marker);
482 m_markers<<marker;
798 }
483 }
799
484
800 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
485 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
@@ -805,17 +490,15 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
805 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
490 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
806 }
491 }
807
492
808 updateLayout();
493 q_ptr->layout()->invalidate();
809 }
494 }
810
495
811 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
496 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
812 {
497 {
813 QList<QGraphicsItem *> items = m_markers->childItems();
498 foreach (LegendMarker *marker, m_markers) {
814
815 foreach (QGraphicsItem *markers, items) {
816 LegendMarker *marker = static_cast<LegendMarker*>(markers);
817 if (marker->series() == series) {
499 if (marker->series() == series) {
818 delete marker;
500 delete marker;
501 m_markers.removeAll(marker);
819 }
502 }
820 }
503 }
821
504
@@ -826,7 +509,7 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
826 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
509 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
827 }
510 }
828
511
829 updateLayout();
512 q_ptr->layout()->invalidate();
830 }
513 }
831
514
832 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
515 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
@@ -850,19 +533,16 void QLegendPrivate::handleUpdatePieSeries()
850 void QLegendPrivate::handleSeriesVisibleChanged()
533 void QLegendPrivate::handleSeriesVisibleChanged()
851 {
534 {
852 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
535 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
853 QList<QGraphicsItem *> items = m_markers->childItems();
854
536
855 foreach (QGraphicsItem *markers, items) {
537 foreach (LegendMarker* marker, m_markers) {
856 LegendMarker *marker = static_cast<LegendMarker*>(markers);
857 if (marker->series() == series) {
538 if (marker->series() == series) {
858 marker->setVisible(!marker->isVisible());
539 marker->setVisible(!marker->isVisible());
859 }
540 }
860 }
541 }
861
542
862 updateLayout();
543 q_ptr->layout()->invalidate();
863 }
544 }
864
545
865
866 #include "moc_qlegend.cpp"
546 #include "moc_qlegend.cpp"
867 #include "moc_qlegend_p.cpp"
547 #include "moc_qlegend_p.cpp"
868
548
@@ -57,7 +57,6 public:
57 ~QLegend();
57 ~QLegend();
58
58
59 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
59 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
60 QRectF boundingRect() const;
61
60
62 void setBrush(const QBrush &brush);
61 void setBrush(const QBrush &brush);
63 QBrush brush() const;
62 QBrush brush() const;
@@ -84,14 +83,11 public:
84 void attachToChart();
83 void attachToChart();
85 bool isAttachedToChart();
84 bool isAttachedToChart();
86
85
87 qreal minWidth() const;
88 qreal minHeight() const;
89
90 void setBackgroundVisible(bool visible = true);
86 void setBackgroundVisible(bool visible = true);
91 bool isBackgroundVisible() const;
87 bool isBackgroundVisible() const;
92
88
89
93 protected:
90 protected:
94 void resizeEvent(QGraphicsSceneResizeEvent *event);
95 void hideEvent(QHideEvent *event);
91 void hideEvent(QHideEvent *event);
96 void showEvent(QShowEvent *event);
92 void showEvent(QShowEvent *event);
97
93
@@ -107,6 +103,8 private:
107 QScopedPointer<QLegendPrivate> d_ptr;
103 QScopedPointer<QLegendPrivate> d_ptr;
108 Q_DISABLE_COPY(QLegend)
104 Q_DISABLE_COPY(QLegend)
109 friend class LegendScroller;
105 friend class LegendScroller;
106 friend class LegendLayout;
107 friend class ChartLayout;
110 };
108 };
111
109
112 QTCOMMERCIALCHART_END_NAMESPACE
110 QTCOMMERCIALCHART_END_NAMESPACE
@@ -37,6 +37,7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 class QChart;
37 class QChart;
38 class ChartPresenter;
38 class ChartPresenter;
39 class QAbstractSeries;
39 class QAbstractSeries;
40 class LegendLayout;
40
41
41 class QLegendPrivate : public QObject
42 class QLegendPrivate : public QObject
42 {
43 {
@@ -47,12 +48,10 public:
47
48
48 void setOffset(qreal x, qreal y);
49 void setOffset(qreal x, qreal y);
49 QPointF offset() const;
50 QPointF offset() const;
50 void updateLayout();
51 void updateDetachedLayout();
52 void attachToChart();
53 int roundness(qreal size);
51 int roundness(qreal size);
54 void setFont(const QFont &font);
52
55 void setLabelBrush(const QBrush &brush);
53 QList<LegendMarker*> markers() { return m_markers; }
54 QGraphicsItemGroup* items() { return m_items; }
56
55
57 public Q_SLOTS:
56 public Q_SLOTS:
58 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
57 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
@@ -64,24 +63,16 public Q_SLOTS:
64 private:
63 private:
65 QLegend *q_ptr;
64 QLegend *q_ptr;
66 ChartPresenter *m_presenter;
65 ChartPresenter *m_presenter;
66 LegendLayout *m_layout;
67 QChart* m_chart;
67 QChart* m_chart;
68 QGraphicsItemGroup* m_markers;
68 QGraphicsItemGroup* m_items;
69 QList<LegendMarker*> m_markers;
69 Qt::Alignment m_alignment;
70 Qt::Alignment m_alignment;
70 QBrush m_brush;
71 QBrush m_brush;
71 QPen m_pen;
72 QPen m_pen;
72 QFont m_font;
73 QFont m_font;
73 QBrush m_labelBrush;
74 QBrush m_labelBrush;
74 QRectF m_rect;
75
75 qreal m_offsetX;
76 qreal m_offsetY;
77 qreal m_minOffsetX;
78 qreal m_minOffsetY;
79 qreal m_maxOffsetX;
80 qreal m_maxOffsetY;
81 qreal m_minWidth;
82 qreal m_minHeight;
83 qreal m_width;
84 qreal m_height;
85 qreal m_diameter;
76 qreal m_diameter;
86 bool m_attachedToChart;
77 bool m_attachedToChart;
87 bool m_backgroundVisible;
78 bool m_backgroundVisible;
@@ -26,6 +26,7
26 #include "qaxis.h"
26 #include "qaxis.h"
27 #include <QGraphicsScene>
27 #include <QGraphicsScene>
28 #include <QGraphicsSceneResizeEvent>
28 #include <QGraphicsSceneResizeEvent>
29 #include <QGraphicsLayout>
29
30
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
32
@@ -117,7 +118,8 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(
117 d_ptr->createConnections();
118 d_ptr->createConnections();
118 d_ptr->m_legend = new LegendScroller(this);
119 d_ptr->m_legend = new LegendScroller(this);
119 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
120 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
120 connect(d_ptr->m_presenter, SIGNAL(marginsChanged(QRectF)), this, SIGNAL(marginsChanged(QRectF)));
121 //connect(d_ptr->m_presenter, SIGNAL(marginsChanged(QRectF)), this, SIGNAL(marginsChanged(QRectF)));
122 setLayout(d_ptr->m_presenter->layout());
121 }
123 }
122
124
123 /*!
125 /*!
@@ -126,6 +128,7 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(
126 QChart::~QChart()
128 QChart::~QChart()
127 {
129 {
128 //delete first presenter , since this is a root of all the graphical items
130 //delete first presenter , since this is a root of all the graphical items
131 setLayout(0);
129 delete d_ptr->m_presenter;
132 delete d_ptr->m_presenter;
130 d_ptr->m_presenter=0;
133 d_ptr->m_presenter=0;
131 }
134 }
@@ -170,10 +173,7 void QChart::removeAllSeries()
170 */
173 */
171 void QChart::setBackgroundBrush(const QBrush& brush)
174 void QChart::setBackgroundBrush(const QBrush& brush)
172 {
175 {
173 //TODO: refactor me
176 d_ptr->m_presenter->setBackgroundBrush(brush);
174 d_ptr->m_presenter->createChartBackgroundItem();
175 d_ptr->m_presenter->m_backgroundItem->setBrush(brush);
176 d_ptr->m_presenter->m_backgroundItem->update();
177 }
177 }
178
178
179 /*!
179 /*!
@@ -181,9 +181,7 void QChart::setBackgroundBrush(const QBrush& brush)
181 */
181 */
182 QBrush QChart::backgroundBrush() const
182 QBrush QChart::backgroundBrush() const
183 {
183 {
184 //TODO: refactor me
184 return d_ptr->m_presenter->backgroundBrush();
185 if (!d_ptr->m_presenter->m_backgroundItem) return QBrush();
186 return (d_ptr->m_presenter->m_backgroundItem)->brush();
187 }
185 }
188
186
189 /*!
187 /*!
@@ -191,10 +189,7 QBrush QChart::backgroundBrush() const
191 */
189 */
192 void QChart::setBackgroundPen(const QPen& pen)
190 void QChart::setBackgroundPen(const QPen& pen)
193 {
191 {
194 //TODO: refactor me
192 d_ptr->m_presenter->setBackgroundPen(pen);
195 d_ptr->m_presenter->createChartBackgroundItem();
196 d_ptr->m_presenter->m_backgroundItem->setPen(pen);
197 d_ptr->m_presenter->m_backgroundItem->update();
198 }
193 }
199
194
200 /*!
195 /*!
@@ -202,9 +197,7 void QChart::setBackgroundPen(const QPen& pen)
202 */
197 */
203 QPen QChart::backgroundPen() const
198 QPen QChart::backgroundPen() const
204 {
199 {
205 //TODO: refactor me
200 return d_ptr->m_presenter->backgroundPen();
206 if (!d_ptr->m_presenter->m_backgroundItem) return QPen();
207 return d_ptr->m_presenter->m_backgroundItem->pen();
208 }
201 }
209
202
210 /*!
203 /*!
@@ -212,10 +205,7 QPen QChart::backgroundPen() const
212 */
205 */
213 void QChart::setTitle(const QString& title)
206 void QChart::setTitle(const QString& title)
214 {
207 {
215 //TODO: refactor me
208 d_ptr->m_presenter->setTitle(title);
216 d_ptr->m_presenter->createChartTitleItem();
217 d_ptr->m_presenter->m_titleItem->setText(title);
218 d_ptr->m_presenter->updateLayout();
219 }
209 }
220
210
221 /*!
211 /*!
@@ -223,11 +213,7 void QChart::setTitle(const QString& title)
223 */
213 */
224 QString QChart::title() const
214 QString QChart::title() const
225 {
215 {
226 //TODO: refactor me
216 return d_ptr->m_presenter->title();
227 if (d_ptr->m_presenter->m_titleItem)
228 return d_ptr->m_presenter->m_titleItem->text();
229 else
230 return QString();
231 }
217 }
232
218
233 /*!
219 /*!
@@ -235,10 +221,7 QString QChart::title() const
235 */
221 */
236 void QChart::setTitleFont(const QFont& font)
222 void QChart::setTitleFont(const QFont& font)
237 {
223 {
238 //TODO: refactor me
224 d_ptr->m_presenter->setTitleFont(font);
239 d_ptr->m_presenter->createChartTitleItem();
240 d_ptr->m_presenter->m_titleItem->setFont(font);
241 d_ptr->m_presenter->updateLayout();
242 }
225 }
243
226
244 /*!
227 /*!
@@ -246,10 +229,7 void QChart::setTitleFont(const QFont& font)
246 */
229 */
247 QFont QChart::titleFont() const
230 QFont QChart::titleFont() const
248 {
231 {
249 if (d_ptr->m_presenter->m_titleItem)
232 return d_ptr->m_presenter->titleFont();
250 return d_ptr->m_presenter->m_titleItem->font();
251 else
252 return QFont();
253 }
233 }
254
234
255 /*!
235 /*!
@@ -257,10 +237,7 QFont QChart::titleFont() const
257 */
237 */
258 void QChart::setTitleBrush(const QBrush &brush)
238 void QChart::setTitleBrush(const QBrush &brush)
259 {
239 {
260 //TODO: refactor me
240 d_ptr->m_presenter->setTitleBrush(brush);
261 d_ptr->m_presenter->createChartTitleItem();
262 d_ptr->m_presenter->m_titleItem->setBrush(brush);
263 d_ptr->m_presenter->updateLayout();
264 }
241 }
265
242
266 /*!
243 /*!
@@ -268,9 +245,7 void QChart::setTitleBrush(const QBrush &brush)
268 */
245 */
269 QBrush QChart::titleBrush() const
246 QBrush QChart::titleBrush() const
270 {
247 {
271 //TODO: refactor me
248 return d_ptr->m_presenter->titleBrush();
272 if (!d_ptr->m_presenter->m_titleItem) return QBrush();
273 return d_ptr->m_presenter->m_titleItem->brush();
274 }
249 }
275
250
276 void QChart::setTheme(QChart::ChartTheme theme)
251 void QChart::setTheme(QChart::ChartTheme theme)
@@ -364,16 +339,9 QRectF QChart::margins() const
364 return d_ptr->m_presenter->margins();
339 return d_ptr->m_presenter->margins();
365 }
340 }
366
341
367
368 /*!
342 /*!
369 Resizes and updates the chart area using the \a event data
343 Sets animation \a options for the chart
370 */
344 */
371 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
372 {
373 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
374 QGraphicsWidget::resizeEvent(event);
375 d_ptr->m_presenter->setGeometry(d_ptr->m_rect);
376 }
377
345
378 void QChart::setAnimationOptions(AnimationOptions options)
346 void QChart::setAnimationOptions(AnimationOptions options)
379 {
347 {
@@ -390,7 +358,7 QChart::AnimationOptions QChart::animationOptions() const
390 */
358 */
391 void QChart::scrollLeft()
359 void QChart::scrollLeft()
392 {
360 {
393 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
361 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
394 }
362 }
395
363
396 /*!
364 /*!
@@ -398,7 +366,7 void QChart::scrollLeft()
398 */
366 */
399 void QChart::scrollRight()
367 void QChart::scrollRight()
400 {
368 {
401 d_ptr->m_presenter->scroll(d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
369 d_ptr->m_presenter->scroll(d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
402 }
370 }
403
371
404 /*!
372 /*!
@@ -406,7 +374,7 void QChart::scrollRight()
406 */
374 */
407 void QChart::scrollUp()
375 void QChart::scrollUp()
408 {
376 {
409 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
377 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
410 }
378 }
411
379
412 /*!
380 /*!
@@ -414,7 +382,7 void QChart::scrollUp()
414 */
382 */
415 void QChart::scrollDown()
383 void QChart::scrollDown()
416 {
384 {
417 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
385 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1));
418 }
386 }
419
387
420 /*!
388 /*!
@@ -427,32 +395,22 void QChart::scroll(const QPointF &delta)
427
395
428 void QChart::setBackgroundVisible(bool visible)
396 void QChart::setBackgroundVisible(bool visible)
429 {
397 {
430 //TODO: refactor me
398 d_ptr->m_presenter->setBackgroundVisible(visible);
431 d_ptr->m_presenter->createChartBackgroundItem();
432 d_ptr->m_presenter->m_backgroundItem->setVisible(visible);
433 }
399 }
434
400
435 bool QChart::isBackgroundVisible() const
401 bool QChart::isBackgroundVisible() const
436 {
402 {
437 //TODO: refactor me
403 return d_ptr->m_presenter->isBackgroundVisible();
438 if (!d_ptr->m_presenter->m_backgroundItem)
439 return false;
440
441 return d_ptr->m_presenter->m_backgroundItem->isVisible();
442 }
404 }
443
405
444 void QChart::setDropShadowEnabled(bool enabled)
406 void QChart::setDropShadowEnabled(bool enabled)
445 {
407 {
446 d_ptr->m_presenter->createChartBackgroundItem();
408 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
447 d_ptr->m_presenter->m_backgroundItem->setDropShadowEnabled(enabled);
448 }
409 }
449
410
450 bool QChart::isDropShadowEnabled() const
411 bool QChart::isDropShadowEnabled() const
451 {
412 {
452 if (!d_ptr->m_presenter->m_backgroundItem)
413 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
453 return false;
454
455 return d_ptr->m_presenter->m_backgroundItem->isDropShadowEnabled();
456 }
414 }
457
415
458 /*!
416 /*!
@@ -465,6 +423,11 QList<QAbstractSeries*> QChart::series() const
465 return d_ptr->m_dataset->series();
423 return d_ptr->m_dataset->series();
466 }
424 }
467
425
426 void QChart::setMarginsMinimum(const QRectF& margins)
427 {
428 d_ptr->m_presenter->setMarginsMinimum(margins);
429 }
430
468 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
469
432
470 QChartPrivate::QChartPrivate():
433 QChartPrivate::QChartPrivate():
@@ -486,6 +449,7 void QChartPrivate::createConnections()
486 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),m_presenter,SLOT(handleSeriesRemoved(QAbstractSeries*)));
449 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),m_presenter,SLOT(handleSeriesRemoved(QAbstractSeries*)));
487 QObject::connect(m_dataset,SIGNAL(axisAdded(QAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QAxis*,Domain*)));
450 QObject::connect(m_dataset,SIGNAL(axisAdded(QAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QAxis*,Domain*)));
488 QObject::connect(m_dataset,SIGNAL(axisRemoved(QAxis*)),m_presenter,SLOT(handleAxisRemoved(QAxis*)));
451 QObject::connect(m_dataset,SIGNAL(axisRemoved(QAxis*)),m_presenter,SLOT(handleAxisRemoved(QAxis*)));
452 //QObject::connect(m_presenter, SIGNAL(marginsChanged(QRectF)), q_ptr, SIGNAL(marginsChanged(QRectF)));
489 }
453 }
490
454
491 #include "moc_qchart.cpp"
455 #include "moc_qchart.cpp"
@@ -111,15 +111,14 public:
111 QAxis* axisY(QAbstractSeries* series = 0) const;
111 QAxis* axisY(QAbstractSeries* series = 0) const;
112
112
113 QLegend* legend() const;
113 QLegend* legend() const;
114
115 void setMarginsMinimum(const QRectF& margins);
114 QRectF margins() const;
116 QRectF margins() const;
115
117
116 Q_SIGNALS:
118 Q_SIGNALS:
117 void marginsChanged(QRectF newMargins);
119 void marginsChanged(QRectF newMargins);
118
120
119 protected:
121 protected:
120 void resizeEvent(QGraphicsSceneResizeEvent *event);
121
122 protected:
123 QScopedPointer<QChartPrivate> d_ptr;
122 QScopedPointer<QChartPrivate> d_ptr;
124 friend class QLegend;
123 friend class QLegend;
125 friend class ChartPresenter;
124 friend class ChartPresenter;
@@ -42,7 +42,6 struct QChartPrivate
42 {
42 {
43 QChartPrivate();
43 QChartPrivate();
44 ~QChartPrivate();
44 ~QChartPrivate();
45 QRectF m_rect;
46 QLegend* m_legend;
45 QLegend* m_legend;
47 ChartDataSet *m_dataset;
46 ChartDataSet *m_dataset;
48 ChartPresenter *m_presenter;
47 ChartPresenter *m_presenter;
@@ -43,7 +43,8 SOURCES += \
43 $$PWD/qabstractseries.cpp \
43 $$PWD/qabstractseries.cpp \
44 $$PWD/chartbackground.cpp \
44 $$PWD/chartbackground.cpp \
45 $$PWD/chart.cpp \
45 $$PWD/chart.cpp \
46 $$PWD/scroller.cpp
46 $$PWD/scroller.cpp \
47 $$PWD/chartlayout.cpp
47 PRIVATE_HEADERS += \
48 PRIVATE_HEADERS += \
48 $$PWD/chartdataset_p.h \
49 $$PWD/chartdataset_p.h \
49 $$PWD/chartitem_p.h \
50 $$PWD/chartitem_p.h \
@@ -56,7 +57,8 PRIVATE_HEADERS += \
56 $$PWD/qchart_p.h \
57 $$PWD/qchart_p.h \
57 $$PWD/qchartview_p.h \
58 $$PWD/qchartview_p.h \
58 $$PWD/scroller_p.h \
59 $$PWD/scroller_p.h \
59 $$PWD/qabstractseries_p.h
60 $$PWD/qabstractseries_p.h \
61 $$PWD/chartlayout_p.h
60 PUBLIC_HEADERS += \
62 PUBLIC_HEADERS += \
61 $$PWD/qchart.h \
63 $$PWD/qchart.h \
62 $$PWD/qchartglobal.h \
64 $$PWD/qchartglobal.h \
General Comments 0
You need to be logged in to leave comments. Login now