@@ -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 |
|
|
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 |
|
|
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( |
|
|
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 |
|
|
|
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 |
|
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 |
|
|
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 |
|
|
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 { |
|
|
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 |
|
|
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 |
|
|
|
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> |
|
|
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 |
|
|
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; |
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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() |
|
169 | 198 | { |
|
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); |
|
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:: |
|
|
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:: |
|
|
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