##// END OF EJS Templates
Fix to BarSeries animation on BarSets restructured
Marek Rosa -
r1418:faa10209176d
parent child
Show More
@@ -1,115 +1,118
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartanimator_p.h"
21 #include "chartanimator_p.h"
22 #include "axisanimation_p.h"
22 #include "axisanimation_p.h"
23 #include "xyanimation_p.h"
23 #include "xyanimation_p.h"
24 #include "splineanimation_p.h"
24 #include "splineanimation_p.h"
25 #include "xychart_p.h"
25 #include "xychart_p.h"
26 #include "pieanimation_p.h"
26 #include "pieanimation_p.h"
27 #include "baranimation_p.h"
27 #include "baranimation_p.h"
28 #include "barchartitem_p.h"
28 #include "barchartitem_p.h"
29 #include "areachartitem_p.h"
29 #include "areachartitem_p.h"
30 #include "splinechartitem_p.h"
30 #include "splinechartitem_p.h"
31 #include "scatterchartitem_p.h"
31 #include "scatterchartitem_p.h"
32 #include "chartaxis_p.h"
32 #include "chartaxis_p.h"
33 #include <QTimer>
33 #include <QTimer>
34
34
35 Q_DECLARE_METATYPE(QVector<QPointF>)
35 Q_DECLARE_METATYPE(QVector<QPointF>)
36 Q_DECLARE_METATYPE(QVector<qreal>)
36 Q_DECLARE_METATYPE(QVector<qreal>)
37 Q_DECLARE_METATYPE(QVector<QRectF>)
37 Q_DECLARE_METATYPE(QVector<QRectF>)
38
38
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40
40
41 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
41 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
42 {
42 {
43 }
43 }
44
44
45 ChartAnimator::~ChartAnimator()
45 ChartAnimator::~ChartAnimator()
46 {
46 {
47 }
47 }
48 void ChartAnimator::addAnimation(PieChartItem *item)
48 void ChartAnimator::addAnimation(PieChartItem *item)
49 {
49 {
50 ChartAnimation *animation = m_animations.value(item);
50 ChartAnimation *animation = m_animations.value(item);
51
51
52 if (!animation) {
52 if (!animation) {
53 animation = new PieAnimation(item);
53 animation = new PieAnimation(item);
54 m_animations.insert(item, animation);
54 m_animations.insert(item, animation);
55 }
55 }
56
56
57 item->setAnimator(this);
57 item->setAnimator(this);
58 }
58 }
59
59
60 void ChartAnimator::addAnimation(BarChartItem *item)
60 void ChartAnimator::addAnimation(BarChartItem *item)
61 {
61 {
62 ChartAnimation *animation = m_animations.value(item);
62 ChartAnimation *animation = m_animations.value(item);
63
63
64 if (!animation) {
64 if (!animation) {
65 animation = new BarAnimation(item);
65 animation = new BarAnimation(item);
66 m_animations.insert(item, animation);
66 m_animations.insert(item, animation);
67 }
67 }
68
68
69 item->setAnimator(this);
69 item->setAnimator(this);
70 }
70 }
71
71
72
72
73 void ChartAnimator::removeAnimation(Chart *item)
73 void ChartAnimator::removeAnimation(Chart *item)
74 {
74 {
75 item->setAnimator(0);
75 item->setAnimator(0);
76 m_animations.remove(item);
76 m_animations.remove(item);
77 }
77 }
78
78
79 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
79 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
80 {
80 {
81 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
81 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
82 Q_ASSERT(animation);
82 Q_ASSERT(animation);
83 animation->addSlice(sliceItem, sliceData, startupAnimation);
83 animation->addSlice(sliceItem, sliceData, startupAnimation);
84 }
84 }
85
85
86 void ChartAnimator::removeAnimation(PieChartItem *item, PieSliceItem *sliceItem)
86 void ChartAnimator::removeAnimation(PieChartItem *item, PieSliceItem *sliceItem)
87 {
87 {
88 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
88 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
89 Q_ASSERT(animation);
89 Q_ASSERT(animation);
90 animation->removeSlice(sliceItem);
90 animation->removeSlice(sliceItem);
91 }
91 }
92
92
93 void ChartAnimator::updateAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData)
93 void ChartAnimator::updateAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData)
94 {
94 {
95 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
95 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
96 Q_ASSERT(animation);
96 Q_ASSERT(animation);
97 animation->updateValue(sliceItem, sliceData);
97 animation->updateValue(sliceItem, sliceData);
98 }
98 }
99
99
100 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
100 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
101 {
101 {
102 BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item));
102 BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item));
103 Q_ASSERT(animation);
103 m_animations.remove(item);
104 animation->stop();
104 if (animation) {
105 animation->deleteLater();
106 animation = 0;
107 }
108 addAnimation(item);
109 animation = static_cast<BarAnimation *>(m_animations.value(item));
105 animation->setDuration(ChartAnimationDuration);
110 animation->setDuration(ChartAnimationDuration);
106 animation->setStartValue(qVariantFromValue(oldLayout));
107 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
111 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
108 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
112 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
109 animation->setEndValue(qVariantFromValue(newLayout));
110 QTimer::singleShot(0, animation, SLOT(start()));
113 QTimer::singleShot(0, animation, SLOT(start()));
111 }
114 }
112
115
113 #include "moc_chartanimator_p.cpp"
116 #include "moc_chartanimator_p.cpp"
114
117
115 QTCOMMERCIALCHART_END_NAMESPACE
118 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,212 +1,215
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "barchartitem_p.h"
21 #include "barchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "qbarseries.h"
25 #include "qbarseries.h"
26 #include "qbarseries_p.h"
26 #include "qbarseries_p.h"
27 #include "qchart.h"
27 #include "qchart.h"
28 #include "chartpresenter_p.h"
28 #include "chartpresenter_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30 #include "chartdataset_p.h"
30 #include "chartdataset_p.h"
31 #include <QPainter>
31 #include <QPainter>
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
35 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
36 ChartItem(presenter),
36 ChartItem(presenter),
37 m_series(series)
37 m_series(series)
38 {
38 {
39 setFlag(ItemClipsChildrenToShape);
39 setFlag(ItemClipsChildrenToShape);
40 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
40 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
41 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
41 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
42 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
42 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleLayoutChanged()));
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleLayoutChanged()));
44 setZValue(ChartPresenter::BarSeriesZValue);
44 setZValue(ChartPresenter::BarSeriesZValue);
45 handleDataStructureChanged();
45 handleDataStructureChanged();
46 }
46 }
47
47
48 BarChartItem::~BarChartItem()
48 BarChartItem::~BarChartItem()
49 {
49 {
50 }
50 }
51
51
52 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
52 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
53 {
53 {
54 Q_UNUSED(painter);
54 Q_UNUSED(painter);
55 Q_UNUSED(option);
55 Q_UNUSED(option);
56 Q_UNUSED(widget);
56 Q_UNUSED(widget);
57 }
57 }
58
58
59 QRectF BarChartItem::boundingRect() const
59 QRectF BarChartItem::boundingRect() const
60 {
60 {
61 return m_rect;
61 return m_rect;
62 }
62 }
63
63
64 void BarChartItem::handleDataStructureChanged()
64 void BarChartItem::handleDataStructureChanged()
65 {
65 {
66 foreach(QGraphicsItem *item, childItems()) {
66 foreach(QGraphicsItem *item, childItems()) {
67 delete item;
67 delete item;
68 }
68 }
69
69
70 m_bars.clear();
70 m_bars.clear();
71 m_labels.clear();
71 m_labels.clear();
72 m_layout.clear();
72 m_layout.clear();
73
73
74 bool labelsVisible = m_series->isLabelsVisible();
74 bool labelsVisible = m_series->isLabelsVisible();
75
75
76 // Create new graphic items for bars
76 // Create new graphic items for bars
77 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
77 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
78 for (int s = 0; s < m_series->barsetCount(); s++) {
78 for (int s = 0; s < m_series->barsetCount(); s++) {
79 QBarSet *set = m_series->d_func()->barsetAt(s);
79 QBarSet *set = m_series->d_func()->barsetAt(s);
80
80
81 // Bars
81 // Bars
82 Bar *bar = new Bar(set,c,this);
82 Bar *bar = new Bar(set,c,this);
83 m_bars.append(bar);
83 m_bars.append(bar);
84 connect(bar, SIGNAL(clicked(QBarSet*,int)), m_series, SIGNAL(clicked(QBarSet*,int)));
84 connect(bar, SIGNAL(clicked(QBarSet*,int)), m_series, SIGNAL(clicked(QBarSet*,int)));
85 connect(bar, SIGNAL(hovered(QBarSet*,bool)), m_series, SIGNAL(hovered(QBarSet*,bool)));
85 connect(bar, SIGNAL(hovered(QBarSet*,bool)), m_series, SIGNAL(hovered(QBarSet*,bool)));
86 m_layout.append(QRectF(0, 0, 0, 0));
86 m_layout.append(QRectF(0, 0, 0, 0));
87
87
88 // Labels
88 // Labels
89 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this);
89 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this);
90 label->setVisible(labelsVisible);
90 label->setVisible(labelsVisible);
91 m_labels.append(label);
91 m_labels.append(label);
92 }
92 }
93 }
93 }
94
94
95 // TODO: Is this the right place to call it?
95 // TODO: Is this the right place to call it?
96 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
96 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
97 handleLayoutChanged();
97 handleLayoutChanged();
98 }
98 }
99
99
100 QVector<QRectF> BarChartItem::calculateLayout()
100 QVector<QRectF> BarChartItem::calculateLayout()
101 {
101 {
102 QVector<QRectF> layout;
102 QVector<QRectF> layout;
103
103
104 // Use temporary qreals for accuracy
104 // Use temporary qreals for accuracy
105 qreal categoryCount = m_series->d_func()->categoryCount();
105 qreal categoryCount = m_series->d_func()->categoryCount();
106 qreal setCount = m_series->barsetCount();
106 qreal setCount = m_series->barsetCount();
107 bool barsVisible = m_series->isVisible();
107 bool barsVisible = m_series->isVisible();
108
108
109 // Domain:
109 // Domain:
110 qreal width = geometry().width();
110 qreal width = geometry().width();
111 qreal height = geometry().height();
111 qreal height = geometry().height();
112 qreal rangeY = m_domainMaxY - m_domainMinY;
112 qreal rangeY = m_domainMaxY - m_domainMinY;
113 qreal rangeX = m_domainMaxX - m_domainMinX;
113 qreal rangeX = m_domainMaxX - m_domainMinX;
114 qreal scaleY = (height / rangeY);
114 qreal scaleY = (height / rangeY);
115 qreal scaleX = (width / rangeX);
115 qreal scaleX = (width / rangeX);
116 qreal barWidth = scaleX - scaleX * m_series->d_func()->barMargin();
116 qreal barWidth = scaleX - scaleX * m_series->d_func()->barMargin();
117
117
118 int itemIndex(0);
118 int itemIndex(0);
119 for (int category = 0; category < categoryCount; category++) {
119 for (int category = 0; category < categoryCount; category++) {
120 qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y();
120 qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y();
121 for (int set = 0; set < setCount; set++) {
121 for (int set = 0; set < setCount; set++) {
122 QBarSet* barSet = m_series->d_func()->barsetAt(set);
122 QBarSet* barSet = m_series->d_func()->barsetAt(set);
123 qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
123 qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
124 qreal barHeight = barSet->at(category).y() * scaleY;
124 qreal barHeight = barSet->at(category).y() * scaleY;
125
125
126 Bar* bar = m_bars.at(itemIndex);
126 Bar* bar = m_bars.at(itemIndex);
127 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
127 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
128
128
129 layout.append(rect);
129 layout.append(rect);
130 bar->setPen(barSet->pen());
130 bar->setPen(barSet->pen());
131 bar->setBrush(barSet->brush());
131 bar->setBrush(barSet->brush());
132 bar->setVisible(barsVisible);
132 bar->setVisible(barsVisible);
133
133
134 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
134 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
135
135
136 if (!qFuzzyIsNull(barSet->at(category).y())) {
136 if (!qFuzzyIsNull(barSet->at(category).y())) {
137 label->setText(QString::number(barSet->at(category).y()));
137 label->setText(QString::number(barSet->at(category).y()));
138 } else {
138 } else {
139 label->setText(QString(""));
139 label->setText(QString(""));
140 }
140 }
141
141
142 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
142 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
143 ,yPos - barHeight/2 - label->boundingRect().height()/2);
143 ,yPos - barHeight/2 - label->boundingRect().height()/2);
144 label->setFont(barSet->labelFont());
144 label->setFont(barSet->labelFont());
145 label->setBrush(barSet->labelBrush());
145 label->setBrush(barSet->labelBrush());
146
146
147 itemIndex++;
147 itemIndex++;
148 }
148 }
149 }
149 }
150
150
151 return layout;
151 return layout;
152 }
152 }
153
153
154 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
154 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
155 {
155 {
156 if (animator()) {
156 if (animator()) {
157 animator()->updateLayout(this, m_layout, layout);
157 animator()->updateLayout(this, m_layout, layout);
158 } else {
158 } else {
159 setLayout(layout);
159 setLayout(layout);
160 update();
160 update();
161 }
161 }
162 }
162 }
163
163
164 void BarChartItem::setLayout(const QVector<QRectF> &layout)
164 void BarChartItem::setLayout(const QVector<QRectF> &layout)
165 {
165 {
166 if (layout.count() != m_bars.count())
167 return;
168
166 m_layout = layout;
169 m_layout = layout;
167
170
168 for (int i=0; i < m_bars.count(); i++) {
171 for (int i=0; i < m_bars.count(); i++) {
169 m_bars.at(i)->setRect(layout.at(i));
172 m_bars.at(i)->setRect(layout.at(i));
170 }
173 }
171
174
172 update();
175 update();
173 }
176 }
174 //handlers
177 //handlers
175
178
176 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
179 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
177 {
180 {
178 m_domainMinX = minX;
181 m_domainMinX = minX;
179 m_domainMaxX = maxX;
182 m_domainMaxX = maxX;
180 m_domainMinY = minY;
183 m_domainMinY = minY;
181 m_domainMaxY = maxY;
184 m_domainMaxY = maxY;
182 handleLayoutChanged();
185 handleLayoutChanged();
183 }
186 }
184
187
185 void BarChartItem::handleGeometryChanged(const QRectF &rect)
188 void BarChartItem::handleGeometryChanged(const QRectF &rect)
186 {
189 {
187 prepareGeometryChange();
190 prepareGeometryChange();
188 m_rect = rect;
191 m_rect = rect;
189 handleLayoutChanged();
192 handleLayoutChanged();
190 }
193 }
191
194
192 void BarChartItem::handleLayoutChanged()
195 void BarChartItem::handleLayoutChanged()
193 {
196 {
194 if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) {
197 if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) {
195 // rect size zero.
198 // rect size zero.
196 return;
199 return;
197 }
200 }
198 QVector<QRectF> layout = calculateLayout();
201 QVector<QRectF> layout = calculateLayout();
199 applyLayout(layout);
202 applyLayout(layout);
200 }
203 }
201
204
202 void BarChartItem::handleLabelsVisibleChanged(bool visible)
205 void BarChartItem::handleLabelsVisibleChanged(bool visible)
203 {
206 {
204 foreach (QGraphicsSimpleTextItem* label, m_labels) {
207 foreach (QGraphicsSimpleTextItem* label, m_labels) {
205 label->setVisible(visible);
208 label->setVisible(visible);
206 }
209 }
207 update();
210 update();
208 }
211 }
209
212
210 #include "moc_barchartitem_p.cpp"
213 #include "moc_barchartitem_p.cpp"
211
214
212 QTCOMMERCIALCHART_END_NAMESPACE
215 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now