##// END OF EJS Templates
Refactors axis animation, line animations
Michal Klocek -
r1241:51695bb27b0e
parent child
Show More
@@ -0,0 +1,112
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "chartaxisx_p.h"
22 #include "qaxis.h"
23 #include "qaxis_p.h"
24 #include "qaxiscategories_p.h"
25 #include "chartpresenter_p.h"
26 #include "chartanimator_p.h"
27
28 static int label_padding = 5;
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
32 ChartAxisX::ChartAxisX(QAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
33 {
34 }
35
36 ChartAxisX::~ChartAxisX()
37 {
38 }
39
40 QVector<qreal> ChartAxisX::calculateLayout() const
41 {
42 Q_ASSERT(m_ticksCount>=2);
43
44 QVector<qreal> points;
45 points.resize(m_ticksCount);
46
47 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
48 for (int i = 0; i < m_ticksCount; ++i) {
49 int x = i * deltaX + m_rect.left();
50 points[i] = x;
51 }
52 return points;
53 }
54
55 void ChartAxisX::updateGeometry()
56 {
57 const QVector<qreal>& layout = ChartAxis::layout();
58
59 QStringList ticksList;
60
61 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
62
63 QList<QGraphicsItem *> lines = m_grid->childItems();
64 QList<QGraphicsItem *> labels = m_labels->childItems();
65 QList<QGraphicsItem *> shades = m_shades->childItems();
66 QList<QGraphicsItem *> axis = m_axis->childItems();
67
68 Q_ASSERT(labels.size() == ticksList.size());
69 Q_ASSERT(layout.size() == ticksList.size());
70
71 qreal minWidth = 0;
72 qreal minHeight = 0;
73
74 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
75 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
76
77 for (int i = 0; i < layout.size(); ++i) {
78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
79 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
80 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
81 if (!categories || i<1) {
82 labelItem->setText(ticksList.at(i));
83 const QRectF& rect = labelItem->boundingRect();
84 minWidth+=rect.width();
85 minHeight=qMax(rect.height(),minHeight);
86 QPointF center = rect.center();
87 labelItem->setTransformOriginPoint(center.x(), center.y());
88 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
89 }
90 else {
91 labelItem->setText(ticksList.at(i));
92 const QRectF& rect = labelItem->boundingRect();
93 minWidth+=rect.width();
94 minHeight=qMax(rect.height()+label_padding,minHeight);
95 QPointF center = rect.center();
96 labelItem->setTransformOriginPoint(center.x(), center.y());
97 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
98 }
99
100 if ((i+1)%2 && i>1) {
101 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
102 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
103 }
104 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
105 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
106 }
107
108 presenter()->setMinimumMarginWidth(this,minWidth);
109 presenter()->setMinimumMarginHeight(this,minHeight);
110 }
111
112 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,46
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #ifndef CHARTAXISX_H
22 #define CHARTAXISX_H
23
24 #include "chartaxis_p.h"
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28 class QAxis;
29 class ChartPresenter;
30
31 class ChartAxisX : public ChartAxis
32 {
33 public:
34 ChartAxisX(QAxis *axis, ChartPresenter *presenter);
35 ~ChartAxisX();
36
37 AxisType axisType() const { return X_AXIS;}
38
39 protected:
40 QVector<qreal> calculateLayout() const;
41 void updateGeometry();
42 };
43
44 QTCOMMERCIALCHART_END_NAMESPACE
45
46 #endif /* AXISITEM_H_ */
@@ -0,0 +1,116
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "chartaxisy_p.h"
22 #include "qaxis.h"
23 #include "qaxis_p.h"
24 #include "qaxiscategories_p.h"
25 #include "chartpresenter_p.h"
26 #include "chartanimator_p.h"
27
28
29 static int label_padding = 5;
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
33 ChartAxisY::ChartAxisY(QAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
34 {
35 }
36
37 ChartAxisY::~ChartAxisY()
38 {
39 }
40
41 QVector<qreal> ChartAxisY::calculateLayout() const
42 {
43 Q_ASSERT(m_ticksCount>=2);
44
45 QVector<qreal> points;
46 points.resize(m_ticksCount);
47
48 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
49 for (int i = 0; i < m_ticksCount; ++i) {
50 int y = i * -deltaY + m_rect.bottom();
51 points[i] = y;
52 }
53
54 return points;
55 }
56
57 void ChartAxisY::updateGeometry()
58 {
59 const QVector<qreal> &layout = ChartAxis::layout();
60
61 QStringList ticksList;
62
63 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
64
65 QList<QGraphicsItem *> lines = m_grid->childItems();
66 QList<QGraphicsItem *> labels = m_labels->childItems();
67 QList<QGraphicsItem *> shades = m_shades->childItems();
68 QList<QGraphicsItem *> axis = m_axis->childItems();
69
70 Q_ASSERT(labels.size() == ticksList.size());
71 Q_ASSERT(layout.size() == ticksList.size());
72
73 qreal minWidth = 0;
74 qreal minHeight = 0;
75
76 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
77 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
78
79 for (int i = 0; i < layout.size(); ++i) {
80 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
81 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
82 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
83
84 if (!categories || i<1) {
85 labelItem->setText(ticksList.at(i));
86 const QRectF& rect = labelItem->boundingRect();
87 minWidth=qMax(rect.width()+label_padding,minWidth);
88 minHeight+=rect.height();
89 QPointF center = rect.center();
90 labelItem->setTransformOriginPoint(center.x(), center.y());
91 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
92 }
93 else {
94 labelItem->setText(ticksList.at(i));
95 const QRectF& rect = labelItem->boundingRect();
96 minWidth=qMax(rect.width(),minWidth);
97 minHeight+=rect.height();
98 QPointF center = rect.center();
99 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());
101 }
102
103 if ((i+1)%2 && i>1) {
104 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
105 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
106 }
107 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
108 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
109 }
110
111 presenter()->setMinimumMarginWidth(this,minWidth);
112 presenter()->setMinimumMarginHeight(this,minHeight);
113
114 }
115
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,46
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #ifndef CHARTAXISY_H
22 #define CHARTAXISY_H
23
24 #include "chartaxis_p.h"
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28 class QAxis;
29 class ChartPresenter;
30
31 class ChartAxisY : public ChartAxis
32 {
33 public:
34 ChartAxisY(QAxis *axis, ChartPresenter *presenter);
35 ~ChartAxisY();
36
37 AxisType axisType() const { return Y_AXIS;}
38
39 protected:
40 QVector<qreal> calculateLayout() const;
41 void updateGeometry();
42 };
43
44 QTCOMMERCIALCHART_END_NAMESPACE
45
46 #endif /* AXISITEM_H_ */
@@ -19,7 +19,9
19 19 ****************************************************************************/
20 20
21 21 #include "axisanimation_p.h"
22 #include "chartaxis_p.h"
22 23 #include <QTimer>
24 #include <QDebug>
23 25
24 26 Q_DECLARE_METATYPE(QVector<qreal>)
25 27
@@ -27,14 +29,84 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 29
28 30
29 31 AxisAnimation::AxisAnimation(ChartAxis *axis): ChartAnimation(axis),
30 m_axis(axis)
32 m_axis(axis),
33 m_type(DefaultAnimation)
31 34 {
35 setDuration(ChartAnimationDuration);
36 setEasingCurve(QEasingCurve::OutQuart);
32 37 }
33 38
34 39 AxisAnimation::~AxisAnimation()
35 40 {
36 41 }
37 42
43 void AxisAnimation::setAnimationType(Animation type)
44 {
45 if (state() != QAbstractAnimation::Stopped) stop();
46 m_type=type;
47 }
48
49 void AxisAnimation::setAnimationPoint(const QPointF& point)
50 {
51 if (state() != QAbstractAnimation::Stopped) stop();
52 m_point=point;
53 }
54
55 void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayout)
56 {
57 if (state() != QAbstractAnimation::Stopped) stop();
58
59 if (newLayout.count() == 0)
60 return;
61
62 switch (m_type) {
63 case ZoomOutAnimation: {
64 QRectF rect = m_axis->geometry();
65 oldLayout.resize(newLayout.count());
66
67 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
68 oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.bottom();
69 oldLayout[j] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.right() : rect.top();
70 }
71 }
72 break;
73 case ZoomInAnimation: {
74 int index = qMin(oldLayout.count() * (m_axis->axisType() == ChartAxis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
75 oldLayout.resize(newLayout.count());
76
77 for(int i = 0; i < oldLayout.count(); i++)
78 oldLayout[i]= oldLayout[index];
79 }
80 break;
81 case MoveForwardAnimation: {
82 oldLayout.resize(newLayout.count());
83
84 for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
85 oldLayout[i]= oldLayout[j];
86 }
87 break;
88 case MoveBackwordAnimation: {
89 oldLayout.resize(newLayout.count());
90
91 for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
92 oldLayout[i]= oldLayout[j];
93 }
94 break;
95 default: {
96 oldLayout.resize(newLayout.count());
97 QRectF rect = m_axis->geometry();
98 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
99 oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
100 }
101 break;
102 }
103
104 QVariantAnimation::KeyValues value;
105 setKeyValues(value); //workaround for wrong interpolation call
106 setKeyValueAt(0.0, qVariantFromValue(oldLayout));
107 setKeyValueAt(1.0, qVariantFromValue(newLayout));
108 }
109
38 110 QVariant AxisAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
39 111 {
40 112 QVector<qreal> startVector = qVariantValue<QVector<qreal> >(start);
@@ -58,6 +130,7 void AxisAnimation::updateCurrentValue (const QVariant &value )
58 130 QVector<qreal> vector = qVariantValue<QVector<qreal> >(value);
59 131 Q_ASSERT(vector.count() != 0);
60 132 m_axis->setLayout(vector);
133 m_axis->updateGeometry();
61 134 }
62 135
63 136 }
@@ -21,22 +21,29
21 21 #ifndef AXISANIMATION_H
22 22 #define AXISANIMATION_H
23 23
24 #include "chartaxis_p.h"
25 24 #include "chartanimation_p.h"
26
25 #include <QPointF>
27 26
28 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 28
29 class ChartAxis;
30
30 31 class AxisAnimation: public ChartAnimation
31 32 {
32 33 public:
34 enum Animation { DefaultAnimation, ZoomOutAnimation, ZoomInAnimation, MoveForwardAnimation, MoveBackwordAnimation};
33 35 AxisAnimation(ChartAxis *axis);
34 36 ~AxisAnimation();
37 void setAnimationType(Animation type);
38 void setAnimationPoint(const QPointF& point);
39 void setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayout);
35 40 protected:
36 41 QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress ) const;
37 42 void updateCurrentValue(const QVariant &value );
38 43 private:
39 44 ChartAxis *m_axis;
45 Animation m_type;
46 QPointF m_point;
40 47 };
41 48
42 49 QTCOMMERCIALCHART_END_NAMESPACE
@@ -30,6 +30,7 const static int ChartAnimationDuration = 1000;
30 30
31 31 class ChartAnimation: public QVariantAnimation
32 32 {
33 Q_OBJECT
33 34 public:
34 35 ChartAnimation(QObject *parent = 0):QVariantAnimation(parent){};
35 36 };
@@ -29,6 +29,7
29 29 #include "areachartitem_p.h"
30 30 #include "splinechartitem_p.h"
31 31 #include "scatterchartitem_p.h"
32 #include "chartaxis_p.h"
32 33 #include <QTimer>
33 34
34 35 Q_DECLARE_METATYPE(QVector<QPointF>)
@@ -37,27 +38,13 Q_DECLARE_METATYPE(QVector<QRectF>)
37 38
38 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 40
40 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent),
41 m_state(ShowState)
41 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
42 42 {
43 43 }
44 44
45 45 ChartAnimator::~ChartAnimator()
46 46 {
47 47 }
48
49 void ChartAnimator::addAnimation(ChartAxis *item)
50 {
51 ChartAnimation *animation = m_animations.value(item);
52
53 if (!animation) {
54 animation = new AxisAnimation(item);
55 m_animations.insert(item, animation);
56 }
57
58 item->setAnimator(this);
59 }
60
61 48 void ChartAnimator::addAnimation(PieChartItem *item)
62 49 {
63 50 ChartAnimation *animation = m_animations.value(item);
@@ -89,75 +76,6 void ChartAnimator::removeAnimation(Chart *item)
89 76 m_animations.remove(item);
90 77 }
91 78
92 void ChartAnimator::updateLayout(ChartAxis *item , QVector<qreal> &newLayout)
93 {
94 AxisAnimation *animation = static_cast<AxisAnimation*>(m_animations.value(item));
95
96 Q_ASSERT(animation);
97
98 QVector<qreal> oldLayout = item->layout();
99
100 if (newLayout.count() == 0)
101 return;
102
103 switch (m_state) {
104 case ZoomOutState: {
105 QRectF rect = item->geometry();
106 oldLayout.resize(newLayout.count());
107
108 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
109 oldLayout[i] = item->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.bottom();
110 oldLayout[j] = item->axisType() == ChartAxis::X_AXIS ? rect.right() : rect.top();
111 }
112 }
113 break;
114 case ZoomInState: {
115 int index = qMin(oldLayout.count() * (item->axisType() == ChartAxis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
116 oldLayout.resize(newLayout.count());
117
118 for(int i = 0; i < oldLayout.count(); i++)
119 oldLayout[i]= oldLayout[index];
120 }
121 break;
122 case ScrollDownState:
123 case ScrollRightState: {
124 oldLayout.resize(newLayout.count());
125
126 for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
127 oldLayout[i]= oldLayout[j];
128 }
129 break;
130 case ScrollUpState:
131 case ScrollLeftState: {
132 oldLayout.resize(newLayout.count());
133
134 for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
135 oldLayout[i]= oldLayout[j];
136 }
137 break;
138 default: {
139 oldLayout.resize(newLayout.count());
140 QRectF rect = item->geometry();
141 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
142 oldLayout[i] = item->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
143 }
144 break;
145 }
146
147
148 if (animation->state() != QAbstractAnimation::Stopped)
149 animation->stop();
150
151 animation->setDuration(ChartAnimationDuration);
152 animation->setEasingCurve(QEasingCurve::OutQuart);
153 QVariantAnimation::KeyValues value;
154 animation->setKeyValues(value); //workaround for wrong interpolation call
155 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
156 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
157
158 QTimer::singleShot(0, animation, SLOT(start()));
159 }
160
161 79 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
162 80 {
163 81 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
@@ -189,22 +107,6 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldL
189 107 QTimer::singleShot(0, animation, SLOT(start()));
190 108 }
191 109
192
193 void ChartAnimator::setState(State state, const QPointF &point)
194 {
195 m_state = state;
196 m_point = point;
197 }
198
199 void ChartAnimator::startAnimation(XYAnimation* animation)
200 {
201 Q_ASSERT(animation);
202 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
203 animation->setDuration(ChartAnimationDuration);
204 animation->setEasingCurve(QEasingCurve::OutQuart);
205 QTimer::singleShot(0, animation, SLOT(start()));
206 }
207
208 110 #include "moc_chartanimator_p.cpp"
209 111
210 112 QTCOMMERCIALCHART_END_NAMESPACE
@@ -42,33 +42,21 class ChartAnimator : public QObject
42 42 {
43 43 Q_OBJECT
44 44 public:
45 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState, ScrollRightState, ZoomInState, ZoomOutState};
46
47 45 ChartAnimator(QObject *parent = 0);
48 46 virtual ~ChartAnimator();
49 47
50 void addAnimation(ChartAxis *item);
51 48 void addAnimation(PieChartItem *item);
52 49 void addAnimation(BarChartItem *item);
53 50 void removeAnimation(Chart *item);
54 51
55 void animationStarted();
56 void updateLayout(ChartAxis *item, QVector<qreal> &layout);
57
58 52 void addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty);
59 53 void removeAnimation(PieChartItem *item, PieSliceItem *sliceItem);
60 54 void updateAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData);
61 55
62 56 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
63 57
64 void setState(State state,const QPointF &point = QPointF());
65
66 void startAnimation(XYAnimation* animation);
67
68 58 private:
69 59 QMap<Chart *, ChartAnimation *> m_animations;
70 State m_state;
71 QPointF m_point;
72 60 };
73 61
74 62 QTCOMMERCIALCHART_END_NAMESPACE
@@ -94,7 +94,10 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
94 94
95 95 switch (animationType()) {
96 96
97 case MoveDownAnimation: {
97 case RemovePointAnimation:
98 case AddPointAnimation:
99 case ReplacePointAnimation:
100 {
98 101 if (startPair.first.count() != endPair.first.count())
99 102 break;
100 103 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
@@ -115,7 +118,7 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
115 118
116 119 }
117 120 break;
118 case LineDrawAnimation:{
121 case NewAnimation:{
119 122 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
120 123 int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
121 124 for(int i = 0; i < count; i++) {
@@ -29,8 +29,10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29 XYAnimation::XYAnimation(XYChart *item):ChartAnimation(item),
30 30 m_item(item),
31 31 m_dirty(false),
32 m_type(MoveDownAnimation)
32 m_type(NewAnimation)
33 33 {
34 setDuration(ChartAnimationDuration);
35 setEasingCurve(QEasingCurve::OutQuart);
34 36 }
35 37
36 38 XYAnimation::~XYAnimation()
@@ -43,34 +45,44 void XYAnimation::setAnimationType(Animation type)
43 45 m_type=type;
44 46 }
45 47
46 void XYAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
48 void XYAnimation::setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index)
47 49 {
48 50 if (state() != QAbstractAnimation::Stopped) stop();
49 51
50 int x = oldPoints.count();
51 int y = newPoints.count();
52
53 if (x != y && abs(x - y) != 1) {
54 m_oldPoints = newPoints;
55 oldPoints.resize(newPoints.size());
56 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
57 setKeyValueAt(1.0, qVariantFromValue(newPoints));
52 if (m_item->isDirty()) {
53 m_oldPoints = oldPoints;
54 m_newPoints = newPoints;
58 55 m_dirty = false;
59 56 }
60 57 else {
61 58 if (m_dirty) {
59 m_newPoints = newPoints;
62 60 m_oldPoints = oldPoints;
63 61 m_dirty = false;
64 62 }
65 oldPoints = newPoints;
66 if (y < x)
67 m_oldPoints.remove(index); //remove
68 if (y > x)
63 }
64
65 int x = m_oldPoints.count();
66 int y = m_newPoints.count();
67
68 if (abs(x - y) == 1) {
69 if (y < x){
70 if(!newPoints.isEmpty()) m_newPoints.insert(index,newPoints[index]);
71 m_index=index;if(newPoints.isEmpty())
72 m_dirty=true;
73 }
74 if (y > x){
69 75 m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]); //add
70 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
71 setKeyValueAt(1.0, qVariantFromValue(newPoints));
72 Q_ASSERT(m_oldPoints.count() == newPoints.count());
73 76 }
77 }else{
78 m_newPoints=newPoints;
79 m_dirty=false;
80 m_oldPoints.resize(m_newPoints.size());
81 }
82
83 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
84 setKeyValueAt(1.0, qVariantFromValue(m_newPoints));
85
74 86 }
75 87
76 88 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
@@ -81,8 +93,10 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
81 93
82 94 switch (m_type) {
83 95
84 case MoveDownAnimation: {
85
96 case ReplacePointAnimation:
97 case AddPointAnimation:
98 case RemovePointAnimation:
99 {
86 100 if (startVector.count() != endVector.count())
87 101 break;
88 102
@@ -94,7 +108,7 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
94 108
95 109 }
96 110 break;
97 case LineDrawAnimation: {
111 case NewAnimation: {
98 112 for(int i = 0; i < endVector.count() * qBound(qreal(0), progress, qreal(1)); i++)
99 113 result << endVector[i];
100 114 }
@@ -110,11 +124,23 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
110 124 void XYAnimation::updateCurrentValue (const QVariant &value)
111 125 {
112 126 if(state()!=QAbstractAnimation::Stopped){ //workaround
113 m_dirty = true;
114 127 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
115 128 m_item->setGeometryPoints(vector);
116 129 m_item->updateGeometry();
130 m_item->setDirty(true);
131 }
132 }
133
134 void XYAnimation::updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState )
135 {
136 if(oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped)
137 {
138 if(m_item->isDirty() && m_type==RemovePointAnimation){
139 if(!m_newPoints.isEmpty()) m_newPoints.remove(m_index);
140 m_item->setGeometryPoints(m_newPoints);
141 }
117 142 }
118 143 }
119 144
145 #include "moc_chartanimation_p.cpp"
120 146 QTCOMMERCIALCHART_END_NAMESPACE
@@ -31,20 +31,22 class XYChart;
31 31 class XYAnimation : public ChartAnimation
32 32 {
33 33 public:
34 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
34 enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
35 35 XYAnimation(XYChart *item);
36 36 ~XYAnimation();
37 void setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index);
37 void setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints,int index);
38 38 void setAnimationType(Animation type);
39 39 Animation animationType() const { return m_type; };
40 40
41 41 protected:
42 42 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress ) const;
43 43 void updateCurrentValue (const QVariant &value );
44
44 void updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState );
45 45 private:
46 46 XYChart *m_item;
47 47 QVector<QPointF> m_oldPoints;
48 QVector<QPointF> m_newPoints;
49 int m_index;
48 50 bool m_dirty;
49 51 Animation m_type;
50 52 };
@@ -25,6 +25,7
25 25 #include "chartpresenter_p.h"
26 26 #include <QPainter>
27 27 #include <QGraphicsSceneMouseEvent>
28 #include <QDebug>
28 29
29 30
30 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -39,9 +40,9 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
39 40 m_pointsVisible(false)
40 41 {
41 42 setZValue(ChartPresenter::LineChartZValue);
42 m_upper = new AreaBoundItem(this,m_series->upperSeries());
43 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
43 44 if (m_series->lowerSeries())
44 m_lower = new AreaBoundItem(this,m_series->lowerSeries());
45 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
45 46
46 47 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
47 48 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
@@ -75,7 +75,9 private:
75 75 class AreaBoundItem : public LineChartItem
76 76 {
77 77 public:
78 AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries) : LineChartItem(lineSeries, 0), m_item(item) {}
78 AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries,ChartPresenter* presenter) : LineChartItem(lineSeries, 0), m_item(item) {
79 setPresenter(presenter);
80 }
79 81 ~AreaBoundItem() {}
80 82
81 83 void updateGeometry() {
@@ -3,11 +3,15 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/chartaxis.cpp \
6 $$PWD/chartaxisx.cpp \
7 $$PWD/chartaxisy.cpp \
6 8 $$PWD/qaxis.cpp \
7 9 $$PWD/qaxiscategories.cpp
8 10
9 11 PRIVATE_HEADERS += \
10 12 $$PWD/chartaxis_p.h \
13 $$PWD/chartaxisx_p.h \
14 $$PWD/chartaxisy_p.h \
11 15 $$PWD/qaxis_p.h \
12 16 $$PWD/qaxiscategories_p.h
13 17
@@ -28,13 +28,10
28 28 #include <QDebug>
29 29 #include <cmath>
30 30
31 static int label_padding = 5;
32
33 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 32
35 ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
33 ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter) : Chart(presenter),
36 34 m_chartAxis(axis),
37 m_type(type),
38 35 m_labelsAngle(0),
39 36 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
40 37 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
@@ -42,7 +39,8 ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter,AxisType type) : Char
42 39 m_axis(new QGraphicsItemGroup(presenter->rootItem())),
43 40 m_min(0),
44 41 m_max(0),
45 m_ticksCount(0)
42 m_ticksCount(0),
43 m_animation(0)
46 44 {
47 45 //initial initialization
48 46 m_axis->setZValue(ChartPresenter::AxisZValue);
@@ -61,9 +59,18 ChartAxis::~ChartAxis()
61 59 {
62 60 }
63 61
64 void ChartAxis::createItems(int count)
62 void ChartAxis::setAnimation(AxisAnimation* animation)
63 {
64 m_animation=animation;
65 }
66
67 void ChartAxis::setLayout(QVector<qreal> &layout)
65 68 {
69 m_layoutVector=layout;
70 }
66 71
72 void ChartAxis::createItems(int count)
73 {
67 74 if (m_axis->children().size() == 0)
68 75 m_axis->addToGroup(new AxisItem(this));
69 76 for (int i = 0; i < count; ++i) {
@@ -91,16 +98,51 void ChartAxis::deleteItems(int count)
91 98
92 99 void ChartAxis::updateLayout(QVector<qreal> &layout)
93 100 {
94 if (animator()) {
95 animator()->updateLayout(this,layout);
96 } else {
101 int diff = m_layoutVector.size() - layout.size();
102
103 if (diff>0) {
104 deleteItems(diff);
105 }
106 else if (diff<0) {
107 createItems(-diff);
108 }
109
110 if( diff!=0) handleAxisUpdated();
111
112 if (m_animation) {
113 switch(presenter()->state()){
114 case ChartPresenter::ZoomInState:
115 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
116 m_animation->setAnimationPoint(presenter()->statePoint());
117 break;
118 case ChartPresenter::ZoomOutState:
119 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
120 m_animation->setAnimationPoint(presenter()->statePoint());
121 break;
122 case ChartPresenter::ScrollUpState:
123 case ChartPresenter::ScrollLeftState:
124 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
125 break;
126 case ChartPresenter::ScrollDownState:
127 case ChartPresenter::ScrollRightState:
128 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
129 break;
130 case ChartPresenter::ShowState:
131 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
132 break;
133 }
134 m_animation->setValues(m_layoutVector,layout);
135 presenter()->startAnimation(m_animation);
136 }
137 else {
97 138 setLayout(layout);
139 updateGeometry();
98 140 }
99 141 }
100 142
101 143 bool ChartAxis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
102 144 {
103 Q_ASSERT(max>=min);
145 Q_ASSERT(max>min);
104 146 Q_ASSERT(ticks>1);
105 147
106 148 QAxisCategories* categories = m_chartAxis->categories();
@@ -112,6 +154,7 bool ChartAxis::createLabels(QStringList &labels,qreal min, qreal max,int ticks)
112 154 n++;
113 155 for (int i=0; i< ticks; i++) {
114 156 qreal value = min + (i * (max - min)/ (ticks-1));
157 Q_UNUSED(value);
115 158 labels << QString::number(value,'f',n);
116 159 }
117 160 } else {
@@ -230,153 +273,6 void ChartAxis::setGridPen(const QPen &pen)
230 273 }
231 274 }
232 275
233 QVector<qreal> ChartAxis::calculateLayout() const
234 {
235 Q_ASSERT(m_ticksCount>=2);
236
237 QVector<qreal> points;
238 points.resize(m_ticksCount);
239
240 switch (m_type)
241 {
242 case X_AXIS:
243 {
244 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
245 for (int i = 0; i < m_ticksCount; ++i) {
246 int x = i * deltaX + m_rect.left();
247 points[i] = x;
248 }
249 }
250 break;
251 case Y_AXIS:
252 {
253 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
254 for (int i = 0; i < m_ticksCount; ++i) {
255 int y = i * -deltaY + m_rect.bottom();
256 points[i] = y;
257 }
258 }
259 break;
260 }
261 return points;
262 }
263
264 void ChartAxis::setLayout(QVector<qreal> &layout)
265 {
266 int diff = m_layoutVector.size() - layout.size();
267
268 if (diff>0) {
269 deleteItems(diff);
270 } else if (diff<0) {
271 createItems(-diff);
272 }
273
274 if( diff!=0) handleAxisUpdated();
275
276 QStringList ticksList;
277
278 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
279
280 QList<QGraphicsItem *> lines = m_grid->childItems();
281 QList<QGraphicsItem *> labels = m_labels->childItems();
282 QList<QGraphicsItem *> shades = m_shades->childItems();
283 QList<QGraphicsItem *> axis = m_axis->childItems();
284
285 Q_ASSERT(labels.size() == ticksList.size());
286 Q_ASSERT(layout.size() == ticksList.size());
287
288 qreal minWidth = 0;
289 qreal minHeight = 0;
290
291 switch (m_type)
292 {
293 case X_AXIS:
294 {
295 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
296 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
297
298 for (int i = 0; i < layout.size(); ++i) {
299 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
300 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
301 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
302 if (!categories || i<1) {
303 labelItem->setText(ticksList.at(i));
304 const QRectF& rect = labelItem->boundingRect();
305 minWidth+=rect.width();
306 minHeight=qMax(rect.height(),minHeight);
307 QPointF center = rect.center();
308 labelItem->setTransformOriginPoint(center.x(), center.y());
309 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
310 } else {
311 labelItem->setText(ticksList.at(i));
312 const QRectF& rect = labelItem->boundingRect();
313 minWidth+=rect.width();
314 minHeight=qMax(rect.height()+label_padding,minHeight);
315 QPointF center = rect.center();
316 labelItem->setTransformOriginPoint(center.x(), center.y());
317 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
318 }
319
320 if ((i+1)%2 && i>1) {
321 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
322 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
323 }
324 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
325 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
326 }
327
328 }
329 break;
330
331 case Y_AXIS:
332 {
333 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
334 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
335
336 for (int i = 0; i < layout.size(); ++i) {
337 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
338 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
339 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
340
341 if (!categories || i<1) {
342 labelItem->setText(ticksList.at(i));
343 const QRectF& rect = labelItem->boundingRect();
344 minWidth=qMax(rect.width()+label_padding,minWidth);
345 minHeight+=rect.height();
346 QPointF center = rect.center();
347 labelItem->setTransformOriginPoint(center.x(), center.y());
348 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
349 } else {
350 labelItem->setText(ticksList.at(i));
351 const QRectF& rect = labelItem->boundingRect();
352 minWidth=qMax(rect.width(),minWidth);
353 minHeight+=rect.height();
354 QPointF center = rect.center();
355 labelItem->setTransformOriginPoint(center.x(), center.y());
356 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
357 }
358
359 if ((i+1)%2 && i>1) {
360 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
361 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
362 }
363 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
364 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
365 }
366 }
367 break;
368 default:
369 qWarning()<<"Unknown axis type";
370 break;
371 }
372
373 m_layoutVector=layout;
374
375 presenter()->setMinimumMarginWidth(this,minWidth);
376 presenter()->setMinimumMarginHeight(this,minHeight);
377
378 }
379
380 276 bool ChartAxis::isEmpty()
381 277 {
382 278 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
@@ -442,7 +338,6 void ChartAxis::handleRangeChanged(qreal min, qreal max,int tickCount)
442 338 if (isEmpty()) return;
443 339 QVector<qreal> layout = calculateLayout();
444 340 updateLayout(layout);
445
446 341 }
447 342
448 343 void ChartAxis::handleGeometryChanged(const QRectF &rect)
@@ -18,11 +18,12
18 18 **
19 19 ****************************************************************************/
20 20
21 #ifndef AXIS_H
22 #define AXIS_H
21 #ifndef CHARTAXIS_H
22 #define CHARTAXIS_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "chart_p.h"
26 #include "axisanimation_p.h"
26 27 #include <QGraphicsItem>
27 28
28 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -36,10 +37,10 class ChartAxis : public Chart
36 37 public:
37 38 enum AxisType{X_AXIS,Y_AXIS};
38 39
39 ChartAxis(QAxis *axis, ChartPresenter *presenter, AxisType type = X_AXIS);
40 ChartAxis(QAxis *axis, ChartPresenter *presenter);
40 41 ~ChartAxis();
41 42
42 AxisType axisType() const { return m_type; }
43 virtual AxisType axisType() const = 0;
43 44
44 45 void setAxisOpacity(qreal opacity);
45 46 qreal axisOpacity() const;
@@ -66,8 +67,18 public:
66 67 void setLabelsBrush(const QBrush &brush);
67 68 void setLabelsFont(const QFont &font);
68 69
69 inline QRectF geometry() const { return m_rect; }
70 inline QVector<qreal> layout() { return m_layoutVector; }
70 void setLayout(QVector<qreal> &layout);
71 QVector<qreal> layout() const { return m_layoutVector; }
72
73 void setAnimation(AxisAnimation* animation);
74 ChartAnimation* animation() const { return m_animation; };
75
76 QRectF geometry() const { return m_rect; }
77
78 protected:
79 virtual void updateGeometry() = 0;
80 virtual QVector<qreal> calculateLayout() const = 0;
81 bool createLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
71 82
72 83 public Q_SLOTS:
73 84 void handleAxisUpdated();
@@ -75,22 +86,15 public Q_SLOTS:
75 86 void handleRangeChanged(qreal min , qreal max,int tickCount);
76 87 void handleGeometryChanged(const QRectF &size);
77 88
78
79 89 private:
80 90 inline bool isEmpty();
81 91 void createItems(int count);
82 92 void deleteItems(int count);
83
84 QVector<qreal> calculateLayout() const;
85 93 void updateLayout(QVector<qreal> &layout);
86 void setLayout(QVector<qreal> &layout);
87
88 bool createLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
89 94 void axisSelected();
90 95
91 private:
96 protected:
92 97 QAxis* m_chartAxis;
93 AxisType m_type;
94 98 QRectF m_rect;
95 99 int m_labelsAngle;
96 100 QScopedPointer<QGraphicsItemGroup> m_grid;
@@ -101,6 +105,7 private:
101 105 qreal m_min;
102 106 qreal m_max;
103 107 int m_ticksCount;
108 AxisAnimation *m_animation;
104 109
105 110 friend class AxisAnimation;
106 111 friend class AxisItem;
@@ -24,11 +24,15
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 #include "chartanimation_p.h"
27 28 #include "qabstractseries_p.h"
28 29 #include "qareaseries.h"
29 30 #include "chartaxis_p.h"
31 #include "chartaxisx_p.h"
32 #include "chartaxisy_p.h"
30 33 #include "areachartitem_p.h"
31 34 #include "chartbackground_p.h"
35 #include <QTimer>
32 36
33 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 38
@@ -41,6 +45,7 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
41 45 m_options(QChart::NoAnimation),
42 46 m_minLeftMargin(0),
43 47 m_minBottomMargin(0),
48 m_state(ShowState),
44 49 m_backgroundItem(0),
45 50 m_titleItem(0),
46 51 m_marginBig(60),
@@ -48,6 +53,7 m_marginSmall(20),
48 53 m_marginTiny(10),
49 54 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
50 55 {
56
51 57 }
52 58
53 59 ChartPresenter::~ChartPresenter()
@@ -112,10 +118,17 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
112 118
113 119 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
114 120 {
115 ChartAxis* item = new ChartAxis(axis,this,axis==m_dataset->axisX()?ChartAxis::X_AXIS : ChartAxis::Y_AXIS);
121 ChartAxis* item;
122
123 if(axis == m_dataset->axisX()){
124 item = new ChartAxisX(axis,this);
125 }else{
126 item = new ChartAxisY(axis,this);
127 }
116 128
117 129 if(m_options.testFlag(QChart::GridAxisAnimations)){
118 m_animator->addAnimation(item);
130 item->setAnimator(m_animator);
131 item->setAnimation(new AxisAnimation(item));
119 132 }
120 133
121 134 if(axis==m_dataset->axisX()){
@@ -244,21 +257,15 void ChartPresenter::zoomIn(const QRectF& rect)
244 257 if (!r.isValid())
245 258 return;
246 259
247 if (m_animator) {
248 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
249 m_animator->setState(ChartAnimator::ZoomInState,point);
250 }
251
260 m_state = ZoomInState;
261 m_statePoint = QPointF(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
252 262 m_dataset->zoomInDomain(r,chartGeometry().size());
253
254 if (m_animator)
255 m_animator->setState(ChartAnimator::ShowState);
263 m_state = ShowState;
256 264 }
257 265
258 266 void ChartPresenter::zoomOut(qreal factor)
259 267 {
260 if (m_animator)
261 m_animator->setState(ChartAnimator::ZoomOutState);
268 m_state = ZoomOutState;
262 269
263 270 QRectF chartRect;
264 271 chartRect.setSize(chartGeometry().size());
@@ -268,27 +275,21 void ChartPresenter::zoomOut(qreal factor)
268 275 rect.moveCenter(chartRect.center());
269 276 if (!rect.isValid())
270 277 return;
271
278 m_statePoint = QPointF(rect.center().x()/chartGeometry().width(),rect.center().y()/chartGeometry().height());
272 279 m_dataset->zoomOutDomain(rect, chartRect.size());
273
274 if (m_animator)
275 m_animator->setState(ChartAnimator::ShowState);
280 m_state = ShowState;
276 281 }
277 282
278 283 void ChartPresenter::scroll(int dx,int dy)
279 284 {
280 if(m_animator){
281 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
282 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
283 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
284 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
285 }
286 285
287 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
286 if(dx<0) m_state=ScrollLeftState;
287 if(dx>0) m_state=ScrollRightState;
288 if(dy<0) m_state=ScrollUpState;
289 if(dy>0) m_state=ScrollDownState;
288 290
289 if(m_animator){
290 m_animator->setState(ChartAnimator::ShowState);
291 }
291 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
292 m_state = ShowState;
292 293 }
293 294
294 295 QChart::AnimationOptions ChartPresenter::animationOptions() const
@@ -389,7 +390,6 void ChartPresenter::updateLayout()
389 390 emit geometryChanged(m_chartRect);
390 391 }
391 392
392
393 393 }
394 394
395 395 void ChartPresenter::createChartBackgroundItem()
@@ -409,6 +409,22 void ChartPresenter::createChartTitleItem()
409 409 }
410 410 }
411 411
412 void ChartPresenter::handleAnimationFinished()
413 {
414 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
415 if(m_animations.empty()) emit animationsFinished();
416 }
417
418 void ChartPresenter::startAnimation(ChartAnimation* animation)
419 {
420 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
421 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
422 if(!m_animations.isEmpty()){
423 m_animations.append(animation);
424 }
425 QTimer::singleShot(0, animation, SLOT(start()));
426 }
427
412 428 #include "moc_chartpresenter_p.cpp"
413 429
414 430 QTCOMMERCIALCHART_END_NAMESPACE
@@ -35,6 +35,7 class ChartAxis;
35 35 class ChartTheme;
36 36 class ChartAnimator;
37 37 class ChartBackground;
38 class ChartAnimation;
38 39
39 40 class ChartPresenter: public QObject
40 41 {
@@ -51,6 +52,14 public:
51 52 AxisZValue,
52 53 LegendZValue
53 54 };
55 enum State {ShowState,
56 ScrollUpState,
57 ScrollDownState,
58 ScrollLeftState,
59 ScrollRightState,
60 ZoomInState,
61 ZoomOutState
62 };
54 63
55 64 ChartPresenter(QChart* chart,ChartDataSet *dataset);
56 65 virtual ~ChartPresenter();
@@ -79,6 +88,9 public:
79 88 qreal minimumLeftMargin() const { return m_minLeftMargin; }
80 89 qreal minimumBottomMargin() const { return m_minBottomMargin; }
81 90
91 void startAnimation(ChartAnimation* animation);
92 State state() const { return m_state; }
93 QPointF statePoint() const { return m_statePoint; }
82 94 public: //TODO: fix me
83 95 void resetAllElements();
84 96 void createChartBackgroundItem();
@@ -92,9 +104,12 public Q_SLOTS:
92 104 void handleAxisRemoved(QAxis* axis);
93 105 void updateLayout();
94 106
107 private Q_SLOTS:
108 void handleAnimationFinished();
109
95 110 Q_SIGNALS:
96 111 void geometryChanged(const QRectF& rect);
97
112 void animationsFinished();
98 113
99 114 private:
100 115 QChart* m_chart;
@@ -108,6 +123,10 private:
108 123 QChart::AnimationOptions m_options;
109 124 qreal m_minLeftMargin;
110 125 qreal m_minBottomMargin;
126 State m_state;
127 QPointF m_statePoint;
128 QList<ChartAnimation*> m_animations;
129
111 130 public: //TODO: fixme
112 131 ChartBackground* m_backgroundItem;
113 132 QGraphicsSimpleTextItem* m_titleItem;
@@ -116,7 +135,6 public: //TODO: fixme
116 135 int m_marginTiny;
117 136 QRectF m_chartMargins;
118 137 QRectF m_legendMargins;
119
120 138 };
121 139
122 140 QTCOMMERCIALCHART_END_NAMESPACE
@@ -87,7 +87,7 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF>
87 87
88 88 if (m_animation) {
89 89 m_animation->setValues(oldPoints,newPoints,m_controlPoints,controlPoints,index);
90 animator()->startAnimation(m_animation);
90 presenter()->startAnimation(m_animation);
91 91 }
92 92 else {
93 93 setGeometryPoints(newPoints);
@@ -26,6 +26,7
26 26 #include <QPainter>
27 27 #include <QAbstractItemModel>
28 28 #include "qxymodelmapper.h"
29 #include <QDebug>
29 30
30 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 32
@@ -37,7 +38,8 m_maxX(0),
37 38 m_minY(0),
38 39 m_maxY(0),
39 40 m_series(series),
40 m_animation(0)
41 m_animation(0),
42 m_dirty(true)
41 43 {
42 44 QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
43 45 QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
@@ -46,7 +48,7 m_animation(0)
46 48 QObject::connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
47 49 }
48 50
49 void XYChart::setGeometryPoints(QVector<QPointF>& points)
51 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
50 52 {
51 53 m_points = points;
52 54 }
@@ -61,6 +63,11 void XYChart::setAnimation(XYAnimation* animation)
61 63 m_animation=animation;
62 64 }
63 65
66 void XYChart::setDirty(bool dirty)
67 {
68 m_dirty=dirty;
69 }
70
64 71 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
65 72 {
66 73 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
@@ -110,7 +117,9 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoin
110 117 {
111 118 if (m_animation) {
112 119 m_animation->setValues(oldPoints, newPoints, index);
113 animator()->startAnimation(m_animation);
120 setGeometryPoints(newPoints);
121 setDirty(false);
122 presenter()->startAnimation(m_animation);
114 123 }
115 124 else {
116 125 setGeometryPoints(newPoints);
@@ -124,13 +133,19 void XYChart::handlePointAdded(int index)
124 133 {
125 134 Q_ASSERT(index<m_series->count());
126 135 Q_ASSERT(index>=0);
127 QVector<QPointF> points = m_points;
128 QPointF point;
129 point = calculateGeometryPoint(index);
130 points.insert(index, point);
136
137 QVector<QPointF> points;
131 138
132 139 if(m_animation) {
133 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
140 m_animation->setAnimationType(XYAnimation::AddPointAnimation);
141 }
142
143 if(m_dirty) {
144 points = calculateGeometryPoints();
145 } else {
146 points = m_points;
147 QPointF point = calculateGeometryPoint(index);
148 points.insert(index, point);
134 149 }
135 150
136 151 updateChart(m_points,points,index);
@@ -138,13 +153,20 void XYChart::handlePointAdded(int index)
138 153
139 154 void XYChart::handlePointRemoved(int index)
140 155 {
141 Q_ASSERT(index<m_series->count() + 1);
156 Q_ASSERT(index<=m_series->count());
142 157 Q_ASSERT(index>=0);
143 QVector<QPointF> points = m_points;
144 points.remove(index);
158
159 QVector<QPointF> points;
145 160
146 161 if(m_animation) {
147 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
162 m_animation->setAnimationType(XYAnimation::RemovePointAnimation);
163 }
164
165 if(m_dirty) {
166 points = calculateGeometryPoints();
167 } else {
168 points = m_points;
169 points.remove(index);
148 170 }
149 171
150 172 updateChart(m_points,points,index);
@@ -154,12 +176,19 void XYChart::handlePointReplaced(int index)
154 176 {
155 177 Q_ASSERT(index<m_series->count());
156 178 Q_ASSERT(index>=0);
157 QPointF point = calculateGeometryPoint(index);
158 QVector<QPointF> points = m_points;
159 points.replace(index,point);
179
180 QVector<QPointF> points;
160 181
161 182 if(m_animation) {
162 m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
183 m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
184 }
185
186 if(m_dirty) {
187 points = calculateGeometryPoints();
188 } else {
189 QPointF point = calculateGeometryPoint(index);
190 points = m_points;
191 points.replace(index,point);
163 192 }
164 193
165 194 updateChart(m_points,points,index);
@@ -170,7 +199,7 void XYChart::handleReinitialized()
170 199 QVector<QPointF> points = calculateGeometryPoints();
171 200
172 201 if(m_animation) {
173 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
202 m_animation->setAnimationType(XYAnimation::NewAnimation);
174 203 }
175 204
176 205 updateChart(m_points,points);
@@ -178,16 +207,19 void XYChart::handleReinitialized()
178 207
179 208 void XYChart::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
180 209 {
210 qDebug()<<__FUNCTION__;
181 211 m_minX=minX;
182 212 m_maxX=maxX;
183 213 m_minY=minY;
184 214 m_maxY=maxY;
185 215 if (isEmpty()) return;
216
186 217 QVector<QPointF> points = calculateGeometryPoints();
187 218
188 219 if(m_animation) {
189 m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
220 m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
190 221 }
222
191 223 updateChart(m_points,points);
192 224 }
193 225
@@ -199,10 +231,13 void XYChart::handleGeometryChanged(const QRectF &rect)
199 231 m_origin=rect.topLeft();
200 232
201 233 if (isEmpty()) return;
234
202 235 QVector<QPointF> points = calculateGeometryPoints();
236
203 237 if(m_animation) {
204 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
238 m_animation->setAnimationType(XYAnimation::NewAnimation);
205 239 }
240
206 241 updateChart(m_points,points);
207 242 }
208 243
@@ -38,7 +38,7 public:
38 38 explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
39 39 ~XYChart(){};
40 40
41 void setGeometryPoints(QVector<QPointF>& points);
41 void setGeometryPoints(const QVector<QPointF>& points);
42 42 QVector<QPointF> geometryPoints() const { return m_points; }
43 43
44 44 void setClipRect(const QRectF &rect);
@@ -51,6 +51,9 public:
51 51 ChartAnimation* animation() const { return m_animation; }
52 52 virtual void updateGeometry() = 0;
53 53
54 bool isDirty() const { return m_dirty; }
55 void setDirty(bool dirty);
56
54 57 public Q_SLOTS:
55 58 void handlePointAdded(int index);
56 59 void handlePointRemoved(int index);
@@ -83,6 +86,7 private:
83 86 QRectF m_clipRect;
84 87 QVector<QPointF> m_points;
85 88 XYAnimation* m_animation;
89 bool m_dirty;
86 90
87 91 friend class AreaChartItem;
88 92
General Comments 0
You need to be logged in to leave comments. Login now