##// END OF EJS Templates
Refactor animator...
Michal Klocek -
r1735:0a19606ca1b1
parent child
Show More
@@ -1,33 +1,31
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/axisanimation.cpp \
6 $$PWD/chartanimator.cpp \
7 6 $$PWD/xyanimation.cpp \
8 7 $$PWD/pieanimation.cpp \
9 8 $$PWD/piesliceanimation.cpp \
10 9 $$PWD/splineanimation.cpp \
11 10 $$PWD/baranimation.cpp \
12 11 $$PWD/stackedbaranimation.cpp \
13 12 $$PWD/percentbaranimation.cpp \
14 13 $$PWD/abstractbaranimation.cpp \
15 14 $$PWD/horizontalbaranimation.cpp \
16 15 $$PWD/horizontalstackedbaranimation.cpp \
17 16 $$PWD/horizontalpercentbaranimation.cpp
18 17
19 18 PRIVATE_HEADERS += \
20 19 $$PWD/axisanimation_p.h \
21 $$PWD/chartanimator_p.h \
22 20 $$PWD/chartanimation_p.h \
23 21 $$PWD/xyanimation_p.h \
24 22 $$PWD/pieanimation_p.h \
25 23 $$PWD/piesliceanimation_p.h \
26 24 $$PWD/splineanimation_p.h \
27 25 $$PWD/baranimation_p.h \
28 26 $$PWD/stackedbaranimation_p.h \
29 27 $$PWD/percentbaranimation_p.h \
30 28 $$PWD/abstractbaranimation_p.h \
31 29 $$PWD/horizontalbaranimation_p.h \
32 30 $$PWD/horizontalstackedbaranimation_p.h \
33 31 $$PWD/horizontalpercentbaranimation_p.h
@@ -1,100 +1,101
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 "pieanimation_p.h"
22 22 #include "piesliceanimation_p.h"
23 23 #include "piechartitem_p.h"
24 24 #include <QTimer>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 PieAnimation::PieAnimation(PieChartItem *item)
29 29 :ChartAnimation(item),
30 30 m_item(item)
31 31 {
32 32 }
33 33
34 34 PieAnimation::~PieAnimation()
35 35 {
36 36 }
37 37
38 void PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
38 ChartAnimation* PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
39 39 {
40 40 PieSliceAnimation *animation = m_animations.value(sliceItem);
41 41 Q_ASSERT(animation);
42 42 animation->stop();
43 43
44 44 animation->updateValue(sliceData);
45 45 animation->setDuration(ChartAnimationDuration);
46 46 animation->setEasingCurve(QEasingCurve::OutQuart);
47 47
48 QTimer::singleShot(0, animation, SLOT(start()));
48 return animation;
49 49 }
50 50
51 void PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
51 ChartAnimation* PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
52 52 {
53 53 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
54 54 m_animations.insert(sliceItem, animation);
55 55
56 56 PieSliceData startValue = sliceData;
57 57 startValue.m_radius = 0;
58 58 if (startupAnimation)
59 59 startValue.m_startAngle = 0;
60 60 else
61 61 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan / 2);
62 62 startValue.m_angleSpan = 0;
63 63 animation->setValue(startValue, sliceData);
64 64
65 65 animation->setDuration(ChartAnimationDuration);
66 66 animation->setEasingCurve(QEasingCurve::OutQuart);
67 QTimer::singleShot(0, animation, SLOT(start()));
67
68 return animation;
68 69 }
69 70
70 void PieAnimation::removeSlice(PieSliceItem *sliceItem)
71 ChartAnimation* PieAnimation::removeSlice(PieSliceItem *sliceItem)
71 72 {
72 73 PieSliceAnimation *animation = m_animations.value(sliceItem);
73 74 Q_ASSERT(animation);
74 75 animation->stop();
75 76
76 77 PieSliceData endValue = animation->currentSliceValue();
77 78 endValue.m_radius = 0;
78 79 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
79 80 endValue.m_angleSpan = 0;
80 81 endValue.m_isLabelVisible = false;
81 82
82 83 animation->updateValue(endValue);
83 84 animation->setDuration(ChartAnimationDuration);
84 85 animation->setEasingCurve(QEasingCurve::OutQuart);
85 86
86 87 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
87 88 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
88 89 m_animations.remove(sliceItem);
89 90
90 QTimer::singleShot(0, animation, SLOT(start()));
91 return animation;
91 92 }
92 93
93 94 void PieAnimation::updateCurrentValue(const QVariant &)
94 95 {
95 96 // nothing to do...
96 97 }
97 98
98 99 #include "moc_pieanimation_p.cpp"
99 100
100 101 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,62 +1,62
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef PIEANIMATION_P_H
31 31 #define PIEANIMATION_P_H
32 32
33 33 #include "chartanimation_p.h"
34 34 #include "piechartitem_p.h"
35 35 #include "piesliceanimation_p.h"
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class PieChartItem;
40 40
41 41 class PieAnimation : public ChartAnimation
42 42 {
43 43 Q_OBJECT
44 44
45 45 public:
46 46 PieAnimation(PieChartItem *item);
47 47 ~PieAnimation();
48 void updateValue(PieSliceItem *sliceItem, const PieSliceData &newValue);
49 void addSlice(PieSliceItem *sliceItem, const PieSliceData &endValue, bool startupAnimation);
50 void removeSlice(PieSliceItem *sliceItem);
48 ChartAnimation* updateValue(PieSliceItem *sliceItem, const PieSliceData &newValue);
49 ChartAnimation* addSlice(PieSliceItem *sliceItem, const PieSliceData &endValue, bool startupAnimation);
50 ChartAnimation* removeSlice(PieSliceItem *sliceItem);
51 51
52 52 public: // from QVariantAnimation
53 53 void updateCurrentValue(const QVariant &value);
54 54
55 55 private:
56 56 PieChartItem *m_item;
57 57 QHash<PieSliceItem *, PieSliceAnimation *> m_animations;
58 58 };
59 59
60 60 QTCOMMERCIALCHART_END_NAMESPACE
61 61
62 62 #endif
@@ -1,125 +1,125
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 "piesliceanimation_p.h"
22 22 #include "piechartitem_p.h"
23 23
24 24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 qreal linearPos(qreal start, qreal end, qreal pos)
29 29 {
30 30 return start + ((end - start) * pos);
31 31 }
32 32
33 33 QPointF linearPos(QPointF start, QPointF end, qreal pos)
34 34 {
35 35 qreal x = linearPos(start.x(), end.x(), pos);
36 36 qreal y = linearPos(start.y(), end.y(), pos);
37 37 return QPointF(x, y);
38 38 }
39 39
40 40 QPen linearPos(QPen start, QPen end, qreal pos)
41 41 {
42 42 QColor c;
43 43 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
44 44 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
45 45 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
46 46 end.setColor(c);
47 47 return end;
48 48 }
49 49
50 50 QBrush linearPos(QBrush start, QBrush end, qreal pos)
51 51 {
52 52 QColor c;
53 53 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
54 54 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
55 55 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
56 56 end.setColor(c);
57 57 return end;
58 58 }
59 59
60 60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
61 :QVariantAnimation(sliceItem),
61 :ChartAnimation(sliceItem),
62 62 m_sliceItem(sliceItem)
63 63 {
64 64 }
65 65
66 66 PieSliceAnimation::~PieSliceAnimation()
67 67 {
68 68 }
69 69
70 70 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
71 71 {
72 72 if (state() != QAbstractAnimation::Stopped)
73 73 stop();
74 74
75 75 m_currentValue = startValue;
76 76
77 77 setKeyValueAt(0.0, qVariantFromValue(startValue));
78 78 setKeyValueAt(1.0, qVariantFromValue(endValue));
79 79 }
80 80
81 81 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
82 82 {
83 83 if (state() != QAbstractAnimation::Stopped)
84 84 stop();
85 85
86 86 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
87 87 setKeyValueAt(1.0, qVariantFromValue(endValue));
88 88 }
89 89
90 90 PieSliceData PieSliceAnimation::currentSliceValue()
91 91 {
92 92 // NOTE:
93 93 // We must use an internal current value because QVariantAnimation::currentValue() is updated
94 94 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
95 95 // will have the end value set from the first call and the second call will interpolate that instead of
96 96 // the original current value as it was before the first call.
97 97 return m_currentValue;
98 98 }
99 99
100 100 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
101 101 {
102 102 PieSliceData startValue = qVariantValue<PieSliceData>(start);
103 103 PieSliceData endValue = qVariantValue<PieSliceData>(end);
104 104
105 105 PieSliceData result;
106 106 result = endValue;
107 107 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
108 108 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
109 109 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
110 110 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
111 111 result.m_slicePen = linearPos(startValue.m_slicePen, endValue.m_slicePen, progress);
112 112 result.m_sliceBrush = linearPos(startValue.m_sliceBrush, endValue.m_sliceBrush, progress);
113 113
114 114 return qVariantFromValue(result);
115 115 }
116 116
117 117 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
118 118 {
119 119 if (state() != QAbstractAnimation::Stopped) { //workaround
120 120 m_currentValue = qVariantValue<PieSliceData>(value);
121 121 m_sliceItem->setLayout(m_currentValue);
122 122 }
123 123 }
124 124
125 125 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,60 +1,60
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef PIESLICEANIMATION_P_H
31 31 #define PIESLICEANIMATION_P_H
32 32
33 #include <QVariantAnimation>
33 #include "chartanimation_p.h"
34 34 #include "piesliceitem_p.h"
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class PieChartItem;
39 39
40 class PieSliceAnimation : public QVariantAnimation
40 class PieSliceAnimation : public ChartAnimation
41 41 {
42 42 public:
43 43 PieSliceAnimation(PieSliceItem *sliceItem);
44 44 ~PieSliceAnimation();
45 45 void setValue(const PieSliceData &startValue, const PieSliceData &endValue);
46 46 void updateValue(const PieSliceData &endValue);
47 47 PieSliceData currentSliceValue();
48 48
49 49 protected:
50 50 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
51 51 void updateCurrentValue(const QVariant &value);
52 52
53 53 private:
54 54 PieSliceItem *m_sliceItem;
55 55 PieSliceData m_currentValue;
56 56 };
57 57
58 58 QTCOMMERCIALCHART_END_NAMESPACE
59 59
60 60 #endif
@@ -1,399 +1,396
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 "qareaseries.h"
22 22 #include "qareaseries_p.h"
23 23 #include "qlineseries.h"
24 24 #include "areachartitem_p.h"
25 25 #include "legendmarker_p.h"
26 26 #include "domain_p.h"
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
30 29 #include "qvaluesaxis.h"
31 30
32 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 32
34 33 /*!
35 34 \class QAreaSeries
36 35 \brief The QAreaSeries class is used for making area charts.
37 36
38 37 \mainclass
39 38
40 39 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
41 40 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
42 41 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line.
43 42 In that case QAreaSeries should be initiated with two QLineSeries instances. Please note terms "upper" and "lower" boundary can be misleading in cases
44 43 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled.
45 44
46 45 See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart.
47 46 \image examples_areachart.png
48 47 */
49 48 /*!
50 49 \qmlclass AreaSeries QAreaSeries
51 50
52 51 The following QML shows how to create a simple area chart:
53 52 \snippet ../demos/qmlchart/qml/qmlchart/View4.qml 1
54 53 \beginfloatleft
55 54 \image demos_qmlchart4.png
56 55 \endfloat
57 56 \clearfloat
58 57 */
59 58
60 59 /*!
61 60 \property QAreaSeries::upperSeries
62 61 \brief The upper one of the two line series used to define area series boundaries.
63 62 */
64 63 /*!
65 64 \qmlproperty LineSeries AreaSeries::upperSeries
66 65 The upper one of the two line series used to define area series boundaries.
67 66 */
68 67
69 68 /*!
70 69 \property QAreaSeries::lowerSeries
71 70 The lower one of the two line series used to define are series boundaries. Note if
72 71 QAreaSeries was counstucted wihtout a\ lowerSeries this is null.
73 72 */
74 73 /*!
75 74 \qmlproperty LineSeries AreaSeries::lowerSeries
76 75 The lower one of the two line series used to define are series boundaries. Note if
77 76 AreaSeries was counstucted wihtout a\ lowerSeries this is null.
78 77 */
79 78
80 79 /*!
81 80 \property QAreaSeries::color
82 81 Fill (brush) color of the series. This is a convenience property for modifying the color of brush.
83 82 \sa QAreaSeries::brush()
84 83 */
85 84 /*!
86 85 \qmlproperty color AreaSeries::color
87 86 Fill (brush) color of the series.
88 87 */
89 88
90 89 /*!
91 90 \property QAreaSeries::borderColor
92 91 Line (pen) color of the series. This is a convenience property for modifying the color of pen.
93 92 \sa QAreaSeries::pen()
94 93 */
95 94 /*!
96 95 \qmlproperty color AreaSeries::borderColor
97 96 Line (pen) color of the series.
98 97 */
99 98
100 99 /*!
101 100 \fn QPen QAreaSeries::pen() const
102 101 \brief Returns the pen used to draw line for this series.
103 102 \sa setPen()
104 103 */
105 104
106 105 /*!
107 106 \fn QPen QAreaSeries::brush() const
108 107 \brief Returns the brush used to draw line for this series.
109 108 \sa setBrush()
110 109 */
111 110
112 111 /*!
113 112 \fn void QAreaSeries::colorChanged(QColor color)
114 113 \brief Signal is emitted when the fill (brush) color has changed to \a color.
115 114 */
116 115 /*!
117 116 \qmlsignal AreaSeries::onColorChanged(color color)
118 117 Signal is emitted when the fill (brush) color has changed to \a color.
119 118 */
120 119
121 120 /*!
122 121 \fn void QAreaSeries::borderColorChanged(QColor color)
123 122 \brief Signal is emitted when the line (pen) color has changed to \a color.
124 123 */
125 124 /*!
126 125 \qmlsignal AreaSeries::onBorderColorChanged(color color)
127 126 Signal is emitted when the line (pen) color has changed to \a color.
128 127 */
129 128
130 129 /*!
131 130 \fn void QAreaSeries::clicked(const QPointF& point)
132 131 \brief Signal is emitted when user clicks the \a point on area chart.
133 132 */
134 133 /*!
135 134 \qmlsignal AreaSeries::onClicked(QPointF point)
136 135 Signal is emitted when user clicks the \a point on area chart.
137 136 */
138 137
139 138 /*!
140 139 \fn void QAreaSeries::selected()
141 140 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
142 141 implemented by the user of QAreaSeries API.
143 142 */
144 143 /*!
145 144 \qmlsignal AreaSeries::onSelected()
146 145 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
147 146 implemented by the user of AreaSeries API.
148 147 */
149 148
150 149 /*!
151 150 \fn void QAreaSeriesPrivate::updated()
152 151 \brief \internal
153 152 */
154 153
155 154 /*!
156 155 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
157 156 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
158 157 When series object is added to QChartView or QChart instance ownerships is transferred.
159 158 */
160 159 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
161 160 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
162 161 {
163 162 }
164 163
165 164 /*!
166 165 Constructs area series object without upper or lower series with \a parent object.
167 166 */
168 167 QAreaSeries::QAreaSeries(QObject *parent)
169 168 : QAbstractSeries(*new QAreaSeriesPrivate(0, 0, this), parent)
170 169 {
171 170 }
172 171
173 172 /*!
174 173 Destroys the object.
175 174 */
176 175 QAreaSeries::~QAreaSeries()
177 176 {
178 177 Q_D(QAreaSeries);
179 178 if(d->m_dataset){
180 179 d->m_dataset->removeSeries(this);
181 180 }
182 181 }
183 182
184 183 /*!
185 184 Returns QChartSeries::SeriesTypeArea.
186 185 */
187 186 QAbstractSeries::SeriesType QAreaSeries::type() const
188 187 {
189 188 return QAbstractSeries::SeriesTypeArea;
190 189 }
191 190
192 191 /*!
193 192 Sets the \a series that is to be used as the area chart upper series.
194 193 */
195 194 void QAreaSeries::setUpperSeries(QLineSeries* series)
196 195 {
197 196 Q_D(QAreaSeries);
198 197 d->m_upperSeries = series;
199 198 }
200 199
201 200 QLineSeries* QAreaSeries::upperSeries() const
202 201 {
203 202 Q_D(const QAreaSeries);
204 203 return d->m_upperSeries;
205 204 }
206 205
207 206 /*!
208 207 Sets the \a series that is to be used as the area chart lower series.
209 208 */
210 209 void QAreaSeries::setLowerSeries(QLineSeries* series)
211 210 {
212 211 Q_D(QAreaSeries);
213 212 d->m_lowerSeries = series;
214 213 }
215 214
216 215 QLineSeries* QAreaSeries::lowerSeries() const
217 216 {
218 217 Q_D(const QAreaSeries);
219 218 return d->m_lowerSeries;
220 219 }
221 220
222 221 /*!
223 222 Sets \a pen used for drawing area outline.
224 223 */
225 224 void QAreaSeries::setPen(const QPen &pen)
226 225 {
227 226 Q_D(QAreaSeries);
228 227 if (d->m_pen != pen) {
229 228 d->m_pen = pen;
230 229 emit d->updated();
231 230 }
232 231 }
233 232
234 233 QPen QAreaSeries::pen() const
235 234 {
236 235 Q_D(const QAreaSeries);
237 236 return d->m_pen;
238 237 }
239 238
240 239 /*!
241 240 Sets \a brush used for filling the area.
242 241 */
243 242 void QAreaSeries::setBrush(const QBrush &brush)
244 243 {
245 244 Q_D(QAreaSeries);
246 245 if (d->m_brush != brush) {
247 246 d->m_brush = brush;
248 247 emit d->updated();
249 248 }
250 249 }
251 250
252 251 QBrush QAreaSeries::brush() const
253 252 {
254 253 Q_D(const QAreaSeries);
255 254 return d->m_brush;
256 255 }
257 256
258 257 void QAreaSeries::setColor(const QColor &color)
259 258 {
260 259 QBrush b = brush();
261 260 if (b.color() != color) {
262 261 b.setColor(color);
263 262 setBrush(b);
264 263 emit colorChanged(color);
265 264 }
266 265 }
267 266
268 267 QColor QAreaSeries::color() const
269 268 {
270 269 return brush().color();
271 270 }
272 271
273 272 void QAreaSeries::setBorderColor(const QColor &color)
274 273 {
275 274 QPen p = pen();
276 275 if (p.color() != color) {
277 276 p.setColor(color);
278 277 setPen(p);
279 278 emit borderColorChanged(color);
280 279 }
281 280 }
282 281
283 282 QColor QAreaSeries::borderColor() const
284 283 {
285 284 return pen().color();
286 285 }
287 286
288 287 /*!
289 288 Sets if data points are \a visible and should be drawn on line.
290 289 */
291 290 void QAreaSeries::setPointsVisible(bool visible)
292 291 {
293 292 Q_D(QAreaSeries);
294 293 if (d->m_pointsVisible != visible) {
295 294 d->m_pointsVisible = visible;
296 295 emit d->updated();
297 296 }
298 297 }
299 298
300 299 /*!
301 300 Returns if the points are drawn for this series.
302 301 \sa setPointsVisible()
303 302 */
304 303 bool QAreaSeries::pointsVisible() const
305 304 {
306 305 Q_D(const QAreaSeries);
307 306 return d->m_pointsVisible;
308 307 }
309 308
310 309 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
311 310
312 311 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
313 312 QAbstractSeriesPrivate(q),
314 313 m_upperSeries(upperSeries),
315 314 m_lowerSeries(lowerSeries),
316 315 m_pointsVisible(false)
317 316 {
318 317 }
319 318
320 319 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
321 320 {
322 321 Q_Q(QAreaSeries);
323 322
324 323 qreal minX(domain.minX());
325 324 qreal minY(domain.minY());
326 325 qreal maxX(domain.maxX());
327 326 qreal maxY(domain.maxY());
328 327
329 328 QLineSeries* upperSeries = q->upperSeries();
330 329 QLineSeries* lowerSeries = q->lowerSeries();
331 330
332 331 const QList<QPointF>& points = upperSeries->points();
333 332
334 333 for (int i = 0; i < points.count(); i++)
335 334 {
336 335 qreal x = points[i].x();
337 336 qreal y = points[i].y();
338 337 minX = qMin(minX, x);
339 338 minY = qMin(minY, y);
340 339 maxX = qMax(maxX, x);
341 340 maxY = qMax(maxY, y);
342 341 }
343 342 if(lowerSeries) {
344 343
345 344 const QList<QPointF>& points = lowerSeries->points();
346 345
347 346 for (int i = 0; i < points.count(); i++)
348 347 {
349 348 qreal x = points[i].x();
350 349 qreal y = points[i].y();
351 350 minX = qMin(minX, x);
352 351 minY = qMin(minY, y);
353 352 maxX = qMax(maxX, x);
354 353 maxY = qMax(maxY, y);
355 354 }}
356 355
357 356 domain.setRange(minX,maxX,minY,maxY);
358 357 }
359 358
360 359 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
361 360 {
362 361 Q_Q(QAreaSeries);
363 362
364 363 AreaChartItem* area = new AreaChartItem(q,presenter);
365 364 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
366 area->upperLineItem()->setAnimator(presenter->animator());
367 365 area->upperLineItem()->setAnimation(new XYAnimation(area->upperLineItem()));
368 366 if(q->lowerSeries()) {
369 area->lowerLineItem()->setAnimator(presenter->animator());
370 367 area->lowerLineItem()->setAnimation(new XYAnimation(area->lowerLineItem()));
371 368 }
372 369 }
373 370 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
374 371 return area;
375 372 }
376 373
377 374 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
378 375 {
379 376 Q_Q(QAreaSeries);
380 377 QList<LegendMarker*> list;
381 378 return list << new AreaLegendMarker(q,legend);
382 379 }
383 380
384 381
385 382 void QAreaSeriesPrivate::initializeAxis(QAbstractAxis* axis)
386 383 {
387 384 Q_UNUSED(axis);
388 385 }
389 386
390 387 QAbstractAxis::AxisType QAreaSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
391 388 {
392 389 Q_UNUSED(orientation);
393 390 return QAbstractAxis::AxisTypeValues;
394 391 }
395 392
396 393 #include "moc_qareaseries.cpp"
397 394 #include "moc_qareaseries_p.cpp"
398 395
399 396 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,371 +1,370
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 "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 #include "chartanimator_p.h"
26 25 #include "domain_p.h"
27 26 #include <qmath.h>
28 27 #include <QDateTime>
29 28
30 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 30
32 31 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : Chart(presenter),
33 32 m_chartAxis(axis),
34 33 m_labelsAngle(0),
35 34 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
36 35 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
37 36 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
38 37 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
39 38 m_min(0),
40 39 m_max(0),
41 40 m_animation(0),
42 41 m_minWidth(0),
43 42 m_minHeight(0)
44 43 {
45 44 //initial initialization
46 45 m_arrow->setZValue(ChartPresenter::AxisZValue);
47 46 m_arrow->setHandlesChildEvents(false);
48 47
49 48 m_shades->setZValue(ChartPresenter::ShadesZValue);
50 49 m_grid->setZValue(ChartPresenter::GridZValue);
51 50
52 51 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
53 52
54 53 QGraphicsSimpleTextItem item;
55 54 m_font = item.font();
56 55 }
57 56
58 57 ChartAxis::~ChartAxis()
59 58 {
60 59 }
61 60
62 61 void ChartAxis::setAnimation(AxisAnimation* animation)
63 62 {
64 63 m_animation=animation;
65 64 }
66 65
67 66 void ChartAxis::setLayout(QVector<qreal> &layout)
68 67 {
69 68 m_layoutVector=layout;
70 69 }
71 70
72 71 void ChartAxis::createItems(int count)
73 72 {
74 73 if (m_arrow->children().size() == 0)
75 74 m_arrow->addToGroup(new AxisItem(this));
76 75 for (int i = 0; i < count; ++i) {
77 76 m_grid->addToGroup(new QGraphicsLineItem());
78 77 m_labels->addToGroup(new QGraphicsSimpleTextItem());
79 78 m_arrow->addToGroup(new QGraphicsLineItem());
80 79 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem());
81 80 }
82 81 }
83 82
84 83 void ChartAxis::deleteItems(int count)
85 84 {
86 85 QList<QGraphicsItem *> lines = m_grid->childItems();
87 86 QList<QGraphicsItem *> labels = m_labels->childItems();
88 87 QList<QGraphicsItem *> shades = m_shades->childItems();
89 88 QList<QGraphicsItem *> axis = m_arrow->childItems();
90 89
91 90 for (int i = 0; i < count; ++i) {
92 91 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
93 92 delete(lines.takeLast());
94 93 delete(labels.takeLast());
95 94 delete(axis.takeLast());
96 95 }
97 96 }
98 97
99 98 void ChartAxis::updateLayout(QVector<qreal> &layout)
100 99 {
101 100 int diff = m_layoutVector.size() - layout.size();
102 101
103 102 if (diff>0) {
104 103 deleteItems(diff);
105 104 }
106 105 else if (diff<0) {
107 106 createItems(-diff);
108 107 }
109 108
110 109 if(diff<0) handleAxisUpdated();
111 110
112 111 if (m_animation) {
113 112 switch(presenter()->state()){
114 113 case ChartPresenter::ZoomInState:
115 114 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
116 115 m_animation->setAnimationPoint(presenter()->statePoint());
117 116 break;
118 117 case ChartPresenter::ZoomOutState:
119 118 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
120 119 m_animation->setAnimationPoint(presenter()->statePoint());
121 120 break;
122 121 case ChartPresenter::ScrollUpState:
123 122 case ChartPresenter::ScrollLeftState:
124 123 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
125 124 break;
126 125 case ChartPresenter::ScrollDownState:
127 126 case ChartPresenter::ScrollRightState:
128 127 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
129 128 break;
130 129 case ChartPresenter::ShowState:
131 130 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
132 131 break;
133 132 }
134 133 m_animation->setValues(m_layoutVector,layout);
135 134 presenter()->startAnimation(m_animation);
136 135 }
137 136 else {
138 137 setLayout(layout);
139 138 updateGeometry();
140 139 }
141 140 }
142 141
143 142 void ChartAxis::setArrowOpacity(qreal opacity)
144 143 {
145 144 m_arrow->setOpacity(opacity);
146 145 }
147 146
148 147 qreal ChartAxis::arrowOpacity() const
149 148 {
150 149 return m_arrow->opacity();
151 150 }
152 151
153 152 void ChartAxis::setArrowVisibility(bool visible)
154 153 {
155 154 m_arrow->setOpacity(visible);
156 155 }
157 156
158 157 void ChartAxis::setGridOpacity(qreal opacity)
159 158 {
160 159 m_grid->setOpacity(opacity);
161 160 }
162 161
163 162 qreal ChartAxis::gridOpacity() const
164 163 {
165 164 return m_grid->opacity();
166 165 }
167 166
168 167 void ChartAxis::setGridVisibility(bool visible)
169 168 {
170 169 m_grid->setOpacity(visible);
171 170 }
172 171
173 172 void ChartAxis::setLabelsOpacity(qreal opacity)
174 173 {
175 174 m_labels->setOpacity(opacity);
176 175 }
177 176
178 177 qreal ChartAxis::labelsOpacity() const
179 178 {
180 179 return m_labels->opacity();
181 180 }
182 181
183 182 void ChartAxis::setLabelsVisibility(bool visible)
184 183 {
185 184 m_labels->setOpacity(visible);
186 185 }
187 186
188 187 void ChartAxis::setShadesOpacity(qreal opacity)
189 188 {
190 189 m_shades->setOpacity(opacity);
191 190 }
192 191
193 192 qreal ChartAxis::shadesOpacity() const
194 193 {
195 194 return m_shades->opacity();
196 195 }
197 196
198 197 void ChartAxis::setShadesVisibility(bool visible)
199 198 {
200 199 m_shades->setVisible(visible);
201 200 }
202 201
203 202 void ChartAxis::setLabelsAngle(int angle)
204 203 {
205 204 foreach(QGraphicsItem* item , m_labels->childItems()) {
206 205 item->setRotation(angle);
207 206 }
208 207
209 208 m_labelsAngle=angle;
210 209 }
211 210
212 211 void ChartAxis::setLabelsPen(const QPen &pen)
213 212 {
214 213 foreach(QGraphicsItem* item , m_labels->childItems()) {
215 214 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
216 215 }
217 216 }
218 217
219 218 void ChartAxis::setLabelsBrush(const QBrush &brush)
220 219 {
221 220 foreach(QGraphicsItem* item , m_labels->childItems()) {
222 221 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
223 222 }
224 223 }
225 224
226 225 void ChartAxis::setLabelsFont(const QFont &font)
227 226 {
228 227 foreach(QGraphicsItem* item , m_labels->childItems()) {
229 228 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
230 229 }
231 230 m_font = font;
232 231 }
233 232
234 233 void ChartAxis::setShadesBrush(const QBrush &brush)
235 234 {
236 235 foreach(QGraphicsItem* item , m_shades->childItems()) {
237 236 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
238 237 }
239 238 }
240 239
241 240 void ChartAxis::setShadesPen(const QPen &pen)
242 241 {
243 242 foreach(QGraphicsItem* item , m_shades->childItems()) {
244 243 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
245 244 }
246 245 }
247 246
248 247 void ChartAxis::setArrowPen(const QPen &pen)
249 248 {
250 249 foreach(QGraphicsItem* item , m_arrow->childItems()) {
251 250 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
252 251 }
253 252 }
254 253
255 254 void ChartAxis::setGridPen(const QPen &pen)
256 255 {
257 256 foreach(QGraphicsItem* item , m_grid->childItems()) {
258 257 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
259 258 }
260 259 }
261 260
262 261 bool ChartAxis::isEmpty()
263 262 {
264 263 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
265 264 }
266 265
267 266 void ChartAxis::handleDomainUpdated()
268 267 {
269 268 Domain* domain = qobject_cast<Domain*>(sender());
270 269 qreal min(0);
271 270 qreal max(0);
272 271
273 272 if(m_chartAxis->orientation()==Qt::Horizontal) {
274 273 min = domain->minX();
275 274 max = domain->maxX();
276 275 }
277 276 else if (m_chartAxis->orientation()==Qt::Vertical)
278 277 {
279 278 min = domain->minY();
280 279 max = domain->maxY();
281 280 }
282 281
283 282 if (!qFuzzyIsNull(m_min - min) || !qFuzzyIsNull(m_max - max))
284 283 {
285 284 m_min = min;
286 285 m_max = max;
287 286
288 287 if (!isEmpty()) {
289 288 QVector<qreal> layout = calculateLayout();
290 289 updateLayout(layout);
291 290 }
292 291 }
293 292 }
294 293
295 294 void ChartAxis::handleAxisUpdated()
296 295 {
297 296 if(isEmpty()) return;
298 297
299 298
300 299 bool visible = m_chartAxis->isVisible();
301 300
302 301 setArrowVisibility(visible && m_chartAxis->isArrowVisible());
303 302 setGridVisibility(visible && m_chartAxis->isGridLineVisible());
304 303 setLabelsVisibility(visible && m_chartAxis->labelsVisible());
305 304 setShadesVisibility(visible && m_chartAxis->shadesVisible());
306 305 setLabelsAngle(m_chartAxis->labelsAngle());
307 306 setArrowPen(m_chartAxis->axisPen());
308 307 setLabelsPen(m_chartAxis->labelsPen());
309 308 setLabelsBrush(m_chartAxis->labelsBrush());
310 309 setLabelsFont(m_chartAxis->labelsFont());
311 310 setGridPen(m_chartAxis->gridLinePen());
312 311 setShadesPen(m_chartAxis->shadesPen());
313 312 setShadesBrush(m_chartAxis->shadesBrush());
314 313
315 314 }
316 315
317 316 void ChartAxis::hide()
318 317 {
319 318 setArrowVisibility(false);
320 319 setGridVisibility(false);
321 320 setLabelsVisibility(false);
322 321 setShadesVisibility(false);
323 322 }
324 323
325 324 void ChartAxis::handleGeometryChanged(const QRectF &rect)
326 325 {
327 326 if(m_rect != rect)
328 327 {
329 328 m_rect = rect;
330 329 if (isEmpty()) return;
331 330 QVector<qreal> layout = calculateLayout();
332 331 updateLayout(layout);
333 332 }
334 333 }
335 334
336 335
337 336 qreal ChartAxis::minimumWidth()
338 337 {
339 338 if(m_minWidth == 0) updateGeometry();
340 339 return m_minWidth;
341 340 }
342 341
343 342 qreal ChartAxis::minimumHeight()
344 343 {
345 344 if(m_minHeight == 0) updateGeometry();
346 345 return m_minHeight;
347 346 }
348 347
349 348
350 349 void ChartAxis::axisSelected()
351 350 {
352 351 qDebug()<<"TODO: axis clicked";
353 352 }
354 353
355 354
356 355 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
357 356 {
358 357 Q_ASSERT(max>min);
359 358 Q_ASSERT(ticks>1);
360 359
361 360 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
362 361 n++;
363 362 for (int i=0; i< ticks; i++) {
364 363 qreal value = min + (i * (max - min)/ (ticks-1));
365 364 labels << QString::number(value,'f',n);
366 365 }
367 366 }
368 367
369 368 #include "moc_chartaxis_p.cpp"
370 369
371 370 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,138 +1,136
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 "chartdatetimeaxisx_p.h"
22 #include "qabstractaxis.h"
23 22 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 23 #include "qdatetimeaxis.h"
26 24 #include <QGraphicsLayout>
27 #include <QDebug>
28 #include <QFontMetrics>
29 #include <cmath>
30 25 #include <QDateTime>
26 #include <QFontMetrics>
27 #include <qmath.h>
28
31 29
32 30 static int label_padding = 5;
33 31
34 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 33
36 34 ChartDateTimeAxisX::ChartDateTimeAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
37 35 m_tickCount(0)
38 36 {
39 37 }
40 38
41 39 ChartDateTimeAxisX::~ChartDateTimeAxisX()
42 40 {
43 41 }
44 42
45 43 void ChartDateTimeAxisX::createLabels(QStringList &labels,qreal min, qreal max, int ticks)
46 44 {
47 45 Q_ASSERT(max>min);
48 46 Q_ASSERT(ticks>1);
49 47
50 48 QDateTimeAxis *axis = qobject_cast<QDateTimeAxis *>(m_chartAxis);
51 49
52 50 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
53 51 n++;
54 52 for (int i=0; i< ticks; i++) {
55 53 qreal value = min + (i * (max - min)/ (ticks-1));
56 54 labels << QDateTime::fromMSecsSinceEpoch(value).toString(axis->formatString());
57 55 }
58 56 }
59 57
60 58 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
61 59 {
62 60 Q_ASSERT(m_tickCount>=2);
63 61
64 62 QVector<qreal> points;
65 63 points.resize(m_tickCount);
66 64
67 65 const qreal deltaX = m_rect.width()/(m_tickCount-1);
68 66 for (int i = 0; i < m_tickCount; ++i) {
69 67 int x = i * deltaX + m_rect.left();
70 68 points[i] = x;
71 69 }
72 70 return points;
73 71 }
74 72
75 73 void ChartDateTimeAxisX::updateGeometry()
76 74 {
77 75 const QVector<qreal>& layout = ChartAxis::layout();
78 76
79 77 m_minWidth = 0;
80 78 m_minHeight = 0;
81 79
82 80 if(layout.isEmpty()) return;
83 81
84 82 QStringList ticksList;
85 83
86 84 createLabels(ticksList,m_min,m_max,layout.size());
87 85
88 86 QList<QGraphicsItem *> lines = m_grid->childItems();
89 87 QList<QGraphicsItem *> labels = m_labels->childItems();
90 88 QList<QGraphicsItem *> shades = m_shades->childItems();
91 89 QList<QGraphicsItem *> axis = m_arrow->childItems();
92 90
93 91 Q_ASSERT(labels.size() == ticksList.size());
94 92 Q_ASSERT(layout.size() == ticksList.size());
95 93
96 94 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
97 95 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
98 96
99 97 qreal width = 0;
100 98 for (int i = 0; i < layout.size(); ++i) {
101 99 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
102 100 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
103 101 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
104 102 labelItem->setText(ticksList.at(i));
105 103 const QRectF& rect = labelItem->boundingRect();
106 104 QPointF center = rect.center();
107 105 labelItem->setTransformOriginPoint(center.x(), center.y());
108 106 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
109 107
110 108 if(labelItem->pos().x()<=width){
111 109 labelItem->setVisible(false);
112 110 lineItem->setVisible(false);
113 111 }else{
114 112 labelItem->setVisible(true);
115 113 lineItem->setVisible(true);
116 114 width=rect.width()+labelItem->pos().x();
117 115 }
118 116 m_minWidth+=rect.width();
119 117 m_minHeight=qMax(rect.height(),m_minHeight);
120 118
121 119 if ((i+1)%2 && i>1) {
122 120 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
123 121 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
124 122 }
125 123 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
126 124 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
127 125 }
128 126 }
129 127
130 128 void ChartDateTimeAxisX::handleAxisUpdated()
131 129 {
132 130 //TODO:: fix this
133 131 QDateTimeAxis* axis = qobject_cast<QDateTimeAxis*>(m_chartAxis);
134 132 m_tickCount = axis->ticksCount();
135 133 ChartAxis::handleAxisUpdated();
136 134 }
137 135
138 136 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,144 +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 #include "chartdatetimeaxisy_p.h"
22 #include "qabstractaxis.h"
23 22 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 23 #include "qdatetimeaxis.h"
26 24 #include <QGraphicsLayout>
27 #include <QDebug>
28 25 #include <QFontMetrics>
29 #include <cmath>
30 26 #include <QDateTime>
27 #include <qmath.h>
28
31 29
32 30 static int label_padding = 5;
33 31
34 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 33
36 34 ChartDateTimeAxisY::ChartDateTimeAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
37 35 m_tickCount(0)
38 36 {
39 37 }
40 38
41 39 ChartDateTimeAxisY::~ChartDateTimeAxisY()
42 40 {
43 41 }
44 42
45 43 void ChartDateTimeAxisY::createLabels(QStringList &labels,qreal min, qreal max, int ticks)
46 44 {
47 45 Q_ASSERT(max>min);
48 46 Q_ASSERT(ticks>1);
49 47
50 48 QDateTimeAxis *axis = qobject_cast<QDateTimeAxis *>(m_chartAxis);
51 49
52 50 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
53 51 n++;
54 52 for (int i=0; i< ticks; i++) {
55 53 qreal value = min + (i * (max - min)/ (ticks-1));
56 54 labels << QDateTime::fromMSecsSinceEpoch(value).toString(axis->formatString());
57 55 }
58 56 }
59 57
60 58 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
61 59 {
62 60 Q_ASSERT(m_tickCount>=2);
63 61
64 62 QVector<qreal> points;
65 63 points.resize(m_tickCount);
66 64
67 65 const qreal deltaY = m_rect.height()/(m_tickCount-1);
68 66 for (int i = 0; i < m_tickCount; ++i) {
69 67 int y = i * -deltaY + m_rect.bottom();
70 68 points[i] = y;
71 69 }
72 70
73 71 return points;
74 72 }
75 73
76 74 void ChartDateTimeAxisY::updateGeometry()
77 75 {
78 76 const QVector<qreal> &layout = ChartAxis::layout();
79 77 m_minWidth = 0;
80 78 m_minHeight = 0;
81 79
82 80 if(layout.isEmpty()) return;
83 81
84 82 QStringList ticksList;
85 83
86 84 createLabels(ticksList,m_min,m_max,layout.size());
87 85
88 86 QList<QGraphicsItem *> lines = m_grid->childItems();
89 87 QList<QGraphicsItem *> labels = m_labels->childItems();
90 88 QList<QGraphicsItem *> shades = m_shades->childItems();
91 89 QList<QGraphicsItem *> axis = m_arrow->childItems();
92 90
93 91 Q_ASSERT(labels.size() == ticksList.size());
94 92 Q_ASSERT(layout.size() == ticksList.size());
95 93
96 94 qreal height = 2*m_rect.bottom();
97 95
98 96 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
99 97 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
100 98
101 99 for (int i = 0; i < layout.size(); ++i) {
102 100 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
103 101 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
104 102 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
105 103
106 104 labelItem->setText(ticksList.at(i));
107 105 const QRectF& rect = labelItem->boundingRect();
108 106
109 107 QPointF center = rect.center();
110 108 labelItem->setTransformOriginPoint(center.x(), center.y());
111 109 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
112 110
113 111 if(labelItem->pos().y()+rect.height()>height) {
114 112 labelItem->setVisible(false);
115 113 lineItem->setVisible(false);
116 114 }
117 115 else {
118 116 labelItem->setVisible(true);
119 117 lineItem->setVisible(true);
120 118 height=labelItem->pos().y();
121 119 }
122 120
123 121 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
124 122 m_minHeight+=rect.height();
125 123
126 124 if ((i+1)%2 && i>1) {
127 125 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
128 126 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
129 127 }
130 128 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
131 129 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
132 130 }
133 131 }
134 132
135 133 void ChartDateTimeAxisY::handleAxisUpdated()
136 134 {
137 135 //TODO:: fix this
138 136 QDateTimeAxis* axis = qobject_cast<QDateTimeAxis*>(m_chartAxis);
139 137 m_tickCount = axis->ticksCount();
140 138 ChartAxis::handleAxisUpdated();
141 139 }
142 140
143 141
144 142 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,126 +1,124
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 "chartintervalsaxisx_p.h"
22 #include "qintervalsaxis.h"
22 23 #include "qabstractaxis.h"
23 24 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 25 #include <QGraphicsLayout>
26 #include <QDebug>
27 26 #include <QFontMetrics>
28 #include <cmath>
29 #include <QIntervalsAxis>
27 #include <qmath.h>
30 28
31 29 static int label_padding = 5;
32 30
33 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 32
35 33 ChartIntervalAxisX::ChartIntervalAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
36 34 {
37 35 }
38 36
39 37 ChartIntervalAxisX::~ChartIntervalAxisX()
40 38 {
41 39 }
42 40
43 41 QVector<qreal> ChartIntervalAxisX::calculateLayout() const
44 42 {
45 43 QIntervalsAxis *axis = qobject_cast<QIntervalsAxis *>(m_chartAxis);
46 44 int tickCount = axis->intervalsLabels().count() + 1;
47 45 QVector<qreal> points;
48 46
49 47 if (tickCount < 2)
50 48 return points;
51 49
52 50 points.resize(tickCount);
53 51
54 52 qreal scale = m_rect.width() / axis->max();
55 53 for (int i = 0; i < tickCount; ++i)
56 54 if (i < tickCount - 1) {
57 55 int x = axis->intervalMin(axis->intervalsLabels().at(i)) * scale + m_rect.left();
58 56 points[i] = x;
59 57 } else {
60 58 int x = axis->intervalMax(axis->intervalsLabels().at(i - 1)) * scale + m_rect.left();
61 59 points[i] = x;
62 60 }
63 61
64 62 return points;
65 63 }
66 64
67 65 void ChartIntervalAxisX::updateGeometry()
68 66 {
69 67 const QVector<qreal>& layout = ChartAxis::layout();
70 68
71 69 m_minWidth = 0;
72 70 m_minHeight = 0;
73 71
74 72 if(layout.isEmpty()) return;
75 73
76 74 QIntervalsAxis *intervalAxis = qobject_cast<QIntervalsAxis *>(m_chartAxis);
77 75
78 76 QStringList ticksList = intervalAxis->intervalsLabels();
79 77
80 78 // createNumberLabels(ticksList,m_min,m_max,layout.size());
81 79
82 80 QList<QGraphicsItem *> lines = m_grid->childItems();
83 81 QList<QGraphicsItem *> labels = m_labels->childItems();
84 82 QList<QGraphicsItem *> shades = m_shades->childItems();
85 83 QList<QGraphicsItem *> axis = m_arrow->childItems();
86 84
87 85 // Q_ASSERT(labels.size() == ticksList.size());
88 86 // Q_ASSERT(layout.size() == ticksList.size());
89 87
90 88 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
91 89 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
92 90
93 91 // qreal width = 0;
94 92 for (int i = 0; i < layout.size(); ++i) {
95 93 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
96 94 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
97 95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
98 96 if (i < ticksList.count()) {
99 97 labelItem->setText(ticksList.at(i));
100 98 }
101 99 const QRectF& rect = labelItem->boundingRect();
102 100 QPointF center = rect.center();
103 101 labelItem->setTransformOriginPoint(center.x(), center.y());
104 102 if (i < ticksList.count())
105 103 labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), m_rect.bottom() + label_padding);
106 104 else
107 105 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
108 106
109 107 if(labelItem->pos().x() > m_rect.width() + m_rect.left() - rect.width() / 2){
110 108 labelItem->setVisible(false);
111 109 lineItem->setVisible(false);
112 110 }
113 111
114 112 m_minWidth += rect.width();
115 113 m_minHeight = qMax(rect.height(), m_minHeight);
116 114
117 115 if ((i + 1) % 2 && i > 1) {
118 116 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i / 2 - 1));
119 117 rectItem->setRect(layout[i - 1],m_rect.top(),layout[i]-layout[i - 1],m_rect.height());
120 118 }
121 119 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
122 120 lineItem->setLine(layout[i],m_rect.bottom(),layout[i], m_rect.bottom() + 5);
123 121 }
124 122 }
125 123
126 124 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,132 +1,131
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 "chartintervalsaxisy_p.h"
22 #include "qintervalsaxis.h"
22 23 #include "qabstractaxis.h"
23 24 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 25 #include <QGraphicsLayout>
26 #include <QDebug>
27 26 #include <QFontMetrics>
28 #include <cmath>
29 #include <QIntervalsAxis>
27 #include <qmath.h>
28
30 29
31 30 static int label_padding = 5;
32 31
33 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 33
35 34 ChartIntervalAxisY::ChartIntervalAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
36 35 {
37 36 }
38 37
39 38 ChartIntervalAxisY::~ChartIntervalAxisY()
40 39 {
41 40 }
42 41
43 42 QVector<qreal> ChartIntervalAxisY::calculateLayout() const
44 43 {
45 44 QIntervalsAxis *axis = qobject_cast<QIntervalsAxis *>(m_chartAxis);
46 45 int tickCount = axis->intervalsLabels().count() + 1;
47 46 QVector<qreal> points;
48 47
49 48 if (tickCount < 2)
50 49 return points;
51 50
52 51 points.resize(tickCount);
53 52
54 53 qreal scale = m_rect.height() / axis->max();
55 54 for (int i = 0; i < tickCount; ++i)
56 55 if (i < tickCount - 1) {
57 56 int y = -axis->intervalMin(axis->intervalsLabels().at(i)) * scale + m_rect.bottom();
58 57 points[i] = y;
59 58 } else {
60 59 int y = -axis->intervalMax(axis->intervalsLabels().at(i - 1)) * scale + m_rect.bottom();
61 60 points[i] = y;
62 61 }
63 62
64 63 return points;
65 64 }
66 65
67 66 void ChartIntervalAxisY::updateGeometry()
68 67 {
69 68 const QVector<qreal> &layout = ChartAxis::layout();
70 69 m_minWidth = 0;
71 70 m_minHeight = 0;
72 71
73 72 if(layout.isEmpty()) return;
74 73
75 74 QIntervalsAxis *intervalAxis = qobject_cast<QIntervalsAxis *>(m_chartAxis);
76 75
77 76 QStringList ticksList = intervalAxis->intervalsLabels();
78 77
79 78 QList<QGraphicsItem *> lines = m_grid->childItems();
80 79 QList<QGraphicsItem *> labels = m_labels->childItems();
81 80 QList<QGraphicsItem *> shades = m_shades->childItems();
82 81 QList<QGraphicsItem *> axis = m_arrow->childItems();
83 82
84 83 // Q_ASSERT(labels.size() == ticksList.size());
85 84 // Q_ASSERT(layout.size() == ticksList.size());
86 85
87 86 qreal height = 2*m_rect.bottom();
88 87
89 88 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
90 89 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
91 90
92 91 for (int i = 0; i < layout.size(); ++i) {
93 92 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
94 93 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
95 94 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
96 95
97 96 if (i < ticksList.count()) {
98 97 labelItem->setText(ticksList.at(i));
99 98 }
100 99 const QRectF& rect = labelItem->boundingRect();
101 100
102 101 QPointF center = rect.center();
103 102 labelItem->setTransformOriginPoint(center.x(), center.y());
104 103
105 104 if (i < ticksList.count())
106 105 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
107 106 else
108 107 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
109 108
110 109 if(labelItem->pos().y()+rect.height()>height) {
111 110 labelItem->setVisible(false);
112 111 lineItem->setVisible(false);
113 112 }
114 113 else {
115 114 labelItem->setVisible(true);
116 115 lineItem->setVisible(true);
117 116 height=labelItem->pos().y();
118 117 }
119 118
120 119 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
121 120 m_minHeight+=rect.height();
122 121
123 122 if ((i+1)%2 && i>1) {
124 123 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
125 124 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
126 125 }
127 126 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
128 127 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
129 128 }
130 129 }
131 130
132 131 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,122 +1,120
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 "chartvaluesaxisx_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 24 #include "qvaluesaxis.h"
26 25 #include <QGraphicsLayout>
27 #include <QDebug>
28 26 #include <QFontMetrics>
29 #include <cmath>
27 #include <qmath.h>
30 28
31 29 static int label_padding = 5;
32 30
33 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 32
35 33 ChartValuesAxisX::ChartValuesAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
36 34 m_tickCount(0)
37 35 {
38 36 }
39 37
40 38 ChartValuesAxisX::~ChartValuesAxisX()
41 39 {
42 40 }
43 41
44 42 QVector<qreal> ChartValuesAxisX::calculateLayout() const
45 43 {
46 44 Q_ASSERT(m_tickCount>=2);
47 45
48 46 QVector<qreal> points;
49 47 points.resize(m_tickCount);
50 48
51 49 const qreal deltaX = m_rect.width()/(m_tickCount-1);
52 50 for (int i = 0; i < m_tickCount; ++i) {
53 51 int x = i * deltaX + m_rect.left();
54 52 points[i] = x;
55 53 }
56 54 return points;
57 55 }
58 56
59 57 void ChartValuesAxisX::updateGeometry()
60 58 {
61 59 const QVector<qreal>& layout = ChartAxis::layout();
62 60
63 61 m_minWidth = 0;
64 62 m_minHeight = 0;
65 63
66 64 if(layout.isEmpty()) return;
67 65
68 66 QStringList ticksList;
69 67
70 68 createNumberLabels(ticksList,m_min,m_max,layout.size());
71 69
72 70 QList<QGraphicsItem *> lines = m_grid->childItems();
73 71 QList<QGraphicsItem *> labels = m_labels->childItems();
74 72 QList<QGraphicsItem *> shades = m_shades->childItems();
75 73 QList<QGraphicsItem *> axis = m_arrow->childItems();
76 74
77 75 Q_ASSERT(labels.size() == ticksList.size());
78 76 Q_ASSERT(layout.size() == ticksList.size());
79 77
80 78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
81 79 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
82 80
83 81 qreal width = 0;
84 82 for (int i = 0; i < layout.size(); ++i) {
85 83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
86 84 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
87 85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
88 86 labelItem->setText(ticksList.at(i));
89 87 const QRectF& rect = labelItem->boundingRect();
90 88 QPointF center = rect.center();
91 89 labelItem->setTransformOriginPoint(center.x(), center.y());
92 90 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
93 91
94 92 if(labelItem->pos().x()<=width){
95 93 labelItem->setVisible(false);
96 94 lineItem->setVisible(false);
97 95 }else{
98 96 labelItem->setVisible(true);
99 97 lineItem->setVisible(true);
100 98 width=rect.width()+labelItem->pos().x();
101 99 }
102 100 m_minWidth+=rect.width();
103 101 m_minHeight=qMax(rect.height(),m_minHeight);
104 102
105 103 if ((i+1)%2 && i>1) {
106 104 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
107 105 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
108 106 }
109 107 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
110 108 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
111 109 }
112 110 }
113 111
114 112 void ChartValuesAxisX::handleAxisUpdated()
115 113 {
116 114 //TODO:: fix this
117 115 QValuesAxis* axis = qobject_cast<QValuesAxis*>(m_chartAxis);
118 116 m_tickCount = axis->ticksCount();
119 117 ChartAxis::handleAxisUpdated();
120 118 }
121 119
122 120 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,128 +1,126
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 "chartvaluesaxisy_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 #include "chartanimator_p.h"
25 24 #include "qvaluesaxis.h"
26 25 #include <QGraphicsLayout>
27 #include <QDebug>
28 26 #include <QFontMetrics>
29 #include <cmath>
27 #include <qmath.h>
30 28
31 29 static int label_padding = 5;
32 30
33 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 32
35 33 ChartValuesAxisY::ChartValuesAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
36 34 m_tickCount(0)
37 35 {
38 36 }
39 37
40 38 ChartValuesAxisY::~ChartValuesAxisY()
41 39 {
42 40 }
43 41
44 42 QVector<qreal> ChartValuesAxisY::calculateLayout() const
45 43 {
46 44 Q_ASSERT(m_tickCount>=2);
47 45
48 46 QVector<qreal> points;
49 47 points.resize(m_tickCount);
50 48
51 49 const qreal deltaY = m_rect.height()/(m_tickCount-1);
52 50 for (int i = 0; i < m_tickCount; ++i) {
53 51 int y = i * -deltaY + m_rect.bottom();
54 52 points[i] = y;
55 53 }
56 54
57 55 return points;
58 56 }
59 57
60 58 void ChartValuesAxisY::updateGeometry()
61 59 {
62 60 const QVector<qreal> &layout = ChartAxis::layout();
63 61 m_minWidth = 0;
64 62 m_minHeight = 0;
65 63
66 64 if(layout.isEmpty()) return;
67 65
68 66 QStringList ticksList;
69 67
70 68 createNumberLabels(ticksList,m_min,m_max,layout.size());
71 69
72 70 QList<QGraphicsItem *> lines = m_grid->childItems();
73 71 QList<QGraphicsItem *> labels = m_labels->childItems();
74 72 QList<QGraphicsItem *> shades = m_shades->childItems();
75 73 QList<QGraphicsItem *> axis = m_arrow->childItems();
76 74
77 75 Q_ASSERT(labels.size() == ticksList.size());
78 76 Q_ASSERT(layout.size() == ticksList.size());
79 77
80 78 qreal height = 2*m_rect.bottom();
81 79
82 80 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
83 81 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
84 82
85 83 for (int i = 0; i < layout.size(); ++i) {
86 84 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
87 85 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
88 86 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
89 87
90 88 labelItem->setText(ticksList.at(i));
91 89 const QRectF& rect = labelItem->boundingRect();
92 90
93 91 QPointF center = rect.center();
94 92 labelItem->setTransformOriginPoint(center.x(), center.y());
95 93 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
96 94
97 95 if(labelItem->pos().y()+rect.height()>height) {
98 96 labelItem->setVisible(false);
99 97 lineItem->setVisible(false);
100 98 }
101 99 else {
102 100 labelItem->setVisible(true);
103 101 lineItem->setVisible(true);
104 102 height=labelItem->pos().y();
105 103 }
106 104
107 105 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
108 106 m_minHeight+=rect.height();
109 107
110 108 if ((i+1)%2 && i>1) {
111 109 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
112 110 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
113 111 }
114 112 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
115 113 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
116 114 }
117 115 }
118 116
119 117 void ChartValuesAxisY::handleAxisUpdated()
120 118 {
121 119 //TODO:: fix this
122 120 QValuesAxis* axis = qobject_cast<QValuesAxis*>(m_chartAxis);
123 121 m_tickCount = axis->ticksCount();
124 122 ChartAxis::handleAxisUpdated();
125 123 }
126 124
127 125
128 126 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,179 +1,179
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 "abstractbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "qabstractbarseries.h"
26 26 #include "qabstractbarseries_p.h"
27 27 #include "qchart.h"
28 28 #include "chartpresenter_p.h"
29 #include "chartanimator_p.h"
29 #include "charttheme_p.h"
30 30 #include "abstractbaranimation_p.h"
31 31 #include "chartdataset_p.h"
32 32 #include <QPainter>
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
37 37 ChartItem(presenter),
38 38 m_animation(0),
39 39 m_series(series)
40 40 {
41 41 setFlag(ItemClipsChildrenToShape);
42 42 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
43 43 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
44 44 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
45 45 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
46 46 setZValue(ChartPresenter::BarSeriesZValue);
47 47 handleDataStructureChanged();
48 48 }
49 49
50 50 AbstractBarChartItem::~AbstractBarChartItem()
51 51 {
52 52 }
53 53
54 54 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
55 55 {
56 56 Q_UNUSED(painter);
57 57 Q_UNUSED(option);
58 58 Q_UNUSED(widget);
59 59 }
60 60
61 61 QRectF AbstractBarChartItem::boundingRect() const
62 62 {
63 63 return m_rect;
64 64 }
65 65
66 66 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
67 67 {
68 68 if (m_animation) {
69 69 m_animation->setup(m_layout,layout);
70 70 presenter()->startAnimation(m_animation);
71 71
72 72 } else {
73 73 setLayout(layout);
74 74 update();
75 75 }
76 76 }
77 77
78 78 void AbstractBarChartItem::setAnimation(AbstractBarAnimation *animation)
79 79 {
80 80 m_animation = animation;
81 81 }
82 82
83 83 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
84 84 {
85 85 if (layout.count() != m_bars.count())
86 86 return;
87 87
88 88 m_layout = layout;
89 89
90 90 for (int i=0; i < m_bars.count(); i++) {
91 91 m_bars.at(i)->setRect(layout.at(i));
92 92 }
93 93 }
94 94 //handlers
95 95
96 96 void AbstractBarChartItem::handleDomainUpdated()
97 97 {
98 98 m_domainMinX = domain()->minX();
99 99 m_domainMaxX = domain()->maxX();
100 100 m_domainMinY = domain()->minY();
101 101 m_domainMaxY = domain()->maxY();
102 102 handleLayoutChanged();
103 103 }
104 104
105 105 void AbstractBarChartItem::handleGeometryChanged(const QRectF &rect)
106 106 {
107 107 prepareGeometryChange();
108 108 m_rect = rect;
109 109 handleLayoutChanged();
110 110 }
111 111
112 112 void AbstractBarChartItem::handleLayoutChanged()
113 113 {
114 114 if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) {
115 115 // rect size zero.
116 116 return;
117 117 }
118 118 QVector<QRectF> layout = calculateLayout();
119 119 applyLayout(layout);
120 120 }
121 121
122 122 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
123 123 {
124 124 foreach (QGraphicsSimpleTextItem* label, m_labels) {
125 125 label->setVisible(visible);
126 126 }
127 127 update();
128 128 }
129 129
130 130 void AbstractBarChartItem::handleDataStructureChanged()
131 131 {
132 132 foreach(QGraphicsItem *item, childItems()) {
133 133 delete item;
134 134 }
135 135
136 136 m_bars.clear();
137 137 m_labels.clear();
138 138 m_layout.clear();
139 139
140 140 bool labelsVisible = m_series->isLabelsVisible();
141 141
142 142 // Create new graphic items for bars
143 143 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
144 144 for (int s = 0; s < m_series->count(); s++) {
145 145 QBarSet *set = m_series->d_func()->barsetAt(s);
146 146
147 147 // Bars
148 148 Bar *bar = new Bar(set,c,this);
149 149 m_bars.append(bar);
150 150 connect(bar, SIGNAL(clicked(int, QBarSet*)), m_series, SIGNAL(clicked(int, QBarSet*)));
151 151 connect(bar, SIGNAL(hovered(bool, QBarSet*)), m_series, SIGNAL(hovered(bool, QBarSet*)));
152 152 connect(bar, SIGNAL(clicked(int, QBarSet*)), set, SIGNAL(clicked(int)));
153 153 connect(bar, SIGNAL(hovered(bool, QBarSet*)), set, SIGNAL(hovered(bool)));
154 154 m_layout.append(QRectF(0, 0, 0, 0));
155 155
156 156 // Labels
157 157 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this);
158 158 label->setVisible(labelsVisible);
159 159 m_labels.append(label);
160 160 }
161 161 }
162 162
163 163 // TODO: Is this the right place to call it?
164 164 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
165 165 handleLayoutChanged();
166 166 }
167 167
168 168 void AbstractBarChartItem::handleVisibleChanged()
169 169 {
170 170 bool visible = m_series->isVisible();
171 171 handleLabelsVisibleChanged(visible);
172 172 foreach(QGraphicsItem *item, childItems()) {
173 173 item->setVisible(visible);
174 174 }
175 175 }
176 176
177 177 #include "moc_abstractbarchartitem_p.cpp"
178 178
179 179 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,119 +1,118
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 "qhorizontalbarseries.h"
22 22 #include "qhorizontalbarseries_p.h"
23 23 #include "horizontalbarchartitem_p.h"
24 24 #include "horizontalbaranimation_p.h"
25 25 #include "qbarcategoriesaxis.h"
26 26
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 29
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QHorizontalBarSeries
35 35 \brief Series for creating horizontal bar chart
36 36 \mainclass
37 37
38 38 QHorizontalBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
39 39 as groups, where bars in same category are grouped next to each other. QHorizontalBarSeries groups the data
40 40 from sets to categories, which are defined by a QStringList.
41 41
42 42 See the \l {HorizontalBarChart Example} {horizontal bar chart example} to learn how to create a horizontal bar chart.
43 43 \image examples_horizontalbarchart.png
44 44
45 45 \sa QBarSet, QBarSeries, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries, QHorizontalStackedBarSeries, QHorizontalPercentBarSeries
46 46 */
47 47 /*
48 48 // TODO:
49 49 \qmlclass Horizontal QHorizontalBarSeries
50 50 \inherits AbstractBarSeries
51 51
52 52 The following QML shows how to create a simple grouped bar chart:
53 53 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
54 54 \beginfloatleft
55 55 \image demos_qmlchart6.png
56 56 \endfloat
57 57 \clearfloat
58 58 */
59 59
60 60
61 61
62 62 QHorizontalBarSeries::QHorizontalBarSeries(QObject *parent) :
63 63 QAbstractBarSeries(*new QHorizontalBarSeriesPrivate(this), parent)
64 64 {
65 65 }
66 66
67 67 QHorizontalBarSeries::~QHorizontalBarSeries()
68 68 {
69 69 Q_D(QHorizontalBarSeries);
70 70 if(d->m_dataset) {
71 71 d->m_dataset->removeSeries(this);
72 72 }
73 73 }
74 74
75 75 QAbstractSeries::SeriesType QHorizontalBarSeries::type() const
76 76 {
77 77 return QAbstractSeries::SeriesTypeHorizontalBar;
78 78 }
79 79
80 80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 81
82 82 QHorizontalBarSeriesPrivate::QHorizontalBarSeriesPrivate(QHorizontalBarSeries *q) : QAbstractBarSeriesPrivate(q)
83 83 {
84 84
85 85 }
86 86
87 87 void QHorizontalBarSeriesPrivate::scaleDomain(Domain& domain)
88 88 {
89 89 qreal minX(domain.minX());
90 90 qreal minY(domain.minY());
91 91 qreal maxX(domain.maxX());
92 92 qreal maxY(domain.maxY());
93 93
94 94 qreal y = categoryCount();
95 95 qreal x = max();
96 96 minX = qMin(minX, x);
97 97 minY = qMin(minY, - (qreal)0.5);
98 98 maxX = qMax(maxX, x);
99 99 maxY = qMax(maxY, y - (qreal)0.5);
100 100
101 101 domain.setRange(minX,maxX,minY,maxY);
102 102 }
103 103
104 104 Chart* QHorizontalBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
105 105 {
106 106 Q_Q(QHorizontalBarSeries);
107 107
108 108 HorizontalBarChartItem* bar = new HorizontalBarChartItem(q,presenter);
109 109 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
110 bar->setAnimator(presenter->animator());
111 110 bar->setAnimation(new HorizontalBarAnimation(bar));
112 111 }
113 112 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
114 113 return bar;
115 114 }
116 115
117 116 #include "moc_qhorizontalbarseries.cpp"
118 117
119 118 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,66
1 1 #include "qhorizontalpercentbarseries.h"
2 2 #include "qhorizontalpercentbarseries_p.h"
3 3 #include "horizontalpercentbarchartitem_p.h"
4 4 #include "horizontalpercentbaranimation_p.h"
5 5
6 6 #include "chartdataset_p.h"
7 7 #include "charttheme_p.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QHorizontalPercentBarSeries::QHorizontalPercentBarSeries(QObject *parent) :
12 12 QAbstractBarSeries(*new QHorizontalPercentBarSeriesPrivate(this), parent)
13 13 {
14 14 }
15 15
16 16 QAbstractSeries::SeriesType QHorizontalPercentBarSeries::type() const
17 17 {
18 18 return QAbstractSeries::SeriesTypeHorizontalPercentBar;
19 19 }
20 20
21 21 QHorizontalPercentBarSeries::~QHorizontalPercentBarSeries()
22 22 {
23 23 Q_D(QHorizontalPercentBarSeries);
24 24 if(d->m_dataset) {
25 25 d->m_dataset->removeSeries(this);
26 26 }
27 27 }
28 28
29 29 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 30
31 31 QHorizontalPercentBarSeriesPrivate::QHorizontalPercentBarSeriesPrivate(QHorizontalPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
32 32 {
33 33
34 34 }
35 35
36 36 void QHorizontalPercentBarSeriesPrivate::scaleDomain(Domain& domain)
37 37 {
38 38 qreal minX(domain.minX());
39 39 qreal minY(domain.minY());
40 40 qreal maxX(domain.maxX());
41 41 qreal maxY(domain.maxY());
42 42
43 43 qreal y = categoryCount();
44 44 minX = 0;
45 45 maxX = 100;
46 46 minY = qMin(minY, - (qreal)0.5);
47 47 maxY = qMax(maxY, y - (qreal)0.5);
48 48
49 49 domain.setRange(minX,maxX,minY,maxY);
50 50 }
51 51
52 52 Chart* QHorizontalPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
53 53 {
54 54 Q_Q(QHorizontalPercentBarSeries);
55 55
56 56 HorizontalPercentBarChartItem* bar = new HorizontalPercentBarChartItem(q,presenter);
57 57 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
58 bar->setAnimator(presenter->animator());
59 58 bar->setAnimation(new HorizontalPercentBarAnimation(bar));
60 59 }
61 60 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
62 61 return bar;
63 62 }
64 63
65 64 #include "moc_qhorizontalpercentbarseries.cpp"
66 65
67 66 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,68 +1,67
1 1 #include "qhorizontalstackedbarseries.h"
2 2 #include "qhorizontalstackedbarseries_p.h"
3 3 #include "horizontalstackedbarchartitem_p.h"
4 4 #include "horizontalstackedbaranimation_p.h"
5 5
6 6 #include "chartdataset_p.h"
7 7 #include "charttheme_p.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QHorizontalStackedBarSeries::QHorizontalStackedBarSeries(QObject *parent) :
12 12 QAbstractBarSeries(*new QHorizontalStackedBarSeriesPrivate(this), parent)
13 13 {
14 14 }
15 15
16 16 QHorizontalStackedBarSeries::~QHorizontalStackedBarSeries()
17 17 {
18 18 Q_D(QHorizontalStackedBarSeries);
19 19 if(d->m_dataset) {
20 20 d->m_dataset->removeSeries(this);
21 21 }
22 22 }
23 23
24 24 QAbstractSeries::SeriesType QHorizontalStackedBarSeries::type() const
25 25 {
26 26 return QAbstractSeries::SeriesTypeHorizontalStackedBar;
27 27 }
28 28
29 29 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 30
31 31 QHorizontalStackedBarSeriesPrivate::QHorizontalStackedBarSeriesPrivate(QHorizontalStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
32 32 {
33 33
34 34 }
35 35
36 36 void QHorizontalStackedBarSeriesPrivate::scaleDomain(Domain& domain)
37 37 {
38 38 qreal minX(domain.minX());
39 39 qreal minY(domain.minY());
40 40 qreal maxX(domain.maxX());
41 41 qreal maxY(domain.maxY());
42 42
43 43 qreal y = categoryCount();
44 44 qreal x = maxCategorySum();
45 45 minX = qMin(minX, x);
46 46 minY = qMin(minY, - (qreal)0.5);
47 47 maxX = qMax(maxX, x);
48 48 maxY = qMax(maxY, y - (qreal)0.5);
49 49
50 50 domain.setRange(minX,maxX,minY,maxY);
51 51 }
52 52
53 53 Chart* QHorizontalStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
54 54 {
55 55 Q_Q(QHorizontalStackedBarSeries);
56 56
57 57 HorizontalStackedBarChartItem* bar = new HorizontalStackedBarChartItem(q,presenter);
58 58 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
59 bar->setAnimator(presenter->animator());
60 59 bar->setAnimation(new HorizontalStackedBarAnimation(bar));
61 60 }
62 61 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
63 62 return bar;
64 63 }
65 64
66 65 #include "moc_qhorizontalstackedbarseries.cpp"
67 66
68 67 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,124 +1,122
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 "qbarseries.h"
22 22 #include "qbarseries_p.h"
23 23 #include "barchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
27 26 #include "baranimation_p.h"
28 27 #include "qvaluesaxis.h"
29 28 #include "qbarcategoriesaxis.h"
30 29
31 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 31
33 32 /*!
34 33 \class QBarSeries
35 34 \brief Series for creating bar chart
36 35 \mainclass
37 36
38 37 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
39 38 as groups, where bars in same category are grouped next to each other. QBarSeries groups the data
40 39 from sets to categories, which are defined by a QStringList.
41 40
42 41 See the \l {BarChart Example} {bar chart example} to learn how to create a grouped bar chart.
43 42 \image examples_barchart.png
44 43
45 44 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries
46 45 */
47 46 /*!
48 47 \qmlclass BarSeries QBarSeries
49 48 \inherits AbstractBarSeries
50 49
51 50 The following QML shows how to create a simple grouped bar chart:
52 51 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
53 52 \beginfloatleft
54 53 \image demos_qmlchart6.png
55 54 \endfloat
56 55 \clearfloat
57 56 */
58 57
59 58 /*!
60 59 Constructs empty QBarSeries.
61 60 QBarSeries is QObject which is a child of a \a parent.
62 61 */
63 62 QBarSeries::QBarSeries(QObject *parent)
64 63 : QAbstractBarSeries(*new QBarSeriesPrivate(this), parent)
65 64 {
66 65 }
67 66
68 67 /*!
69 68 Returns QChartSeries::SeriesTypeBar.
70 69 */
71 70 QAbstractSeries::SeriesType QBarSeries::type() const
72 71 {
73 72 return QAbstractSeries::SeriesTypeBar;
74 73 }
75 74
76 75 QBarSeries::~QBarSeries()
77 76 {
78 77 Q_D(QBarSeries);
79 78 if(d->m_dataset) {
80 79 d->m_dataset->removeSeries(this);
81 80 }
82 81 }
83 82 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 83
85 84 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractBarSeriesPrivate(q)
86 85 {
87 86
88 87 }
89 88
90 89 void QBarSeriesPrivate::scaleDomain(Domain& domain)
91 90 {
92 91 qreal minX(domain.minX());
93 92 qreal minY(domain.minY());
94 93 qreal maxX(domain.maxX());
95 94 qreal maxY(domain.maxY());
96 95
97 96 qreal x = categoryCount();
98 97 qreal y = max();
99 98 minX = qMin(minX, - (qreal)0.5);
100 99 minY = qMin(minY, y);
101 100 maxX = qMax(maxX, x - (qreal)0.5);
102 101 maxY = qMax(maxY, y);
103 102
104 103 domain.setRange(minX,maxX,minY,maxY);
105 104 }
106 105
107 106
108 107 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
109 108 {
110 109 Q_Q(QBarSeries);
111 110
112 111 BarChartItem* bar = new BarChartItem(q,presenter);
113 112 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
114 bar->setAnimator(presenter->animator());
115 113 bar->setAnimation(new BarAnimation(bar));
116 114 }
117 115 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
118 116 return bar;
119 117 }
120 118
121 119 #include "moc_qbarseries.cpp"
122 120
123 121 QTCOMMERCIALCHART_END_NAMESPACE
124 122
@@ -1,102 +1,101
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 "percentbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qabstractbarseries_p.h"
24 24 #include "qbarset.h"
25 #include "chartanimator_p.h"
26 25 #include "qbarset_p.h"
27 26
28 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 28
30 29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
31 30 AbstractBarChartItem(series, presenter)
32 31 {
33 32 }
34 33
35 34 QVector<QRectF> PercentBarChartItem::calculateLayout()
36 35 {
37 36 QVector<QRectF> layout;
38 37
39 38 // Use temporary qreals for accuracy
40 39 qreal categoryCount = m_series->d_func()->categoryCount();
41 40 qreal setCount = m_series->count();
42 41 bool barsVisible = m_series->isVisible();
43 42
44 43 // Domain:
45 44 qreal width = geometry().width();
46 45 qreal height = geometry().height();
47 46 qreal rangeY = m_domainMaxY - m_domainMinY;
48 47 qreal rangeX = m_domainMaxX - m_domainMinX;
49 48 qreal scaleY = (height / rangeY);
50 49 qreal scaleX = (width / rangeX);
51 50 qreal barWidth = scaleX * m_series->d_func()->barWidth();
52 51
53 52 int itemIndex(0);
54 53 for (int category = 0; category < categoryCount; category++) {
55 54 qreal colSum = m_series->d_func()->categorySum(category);
56 55 qreal percentage = (100 / colSum);
57 56 qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y();
58 57 for (int set=0; set < setCount; set++) {
59 58 QBarSetPrivate* barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
60 59
61 60 qreal xPos = (barSet->pos(category) - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
62 61
63 62 qreal barHeight = barSet->value(category) * percentage * scaleY;
64 63 Bar* bar = m_bars.at(itemIndex);
65 64 bar->setPen(barSet->m_pen);
66 65 bar->setBrush(barSet->m_brush);
67 66 if (qFuzzyIsNull(barHeight)) {
68 67 bar->setVisible(false);
69 68 } else {
70 69 bar->setVisible(barsVisible);
71 70 }
72 71
73 72 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
74 73 layout.append(rect);
75 74
76 75 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
77 76
78 77 if (!qFuzzyIsNull(m_series->d_func()->valueAt(set,category))) {
79 78 int p = m_series->d_func()->percentageAt(set,category) * 100;
80 79 QString vString(QString::number(p));
81 80 vString.truncate(3);
82 81 vString.append("%");
83 82 label->setText(vString);
84 83 } else {
85 84 label->setText(QString(""));
86 85 }
87 86
88 87 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
89 88 ,yPos - barHeight/2 - label->boundingRect().height()/2);
90 89 label->setFont(barSet->m_labelFont);
91 90 label->setBrush(barSet->m_labelBrush);
92 91
93 92 itemIndex++;
94 93 yPos -= barHeight;
95 94 }
96 95 }
97 96 return layout;
98 97 }
99 98
100 99 #include "moc_percentbarchartitem_p.cpp"
101 100
102 101 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,123 +1,121
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 "qpercentbarseries.h"
22 22 #include "qpercentbarseries_p.h"
23 23 #include "percentbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
27 26 #include "qvaluesaxis.h"
28 27 #include "percentbaranimation_p.h"
29 28
30 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 30
32 31 /*!
33 32 \class QPercentBarSeries
34 33 \brief Series for creating percent bar chart
35 34 \mainclass
36 35
37 36 QPercentBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 37 as stacks, where each bar is shown as percentage of all bars in that category.
39 38 QPercentBarSeries groups the data from sets to categories, which are defined by a QStringList.
40 39
41 40 See the \l {PercentbarChart Example} {percent bar chart example} to learn how to create a percent bar chart.
42 41 \image examples_percentbarchart.png
43 42
44 43 \sa QBarSet, QStackedBarSeries, QAbstractBarSeries
45 44 */
46 45 /*!
47 46 \qmlclass PercentBarSeries QPercentBarSeries
48 47 \inherits QAbstractBarSeries
49 48
50 49 The following QML shows how to create a simple percent bar chart:
51 50 \snippet ../demos/qmlchart/qml/qmlchart/View8.qml 1
52 51 \beginfloatleft
53 52 \image demos_qmlchart8.png
54 53 \endfloat
55 54 \clearfloat
56 55 */
57 56
58 57 /*!
59 58 Constructs empty QPercentBarSeries.
60 59 QPercentBarSeries is QObject which is a child of a \a parent.
61 60 */
62 61 QPercentBarSeries::QPercentBarSeries(QObject *parent)
63 62 : QAbstractBarSeries(*new QPercentBarSeriesPrivate(this), parent)
64 63 {
65 64 }
66 65
67 66 QPercentBarSeries::~QPercentBarSeries()
68 67 {
69 68 Q_D(QPercentBarSeries);
70 69 if(d->m_dataset) {
71 70 d->m_dataset->removeSeries(this);
72 71 }
73 72 }
74 73
75 74 /*!
76 75 Returns QChartSeries::SeriesTypePercentBar.
77 76 */
78 77 QAbstractSeries::SeriesType QPercentBarSeries::type() const
79 78 {
80 79 return QAbstractSeries::SeriesTypePercentBar;
81 80 }
82 81
83 82 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 83
85 84 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
86 85 {
87 86
88 87 }
89 88
90 89 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
91 90 {
92 91 qreal minX(domain.minX());
93 92 qreal minY(domain.minY());
94 93 qreal maxX(domain.maxX());
95 94 qreal maxY(domain.maxY());
96 95
97 96 qreal x = categoryCount();
98 97 minX = qMin(minX, - (qreal)0.5);
99 98 maxX = qMax(maxX, x - (qreal)0.5);
100 99 minY = 0;
101 100 maxY = 100;
102 101
103 102 domain.setRange(minX,maxX,minY,maxY);
104 103 }
105 104
106 105
107 106 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
108 107 {
109 108 Q_Q(QPercentBarSeries);
110 109
111 110 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
112 111 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
113 bar->setAnimator(presenter->animator());
114 112 bar->setAnimation(new PercentBarAnimation(bar));
115 113 }
116 114 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
117 115 return bar;
118 116 }
119 117
120 118 #include "moc_qpercentbarseries.cpp"
121 119
122 120 QTCOMMERCIALCHART_END_NAMESPACE
123 121
@@ -1,124 +1,122
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 "qstackedbarseries.h"
22 22 #include "qstackedbarseries_p.h"
23 23 #include "stackedbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
27 26 #include "qvaluesaxis.h"
28 27 #include "stackedbaranimation_p.h"
29 28
30 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 30
32 31 /*!
33 32 \class QStackedBarSeries
34 33 \brief Series for creating stacked bar chart
35 34 \mainclass
36 35
37 36 QStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 37 as stacks, where bars in same category are stacked on top of each other.
39 38 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
40 39
41 40 See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
42 41 \image examples_stackedbarchart.png
43 42
44 43 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries
45 44 */
46 45
47 46 /*!
48 47 \qmlclass StackedBarSeries QStackedBarSeries
49 48 \inherits AbstractBarSeries
50 49
51 50 The following QML shows how to create a simple stacked bar chart:
52 51 \snippet ../demos/qmlchart/qml/qmlchart/View7.qml 1
53 52 \beginfloatleft
54 53 \image demos_qmlchart7.png
55 54 \endfloat
56 55 \clearfloat
57 56 */
58 57
59 58 /*!
60 59 Constructs empty QStackedBarSeries.
61 60 QStackedBarSeries is QObject which is a child of a \a parent.
62 61 */
63 62 QStackedBarSeries::QStackedBarSeries(QObject *parent)
64 63 : QAbstractBarSeries(*new QStackedBarSeriesPrivate(this), parent)
65 64 {
66 65 }
67 66
68 67 QStackedBarSeries::~QStackedBarSeries()
69 68 {
70 69 Q_D(QStackedBarSeries);
71 70 if(d->m_dataset) {
72 71 d->m_dataset->removeSeries(this);
73 72 }
74 73 }
75 74 /*!
76 75 Returns QChartSeries::SeriesTypeStackedBar.
77 76 */
78 77 QAbstractSeries::SeriesType QStackedBarSeries::type() const
79 78 {
80 79 return QAbstractSeries::SeriesTypeStackedBar;
81 80 }
82 81
83 82 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 83
85 84 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
86 85 {
87 86
88 87 }
89 88
90 89 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
91 90 {
92 91 qreal minX(domain.minX());
93 92 qreal minY(domain.minY());
94 93 qreal maxX(domain.maxX());
95 94 qreal maxY(domain.maxY());
96 95
97 96 qreal x = categoryCount();
98 97 qreal y = maxCategorySum();
99 98 minX = qMin(minX, - (qreal)0.5);
100 99 minY = qMin(minY, y);
101 100 maxX = qMax(maxX, x - (qreal)0.5);
102 101 maxY = qMax(maxY, y);
103 102
104 103 domain.setRange(minX,maxX,minY,maxY);
105 104 }
106 105
107 106
108 107 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
109 108 {
110 109 Q_Q(QStackedBarSeries);
111 110
112 111 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
113 112 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
114 bar->setAnimator(presenter->animator());
115 113 bar->setAnimation(new StackedBarAnimation(bar));
116 114 }
117 115 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
118 116 return bar;
119 117 }
120 118
121 119 #include "moc_qstackedbarseries.cpp"
122 120
123 121 QTCOMMERCIALCHART_END_NAMESPACE
124 122
@@ -1,95 +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 #include "stackedbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qbarset_p.h"
24 24 #include "qabstractbarseries_p.h"
25 25 #include "qbarset.h"
26 #include "chartanimator_p.h"
27 26
28 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 28
30 29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
31 30 AbstractBarChartItem(series, presenter)
32 31 {
33 32 }
34 33
35 34 QVector<QRectF> StackedBarChartItem::calculateLayout()
36 35 {
37 36 QVector<QRectF> layout;
38 37 // Use temporary qreals for accuracy
39 38 qreal categoryCount = m_series->d_func()->categoryCount();
40 39 qreal setCount = m_series->count();
41 40 bool barsVisible = m_series->isVisible();
42 41
43 42 // Domain:
44 43 qreal width = geometry().width();
45 44 qreal height = geometry().height();
46 45 qreal rangeY = m_domainMaxY - m_domainMinY;
47 46 qreal rangeX = m_domainMaxX - m_domainMinX;
48 47 qreal scaleY = (height / rangeY);
49 48 qreal scaleX = (width / rangeX);
50 49 qreal barWidth = scaleX * m_series->d_func()->barWidth();
51 50
52 51 int itemIndex(0);
53 52 for (int category = 0; category < categoryCount; category++) {
54 53 qreal yPos = height + rangeY * m_domainMinY + geometry().topLeft().y();
55 54 for (int set=0; set < setCount; set++) {
56 55 QBarSetPrivate* barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
57 56
58 57 qreal xPos = (barSet->pos(category) - m_domainMinX) * scaleX + m_rect.left() - barWidth/2;
59 58
60 59 qreal barHeight = barSet->value(category) * scaleY;
61 60 Bar* bar = m_bars.at(itemIndex);
62 61 bar->setPen(barSet->m_pen);
63 62 bar->setBrush(barSet->m_brush);
64 63 if (qFuzzyIsNull(barHeight)) {
65 64 bar->setVisible(false);
66 65 } else {
67 66 bar->setVisible(barsVisible);
68 67 }
69 68
70 69 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
71 70 layout.append(rect);
72 71
73 72 QGraphicsSimpleTextItem* label = m_labels.at(itemIndex);
74 73
75 74 if (!qFuzzyIsNull(barSet->value(category))) {
76 75 label->setText(QString::number(barSet->value(category)));
77 76 } else {
78 77 label->setText(QString(""));
79 78 }
80 79
81 80 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
82 81 ,yPos - barHeight/2 - label->boundingRect().height()/2);
83 82 label->setFont(barSet->m_labelFont);
84 83 label->setBrush(barSet->m_labelBrush);
85 84 itemIndex++;
86 85 yPos -= barHeight;
87 86 }
88 87 }
89 88
90 89 return layout;
91 90 }
92 91
93 92 #include "moc_stackedbarchartitem_p.cpp"
94 93
95 94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,76
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 "chart_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "domain_p.h"
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 Chart::Chart(ChartPresenter *presenter):QObject(presenter),
28 m_animator(0),
29 28 m_presenter(presenter),
30 29 m_domain(0)
31 30 {
32 31 }
33 32
34 void Chart::setAnimator(ChartAnimator* animator)
35 {
36 m_animator=animator;
37 }
38
39 ChartAnimator* Chart::animator() const
40 {
41 return m_animator;
42 }
43
44
45 33 void Chart::setPresenter(ChartPresenter *presenter)
46 34 {
47 35 m_presenter=presenter;
48 36 }
49 37
50 38 ChartPresenter* Chart::presenter() const
51 39 {
52 40 return m_presenter;
53 41 }
54 42
55 43 void Chart::setDomain(Domain *domain)
56 44 {
57 45 m_domain=domain;
58 46 }
59 47
60 48 Domain* Chart::domain() const
61 49 {
62 50 return m_domain;
63 51 }
64 52
65 53 void Chart::handleGeometryChanged(const QRectF& rect)
66 54 {
67 55 Q_UNUSED(rect);
68 56 qWarning()<<"Slot not implemented";
69 57 }
70 58
71 59 void Chart::handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY)
72 60 {
73 61 Q_UNUSED(minX);
74 62 Q_UNUSED(maxX);
75 63 Q_UNUSED(minY);
76 64 Q_UNUSED(maxY);
77 65 qWarning()<<"Slot not implemented";
78 66 }
79 67
80 68 void Chart::handleDomainUpdated()
81 69 {
82 70 qWarning()<<"Slot not implemented";
83 71 }
84 72
85 73
86 74 #include "moc_chart_p.cpp"
87 75
88 76 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,69
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHART_H
31 31 #define CHART_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QObject>
35 35 #include <QRect>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class ChartAnimator;
40 40 class ChartPresenter;
41 41 class ChartAnimation;
42 42 class Domain;
43 43
44 44 class Chart: public QObject
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 explicit Chart(ChartPresenter *presenter);
49 49
50 50 public Q_SLOTS:
51 51 virtual void handleGeometryChanged(const QRectF& rect);
52 52 virtual void handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY);
53 53 virtual void handleDomainUpdated();
54 virtual ChartAnimation* animation() const { return 0; };
54 55
55 void setAnimator(ChartAnimator* animator);
56 ChartAnimator* animator() const;
57 56 void setPresenter(ChartPresenter *presenter);
58 57 ChartPresenter* presenter() const;
59 58 void setDomain(Domain *domain);
60 59 Domain* domain() const;
61 virtual ChartAnimation* animation() const { return 0; };
60
62 61
63 62 private:
64 ChartAnimator* m_animator;
65 63 ChartPresenter* m_presenter;
66 64 Domain* m_domain;
67 65 };
68 66
69 67 QTCOMMERCIALCHART_END_NAMESPACE
70 68
71 69 #endif
@@ -1,469 +1,450
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 "qabstractaxis.h"
24 24 #include "qabstractaxis_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
28 27 #include "chartanimation_p.h"
29 28 #include "qabstractseries_p.h"
30 29 #include "qareaseries.h"
31 30 #include "chartaxis_p.h"
32 31 //#include "chartaxisx_p.h"
33 32 //#include "chartaxisy_p.h"
34 33 #include "areachartitem_p.h"
35 34 #include "chartbackground_p.h"
36 35 #include "chartlayout_p.h"
37 36 #include <QTimer>
38 37
39 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 39
41 40 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
42 41 m_chart(chart),
43 m_animator(0),
44 42 m_dataset(dataset),
45 43 m_chartTheme(0),
46 44 m_options(QChart::NoAnimation),
47 45 m_state(ShowState),
48 46 m_layout(new ChartLayout(this)),
49 47 m_backgroundItem(0),
50 48 m_titleItem(0)
51 49 {
52 50
53 51 }
54 52
55 53 ChartPresenter::~ChartPresenter()
56 54 {
57 55 delete m_chartTheme;
58 56 }
59 57
60 58 void ChartPresenter::setGeometry(const QRectF& rect)
61 59 {
62 60
63 61 Q_ASSERT(rect.isValid());
64 62
65 63 if(m_rect!=rect) {
66 64 m_rect=rect;
67 65 emit geometryChanged(m_rect);
68 66 }
69 67 }
70 68
71 69 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
72 70 {
73 71 ChartAxis* item = axis->d_ptr->createGraphics(this);
74 72 item->setDomain(domain);
75 73
76 74 if(m_options.testFlag(QChart::GridAxisAnimations)){
77 item->setAnimator(m_animator);
78 75 item->setAnimation(new AxisAnimation(item));
79 76 }
80 77
81 78 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
82 79 QObject::connect(domain,SIGNAL(updated()),item,SLOT(handleDomainUpdated()));
83 80 QObject::connect(axis,SIGNAL(visibleChanged(bool)),this,SLOT(handleAxisVisibleChanged(bool)));
84 81
85 82 //initialize
86 83 domain->emitUpdated();
87 84 m_chartTheme->decorate(axis);
88 85 axis->d_ptr->setDirty(false);
89 86 axis->d_ptr->emitUpdated();
90 87 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
91 88
92 89 m_axisItems.insert(axis, item);
93 90 selectVisibleAxis();
94 91 }
95 92
96 93 void ChartPresenter::handleAxisRemoved(QAbstractAxis* axis)
97 94 {
98 95 ChartAxis* item = m_axisItems.take(axis);
99 96 Q_ASSERT(item);
100 97 selectVisibleAxis();
101 if(m_animator) m_animator->removeAnimation(item);
102 98 item->hide();
103 99 item->disconnect();
104 100 QObject::disconnect(this,0,item,0);
105 101 item->deleteLater();
106 102 }
107 103
108 104
109 105 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
110 106 {
111 107 Chart *item = series->d_ptr->createGraphics(this);
112 108 Q_ASSERT(item);
113 109 item->setDomain(domain);
114 110
115 111 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
116 112 QObject::connect(domain,SIGNAL(updated()),item,SLOT(handleDomainUpdated()));
117 113 //initialize
118 114 item->handleDomainUpdated();
119 115
120 116 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
121 117 m_chartItems.insert(series,item);
122 118 }
123 119
124 120 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
125 121 {
126 122 Chart* item = m_chartItems.take(series);
127 123 Q_ASSERT(item);
128 if(m_animator) {
129 //small hack to handle area animations
130 if(series->type() == QAbstractSeries::SeriesTypeArea){
131 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
132 AreaChartItem* area = static_cast<AreaChartItem*>(item);
133 m_animator->removeAnimation(area->upperLineItem());
134 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
135 }else
136 m_animator->removeAnimation(item);
137 }
138 124 item->deleteLater();
139 125 }
140 126
141 127 void ChartPresenter::selectVisibleAxis()
142 128 {
143 129 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
144 130
145 131 while (i.hasNext()) {
146 132 i.next();
147 133 i.key()->hide();
148 134 }
149 135
150 136 i.toFront();
151 137
152 138 bool axisX=false;
153 139 bool axisY=false;
154 140
155 141 while (i.hasNext()) {
156 142 i.next();
157 143 if(i.key()->orientation()==Qt::Vertical && !axisY) {
158 144 axisY=true;
159 145 i.key()->show();
160 146 }
161 147 if(i.key()->orientation()==Qt::Horizontal && !axisX) {
162 148 axisX=true;
163 149 i.key()->show();
164 150 }
165 151
166 152 }
167 153 }
168 154
169 155
170 156 void ChartPresenter::handleAxisVisibleChanged(bool visible)
171 157 {
172 158 QAbstractAxis* axis = static_cast<QAbstractAxis*> (sender());
173 159 Q_ASSERT(axis);
174 160 if(visible){
175 161
176 162 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
177 163
178 164 while (i.hasNext()) {
179 165 i.next();
180 166 if(i.key()==axis) {
181 167 continue;
182 168 }
183 169 if(i.key()->orientation()==axis->orientation()) {
184 170 i.key()->setVisible(false);
185 171 }
186 172 }
187 173 }
188 174 }
189 175
190 176 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
191 177 {
192 178 if(m_chartTheme && m_chartTheme->id() == theme) return;
193 179 delete m_chartTheme;
194 180 m_chartTheme = ChartTheme::createTheme(theme);
195 181 m_chartTheme->setForced(force);
196 182 m_chartTheme->decorate(m_chart);
197 183 m_chartTheme->decorate(m_chart->legend());
198 184 resetAllElements();
199 185
200 186 // We do not want "force" to stay on.
201 187 // Bar/pie are calling decorate when adding/removing slices/bars which means
202 188 // that to preserve users colors "force" must not be on.
203 189 m_chartTheme->setForced(false);
204 190 }
205 191
206 192 QChart::ChartTheme ChartPresenter::theme()
207 193 {
208 194 return m_chartTheme->id();
209 195 }
210 196
211 197 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
212 198 {
213 199 if(m_options!=options) {
214
215 200 m_options=options;
216
217 if(m_options!=QChart::NoAnimation && !m_animator) {
218 m_animator= new ChartAnimator(this);
219 }
220 201 resetAllElements();
221 202 }
222 203
223 204 }
224 205
225 206 void ChartPresenter::resetAllElements()
226 207 {
227 208 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
228 209 while (i.hasNext()) {
229 210 i.next();
230 211 Domain* domain = i.value()->domain();
231 212 QAbstractAxis* axis = i.key();
232 213 handleAxisRemoved(axis);
233 214 handleAxisAdded(axis,domain);
234 215 }
235 216
236 217 QMapIterator<QAbstractSeries*, Chart*> j(m_chartItems);
237 218 while (j.hasNext()) {
238 219 j.next();
239 220 Domain* domain = j.value()->domain();
240 221 QAbstractSeries* series = j.key();
241 222 handleSeriesRemoved(series);
242 223 handleSeriesAdded(series,domain);
243 224 }
244 225 }
245 226
246 227 void ChartPresenter::zoomIn(qreal factor)
247 228 {
248 229 QRectF rect = geometry();
249 230 rect.setWidth(rect.width()/factor);
250 231 rect.setHeight(rect.height()/factor);
251 232 rect.moveCenter(geometry().center());
252 233 zoomIn(rect);
253 234 }
254 235
255 236 void ChartPresenter::zoomIn(const QRectF& rect)
256 237 {
257 238 QRectF r = rect.normalized();
258 239 r.translate(-geometry().topLeft());
259 240 if (!r.isValid())
260 241 return;
261 242
262 243 m_state = ZoomInState;
263 244 m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
264 245 m_dataset->zoomInDomain(r,geometry().size());
265 246 m_state = ShowState;
266 247 }
267 248
268 249 void ChartPresenter::zoomOut(qreal factor)
269 250 {
270 251 m_state = ZoomOutState;
271 252
272 253 QRectF chartRect;
273 254 chartRect.setSize(geometry().size());
274 255
275 256 QRectF rect;
276 257 rect.setSize(chartRect.size()/factor);
277 258 rect.moveCenter(chartRect.center());
278 259 if (!rect.isValid())
279 260 return;
280 261 m_statePoint = QPointF(rect.center().x()/geometry().width(),rect.center().y()/geometry().height());
281 262 m_dataset->zoomOutDomain(rect, chartRect.size());
282 263 m_state = ShowState;
283 264 }
284 265
285 266 void ChartPresenter::scroll(qreal dx,qreal dy)
286 267 {
287 268 if(dx<0) m_state=ScrollLeftState;
288 269 if(dx>0) m_state=ScrollRightState;
289 270 if(dy<0) m_state=ScrollUpState;
290 271 if(dy>0) m_state=ScrollDownState;
291 272
292 273 m_dataset->scrollDomain(dx,dy,geometry().size());
293 274 m_state = ShowState;
294 275 }
295 276
296 277 QChart::AnimationOptions ChartPresenter::animationOptions() const
297 278 {
298 279 return m_options;
299 280 }
300 281
301 282 void ChartPresenter::createBackgroundItem()
302 283 {
303 284 if (!m_backgroundItem) {
304 285 m_backgroundItem = new ChartBackground(rootItem());
305 286 m_backgroundItem->setPen(Qt::NoPen);
306 287 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
307 288 }
308 289 }
309 290
310 291 void ChartPresenter::createTitleItem()
311 292 {
312 293 if (!m_titleItem) {
313 294 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
314 295 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
315 296 }
316 297 }
317 298
318 299
319 300 void ChartPresenter::handleAnimationFinished()
320 301 {
321 302 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
322 303 if(m_animations.empty()) emit animationsFinished();
323 304 }
324 305
325 306 void ChartPresenter::startAnimation(ChartAnimation* animation)
326 307 {
327 308 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
328 309 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
329 310 if(!m_animations.isEmpty()){
330 311 m_animations.append(animation);
331 312 }
332 313 QTimer::singleShot(0, animation, SLOT(start()));
333 314 }
334 315
335 316 QGraphicsRectItem* ChartPresenter::backgroundItem()
336 317 {
337 318 return m_backgroundItem;
338 319 }
339 320
340 321 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
341 322 {
342 323 createBackgroundItem();
343 324 m_backgroundItem->setBrush(brush);
344 325 m_layout->invalidate();
345 326 }
346 327
347 328 QBrush ChartPresenter::backgroundBrush() const
348 329 {
349 330 if (!m_backgroundItem) return QBrush();
350 331 return m_backgroundItem->brush();
351 332 }
352 333
353 334 void ChartPresenter::setBackgroundPen(const QPen& pen)
354 335 {
355 336 createBackgroundItem();
356 337 m_backgroundItem->setPen(pen);
357 338 m_layout->invalidate();
358 339 }
359 340
360 341 QPen ChartPresenter::backgroundPen() const
361 342 {
362 343 if (!m_backgroundItem) return QPen();
363 344 return m_backgroundItem->pen();
364 345 }
365 346
366 347 QGraphicsItem* ChartPresenter::titleItem()
367 348 {
368 349 return m_titleItem;
369 350 }
370 351
371 352 void ChartPresenter::setTitle(const QString& title)
372 353 {
373 354 createTitleItem();
374 355 m_titleItem->setText(title);
375 356 m_layout->invalidate();
376 357 }
377 358
378 359 QString ChartPresenter::title() const
379 360 {
380 361 if (!m_titleItem) return QString();
381 362 return m_titleItem->text();
382 363 }
383 364
384 365 void ChartPresenter::setTitleFont(const QFont& font)
385 366 {
386 367 createTitleItem();
387 368 m_titleItem->setFont(font);
388 369 m_layout->invalidate();
389 370 }
390 371
391 372 QFont ChartPresenter::titleFont() const
392 373 {
393 374 if (!m_titleItem) return QFont();
394 375 return m_titleItem->font();
395 376 }
396 377
397 378 void ChartPresenter::setTitleBrush(const QBrush &brush)
398 379 {
399 380 createTitleItem();
400 381 m_titleItem->setBrush(brush);
401 382 m_layout->invalidate();
402 383 }
403 384
404 385 QBrush ChartPresenter::titleBrush() const
405 386 {
406 387 if (!m_titleItem) return QBrush();
407 388 return m_titleItem->brush();
408 389 }
409 390
410 391 void ChartPresenter::setBackgroundVisible(bool visible)
411 392 {
412 393 createBackgroundItem();
413 394 m_backgroundItem->setVisible(visible);
414 395 }
415 396
416 397
417 398 bool ChartPresenter::isBackgroundVisible() const
418 399 {
419 400 if (!m_backgroundItem) return false;
420 401 return m_backgroundItem->isVisible();
421 402 }
422 403
423 404 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
424 405 {
425 406 createBackgroundItem();
426 407 m_backgroundItem->setDropShadowEnabled(enabled);
427 408 }
428 409
429 410 bool ChartPresenter::isBackgroundDropShadowEnabled() const
430 411 {
431 412 if (!m_backgroundItem) return false;
432 413 return m_backgroundItem->isDropShadowEnabled();
433 414 }
434 415
435 416
436 417 QGraphicsLayout* ChartPresenter::layout()
437 418 {
438 419 return m_layout;
439 420 }
440 421
441 422 void ChartPresenter::setMarginsMinimum(const QRectF& margins)
442 423 {
443 424 Q_UNUSED(margins);
444 425 // m_layout->setMarginsMinimum(margins);
445 426 }
446 427
447 428 QRectF ChartPresenter::margins() const
448 429 {
449 430 return m_layout->margins();
450 431 }
451 432
452 433 QLegend* ChartPresenter::legend()
453 434 {
454 435 return m_chart->legend();
455 436 }
456 437
457 438 QList<ChartAxis*> ChartPresenter::axisItems() const
458 439 {
459 440 return m_axisItems.values();
460 441 }
461 442
462 443 void ChartPresenter::setVisible(bool visible)
463 444 {
464 445 m_chart->setVisible(visible);
465 446 }
466 447
467 448 #include "moc_chartpresenter_p.cpp"
468 449
469 450 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,176 +1,174
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTPRESENTER_H
31 31 #define CHARTPRESENTER_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
35 35 #include <QRectF>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class Chart;
40 40 class QAbstractSeries;
41 41 class ChartDataSet;
42 42 class Domain;
43 43 class ChartAxis;
44 44 class ChartTheme;
45 45 class ChartAnimator;
46 46 class ChartBackground;
47 47 class ChartAnimation;
48 48 class ChartLayout;
49 49
50 50 class ChartPresenter: public QObject
51 51 {
52 52 Q_OBJECT
53 53 public:
54 54 enum ZValues {
55 55 BackgroundZValue = -1,
56 56 ShadesZValue,
57 57 GridZValue,
58 58 SeriesZValue,
59 59 LineChartZValue = SeriesZValue,
60 60 BarSeriesZValue = SeriesZValue,
61 61 ScatterSeriesZValue = SeriesZValue,
62 62 PieSeriesZValue = SeriesZValue,
63 63 AxisZValue,
64 64 LegendZValue
65 65 };
66 66
67 67 enum State {
68 68 ShowState,
69 69 ScrollUpState,
70 70 ScrollDownState,
71 71 ScrollLeftState,
72 72 ScrollRightState,
73 73 ZoomInState,
74 74 ZoomOutState
75 75 };
76 76
77 77 ChartPresenter(QChart* chart,ChartDataSet *dataset);
78 78 virtual ~ChartPresenter();
79 79
80 ChartAnimator* animator() const { return m_animator; }
81 80 ChartTheme *chartTheme() const { return m_chartTheme; }
82 81 ChartDataSet *dataSet() const { return m_dataset; }
83 82 QGraphicsItem* rootItem() const { return m_chart; }
84 83 QGraphicsRectItem* backgroundItem();
85 84 QGraphicsItem* titleItem();
86 85 QList<ChartAxis*> axisItems() const;
87 86
88 87 QLegend* legend();
89 88
90 89 void setBackgroundBrush(const QBrush& brush);
91 90 QBrush backgroundBrush() const;
92 91
93 92 void setBackgroundPen(const QPen& pen);
94 93 QPen backgroundPen() const;
95 94
96 95 void setTitle(const QString& title);
97 96 QString title() const;
98 97
99 98 void setTitleFont(const QFont& font);
100 99 QFont titleFont() const;
101 100
102 101 void setTitleBrush(const QBrush &brush);
103 102 QBrush titleBrush() const;
104 103
105 104 void setBackgroundVisible(bool visible);
106 105 bool isBackgroundVisible() const;
107 106
108 107 void setBackgroundDropShadowEnabled(bool enabled);
109 108 bool isBackgroundDropShadowEnabled() const;
110 109
111 110 void setVisible(bool visible);
112 111
113 112 void setTheme(QChart::ChartTheme theme,bool force = true);
114 113 QChart::ChartTheme theme();
115 114
116 115 void setAnimationOptions(QChart::AnimationOptions options);
117 116 QChart::AnimationOptions animationOptions() const;
118 117
119 118 void zoomIn(qreal factor);
120 119 void zoomIn(const QRectF& rect);
121 120 void zoomOut(qreal factor);
122 121 void scroll(qreal dx,qreal dy);
123 122
124 123 void setGeometry(const QRectF& rect);
125 124 QRectF geometry() { return m_rect; }
126 125
127 126 void startAnimation(ChartAnimation* animation);
128 127 State state() const { return m_state; }
129 128 QPointF statePoint() const { return m_statePoint; }
130 129
131 130 void resetAllElements();
132 131
133 132 void setMarginsMinimum(const QRectF& margins);
134 133 QRectF margins() const;
135 134 QGraphicsLayout* layout();
136 135
137 136 private:
138 137 void createBackgroundItem();
139 138 void createTitleItem();
140 139 void selectVisibleAxis();
141 140
142 141 public Q_SLOTS:
143 142 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
144 143 void handleSeriesRemoved(QAbstractSeries* series);
145 144 void handleAxisAdded(QAbstractAxis* axis,Domain* domain);
146 145 void handleAxisRemoved(QAbstractAxis* axis);
147 146 void handleAxisVisibleChanged(bool visible);
148 147
149 148 private Q_SLOTS:
150 149 void handleAnimationFinished();
151 150
152 151 Q_SIGNALS:
153 152 void geometryChanged(const QRectF& rect);
154 153 void animationsFinished();
155 154 void marginsChanged(QRectF margins);
156 155
157 156 private:
158 157 QChart* m_chart;
159 ChartAnimator* m_animator;
160 158 ChartDataSet* m_dataset;
161 159 ChartTheme *m_chartTheme;
162 160 QMap<QAbstractSeries*, Chart*> m_chartItems;
163 161 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
164 162 QRectF m_rect;
165 163 QChart::AnimationOptions m_options;
166 164 State m_state;
167 165 QPointF m_statePoint;
168 166 QList<ChartAnimation*> m_animations;
169 167 ChartLayout* m_layout;
170 168 ChartBackground* m_backgroundItem;
171 169 QGraphicsSimpleTextItem* m_titleItem;
172 170 };
173 171
174 172 QTCOMMERCIALCHART_END_NAMESPACE
175 173
176 174 #endif /* CHARTPRESENTER_H_ */
@@ -1,134 +1,132
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 "qlineseries.h"
22 22 #include "qlineseries_p.h"
23 23 #include "linechartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
27 26
28 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 28
30 29 /*!
31 30 \class QLineSeries
32 31 \brief The QLineSeries class is used for making line charts.
33 32
34 33 \mainclass
35 34
36 35 A line chart is used to show information as a series of data points
37 36 connected by straight lines.
38 37
39 38 \image examples_linechart.png
40 39
41 40 Creating basic line chart is simple:
42 41 \code
43 42 QLineSeries* series = new QLineSeries();
44 43 series->append(0, 6);
45 44 series->append(2, 4);
46 45 ...
47 46 chart->addSeries(series);
48 47 \endcode
49 48 */
50 49 /*!
51 50 \qmlclass LineSeries QLineSeries
52 51 \inherits XYSeries
53 52
54 53 The following QML shows how to create a simple line chart:
55 54 \snippet ../demos/qmlchart/qml/qmlchart/View2.qml 1
56 55 \beginfloatleft
57 56 \image demos_qmlchart2.png
58 57 \endfloat
59 58 \clearfloat
60 59 */
61 60
62 61 /*!
63 62 \fn virtual SeriesType QLineSeries::type() const
64 63 \brief Returns type of series.
65 64 \sa QAbstractSeries, SeriesType
66 65 */
67 66
68 67 /*!
69 68 Constructs empty series object which is a child of \a parent.
70 69 When series object is added to QChartView or QChart instance ownerships is transferred.
71 70 */
72 71 QLineSeries::QLineSeries(QObject *parent) : QXYSeries(*new QLineSeriesPrivate(this),parent)
73 72 {
74 73
75 74 }
76 75
77 76 /*!
78 77 \internal
79 78 */
80 79 QLineSeries::QLineSeries(QLineSeriesPrivate &d,QObject *parent) : QXYSeries (d,parent)
81 80 {
82 81
83 82 }
84 83 /*!
85 84 Destroys the object. Series added to QChartView or QChart instances are owned by those,
86 85 and are deleted when mentioned object are destroyed.
87 86 */
88 87 QLineSeries::~QLineSeries()
89 88 {
90 89 Q_D(QLineSeries);
91 90 if(d->m_dataset){
92 91 d->m_dataset->removeSeries(this);
93 92 }
94 93 }
95 94
96 95 QAbstractSeries::SeriesType QLineSeries::type() const
97 96 {
98 97 return QAbstractSeries::SeriesTypeLine;
99 98 }
100 99
101 100 /*
102 101 QDebug operator<< (QDebug debug, const QLineSeries series)
103 102 {
104 103 Q_ASSERT(series.d_func()->m_x.size() == series.d_func()->m_y.size());
105 104 int size = series.d_func()->m_x.size();
106 105 for (int i=0; i<size; i++) {
107 106 debug.nospace() << "(" << series.d_func()->m_x.at(i) << ','<< series.d_func()->m_y.at(i) << ") ";
108 107 }
109 108 return debug.space();
110 109 }
111 110 */
112 111
113 112 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114 113
115 114 QLineSeriesPrivate::QLineSeriesPrivate(QLineSeries* q):QXYSeriesPrivate(q)
116 115 {
117 116
118 117 };
119 118
120 119 Chart* QLineSeriesPrivate::createGraphics(ChartPresenter* presenter)
121 120 {
122 121 Q_Q(QLineSeries);
123 122 LineChartItem* line = new LineChartItem(q,presenter);
124 123 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
125 line->setAnimator(presenter->animator());
126 124 line->setAnimation(new XYAnimation(line));
127 125 }
128 126 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
129 127 return line;
130 128 }
131 129
132 130 #include "moc_qlineseries.cpp"
133 131
134 132 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,226 +1,238
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 "piechartitem_p.h"
22 22 #include "piesliceitem_p.h"
23 23 #include "qpieslice.h"
24 24 #include "qpieslice_p.h"
25 25 #include "qpieseries.h"
26 26 #include "qpieseries_p.h"
27 27 #include "chartpresenter_p.h"
28 28 #include "chartdataset_p.h"
29 #include "chartanimator_p.h"
29 #include "pieanimation_p.h"
30 30 #include <QPainter>
31 31 #include <QTimer>
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
36 36 :ChartItem(presenter),
37 m_series(series)
37 m_series(series),
38 m_animation(0)
38 39 {
39 40 Q_ASSERT(series);
40 41
41 42 QPieSeriesPrivate *p = QPieSeriesPrivate::fromSeries(series);
42 43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
43 44 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
44 45 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
45 46 connect(p, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
46 47 connect(p, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
47 48 connect(p, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
48 49 connect(p, SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
49 50
50 51 // Note: the following does not affect as long as the item does not have anything to paint
51 52 setZValue(ChartPresenter::PieSeriesZValue);
52 53
53 54 // Note: will not create slice items until we have a proper rectangle to draw on.
54 55 }
55 56
56 57 PieChartItem::~PieChartItem()
57 58 {
58 59 // slices deleted automatically through QGraphicsItem
59 60 }
60 61
62 void PieChartItem::setAnimation(PieAnimation* animation)
63 {
64 m_animation=animation;
65 }
66
67 ChartAnimation* PieChartItem::animation() const
68 {
69 return m_animation;
70 }
71
61 72 void PieChartItem::handleGeometryChanged(const QRectF& rect)
62 73 {
63 74 prepareGeometryChange();
64 75 m_rect = rect;
65 76 updateLayout();
66 77
67 78 // This is for delayed initialization of the slice items during startup.
68 79 // It ensures that startup animation originates from the correct position.
69 80 if (m_sliceItems.isEmpty())
70 81 handleSlicesAdded(m_series->slices());
71 82 }
72 83
73 84 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
74 85 {
75 86 Q_UNUSED(minX);
76 87 Q_UNUSED(maxX);
77 88 Q_UNUSED(minY);
78 89 Q_UNUSED(maxY);
79 90 // does not apply to pie
80 91 }
81 92
82 93 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
83 94 {
84 95 Q_UNUSED(min);
85 96 Q_UNUSED(max);
86 97 Q_UNUSED(tickXCount);
87 98 // does not apply to pie
88 99 }
89 100
90 101 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
91 102 {
92 103 Q_UNUSED(min);
93 104 Q_UNUSED(max);
94 105 Q_UNUSED(tickYCount);
95 106 // does not apply to pie
96 107 }
97 108
98 109 void PieChartItem::updateLayout()
99 110 {
100 111 // find pie center coordinates
101 112 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
102 113 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
103 114
104 115 // find maximum radius for pie
105 116 m_pieRadius = m_rect.height() / 2;
106 117 if (m_rect.width() < m_rect.height())
107 118 m_pieRadius = m_rect.width() / 2;
108 119
109 120 m_donutInnerRadius = m_pieRadius;
110 121 // apply size factor
111 122 m_pieRadius *= m_series->pieSize();
112 123 m_donutInnerRadius *= m_series->donutInnerSize();
113 124
114 125 // set layouts for existing slice items
115 126 foreach (QPieSlice* slice, m_series->slices()) {
116 127 PieSliceItem *sliceItem = m_sliceItems.value(slice);
117 128 if (sliceItem) {
118 129 PieSliceData sliceData = updateSliceGeometry(slice);
119 if (animator())
120 animator()->updateAnimation(this, sliceItem, sliceData);
130 if (m_animation){
131 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
132 }
121 133 else
122 134 sliceItem->setLayout(sliceData);
123 135 }
124 136 }
125 137
126 138 update();
127 139 }
128 140
129 141 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
130 142 {
131 143 // delay creating slice items until there is a proper rectangle
132 144 if (!m_rect.isValid() && m_sliceItems.isEmpty())
133 145 return;
134 146
135 147 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
136 148
137 149 bool startupAnimation = m_sliceItems.isEmpty();
138 150
139 151 foreach (QPieSlice *slice, slices) {
140 152 PieSliceItem* sliceItem = new PieSliceItem(this);
141 153 m_sliceItems.insert(slice, sliceItem);
142 154
143 155 // Note: no need to connect to slice valueChanged() etc.
144 156 // This is handled through calculatedDataChanged signal.
145 157 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
146 158 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
147 159 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
148 160 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
149 161 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
150 162 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
151 163
152 164 QPieSlicePrivate *p = QPieSlicePrivate::fromSlice(slice);
153 165 connect(p, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
154 166 connect(p, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
155 167 connect(p, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
156 168 connect(p, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
157 169
158 170 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
159 171 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
160 172
161 173 PieSliceData sliceData = updateSliceGeometry(slice);
162 if (animator())
163 animator()->addAnimation(this, sliceItem, sliceData, startupAnimation);
174 if (m_animation)
175 presenter()->startAnimation(m_animation->addSlice(sliceItem, sliceData, startupAnimation));
164 176 else
165 177 sliceItem->setLayout(sliceData);
166 178 }
167 179 }
168 180
169 181 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
170 182 {
171 183 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
172 184
173 185 foreach (QPieSlice *slice, slices) {
174 186
175 187 PieSliceItem *sliceItem = m_sliceItems.value(slice);
176 188
177 189 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
178 190 if (!sliceItem)
179 191 continue;
180 192
181 193 m_sliceItems.remove(slice);
182 194
183 if (animator())
184 animator()->removeAnimation(this, sliceItem); // animator deletes the PieSliceItem
195 if (m_animation)
196 presenter()->startAnimation(m_animation->removeSlice(sliceItem)); // animator deletes the PieSliceItem
185 197 else
186 198 delete sliceItem;
187 199 }
188 200 }
189 201
190 202 void PieChartItem::handleSliceChanged()
191 203 {
192 204 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
193 205 if (!slice) {
194 206 QPieSlicePrivate* slicep = qobject_cast<QPieSlicePrivate *>(sender());
195 207 slice = slicep->q_ptr;
196 208 }
197 209 Q_ASSERT(m_sliceItems.contains(slice));
198 210
199 211 PieSliceItem *sliceItem = m_sliceItems.value(slice);
200 212 PieSliceData sliceData = updateSliceGeometry(slice);
201 if (animator())
202 animator()->updateAnimation(this, sliceItem, sliceData);
213 if (m_animation)
214 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
203 215 else
204 216 sliceItem->setLayout(sliceData);
205 217
206 218 update();
207 219 }
208 220
209 221 void PieChartItem::handleSeriesVisibleChanged()
210 222 {
211 223 setVisible(m_series->isVisible());
212 224 }
213 225
214 226 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
215 227 {
216 228 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
217 229 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
218 230 sliceData.m_radius = m_pieRadius;
219 231 sliceData.m_donut = m_series->donut();
220 232 sliceData.m_innerRadius = m_donutInnerRadius;
221 233 return sliceData;
222 234 }
223 235
224 236 #include "moc_piechartitem_p.cpp"
225 237
226 238 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,87
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef PIECHARTITEM_H
31 31 #define PIECHARTITEM_H
32 32
33 33 #include "qpieseries.h"
34 34 #include "chartitem_p.h"
35 35 #include "piesliceitem_p.h"
36 36
37 37 class QGraphicsItem;
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39 class QPieSlice;
40 40 class ChartPresenter;
41 class PieAnimation;
41 42
42 43 class PieChartItem : public ChartItem
43 44 {
44 45 Q_OBJECT
45 46
46 47 public:
47 48 explicit PieChartItem(QPieSeries *series, ChartPresenter *presenter);
48 49 ~PieChartItem();
49 50
50 51 // from QGraphicsItem
51 52 QRectF boundingRect() const { return m_rect; }
52 53 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
53 54
54 55 public Q_SLOTS:
55 56 // from Chart
56 57 virtual void handleGeometryChanged(const QRectF &rect);
57 58 virtual void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
58 59 virtual void rangeXChanged(qreal min, qreal max, int tickXCount);
59 60 virtual void rangeYChanged(qreal min, qreal max, int tickYCount);
60 61
61 62 void updateLayout();
62 63 void handleSlicesAdded(QList<QPieSlice*> slices);
63 64 void handleSlicesRemoved(QList<QPieSlice*> slices);
64 65 void handleSliceChanged();
65 66 void handleSeriesVisibleChanged();
66 67
68 void setAnimation(PieAnimation* animation);
69 ChartAnimation* animation() const;
70
67 71 private:
68 72 PieSliceData updateSliceGeometry(QPieSlice *slice);
69 73
70 74 private:
71 75 QHash<QPieSlice*, PieSliceItem*> m_sliceItems;
72 76 QPieSeries *m_series;
73 77 QRectF m_rect;
74 78 QPointF m_pieCenter;
75 79 qreal m_pieRadius;
76 80 qreal m_donutInnerRadius;
81 PieAnimation* m_animation;
82
77 83 };
78 84
79 85 QTCOMMERCIALCHART_END_NAMESPACE
80 86
81 87 #endif // PIECHARTITEM_H
@@ -1,857 +1,857
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 "qpieseries.h"
22 22 #include "qpieseries_p.h"
23 23 #include "qpieslice.h"
24 24 #include "qpieslice_p.h"
25 25 #include "pieslicedata_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "charttheme_p.h"
28 #include "chartanimator_p.h"
29 28 #include "legendmarker_p.h"
30 29 #include "qabstractaxis.h"
30 #include "pieanimation_p.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QPieSeries
36 36 \brief Pie series API for QtCommercial Charts
37 37
38 38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 40 The actual slice size is determined by that relative value.
41 41
42 42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 43 These relate to the actual chart rectangle.
44 44
45 45 By default the pie is defined as a full pie but it can also be a partial pie.
46 46 This can be done by setting a starting angle and angle span to the series.
47 47 Full pie is 360 degrees where 0 is at 12 a'clock.
48 48
49 49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 50 \image examples_piechart.png
51 51 */
52 52 /*!
53 53 \qmlclass PieSeries QPieSeries
54 54 \inherits AbstractSeries
55 55
56 56 The following QML shows how to create a simple pie chart.
57 57
58 58 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
59 59
60 60 \beginfloatleft
61 61 \image demos_qmlchart1.png
62 62 \endfloat
63 63 \clearfloat
64 64 */
65 65
66 66 /*!
67 67 \property QPieSeries::horizontalPosition
68 68 \brief Defines the horizontal position of the pie.
69 69
70 70 The value is a relative value to the chart rectangle where:
71 71
72 72 \list
73 73 \o 0.0 is the absolute left.
74 74 \o 1.0 is the absolute right.
75 75 \endlist
76 76 Default value is 0.5 (center).
77 77 \sa verticalPosition
78 78 */
79 79
80 80 /*!
81 81 \qmlproperty real PieSeries::horizontalPosition
82 82
83 83 Defines the horizontal position of the pie.
84 84
85 85 The value is a relative value to the chart rectangle where:
86 86
87 87 \list
88 88 \o 0.0 is the absolute left.
89 89 \o 1.0 is the absolute right.
90 90 \endlist
91 91 Default value is 0.5 (center).
92 92 \sa verticalPosition
93 93 */
94 94
95 95 /*!
96 96 \property QPieSeries::verticalPosition
97 97 \brief Defines the vertical position of the pie.
98 98
99 99 The value is a relative value to the chart rectangle where:
100 100
101 101 \list
102 102 \o 0.0 is the absolute top.
103 103 \o 1.0 is the absolute bottom.
104 104 \endlist
105 105 Default value is 0.5 (center).
106 106 \sa horizontalPosition
107 107 */
108 108
109 109 /*!
110 110 \qmlproperty real PieSeries::verticalPosition
111 111
112 112 Defines the vertical position of the pie.
113 113
114 114 The value is a relative value to the chart rectangle where:
115 115
116 116 \list
117 117 \o 0.0 is the absolute top.
118 118 \o 1.0 is the absolute bottom.
119 119 \endlist
120 120 Default value is 0.5 (center).
121 121 \sa horizontalPosition
122 122 */
123 123
124 124 /*!
125 125 \property QPieSeries::size
126 126 \brief Defines the pie size.
127 127
128 128 The value is a relative value to the chart rectangle where:
129 129
130 130 \list
131 131 \o 0.0 is the minimum size (pie not drawn).
132 132 \o 1.0 is the maximum size that can fit the chart.
133 133 \endlist
134 134
135 135 Default value is 0.7.
136 136 */
137 137
138 138 /*!
139 139 \qmlproperty real PieSeries::size
140 140
141 141 Defines the pie size.
142 142
143 143 The value is a relative value to the chart rectangle where:
144 144
145 145 \list
146 146 \o 0.0 is the minimum size (pie not drawn).
147 147 \o 1.0 is the maximum size that can fit the chart.
148 148 \endlist
149 149
150 150 Default value is 0.7.
151 151 */
152 152
153 153 /*!
154 154 \property QPieSeries::donutInnerSize
155 155 \brief Defines the donut inner size.
156 156
157 157 The value is a relative value to the chart rectangle where:
158 158
159 159 \list
160 160 \o 0.0 is the minimum size (pie not drawn).
161 161 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
162 162 \endlist
163 163
164 164 The value is never greater then size property.
165 165 Default value is 0.5.
166 166 */
167 167
168 168 /*!
169 169 \qmlproperty real PieSeries::donutInnerSize
170 170
171 171 Defines the donut inner size.
172 172
173 173 The value is a relative value to the chart rectangle where:
174 174
175 175 \list
176 176 \o 0.0 is the minimum size (donut is a pie).
177 177 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
178 178 \endlist
179 179
180 180 The value is never greater then size property.
181 181 Default value is 0.5.
182 182 */
183 183
184 184 /*!
185 185 \property QPieSeries::startAngle
186 186 \brief Defines the starting angle of the pie.
187 187
188 188 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
189 189
190 190 Default is value is 0.
191 191 */
192 192
193 193 /*!
194 194 \qmlproperty real PieSeries::startAngle
195 195
196 196 Defines the starting angle of the pie.
197 197
198 198 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
199 199
200 200 Default is value is 0.
201 201 */
202 202
203 203 /*!
204 204 \property QPieSeries::endAngle
205 205 \brief Defines the ending angle of the pie.
206 206
207 207 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
208 208
209 209 Default is value is 360.
210 210 */
211 211
212 212 /*!
213 213 \qmlproperty real PieSeries::endAngle
214 214
215 215 Defines the ending angle of the pie.
216 216
217 217 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
218 218
219 219 Default is value is 360.
220 220 */
221 221
222 222 /*!
223 223 \property QPieSeries::count
224 224
225 225 Number of slices in the series.
226 226 */
227 227
228 228 /*!
229 229 \qmlproperty int PieSeries::count
230 230
231 231 Number of slices in the series.
232 232 */
233 233
234 234 /*!
235 235 \property QPieSeries::donut
236 236
237 237 Defines whether the series should be drawn as a donut
238 238 */
239 239
240 240 /*!
241 241 \qmlproperty int PieSeries::donut
242 242
243 243 Defines whether the series should be drawn as a donut
244 244 */
245 245
246 246 /*!
247 247 \fn void QPieSeries::countChanged()
248 248 Emitted when the slice count has changed.
249 249 \sa count
250 250 */
251 251 /*!
252 252 \qmlsignal PieSeries::onCountChanged()
253 253 Emitted when the slice count has changed.
254 254 */
255 255
256 256 /*!
257 257 \property QPieSeries::sum
258 258
259 259 Sum of all slices.
260 260
261 261 The series keeps track of the sum of all slices it holds.
262 262 */
263 263
264 264 /*!
265 265 \qmlproperty real PieSeries::sum
266 266
267 267 Sum of all slices.
268 268
269 269 The series keeps track of the sum of all slices it holds.
270 270 */
271 271
272 272 /*!
273 273 \fn void QPieSeries::sumChanged()
274 274 Emitted when the sum of all slices has changed.
275 275 \sa sum
276 276 */
277 277 /*!
278 278 \qmlsignal PieSeries::onSumChanged()
279 279 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
280 280 change value of a slice.
281 281 */
282 282
283 283 /*!
284 284 \fn void QPieSeries::added(QList<QPieSlice*> slices)
285 285
286 286 This signal is emitted when \a slices have been added to the series.
287 287
288 288 \sa append(), insert()
289 289 */
290 290 /*!
291 291 \qmlsignal PieSeries::onAdded(PieSlice slice)
292 292 Emitted when \a slice has been added to the series.
293 293 */
294 294
295 295 /*!
296 296 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
297 297 This signal is emitted when \a slices have been removed from the series.
298 298 \sa remove()
299 299 */
300 300 /*!
301 301 \qmlsignal PieSeries::onRemoved(PieSlice slice)
302 302 Emitted when \a slice has been removed from the series.
303 303 */
304 304
305 305 /*!
306 306 \fn void QPieSeries::clicked(QPieSlice* slice)
307 307 This signal is emitted when a \a slice has been clicked.
308 308 \sa QPieSlice::clicked()
309 309 */
310 310 /*!
311 311 \qmlsignal PieSeries::onClicked(PieSlice slice)
312 312 This signal is emitted when a \a slice has been clicked.
313 313 */
314 314
315 315 /*!
316 316 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
317 317 This signal is emitted when user has hovered over or away from the \a slice.
318 318 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
319 319 \sa QPieSlice::hovered()
320 320 */
321 321 /*!
322 322 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
323 323 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
324 324 over the slice and false when hover has moved away from the slice.
325 325 */
326 326
327 327 /*!
328 328 \qmlmethod PieSlice PieSeries::at(int index)
329 329 Returns slice at \a index. Returns null if the index is not valid.
330 330 */
331 331
332 332 /*!
333 333 \qmlmethod PieSlice PieSeries::find(string label)
334 334 Returns the first slice with \a label. Returns null if the index is not valid.
335 335 */
336 336
337 337 /*!
338 338 \qmlmethod PieSlice PieSeries::append(string label, real value)
339 339 Adds a new slice with \a label and \a value to the pie.
340 340 */
341 341
342 342 /*!
343 343 \qmlmethod bool PieSeries::remove(PieSlice slice)
344 344 Removes the \a slice from the pie. Returns true if the removal was successfull, false otherwise.
345 345 */
346 346
347 347 /*!
348 348 \qmlmethod PieSeries::clear()
349 349 Removes all slices from the pie.
350 350 */
351 351
352 352 /*!
353 353 Constructs a series object which is a child of \a parent.
354 354 */
355 355 QPieSeries::QPieSeries(QObject *parent) :
356 356 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
357 357 {
358 358
359 359 }
360 360
361 361 /*!
362 362 Destroys the series and its slices.
363 363 */
364 364 QPieSeries::~QPieSeries()
365 365 {
366 366 // NOTE: d_prt destroyed by QObject
367 367 }
368 368
369 369 /*!
370 370 Returns QChartSeries::SeriesTypePie.
371 371 */
372 372 QAbstractSeries::SeriesType QPieSeries::type() const
373 373 {
374 374 return QAbstractSeries::SeriesTypePie;
375 375 }
376 376
377 377 /*!
378 378 Appends a single \a slice to the series.
379 379 Slice ownership is passed to the series.
380 380
381 381 Returns true if append was succesfull.
382 382 */
383 383 bool QPieSeries::append(QPieSlice* slice)
384 384 {
385 385 return append(QList<QPieSlice*>() << slice);
386 386 }
387 387
388 388 /*!
389 389 Appends an array of \a slices to the series.
390 390 Slice ownership is passed to the series.
391 391
392 392 Returns true if append was successfull.
393 393 */
394 394 bool QPieSeries::append(QList<QPieSlice*> slices)
395 395 {
396 396 Q_D(QPieSeries);
397 397
398 398 if (slices.count() == 0)
399 399 return false;
400 400
401 401 foreach (QPieSlice* s, slices) {
402 402 if (!s || d->m_slices.contains(s))
403 403 return false;
404 404 if (s->series()) // already added to some series
405 405 return false;
406 406 }
407 407
408 408 foreach (QPieSlice* s, slices) {
409 409 s->setParent(this);
410 410 QPieSlicePrivate::fromSlice(s)->m_series = this;
411 411 d->m_slices << s;
412 412 }
413 413
414 414 d->updateDerivativeData();
415 415
416 416 foreach (QPieSlice* s, slices) {
417 417 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
418 418 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
419 419 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
420 420 }
421 421
422 422 emit added(slices);
423 423 emit countChanged();
424 424
425 425 return true;
426 426 }
427 427
428 428 /*!
429 429 Appends a single \a slice to the series and returns a reference to the series.
430 430 Slice ownership is passed to the series.
431 431 */
432 432 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
433 433 {
434 434 append(slice);
435 435 return *this;
436 436 }
437 437
438 438
439 439 /*!
440 440 Appends a single slice to the series with give \a value and \a label.
441 441 Slice ownership is passed to the series.
442 442 */
443 443 QPieSlice* QPieSeries::append(QString label, qreal value)
444 444 {
445 445 QPieSlice* slice = new QPieSlice(label, value);
446 446 append(slice);
447 447 return slice;
448 448 }
449 449
450 450 /*!
451 451 Inserts a single \a slice to the series before the slice at \a index position.
452 452 Slice ownership is passed to the series.
453 453
454 454 Returns true if insert was successfull.
455 455 */
456 456 bool QPieSeries::insert(int index, QPieSlice* slice)
457 457 {
458 458 Q_D(QPieSeries);
459 459
460 460 if (index < 0 || index > d->m_slices.count())
461 461 return false;
462 462
463 463 if (!slice || d->m_slices.contains(slice))
464 464 return false;
465 465
466 466 if (slice->series()) // already added to some series
467 467 return false;
468 468
469 469 slice->setParent(this);
470 470 QPieSlicePrivate::fromSlice(slice)->m_series = this;
471 471 d->m_slices.insert(index, slice);
472 472
473 473 d->updateDerivativeData();
474 474
475 475 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
476 476 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
477 477 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
478 478
479 479 emit added(QList<QPieSlice*>() << slice);
480 480 emit countChanged();
481 481
482 482 return true;
483 483 }
484 484
485 485 /*!
486 486 Removes a single \a slice from the series and deletes the slice.
487 487
488 488 Do not reference the pointer after this call.
489 489
490 490 Returns true if remove was successfull.
491 491 */
492 492 bool QPieSeries::remove(QPieSlice* slice)
493 493 {
494 494 Q_D(QPieSeries);
495 495
496 496 if (!d->m_slices.removeOne(slice))
497 497 return false;
498 498
499 499 d->updateDerivativeData();
500 500
501 501 emit removed(QList<QPieSlice*>() << slice);
502 502 emit countChanged();
503 503
504 504 delete slice;
505 505 slice = 0;
506 506
507 507 return true;
508 508 }
509 509
510 510 /*!
511 511 Clears all slices from the series.
512 512 */
513 513 void QPieSeries::clear()
514 514 {
515 515 Q_D(QPieSeries);
516 516 if (d->m_slices.count() == 0)
517 517 return;
518 518
519 519 QList<QPieSlice*> slices = d->m_slices;
520 520 foreach (QPieSlice* s, d->m_slices) {
521 521 d->m_slices.removeOne(s);
522 522 delete s;
523 523 }
524 524
525 525 d->updateDerivativeData();
526 526
527 527 emit removed(slices);
528 528 emit countChanged();
529 529 }
530 530
531 531 /*!
532 532 Returns a list of slices that belong to this series.
533 533 */
534 534 QList<QPieSlice*> QPieSeries::slices() const
535 535 {
536 536 Q_D(const QPieSeries);
537 537 return d->m_slices;
538 538 }
539 539
540 540 /*!
541 541 returns the number of the slices in this series.
542 542 */
543 543 int QPieSeries::count() const
544 544 {
545 545 Q_D(const QPieSeries);
546 546 return d->m_slices.count();
547 547 }
548 548
549 549 /*!
550 550 Returns true is the series is empty.
551 551 */
552 552 bool QPieSeries::isEmpty() const
553 553 {
554 554 Q_D(const QPieSeries);
555 555 return d->m_slices.isEmpty();
556 556 }
557 557
558 558 /*!
559 559 Returns the sum of all slice values in this series.
560 560
561 561 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
562 562 */
563 563 qreal QPieSeries::sum() const
564 564 {
565 565 Q_D(const QPieSeries);
566 566 return d->m_sum;
567 567 }
568 568
569 569 void QPieSeries::setDonut(bool donut)
570 570 {
571 571 Q_D(QPieSeries);
572 572 d->m_donutChart = donut;
573 573 d->updateDerivativeData();
574 574 }
575 575
576 576 bool QPieSeries::donut() const
577 577 {
578 578 Q_D(const QPieSeries);
579 579 return d->m_donutChart;
580 580 }
581 581
582 582 void QPieSeries::setDonutInnerSize(qreal innerSize)
583 583 {
584 584 Q_D(QPieSeries);
585 585
586 586 if (innerSize < 0.0)
587 587 innerSize = 0.0;
588 588 if (innerSize > d->m_pieRelativeSize)
589 589 innerSize = d->m_pieRelativeSize;
590 590
591 591 d->m_donutRelativeInnerSize = innerSize;
592 592 d->updateDerivativeData();
593 593 emit d->pieSizeChanged();
594 594 }
595 595
596 596 qreal QPieSeries::donutInnerSize() const
597 597 {
598 598 Q_D(const QPieSeries);
599 599 return d->m_donutRelativeInnerSize;
600 600 }
601 601
602 602 void QPieSeries::setHorizontalPosition(qreal relativePosition)
603 603 {
604 604 Q_D(QPieSeries);
605 605
606 606 if (relativePosition < 0.0)
607 607 relativePosition = 0.0;
608 608 if (relativePosition > 1.0)
609 609 relativePosition = 1.0;
610 610
611 611 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
612 612 d->m_pieRelativeHorPos = relativePosition;
613 613 emit d->horizontalPositionChanged();
614 614 }
615 615 }
616 616
617 617 qreal QPieSeries::horizontalPosition() const
618 618 {
619 619 Q_D(const QPieSeries);
620 620 return d->m_pieRelativeHorPos;
621 621 }
622 622
623 623 void QPieSeries::setVerticalPosition(qreal relativePosition)
624 624 {
625 625 Q_D(QPieSeries);
626 626
627 627 if (relativePosition < 0.0)
628 628 relativePosition = 0.0;
629 629 if (relativePosition > 1.0)
630 630 relativePosition = 1.0;
631 631
632 632 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
633 633 d->m_pieRelativeVerPos = relativePosition;
634 634 emit d->verticalPositionChanged();
635 635 }
636 636 }
637 637
638 638 qreal QPieSeries::verticalPosition() const
639 639 {
640 640 Q_D(const QPieSeries);
641 641 return d->m_pieRelativeVerPos;
642 642 }
643 643
644 644 void QPieSeries::setPieSize(qreal relativeSize)
645 645 {
646 646 Q_D(QPieSeries);
647 647
648 648 if (relativeSize < 0.0)
649 649 relativeSize = 0.0;
650 650 if (relativeSize > 1.0)
651 651 relativeSize = 1.0;
652 652
653 653 if (!qFuzzyIsNull(d->m_pieRelativeSize - relativeSize)) {
654 654 d->m_pieRelativeSize = relativeSize;
655 655 emit d->pieSizeChanged();
656 656 }
657 657 }
658 658
659 659 qreal QPieSeries::pieSize() const
660 660 {
661 661 Q_D(const QPieSeries);
662 662 return d->m_pieRelativeSize;
663 663 }
664 664
665 665
666 666 void QPieSeries::setPieStartAngle(qreal angle)
667 667 {
668 668 Q_D(QPieSeries);
669 669 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
670 670 return;
671 671 d->m_pieStartAngle = angle;
672 672 d->updateDerivativeData();
673 673 emit d->pieStartAngleChanged();
674 674 }
675 675
676 676 qreal QPieSeries::pieStartAngle() const
677 677 {
678 678 Q_D(const QPieSeries);
679 679 return d->m_pieStartAngle;
680 680 }
681 681
682 682 /*!
683 683 Sets the end angle of the pie.
684 684
685 685 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
686 686
687 687 \a angle must be greater than start angle.
688 688
689 689 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
690 690 */
691 691 void QPieSeries::setPieEndAngle(qreal angle)
692 692 {
693 693 Q_D(QPieSeries);
694 694 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
695 695 return;
696 696 d->m_pieEndAngle = angle;
697 697 d->updateDerivativeData();
698 698 emit d->pieEndAngleChanged();
699 699 }
700 700
701 701 /*!
702 702 Returns the end angle of the pie.
703 703
704 704 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
705 705
706 706 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
707 707 */
708 708 qreal QPieSeries::pieEndAngle() const
709 709 {
710 710 Q_D(const QPieSeries);
711 711 return d->m_pieEndAngle;
712 712 }
713 713
714 714 /*!
715 715 Sets the all the slice labels \a visible or invisible.
716 716
717 717 Note that this affects only the current slices in the series.
718 718 If user adds a new slice the default label visibility is false.
719 719
720 720 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
721 721 */
722 722 void QPieSeries::setLabelsVisible(bool visible)
723 723 {
724 724 Q_D(QPieSeries);
725 725 foreach (QPieSlice* s, d->m_slices)
726 726 s->setLabelVisible(visible);
727 727 }
728 728
729 729 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
730 730 {
731 731 Q_D(QPieSeries);
732 732 foreach (QPieSlice* s, d->m_slices)
733 733 s->setLabelPosition(position);
734 734 }
735 735
736 736 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
737 737
738 738
739 739 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
740 740 QAbstractSeriesPrivate(parent),
741 741 m_pieRelativeHorPos(0.5),
742 742 m_pieRelativeVerPos(0.5),
743 743 m_pieRelativeSize(0.7),
744 744 m_pieStartAngle(0),
745 745 m_pieEndAngle(360),
746 746 m_sum(0),
747 747 m_donutChart(false),
748 748 m_donutRelativeInnerSize(0.5)
749 749 {
750 750 }
751 751
752 752 QPieSeriesPrivate::~QPieSeriesPrivate()
753 753 {
754 754 }
755 755
756 756 void QPieSeriesPrivate::updateDerivativeData()
757 757 {
758 758 // calculate sum of all slices
759 759 qreal sum = 0;
760 760 foreach (QPieSlice* s, m_slices)
761 761 sum += s->value();
762 762
763 763 if (!qFuzzyIsNull(m_sum - sum)) {
764 764 m_sum = sum;
765 765 emit q_func()->sumChanged();
766 766 }
767 767
768 768 // nothing to show..
769 769 if (qFuzzyIsNull(m_sum))
770 770 return;
771 771
772 772 // update slice attributes
773 773 qreal sliceAngle = m_pieStartAngle;
774 774 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
775 775 QVector<QPieSlice*> changed;
776 776 foreach (QPieSlice* s, m_slices) {
777 777 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
778 778 d->setPercentage(s->value() / m_sum);
779 779 d->setStartAngle(sliceAngle);
780 780 d->setAngleSpan(pieSpan * s->percentage());
781 781 sliceAngle += s->angleSpan();
782 782 }
783 783
784 784
785 785 emit calculatedDataChanged();
786 786 }
787 787
788 788 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
789 789 {
790 790 return series->d_func();
791 791 }
792 792
793 793 void QPieSeriesPrivate::sliceValueChanged()
794 794 {
795 795 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
796 796 updateDerivativeData();
797 797 }
798 798
799 799 void QPieSeriesPrivate::sliceClicked()
800 800 {
801 801 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
802 802 Q_ASSERT(m_slices.contains(slice));
803 803 Q_Q(QPieSeries);
804 804 emit q->clicked(slice);
805 805 }
806 806
807 807 void QPieSeriesPrivate::sliceHovered(bool state)
808 808 {
809 809 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
810 810 Q_ASSERT(m_slices.contains(slice));
811 811 Q_Q(QPieSeries);
812 812 emit q->hovered(slice, state);
813 813 }
814 814
815 815 void QPieSeriesPrivate::scaleDomain(Domain& domain)
816 816 {
817 817 Q_UNUSED(domain);
818 818 // does not apply to pie
819 819 }
820 820
821 821 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
822 822 {
823 823 Q_Q(QPieSeries);
824 824 PieChartItem* pie = new PieChartItem(q,presenter);
825 825 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
826 presenter->animator()->addAnimation(pie);
826 pie->setAnimation(new PieAnimation(pie));
827 827 }
828 828 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
829 829 return pie;
830 830 }
831 831
832 832 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
833 833 {
834 834 Q_Q(QPieSeries);
835 835 QList<LegendMarker*> markers;
836 836 foreach(QPieSlice* slice, q->slices()) {
837 837 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
838 838 markers << marker;
839 839 }
840 840 return markers;
841 841 }
842 842
843 843 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
844 844 {
845 845 Q_UNUSED(axis);
846 846 }
847 847
848 848 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
849 849 {
850 850 Q_UNUSED(orientation);
851 851 return QAbstractAxis::AxisTypeNoAxis;
852 852 }
853 853
854 854 #include "moc_qpieseries.cpp"
855 855 #include "moc_qpieseries_p.cpp"
856 856
857 857 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,264 +1,262
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 "qscatterseries.h"
22 22 #include "qscatterseries_p.h"
23 23 #include "scatterchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
27 26
28 27 /*!
29 28 \class QScatterSeries
30 29 \brief The QScatterSeries class is used for making scatter charts.
31 30
32 31 \mainclass
33 32
34 33 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
35 34 and the vertical axis.
36 35
37 36 \image examples_scatterchart.png
38 37
39 38 Creating basic scatter chart is simple:
40 39 \code
41 40 QScatterSeries* series = new QScatterSeries();
42 41 series->append(0, 6);
43 42 series->append(2, 4);
44 43 ...
45 44 chart->addSeries(series);
46 45 \endcode
47 46 */
48 47 /*!
49 48 \qmlclass ScatterSeries QScatterSeries
50 49 \inherits XYSeries
51 50
52 51 The following QML shows how to create a chart with two simple scatter series:
53 52 \snippet ../demos/qmlchart/qml/qmlchart/View5.qml 1
54 53 \snippet ../demos/qmlchart/qml/qmlchart/View5.qml 2
55 54
56 55 \beginfloatleft
57 56 \image demos_qmlchart5.png
58 57 \endfloat
59 58 \clearfloat
60 59 */
61 60
62 61 /*!
63 62 \enum QScatterSeries::MarkerShape
64 63
65 64 This enum describes the shape used when rendering marker items.
66 65
67 66 \value MarkerShapeCircle
68 67 \value MarkerShapeRectangle
69 68 */
70 69
71 70 /*!
72 71 \property QScatterSeries::color
73 72 Fill (brush) color of the series. This is a convenience property for modifying the color of brush.
74 73 \sa QScatterSeries::brush()
75 74 */
76 75
77 76 /*!
78 77 \property QScatterSeries::borderColor
79 78 Line (pen) color of the series. This is a convenience property for modifying the color of pen.
80 79 \sa QScatterSeries::pen()
81 80 */
82 81
83 82 /*!
84 83 \property QScatterSeries::markerShape
85 84 Defines the shape of the marker used to draw the points in the series. The default shape is MarkerShapeCircle.
86 85 */
87 86 /*!
88 87 \qmlproperty MarkerShape ScatterSeries::markerShape
89 88 Defines the shape of the marker used to draw the points in the series. One of ScatterSeries
90 89 ScatterSeries.MarkerShapeCircle or ScatterSeries.MarkerShapeRectangle.
91 90 The default shape is ScatterSeries.MarkerShapeCircle.
92 91 */
93 92
94 93 /*!
95 94 \property QScatterSeries::markerSize
96 95 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
97 96 */
98 97 /*!
99 98 \qmlproperty real ScatterSeries::markerSize
100 99 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
101 100 */
102 101
103 102 /*!
104 103 \fn void QScatterSeries::colorChanged(QColor color)
105 104 Signal is emitted when the fill (brush) color has changed to \a color.
106 105 */
107 106
108 107 /*!
109 108 \fn void QScatterSeries::borderColorChanged(QColor color)
110 109 Signal is emitted when the line (pen) color has changed to \a color.
111 110 */
112 111 /*!
113 112 \qmlsignal ScatterSeries::borderColorChanged(color color)
114 113 Signal is emitted when the line (pen) color has changed to \a color.
115 114 */
116 115
117 116 /*!
118 117 \fn QChartSeriesType QScatterSeries::type() const
119 118 Returns QChartSeries::SeriesTypeScatter.
120 119 \sa QAbstractSeries, SeriesType
121 120 */
122 121
123 122 QTCOMMERCIALCHART_BEGIN_NAMESPACE
124 123
125 124 /*!
126 125 Constructs a series object which is a child of \a parent.
127 126 */
128 127 QScatterSeries::QScatterSeries(QObject *parent) : QXYSeries(*new QScatterSeriesPrivate(this),parent)
129 128 {
130 129 }
131 130
132 131 /*!
133 132 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
134 133 */
135 134 QScatterSeries::~QScatterSeries()
136 135 {
137 136 Q_D(QScatterSeries);
138 137 if(d->m_dataset) {
139 138 d->m_dataset->removeSeries(this);
140 139 }
141 140 }
142 141
143 142 QAbstractSeries::SeriesType QScatterSeries::type() const
144 143 {
145 144 return QAbstractSeries::SeriesTypeScatter;
146 145 }
147 146
148 147 /*!
149 148 Sets \a pen used for drawing points' border on the chart. If the pen is not defined, the
150 149 pen from chart theme is used.
151 150 \sa QChart::setTheme()
152 151 */
153 152 void QScatterSeries::setPen(const QPen &pen)
154 153 {
155 154 Q_D(QXYSeries);
156 155 if (d->m_pen != pen) {
157 156 bool emitColorChanged = d->m_pen.color() != pen.color();
158 157 d->m_pen = pen;
159 158 emit d->updated();
160 159 if (emitColorChanged)
161 160 emit borderColorChanged(pen.color());
162 161 }
163 162 }
164 163
165 164 /*!
166 165 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
167 166 from chart theme setting is used.
168 167 \sa QChart::setTheme()
169 168 */
170 169 void QScatterSeries::setBrush(const QBrush &brush)
171 170 {
172 171 Q_D(QScatterSeries);
173 172 if (d->m_brush != brush) {
174 173 bool emitColorChanged = d->m_brush.color() != brush.color();
175 174 d->m_brush = brush;
176 175 emit d->updated();
177 176 if (emitColorChanged)
178 177 emit colorChanged(brush.color());
179 178 }
180 179 }
181 180
182 181 void QScatterSeries::setColor(const QColor &color)
183 182 {
184 183 QBrush b = brush();
185 184 if (b.color() != color) {
186 185 b.setColor(color);
187 186 setBrush(b);
188 187 }
189 188 }
190 189
191 190 QColor QScatterSeries::color() const
192 191 {
193 192 return brush().color();
194 193 }
195 194
196 195 void QScatterSeries::setBorderColor(const QColor &color)
197 196 {
198 197 QPen p = pen();
199 198 if (p.color() != color) {
200 199 p.setColor(color);
201 200 setPen(p);
202 201 }
203 202 }
204 203
205 204 QColor QScatterSeries::borderColor() const
206 205 {
207 206 return pen().color();
208 207 }
209 208
210 209 QScatterSeries::MarkerShape QScatterSeries::markerShape() const
211 210 {
212 211 Q_D(const QScatterSeries);
213 212 return d->m_shape;
214 213 }
215 214
216 215 void QScatterSeries::setMarkerShape(MarkerShape shape)
217 216 {
218 217 Q_D(QScatterSeries);
219 218 if (d->m_shape != shape) {
220 219 d->m_shape = shape;
221 220 emit d->updated();
222 221 }
223 222 }
224 223
225 224 qreal QScatterSeries::markerSize() const
226 225 {
227 226 Q_D(const QScatterSeries);
228 227 return d->m_size;
229 228 }
230 229
231 230 void QScatterSeries::setMarkerSize(qreal size)
232 231 {
233 232 Q_D(QScatterSeries);
234 233
235 234 if (!qFuzzyIsNull(d->m_size - size)) {
236 235 d->m_size = size;
237 236 emit d->updated();
238 237 }
239 238 }
240 239
241 240 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
242 241
243 242 QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries* q) :
244 243 QXYSeriesPrivate(q),
245 244 m_shape(QScatterSeries::MarkerShapeCircle),
246 245 m_size(15.0)
247 246 {
248 247 }
249 248
250 249 Chart* QScatterSeriesPrivate::createGraphics(ChartPresenter* presenter)
251 250 {
252 251 Q_Q(QScatterSeries);
253 252 ScatterChartItem *scatter = new ScatterChartItem(q,presenter);
254 253 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
255 scatter->setAnimator(presenter->animator());
256 254 scatter->setAnimation(new XYAnimation(scatter));
257 255 }
258 256 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
259 257 return scatter;
260 258 }
261 259
262 260 #include "moc_qscatterseries.cpp"
263 261
264 262 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,236 +1,235
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 "qsplineseries.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "splinechartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "splineanimation_p.h"
27 27
28 28 /*!
29 29 \class QSplineSeries
30 30 \brief Series type used to store data needed to draw a spline.
31 31
32 32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34 34
35 35 \image examples_splinechart.png
36 36
37 37 Creating basic spline chart is simple:
38 38 \code
39 39 QSplineSeries* series = new QSplineSeries();
40 40 series->append(0, 6);
41 41 series->append(2, 4);
42 42 ...
43 43 chart->addSeries(series);
44 44 \endcode
45 45 */
46 46
47 47 /*!
48 48 \qmlclass SplineSeries QSplineSeries
49 49 \inherits XYSeries
50 50
51 51 The following QML shows how to create a simple spline chart:
52 52 \snippet ../demos/qmlchart/qml/qmlchart/View3.qml 1
53 53 \beginfloatleft
54 54 \image demos_qmlchart3.png
55 55 \endfloat
56 56 \clearfloat
57 57 */
58 58
59 59 /*!
60 60 \fn QSeriesType QSplineSeries::type() const
61 61 Returns the type of the series
62 62 */
63 63
64 64 QTCOMMERCIALCHART_BEGIN_NAMESPACE
65 65
66 66 /*!
67 67 Constructs empty series object which is a child of \a parent.
68 68 When series object is added to QChartView or QChart instance then the ownerships is transferred.
69 69 */
70 70
71 71 QSplineSeries::QSplineSeries(QObject *parent) :
72 72 QLineSeries(*new QSplineSeriesPrivate(this),parent)
73 73 {
74 74 Q_D(QSplineSeries);
75 75 QObject::connect(this,SIGNAL(pointAdded(int)), d, SLOT(updateControlPoints()));
76 76 QObject::connect(this,SIGNAL(pointRemoved(int)), d, SLOT(updateControlPoints()));
77 77 QObject::connect(this,SIGNAL(pointReplaced(int)), d, SLOT(updateControlPoints()));
78 78 }
79 79
80 80 /*!
81 81 Destroys the object.
82 82 */
83 83 QSplineSeries::~QSplineSeries()
84 84 {
85 85 Q_D(QSplineSeries);
86 86 if(d->m_dataset){
87 87 d->m_dataset->removeSeries(this);
88 88 }
89 89 }
90 90
91 91 QAbstractSeries::SeriesType QSplineSeries::type() const
92 92 {
93 93 return QAbstractSeries::SeriesTypeSpline;
94 94 }
95 95
96 96 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 97
98 98 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
99 99 {
100 100 }
101 101
102 102 /*!
103 103 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
104 104 */
105 105 void QSplineSeriesPrivate::calculateControlPoints()
106 106 {
107 107 Q_Q(QSplineSeries);
108 108
109 109 const QList<QPointF>& points = q->points();
110 110
111 111 int n = points.count() - 1;
112 112
113 113 if (n == 1)
114 114 {
115 115 //for n==1
116 116 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
117 117 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
118 118 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
119 119 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
120 120 return;
121 121 }
122 122
123 123 // Calculate first Bezier control points
124 124 // Set of equations for P0 to Pn points.
125 125 //
126 126 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
127 127 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
128 128 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
129 129 // | . . . . . . . . . . . . | | ... | | ... |
130 130 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
131 131 // | . . . . . . . . . . . . | | ... | | ... |
132 132 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
133 133 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
134 134 //
135 135 QVector<qreal> vector;
136 136 vector.resize(n);
137 137
138 138 vector[0] = points[0].x() + 2 * points[1].x();
139 139
140 140
141 141 for (int i = 1; i < n - 1; ++i){
142 142 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
143 143 }
144 144
145 145 vector[n - 1] = (8 * points[n-1].x() + points[n].x()) / 2.0;
146 146
147 147 QVector<qreal> xControl = firstControlPoints(vector);
148 148
149 149 vector[0] = points[0].y() + 2 * points[1].y();
150 150
151 151 for (int i = 1; i < n - 1; ++i) {
152 152 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
153 153 }
154 154
155 155 vector[n - 1] = (8 * points[n-1].y() + points[n].y()) / 2.0;
156 156
157 157 QVector<qreal> yControl = firstControlPoints(vector);
158 158
159 159 for (int i = 0,j =0; i < n; ++i, ++j) {
160 160
161 161 m_controlPoints[j].setX(xControl[i]);
162 162 m_controlPoints[j].setY(yControl[i]);
163 163
164 164 j++;
165 165
166 166 if (i < n - 1){
167 167 m_controlPoints[j].setX(2 * points[i+1].x() - xControl[i + 1]);
168 168 m_controlPoints[j].setY(2 * points[i+1].y() - yControl[i + 1]);
169 169 }else{
170 170 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
171 171 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
172 172 }
173 173 }
174 174 }
175 175
176 176 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
177 177 {
178 178 QVector<qreal> result;
179 179
180 180 int count = vector.count();
181 181 result.resize(count);
182 182 result[0] = vector[0] / 2.0;
183 183
184 184 QVector<qreal> temp;
185 185 temp.resize(count);
186 186 temp[0] = 0;
187 187
188 188 qreal b = 2.0;
189 189
190 190 for (int i = 1; i < count; i++) {
191 191 temp[i] = 1 / b;
192 192 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
193 193 result[i]=(vector[i] - result[i - 1]) / b;
194 194 }
195 195 for (int i = 1; i < count; i++)
196 196 result[count - i - 1] -= temp[count - i] * result[count - i];
197 197
198 198 return result;
199 199 }
200 200
201 201 QPointF QSplineSeriesPrivate::controlPoint(int index) const
202 202 {
203 203 // Q_D(const QSplineSeries);
204 204 // return d->m_controlPoints[index];
205 205 return m_controlPoints[index];
206 206 }
207 207
208 208 /*!
209 209 Updates the control points, besed on currently avaiable knots.
210 210 */
211 211 void QSplineSeriesPrivate::updateControlPoints()
212 212 {
213 213 Q_Q(QSplineSeries);
214 214 if (q->count() > 1) {
215 215 m_controlPoints.resize(2*q->count()-2);
216 216 calculateControlPoints();
217 217 }
218 218 }
219 219
220 220 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
221 221 {
222 222 Q_Q(QSplineSeries);
223 223 SplineChartItem* spline = new SplineChartItem(q,presenter);
224 224 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
225 spline->setAnimator(presenter->animator());
226 225 spline->setAnimation(new SplineAnimation(spline));
227 226 }
228 227
229 228 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
230 229 return spline;
231 230 }
232 231
233 232 #include "moc_qsplineseries.cpp"
234 233 #include "moc_qsplineseries_p.cpp"
235 234
236 235 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,171 +1,176
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 #include "chartanimator_p.h"
24 #include "splineanimation_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 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
40 40 handleUpdated();
41 41 }
42 42
43 43 QRectF SplineChartItem::boundingRect() const
44 44 {
45 45 return m_rect;
46 46 }
47 47
48 48 QPainterPath SplineChartItem::shape() const
49 49 {
50 50 return m_path;
51 51 }
52 52
53 53 void SplineChartItem::setAnimation(SplineAnimation* animation)
54 54 {
55 55 m_animation=animation;
56 56 XYChart::setAnimation(animation);
57 57 }
58 58
59 ChartAnimation* SplineChartItem::animation() const
60 {
61 return m_animation;
62 }
63
59 64 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
60 65 {
61 66 m_controlPoints=points;
62 67 }
63 68
64 69 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
65 70 {
66 71 return m_controlPoints;
67 72 }
68 73
69 74 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
70 75 {
71 76 QVector<QPointF> controlPoints;
72 77
73 78 if(newPoints.count()>=2) {
74 79 controlPoints.resize(newPoints.count()*2-2);
75 80 }
76 81
77 82 for (int i = 0; i < newPoints.size() - 1; i++) {
78 83 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
79 84 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
80 85 }
81 86
82 87 if (controlPoints.count()<2) {
83 88 setGeometryPoints(newPoints);
84 89 setControlGeometryPoints(controlPoints);
85 90 updateGeometry();
86 91 return;
87 92 }
88 93
89 94 if (m_animation) {
90 95 m_animation->setup(oldPoints,newPoints,m_controlPoints,controlPoints,index);
91 96 setGeometryPoints(newPoints);
92 97 setDirty(false);
93 98 presenter()->startAnimation(m_animation);
94 99 }
95 100 else {
96 101 setGeometryPoints(newPoints);
97 102 setControlGeometryPoints(controlPoints);
98 103 updateGeometry();
99 104 }
100 105 }
101 106
102 107 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
103 108 {
104 109 return XYChart::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
105 110 }
106 111
107 112 void SplineChartItem::updateGeometry()
108 113 {
109 114 const QVector<QPointF> &points = geometryPoints();
110 115 const QVector<QPointF> &controlPoints = controlGeometryPoints();
111 116
112 117 if ((points.size()<2) || (controlPoints.size()<2)) {
113 118 prepareGeometryChange();
114 119 m_path = QPainterPath();
115 120 m_rect = QRect();
116 121 return;
117 122 }
118 123
119 124 Q_ASSERT(points.count()*2-2 == controlPoints.count());
120 125
121 126 QPainterPath splinePath(points.at(0));
122 127
123 128 for (int i = 0; i < points.size() - 1; i++) {
124 129 const QPointF& point = points.at(i + 1);
125 130 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
126 131 }
127 132
128 133 prepareGeometryChange();
129 134 m_path = splinePath;
130 135 m_rect = splinePath.boundingRect();
131 136 setPos(origin());
132 137 }
133 138
134 139 //handlers
135 140
136 141 void SplineChartItem::handleUpdated()
137 142 {
138 143 setVisible(m_series->isVisible());
139 144 m_pointsVisible = m_series->pointsVisible();
140 145 m_linePen = m_series->pen();
141 146 m_pointPen = m_series->pen();
142 147 m_pointPen.setWidthF(2*m_pointPen.width());
143 148 update();
144 149 }
145 150
146 151 //painter
147 152
148 153 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
149 154 {
150 155 Q_UNUSED(widget)
151 156 Q_UNUSED(option)
152 157
153 158 painter->save();
154 159 painter->setClipRect(clipRect());
155 160 painter->setPen(m_linePen);
156 161 painter->drawPath(m_path);
157 162 if (m_pointsVisible) {
158 163 painter->setPen(m_pointPen);
159 164 painter->drawPoints(geometryPoints());
160 165 }
161 166 painter->restore();
162 167 }
163 168
164 169 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
165 170 {
166 171 emit XYChart::clicked(calculateDomainPoint(event->pos()));
167 172 }
168 173
169 174 #include "moc_splinechartitem_p.cpp"
170 175
171 176 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,83 +1,84
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef SPLINECHARTITEM_P_H
31 31 #define SPLINECHARTITEM_P_H
32 32
33 33 #include "qsplineseries.h"
34 34 #include "xychart_p.h"
35 #include "splineanimation_p.h"
36 35
37 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 37
38 class SplineAnimation;
39
39 40 class SplineChartItem : public XYChart, public QGraphicsItem
40 41 {
41 42 Q_OBJECT
42 43 Q_INTERFACES(QGraphicsItem)
43 44 public:
44 45 SplineChartItem(QSplineSeries *series, ChartPresenter *presenter);
45 46
46 47 //from QGraphicsItem
47 48 QRectF boundingRect() const;
48 49 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
49 50 QPainterPath shape() const;
50 51
51 52 void setControlGeometryPoints(QVector<QPointF>& points);
52 53 QVector<QPointF> controlGeometryPoints() const;
53 54
54 55 void setAnimation(SplineAnimation* animation);
55 ChartAnimation* animation() const { return m_animation; }
56 ChartAnimation* animation() const;
56 57
57 58 public Q_SLOTS:
58 59 void handleUpdated();
59 60
60 61 protected:
61 62 void updateGeometry();
62 63 void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index);
63 64 void mousePressEvent(QGraphicsSceneMouseEvent *event);
64 65
65 66 private:
66 67 QPointF calculateGeometryControlPoint(int index) const;
67 68
68 69 private:
69 70 QSplineSeries *m_series;
70 71 QPainterPath m_path;
71 72 QRectF m_rect;
72 73 QPen m_linePen;
73 74 QPen m_pointPen;
74 75 bool m_pointsVisible;
75 76 QVector<QPointF> m_controlPoints;
76 77 SplineAnimation* m_animation;
77 78
78 79 friend class SplineAnimation;
79 80 };
80 81
81 82 QTCOMMERCIALCHART_END_NAMESPACE
82 83
83 84 #endif // SPLINECHARTITEM_P_H
@@ -1,223 +1,222
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 #include "chartanimator_p.h"
26 25 #include "domain_p.h"
26 #include "qxymodelmapper.h"
27 27 #include <QPainter>
28 28 #include <QAbstractItemModel>
29 #include "qxymodelmapper.h"
30 #include <QDebug>
29
31 30
32 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 32
34 33 //TODO: optimize : remove points which are not visible
35 34
36 35 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):Chart(presenter),
37 36 m_minX(0),
38 37 m_maxX(0),
39 38 m_minY(0),
40 39 m_maxY(0),
41 40 m_series(series),
42 41 m_animation(0),
43 42 m_dirty(true)
44 43 {
45 44 // QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
46 45 // QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
47 46 // QObject::connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
48 47 QObject::connect(series, SIGNAL(pointReplaced(int)), this,SLOT(handlePointReplaced(int)));
49 48 QObject::connect(series, SIGNAL(pointAdded(int)), this,SLOT(handlePointAdded(int)));
50 49 QObject::connect(series, SIGNAL(pointRemoved(int)), this,SLOT(handlePointRemoved(int)));
51 50 QObject::connect(this, SIGNAL(clicked(QPointF)), series,SIGNAL(clicked(QPointF)));
52 51 }
53 52
54 53 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
55 54 {
56 55 m_points = points;
57 56 }
58 57
59 58 void XYChart::setClipRect(const QRectF &rect)
60 59 {
61 60 m_clipRect = rect;
62 61 }
63 62
64 63 void XYChart::setAnimation(XYAnimation* animation)
65 64 {
66 65 m_animation=animation;
67 66 }
68 67
69 68 void XYChart::setDirty(bool dirty)
70 69 {
71 70 m_dirty=dirty;
72 71 }
73 72
74 73 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
75 74 {
76 75 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
77 76 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
78 77 qreal x = (point.x() - m_minX)* deltaX;
79 78 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
80 79 return QPointF(x,y);
81 80 }
82 81
83 82 QPointF XYChart::calculateGeometryPoint(int index) const
84 83 {
85 84 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
86 85 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
87 86 const QList<QPointF>& vector = m_series->points();
88 87 qreal x = (vector[index].x() - m_minX)* deltaX;
89 88 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
90 89 return QPointF(x,y);
91 90 }
92 91
93 92 QVector<QPointF> XYChart::calculateGeometryPoints() const
94 93 {
95 94 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
96 95 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
97 96
98 97 QVector<QPointF> result;
99 98 result.resize(m_series->count());
100 99 const QList<QPointF>& vector = m_series->points();
101 100 for (int i = 0; i < m_series->count(); ++i) {
102 101 qreal x = (vector[i].x() - m_minX)* deltaX;
103 102 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
104 103 result[i].setX(x);
105 104 result[i].setY(y);
106 105 }
107 106 return result;
108 107 }
109 108
110 109 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
111 110 {
112 111 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
113 112 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
114 113 qreal x = point.x()/deltaX +m_minX;
115 114 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
116 115 return QPointF(x,y);
117 116 }
118 117
119 118 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
120 119 {
121 120
122 121 if (m_animation) {
123 122 m_animation->setup(oldPoints, newPoints, index);
124 123 setGeometryPoints(newPoints);
125 124 setDirty(false);
126 125 presenter()->startAnimation(m_animation);
127 126 }
128 127 else {
129 128 setGeometryPoints(newPoints);
130 129 updateGeometry();
131 130 }
132 131 }
133 132
134 133 //handlers
135 134
136 135 void XYChart::handlePointAdded(int index)
137 136 {
138 137 Q_ASSERT(index<m_series->count());
139 138 Q_ASSERT(index>=0);
140 139
141 140 QVector<QPointF> points;
142 141
143 142 if(m_dirty) {
144 143 points = calculateGeometryPoints();
145 144 } else {
146 145 points = m_points;
147 146 QPointF point = calculateGeometryPoint(index);
148 147 points.insert(index, point);
149 148 }
150 149
151 150 updateChart(m_points,points,index);
152 151 }
153 152
154 153 void XYChart::handlePointRemoved(int index)
155 154 {
156 155 Q_ASSERT(index<=m_series->count());
157 156 Q_ASSERT(index>=0);
158 157
159 158 QVector<QPointF> points;
160 159
161 160 if(m_dirty) {
162 161 points = calculateGeometryPoints();
163 162 } else {
164 163 points = m_points;
165 164 points.remove(index);
166 165 }
167 166
168 167 updateChart(m_points,points,index);
169 168 }
170 169
171 170 void XYChart::handlePointReplaced(int index)
172 171 {
173 172 Q_ASSERT(index<m_series->count());
174 173 Q_ASSERT(index>=0);
175 174
176 175 QVector<QPointF> points;
177 176
178 177 if(m_dirty) {
179 178 points = calculateGeometryPoints();
180 179 } else {
181 180 QPointF point = calculateGeometryPoint(index);
182 181 points = m_points;
183 182 points.replace(index,point);
184 183 }
185 184
186 185 updateChart(m_points,points,index);
187 186 }
188 187
189 188 void XYChart::handleDomainUpdated()
190 189 {
191 190 m_minX=domain()->minX();
192 191 m_maxX=domain()->maxX();
193 192 m_minY=domain()->minY();
194 193 m_maxY=domain()->maxY();
195 194 if (isEmpty()) return;
196 195
197 196 QVector<QPointF> points = calculateGeometryPoints();
198 197
199 198 updateChart(m_points,points);
200 199 }
201 200
202 201 void XYChart::handleGeometryChanged(const QRectF &rect)
203 202 {
204 203 Q_ASSERT(rect.isValid());
205 204 m_size=rect.size();
206 205 m_clipRect=rect.translated(-rect.topLeft());
207 206 m_origin=rect.topLeft();
208 207
209 208 if (isEmpty()) return;
210 209
211 210 QVector<QPointF> points = calculateGeometryPoints();
212 211
213 212 updateChart(m_points,points);
214 213 }
215 214
216 215 bool XYChart::isEmpty()
217 216 {
218 217 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
219 218 }
220 219
221 220 #include "moc_xychart_p.cpp"
222 221
223 222 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now