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