##// 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_ */
@@ -1,65 +1,138
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "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
26 28 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);
41 113 QVector<qreal> endVecotr = qVariantValue<QVector<qreal> >(end);
42 114 QVector<qreal> result;
43 115
44 116 Q_ASSERT(startVector.count() == endVecotr.count()) ;
45 117
46 118 for(int i = 0; i < startVector.count(); i++){
47 119 qreal value = startVector[i] + ((endVecotr[i]- startVector[i]) * progress);//qBound(0.0, progress, 1.0));
48 120 result << value;
49 121 }
50 122 return qVariantFromValue(result);
51 123 }
52 124
53 125
54 126 void AxisAnimation::updateCurrentValue (const QVariant &value )
55 127 {
56 128 if (state() != QAbstractAnimation::Stopped)//workaround
57 129 {
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 }
64 137
65 138 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,46 +1,53
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #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
43 50
44 51
45 52
46 53 #endif /* AXISITEM_H_ */
@@ -1,41 +1,42
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef CHARTANIMATION_H
22 22 #define CHARTANIMATION_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include <QVariantAnimation>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 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 };
36 37
37 38 QTCOMMERCIALCHART_END_NAMESPACE
38 39
39 40
40 41
41 42 #endif /* AXISITEM_H_ */
@@ -1,210 +1,112
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartanimator_p.h"
22 22 #include "axisanimation_p.h"
23 23 #include "xyanimation_p.h"
24 24 #include "splineanimation_p.h"
25 25 #include "xychart_p.h"
26 26 #include "pieanimation_p.h"
27 27 #include "baranimation_p.h"
28 28 #include "barchartitem_p.h"
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>)
35 36 Q_DECLARE_METATYPE(QVector<qreal>)
36 37 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);
64 51
65 52 if (!animation) {
66 53 animation = new PieAnimation(item);
67 54 m_animations.insert(item, animation);
68 55 }
69 56
70 57 item->setAnimator(this);
71 58 }
72 59
73 60 void ChartAnimator::addAnimation(BarChartItem *item)
74 61 {
75 62 ChartAnimation *animation = m_animations.value(item);
76 63
77 64 if (!animation) {
78 65 animation = new BarAnimation(item);
79 66 m_animations.insert(item, animation);
80 67 }
81 68
82 69 item->setAnimator(this);
83 70 }
84 71
85 72
86 73 void ChartAnimator::removeAnimation(Chart *item)
87 74 {
88 75 item->setAnimator(0);
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));
164 82 Q_ASSERT(animation);
165 83 animation->addSlice(sliceItem, sliceData, startupAnimation);
166 84 }
167 85
168 86 void ChartAnimator::removeAnimation(PieChartItem *item, PieSliceItem *sliceItem)
169 87 {
170 88 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
171 89 Q_ASSERT(animation);
172 90 animation->removeSlice(sliceItem);
173 91 }
174 92
175 93 void ChartAnimator::updateAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData)
176 94 {
177 95 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
178 96 Q_ASSERT(animation);
179 97 animation->updateValue(sliceItem, sliceData);
180 98 }
181 99
182 100 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
183 101 {
184 102 BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item));
185 103 Q_ASSERT(animation);
186 104 animation->setDuration(ChartAnimationDuration);
187 105 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
188 106 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
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
@@ -1,76 +1,64
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef CHARTANIMATOR_P_H
22 22 #define CHARTANIMATOR_P_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "chartanimation_p.h"
26 26 #include "piechartitem_p.h"
27 27 #include "barchartitem_p.h"
28 28 #include <QPointF>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 class ChartItem;
33 33 class ChartAxis;
34 34 class AreaChartItem;
35 35 class SplineChartItem;
36 36 class ScatterChartItem;
37 37 class LineChartItem;
38 38 class XYChartItem;
39 39 class XYAnimation;
40 40
41 41 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
75 63
76 64 #endif
@@ -1,150 +1,153
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "splineanimation_p.h"
22 22 #include "splinechartitem_p.h"
23 23 #include <QDebug>
24 24
25 25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 26 Q_DECLARE_METATYPE(SplineVector)
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
31 31 m_item(item),
32 32 m_dirty(true)
33 33 {
34 34 }
35 35
36 36 SplineAnimation::~SplineAnimation()
37 37 {
38 38 }
39 39
40 40 void SplineAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
41 41 {
42 42 int x = oldPoints.count();
43 43 int y = newPoints.count();
44 44
45 45 Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
46 46
47 47 if (x != y && abs(x - y) != 1) {
48 48 m_oldSpline.first = newPoints;
49 49 m_oldSpline.second = newControlPoints;
50 50 oldPoints.resize(newPoints.size());
51 51 oldControlPoints.resize(newControlPoints.size());
52 52 SplineVector oldPair;
53 53 oldPair.first = oldPoints;
54 54 oldPair.second = oldControlPoints;
55 55 SplineVector newPair;
56 56 newPair.first = newPoints;
57 57 newPair.second = newControlPoints;
58 58 setKeyValueAt(0.0, qVariantFromValue(oldPair));
59 59 setKeyValueAt(1.0, qVariantFromValue(newPair));
60 60 m_dirty = false;
61 61 }
62 62 else {
63 63 if(m_dirty) {
64 64 m_oldSpline.first = oldPoints;
65 65 m_oldSpline.second = oldControlPoints;
66 66 m_dirty = false;
67 67 }
68 68 oldPoints = newPoints;
69 69 oldControlPoints = newControlPoints;
70 70 if (y < x) {
71 71 m_oldSpline.first.remove(index); //remove
72 72 m_oldSpline.second.remove(index * 2);
73 73 m_oldSpline.second.remove(index * 2);
74 74 }
75 75 if (y > x) {
76 76 m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
77 77 m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
78 78 m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
79 79 }
80 80 SplineVector newPair;
81 81 newPair.first=newPoints;
82 82 newPair.second=newControlPoints;
83 83 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
84 84 setKeyValueAt(1.0, qVariantFromValue(newPair));
85 85 }
86 86 }
87 87
88 88 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
89 89 {
90 90
91 91 SplineVector startPair = qVariantValue< SplineVector >(start);
92 92 SplineVector endPair = qVariantValue< SplineVector >(end);
93 93 SplineVector result;
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());
101 104 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
102 105 for(int i = 0; i < endPair.first.count(); i++) {
103 106 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
104 107 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
105 108 result.first << QPointF(x,y);
106 109 if (i + 1 >= endPair.first.count())
107 110 continue;
108 111 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
109 112 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
110 113 result.second << QPoint(x,y);
111 114 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
112 115 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
113 116 result.second << QPoint(x,y);
114 117 }
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++) {
122 125 result.first << endPair.first[i];
123 126 if(i + 1 == count)
124 127 break;
125 128 result.second << endPair.second[2 * i];
126 129 result.second << endPair.second[2 * i + 1];
127 130 }
128 131 }
129 132 break;
130 133 default:
131 134 qWarning() << "Unknown type of animation";
132 135 break;
133 136 }
134 137
135 138 return qVariantFromValue(result);
136 139 }
137 140
138 141 void SplineAnimation::updateCurrentValue (const QVariant &value )
139 142 {
140 143 if (state() != QAbstractAnimation::Stopped) { //workaround
141 144 m_dirty = true;
142 145 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
143 146 m_item->setGeometryPoints(pair.first);
144 147 m_item->setControlGeometryPoints(pair.second);
145 148 m_item->updateGeometry();
146 149 }
147 150 }
148 151
149 152
150 153 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,120 +1,146
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xyanimation_p.h"
22 22 #include "xychart_p.h"
23 23 #include <QDebug>
24 24
25 25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
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()
37 39 {
38 40 }
39 41
40 42 void XYAnimation::setAnimationType(Animation type)
41 43 {
42 if (state() != QAbstractAnimation::Stopped) stop();
44 if (state() != QAbstractAnimation::Stopped) stop();
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 if (state() != QAbstractAnimation::Stopped) stop();
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));
58 m_dirty = false;
52 if (m_item->isDirty()) {
53 m_oldPoints = oldPoints;
54 m_newPoints = newPoints;
55 m_dirty=false;
59 56 }
60 57 else {
61 if (m_dirty) {
58 if(m_dirty) {
59 m_newPoints = newPoints;
62 60 m_oldPoints = oldPoints;
63 m_dirty = false;
61 m_dirty=false;
62 }
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){
75 m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]);//add
64 76 }
65 oldPoints = newPoints;
66 if (y < x)
67 m_oldPoints.remove(index); //remove
68 if (y > x)
69 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());
77 }else{
78 m_newPoints=newPoints;
79 m_dirty=false;
80 m_oldPoints.resize(m_newPoints.size());
73 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
77 89 {
78 90 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
79 91 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
80 92 QVector<QPointF> result;
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
89 103 for(int i = 0; i < startVector.count(); i++) {
90 104 qreal x = startVector[i].x() + ((endVector[i].x() - startVector[i].x()) * progress);
91 105 qreal y = startVector[i].y() + ((endVector[i].y() - startVector[i].y()) * progress);
92 106 result << QPointF(x, y);
93 107 }
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 }
101 115 break;
102 116 default:
103 117 qWarning() << "Unknown type of animation";
104 118 break;
105 119 }
106 120
107 121 return qVariantFromValue(result);
108 122 }
109 123
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);
117 131 }
118 132 }
119 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 }
142 }
143 }
144
145 #include "moc_chartanimation_p.cpp"
120 146 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,54 +1,56
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef XYANIMATION_P_H
22 22 #define XYANIMATION_P_H
23 23
24 24 #include "chartanimation_p.h"
25 25 #include <QPointF>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class XYChart;
30 30
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 };
51 53
52 54 QTCOMMERCIALCHART_END_NAMESPACE
53 55
54 56 #endif
@@ -1,142 +1,143
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "areachartitem_p.h"
22 22 #include "qareaseries.h"
23 23 #include "qareaseries_p.h"
24 24 #include "qlineseries.h"
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
31 32
32 33 //TODO: optimize : remove points which are not visible
33 34
34 35 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
35 36 : ChartItem(presenter),
36 37 m_series(areaSeries),
37 38 m_upper(0),
38 39 m_lower(0),
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)));
48 49
49 50 handleUpdated();
50 51 }
51 52
52 53 AreaChartItem::~AreaChartItem()
53 54 {
54 55 delete m_upper;
55 56 delete m_lower;
56 57 }
57 58
58 59 QRectF AreaChartItem::boundingRect() const
59 60 {
60 61 return m_rect;
61 62 }
62 63
63 64 QPainterPath AreaChartItem::shape() const
64 65 {
65 66 return m_path;
66 67 }
67 68
68 69 void AreaChartItem::updatePath()
69 70 {
70 71 QPainterPath path;
71 72
72 73 path = m_upper->shape();
73 74
74 75 if (m_lower) {
75 76 path.connectPath(m_lower->shape().toReversed());
76 77 } else {
77 78 QPointF first = path.pointAtPercent(0);
78 79 QPointF last = path.pointAtPercent(1);
79 80 path.lineTo(last.x(),m_clipRect.bottom());
80 81 path.lineTo(first.x(),m_clipRect.bottom());
81 82 }
82 83 path.closeSubpath();
83 84 prepareGeometryChange();
84 85 m_path = path;
85 86 m_rect = path.boundingRect();
86 87 update();
87 88 }
88 89
89 90 void AreaChartItem::handleUpdated()
90 91 {
91 92 m_pointsVisible = m_series->pointsVisible();
92 93 m_linePen = m_series->pen();
93 94 m_brush = m_series->brush();
94 95 m_pointPen = m_series->pen();
95 96 m_pointPen.setWidthF(2 * m_pointPen.width());
96 97
97 98 update();
98 99 }
99 100
100 101 void AreaChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
101 102 {
102 103 m_upper->handleDomainChanged(minX,maxX,minY,maxY);
103 104 if (m_lower)
104 105 m_lower->handleDomainChanged(minX,maxX,minY,maxY);
105 106 }
106 107
107 108 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
108 109 {
109 110 m_clipRect=rect.translated(-rect.topLeft());
110 111 setPos(rect.topLeft());
111 112 m_upper->handleGeometryChanged(rect);
112 113 if (m_lower)
113 114 m_lower->handleGeometryChanged(rect);
114 115 }
115 116
116 117 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
117 118 {
118 119 Q_UNUSED(widget)
119 120 Q_UNUSED(option)
120 121
121 122 painter->save();
122 123 painter->setPen(m_linePen);
123 124 painter->setBrush(m_brush);
124 125 painter->setClipRect(m_clipRect);
125 126 painter->drawPath(m_path);
126 127 if (m_pointsVisible) {
127 128 painter->setPen(m_pointPen);
128 129 painter->drawPoints(m_upper->geometryPoints());
129 130 if (m_lower)
130 131 painter->drawPoints(m_lower->geometryPoints());
131 132 }
132 133 painter->restore();
133 134 }
134 135
135 136 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
136 137 {
137 138 emit clicked(m_upper->calculateDomainPoint(event->pos()));
138 139 }
139 140
140 141 #include "moc_areachartitem_p.cpp"
141 142
142 143 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,92 +1,94
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef AREACHARTITEM_H
22 22 #define AREACHARTITEM_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "linechartitem_p.h"
26 26 #include <QPen>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class QAreaSeries;
31 31 class AreaChartItem;
32 32
33 33 class AreaChartItem : public ChartItem
34 34 {
35 35 Q_OBJECT
36 36 public:
37 37 AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter);
38 38 ~AreaChartItem();
39 39
40 40 //from QGraphicsItem
41 41 QRectF boundingRect() const;
42 42 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
43 43 QPainterPath shape() const;
44 44
45 45 LineChartItem* upperLineItem() const { return m_upper; }
46 46 LineChartItem* lowerLineItem() const { return m_lower; }
47 47
48 48 void updatePath();
49 49
50 50 protected:
51 51 void mousePressEvent(QGraphicsSceneMouseEvent *event);
52 52
53 53 Q_SIGNALS:
54 54 void clicked(const QPointF &point);
55 55
56 56 public Q_SLOTS:
57 57 void handleUpdated();
58 58 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
59 59 void handleGeometryChanged(const QRectF &size);
60 60
61 61 private:
62 62 QAreaSeries* m_series;
63 63 LineChartItem* m_upper;
64 64 LineChartItem* m_lower;
65 65 QPainterPath m_path;
66 66 QRectF m_rect;
67 67 QRectF m_clipRect;
68 68 QPen m_linePen;
69 69 QPen m_pointPen;
70 70 QBrush m_brush;
71 71 bool m_pointsVisible;
72 72
73 73 };
74 74
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() {
82 84 LineChartItem::updateGeometry();
83 85 m_item->updatePath();
84 86 }
85 87
86 88 private:
87 89 AreaChartItem* m_item;
88 90 };
89 91
90 92 QTCOMMERCIALCHART_END_NAMESPACE
91 93
92 94 #endif
@@ -1,16 +1,20
1 1 INCLUDEPATH += $$PWD
2 2 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
14 18 PUBLIC_HEADERS += \
15 19 $$PWD/qaxis.h \
16 20 $$PWD/qaxiscategories.h No newline at end of file
@@ -1,466 +1,361
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartaxis_p.h"
22 22 #include "qaxis.h"
23 23 #include "qaxis_p.h"
24 24 #include "qaxiscategories_p.h"
25 25 #include "chartpresenter_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include <QPainter>
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())),
41 38 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
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);
49 47 m_axis->setHandlesChildEvents(false);
50 48
51 49 m_shades->setZValue(ChartPresenter::ShadesZValue);
52 50 m_grid->setZValue(ChartPresenter::GridZValue);
53 51
54 52 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
55 53 QObject::connect(m_chartAxis->categories()->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
56 54
57 55 handleAxisUpdated();
58 56 }
59 57
60 58 ChartAxis::~ChartAxis()
61 59 {
62 60 }
63 61
64 void ChartAxis::createItems(int count)
62 void ChartAxis::setAnimation(AxisAnimation* animation)
65 63 {
64 m_animation=animation;
65 }
66 66
67 void ChartAxis::setLayout(QVector<qreal> &layout)
68 {
69 m_layoutVector=layout;
70 }
71
72 void ChartAxis::createItems(int count)
73 {
67 74 if (m_axis->children().size() == 0)
68 m_axis->addToGroup(new AxisItem(this));
75 m_axis->addToGroup(new AxisItem(this));
69 76 for (int i = 0; i < count; ++i) {
70 77 m_grid->addToGroup(new QGraphicsLineItem());
71 78 m_labels->addToGroup(new QGraphicsSimpleTextItem());
72 79 m_axis->addToGroup(new QGraphicsLineItem());
73 80 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem());
74 }
81 }
75 82 }
76 83
77 84 void ChartAxis::deleteItems(int count)
78 85 {
79 86 QList<QGraphicsItem *> lines = m_grid->childItems();
80 87 QList<QGraphicsItem *> labels = m_labels->childItems();
81 88 QList<QGraphicsItem *> shades = m_shades->childItems();
82 89 QList<QGraphicsItem *> axis = m_axis->childItems();
83 90
84 91 for (int i = 0; i < count; ++i) {
85 92 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
86 93 delete(lines.takeLast());
87 94 delete(labels.takeLast());
88 95 delete(axis.takeLast());
89 96 }
90 97 }
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();
107 149
108 150 bool category = categories->count()>0;
109 151
110 152 if (!category) {
111 153 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
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 {
118 161 QList<qreal> values = categories->values();
119 162 for (int i=0; i< ticks; i++) {
120 163 qreal value = (min + (i * (max - min)/ (ticks-1)));
121 164 int j=0;
122 165 for (; j<values.count(); j++) {
123 166 if (values.at(j) > value) break;
124 167 }
125 168 if (j!=0) value=values.at(j-1);
126 169
127 170 QString label = categories->label(value);
128 171 labels << label;
129 172 }
130 173 }
131 174
132 175 return category;
133 176 }
134 177
135 178 void ChartAxis::setAxisOpacity(qreal opacity)
136 179 {
137 180 m_axis->setOpacity(opacity);
138 181 }
139 182
140 183 qreal ChartAxis::axisOpacity() const
141 184 {
142 185 return m_axis->opacity();
143 186 }
144 187
145 188 void ChartAxis::setGridOpacity(qreal opacity)
146 189 {
147 190 m_grid->setOpacity(opacity);
148 191 }
149 192
150 193 qreal ChartAxis::gridOpacity() const
151 194 {
152 195 return m_grid->opacity();
153 196 }
154 197
155 198 void ChartAxis::setLabelsOpacity(qreal opacity)
156 199 {
157 200 m_labels->setOpacity(opacity);
158 201 }
159 202
160 203 qreal ChartAxis::labelsOpacity() const
161 204 {
162 205 return m_labels->opacity();
163 206 }
164 207
165 208 void ChartAxis::setShadesOpacity(qreal opacity)
166 209 {
167 210 m_shades->setOpacity(opacity);
168 211 }
169 212
170 213 qreal ChartAxis::shadesOpacity() const
171 214 {
172 215 return m_shades->opacity();
173 216 }
174 217
175 218 void ChartAxis::setLabelsAngle(int angle)
176 219 {
177 220 foreach(QGraphicsItem* item , m_labels->childItems()) {
178 221 item->setRotation(angle);
179 222 }
180 223
181 224 m_labelsAngle=angle;
182 225 }
183 226
184 227 void ChartAxis::setLabelsPen(const QPen &pen)
185 228 {
186 229 foreach(QGraphicsItem* item , m_labels->childItems()) {
187 230 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
188 231 }
189 232 }
190 233
191 234 void ChartAxis::setLabelsBrush(const QBrush &brush)
192 235 {
193 236 foreach(QGraphicsItem* item , m_labels->childItems()) {
194 237 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
195 238 }
196 239 }
197 240
198 241 void ChartAxis::setLabelsFont(const QFont &font)
199 242 {
200 243 foreach(QGraphicsItem* item , m_labels->childItems()) {
201 244 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
202 245 }
203 246 }
204 247
205 248 void ChartAxis::setShadesBrush(const QBrush &brush)
206 249 {
207 250 foreach(QGraphicsItem* item , m_shades->childItems()) {
208 251 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
209 252 }
210 253 }
211 254
212 255 void ChartAxis::setShadesPen(const QPen &pen)
213 256 {
214 257 foreach(QGraphicsItem* item , m_shades->childItems()) {
215 258 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
216 259 }
217 260 }
218 261
219 262 void ChartAxis::setAxisPen(const QPen &pen)
220 263 {
221 264 foreach(QGraphicsItem* item , m_axis->childItems()) {
222 265 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
223 266 }
224 267 }
225 268
226 269 void ChartAxis::setGridPen(const QPen &pen)
227 270 {
228 271 foreach(QGraphicsItem* item , m_grid->childItems()) {
229 272 static_cast<QGraphicsLineItem*>(item)->setPen(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;
383 279 }
384 280
385 281 //handlers
386 282
387 283 void ChartAxis::handleAxisCategoriesUpdated()
388 284 {
389 285 if (isEmpty()) return;
390 286 updateLayout(m_layoutVector);
391 287 }
392 288
393 289 void ChartAxis::handleAxisUpdated()
394 290 {
395 291
396 292 if (isEmpty()) return;
397 293
398 294 if (m_chartAxis->isAxisVisible()) {
399 295 setAxisOpacity(100);
400 296 } else {
401 297 setAxisOpacity(0);
402 298 }
403 299
404 300 if (m_chartAxis->isGridLineVisible()) {
405 301 setGridOpacity(100);
406 302 } else {
407 303 setGridOpacity(0);
408 304 }
409 305
410 306 if (m_chartAxis->labelsVisible()) {
411 307 setLabelsOpacity(100);
412 308 } else {
413 309 setLabelsOpacity(0);
414 310 }
415 311
416 312 if (m_chartAxis->shadesVisible()) {
417 313 setShadesOpacity(m_chartAxis->shadesOpacity());
418 314 } else {
419 315 setShadesOpacity(0);
420 316 }
421 317
422 318 setLabelsAngle(m_chartAxis->labelsAngle());
423 319 setAxisPen(m_chartAxis->axisPen());
424 320 setLabelsPen(m_chartAxis->labelsPen());
425 321 setLabelsBrush(m_chartAxis->labelsBrush());
426 322 setLabelsFont(m_chartAxis->labelsFont());
427 323 setGridPen(m_chartAxis->gridLinePen());
428 324 setShadesPen(m_chartAxis->shadesPen());
429 325 setShadesBrush(m_chartAxis->shadesBrush());
430 326
431 327 }
432 328
433 329 void ChartAxis::handleRangeChanged(qreal min, qreal max,int tickCount)
434 330 {
435 331 if (qFuzzyIsNull(min - max) || tickCount < 2)
436 332 return;
437 333
438 334 m_min = min;
439 335 m_max = max;
440 336 m_ticksCount= tickCount;
441 337
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)
449 344 {
450 345 if(m_rect != rect)
451 346 {
452 347 m_rect = rect;
453 348 if (isEmpty()) return;
454 349 QVector<qreal> layout = calculateLayout();
455 350 updateLayout(layout);
456 351 }
457 352 }
458 353
459 354 void ChartAxis::axisSelected()
460 355 {
461 356 qDebug()<<"TODO: axis clicked";
462 357 }
463 358
464 359 #include "moc_chartaxis_p.cpp"
465 360
466 361 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,143 +1,148
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 #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
29 30
30 31 class QAxis;
31 32 class ChartPresenter;
32 33
33 34 class ChartAxis : public Chart
34 35 {
35 36 Q_OBJECT
36 37 public:
37 enum AxisType{X_AXIS,Y_AXIS};
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;
46 47
47 48 void setGridOpacity(qreal opacity);
48 49 qreal gridOpacity() const;
49 50
50 51 void setLabelsOpacity(qreal opacity);
51 52 qreal labelsOpacity() const;
52 53
53 54 void setShadesOpacity(qreal opacity);
54 55 qreal shadesOpacity() const;
55 56
56 57 void setLabelsAngle(int angle);
57 58 int labelsAngle()const { return m_labelsAngle; }
58 59
59 60 void setShadesBrush(const QBrush &brush);
60 61 void setShadesPen(const QPen &pen);
61 62
62 63 void setAxisPen(const QPen &pen);
63 64 void setGridPen(const QPen &pen);
64 65
65 66 void setLabelsPen(const QPen &pen);
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();
74 85 void handleAxisCategoriesUpdated();
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;
97 101 QScopedPointer<QGraphicsItemGroup> m_shades;
98 102 QScopedPointer<QGraphicsItemGroup> m_labels;
99 103 QScopedPointer<QGraphicsItemGroup> m_axis;
100 104 QVector<qreal> m_layoutVector;
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;
107 112
108 113 };
109 114
110 115 class AxisItem: public QGraphicsLineItem
111 116 {
112 117
113 118 public:
114 119 explicit AxisItem(ChartAxis *axis, QGraphicsItem *parent = 0) : QGraphicsLineItem(parent), m_axis(axis) {}
115 120
116 121 protected:
117 122 void mousePressEvent(QGraphicsSceneMouseEvent *event)
118 123 {
119 124 Q_UNUSED(event)
120 125 m_axis->axisSelected();
121 126 }
122 127
123 128 QRectF boundingRect() const
124 129 {
125 130 return shape().boundingRect();
126 131 }
127 132
128 133 QPainterPath shape() const
129 134 {
130 135 QPainterPath path = QGraphicsLineItem::shape();
131 136 QRectF rect = path.boundingRect();
132 137 path.addRect(rect.adjusted(0,0,m_axis->axisType()!=ChartAxis::X_AXIS?8:0,m_axis->axisType()!=ChartAxis::Y_AXIS?8:0));
133 138 return path;
134 139 }
135 140
136 141 private:
137 142 ChartAxis* m_axis;
138 143
139 144 };
140 145
141 146 QTCOMMERCIALCHART_END_NAMESPACE
142 147
143 148 #endif /* AXISITEM_H_ */
@@ -1,414 +1,430
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #include "chartpresenter_p.h"
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "qaxis.h"
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
35 39 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
36 40 m_chart(chart),
37 41 m_animator(0),
38 42 m_dataset(dataset),
39 43 m_chartTheme(0),
40 44 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),
47 52 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()
54 60 {
55 61 delete m_chartTheme;
56 62 }
57 63
58 64 void ChartPresenter::setGeometry(const QRectF& rect)
59 65 {
60 66 m_rect = rect;
61 67 Q_ASSERT(m_rect.isValid());
62 68 updateLayout();
63 69 }
64 70
65 71 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
66 72 {
67 73 switch(axis->axisType()){
68 74 case ChartAxis::X_AXIS:
69 75 {
70 76 if(width>m_chartRect.width()+ m_chartMargins.left()) {
71 77 m_minLeftMargin= width - m_chartRect.width();
72 78 updateLayout();
73 79 }
74 80 break;
75 81 }
76 82 case ChartAxis::Y_AXIS:
77 83 {
78 84
79 85 if(m_minLeftMargin!=width){
80 86 m_minLeftMargin= width;
81 87 updateLayout();
82 88 }
83 89 break;
84 90 }
85 91
86 92 }
87 93 }
88 94
89 95 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
90 96 {
91 97 switch(axis->axisType()){
92 98 case ChartAxis::X_AXIS:
93 99 {
94 100 if(m_minBottomMargin!=height) {
95 101 m_minBottomMargin= height;
96 102 updateLayout();
97 103 }
98 104 break;
99 105 }
100 106 case ChartAxis::Y_AXIS:
101 107 {
102 108
103 109 if(height>m_chartMargins.bottom()+m_chartRect.height()){
104 110 m_minBottomMargin= height - m_chartRect.height();
105 111 updateLayout();
106 112 }
107 113 break;
108 114 }
109 115
110 116 }
111 117 }
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()){
122 135 m_chartTheme->decorate(axis,true);
123 136 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
124 137 //initialize
125 138 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
126 139
127 140 }
128 141 else{
129 142 m_chartTheme->decorate(axis,false);
130 143 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
131 144 //initialize
132 145 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
133 146 }
134 147
135 148 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
136 149 //initialize
137 150 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
138 151 m_axisItems.insert(axis, item);
139 152 }
140 153
141 154 void ChartPresenter::handleAxisRemoved(QAxis* axis)
142 155 {
143 156 ChartAxis* item = m_axisItems.take(axis);
144 157 Q_ASSERT(item);
145 158 if(m_animator) m_animator->removeAnimation(item);
146 159 delete item;
147 160 }
148 161
149 162
150 163 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
151 164 {
152 165 Chart *item = series->d_ptr->createGraphics(this);
153 166 Q_ASSERT(item);
154 167 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
155 168 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
156 169 //initialize
157 170 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
158 171 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
159 172 m_chartItems.insert(series,item);
160 173 }
161 174
162 175 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
163 176 {
164 177 Chart* item = m_chartItems.take(series);
165 178 Q_ASSERT(item);
166 179 if(m_animator) {
167 180 //small hack to handle area animations
168 181 if(series->type() == QAbstractSeries::SeriesTypeArea){
169 182 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
170 183 AreaChartItem* area = static_cast<AreaChartItem*>(item);
171 184 m_animator->removeAnimation(area->upperLineItem());
172 185 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
173 186 }else
174 187 m_animator->removeAnimation(item);
175 188 }
176 189 delete item;
177 190 }
178 191
179 192 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
180 193 {
181 194 if(m_chartTheme && m_chartTheme->id() == theme) return;
182 195 delete m_chartTheme;
183 196 m_chartTheme = ChartTheme::createTheme(theme);
184 197 m_chartTheme->setForced(force);
185 198 m_chartTheme->decorate(m_chart);
186 199 m_chartTheme->decorate(m_chart->legend());
187 200 resetAllElements();
188 201
189 202 // We do not want "force" to stay on.
190 203 // Bar/pie are calling decorate when adding/removing slices/bars which means
191 204 // that to preserve users colors "force" must not be on.
192 205 m_chartTheme->setForced(false);
193 206 }
194 207
195 208 QChart::ChartTheme ChartPresenter::theme()
196 209 {
197 210 return m_chartTheme->id();
198 211 }
199 212
200 213 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
201 214 {
202 215 if(m_options!=options) {
203 216
204 217 m_options=options;
205 218
206 219 if(m_options!=QChart::NoAnimation && !m_animator) {
207 220 m_animator= new ChartAnimator(this);
208 221 }
209 222 resetAllElements();
210 223 }
211 224
212 225 }
213 226
214 227 void ChartPresenter::resetAllElements()
215 228 {
216 229 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
217 230 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
218 231
219 232 foreach(QAxis *axis, axisList) {
220 233 handleAxisRemoved(axis);
221 234 handleAxisAdded(axis,m_dataset->domain(axis));
222 235 }
223 236 foreach(QAbstractSeries *series, seriesList) {
224 237 handleSeriesRemoved(series);
225 238 handleSeriesAdded(series,m_dataset->domain(series));
226 239 // m_dataset->removeSeries(series);
227 240 // m_dataset->addSeries(series);
228 241 }
229 242 }
230 243
231 244 void ChartPresenter::zoomIn(qreal factor)
232 245 {
233 246 QRectF rect = chartGeometry();
234 247 rect.setWidth(rect.width()/factor);
235 248 rect.setHeight(rect.height()/factor);
236 249 rect.moveCenter(chartGeometry().center());
237 250 zoomIn(rect);
238 251 }
239 252
240 253 void ChartPresenter::zoomIn(const QRectF& rect)
241 254 {
242 255 QRectF r = rect.normalized();
243 256 r.translate(-m_chartMargins.topLeft());
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());
265 272
266 273 QRectF rect;
267 274 rect.setSize(chartRect.size()/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
295 296 {
296 297 return m_options;
297 298 }
298 299
299 300 void ChartPresenter::updateLayout()
300 301 {
301 302 if (!m_rect.isValid()) return;
302 303
303 304 // recalculate title size
304 305
305 306 QSize titleSize;
306 307 int titlePadding=0;
307 308
308 309 if (m_titleItem) {
309 310 titleSize= m_titleItem->boundingRect().size().toSize();
310 311 }
311 312
312 313 //defaults
313 314 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));
314 315 titlePadding = m_chartMargins.top()/2;
315 316
316 317 QLegend* legend = m_chart->d_ptr->m_legend;
317 318
318 319 // recalculate legend position
319 320 if (legend->isAttachedToChart() && legend->isEnabled()) {
320 321
321 322 QRect legendRect;
322 323
323 324 // Reserve some space for legend
324 325 switch (legend->alignment()) {
325 326
326 327 case QLegend::AlignmentTop: {
327 328 int ledgendSize = legend->minHeight();
328 329 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
329 330 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
330 331 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
331 332 titlePadding = m_marginTiny + m_marginTiny;
332 333 break;
333 334 }
334 335 case QLegend::AlignmentBottom: {
335 336 int ledgendSize = legend->minHeight();
336 337 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
337 338 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
338 339 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
339 340 titlePadding = m_chartMargins.top()/2;
340 341 break;
341 342 }
342 343 case QLegend::AlignmentLeft: {
343 344 int ledgendSize = legend->minWidth();
344 345 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
345 346 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
346 347 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
347 348 titlePadding = m_chartMargins.top()/2;
348 349 break;
349 350 }
350 351 case QLegend::AlignmentRight: {
351 352 int ledgendSize = legend->minWidth();
352 353 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
353 354 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
354 355 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
355 356 titlePadding = m_chartMargins.top()/2;
356 357 break;
357 358 }
358 359 default: {
359 360 break;
360 361 }
361 362 }
362 363 }
363 364
364 365 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
365 366 {
366 367 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
367 368 return;
368 369 }
369 370
370 371
371 372 // recalculate title position
372 373 if (m_titleItem) {
373 374 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
374 375 m_titleItem->setPos(center.x(),titlePadding);
375 376 }
376 377
377 378 //recalculate background gradient
378 379 if (m_backgroundItem) {
379 380 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
380 381 }
381 382
382 383
383 384 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
384 385
385 386 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
386 387
387 388 if(m_chartRect!=chartRect && chartRect.isValid()){
388 389 m_chartRect=chartRect;
389 390 emit geometryChanged(m_chartRect);
390 391 }
391 392
392
393 393 }
394 394
395 395 void ChartPresenter::createChartBackgroundItem()
396 396 {
397 397 if (!m_backgroundItem) {
398 398 m_backgroundItem = new ChartBackground(rootItem());
399 399 m_backgroundItem->setPen(Qt::NoPen);
400 400 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
401 401 }
402 402 }
403 403
404 404 void ChartPresenter::createChartTitleItem()
405 405 {
406 406 if (!m_titleItem) {
407 407 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
408 408 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
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
@@ -1,124 +1,142
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef CHARTPRESENTER_H
22 22 #define CHARTPRESENTER_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
26 26 #include <QRectF>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class Chart;
31 31 class QAbstractSeries;
32 32 class ChartDataSet;
33 33 class Domain;
34 34 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 {
41 42 Q_OBJECT
42 43 public:
43 44 enum ZValues {
44 45 BackgroundZValue = -1,
45 46 ShadesZValue,
46 47 GridZValue,
47 48 LineChartZValue,
48 49 BarSeriesZValue,
49 50 ScatterSeriesZValue,
50 51 PieSeriesZValue,
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();
57 66
58 67 ChartAnimator* animator() const { return m_animator; }
59 68 ChartTheme *chartTheme() const { return m_chartTheme; }
60 69 ChartDataSet *dataSet() const { return m_dataset; }
61 70 QGraphicsItem* rootItem() const { return m_chart; }
62 71
63 72 void setTheme(QChart::ChartTheme theme,bool force = true);
64 73 QChart::ChartTheme theme();
65 74
66 75 void setAnimationOptions(QChart::AnimationOptions options);
67 76 QChart::AnimationOptions animationOptions() const;
68 77
69 78 void zoomIn(qreal factor);
70 79 void zoomIn(const QRectF& rect);
71 80 void zoomOut(qreal factor);
72 81 void scroll(int dx,int dy);
73 82
74 83 void setGeometry(const QRectF& rect);
75 84 QRectF chartGeometry() const { return m_chartRect; }
76 85
77 86 void setMinimumMarginHeight(ChartAxis* axis, qreal height);
78 87 void setMinimumMarginWidth(ChartAxis* axis, qreal width);
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();
85 97 void createChartTitleItem();
86 98 QRectF margins() const { return m_chartMargins;}
87 99
88 100 public Q_SLOTS:
89 101 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
90 102 void handleSeriesRemoved(QAbstractSeries* series);
91 103 void handleAxisAdded(QAxis* axis,Domain* domain);
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;
101 116 ChartAnimator* m_animator;
102 117 ChartDataSet* m_dataset;
103 118 ChartTheme *m_chartTheme;
104 119 QMap<QAbstractSeries *, Chart *> m_chartItems;
105 120 QMap<QAxis *, ChartAxis *> m_axisItems;
106 121 QRectF m_rect;
107 122 QRectF m_chartRect;
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;
114 133 int m_marginBig;
115 134 int m_marginSmall;
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
123 141
124 142 #endif /* CHARTPRESENTER_H_ */
@@ -1,164 +1,164
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "splinechartitem_p.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 25 #include <QPainter>
26 26 #include <QGraphicsSceneMouseEvent>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
31 31 XYChart(series, presenter),
32 32 QGraphicsItem(presenter ? presenter->rootItem() : 0),
33 33 m_series(series),
34 34 m_pointsVisible(false),
35 35 m_animation(0)
36 36 {
37 37 setZValue(ChartPresenter::LineChartZValue);
38 38 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
39 39 handleUpdated();
40 40 }
41 41
42 42 QRectF SplineChartItem::boundingRect() const
43 43 {
44 44 return m_rect;
45 45 }
46 46
47 47 QPainterPath SplineChartItem::shape() const
48 48 {
49 49 return m_path;
50 50 }
51 51
52 52 void SplineChartItem::setAnimation(SplineAnimation* animation)
53 53 {
54 54 m_animation=animation;
55 55 XYChart::setAnimation(animation);
56 56 }
57 57
58 58 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
59 59 {
60 60 m_controlPoints=points;
61 61 }
62 62
63 63 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
64 64 {
65 65 return m_controlPoints;
66 66 }
67 67
68 68 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
69 69 {
70 70 QVector<QPointF> controlPoints;
71 71
72 72 if(newPoints.count()>=2) {
73 73 controlPoints.resize(newPoints.count()*2-2);
74 74 }
75 75
76 76 for (int i = 0; i < newPoints.size() - 1; i++) {
77 77 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
78 78 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
79 79 }
80 80
81 81 if (controlPoints.count()<2) {
82 82 setGeometryPoints(newPoints);
83 83 setControlGeometryPoints(controlPoints);
84 84 updateGeometry();
85 85 return;
86 86 }
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);
94 94 setControlGeometryPoints(controlPoints);
95 95 updateGeometry();
96 96 }
97 97 }
98 98
99 99 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
100 100 {
101 101 return XYChart::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
102 102 }
103 103
104 104 void SplineChartItem::updateGeometry()
105 105 {
106 106 const QVector<QPointF> &points = geometryPoints();
107 107 const QVector<QPointF> &controlPoints = controlGeometryPoints();
108 108
109 109 if ((points.size()<2) || (controlPoints.size()<2)) {
110 110 m_path = QPainterPath();
111 111 return;
112 112 }
113 113
114 114 Q_ASSERT(points.count()*2-2 == controlPoints.count());
115 115
116 116 QPainterPath splinePath(points.at(0));
117 117
118 118 for (int i = 0; i < points.size() - 1; i++) {
119 119 const QPointF& point = points.at(i + 1);
120 120 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
121 121 }
122 122
123 123 prepareGeometryChange();
124 124 m_path = splinePath;
125 125 m_rect = splinePath.boundingRect();
126 126 setPos(origin());
127 127 }
128 128
129 129 //handlers
130 130
131 131 void SplineChartItem::handleUpdated()
132 132 {
133 133 m_pointsVisible = m_series->pointsVisible();
134 134 m_linePen = m_series->pen();
135 135 m_pointPen = m_series->pen();
136 136 m_pointPen.setWidthF(2*m_pointPen.width());
137 137 update();
138 138 }
139 139
140 140 //painter
141 141
142 142 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
143 143 {
144 144 Q_UNUSED(widget)
145 145 Q_UNUSED(option)
146 146 painter->save();
147 147 painter->setClipRect(clipRect());
148 148 painter->setPen(m_linePen);
149 149 painter->drawPath(m_path);
150 150 if (m_pointsVisible) {
151 151 painter->setPen(m_pointPen);
152 152 painter->drawPoints(geometryPoints());
153 153 }
154 154 painter->restore();
155 155 }
156 156
157 157 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
158 158 {
159 159 emit XYChart::clicked(calculateDomainPoint(event->pos()));
160 160 }
161 161
162 162 #include "moc_splinechartitem_p.cpp"
163 163
164 164 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,216 +1,251
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xychart_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartanimator_p.h"
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
32 33 //TODO: optimize : remove points which are not visible
33 34
34 35 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):Chart(presenter),
35 36 m_minX(0),
36 37 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)));
44 46 QObject::connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
45 47 QObject::connect(series->d_func(),SIGNAL(reinitialized()),this,SLOT(handleReinitialized()));
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 }
53 55
54 56 void XYChart::setClipRect(const QRectF &rect)
55 57 {
56 58 m_clipRect = rect;
57 59 }
58 60
59 61 void XYChart::setAnimation(XYAnimation* animation)
60 62 {
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);
67 74 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
68 75 qreal x = (point.x() - m_minX)* deltaX;
69 76 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
70 77 return QPointF(x,y);
71 78 }
72 79
73 80 QPointF XYChart::calculateGeometryPoint(int index) const
74 81 {
75 82 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
76 83 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
77 84 const QList<QPointF>& vector = m_series->points();
78 85 qreal x = (vector[index].x() - m_minX)* deltaX;
79 86 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
80 87 return QPointF(x,y);
81 88 }
82 89
83 90 QVector<QPointF> XYChart::calculateGeometryPoints() const
84 91 {
85 92 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
86 93 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
87 94
88 95 QVector<QPointF> result;
89 96 result.resize(m_series->count());
90 97 const QList<QPointF>& vector = m_series->points();
91 98 for (int i = 0; i < m_series->count(); ++i) {
92 99 qreal x = (vector[i].x() - m_minX)* deltaX;
93 100 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
94 101 result[i].setX(x);
95 102 result[i].setY(y);
96 103 }
97 104 return result;
98 105 }
99 106
100 107 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
101 108 {
102 109 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
103 110 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
104 111 qreal x = point.x()/deltaX +m_minX;
105 112 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
106 113 return QPointF(x,y);
107 114 }
108 115
109 116 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
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);
117 126 updateGeometry();
118 127 }
119 128 }
120 129
121 130 //handlers
122 131
123 132 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);
131 136
132 if(m_animation) {
133 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
134 }
137 QVector<QPointF> points;
138
139 if(m_animation) {
140 m_animation->setAnimationType(XYAnimation::AddPointAnimation);
141 }
135 142
136 updateChart(m_points,points,index);
143 if(m_dirty) {
144 points = calculateGeometryPoints();
145 } else {
146 points = m_points;
147 QPointF point = calculateGeometryPoint(index);
148 points.insert(index, point);
149 }
150
151 updateChart(m_points,points,index);
137 152 }
138 153
139 154 void XYChart::handlePointRemoved(int index)
140 155 {
141 Q_ASSERT(index<m_series->count() + 1);
142 Q_ASSERT(index>=0);
143 QVector<QPointF> points = m_points;
144 points.remove(index);
156 Q_ASSERT(index<=m_series->count());
157 Q_ASSERT(index>=0);
145 158
146 if(m_animation) {
147 m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
148 }
159 QVector<QPointF> points;
149 160
150 updateChart(m_points,points,index);
161 if(m_animation) {
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);
170 }
171
172 updateChart(m_points,points,index);
151 173 }
152 174
153 175 void XYChart::handlePointReplaced(int index)
154 176 {
155 Q_ASSERT(index<m_series->count());
156 Q_ASSERT(index>=0);
157 QPointF point = calculateGeometryPoint(index);
158 QVector<QPointF> points = m_points;
159 points.replace(index,point);
177 Q_ASSERT(index<m_series->count());
178 Q_ASSERT(index>=0);
160 179
161 if(m_animation) {
162 m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
163 }
180 QVector<QPointF> points;
164 181
165 updateChart(m_points,points,index);
182 if(m_animation) {
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);
192 }
193
194 updateChart(m_points,points,index);
166 195 }
167 196
168 197 void XYChart::handleReinitialized()
169 198 {
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);
177 206 }
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
194 226 void XYChart::handleGeometryChanged(const QRectF &rect)
195 227 {
196 228 Q_ASSERT(rect.isValid());
197 229 m_size=rect.size();
198 230 m_clipRect=rect.translated(-rect.topLeft());
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);
205 }
238 m_animation->setAnimationType(XYAnimation::NewAnimation);
239 }
240
206 241 updateChart(m_points,points);
207 242 }
208 243
209 244 bool XYChart::isEmpty()
210 245 {
211 246 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
212 247 }
213 248
214 249 #include "moc_xychart_p.cpp"
215 250
216 251 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,93 +1,97
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef XYCHARTITEM_H
22 22 #define XYCHARTITEM_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "chartitem_p.h"
26 26 #include "xyanimation_p.h"
27 27 #include <QPen>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class ChartPresenter;
32 32 class QXYSeries;
33 33
34 34 class XYChart : public Chart
35 35 {
36 36 Q_OBJECT
37 37 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);
45 45 QRectF clipRect() const { return m_clipRect; }
46 46
47 47 QSizeF size() const { return m_size; }
48 48 QPointF origin() const { return m_origin; }
49 49
50 50 void setAnimation(XYAnimation* animation);
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);
57 60 void handlePointReplaced(int index);
58 61 void handleReinitialized();
59 62 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
60 63 void handleGeometryChanged(const QRectF &size);
61 64
62 65 Q_SIGNALS:
63 66 void clicked(const QPointF& point);
64 67
65 68 protected:
66 69 virtual void updateChart(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = 0);
67 70 QPointF calculateGeometryPoint(const QPointF &point) const;
68 71 QPointF calculateGeometryPoint(int index) const;
69 72 QPointF calculateDomainPoint(const QPointF &point) const;
70 73 QVector<QPointF> calculateGeometryPoints() const;
71 74
72 75 private:
73 76 inline bool isEmpty();
74 77
75 78 private:
76 79 qreal m_minX;
77 80 qreal m_maxX;
78 81 qreal m_minY;
79 82 qreal m_maxY;
80 83 QXYSeries* m_series;
81 84 QSizeF m_size;
82 85 QPointF m_origin;
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
89 93 };
90 94
91 95 QTCOMMERCIALCHART_END_NAMESPACE
92 96
93 97 #endif
General Comments 0
You need to be logged in to leave comments. Login now