##// END OF EJS Templates
Krazy reported errors...
Michal Klocek -
r974:de7be57d3935
parent child
Show More
@@ -1,42 +1,42
1 /*!
1 /*!
2 \example examples/stackedbarchartdrilldown
2 \example examples/stackedbarchartdrilldown
3 \title StackedBarChart Drilldown Example
3 \title StackedBarChart Drilldown Example
4 \subtitle
4 \subtitle
5
5
6 The example shows how to implement drilldown using stacked barchart. In drilldown example we create stacked barchart, which shows the harvest of various chili peppers during season. In season view the harvest is grouped by month. To drill down to weekly view, user clicks selected month with right mouse button. On weekly view, the harvest of clicked month is shown by week. For example purposes each month is 4 weeks long :)
6 The example shows how to implement drilldown using stacked barchart. In drilldown example we create stacked barchart, which shows the harvest of various chili peppers during season. In season view the harvest is grouped by month. To drill down to weekly view, user clicks selected month with right mouse button. On weekly view, the harvest of clicked month is shown by week. For example purposes each month is 4 weeks long :)
7
7
8 Season view looks like this:
8 Season view looks like this:
9 \image stackedbarchart_drilldown_season.png
9 \image stackedbarchart_drilldown_season.png
10
10
11 Right mouse button clicked on august, shows the harvest from august:
11 Right mouse button clicked on august, shows the harvest from august:
12 \image stackedbarchart_drilldown_august.png
12 \image stackedbarchart_drilldown_august.png
13
13
14 Here we define a drilldown series, which adds mapping for categories to other drilldown series.
14 Here we define a drilldown series, which adds mapping for categories to other drilldown series.
15 Purpose of drilldown series is to contain knowledge of the drilldown structure. The mapDrilldownSeries function maps the category to given series. We can ask the mapping for category with drilldownSeries(QString category) function.
15 Purpose of drilldown series is to contain knowledge of the drilldown structure. The mapDrilldownSeries function maps the category to given series. We can ask the mapping for category with drilldownSeries(QString category) function.
16
16
17 \snippet ../examples/stackedbarchartdrilldown/main.cpp 1
17 \snippet ../examples/stackedbarchartdrilldown/main.cpp 1
18
18
19 To enable drilldown we create own view, which implements handler for right click. All QBarSeries derived classes send out rightClicked(QBarSet*, QString) signal when series is clicked with right mouse button. The parameters QBarSet and QString contain the pointer to clicked bar set and name of category, where click occured.
19 To enable drilldown we create own view, which implements handler for right click. All QBarSeries derived classes send out rightClicked(QBarSet*, QString) signal when series is clicked with right mouse button. The parameters QBarSet and QString contain the pointer to clicked bar set and name of category, where click occurred.
20
20
21 In our DrilldownChart we implement handler, which selects the drilldown chart with the category.
21 In our DrilldownChart we implement handler, which selects the drilldown chart with the category.
22
22
23 \snippet ../examples/stackedbarchartdrilldown/main.cpp 2
23 \snippet ../examples/stackedbarchartdrilldown/main.cpp 2
24
24
25 Here we define data, which we use to construct the chart.
25 Here we define data, which we use to construct the chart.
26
26
27 \snippet ../examples/stackedbarchartdrilldown/main.cpp 3
27 \snippet ../examples/stackedbarchartdrilldown/main.cpp 3
28
28
29 To create the drilldown structure, we first create our top level series, which we call seasonSeries. For each month in seasonSeries we create a drilldown series, called weeklySeries which contains more detailed data for that month.
29 To create the drilldown structure, we first create our top level series, which we call seasonSeries. For each month in seasonSeries we create a drilldown series, called weeklySeries which contains more detailed data for that month.
30 In weeklySeries, we use the drilldown handler to bring us back to seasonSeries. To do this we add mapping to the series. The seasonSeries is mapped to weeklySeries for each month. Every weeklySeries is mapped back to the seasonSeries.
30 In weeklySeries, we use the drilldown handler to bring us back to seasonSeries. To do this we add mapping to the series. The seasonSeries is mapped to weeklySeries for each month. Every weeklySeries is mapped back to the seasonSeries.
31 To make mapping work, we connect the rightClicked signals from our series to the drilldownChart.
31 To make mapping work, we connect the rightClicked signals from our series to the drilldownChart.
32
32
33 \snippet ../examples/stackedbarchartdrilldown/main.cpp 4
33 \snippet ../examples/stackedbarchartdrilldown/main.cpp 4
34
34
35 When we have our drilldown structure ready, we can add the data to it. Here we generate random crop for each plant in each week. The monthly crop is calculated from weekly crops. To enable floating values, we connect the clicked signal to toggle the value of corresponding set.
35 When we have our drilldown structure ready, we can add the data to it. Here we generate random crop for each plant in each week. The monthly crop is calculated from weekly crops. To enable floating values, we connect the clicked signal to toggle the value of corresponding set.
36
36
37 \snippet ../examples/stackedbarchartdrilldown/main.cpp 5
37 \snippet ../examples/stackedbarchartdrilldown/main.cpp 5
38
38
39 Here we set the chart to show top level series initially.
39 Here we set the chart to show top level series initially.
40
40
41 \snippet ../examples/stackedbarchartdrilldown/main.cpp 6
41 \snippet ../examples/stackedbarchartdrilldown/main.cpp 6
42 */
42 */
@@ -1,299 +1,301
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartanimator_p.h"
21 #include "chartanimator_p.h"
22 #include "axisanimation_p.h"
22 #include "axisanimation_p.h"
23 #include "xyanimation_p.h"
23 #include "xyanimation_p.h"
24 #include "splineanimation_p.h"
24 #include "splineanimation_p.h"
25 #include "xychartitem_p.h"
25 #include "xychartitem_p.h"
26 #include "pieanimation_p.h"
26 #include "pieanimation_p.h"
27 #include "baranimation_p.h"
27 #include "baranimation_p.h"
28 #include "barchartitem_p.h"
28 #include "barchartitem_p.h"
29 #include "areachartitem_p.h"
29 #include "areachartitem_p.h"
30 #include "splinechartitem_p.h"
30 #include "splinechartitem_p.h"
31 #include "scatterchartitem_p.h"
31 #include "scatterchartitem_p.h"
32 #include <QTimer>
32 #include <QTimer>
33
33
34 Q_DECLARE_METATYPE(QVector<QPointF>)
34 Q_DECLARE_METATYPE(QVector<QPointF>)
35 Q_DECLARE_METATYPE(QVector<qreal>)
35 Q_DECLARE_METATYPE(QVector<qreal>)
36 Q_DECLARE_METATYPE(QVector<QRectF>)
36 Q_DECLARE_METATYPE(QVector<QRectF>)
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 const static int duration = 1000;
40 const static int duration = 1000;
41
41
42 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent),
42 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent),
43 m_state(ShowState)
43 m_state(ShowState)
44 {
44 {
45 }
45 }
46
46
47 ChartAnimator::~ChartAnimator()
47 ChartAnimator::~ChartAnimator()
48 {
48 {
49 }
49 }
50
50
51 void ChartAnimator::addAnimation(Axis *item)
51 void ChartAnimator::addAnimation(Axis *item)
52 {
52 {
53 ChartAnimation *animation = m_animations.value(item);
53 ChartAnimation *animation = m_animations.value(item);
54
54
55 if (!animation) {
55 if (!animation) {
56 animation = new AxisAnimation(item);
56 animation = new AxisAnimation(item);
57 m_animations.insert(item, animation);
57 m_animations.insert(item, animation);
58 }
58 }
59
59
60 item->setAnimator(this);
60 item->setAnimator(this);
61 }
61 }
62
62
63 void ChartAnimator::addAnimation(SplineChartItem *item)
63 void ChartAnimator::addAnimation(SplineChartItem *item)
64 {
64 {
65 ChartAnimation *animation = m_animations.value(item);
65 ChartAnimation *animation = m_animations.value(item);
66
66
67 if (!animation) {
67 if (!animation) {
68 animation = new SplineAnimation(item);
68 animation = new SplineAnimation(item);
69 m_animations.insert(item, animation);
69 m_animations.insert(item, animation);
70 }
70 }
71
71
72 item->setAnimator(this);
72 item->setAnimator(this);
73 }
73 }
74
74
75 void ChartAnimator::addAnimation(ScatterChartItem *item)
75 void ChartAnimator::addAnimation(ScatterChartItem *item)
76 {
76 {
77 ChartAnimation *animation = m_animations.value(item);
77 ChartAnimation *animation = m_animations.value(item);
78
78
79 if (!animation) {
79 if (!animation) {
80 animation = new XYAnimation(item);
80 animation = new XYAnimation(item);
81 m_animations.insert(item, animation);
81 m_animations.insert(item, animation);
82 }
82 }
83
83
84 item->setAnimator(this);
84 item->setAnimator(this);
85 }
85 }
86
86
87 void ChartAnimator::addAnimation(LineChartItem *item)
87 void ChartAnimator::addAnimation(LineChartItem *item)
88 {
88 {
89 ChartAnimation *animation = m_animations.value(item);
89 ChartAnimation *animation = m_animations.value(item);
90
90
91 if (!animation) {
91 if (!animation) {
92 animation = new XYAnimation(item);
92 animation = new XYAnimation(item);
93 m_animations.insert(item, animation);
93 m_animations.insert(item, animation);
94 }
94 }
95
95
96 item->setAnimator(this);
96 item->setAnimator(this);
97 }
97 }
98
98
99 void ChartAnimator::addAnimation(PieChartItem *item)
99 void ChartAnimator::addAnimation(PieChartItem *item)
100 {
100 {
101 ChartAnimation *animation = m_animations.value(item);
101 ChartAnimation *animation = m_animations.value(item);
102
102
103 if (!animation) {
103 if (!animation) {
104 animation = new PieAnimation(item);
104 animation = new PieAnimation(item);
105 m_animations.insert(item, animation);
105 m_animations.insert(item, animation);
106 }
106 }
107
107
108 item->setAnimator(this);
108 item->setAnimator(this);
109 }
109 }
110
110
111 void ChartAnimator::addAnimation(BarChartItem *item)
111 void ChartAnimator::addAnimation(BarChartItem *item)
112 {
112 {
113 ChartAnimation *animation = m_animations.value(item);
113 ChartAnimation *animation = m_animations.value(item);
114
114
115 if (!animation) {
115 if (!animation) {
116 animation = new BarAnimation(item);
116 animation = new BarAnimation(item);
117 m_animations.insert(item, animation);
117 m_animations.insert(item, animation);
118 }
118 }
119
119
120 item->setAnimator(this);
120 item->setAnimator(this);
121 }
121 }
122
122
123
123
124 void ChartAnimator::removeAnimation(Chart *item)
124 void ChartAnimator::removeAnimation(Chart *item)
125 {
125 {
126 item->setAnimator(0);
126 item->setAnimator(0);
127 m_animations.remove(item);
127 m_animations.remove(item);
128 }
128 }
129
129
130 void ChartAnimator::updateLayout(Axis *item , QVector<qreal> &newLayout)
130 void ChartAnimator::updateLayout(Axis *item , QVector<qreal> &newLayout)
131 {
131 {
132 AxisAnimation *animation = static_cast<AxisAnimation*>(m_animations.value(item));
132 AxisAnimation *animation = static_cast<AxisAnimation*>(m_animations.value(item));
133
133
134 Q_ASSERT(animation);
134 Q_ASSERT(animation);
135
135
136 QVector<qreal> oldLayout = item->layout();
136 QVector<qreal> oldLayout = item->layout();
137
137
138 if (newLayout.count() == 0)
138 if (newLayout.count() == 0)
139 return;
139 return;
140
140
141 switch (m_state) {
141 switch (m_state) {
142 case ZoomOutState: {
142 case ZoomOutState: {
143 QRectF rect = item->geometry();
143 QRectF rect = item->geometry();
144 oldLayout.resize(newLayout.count());
144 oldLayout.resize(newLayout.count());
145
145
146 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; i++, j--) {
146 for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
147 oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.bottom();
147 oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.bottom();
148 oldLayout[j] = item->axisType() == Axis::X_AXIS ? rect.right() : rect.top();
148 oldLayout[j] = item->axisType() == Axis::X_AXIS ? rect.right() : rect.top();
149 }
149 }
150 }
150 }
151 break;
151 break;
152 case ZoomInState: {
152 case ZoomInState: {
153 int index = qMin(oldLayout.count() * (item->axisType() == Axis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
153 int index = qMin(oldLayout.count() * (item->axisType() == Axis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
154 oldLayout.resize(newLayout.count());
154 oldLayout.resize(newLayout.count());
155
155
156 for(int i = 0; i < oldLayout.count(); i++)
156 for(int i = 0; i < oldLayout.count(); i++)
157 oldLayout[i]= oldLayout[index];
157 oldLayout[i]= oldLayout[index];
158 }
158 }
159 break;
159 break;
160 case ScrollDownState:
160 case ScrollDownState:
161 case ScrollRightState: {
161 case ScrollRightState: {
162 oldLayout.resize(newLayout.count());
162 oldLayout.resize(newLayout.count());
163
163
164 for(int i = 0, j = i + 1; i < oldLayout.count() - 1; i++, j++)
164 for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
165 oldLayout[i]= oldLayout[j];
165 oldLayout[i]= oldLayout[j];
166 }
166 }
167 break;
167 break;
168 case ScrollUpState:
168 case ScrollUpState:
169 case ScrollLeftState: {
169 case ScrollLeftState: {
170 oldLayout.resize(newLayout.count());
170 oldLayout.resize(newLayout.count());
171
171
172 for(int i = oldLayout.count() - 1, j = i - 1; i > 0; i--, j--)
172 for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
173 oldLayout[i]= oldLayout[j];
173 oldLayout[i]= oldLayout[j];
174 }
174 }
175 break;
175 break;
176 default: {
176 default: {
177 oldLayout.resize(newLayout.count());
177 oldLayout.resize(newLayout.count());
178 QRectF rect = item->geometry();
178 QRectF rect = item->geometry();
179 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); i++, j--)
179 for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
180 oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.top();
180 oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.top();
181 }
181 }
182 break;
182 break;
183 }
183 }
184
184
185
185
186 if (animation->state() != QAbstractAnimation::Stopped)
186 if (animation->state() != QAbstractAnimation::Stopped)
187 animation->stop();
187 animation->stop();
188
188
189 animation->setDuration(duration);
189 animation->setDuration(duration);
190 animation->setEasingCurve(QEasingCurve::OutQuart);
190 animation->setEasingCurve(QEasingCurve::OutQuart);
191 QVariantAnimation::KeyValues value;
191 QVariantAnimation::KeyValues value;
192 animation->setKeyValues(value); //workaround for wrong interpolation call
192 animation->setKeyValues(value); //workaround for wrong interpolation call
193 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
193 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
194 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
194 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
195
195
196 QTimer::singleShot(0, animation, SLOT(start()));
196 QTimer::singleShot(0, animation, SLOT(start()));
197 }
197 }
198
198
199 void ChartAnimator::updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
199 void ChartAnimator::updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
200 {
200 {
201 SplineAnimation *animation = static_cast<SplineAnimation *>(m_animations.value(item));
201 SplineAnimation *animation = static_cast<SplineAnimation *>(m_animations.value(item));
202
202
203 Q_ASSERT(animation);
203 Q_ASSERT(animation);
204
204
205 if (newPoints.count() < 2 || newControlPoints.count() < 2)
205 if (newPoints.count() < 2 || newControlPoints.count() < 2)
206 return;
206 return;
207
207
208 bool empty = oldPoints.count() == 0;
208 bool empty = oldPoints.count() == 0;
209
209
210
210
211 if (animation->state() != QAbstractAnimation::Stopped)
211 if (animation->state() != QAbstractAnimation::Stopped)
212 animation->stop();
212 animation->stop();
213
213
214 animation->setDuration(duration);
214 animation->setDuration(duration);
215 if (!empty)
215 if (!empty)
216 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
216 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
217 else
217 else
218 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
218 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
219
219
220 animation->setEasingCurve(QEasingCurve::OutQuart);
220 animation->setEasingCurve(QEasingCurve::OutQuart);
221 animation->setValues(oldPoints, newPoints, oldControlPoints, newControlPoints, index);
221 animation->setValues(oldPoints, newPoints, oldControlPoints, newControlPoints, index);
222
222
223 QTimer::singleShot(0, animation, SLOT(start()));
223 QTimer::singleShot(0, animation, SLOT(start()));
224 }
224 }
225
225
226
226
227 void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
227 void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
228 {
228 {
229 XYAnimation *animation = static_cast<XYAnimation *>(m_animations.value(item));
229 XYAnimation *animation = static_cast<XYAnimation *>(m_animations.value(item));
230
230
231 Q_ASSERT(animation);
231 Q_ASSERT(animation);
232
232
233 if (newPoints.count() == 0)
233 if (newPoints.count() == 0)
234 return;
234 return;
235
235
236 bool empty = oldPoints.count() == 0;
236 bool empty = oldPoints.count() == 0;
237
237
238
238
239 if (animation->state() != QAbstractAnimation::Stopped)
239 if (animation->state() != QAbstractAnimation::Stopped)
240 animation->stop();
240 animation->stop();
241
241
242 animation->setDuration(duration);
242 animation->setDuration(duration);
243 if (!empty)
243 if (!empty)
244 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
244 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
245 else
245 else
246 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
246 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
247
247
248 animation->setEasingCurve(QEasingCurve::OutQuart);
248 animation->setEasingCurve(QEasingCurve::OutQuart);
249 animation->setValues(oldPoints, newPoints, index);
249 animation->setValues(oldPoints, newPoints, index);
250
250
251 QTimer::singleShot(0, animation, SLOT(start()));
251 QTimer::singleShot(0, animation, SLOT(start()));
252 }
252 }
253
253
254 void ChartAnimator::addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
254 void ChartAnimator::addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
255 {
255 {
256 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
256 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
257 Q_ASSERT(animation);
257 Q_ASSERT(animation);
258 animation->addSlice(slice, sliceData, isEmpty);
258 animation->addSlice(slice, sliceData, isEmpty);
259 }
259 }
260
260
261 void ChartAnimator::removeAnimation(PieChartItem *item, QPieSlice *slice)
261 void ChartAnimator::removeAnimation(PieChartItem *item, QPieSlice *slice)
262 {
262 {
263 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
263 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
264 Q_ASSERT(animation);
264 Q_ASSERT(animation);
265 animation->removeSlice(slice);
265 animation->removeSlice(slice);
266 }
266 }
267
267
268 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
268 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
269 {
269 {
270 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
270 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
271 Q_ASSERT(animation);
271 Q_ASSERT(animation);
272 animation->updateValues(layout);
272 animation->updateValues(layout);
273 }
273 }
274
274
275 void ChartAnimator::updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData)
275 void ChartAnimator::updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData)
276 {
276 {
277 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
277 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
278 Q_ASSERT(animation);
278 Q_ASSERT(animation);
279 animation->updateValue(slice, sliceData);
279 animation->updateValue(slice, sliceData);
280 }
280 }
281
281
282 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
282 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
283 {
283 {
284 BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item));
284 BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item));
285 Q_ASSERT(animation);
285 Q_ASSERT(animation);
286 animation->setDuration(duration);
286 animation->setDuration(duration);
287 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
287 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
288 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
288 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
289 QTimer::singleShot(0, animation, SLOT(start()));
289 QTimer::singleShot(0, animation, SLOT(start()));
290 }
290 }
291
291
292
292
293 void ChartAnimator::setState(State state, const QPointF &point)
293 void ChartAnimator::setState(State state, const QPointF &point)
294 {
294 {
295 m_state = state;
295 m_state = state;
296 m_point = point;
296 m_point = point;
297 }
297 }
298
298
299 #include "moc_chartanimator_p.cpp"
300
299 QTCOMMERCIALCHART_END_NAMESPACE
301 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,78 +1,79
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef CHARTANIMATOR_P_H
21 #ifndef CHARTANIMATOR_P_H
22 #define CHARTANIMATOR_P_H
22 #define CHARTANIMATOR_P_H
23
23
24 #include "qchartglobal.h"
24 #include "qchartglobal.h"
25 #include "chartanimation_p.h"
25 #include "chartanimation_p.h"
26 #include "piechartitem_p.h"
26 #include "piechartitem_p.h"
27 #include "barchartitem_p.h"
27 #include "barchartitem_p.h"
28 #include <QPointF>
28 #include <QPointF>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 class ChartItem;
32 class ChartItem;
33 class Axis;
33 class Axis;
34 class AreaChartItem;
34 class AreaChartItem;
35 class SplineChartItem;
35 class SplineChartItem;
36 class ScatterChartItem;
36 class ScatterChartItem;
37 class LineChartItem;
37 class LineChartItem;
38 class XYChartItem;
38 class XYChartItem;
39
39
40 class ChartAnimator : public QObject {
40 class ChartAnimator : public QObject
41
41 {
42 Q_OBJECT
42 public:
43 public:
43 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState, ScrollRightState, ZoomInState, ZoomOutState};
44 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState, ScrollRightState, ZoomInState, ZoomOutState};
44
45
45 ChartAnimator(QObject *parent = 0);
46 ChartAnimator(QObject *parent = 0);
46 virtual ~ChartAnimator();
47 virtual ~ChartAnimator();
47
48
48 void addAnimation(Axis *item);
49 void addAnimation(Axis *item);
49 void addAnimation(PieChartItem *item);
50 void addAnimation(PieChartItem *item);
50 void addAnimation(ScatterChartItem *item);
51 void addAnimation(ScatterChartItem *item);
51 void addAnimation(LineChartItem *item);
52 void addAnimation(LineChartItem *item);
52 void addAnimation(SplineChartItem *item);
53 void addAnimation(SplineChartItem *item);
53 void addAnimation(BarChartItem *item);
54 void addAnimation(BarChartItem *item);
54 void removeAnimation(Chart *item);
55 void removeAnimation(Chart *item);
55
56
56 void animationStarted();
57 void animationStarted();
57 void updateLayout(XYChartItem *item, QVector<QPointF> &oldLayout, QVector<QPointF> &newLayout, int index);
58 void updateLayout(XYChartItem *item, QVector<QPointF> &oldLayout, QVector<QPointF> &newLayout, int index);
58 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
59 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
59 void updateLayout(Axis *item, QVector<qreal> &layout);
60 void updateLayout(Axis *item, QVector<qreal> &layout);
60
61
61 void addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty);
62 void addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty);
62 void removeAnimation(PieChartItem *item, QPieSlice *slice);
63 void removeAnimation(PieChartItem *item, QPieSlice *slice);
63 void updateLayout(PieChartItem *item, const PieLayout &layout);
64 void updateLayout(PieChartItem *item, const PieLayout &layout);
64 void updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData);
65 void updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData);
65
66
66 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
67 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
67
68
68 void setState(State state,const QPointF &point = QPointF());
69 void setState(State state,const QPointF &point = QPointF());
69
70
70 private:
71 private:
71 QMap<Chart *, ChartAnimation *> m_animations;
72 QMap<Chart *, ChartAnimation *> m_animations;
72 State m_state;
73 State m_state;
73 QPointF m_point;
74 QPointF m_point;
74 };
75 };
75
76
76 QTCOMMERCIALCHART_END_NAMESPACE
77 QTCOMMERCIALCHART_END_NAMESPACE
77
78
78 #endif
79 #endif
@@ -1,149 +1,149
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "splineanimation_p.h"
21 #include "splineanimation_p.h"
22 #include "splinechartitem_p.h"
22 #include "splinechartitem_p.h"
23
23
24 Q_DECLARE_METATYPE(QVector<QPointF>)
24 Q_DECLARE_METATYPE(QVector<QPointF>)
25 Q_DECLARE_METATYPE(SplineVector)
25 Q_DECLARE_METATYPE(SplineVector)
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 SplineAnimation::SplineAnimation(SplineChartItem* item):ChartAnimation(item),
29 SplineAnimation::SplineAnimation(SplineChartItem* item):ChartAnimation(item),
30 m_item(item),
30 m_item(item),
31 m_dirty(true)
31 m_dirty(true)
32 {
32 {
33 }
33 }
34
34
35 SplineAnimation::~SplineAnimation()
35 SplineAnimation::~SplineAnimation()
36 {
36 {
37 }
37 }
38
38
39 void SplineAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
39 void SplineAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
40 {
40 {
41 int x = oldPoints.count();
41 int x = oldPoints.count();
42 int y = newPoints.count();
42 int y = newPoints.count();
43
43
44 Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
44 Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
45
45
46 if (x != y && abs(x - y) != 1) {
46 if (x != y && abs(x - y) != 1) {
47 m_oldSpline.first = newPoints;
47 m_oldSpline.first = newPoints;
48 m_oldSpline.second = newControlPoints;
48 m_oldSpline.second = newControlPoints;
49 oldPoints.resize(newPoints.size());
49 oldPoints.resize(newPoints.size());
50 oldControlPoints.resize(newControlPoints.size());
50 oldControlPoints.resize(newControlPoints.size());
51 SplineVector oldPair;
51 SplineVector oldPair;
52 oldPair.first = oldPoints;
52 oldPair.first = oldPoints;
53 oldPair.second = oldControlPoints;
53 oldPair.second = oldControlPoints;
54 SplineVector newPair;
54 SplineVector newPair;
55 newPair.first = newPoints;
55 newPair.first = newPoints;
56 newPair.second = newControlPoints;
56 newPair.second = newControlPoints;
57 setKeyValueAt(0.0, qVariantFromValue(oldPair));
57 setKeyValueAt(0.0, qVariantFromValue(oldPair));
58 setKeyValueAt(1.0, qVariantFromValue(newPair));
58 setKeyValueAt(1.0, qVariantFromValue(newPair));
59 m_dirty = false;
59 m_dirty = false;
60 }
60 }
61 else {
61 else {
62 if(m_dirty) {
62 if(m_dirty) {
63 m_oldSpline.first = oldPoints;
63 m_oldSpline.first = oldPoints;
64 m_oldSpline.second = oldControlPoints;
64 m_oldSpline.second = oldControlPoints;
65 m_dirty = false;
65 m_dirty = false;
66 }
66 }
67 oldPoints = newPoints;
67 oldPoints = newPoints;
68 oldControlPoints = newControlPoints;
68 oldControlPoints = newControlPoints;
69 if (y < x) {
69 if (y < x) {
70 m_oldSpline.first.remove(index); //remove
70 m_oldSpline.first.remove(index); //remove
71 m_oldSpline.second.remove(index * 2);
71 m_oldSpline.second.remove(index * 2);
72 m_oldSpline.second.remove(index * 2);
72 m_oldSpline.second.remove(index * 2);
73 }
73 }
74 if (y > x) {
74 if (y > x) {
75 m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
75 m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
76 m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
76 m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
77 m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
77 m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
78 }
78 }
79 SplineVector newPair;
79 SplineVector newPair;
80 newPair.first=newPoints;
80 newPair.first=newPoints;
81 newPair.second=newControlPoints;
81 newPair.second=newControlPoints;
82 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
82 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
83 setKeyValueAt(1.0, qVariantFromValue(newPair));
83 setKeyValueAt(1.0, qVariantFromValue(newPair));
84
84
85 }
85 }
86 }
86 }
87
87
88 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
88 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
89 {
89 {
90
90
91 SplineVector startPair = qVariantValue< SplineVector >(start);
91 SplineVector startPair = qVariantValue< SplineVector >(start);
92 SplineVector endPair = qVariantValue< SplineVector >(end);
92 SplineVector endPair = qVariantValue< SplineVector >(end);
93 SplineVector result;
93 SplineVector result;
94
94
95
95
96 switch (m_type) {
96 switch (m_type) {
97
97
98 case MoveDownAnimation: {
98 case MoveDownAnimation: {
99 if (startPair.first.count() != endPair.first.count())
99 if (startPair.first.count() != endPair.first.count())
100 break;
100 break;
101 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
101 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
102 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
102 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
103 for(int i = 0; i < endPair.first.count(); i++) {
103 for(int i = 0; i < endPair.first.count(); i++) {
104 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
104 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
105 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
105 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
106 result.first << QPointF(x,y);
106 result.first << QPointF(x,y);
107 if (i + 1 >= endPair.first.count())
107 if (i + 1 >= endPair.first.count())
108 continue;
108 continue;
109 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
109 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
110 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
110 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
111 result.second << QPoint(x,y);
111 result.second << QPoint(x,y);
112 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
112 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
113 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
113 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
114 result.second << QPoint(x,y);
114 result.second << QPoint(x,y);
115 }
115 }
116
116
117 }
117 }
118 break;
118 break;
119 case LineDrawAnimation:{
119 case LineDrawAnimation:{
120 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
120 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
121 int count = endPair.first.count()* qBound(0.0, progress, 1.0);
121 int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
122 for(int i = 0; i < count; i++) {
122 for(int i = 0; i < count; i++) {
123 result.first << endPair.first[i];
123 result.first << endPair.first[i];
124 if(i + 1 == count)
124 if(i + 1 == count)
125 break;
125 break;
126 result.second << endPair.second[2 * i];
126 result.second << endPair.second[2 * i];
127 result.second << endPair.second[2 * i + 1];
127 result.second << endPair.second[2 * i + 1];
128 }
128 }
129 }
129 }
130 break;
130 break;
131 default:
131 default:
132 qWarning() << "Unknow type of animation";
132 qWarning() << "Unknow type of animation";
133 break;
133 break;
134 }
134 }
135
135
136 return qVariantFromValue(result);
136 return qVariantFromValue(result);
137 }
137 }
138
138
139 void SplineAnimation::updateCurrentValue (const QVariant &value )
139 void SplineAnimation::updateCurrentValue (const QVariant &value )
140 {
140 {
141 if (state() != QAbstractAnimation::Stopped) { //workaround
141 if (state() != QAbstractAnimation::Stopped) { //workaround
142 m_dirty = true;
142 m_dirty = true;
143 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
143 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
144 m_item->setLayout(pair.first, pair.second);
144 m_item->setLayout(pair.first, pair.second);
145 }
145 }
146 }
146 }
147
147
148
148
149 QTCOMMERCIALCHART_END_NAMESPACE
149 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,109 +1,109
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xyanimation_p.h"
21 #include "xyanimation_p.h"
22 #include "xychartitem_p.h"
22 #include "xychartitem_p.h"
23
23
24 Q_DECLARE_METATYPE(QVector<QPointF>)
24 Q_DECLARE_METATYPE(QVector<QPointF>)
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
28 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
29 m_item(item),
29 m_item(item),
30 m_dirty(false)
30 m_dirty(false)
31 {
31 {
32 }
32 }
33
33
34 XYAnimation::~XYAnimation()
34 XYAnimation::~XYAnimation()
35 {
35 {
36 }
36 }
37
37
38 void XYAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
38 void XYAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
39 {
39 {
40 int x = oldPoints.count();
40 int x = oldPoints.count();
41 int y = newPoints.count();
41 int y = newPoints.count();
42
42
43 if (x != y && abs(x - y) != 1) {
43 if (x != y && abs(x - y) != 1) {
44 m_oldPoints = newPoints;
44 m_oldPoints = newPoints;
45 oldPoints.resize(newPoints.size());
45 oldPoints.resize(newPoints.size());
46 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
46 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
47 setKeyValueAt(1.0, qVariantFromValue(newPoints));
47 setKeyValueAt(1.0, qVariantFromValue(newPoints));
48 m_dirty = false;
48 m_dirty = false;
49 }
49 }
50 else {
50 else {
51 if (m_dirty) {
51 if (m_dirty) {
52 m_oldPoints = oldPoints;
52 m_oldPoints = oldPoints;
53 m_dirty = false;
53 m_dirty = false;
54 }
54 }
55 oldPoints = newPoints;
55 oldPoints = newPoints;
56 if (y < x)
56 if (y < x)
57 m_oldPoints.remove(index); //remove
57 m_oldPoints.remove(index); //remove
58 if (y > x)
58 if (y > x)
59 m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]); //add
59 m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]); //add
60 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
60 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
61 setKeyValueAt(1.0, qVariantFromValue(newPoints));
61 setKeyValueAt(1.0, qVariantFromValue(newPoints));
62 Q_ASSERT(m_oldPoints.count() == newPoints.count());
62 Q_ASSERT(m_oldPoints.count() == newPoints.count());
63 }
63 }
64 }
64 }
65
65
66 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
66 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
67 {
67 {
68 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
68 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
69 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
69 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
70 QVector<QPointF> result;
70 QVector<QPointF> result;
71
71
72 switch (m_type) {
72 switch (m_type) {
73
73
74 case MoveDownAnimation: {
74 case MoveDownAnimation: {
75
75
76 if (startVector.count() != endVector.count())
76 if (startVector.count() != endVector.count())
77 break;
77 break;
78
78
79 for(int i = 0; i < startVector.count(); i++) {
79 for(int i = 0; i < startVector.count(); i++) {
80 qreal x = startVector[i].x() + ((endVector[i].x() - startVector[i].x()) * progress);
80 qreal x = startVector[i].x() + ((endVector[i].x() - startVector[i].x()) * progress);
81 qreal y = startVector[i].y() + ((endVector[i].y() - startVector[i].y()) * progress);
81 qreal y = startVector[i].y() + ((endVector[i].y() - startVector[i].y()) * progress);
82 result << QPointF(x, y);
82 result << QPointF(x, y);
83 }
83 }
84
84
85 }
85 }
86 break;
86 break;
87 case LineDrawAnimation: {
87 case LineDrawAnimation: {
88 for(int i = 0; i < endVector.count() * qBound(0.0, progress, 1.0); i++)
88 for(int i = 0; i < endVector.count() * qBound(qreal(0), progress, qreal(1)); i++)
89 result << endVector[i];
89 result << endVector[i];
90 }
90 }
91 break;
91 break;
92 default:
92 default:
93 qWarning() << "Unknown type of animation";
93 qWarning() << "Unknown type of animation";
94 break;
94 break;
95 }
95 }
96
96
97 return qVariantFromValue(result);
97 return qVariantFromValue(result);
98 }
98 }
99
99
100 void XYAnimation::updateCurrentValue (const QVariant &value)
100 void XYAnimation::updateCurrentValue (const QVariant &value)
101 {
101 {
102 if(state()!=QAbstractAnimation::Stopped){ //workaround
102 if(state()!=QAbstractAnimation::Stopped){ //workaround
103 m_dirty = true;
103 m_dirty = true;
104 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
104 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
105 m_item->setLayout(vector);
105 m_item->setLayout(vector);
106 }
106 }
107 }
107 }
108
108
109 QTCOMMERCIALCHART_END_NAMESPACE
109 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,282 +1,282
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qareaseries.h"
21 #include "qareaseries.h"
22 #include "qareaseries_p.h"
22 #include "qareaseries_p.h"
23 #include "qlineseries.h"
23 #include "qlineseries.h"
24 #include "areachartitem_p.h"
24 #include "areachartitem_p.h"
25 #include "legendmarker_p.h"
25 #include "legendmarker_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 /*!
33 /*!
34 \class QAreaSeries
34 \class QAreaSeries
35 \brief The QAreaSeries class is used for making area charts.
35 \brief The QAreaSeries class is used for making area charts.
36
36
37 \mainclass
37 \mainclass
38
38
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
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
40 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
40 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
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.
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.
42 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
42 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
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.
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.
44
44
45 \image areachart.png
45 \image areachart.png
46
46
47 Creating basic area chart is simple:
47 Creating basic area chart is simple:
48 \code
48 \code
49 QLineSeries* lineSeries = new QLineSeries();
49 QLineSeries* lineSeries = new QLineSeries();
50 series->append(0, 6);
50 series->append(0, 6);
51 series->append(2, 4);
51 series->append(2, 4);
52 QAreaSeries* areaSeries = new QAreaSeries(lineSeries);
52 QAreaSeries* areaSeries = new QAreaSeries(lineSeries);
53 ...
53 ...
54 chartView->addSeries(areaSeries);
54 chartView->addSeries(areaSeries);
55 \endcode
55 \endcode
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn virtual QSeriesType QAreaSeries::type() const
59 \fn virtual QSeriesType QAreaSeries::type() const
60 \brief Returns type of series.
60 \brief Returns type of series.
61 \sa QSeries, QSeriesType
61 \sa QSeries, QSeriesType
62 */
62 */
63
63
64 /*!
64 /*!
65 \fn QLineSeries* QAreaSeries::upperSeries() const
65 \fn QLineSeries* QAreaSeries::upperSeries() const
66 \brief Returns upperSeries used to define one of area boundaries.
66 \brief Returns upperSeries used to define one of area boundaries.
67 */
67 */
68
68
69 /*!
69 /*!
70 \fn QLineSeries* QAreaSeries::lowerSeries() const
70 \fn QLineSeries* QAreaSeries::lowerSeries() const
71 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
71 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
72 this function return Null pointer.
72 this function return Null pointer.
73 */
73 */
74
74
75 /*!
75 /*!
76 \fn QPen QAreaSeries::pen() const
76 \fn QPen QAreaSeries::pen() const
77 \brief Returns the pen used to draw line for this series.
77 \brief Returns the pen used to draw line for this series.
78 \sa setPen()
78 \sa setPen()
79 */
79 */
80
80
81 /*!
81 /*!
82 \fn QPen QAreaSeries::brush() const
82 \fn QPen QAreaSeries::brush() const
83 \brief Returns the brush used to draw line for this series.
83 \brief Returns the brush used to draw line for this series.
84 \sa setBrush()
84 \sa setBrush()
85 */
85 */
86
86
87 /*!
87 /*!
88 \fn bool QAreaSeries::pointsVisible() const
88 \fn bool QAreaSeries::pointsVisible() const
89 \brief Returns if the points are drawn for this series.
89 \brief Returns if the points are drawn for this series.
90 \sa setPointsVisible()
90 \sa setPointsVisible()
91 */
91 */
92
92
93 /*!
93 /*!
94 \fn void QAreaSeries::clicked(const QPointF& point)
94 \fn void QAreaSeries::clicked(const QPointF& point)
95 \brief Signal is emitted when user clicks the \a point on area chart.
95 \brief Signal is emitted when user clicks the \a point on area chart.
96 */
96 */
97
97
98 /*!
98 /*!
99 \fn void QAreaSeries::selected()
99 \fn void QAreaSeries::selected()
100
100
101 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
101 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
102 implemented by the user of QAreaSeries API.
102 implemented by the user of QAreaSeries API.
103 */
103 */
104
104
105 /*!
105 /*!
106 \fn void QAreaSeriesPrivate::updated()
106 \fn void QAreaSeriesPrivate::updated()
107 \brief \internal
107 \brief \internal
108 */
108 */
109
109
110 /*!
110 /*!
111 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
111 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
112 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
112 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
113 When series object is added to QChartView or QChart instance ownerships is transfered.
113 When series object is added to QChartView or QChart instance ownerships is transferred.
114 */
114 */
115 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
115 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
116 : QSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
116 : QSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
117 {
117 {
118 }
118 }
119
119
120 /*!
120 /*!
121 Destroys the object. Series added to QChartView or QChart instances are owned by those,
121 Destroys the object. Series added to QChartView or QChart instances are owned by those,
122 and are deleted when mentioned object are destroyed.
122 and are deleted when mentioned object are destroyed.
123 */
123 */
124 QAreaSeries::~QAreaSeries()
124 QAreaSeries::~QAreaSeries()
125 {
125 {
126 }
126 }
127
127
128
128
129 QSeries::QSeriesType QAreaSeries::type() const
129 QSeries::QSeriesType QAreaSeries::type() const
130 {
130 {
131 return QSeries::SeriesTypeArea;
131 return QSeries::SeriesTypeArea;
132 }
132 }
133
133
134 QLineSeries* QAreaSeries::upperSeries() const
134 QLineSeries* QAreaSeries::upperSeries() const
135 {
135 {
136 Q_D(const QAreaSeries);
136 Q_D(const QAreaSeries);
137 return d->m_upperSeries;
137 return d->m_upperSeries;
138 }
138 }
139
139
140 QLineSeries* QAreaSeries::lowerSeries() const
140 QLineSeries* QAreaSeries::lowerSeries() const
141 {
141 {
142 Q_D(const QAreaSeries);
142 Q_D(const QAreaSeries);
143 return d->m_lowerSeries;
143 return d->m_lowerSeries;
144 }
144 }
145
145
146 /*!
146 /*!
147 Sets \a pen used for drawing area outline.
147 Sets \a pen used for drawing area outline.
148 */
148 */
149 void QAreaSeries::setPen(const QPen &pen)
149 void QAreaSeries::setPen(const QPen &pen)
150 {
150 {
151 Q_D(QAreaSeries);
151 Q_D(QAreaSeries);
152 if (d->m_pen != pen) {
152 if (d->m_pen != pen) {
153 d->m_pen = pen;
153 d->m_pen = pen;
154 emit d->updated();
154 emit d->updated();
155 }
155 }
156 }
156 }
157
157
158 QPen QAreaSeries::pen() const
158 QPen QAreaSeries::pen() const
159 {
159 {
160 Q_D(const QAreaSeries);
160 Q_D(const QAreaSeries);
161 return d->m_pen;
161 return d->m_pen;
162 }
162 }
163
163
164 /*!
164 /*!
165 Sets \a brush used for filling the area.
165 Sets \a brush used for filling the area.
166 */
166 */
167 void QAreaSeries::setBrush(const QBrush &brush)
167 void QAreaSeries::setBrush(const QBrush &brush)
168 {
168 {
169 Q_D(QAreaSeries);
169 Q_D(QAreaSeries);
170 if (d->m_brush != brush) {
170 if (d->m_brush != brush) {
171 d->m_brush = brush;
171 d->m_brush = brush;
172 emit d->updated();
172 emit d->updated();
173 }
173 }
174 }
174 }
175
175
176 QBrush QAreaSeries::brush() const
176 QBrush QAreaSeries::brush() const
177 {
177 {
178 Q_D(const QAreaSeries);
178 Q_D(const QAreaSeries);
179 return d->m_brush;
179 return d->m_brush;
180 }
180 }
181 /*!
181 /*!
182 Sets if data points are \a visible and should be drawn on line.
182 Sets if data points are \a visible and should be drawn on line.
183 */
183 */
184 void QAreaSeries::setPointsVisible(bool visible)
184 void QAreaSeries::setPointsVisible(bool visible)
185 {
185 {
186 Q_D(QAreaSeries);
186 Q_D(QAreaSeries);
187 if (d->m_pointsVisible != visible) {
187 if (d->m_pointsVisible != visible) {
188 d->m_pointsVisible = visible;
188 d->m_pointsVisible = visible;
189 emit d->updated();
189 emit d->updated();
190 }
190 }
191 }
191 }
192
192
193 bool QAreaSeries::pointsVisible() const
193 bool QAreaSeries::pointsVisible() const
194 {
194 {
195 Q_D(const QAreaSeries);
195 Q_D(const QAreaSeries);
196 return d->m_pointsVisible;
196 return d->m_pointsVisible;
197 }
197 }
198
198
199 bool QAreaSeries::setModel(QAbstractItemModel* model)
199 bool QAreaSeries::setModel(QAbstractItemModel* model)
200 {
200 {
201 Q_UNUSED(model);
201 Q_UNUSED(model);
202 qWarning()<<"Not implemented";
202 qWarning()<<"Not implemented";
203 return false;
203 return false;
204 }
204 }
205
205
206 QAbstractItemModel* QAreaSeries::model() const
206 QAbstractItemModel* QAreaSeries::model() const
207 {
207 {
208 return 0;
208 return 0;
209 }
209 }
210
210
211 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
212
212
213 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
213 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
214 QSeriesPrivate(q),
214 QSeriesPrivate(q),
215 m_upperSeries(upperSeries),
215 m_upperSeries(upperSeries),
216 m_lowerSeries(lowerSeries),
216 m_lowerSeries(lowerSeries),
217 m_pointsVisible(false)
217 m_pointsVisible(false)
218 {
218 {
219 }
219 }
220
220
221 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
221 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
222 {
222 {
223 Q_Q(QAreaSeries);
223 Q_Q(QAreaSeries);
224
224
225 qreal minX(domain.minX());
225 qreal minX(domain.minX());
226 qreal minY(domain.minY());
226 qreal minY(domain.minY());
227 qreal maxX(domain.maxX());
227 qreal maxX(domain.maxX());
228 qreal maxY(domain.maxY());
228 qreal maxY(domain.maxY());
229 int tickXCount(domain.tickXCount());
229 int tickXCount(domain.tickXCount());
230 int tickYCount(domain.tickYCount());
230 int tickYCount(domain.tickYCount());
231
231
232 QLineSeries* upperSeries = q->upperSeries();
232 QLineSeries* upperSeries = q->upperSeries();
233 QLineSeries* lowerSeries = q->lowerSeries();
233 QLineSeries* lowerSeries = q->lowerSeries();
234
234
235 for (int i = 0; i < upperSeries->count(); i++)
235 for (int i = 0; i < upperSeries->count(); i++)
236 {
236 {
237 qreal x = upperSeries->x(i);
237 qreal x = upperSeries->x(i);
238 qreal y = upperSeries->y(i);
238 qreal y = upperSeries->y(i);
239 minX = qMin(minX, x);
239 minX = qMin(minX, x);
240 minY = qMin(minY, y);
240 minY = qMin(minY, y);
241 maxX = qMax(maxX, x);
241 maxX = qMax(maxX, x);
242 maxY = qMax(maxY, y);
242 maxY = qMax(maxY, y);
243 }
243 }
244 if(lowerSeries) {
244 if(lowerSeries) {
245 for (int i = 0; i < lowerSeries->count(); i++)
245 for (int i = 0; i < lowerSeries->count(); i++)
246 {
246 {
247 qreal x = lowerSeries->x(i);
247 qreal x = lowerSeries->x(i);
248 qreal y = lowerSeries->y(i);
248 qreal y = lowerSeries->y(i);
249 minX = qMin(minX, x);
249 minX = qMin(minX, x);
250 minY = qMin(minY, y);
250 minY = qMin(minY, y);
251 maxX = qMax(maxX, x);
251 maxX = qMax(maxX, x);
252 maxY = qMax(maxY, y);
252 maxY = qMax(maxY, y);
253 }}
253 }}
254
254
255 domain.setRangeX(minX,maxX,tickXCount);
255 domain.setRangeX(minX,maxX,tickXCount);
256 domain.setRangeY(minY,maxY,tickYCount);
256 domain.setRangeY(minY,maxY,tickYCount);
257 }
257 }
258
258
259 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
259 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
260 {
260 {
261 Q_Q(QAreaSeries);
261 Q_Q(QAreaSeries);
262
262
263 AreaChartItem* area = new AreaChartItem(q,presenter);
263 AreaChartItem* area = new AreaChartItem(q,presenter);
264 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
264 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
265 presenter->animator()->addAnimation(area->upperLineItem());
265 presenter->animator()->addAnimation(area->upperLineItem());
266 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
266 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
267 }
267 }
268 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
268 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
269 return area;
269 return area;
270 }
270 }
271
271
272 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
272 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
273 {
273 {
274 Q_Q(QAreaSeries);
274 Q_Q(QAreaSeries);
275 QList<LegendMarker*> list;
275 QList<LegendMarker*> list;
276 return list << new AreaLegendMarker(q,legend);
276 return list << new AreaLegendMarker(q,legend);
277 }
277 }
278
278
279 #include "moc_qareaseries.cpp"
279 #include "moc_qareaseries.cpp"
280 #include "moc_qareaseries_p.cpp"
280 #include "moc_qareaseries_p.cpp"
281
281
282 QTCOMMERCIALCHART_END_NAMESPACE
282 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,96
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qchartaxiscategories.h"
21 #include "qchartaxiscategories.h"
22 #include "qchartaxiscategories_p.h"
22 #include "qchartaxiscategories_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 QChartAxisCategories::QChartAxisCategories():
26 QChartAxisCategories::QChartAxisCategories():
27 d_ptr(new QChartAxisCategoriesPrivate(this))
27 d_ptr(new QChartAxisCategoriesPrivate(this))
28 {
28 {
29
29
30 }
30 }
31
31
32 QChartAxisCategories::~QChartAxisCategories()
32 QChartAxisCategories::~QChartAxisCategories()
33 {
33 {
34
34
35 }
35 }
36
36
37 void QChartAxisCategories::insert(const QBarCategories &categories)
37 void QChartAxisCategories::insert(const QBarCategories &categories)
38 {
38 {
39 int i=1;
39 int i=1;
40 foreach (QString string , categories) {
40 foreach (const QString& string , categories) {
41 d_ptr->m_map.insert(i,string);
41 d_ptr->m_map.insert(i,string);
42 i++;
42 i++;
43 }
43 }
44 emit d_ptr->updated();
44 emit d_ptr->updated();
45 }
45 }
46
46
47 void QChartAxisCategories::insert(qreal value,QString label)
47 void QChartAxisCategories::insert(qreal value,QString label)
48 {
48 {
49 d_ptr->m_map.insert(value,label);
49 d_ptr->m_map.insert(value,label);
50 emit d_ptr->updated();
50 emit d_ptr->updated();
51 }
51 }
52
52
53 void QChartAxisCategories::remove(qreal value)
53 void QChartAxisCategories::remove(qreal value)
54 {
54 {
55 d_ptr->m_map.remove(value);
55 d_ptr->m_map.remove(value);
56 emit d_ptr->updated();
56 emit d_ptr->updated();
57 }
57 }
58
58
59 void QChartAxisCategories::clear()
59 void QChartAxisCategories::clear()
60 {
60 {
61 d_ptr->m_map.clear();
61 d_ptr->m_map.clear();
62 emit d_ptr->updated();
62 emit d_ptr->updated();
63 }
63 }
64
64
65 int QChartAxisCategories::count()
65 int QChartAxisCategories::count()
66 {
66 {
67 return d_ptr->m_map.count();
67 return d_ptr->m_map.count();
68 }
68 }
69
69
70 QList<qreal> QChartAxisCategories::values() const
70 QList<qreal> QChartAxisCategories::values() const
71 {
71 {
72 return d_ptr->m_map.keys();
72 return d_ptr->m_map.keys();
73 }
73 }
74
74
75 QString QChartAxisCategories::label(qreal value) const
75 QString QChartAxisCategories::label(qreal value) const
76 {
76 {
77 return d_ptr->m_map.value(value);
77 return d_ptr->m_map.value(value);
78 }
78 }
79
79
80 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81
81
82 QChartAxisCategoriesPrivate::QChartAxisCategoriesPrivate(QChartAxisCategories *q):
82 QChartAxisCategoriesPrivate::QChartAxisCategoriesPrivate(QChartAxisCategories *q):
83 q_ptr(q)
83 q_ptr(q)
84 {
84 {
85
85
86 }
86 }
87
87
88 QChartAxisCategoriesPrivate::~QChartAxisCategoriesPrivate()
88 QChartAxisCategoriesPrivate::~QChartAxisCategoriesPrivate()
89 {
89 {
90
90
91 }
91 }
92
92
93 #include "moc_qchartaxiscategories.cpp"
93 #include "moc_qchartaxiscategories.cpp"
94 #include "moc_qchartaxiscategories_p.cpp"
94 #include "moc_qchartaxiscategories_p.cpp"
95
95
96 QTCOMMERCIALCHART_END_NAMESPACE
96 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,198 +1,198
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "barchartmodel_p.h"
21 #include "barchartmodel_p.h"
22 #include "qbarset.h"
22 #include "qbarset.h"
23 #include <limits.h>
23 #include <limits.h>
24 #include <QVector>
24 #include <QVector>
25 #include <QDebug>
25 #include <QDebug>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 BarChartModel::BarChartModel(QStringList categories, QObject *parent) : QObject(parent),
29 BarChartModel::BarChartModel(QStringList categories, QObject *parent) : QObject(parent),
30 m_category(categories)
30 m_category(categories)
31 {
31 {
32 }
32 }
33
33
34 QStringList BarChartModel::category()
34 QStringList BarChartModel::category()
35 {
35 {
36 return m_category;
36 return m_category;
37 }
37 }
38
38
39 void BarChartModel::appendBarSet(QBarSet *set)
39 void BarChartModel::appendBarSet(QBarSet *set)
40 {
40 {
41 m_dataModel.append(set);
41 m_dataModel.append(set);
42 }
42 }
43
43
44 void BarChartModel::removeBarSet(QBarSet *set)
44 void BarChartModel::removeBarSet(QBarSet *set)
45 {
45 {
46 if (m_dataModel.contains(set)) {
46 if (m_dataModel.contains(set)) {
47 m_dataModel.removeOne(set);
47 m_dataModel.removeOne(set);
48 }
48 }
49 }
49 }
50
50
51 void BarChartModel::insertBarSet(int i, QBarSet *set)
51 void BarChartModel::insertBarSet(int i, QBarSet *set)
52 {
52 {
53 m_dataModel.insert(i, set);
53 m_dataModel.insert(i, set);
54 }
54 }
55
55
56 void BarChartModel::insertCategory(int i, QString category)
56 void BarChartModel::insertCategory(int i, QString category)
57 {
57 {
58 m_category.insert(i, category);
58 m_category.insert(i, category);
59 }
59 }
60
60
61 void BarChartModel::removeCategory(int i)
61 void BarChartModel::removeCategory(int i)
62 {
62 {
63 m_category.removeAt(i);
63 m_category.removeAt(i);
64 }
64 }
65
65
66 QBarSet* BarChartModel::barsetAt(int index) const
66 QBarSet* BarChartModel::barsetAt(int index) const
67 {
67 {
68 return m_dataModel.at(index);
68 return m_dataModel.at(index);
69 }
69 }
70
70
71 QList<QBarSet*> BarChartModel::barSets() const
71 QList<QBarSet*> BarChartModel::barSets() const
72 {
72 {
73 return m_dataModel;
73 return m_dataModel;
74 }
74 }
75
75
76 int BarChartModel::barsetCount() const
76 int BarChartModel::barsetCount() const
77 {
77 {
78 return m_dataModel.count();
78 return m_dataModel.count();
79 }
79 }
80
80
81 int BarChartModel::categoryCount() const
81 int BarChartModel::categoryCount() const
82 {
82 {
83 return m_category.count();
83 return m_category.count();
84 }
84 }
85
85
86 qreal BarChartModel::min() const
86 qreal BarChartModel::min() const
87 {
87 {
88 Q_ASSERT(m_dataModel.count() > 0);
88 Q_ASSERT(m_dataModel.count() > 0);
89 // TODO: make min and max members and update them when data changes.
89 // TODO: make min and max members and update them when data changes.
90 // This is slower since they are checked every time, even if data is same since previous call.
90 // This is slower since they are checked every time, even if data is same since previous call.
91 qreal min = INT_MAX;
91 qreal min = INT_MAX;
92
92
93 for (int i = 0; i < m_dataModel.count(); i++) {
93 for (int i = 0; i < m_dataModel.count(); i++) {
94 int itemCount = m_dataModel.at(i)->count();
94 int itemCount = m_dataModel.at(i)->count();
95 for (int j = 0; j < itemCount; j++) {
95 for (int j = 0; j < itemCount; j++) {
96 qreal temp = m_dataModel.at(i)->valueAt(j);
96 qreal temp = m_dataModel.at(i)->valueAt(j);
97 if (temp < min)
97 if (temp < min)
98 min = temp;
98 min = temp;
99 }
99 }
100 }
100 }
101 return min;
101 return min;
102 }
102 }
103
103
104 qreal BarChartModel::max() const
104 qreal BarChartModel::max() const
105 {
105 {
106 if (m_dataModel.count() == 0) return 0;
106 if (m_dataModel.count() == 0) return 0;
107 // TODO: make min and max members and update them when data changes.
107 // TODO: make min and max members and update them when data changes.
108 // This is slower since they are checked every time, even if data is same since previous call.
108 // This is slower since they are checked every time, even if data is same since previous call.
109 qreal max = INT_MIN;
109 qreal max = INT_MIN;
110
110
111 for (int i = 0; i < m_dataModel.count(); i++) {
111 for (int i = 0; i < m_dataModel.count(); i++) {
112 int itemCount = m_dataModel.at(i)->count();
112 int itemCount = m_dataModel.at(i)->count();
113 for (int j = 0; j < itemCount; j++) {
113 for (int j = 0; j < itemCount; j++) {
114 qreal temp = m_dataModel.at(i)->valueAt(j);
114 qreal temp = m_dataModel.at(i)->valueAt(j);
115 if (temp > max)
115 if (temp > max)
116 max = temp;
116 max = temp;
117 }
117 }
118 }
118 }
119
119
120 return max;
120 return max;
121 }
121 }
122
122
123 qreal BarChartModel::valueAt(int set, int category) const
123 qreal BarChartModel::valueAt(int set, int category) const
124 {
124 {
125 if ((set < 0) || (set >= m_dataModel.count())) {
125 if ((set < 0) || (set >= m_dataModel.count())) {
126 // No set, no value.
126 // No set, no value.
127 return 0;
127 return 0;
128 } else if ((category < 0) || (category >= m_dataModel.at(set)->count())) {
128 } else if ((category < 0) || (category >= m_dataModel.at(set)->count())) {
129 // No category, no value.
129 // No category, no value.
130 return 0;
130 return 0;
131 }
131 }
132
132
133 return m_dataModel.at(set)->valueAt(category);
133 return m_dataModel.at(set)->valueAt(category);
134 }
134 }
135
135
136 qreal BarChartModel::percentageAt(int set, int category) const
136 qreal BarChartModel::percentageAt(int set, int category) const
137 {
137 {
138 if ((set < 0) || (set >= m_dataModel.count())) {
138 if ((set < 0) || (set >= m_dataModel.count())) {
139 // No set, no value.
139 // No set, no value.
140 return 0;
140 return 0;
141 } else if ((category < 0) || (category >= m_dataModel.at(set)->count())) {
141 } else if ((category < 0) || (category >= m_dataModel.at(set)->count())) {
142 // No category, no value.
142 // No category, no value.
143 return 0;
143 return 0;
144 }
144 }
145
145
146 qreal value = m_dataModel.at(set)->valueAt(category);
146 qreal value = m_dataModel.at(set)->valueAt(category);
147 qreal total = categorySum(category);
147 qreal total = categorySum(category);
148 if ( qFuzzyCompare(total, 0) )
148 if ( qFuzzyCompare(total, 0) )
149 return 0;
149 return 0;
150
150
151 return value / total;
151 return value / total;
152 }
152 }
153
153
154 qreal BarChartModel::categorySum(int category) const
154 qreal BarChartModel::categorySum(int category) const
155 {
155 {
156 qreal sum(0);
156 qreal sum(0);
157 int count = m_dataModel.count(); // Count sets
157 int count = m_dataModel.count(); // Count sets
158
158
159 for (int set = 0; set < count; set++) {
159 for (int set = 0; set < count; set++) {
160 if (category < m_dataModel.at(set)->count())
160 if (category < m_dataModel.at(set)->count())
161 sum += m_dataModel.at(set)->valueAt(category);
161 sum += m_dataModel.at(set)->valueAt(category);
162 }
162 }
163 return sum;
163 return sum;
164 }
164 }
165
165
166 qreal BarChartModel::absoluteCategorySum(int category) const
166 qreal BarChartModel::absoluteCategorySum(int category) const
167 {
167 {
168 qreal sum(0);
168 qreal sum(0);
169 int count = m_dataModel.count(); // Count sets
169 int count = m_dataModel.count(); // Count sets
170
170
171 for (int set = 0; set < count; set++) {
171 for (int set = 0; set < count; set++) {
172 if (category < m_dataModel.at(set)->count())
172 if (category < m_dataModel.at(set)->count())
173 sum += qAbs(m_dataModel.at(set)->valueAt(category));
173 sum += qAbs(m_dataModel.at(set)->valueAt(category));
174 }
174 }
175 return sum;
175 return sum;
176 }
176 }
177
177
178 qreal BarChartModel::maxCategorySum() const
178 qreal BarChartModel::maxCategorySum() const
179 {
179 {
180 qreal max = INT_MIN;
180 qreal max = INT_MIN;
181 int count = categoryCount();
181 int count = categoryCount();
182
182
183 for (int col = 0; col < count; col++) {
183 for (int col = 0; col < count; col++) {
184 qreal sum = categorySum(col);
184 qreal sum = categorySum(col);
185 if (sum > max)
185 if (sum > max)
186 max = sum;
186 max = sum;
187 }
187 }
188 return max;
188 return max;
189 }
189 }
190
190
191 QString BarChartModel::categoryName(int category)
191 QString BarChartModel::categoryName(int category)
192 {
192 {
193 return m_category.at(category);
193 return m_category.at(category);
194 }
194 }
195
195
196 #include "moc_barchartmodel_p.cpp"
196 #include "moc_barchartmodel_p.cpp"
197
197
198 QTCOMMERCIALCHART_END_NAMESPACE No newline at end of file
198 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,540 +1,540
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qbarseries.h"
21 #include "qbarseries.h"
22 #include "qbarseries_p.h"
22 #include "qbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "barchartmodel_p.h"
25 #include "barchartmodel_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "chartdataset_p.h"
28 #include "chartdataset_p.h"
29 #include "charttheme_p.h"
29 #include "charttheme_p.h"
30 #include "chartanimator_p.h"
30 #include "chartanimator_p.h"
31
31
32 #include <QAbstractItemModel>
32 #include <QAbstractItemModel>
33 #include <QModelIndex>
33 #include <QModelIndex>
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 /*!
37 /*!
38 \class QBarSeries
38 \class QBarSeries
39 \brief part of QtCommercial chart API.
39 \brief part of QtCommercial chart API.
40
40
41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
42 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
42 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
43 by QStringList.
43 by QStringList.
44
44
45 \mainclass
45 \mainclass
46
46
47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 */
48 */
49
49
50 /*!
50 /*!
51 \fn virtual QSeriesType QBarSeries::type() const
51 \fn virtual QSeriesType QBarSeries::type() const
52 \brief Returns type of series.
52 \brief Returns type of series.
53 \sa QSeries, QSeriesType
53 \sa QSeries, QSeriesType
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QBarSeries::clicked(QBarSet *barset, QString category, Qt::MouseButtons button)
57 \fn void QBarSeries::clicked(QBarSet *barset, QString category, Qt::MouseButtons button)
58
58
59 The signal is emitted if the user clicks with a mouse \a button on top of QBarSet \a barset of category \a category
59 The signal is emitted if the user clicks with a mouse \a button on top of QBarSet \a barset of category \a category
60 contained by the series.
60 contained by the series.
61 */
61 */
62
62
63 /*!
63 /*!
64 \fn void QBarSeries::selected()
64 \fn void QBarSeries::selected()
65
65
66 The signal is emitted if the user selects/deselects the series. The logic for storing selections should be
66 The signal is emitted if the user selects/deselects the series. The logic for storing selections should be
67 implemented by the user of QBarSeries API.
67 implemented by the user of QBarSeries API.
68 */
68 */
69
69
70 /*!
70 /*!
71 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
71 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
72 QBarSeries is QObject which is a child of a \a parent.
72 QBarSeries is QObject which is a child of a \a parent.
73 */
73 */
74 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
74 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
75 QSeries(*new QBarSeriesPrivate(categories, this),parent)
75 QSeries(*new QBarSeriesPrivate(categories, this),parent)
76 {
76 {
77 }
77 }
78
78
79 /*!
79 /*!
80 \internal
80 \internal
81 */
81 */
82 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
82 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
83 QSeries(d,parent)
83 QSeries(d,parent)
84 {
84 {
85 }
85 }
86
86
87 QSeries::QSeriesType QBarSeries::type() const
87 QSeries::QSeriesType QBarSeries::type() const
88 {
88 {
89 return QSeries::SeriesTypeBar;
89 return QSeries::SeriesTypeBar;
90 }
90 }
91
91
92 /*!
92 /*!
93 Adds a set of bars to series. Takes ownership of \a set.
93 Adds a set of bars to series. Takes ownership of \a set.
94 Connects the clicked(QString, Qt::MouseButtons) signal
94 Connects the clicked(QString, Qt::MouseButtons) signal
95 of \a set to this series
95 of \a set to this series
96 */
96 */
97 void QBarSeries::appendBarSet(QBarSet *set)
97 void QBarSeries::appendBarSet(QBarSet *set)
98 {
98 {
99 Q_D(QBarSeries);
99 Q_D(QBarSeries);
100 d->m_internalModel->appendBarSet(set);
100 d->m_internalModel->appendBarSet(set);
101 QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged()));
101 QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged()));
102 emit d->restructuredBars();
102 emit d->restructuredBars();
103 }
103 }
104
104
105 /*!
105 /*!
106 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
106 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
107 Disconnects the clicked(QString, Qt::MouseButtons) signal
107 Disconnects the clicked(QString, Qt::MouseButtons) signal
108 of \a set from this series
108 of \a set from this series
109 */
109 */
110 void QBarSeries::removeBarSet(QBarSet *set)
110 void QBarSeries::removeBarSet(QBarSet *set)
111 {
111 {
112 Q_D(QBarSeries);
112 Q_D(QBarSeries);
113 d->m_internalModel->removeBarSet(set);
113 d->m_internalModel->removeBarSet(set);
114 emit d->restructuredBars();
114 emit d->restructuredBars();
115 }
115 }
116
116
117 /*!
117 /*!
118 Adds a list of barsets to series. Takes ownership of \a sets.
118 Adds a list of barsets to series. Takes ownership of \a sets.
119 Connects the clicked(QString, Qt::MouseButtons) signals
119 Connects the clicked(QString, Qt::MouseButtons) signals
120 of \a sets to this series
120 of \a sets to this series
121 */
121 */
122 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
122 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
123 {
123 {
124 Q_D(QBarSeries);
124 Q_D(QBarSeries);
125 foreach (QBarSet* barset, sets) {
125 foreach (QBarSet* barset, sets) {
126 d->m_internalModel->appendBarSet(barset);
126 d->m_internalModel->appendBarSet(barset);
127 QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
127 QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
128 }
128 }
129 emit d->restructuredBars();
129 emit d->restructuredBars();
130
130
131 }
131 }
132
132
133 /*!
133 /*!
134 Removes a list of barsets from series. Releases ownership of \a sets. Doesnt delete \a sets.
134 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
135 Disconnects the clicked(QString, Qt::MouseButtons) signal
135 Disconnects the clicked(QString, Qt::MouseButtons) signal
136 of \a sets from this series
136 of \a sets from this series
137 */
137 */
138 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
138 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
139 {
139 {
140 Q_D(QBarSeries);
140 Q_D(QBarSeries);
141
141
142 foreach (QBarSet* barset, sets) {
142 foreach (QBarSet* barset, sets) {
143 d->m_internalModel->removeBarSet(barset);
143 d->m_internalModel->removeBarSet(barset);
144 }
144 }
145 emit d->restructuredBars();
145 emit d->restructuredBars();
146 }
146 }
147
147
148 /*!
148 /*!
149 Inserts new \a set on the \a i position.
149 Inserts new \a set on the \a i position.
150 The barset that is currently at this postion is moved to postion i + 1
150 The barset that is currently at this postion is moved to postion i + 1
151 */
151 */
152 void QBarSeries::insertBarSet(int i, QBarSet *set)
152 void QBarSeries::insertBarSet(int i, QBarSet *set)
153 {
153 {
154 Q_D(QBarSeries);
154 Q_D(QBarSeries);
155 d->m_internalModel->insertBarSet(i, set);
155 d->m_internalModel->insertBarSet(i, set);
156 emit d->barsetChanged();
156 emit d->barsetChanged();
157 }
157 }
158
158
159 /*!
159 /*!
160 Inserts new \a category on the \a i position.
160 Inserts new \a category on the \a i position.
161 The category that is currently at this postion is moved to postion i + 1
161 The category that is currently at this postion is moved to postion i + 1
162 \sa removeCategory()
162 \sa removeCategory()
163 */
163 */
164 void QBarSeries::insertCategory(int i, QString category)
164 void QBarSeries::insertCategory(int i, QString category)
165 {
165 {
166 Q_D(QBarSeries);
166 Q_D(QBarSeries);
167 d->m_internalModel->insertCategory(i, category);
167 d->m_internalModel->insertCategory(i, category);
168 }
168 }
169
169
170 /*!
170 /*!
171 Removes the category specified by \a i
171 Removes the category specified by \a i
172 \sa insertCategory()
172 \sa insertCategory()
173 */
173 */
174 void QBarSeries::removeCategory(int i)
174 void QBarSeries::removeCategory(int i)
175 {
175 {
176 Q_D(QBarSeries);
176 Q_D(QBarSeries);
177 d->m_internalModel->removeCategory(i);
177 d->m_internalModel->removeCategory(i);
178 }
178 }
179
179
180 /*!
180 /*!
181 Returns number of sets in series.
181 Returns number of sets in series.
182 */
182 */
183 int QBarSeries::barsetCount() const
183 int QBarSeries::barsetCount() const
184 {
184 {
185 Q_D(const QBarSeries);
185 Q_D(const QBarSeries);
186 return d->m_internalModel->barsetCount();
186 return d->m_internalModel->barsetCount();
187 }
187 }
188
188
189 /*!
189 /*!
190 Returns number of categories in series
190 Returns number of categories in series
191 */
191 */
192 int QBarSeries::categoryCount() const
192 int QBarSeries::categoryCount() const
193 {
193 {
194 Q_D(const QBarSeries);
194 Q_D(const QBarSeries);
195 return d->m_internalModel->categoryCount();
195 return d->m_internalModel->categoryCount();
196 }
196 }
197
197
198 /*!
198 /*!
199 Returns a list of sets in series. Keeps ownership of sets.
199 Returns a list of sets in series. Keeps ownership of sets.
200 */
200 */
201 QList<QBarSet*> QBarSeries::barSets() const
201 QList<QBarSet*> QBarSeries::barSets() const
202 {
202 {
203 Q_D(const QBarSeries);
203 Q_D(const QBarSeries);
204 return d->m_internalModel->barSets();
204 return d->m_internalModel->barSets();
205 }
205 }
206
206
207 /*!
207 /*!
208 Enables or disables tooltip depending on parameter \a enabled.
208 Enables or disables tooltip depending on parameter \a enabled.
209 Tooltip shows the name of set, when mouse is hovering on top of bar.
209 Tooltip shows the name of set, when mouse is hovering on top of bar.
210 Calling without parameter \a enabled, enables the tooltip
210 Calling without parameter \a enabled, enables the tooltip
211 */
211 */
212 void QBarSeries::setToolTipEnabled(bool enabled)
212 void QBarSeries::setToolTipEnabled(bool enabled)
213 {
213 {
214 Q_D(QBarSeries);
214 Q_D(QBarSeries);
215 d->setToolTipEnabled(enabled);
215 d->setToolTipEnabled(enabled);
216 }
216 }
217
217
218 /*!
218 /*!
219 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
219 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
220 Sets the \a model to be used as a data source
220 Sets the \a model to be used as a data source
221 */
221 */
222 bool QBarSeries::setModel(QAbstractItemModel *model)
222 bool QBarSeries::setModel(QAbstractItemModel *model)
223 {
223 {
224 Q_D(QBarSeries);
224 Q_D(QBarSeries);
225 return d->setModel(model);
225 return d->setModel(model);
226 }
226 }
227
227
228 /*!
228 /*!
229 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
229 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
230 Sets column/row specified by \a categories to be used as a list of bar series categories.
230 Sets column/row specified by \a categories to be used as a list of bar series categories.
231 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
231 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
232 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
232 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
233 All the columns/rows inbetween those two values are also used as data for bar sets.
233 All the columns/rows inbetween those two values are also used as data for bar sets.
234 The \a orientation paramater specifies whether the data is in columns or in rows.
234 The \a orientation parameter specifies whether the data is in columns or in rows.
235 */
235 */
236 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
236 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
237 {
237 {
238 Q_D(QBarSeries);
238 Q_D(QBarSeries);
239 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
239 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
240 }
240 }
241
241
242 /*!
242 /*!
243 Returns the bar categories of the series.
243 Returns the bar categories of the series.
244 */
244 */
245 QBarCategories QBarSeries::categories() const
245 QBarCategories QBarSeries::categories() const
246 {
246 {
247 Q_D(const QBarSeries);
247 Q_D(const QBarSeries);
248
248
249 QBarCategories categories;
249 QBarCategories categories;
250 int count = d->m_internalModel->categoryCount();
250 int count = d->m_internalModel->categoryCount();
251 for (int i=1; i <= count; i++) {
251 for (int i=1; i <= count; i++) {
252 categories.insert(i, d->m_internalModel->categoryName(i - 1));
252 categories.insert(i, d->m_internalModel->categoryName(i - 1));
253 }
253 }
254 return categories;
254 return categories;
255
255
256 }
256 }
257
257
258 /*!
258 /*!
259 Sets the visibility of labels in series to \a visible
259 Sets the visibility of labels in series to \a visible
260 */
260 */
261 void QBarSeries::setLabelsVisible(bool visible)
261 void QBarSeries::setLabelsVisible(bool visible)
262 {
262 {
263 foreach (QBarSet* s, barSets()) {
263 foreach (QBarSet* s, barSets()) {
264 s->setLabelsVisible(visible);
264 s->setLabelsVisible(visible);
265 }
265 }
266 }
266 }
267
267
268 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
268 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269
269
270 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : QSeriesPrivate(q),
270 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : QSeriesPrivate(q),
271 m_internalModel(new BarChartModel(categories,this)),
271 m_internalModel(new BarChartModel(categories,this)),
272 m_model(0),
272 m_model(0),
273 m_mapCategories(-1),
273 m_mapCategories(-1),
274 m_mapBarBottom(-1),
274 m_mapBarBottom(-1),
275 m_mapBarTop(-1),
275 m_mapBarTop(-1),
276 m_mapFirst(0),
276 m_mapFirst(0),
277 m_mapCount(0),
277 m_mapCount(0),
278 m_mapOrientation(Qt::Vertical)
278 m_mapOrientation(Qt::Vertical)
279 {
279 {
280 }
280 }
281
281
282 QBarSet* QBarSeriesPrivate::barsetAt(int index)
282 QBarSet* QBarSeriesPrivate::barsetAt(int index)
283 {
283 {
284 return m_internalModel->barsetAt(index);
284 return m_internalModel->barsetAt(index);
285 }
285 }
286
286
287 QString QBarSeriesPrivate::categoryName(int category)
287 QString QBarSeriesPrivate::categoryName(int category)
288 {
288 {
289 return m_internalModel->categoryName(category);
289 return m_internalModel->categoryName(category);
290 }
290 }
291
291
292 void QBarSeriesPrivate::setToolTipEnabled(bool enabled)
292 void QBarSeriesPrivate::setToolTipEnabled(bool enabled)
293 {
293 {
294 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
294 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
295 if (enabled) {
295 if (enabled) {
296 for (int i=0; i<m_internalModel->barsetCount(); i++) {
296 for (int i=0; i<m_internalModel->barsetCount(); i++) {
297 QBarSet *set = m_internalModel->barsetAt(i);
297 QBarSet *set = m_internalModel->barsetAt(i);
298 connect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
298 connect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
299 }
299 }
300 } else {
300 } else {
301 for (int i=0; i<m_internalModel->barsetCount(); i++) {
301 for (int i=0; i<m_internalModel->barsetCount(); i++) {
302 QBarSet *set = m_internalModel->barsetAt(i);
302 QBarSet *set = m_internalModel->barsetAt(i);
303 disconnect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
303 disconnect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
304 }
304 }
305 }
305 }
306 }
306 }
307
307
308 qreal QBarSeriesPrivate::min()
308 qreal QBarSeriesPrivate::min()
309 {
309 {
310 return m_internalModel->min();
310 return m_internalModel->min();
311 }
311 }
312
312
313 qreal QBarSeriesPrivate::max()
313 qreal QBarSeriesPrivate::max()
314 {
314 {
315 return m_internalModel->max();
315 return m_internalModel->max();
316 }
316 }
317
317
318 qreal QBarSeriesPrivate::valueAt(int set, int category)
318 qreal QBarSeriesPrivate::valueAt(int set, int category)
319 {
319 {
320 return m_internalModel->valueAt(set, category);
320 return m_internalModel->valueAt(set, category);
321 }
321 }
322
322
323 qreal QBarSeriesPrivate::percentageAt(int set, int category)
323 qreal QBarSeriesPrivate::percentageAt(int set, int category)
324 {
324 {
325 return m_internalModel->percentageAt(set, category);
325 return m_internalModel->percentageAt(set, category);
326 }
326 }
327
327
328 qreal QBarSeriesPrivate::categorySum(int category)
328 qreal QBarSeriesPrivate::categorySum(int category)
329 {
329 {
330 return m_internalModel->categorySum(category);
330 return m_internalModel->categorySum(category);
331 }
331 }
332
332
333 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
333 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
334 {
334 {
335 return m_internalModel->absoluteCategorySum(category);
335 return m_internalModel->absoluteCategorySum(category);
336 }
336 }
337
337
338 qreal QBarSeriesPrivate::maxCategorySum()
338 qreal QBarSeriesPrivate::maxCategorySum()
339 {
339 {
340 return m_internalModel->maxCategorySum();
340 return m_internalModel->maxCategorySum();
341 }
341 }
342
342
343 BarChartModel& QBarSeriesPrivate::modelInternal()
343 BarChartModel& QBarSeriesPrivate::modelInternal()
344 {
344 {
345 return *m_internalModel;
345 return *m_internalModel;
346 }
346 }
347
347
348 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
348 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
349 {
349 {
350 // disconnect signals from old model
350 // disconnect signals from old model
351 if(m_model)
351 if(m_model)
352 {
352 {
353 disconnect(m_model, 0, this, 0);
353 disconnect(m_model, 0, this, 0);
354 m_mapCategories = -1;
354 m_mapCategories = -1;
355 m_mapBarBottom = -1;
355 m_mapBarBottom = -1;
356 m_mapBarTop = -1;
356 m_mapBarTop = -1;
357 m_mapFirst = 0;
357 m_mapFirst = 0;
358 m_mapCount = 0;
358 m_mapCount = 0;
359 m_mapOrientation = Qt::Vertical;
359 m_mapOrientation = Qt::Vertical;
360 }
360 }
361
361
362 // set new model
362 // set new model
363 if(model)
363 if(model)
364 {
364 {
365 m_model = model;
365 m_model = model;
366 return true;
366 return true;
367 }
367 }
368 else
368 else
369 {
369 {
370 m_model = 0;
370 m_model = 0;
371 return false;
371 return false;
372 }
372 }
373 }
373 }
374
374
375 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
375 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
376 {
376 {
377 Q_Q(QBarSeries);
377 Q_Q(QBarSeries);
378
378
379 if (m_model == 0)
379 if (m_model == 0)
380 return;
380 return;
381
381
382 m_mapCategories = categories;
382 m_mapCategories = categories;
383 m_mapBarBottom = bottomBoundry;
383 m_mapBarBottom = bottomBoundry;
384 m_mapBarTop = topBoundry;
384 m_mapBarTop = topBoundry;
385 // m_mapFirst = 1;
385 // m_mapFirst = 1;
386 m_mapOrientation = orientation;
386 m_mapOrientation = orientation;
387
387
388 // connect the signals
388 // connect the signals
389 if (m_mapOrientation == Qt::Vertical) {
389 if (m_mapOrientation == Qt::Vertical) {
390 m_mapCount = m_model->rowCount() - m_mapFirst;
390 m_mapCount = m_model->rowCount() - m_mapFirst;
391 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
391 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
392 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
392 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
393 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)),
393 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)),
394 this, SLOT(modelDataAdded(QModelIndex,int,int)));
394 this, SLOT(modelDataAdded(QModelIndex,int,int)));
395 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
395 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
396 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
396 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
397 } else {
397 } else {
398 m_mapCount = m_model->columnCount() - m_mapFirst;
398 m_mapCount = m_model->columnCount() - m_mapFirst;
399 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
399 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
400 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
400 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
401 connect(m_model,SIGNAL(columnsInserted(QModelIndex,int,int)),
401 connect(m_model,SIGNAL(columnsInserted(QModelIndex,int,int)),
402 this, SLOT(modelDataAdded(QModelIndex,int,int)));
402 this, SLOT(modelDataAdded(QModelIndex,int,int)));
403 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
403 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
404 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
404 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
405 }
405 }
406
406
407 // create the initial bars
407 // create the initial bars
408 delete m_internalModel;
408 delete m_internalModel;
409 if (m_mapOrientation == Qt::Vertical) {
409 if (m_mapOrientation == Qt::Vertical) {
410 QStringList categories;
410 QStringList categories;
411 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
411 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
412 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
412 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
413 m_internalModel = new BarChartModel(categories, this);
413 m_internalModel = new BarChartModel(categories, this);
414
414
415 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
415 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
416 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
416 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
417 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
417 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
418 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
418 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
419 q->appendBarSet(barSet);
419 q->appendBarSet(barSet);
420 }
420 }
421 } else {
421 } else {
422 QStringList categories;
422 QStringList categories;
423 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
423 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
424 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
424 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
425 m_internalModel = new BarChartModel(categories, this);
425 m_internalModel = new BarChartModel(categories, this);
426
426
427 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
427 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
428 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
428 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
429 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
429 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
430 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
430 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
431 q->appendBarSet(barSet);
431 q->appendBarSet(barSet);
432 }
432 }
433 }
433 }
434 }
434 }
435
435
436 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
436 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
437 {
437 {
438 Q_UNUSED(bottomRight)
438 Q_UNUSED(bottomRight)
439
439
440 if (m_mapOrientation == Qt::Vertical)
440 if (m_mapOrientation == Qt::Vertical)
441 {
441 {
442 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
442 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
443 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
443 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
444 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
444 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
445 }
445 }
446 else
446 else
447 {
447 {
448 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
448 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
449 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
449 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
450 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
450 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
451 }
451 }
452 }
452 }
453
453
454 void QBarSeriesPrivate::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
454 void QBarSeriesPrivate::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
455 {
455 {
456 Q_Q(QBarSeries);
456 Q_Q(QBarSeries);
457
457
458 if (m_mapOrientation == Qt::Vertical) {
458 if (m_mapOrientation == Qt::Vertical) {
459 q->insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
459 q->insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
460 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
460 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
461 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
461 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
462 }
462 }
463 } else {
463 } else {
464 q->insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
464 q->insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
465 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
465 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
466 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
466 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
467 }
467 }
468 }
468 }
469 emit restructuredBars();
469 emit restructuredBars();
470 }
470 }
471
471
472 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
472 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
473 {
473 {
474 Q_Q(QBarSeries);
474 Q_Q(QBarSeries);
475 Q_UNUSED(parent)
475 Q_UNUSED(parent)
476 Q_UNUSED(end)
476 Q_UNUSED(end)
477
477
478 q->removeCategory(start - m_mapFirst);
478 q->removeCategory(start - m_mapFirst);
479 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
479 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
480 {
480 {
481 barsetAt(i)->removeValue(start - m_mapFirst);
481 barsetAt(i)->removeValue(start - m_mapFirst);
482 }
482 }
483 emit restructuredBars();
483 emit restructuredBars();
484 }
484 }
485
485
486 void QBarSeriesPrivate::barsetChanged()
486 void QBarSeriesPrivate::barsetChanged()
487 {
487 {
488 emit updatedBars();
488 emit updatedBars();
489 }
489 }
490
490
491 void QBarSeriesPrivate::scaleDomain(Domain& domain)
491 void QBarSeriesPrivate::scaleDomain(Domain& domain)
492 {
492 {
493 qreal minX(domain.minX());
493 qreal minX(domain.minX());
494 qreal minY(domain.minY());
494 qreal minY(domain.minY());
495 qreal maxX(domain.maxX());
495 qreal maxX(domain.maxX());
496 qreal maxY(domain.maxY());
496 qreal maxY(domain.maxY());
497 int tickXCount(domain.tickXCount());
497 int tickXCount(domain.tickXCount());
498 int tickYCount(domain.tickYCount());
498 int tickYCount(domain.tickYCount());
499
499
500 qreal x = m_internalModel->categoryCount();
500 qreal x = m_internalModel->categoryCount();
501 qreal y = max();
501 qreal y = max();
502 minX = qMin(minX, x);
502 minX = qMin(minX, x);
503 minY = qMin(minY, y);
503 minY = qMin(minY, y);
504 maxX = qMax(maxX, x);
504 maxX = qMax(maxX, x);
505 maxY = qMax(maxY, y);
505 maxY = qMax(maxY, y);
506 tickXCount = x+1;
506 tickXCount = x+1;
507
507
508 domain.setRangeX(minX,maxX,tickXCount);
508 domain.setRangeX(minX,maxX,tickXCount);
509 domain.setRangeY(minY,maxY,tickYCount);
509 domain.setRangeY(minY,maxY,tickYCount);
510 }
510 }
511
511
512 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
512 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
513 {
513 {
514 Q_Q(QBarSeries);
514 Q_Q(QBarSeries);
515
515
516 BarChartItem* bar = new BarChartItem(q,presenter);
516 BarChartItem* bar = new BarChartItem(q,presenter);
517 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
517 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
518 presenter->animator()->addAnimation(bar);
518 presenter->animator()->addAnimation(bar);
519 }
519 }
520 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
520 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
521 return bar;
521 return bar;
522
522
523 }
523 }
524
524
525 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
525 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
526 {
526 {
527 Q_Q(QBarSeries);
527 Q_Q(QBarSeries);
528 QList<LegendMarker*> markers;
528 QList<LegendMarker*> markers;
529 foreach(QBarSet* set, q->barSets()) {
529 foreach(QBarSet* set, q->barSets()) {
530 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
530 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
531 markers << marker;
531 markers << marker;
532 }
532 }
533
533
534 return markers;
534 return markers;
535 }
535 }
536
536
537 #include "moc_qbarseries.cpp"
537 #include "moc_qbarseries.cpp"
538 #include "moc_qbarseries_p.cpp"
538 #include "moc_qbarseries_p.cpp"
539
539
540 QTCOMMERCIALCHART_END_NAMESPACE
540 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,108 +1,108
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpercentbarseries.h"
21 #include "qpercentbarseries.h"
22 #include "qpercentbarseries_p.h"
22 #include "qpercentbarseries_p.h"
23 #include "percentbarchartitem_p.h"
23 #include "percentbarchartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 /*!
31 /*!
32 \class QPercentBarSeries
32 \class QPercentBarSeries
33 \brief part of QtCommercial chart API.
33 \brief part of QtCommercial chart API.
34
34
35 QPercentBarSeries represents a series of data shown as bars. Each bar of QBarSet is shown as percentage
35 QPercentBarSeries represents a series of data shown as bars. Each bar of QBarSet is shown as percentage
36 of all bars in category. One QPercentBarSeries can contain multible QBarSet data sets.
36 of all bars in category. One QPercentBarSeries can contain multiple QBarSet data sets.
37 QBarSeries groups the data from sets to categories, which are defined by QStringList.
37 QBarSeries groups the data from sets to categories, which are defined by QStringList.
38
38
39 \mainclass
39 \mainclass
40
40
41 \sa QBarSet, QStackedBarSeries, QBarSeries
41 \sa QBarSet, QStackedBarSeries, QBarSeries
42 */
42 */
43
43
44 /*!
44 /*!
45 \fn virtual QSeriesType QPercentBarSeries::type() const
45 \fn virtual QSeriesType QPercentBarSeries::type() const
46 \brief Returns type of series.
46 \brief Returns type of series.
47 \sa QSeries, QSeriesType
47 \sa QSeries, QSeriesType
48 */
48 */
49
49
50 /*!
50 /*!
51 Constructs empty QPercentBarSeries. Parameter \a categories defines the categories for chart.
51 Constructs empty QPercentBarSeries. Parameter \a categories defines the categories for chart.
52 QPercentBarSeries is QObject which is a child of a \a parent.
52 QPercentBarSeries is QObject which is a child of a \a parent.
53 */
53 */
54 QPercentBarSeries::QPercentBarSeries(QBarCategories categories, QObject *parent)
54 QPercentBarSeries::QPercentBarSeries(QBarCategories categories, QObject *parent)
55 : QBarSeries(*new QPercentBarSeriesPrivate(categories,this), parent)
55 : QBarSeries(*new QPercentBarSeriesPrivate(categories,this), parent)
56 {
56 {
57 }
57 }
58
58
59 QSeries::QSeriesType QPercentBarSeries::type() const
59 QSeries::QSeriesType QPercentBarSeries::type() const
60 {
60 {
61 return QSeries::SeriesTypePercentBar;
61 return QSeries::SeriesTypePercentBar;
62 }
62 }
63
63
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65
65
66 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QBarCategories categories, QPercentBarSeries *q) : QBarSeriesPrivate(categories,q)
66 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QBarCategories categories, QPercentBarSeries *q) : QBarSeriesPrivate(categories,q)
67 {
67 {
68
68
69 }
69 }
70
70
71 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
71 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
72 {
72 {
73 Q_Q(QPercentBarSeries);
73 Q_Q(QPercentBarSeries);
74 qreal minX(domain.minX());
74 qreal minX(domain.minX());
75 qreal minY(domain.minY());
75 qreal minY(domain.minY());
76 qreal maxX(domain.maxX());
76 qreal maxX(domain.maxX());
77 qreal maxY(domain.maxY());
77 qreal maxY(domain.maxY());
78 int tickXCount(domain.tickXCount());
78 int tickXCount(domain.tickXCount());
79 int tickYCount(domain.tickYCount());
79 int tickYCount(domain.tickYCount());
80
80
81 qreal x = q->categoryCount();
81 qreal x = q->categoryCount();
82 minX = qMin(minX, x);
82 minX = qMin(minX, x);
83 maxX = qMax(maxX, x);
83 maxX = qMax(maxX, x);
84 minY = 0;
84 minY = 0;
85 maxY = 100;
85 maxY = 100;
86 tickXCount = x+1;
86 tickXCount = x+1;
87
87
88 domain.setRangeX(minX,maxX,tickXCount);
88 domain.setRangeX(minX,maxX,tickXCount);
89 domain.setRangeY(minY,maxY,tickYCount);
89 domain.setRangeY(minY,maxY,tickYCount);
90 }
90 }
91
91
92
92
93 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
93 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
94 {
94 {
95 Q_Q(QPercentBarSeries);
95 Q_Q(QPercentBarSeries);
96
96
97 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
97 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
99 presenter->animator()->addAnimation(bar);
99 presenter->animator()->addAnimation(bar);
100 }
100 }
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
102 return bar;
102 return bar;
103 }
103 }
104
104
105 #include "moc_qpercentbarseries.cpp"
105 #include "moc_qpercentbarseries.cpp"
106
106
107 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
108
108
@@ -1,108 +1,108
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qstackedbarseries.h"
21 #include "qstackedbarseries.h"
22 #include "qstackedbarseries_p.h"
22 #include "qstackedbarseries_p.h"
23 #include "stackedbarchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
24 #include "barchartmodel_p.h"
24 #include "barchartmodel_p.h"
25 #include "chartdataset_p.h"
25 #include "chartdataset_p.h"
26 #include "charttheme_p.h"
26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 /*!
31 /*!
32 \class QStackedBarSeries
32 \class QStackedBarSeries
33 \brief part of QtCommercial chart API.
33 \brief part of QtCommercial chart API.
34
34
35 QStackedBarSeries represents a series of data shown as bars. All bars in same category are
35 QStackedBarSeries represents a series of data shown as bars. All bars in same category are
36 stacked on top of each other. One QStackedBarSeries can contain multible QBarSet data sets.
36 stacked on top of each other. One QStackedBarSeries can contain multiple QBarSet data sets.
37 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
37 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
38
38
39 \mainclass
39 \mainclass
40
40
41 \sa QBarSet, QPercentBarSeries, QBarSeries
41 \sa QBarSet, QPercentBarSeries, QBarSeries
42 */
42 */
43
43
44 /*!
44 /*!
45 \fn virtual QSeriesType QStackedBarSeries::type() const
45 \fn virtual QSeriesType QStackedBarSeries::type() const
46 \brief Returns type of series.
46 \brief Returns type of series.
47 \sa QSeries, QSeriesType
47 \sa QSeries, QSeriesType
48 */
48 */
49
49
50 /*!
50 /*!
51 Constructs empty QStackedBarSeries. Parameter \a categories defines the categories for chart.
51 Constructs empty QStackedBarSeries. Parameter \a categories defines the categories for chart.
52 QStackedBarSeries is QObject which is a child of a \a parent.
52 QStackedBarSeries is QObject which is a child of a \a parent.
53 */
53 */
54 QStackedBarSeries::QStackedBarSeries(QBarCategories categories, QObject *parent)
54 QStackedBarSeries::QStackedBarSeries(QBarCategories categories, QObject *parent)
55 : QBarSeries(*new QStackedBarSeriesPrivate(categories,this), parent)
55 : QBarSeries(*new QStackedBarSeriesPrivate(categories,this), parent)
56 {
56 {
57 }
57 }
58
58
59 QSeries::QSeriesType QStackedBarSeries::type() const
59 QSeries::QSeriesType QStackedBarSeries::type() const
60 {
60 {
61 return QSeries::SeriesTypeStackedBar;
61 return QSeries::SeriesTypeStackedBar;
62 }
62 }
63
63
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65
65
66 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QBarCategories categories, QStackedBarSeries *q) : QBarSeriesPrivate(categories,q)
66 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QBarCategories categories, QStackedBarSeries *q) : QBarSeriesPrivate(categories,q)
67 {
67 {
68
68
69 }
69 }
70
70
71 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
71 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
72 {
72 {
73 qreal minX(domain.minX());
73 qreal minX(domain.minX());
74 qreal minY(domain.minY());
74 qreal minY(domain.minY());
75 qreal maxX(domain.maxX());
75 qreal maxX(domain.maxX());
76 qreal maxY(domain.maxY());
76 qreal maxY(domain.maxY());
77 int tickXCount(domain.tickXCount());
77 int tickXCount(domain.tickXCount());
78 int tickYCount(domain.tickYCount());
78 int tickYCount(domain.tickYCount());
79
79
80 qreal x = m_internalModel->categoryCount();
80 qreal x = m_internalModel->categoryCount();
81 qreal y = maxCategorySum();
81 qreal y = maxCategorySum();
82 minX = qMin(minX, x);
82 minX = qMin(minX, x);
83 minY = qMin(minY, y);
83 minY = qMin(minY, y);
84 maxX = qMax(maxX, x);
84 maxX = qMax(maxX, x);
85 maxY = qMax(maxY, y);
85 maxY = qMax(maxY, y);
86 tickXCount = x+1;
86 tickXCount = x+1;
87
87
88 domain.setRangeX(minX,maxX,tickXCount);
88 domain.setRangeX(minX,maxX,tickXCount);
89 domain.setRangeY(minY,maxY,tickYCount);
89 domain.setRangeY(minY,maxY,tickYCount);
90 }
90 }
91
91
92
92
93 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
93 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
94 {
94 {
95 Q_Q(QStackedBarSeries);
95 Q_Q(QStackedBarSeries);
96
96
97 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
97 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
99 presenter->animator()->addAnimation(bar);
99 presenter->animator()->addAnimation(bar);
100 }
100 }
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
102 return bar;
102 return bar;
103 }
103 }
104
104
105 #include "moc_qstackedbarseries.cpp"
105 #include "moc_qstackedbarseries.cpp"
106
106
107 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
108
108
@@ -1,255 +1,252
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartdataset_p.h"
21 #include "chartdataset_p.h"
22 #include "qchartaxis.h"
22 #include "qchartaxis.h"
23 #include "qchartaxis_p.h"
23 #include "qchartaxis_p.h"
24 #include "qseries_p.h"
24 #include "qseries_p.h"
25 #include "qbarseries.h"
25 #include "qbarseries.h"
26 #include "qstackedbarseries.h"
26 #include "qstackedbarseries.h"
27 #include "qpercentbarseries.h"
27 #include "qpercentbarseries.h"
28 #include "qpieseries.h"
28 #include "qpieseries.h"
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
32 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
33 m_axisX(new QChartAxis(this)),
33 m_axisX(new QChartAxis(this)),
34 m_axisY(new QChartAxis(this)),
34 m_axisY(new QChartAxis(this)),
35 m_domainIndex(0),
35 m_domainIndex(0),
36 m_axisXInitialized(false)
36 m_axisXInitialized(false)
37 {
37 {
38 }
38 }
39
39
40 ChartDataSet::~ChartDataSet()
40 ChartDataSet::~ChartDataSet()
41 {
41 {
42 }
42 }
43
43
44 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
44 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
45 {
45 {
46 if(axisY==0) axisY = m_axisY;
46 if(axisY==0) axisY = m_axisY;
47
47
48 QChartAxis* axis = m_seriesAxisMap.value(series);
48 QChartAxis* axis = m_seriesAxisMap.value(series);
49
49
50 if(axis) {
50 if(axis) {
51 qWarning() << "Can not add series. Series already on the chart";
51 qWarning() << "Can not add series. Series already on the chart";
52 return;
52 return;
53 }
53 }
54
54
55 if(!series->parent()){
55 series->setParent(this); // take ownership
56 series->setParent(this); // take ownership
56 axisY->setParent(this); // take ownership
57 };
58
59 if(!axisY->parent()){
60 axisY->setParent(this); // take ownership
61 }
62
57
63 Domain* domain = m_axisDomainMap.value(axisY);
58 Domain* domain = m_axisDomainMap.value(axisY);
64
59
65 if(!domain) {
60 if(!domain) {
66 domain = new Domain(axisY);
61 domain = new Domain(axisY);
67 QObject::connect(axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
62 QObject::connect(axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
68 QObject::connect(axisX()->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
63 QObject::connect(axisX()->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
69 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
64 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
70 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),axisX()->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
65 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),axisX()->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
71 //initialize
66 //initialize
72 m_axisDomainMap.insert(axisY,domain);
67 m_axisDomainMap.insert(axisY,domain);
73 emit axisAdded(axisY,domain);
68 emit axisAdded(axisY,domain);
74 }
69 }
75
70
76 if(!m_axisXInitialized){
71 if(!m_axisXInitialized){
77 emit axisAdded(axisX(),domain);
72 emit axisAdded(axisX(),domain);
78 m_axisXInitialized=true;
73 m_axisXInitialized=true;
79 }
74 }
80
75
81 series->d_ptr->scaleDomain(*domain);
76 series->d_ptr->scaleDomain(*domain);
82
77
83 if(series->type() == QSeries::SeriesTypeBar || series->type() == QSeries::SeriesTypeStackedBar || series->type() == QSeries::SeriesTypePercentBar)
78 if(series->type() == QSeries::SeriesTypeBar || series->type() == QSeries::SeriesTypeStackedBar || series->type() == QSeries::SeriesTypePercentBar)
84 {
79 {
85 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
80 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
86 setupCategories(barSeries);
81 setupCategories(barSeries);
87 }
82 }
88
83
89 if (series->type()== QSeries::SeriesTypePie && m_seriesAxisMap.count()==0)
84 if (series->type()== QSeries::SeriesTypePie && m_seriesAxisMap.count()==0)
90 {
85 {
91 axisX()->hide();
86 axisX()->hide();
92 this->axisY()->hide();
87 this->axisY()->hide();
93 }
88 }
94
89
95 m_seriesAxisMap.insert(series,axisY);
90 m_seriesAxisMap.insert(series,axisY);
96
91
97 QMapIterator<int, QSeries*> i(m_indexSeriesMap);
92 QMapIterator<int, QSeries*> i(m_indexSeriesMap);
98
93
99 int key=0;
94 int key=0;
100 while (i.hasNext()) {
95 while (i.hasNext()) {
101 i.next();
96 i.next();
102 if(i.key()!=key) {
97 if(i.key()!=key) {
103 break;
98 break;
104 }
99 }
105 key++;
100 key++;
106 }
101 }
107
102
108 m_indexSeriesMap.insert(key,series);
103 m_indexSeriesMap.insert(key,series);
109
104
110 emit seriesAdded(series,domain);
105 emit seriesAdded(series,domain);
111
106
112 }
107 }
113
108
114 void ChartDataSet::removeSeries(QSeries* series)
109 QChartAxis* ChartDataSet::removeSeries(QSeries* series)
115 {
110 {
116
117 QChartAxis* axis = m_seriesAxisMap.value(series);
111 QChartAxis* axis = m_seriesAxisMap.value(series);
118
112
119 if(!axis){
113 if(!axis){
120 qWarning()<<"Can not remove series. Series not found on the chart.";
114 qWarning()<<"Can not remove series. Series not found on the chart.";
121 return;
115 return 0;
122 }
116 }
117
123 emit seriesRemoved(series);
118 emit seriesRemoved(series);
119
124 m_seriesAxisMap.remove(series);
120 m_seriesAxisMap.remove(series);
125 int key = seriesIndex(series);
121 int key = seriesIndex(series);
126 Q_ASSERT(key!=-1);
122 Q_ASSERT(key!=-1);
127
123
128 m_indexSeriesMap.remove(key);
124 m_indexSeriesMap.remove(key);
129
125 series->setParent(0);
130 if(series->parent()==this){
131 delete series;
132 series=0;
133 }
134
126
135 QList<QChartAxis*> axes = m_seriesAxisMap.values();
127 QList<QChartAxis*> axes = m_seriesAxisMap.values();
136
128
137 int i = axes.indexOf(axis);
129 int i = axes.indexOf(axis);
138
130
139 if(i==-1){
131 if(i==-1){
140 Domain* domain = m_axisDomainMap.take(axis);
132 Domain* domain = m_axisDomainMap.take(axis);
141 emit axisRemoved(axis);
133 emit axisRemoved(axis);
142 if(axis!=axisY()){
134 if(axis!=axisY()){
143 if(axis->parent()==this){
135 axis->setParent(0);
144 delete axis;
145 axis=0;
146 }
147 }
136 }
148 delete domain;
137 delete domain;
149 }
138 }
150
139
151 if(m_seriesAxisMap.values().size()==0)
140 if(m_seriesAxisMap.values().size()==0)
152 {
141 {
153 m_axisXInitialized=false;
142 m_axisXInitialized=false;
154 emit axisRemoved(axisX());
143 emit axisRemoved(axisX());
155 }
144 }
145
146 return axis;
156 }
147 }
157
148
158 void ChartDataSet::removeAllSeries()
149 void ChartDataSet::removeAllSeries()
159 {
150 {
160
161 QList<QSeries*> series = m_seriesAxisMap.keys();
151 QList<QSeries*> series = m_seriesAxisMap.keys();
162
152 QList<QChartAxis*> axes;
163 foreach(QSeries* s , series) {
153 foreach(QSeries* s , series) {
164 removeSeries(s);
154 QChartAxis* axis = removeSeries(s);
155 if(axis==axisY()) continue;
156 int i = axes.indexOf(axis);
157 if(i==-1){
158 axes<<axis;
159 }
165 }
160 }
166
161
167 Q_ASSERT(m_seriesAxisMap.count()==0);
162 Q_ASSERT(m_seriesAxisMap.count()==0);
168 Q_ASSERT(m_axisDomainMap.count()==0);
163 Q_ASSERT(m_axisDomainMap.count()==0);
169
164
165 qDeleteAll(series);
166 qDeleteAll(axes);
170 }
167 }
171
168
172 void ChartDataSet::setupCategories(QBarSeries* series)
169 void ChartDataSet::setupCategories(QBarSeries* series)
173 {
170 {
174 QChartAxisCategories* categories = axisX()->categories();
171 QChartAxisCategories* categories = axisX()->categories();
175 categories->clear();
172 categories->clear();
176 categories->insert(series->categories());
173 categories->insert(series->categories());
177 }
174 }
178
175
179 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
176 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
180 {
177 {
181 QMapIterator<QChartAxis*, Domain*> i(m_axisDomainMap);
178 QMapIterator<QChartAxis*, Domain*> i(m_axisDomainMap);
182 while (i.hasNext()) {
179 while (i.hasNext()) {
183 i.next();
180 i.next();
184 i.value()->zoomIn(rect,size);
181 i.value()->zoomIn(rect,size);
185 }
182 }
186 }
183 }
187
184
188 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
185 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
189 {
186 {
190 QMapIterator<QChartAxis*, Domain*> i(m_axisDomainMap);
187 QMapIterator<QChartAxis*, Domain*> i(m_axisDomainMap);
191 while (i.hasNext()) {
188 while (i.hasNext()) {
192 i.next();
189 i.next();
193 i.value()->zoomOut(rect,size);
190 i.value()->zoomOut(rect,size);
194 }
191 }
195 }
192 }
196
193
197 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
194 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
198 {
195 {
199 int count=0;
196 int count=0;
200 QMapIterator<QSeries*, QChartAxis*> i(m_seriesAxisMap);
197 QMapIterator<QSeries*, QChartAxis*> i(m_seriesAxisMap);
201 while (i.hasNext()) {
198 while (i.hasNext()) {
202 i.next();
199 i.next();
203 if(i.key()->type()==type) count++;
200 if(i.key()->type()==type) count++;
204 }
201 }
205 return count;
202 return count;
206 }
203 }
207
204
208 int ChartDataSet::seriesIndex(QSeries *series)
205 int ChartDataSet::seriesIndex(QSeries *series)
209 {
206 {
210 QMapIterator<int, QSeries*> i(m_indexSeriesMap);
207 QMapIterator<int, QSeries*> i(m_indexSeriesMap);
211 while (i.hasNext()) {
208 while (i.hasNext()) {
212 i.next();
209 i.next();
213 if (i.value() == series)
210 if (i.value() == series)
214 return i.key();
211 return i.key();
215 }
212 }
216 return -1;
213 return -1;
217 }
214 }
218
215
219 QChartAxis* ChartDataSet::axisY(QSeries* series) const
216 QChartAxis* ChartDataSet::axisY(QSeries* series) const
220 {
217 {
221 if(series == 0) return m_axisY;
218 if(series == 0) return m_axisY;
222 return m_seriesAxisMap.value(series);
219 return m_seriesAxisMap.value(series);
223 }
220 }
224
221
225 Domain* ChartDataSet::domain(QSeries* series) const
222 Domain* ChartDataSet::domain(QSeries* series) const
226 {
223 {
227 QChartAxis* axis = m_seriesAxisMap.value(series);
224 QChartAxis* axis = m_seriesAxisMap.value(series);
228 if(axis){
225 if(axis){
229 return m_axisDomainMap.value(axis);
226 return m_axisDomainMap.value(axis);
230 }else
227 }else
231 return 0;
228 return 0;
232 }
229 }
233
230
234 Domain* ChartDataSet::domain(QChartAxis* axis) const
231 Domain* ChartDataSet::domain(QChartAxis* axis) const
235 {
232 {
236 if(!axis || axis==axisX()) {
233 if(!axis || axis==axisX()) {
237 return m_axisDomainMap.value(axisY());
234 return m_axisDomainMap.value(axisY());
238 }
235 }
239 else {
236 else {
240 return m_axisDomainMap.value(axis);
237 return m_axisDomainMap.value(axis);
241 }
238 }
242 }
239 }
243
240
244 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
241 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
245 {
242 {
246 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
243 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
247 while (i.hasNext()) {
244 while (i.hasNext()) {
248 i.next();
245 i.next();
249 i.value()->move(dx,dy,size);
246 i.value()->move(dx,dy,size);
250 }
247 }
251 }
248 }
252
249
253 #include "moc_chartdataset_p.cpp"
250 #include "moc_chartdataset_p.cpp"
254
251
255 QTCOMMERCIALCHART_END_NAMESPACE
252 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,90
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTDATASET_P_H
30 #ifndef CHARTDATASET_P_H
31 #define CHARTDATASET_P_H
31 #define CHARTDATASET_P_H
32
32
33 #include "qseries.h"
33 #include "qseries.h"
34 #include "domain_p.h"
34 #include "domain_p.h"
35 #include <QVector>
35 #include <QVector>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class QChartAxis;
39 class QChartAxis;
40 class QBarSeries;
40 class QBarSeries;
41
41
42 class ChartDataSet : public QObject
42 class ChartDataSet : public QObject
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 public:
45 public:
46 ChartDataSet(QObject* parent=0);
46 ChartDataSet(QObject* parent=0);
47 virtual ~ChartDataSet();
47 virtual ~ChartDataSet();
48
48
49 void addSeries(QSeries* series,QChartAxis *axisY = 0);
49 void addSeries(QSeries* series,QChartAxis *axisY = 0);
50 void removeSeries(QSeries* series);
50 QChartAxis* removeSeries(QSeries* series);
51 void removeAllSeries();
51 void removeAllSeries();
52
52
53 void zoomInDomain(const QRectF& rect, const QSizeF& size);
53 void zoomInDomain(const QRectF& rect, const QSizeF& size);
54 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
54 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
55 void scrollDomain(int dx,int dy,const QSizeF& size);
55 void scrollDomain(int dx,int dy,const QSizeF& size);
56
56
57 int seriesCount(QSeries::QSeriesType type);
57 int seriesCount(QSeries::QSeriesType type);
58 int seriesIndex(QSeries *series);
58 int seriesIndex(QSeries *series);
59
59
60 Domain* domain(QSeries* series) const;
60 Domain* domain(QSeries* series) const;
61 Domain* domain(QChartAxis* axis) const;
61 Domain* domain(QChartAxis* axis) const;
62
62
63 QChartAxis* axisX() const { return m_axisX; }
63 QChartAxis* axisX() const { return m_axisX; }
64 QChartAxis* axisY(QSeries* series = 0) const;
64 QChartAxis* axisY(QSeries* series = 0) const;
65
65
66 Q_SIGNALS:
66 Q_SIGNALS:
67 void seriesAdded(QSeries* series,Domain* domain);
67 void seriesAdded(QSeries* series,Domain* domain);
68 void seriesRemoved(QSeries* series);
68 void seriesRemoved(QSeries* series);
69 void axisAdded(QChartAxis* axis,Domain* domain);
69 void axisAdded(QChartAxis* axis,Domain* domain);
70 void axisRemoved(QChartAxis* axis);
70 void axisRemoved(QChartAxis* axis);
71
71
72 private:
72 private:
73 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
73 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
74 void calculateDomain(QSeries* series,Domain* domain);
74 void calculateDomain(QSeries* series,Domain* domain);
75 void setupCategories(QBarSeries* series);
75 void setupCategories(QBarSeries* series);
76
76
77 private:
77 private:
78 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
78 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
79 QMap<QChartAxis*, Domain*> m_axisDomainMap;
79 QMap<QChartAxis*, Domain*> m_axisDomainMap;
80 QMap<int,QSeries*> m_indexSeriesMap;
80 QMap<int,QSeries*> m_indexSeriesMap;
81 QChartAxis* m_axisX;
81 QChartAxis* m_axisX;
82 QChartAxis* m_axisY;
82 QChartAxis* m_axisY;
83
83
84 int m_domainIndex;
84 int m_domainIndex;
85 bool m_axisXInitialized;
85 bool m_axisXInitialized;
86 };
86 };
87
87
88 QTCOMMERCIALCHART_END_NAMESPACE
88 QTCOMMERCIALCHART_END_NAMESPACE
89
89
90 #endif /* CHARTENGINE_P_H_ */
90 #endif /* CHARTENGINE_P_H_ */
@@ -1,398 +1,398
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "charttheme_p.h"
21 #include "charttheme_p.h"
22 #include "qchart.h"
22 #include "qchart.h"
23 #include "qchartview.h"
23 #include "qchartview.h"
24 #include "qlegend.h"
24 #include "qlegend.h"
25 #include "qchartaxis.h"
25 #include "qchartaxis.h"
26 #include <QTime>
26 #include <QTime>
27
27
28 //series
28 //series
29 #include "qbarset.h"
29 #include "qbarset.h"
30 #include "qbarseries.h"
30 #include "qbarseries.h"
31 #include "qstackedbarseries.h"
31 #include "qstackedbarseries.h"
32 #include "qpercentbarseries.h"
32 #include "qpercentbarseries.h"
33 #include "qlineseries.h"
33 #include "qlineseries.h"
34 #include "qareaseries.h"
34 #include "qareaseries.h"
35 #include "qscatterseries.h"
35 #include "qscatterseries.h"
36 #include "qpieseries.h"
36 #include "qpieseries.h"
37 #include "qpieslice.h"
37 #include "qpieslice.h"
38 #include "qsplineseries.h"
38 #include "qsplineseries.h"
39
39
40 //items
40 //items
41 #include "axis_p.h"
41 #include "axis_p.h"
42 #include "barchartitem_p.h"
42 #include "barchartitem_p.h"
43 #include "stackedbarchartitem_p.h"
43 #include "stackedbarchartitem_p.h"
44 #include "percentbarchartitem_p.h"
44 #include "percentbarchartitem_p.h"
45 #include "linechartitem_p.h"
45 #include "linechartitem_p.h"
46 #include "areachartitem_p.h"
46 #include "areachartitem_p.h"
47 #include "scatterchartitem_p.h"
47 #include "scatterchartitem_p.h"
48 #include "piechartitem_p.h"
48 #include "piechartitem_p.h"
49 #include "splinechartitem_p.h"
49 #include "splinechartitem_p.h"
50
50
51 //themes
51 //themes
52 #include "chartthemesystem_p.h"
52 #include "chartthemesystem_p.h"
53 #include "chartthemelight_p.h"
53 #include "chartthemelight_p.h"
54 #include "chartthemebluecerulean_p.h"
54 #include "chartthemebluecerulean_p.h"
55 #include "chartthemedark_p.h"
55 #include "chartthemedark_p.h"
56 #include "chartthemebrownsand_p.h"
56 #include "chartthemebrownsand_p.h"
57 #include "chartthemebluencs_p.h"
57 #include "chartthemebluencs_p.h"
58 #include "chartthemehighcontrast_p.h"
58 #include "chartthemehighcontrast_p.h"
59 #include "chartthemeblueicy_p.h"
59 #include "chartthemeblueicy_p.h"
60
60
61 QTCOMMERCIALCHART_BEGIN_NAMESPACE
61 QTCOMMERCIALCHART_BEGIN_NAMESPACE
62
62
63 ChartTheme::ChartTheme(QChart::ChartTheme id) :
63 ChartTheme::ChartTheme(QChart::ChartTheme id) :
64 m_masterFont(QFont("arial", 14)),
64 m_masterFont(QFont("arial", 14)),
65 m_labelFont(QFont("arial", 10)),
65 m_labelFont(QFont("arial", 10)),
66 m_titleBrush(QColor(QRgb(0x000000))),
66 m_titleBrush(QColor(QRgb(0x000000))),
67 m_axisLinePen(QPen(QRgb(0x000000))),
67 m_axisLinePen(QPen(QRgb(0x000000))),
68 m_axisLabelBrush(QColor(QRgb(0x000000))),
68 m_axisLabelBrush(QColor(QRgb(0x000000))),
69 m_backgroundShadesPen(Qt::NoPen),
69 m_backgroundShadesPen(Qt::NoPen),
70 m_backgroundShadesBrush(Qt::NoBrush),
70 m_backgroundShadesBrush(Qt::NoBrush),
71 m_backgroundShades(BackgroundShadesNone),
71 m_backgroundShades(BackgroundShadesNone),
72 m_gridLinePen(QPen(QRgb(0x000000))),
72 m_gridLinePen(QPen(QRgb(0x000000))),
73 m_force(false)
73 m_force(false)
74 {
74 {
75 m_id = id;
75 m_id = id;
76 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
76 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
77 }
77 }
78
78
79
79
80 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
80 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
81 {
81 {
82 switch(theme) {
82 switch(theme) {
83 case QChart::ChartThemeLight:
83 case QChart::ChartThemeLight:
84 return new ChartThemeLight();
84 return new ChartThemeLight();
85 case QChart::ChartThemeBlueCerulean:
85 case QChart::ChartThemeBlueCerulean:
86 return new ChartThemeBlueCerulean();
86 return new ChartThemeBlueCerulean();
87 case QChart::ChartThemeDark:
87 case QChart::ChartThemeDark:
88 return new ChartThemeDark();
88 return new ChartThemeDark();
89 case QChart::ChartThemeBrownSand:
89 case QChart::ChartThemeBrownSand:
90 return new ChartThemeBrownSand();
90 return new ChartThemeBrownSand();
91 case QChart::ChartThemeBlueNcs:
91 case QChart::ChartThemeBlueNcs:
92 return new ChartThemeBlueNcs();
92 return new ChartThemeBlueNcs();
93 case QChart::ChartThemeHighContrast:
93 case QChart::ChartThemeHighContrast:
94 return new ChartThemeHighContrast();
94 return new ChartThemeHighContrast();
95 case QChart::ChartThemeBlueIcy:
95 case QChart::ChartThemeBlueIcy:
96 return new ChartThemeBlueIcy();
96 return new ChartThemeBlueIcy();
97 default:
97 default:
98 return new ChartThemeSystem();
98 return new ChartThemeSystem();
99 }
99 }
100 }
100 }
101
101
102 void ChartTheme::decorate(QChart *chart)
102 void ChartTheme::decorate(QChart *chart)
103 {
103 {
104 QBrush brush;
104 QBrush brush;
105
105
106 if(brush == chart->backgroundBrush() || m_force)
106 if(brush == chart->backgroundBrush() || m_force)
107 chart->setBackgroundBrush(m_chartBackgroundGradient);
107 chart->setBackgroundBrush(m_chartBackgroundGradient);
108 chart->setTitleFont(m_masterFont);
108 chart->setTitleFont(m_masterFont);
109 chart->setTitleBrush(m_titleBrush);
109 chart->setTitleBrush(m_titleBrush);
110 }
110 }
111
111
112 void ChartTheme::decorate(QLegend *legend)
112 void ChartTheme::decorate(QLegend *legend)
113 {
113 {
114 QPen pen;
114 QPen pen;
115 QBrush brush;
115 QBrush brush;
116
116
117 if (pen == legend->pen() || m_force){
117 if (pen == legend->pen() || m_force){
118 legend->setPen(Qt::NoPen);
118 legend->setPen(Qt::NoPen);
119 }
119 }
120
120
121
121
122 if (brush == legend->brush() || m_force) {
122 if (brush == legend->brush() || m_force) {
123 legend->setBrush(m_chartBackgroundGradient);
123 legend->setBrush(m_chartBackgroundGradient);
124 }
124 }
125 }
125 }
126
126
127 void ChartTheme::decorate(QAreaSeries *series, int index)
127 void ChartTheme::decorate(QAreaSeries *series, int index)
128 {
128 {
129 QPen pen;
129 QPen pen;
130 QBrush brush;
130 QBrush brush;
131
131
132 if (pen == series->pen() || m_force){
132 if (pen == series->pen() || m_force){
133 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
133 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
134 pen.setWidthF(2);
134 pen.setWidthF(2);
135 series->setPen(pen);
135 series->setPen(pen);
136 }
136 }
137
137
138 if (brush == series->brush() || m_force) {
138 if (brush == series->brush() || m_force) {
139 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
139 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
140 series->setBrush(brush);
140 series->setBrush(brush);
141 }
141 }
142 }
142 }
143
143
144
144
145 void ChartTheme::decorate(QLineSeries *series,int index)
145 void ChartTheme::decorate(QLineSeries *series,int index)
146 {
146 {
147 QPen pen;
147 QPen pen;
148 if(pen == series->pen() || m_force ){
148 if(pen == series->pen() || m_force ){
149 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
149 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
150 pen.setWidthF(2);
150 pen.setWidthF(2);
151 series->setPen(pen);
151 series->setPen(pen);
152 }
152 }
153 }
153 }
154
154
155 void ChartTheme::decorate(QBarSeries *series, int index)
155 void ChartTheme::decorate(QBarSeries *series, int index)
156 {
156 {
157 QBrush brush;
157 QBrush brush;
158 QPen pen;
158 QPen pen;
159 QList<QBarSet *> sets = series->barSets();
159 QList<QBarSet *> sets = series->barSets();
160
160
161 qreal takeAtPos = 0.5;
161 qreal takeAtPos = 0.5;
162 qreal step = 0.2;
162 qreal step = 0.2;
163 if (sets.count() > 1 ) {
163 if (sets.count() > 1 ) {
164 step = 1.0 / (qreal) sets.count();
164 step = 1.0 / (qreal) sets.count();
165 if (sets.count() % m_seriesGradients.count())
165 if (sets.count() % m_seriesGradients.count())
166 step *= m_seriesGradients.count();
166 step *= m_seriesGradients.count();
167 else
167 else
168 step *= (m_seriesGradients.count() - 1);
168 step *= (m_seriesGradients.count() - 1);
169 }
169 }
170
170
171 for (int i(0); i < sets.count(); i++) {
171 for (int i(0); i < sets.count(); i++) {
172 int colorIndex = (index + i) % m_seriesGradients.count();
172 int colorIndex = (index + i) % m_seriesGradients.count();
173 if (i > 0 && i % m_seriesGradients.count() == 0) {
173 if (i > 0 && i % m_seriesGradients.count() == 0) {
174 // There is no dedicated base color for each sets, generate more colors
174 // There is no dedicated base color for each sets, generate more colors
175 takeAtPos += step;
175 takeAtPos += step;
176 if (takeAtPos == 1.0)
176 if (takeAtPos == 1.0)
177 takeAtPos += step;
177 takeAtPos += step;
178 takeAtPos -= (int) takeAtPos;
178 takeAtPos -= (int) takeAtPos;
179 }
179 }
180 if (brush == sets.at(i)->brush() || m_force )
180 if (brush == sets.at(i)->brush() || m_force )
181 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
181 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
182
182
183 // Pick label color from the opposite end of the gradient.
183 // Pick label color from the opposite end of the gradient.
184 // 0.3 as a boundary seems to work well.
184 // 0.3 as a boundary seems to work well.
185 if (takeAtPos < 0.3)
185 if (takeAtPos < 0.3)
186 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
186 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
187 else
187 else
188 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
188 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
189
189
190 if (pen == sets.at(i)->pen() || m_force) {
190 if (pen == sets.at(i)->pen() || m_force) {
191 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
191 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
192 sets.at(i)->setPen(c);
192 sets.at(i)->setPen(c);
193 }
193 }
194 }
194 }
195 }
195 }
196
196
197 void ChartTheme::decorate(QScatterSeries *series, int index)
197 void ChartTheme::decorate(QScatterSeries *series, int index)
198 {
198 {
199 QPen pen;
199 QPen pen;
200 QBrush brush;
200 QBrush brush;
201
201
202 if (pen == series->pen() || m_force) {
202 if (pen == series->pen() || m_force) {
203 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
203 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
204 pen.setWidthF(2);
204 pen.setWidthF(2);
205 series->setPen(pen);
205 series->setPen(pen);
206 }
206 }
207
207
208 if (brush == series->brush() || m_force) {
208 if (brush == series->brush() || m_force) {
209 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
209 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
210 series->setBrush(brush);
210 series->setBrush(brush);
211 }
211 }
212 }
212 }
213
213
214 void ChartTheme::decorate(QPieSeries *series, int index)
214 void ChartTheme::decorate(QPieSeries *series, int index)
215 {
215 {
216
216
217 for (int i(0); i < series->slices().count(); i++) {
217 for (int i(0); i < series->slices().count(); i++) {
218
218
219 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
219 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
220
220
221 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
221 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
224
224
225 QPieSlice *s = series->slices().at(i);
225 QPieSlice *s = series->slices().at(i);
226 PieSliceData data = PieSliceData::data(s);
226 PieSliceData data = PieSliceData::data(s);
227
227
228 if (data.m_slicePen.isThemed() || m_force) {
228 if (data.m_slicePen.isThemed() || m_force) {
229 data.m_slicePen = penColor;
229 data.m_slicePen = penColor;
230 data.m_slicePen.setThemed(true);
230 data.m_slicePen.setThemed(true);
231 }
231 }
232
232
233 if (data.m_sliceBrush.isThemed() || m_force) {
233 if (data.m_sliceBrush.isThemed() || m_force) {
234 data.m_sliceBrush = brushColor;
234 data.m_sliceBrush = brushColor;
235 data.m_sliceBrush.setThemed(true);
235 data.m_sliceBrush.setThemed(true);
236 }
236 }
237
237
238 if (data.m_labelPen.isThemed() || m_force) {
238 if (data.m_labelPen.isThemed() || m_force) {
239 data.m_labelPen = QPen(m_titleBrush.color());
239 data.m_labelPen = QPen(m_titleBrush.color());
240 data.m_labelPen.setThemed(true);
240 data.m_labelPen.setThemed(true);
241 }
241 }
242
242
243 if (data.m_labelFont.isThemed() || m_force) {
243 if (data.m_labelFont.isThemed() || m_force) {
244 data.m_labelFont = m_labelFont;
244 data.m_labelFont = m_labelFont;
245 data.m_labelFont.setThemed(true);
245 data.m_labelFont.setThemed(true);
246 }
246 }
247
247
248 if (PieSliceData::data(s) != data) {
248 if (PieSliceData::data(s) != data) {
249 PieSliceData::data(s) = data;
249 PieSliceData::data(s) = data;
250 emit PieSliceData::data(s).emitChangedSignal(s);
250 emit PieSliceData::data(s).emitChangedSignal(s);
251 }
251 }
252 }
252 }
253 }
253 }
254
254
255 void ChartTheme::decorate(QSplineSeries *series, int index)
255 void ChartTheme::decorate(QSplineSeries *series, int index)
256 {
256 {
257 QPen pen;
257 QPen pen;
258 if(pen == series->pen() || m_force){
258 if(pen == series->pen() || m_force){
259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
260 pen.setWidthF(2);
260 pen.setWidthF(2);
261 series->setPen(pen);
261 series->setPen(pen);
262 }
262 }
263 }
263 }
264
264
265 void ChartTheme::decorate(QChartAxis *axis,bool axisX)
265 void ChartTheme::decorate(QChartAxis *axis,bool axisX)
266 {
266 {
267 QPen pen;
267 QPen pen;
268 QBrush brush;
268 QBrush brush;
269 QFont font;
269 QFont font;
270
270
271 if (axis->isAxisVisible()) {
271 if (axis->isAxisVisible()) {
272
272
273 if(brush == axis->labelsBrush() || m_force){
273 if(brush == axis->labelsBrush() || m_force){
274 axis->setLabelsBrush(m_axisLabelBrush);
274 axis->setLabelsBrush(m_axisLabelBrush);
275 }
275 }
276 if(pen == axis->labelsPen() || m_force){
276 if(pen == axis->labelsPen() || m_force){
277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
278 }
278 }
279
279
280
280
281 if (axis->shadesVisible() || m_force) {
281 if (axis->shadesVisible() || m_force) {
282
282
283 if(brush == axis->shadesBrush() || m_force){
283 if(brush == axis->shadesBrush() || m_force){
284 axis->setShadesBrush(m_backgroundShadesBrush);
284 axis->setShadesBrush(m_backgroundShadesBrush);
285 }
285 }
286
286
287 if(pen == axis->shadesPen() || m_force){
287 if(pen == axis->shadesPen() || m_force){
288 axis->setShadesPen(m_backgroundShadesPen);
288 axis->setShadesPen(m_backgroundShadesPen);
289 }
289 }
290
290
291 if( m_force && (m_backgroundShades == BackgroundShadesBoth
291 if( m_force && (m_backgroundShades == BackgroundShadesBoth
292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
294 axis->setShadesVisible(true);
294 axis->setShadesVisible(true);
295
295
296 }
296 }
297 }
297 }
298
298
299 if(pen == axis->axisPen() || m_force){
299 if(pen == axis->axisPen() || m_force){
300 axis->setAxisPen(m_axisLinePen);
300 axis->setAxisPen(m_axisLinePen);
301 }
301 }
302
302
303 if(pen == axis->gridLinePen() || m_force){
303 if(pen == axis->gridLinePen() || m_force){
304 axis->setGridLinePen(m_gridLinePen);
304 axis->setGridLinePen(m_gridLinePen);
305 }
305 }
306
306
307 if(font == axis->labelsFont() || m_force){
307 if(font == axis->labelsFont() || m_force){
308 axis->setLabelsFont(m_labelFont);
308 axis->setLabelsFont(m_labelFont);
309 }
309 }
310 }
310 }
311 }
311 }
312
312
313 void ChartTheme::generateSeriesGradients()
313 void ChartTheme::generateSeriesGradients()
314 {
314 {
315 // Generate gradients in HSV color space
315 // Generate gradients in HSV color space
316 foreach (QColor color, m_seriesColors) {
316 foreach (const QColor& color, m_seriesColors) {
317 QLinearGradient g;
317 QLinearGradient g;
318 qreal h = color.hsvHueF();
318 qreal h = color.hsvHueF();
319 qreal s = color.hsvSaturationF();
319 qreal s = color.hsvSaturationF();
320
320
321 // TODO: tune the algorithm to give nice results with most base colors defined in
321 // TODO: tune the algorithm to give nice results with most base colors defined in
322 // most themes. The rest of the gradients we can define manually in theme specific
322 // most themes. The rest of the gradients we can define manually in theme specific
323 // implementation.
323 // implementation.
324 QColor start = color;
324 QColor start = color;
325 start.setHsvF(h, 0.0, 1.0);
325 start.setHsvF(h, 0.0, 1.0);
326 g.setColorAt(0.0, start);
326 g.setColorAt(0.0, start);
327
327
328 g.setColorAt(0.5, color);
328 g.setColorAt(0.5, color);
329
329
330 QColor end = color;
330 QColor end = color;
331 end.setHsvF(h, s, 0.25);
331 end.setHsvF(h, s, 0.25);
332 g.setColorAt(1.0, end);
332 g.setColorAt(1.0, end);
333
333
334 m_seriesGradients << g;
334 m_seriesGradients << g;
335 }
335 }
336 }
336 }
337
337
338
338
339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
340 {
340 {
341 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
341 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
345 QColor c;
345 QColor c;
346 c.setRgbF(r, g, b);
346 c.setRgbF(r, g, b);
347 return c;
347 return c;
348 }
348 }
349
349
350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
351 {
351 {
352 Q_ASSERT(pos >= 0 && pos <= 1.0);
352 Q_ASSERT(pos >= 0 && pos <= 1.0);
353
353
354 // another possibility:
354 // another possibility:
355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
356
356
357 QGradientStops stops = gradient.stops();
357 QGradientStops stops = gradient.stops();
358 int count = stops.count();
358 int count = stops.count();
359
359
360 // find previous stop relative to position
360 // find previous stop relative to position
361 QGradientStop prev = stops.first();
361 QGradientStop prev = stops.first();
362 for (int i = 0; i < count; i++) {
362 for (int i = 0; i < count; i++) {
363 QGradientStop stop = stops.at(i);
363 QGradientStop stop = stops.at(i);
364 if (pos > stop.first)
364 if (pos > stop.first)
365 prev = stop;
365 prev = stop;
366
366
367 // given position is actually a stop position?
367 // given position is actually a stop position?
368 if (pos == stop.first) {
368 if (pos == stop.first) {
369 //qDebug() << "stop color" << pos;
369 //qDebug() << "stop color" << pos;
370 return stop.second;
370 return stop.second;
371 }
371 }
372 }
372 }
373
373
374 // find next stop relative to position
374 // find next stop relative to position
375 QGradientStop next = stops.last();
375 QGradientStop next = stops.last();
376 for (int i = count - 1; i >= 0; i--) {
376 for (int i = count - 1; i >= 0; i--) {
377 QGradientStop stop = stops.at(i);
377 QGradientStop stop = stops.at(i);
378 if (pos < stop.first)
378 if (pos < stop.first)
379 next = stop;
379 next = stop;
380 }
380 }
381
381
382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
383
383
384 qreal range = next.first - prev.first;
384 qreal range = next.first - prev.first;
385 qreal posDelta = pos - prev.first;
385 qreal posDelta = pos - prev.first;
386 qreal relativePos = posDelta / range;
386 qreal relativePos = posDelta / range;
387
387
388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
389
389
390 return colorAt(prev.second, next.second, relativePos);
390 return colorAt(prev.second, next.second, relativePos);
391 }
391 }
392
392
393 void ChartTheme::setForced(bool enabled)
393 void ChartTheme::setForced(bool enabled)
394 {
394 {
395 m_force=enabled;
395 m_force=enabled;
396 }
396 }
397
397
398 QTCOMMERCIALCHART_END_NAMESPACE
398 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,451 +1,451
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qseries.h"
23 #include "qseries.h"
24 #include "qseries_p.h"
24 #include "qseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieslice.h"
38 #include "qpieslice.h"
39 #include "chartpresenter_p.h"
39 #include "chartpresenter_p.h"
40 #include <QPainter>
40 #include <QPainter>
41 #include <QPen>
41 #include <QPen>
42 #include <QTimer>
42 #include <QTimer>
43
43
44 #include <QGraphicsSceneEvent>
44 #include <QGraphicsSceneEvent>
45
45
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47
47
48 /*!
48 /*!
49 \class QLegend
49 \class QLegend
50 \brief part of QtCommercial chart API.
50 \brief part of QtCommercial chart API.
51
51
52 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
52 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
53 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
53 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
54 handle the drawing manually.
54 handle the drawing manually.
55 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
55 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
56
56
57 \mainclass
57 \mainclass
58
58
59 \sa QChart, QSeries
59 \sa QChart, QSeries
60 */
60 */
61
61
62 /*!
62 /*!
63 \enum QLegend::Alignment
63 \enum QLegend::Alignment
64
64
65 This enum describes the possible position for legend inside chart.
65 This enum describes the possible position for legend inside chart.
66
66
67 \value AlignmentTop
67 \value AlignmentTop
68 \value AlignmentBottom
68 \value AlignmentBottom
69 \value AlignmentLeft
69 \value AlignmentLeft
70 \value AlignmentRight
70 \value AlignmentRight
71 */
71 */
72
72
73 /*!
73 /*!
74 \fn qreal QLegend::minWidth() const
74 \fn qreal QLegend::minWidth() const
75 Returns minimum width of the legend
75 Returns minimum width of the legend
76 */
76 */
77
77
78 /*!
78 /*!
79 \fn qreal QLegend::minHeight() const
79 \fn qreal QLegend::minHeight() const
80 Returns minimum height of the legend
80 Returns minimum height of the legend
81 */
81 */
82
82
83 /*!
83 /*!
84 Constructs the legend object and sets the parent to \a parent
84 Constructs the legend object and sets the parent to \a parent
85 */
85 */
86
86
87 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
87 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
88 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
88 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
89 {
89 {
90 setZValue(ChartPresenter::LegendZValue);
90 setZValue(ChartPresenter::LegendZValue);
91 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
91 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
92 setEnabled(false); // By default legend is disabled
92 setEnabled(false); // By default legend is disabled
93 setVisible(false);
93 setVisible(false);
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QSeries*,Domain*)));
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QSeries*,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QSeries*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QSeries*)));
96 }
96 }
97
97
98 QLegend::~QLegend()
98 QLegend::~QLegend()
99 {
99 {
100
100
101 }
101 }
102
102
103 /*!
103 /*!
104 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
104 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
105 */
105 */
106
106
107 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
107 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
108 {
108 {
109 Q_UNUSED(option)
109 Q_UNUSED(option)
110 Q_UNUSED(widget)
110 Q_UNUSED(widget)
111 if(!d_ptr->m_backgroundVisible) return;
111 if(!d_ptr->m_backgroundVisible) return;
112
112
113 painter->setOpacity(opacity());
113 painter->setOpacity(opacity());
114 painter->setPen(d_ptr->m_pen);
114 painter->setPen(d_ptr->m_pen);
115 painter->setBrush(d_ptr->m_brush);
115 painter->setBrush(d_ptr->m_brush);
116 painter->drawRect(boundingRect());
116 painter->drawRect(boundingRect());
117 }
117 }
118
118
119 /*!
119 /*!
120 Bounding rect of legend.
120 Bounding rect of legend.
121 */
121 */
122
122
123 QRectF QLegend::boundingRect() const
123 QRectF QLegend::boundingRect() const
124 {
124 {
125 return d_ptr->m_rect;
125 return d_ptr->m_rect;
126 }
126 }
127
127
128 /*!
128 /*!
129 Sets the \a brush of legend. Brush affects the background of legend.
129 Sets the \a brush of legend. Brush affects the background of legend.
130 */
130 */
131 void QLegend::setBrush(const QBrush &brush)
131 void QLegend::setBrush(const QBrush &brush)
132 {
132 {
133 if (d_ptr->m_brush != brush) {
133 if (d_ptr->m_brush != brush) {
134 d_ptr->m_brush = brush;
134 d_ptr->m_brush = brush;
135 update();
135 update();
136 }
136 }
137 }
137 }
138
138
139 /*!
139 /*!
140 Returns the brush used by legend.
140 Returns the brush used by legend.
141 */
141 */
142 QBrush QLegend::brush() const
142 QBrush QLegend::brush() const
143 {
143 {
144 return d_ptr->m_brush;
144 return d_ptr->m_brush;
145 }
145 }
146
146
147 /*!
147 /*!
148 Sets the \a pen of legend. Pen affects the legend borders.
148 Sets the \a pen of legend. Pen affects the legend borders.
149 */
149 */
150 void QLegend::setPen(const QPen &pen)
150 void QLegend::setPen(const QPen &pen)
151 {
151 {
152 if (d_ptr->m_pen != pen) {
152 if (d_ptr->m_pen != pen) {
153 d_ptr->m_pen = pen;
153 d_ptr->m_pen = pen;
154 update();
154 update();
155 }
155 }
156 }
156 }
157
157
158 /*!
158 /*!
159 Returns the pen used by legend
159 Returns the pen used by legend
160 */
160 */
161
161
162 QPen QLegend::pen() const
162 QPen QLegend::pen() const
163 {
163 {
164 return d_ptr->m_pen;
164 return d_ptr->m_pen;
165 }
165 }
166
166
167 /*!
167 /*!
168 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
168 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
169 \sa QLegend::Alignment
169 \sa QLegend::Alignment
170 */
170 */
171 void QLegend::setAlignment(QLegend::Alignments alignment)
171 void QLegend::setAlignment(QLegend::Alignments alignment)
172 {
172 {
173 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
173 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
174 d_ptr->m_alignment = alignment;
174 d_ptr->m_alignment = alignment;
175 d_ptr->updateLayout();
175 d_ptr->updateLayout();
176 }
176 }
177 }
177 }
178
178
179 /*!
179 /*!
180 Returns the preferred layout for legend
180 Returns the preferred layout for legend
181 */
181 */
182 QLegend::Alignments QLegend::alignment() const
182 QLegend::Alignments QLegend::alignment() const
183 {
183 {
184 return d_ptr->m_alignment;
184 return d_ptr->m_alignment;
185 }
185 }
186
186
187 /*!
187 /*!
188 Detaches the legend from chart. Chart won't change layout of the legend.
188 Detaches the legend from chart. Chart won't change layout of the legend.
189 */
189 */
190 void QLegend::detachFromChart()
190 void QLegend::detachFromChart()
191 {
191 {
192 d_ptr->m_attachedToChart = false;
192 d_ptr->m_attachedToChart = false;
193 }
193 }
194
194
195 /*!
195 /*!
196 Attaches the legend to chart. Chart may change layout of the legend.
196 Attaches the legend to chart. Chart may change layout of the legend.
197 */
197 */
198 void QLegend::attachToChart()
198 void QLegend::attachToChart()
199 {
199 {
200 d_ptr->m_attachedToChart = true;
200 d_ptr->m_attachedToChart = true;
201 }
201 }
202
202
203 /*!
203 /*!
204 Returns true, if legend is attached to chart.
204 Returns true, if legend is attached to chart.
205 */
205 */
206 bool QLegend::isAttachedToChart()
206 bool QLegend::isAttachedToChart()
207 {
207 {
208 return d_ptr->m_attachedToChart;
208 return d_ptr->m_attachedToChart;
209 }
209 }
210
210
211 void QLegend::setOffset(const QPointF& point)
211 void QLegend::setOffset(const QPointF& point)
212 {
212 {
213 d_ptr->setOffset(point.x(),point.y());
213 d_ptr->setOffset(point.x(),point.y());
214 }
214 }
215
215
216 QPointF QLegend::offset() const
216 QPointF QLegend::offset() const
217 {
217 {
218 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
218 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
219 }
219 }
220
220
221 /*!
221 /*!
222 Sets the visibility of legend background to \a visible
222 Sets the visibility of legend background to \a visible
223 */
223 */
224 void QLegend::setBackgroundVisible(bool visible)
224 void QLegend::setBackgroundVisible(bool visible)
225 {
225 {
226 if(d_ptr->m_backgroundVisible!=visible)
226 if(d_ptr->m_backgroundVisible!=visible)
227 {
227 {
228 d_ptr->m_backgroundVisible=visible;
228 d_ptr->m_backgroundVisible=visible;
229 update();
229 update();
230 }
230 }
231 }
231 }
232
232
233 /*!
233 /*!
234 Returns the visibility of legend background
234 Returns the visibility of legend background
235 */
235 */
236 bool QLegend::isBackgroundVisible() const
236 bool QLegend::isBackgroundVisible() const
237 {
237 {
238 return d_ptr->m_backgroundVisible;
238 return d_ptr->m_backgroundVisible;
239 }
239 }
240
240
241 /*!
241 /*!
242 \internal \a event see QGraphicsWidget for details
242 \internal \a event see QGraphicsWidget for details
243 */
243 */
244 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
244 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
245 {
245 {
246 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
246 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
247 QGraphicsWidget::resizeEvent(event);
247 QGraphicsWidget::resizeEvent(event);
248 if(d_ptr->m_rect != rect) {
248 if(d_ptr->m_rect != rect) {
249 d_ptr->m_rect = rect;
249 d_ptr->m_rect = rect;
250 d_ptr->updateLayout();
250 d_ptr->updateLayout();
251 }
251 }
252 }
252 }
253
253
254 /*!
254 /*!
255 \internal \a event see QGraphicsWidget for details
255 \internal \a event see QGraphicsWidget for details
256 */
256 */
257 void QLegend::hideEvent(QHideEvent *event)
257 void QLegend::hideEvent(QHideEvent *event)
258 {
258 {
259 QGraphicsWidget::hideEvent(event);
259 QGraphicsWidget::hideEvent(event);
260 setEnabled(false);
260 setEnabled(false);
261 d_ptr->updateLayout();
261 d_ptr->updateLayout();
262 }
262 }
263
263
264 /*!
264 /*!
265 \internal \a event see QGraphicsWidget for details
265 \internal \a event see QGraphicsWidget for details
266 */
266 */
267 void QLegend::showEvent(QShowEvent *event)
267 void QLegend::showEvent(QShowEvent *event)
268 {
268 {
269 QGraphicsWidget::showEvent(event);
269 QGraphicsWidget::showEvent(event);
270 setEnabled(true);
270 setEnabled(true);
271 d_ptr->updateLayout();
271 d_ptr->updateLayout();
272 }
272 }
273
273
274 qreal QLegend::minWidth() const
274 qreal QLegend::minWidth() const
275 {
275 {
276 return d_ptr->m_minWidth;
276 return d_ptr->m_minWidth;
277 }
277 }
278
278
279 qreal QLegend::minHeight() const
279 qreal QLegend::minHeight() const
280 {
280 {
281 return d_ptr->m_minHeight;
281 return d_ptr->m_minHeight;
282 }
282 }
283
283
284 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
284 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
285
285
286 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
286 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
287 q_ptr(q),
287 q_ptr(q),
288 m_presenter(presenter),
288 m_presenter(presenter),
289 m_markers(new QGraphicsItemGroup(q)),
289 m_markers(new QGraphicsItemGroup(q)),
290 m_alignment(QLegend::AlignmentTop),
290 m_alignment(QLegend::AlignmentTop),
291 m_offsetX(0),
291 m_offsetX(0),
292 m_offsetY(0),
292 m_offsetY(0),
293 m_minWidth(0),
293 m_minWidth(0),
294 m_minHeight(0),
294 m_minHeight(0),
295 m_width(0),
295 m_width(0),
296 m_height(0),
296 m_height(0),
297 m_attachedToChart(true),
297 m_attachedToChart(true),
298 m_backgroundVisible(false)
298 m_backgroundVisible(false)
299 {
299 {
300
300
301 }
301 }
302
302
303 QLegendPrivate::~QLegendPrivate()
303 QLegendPrivate::~QLegendPrivate()
304 {
304 {
305
305
306 }
306 }
307
307
308 void QLegendPrivate::setOffset(qreal x, qreal y)
308 void QLegendPrivate::setOffset(qreal x, qreal y)
309 {
309 {
310
310
311 switch(m_alignment) {
311 switch(m_alignment) {
312
312
313 case QLegend::AlignmentTop:
313 case QLegend::AlignmentTop:
314 case QLegend::AlignmentBottom: {
314 case QLegend::AlignmentBottom: {
315 if(m_width<=m_rect.width()) return;
315 if(m_width<=m_rect.width()) return;
316
316
317 if (x != m_offsetX) {
317 if (x != m_offsetX) {
318 m_offsetX = qBound(0.0, x, m_width - m_rect.width());
318 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
319 m_markers->setPos(-m_offsetX,m_rect.top());
319 m_markers->setPos(-m_offsetX,m_rect.top());
320 }
320 }
321 break;
321 break;
322 }
322 }
323 case QLegend::AlignmentLeft:
323 case QLegend::AlignmentLeft:
324 case QLegend::AlignmentRight: {
324 case QLegend::AlignmentRight: {
325
325
326 if(m_height<=m_rect.height()) return;
326 if(m_height<=m_rect.height()) return;
327
327
328 if (y != m_offsetY) {
328 if (y != m_offsetY) {
329 m_offsetY = qBound(0.0, y, m_height - m_rect.height());
329 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
330 m_markers->setPos(m_rect.left(),-m_offsetY);
330 m_markers->setPos(m_rect.left(),-m_offsetY);
331 }
331 }
332 break;
332 break;
333 }
333 }
334 }
334 }
335 }
335 }
336
336
337
337
338 void QLegendPrivate::updateLayout()
338 void QLegendPrivate::updateLayout()
339 {
339 {
340 m_offsetX=0;
340 m_offsetX=0;
341 QList<QGraphicsItem *> items = m_markers->childItems();
341 QList<QGraphicsItem *> items = m_markers->childItems();
342
342
343 if(items.isEmpty()) return;
343 if(items.isEmpty()) return;
344
344
345 m_minWidth=0;
345 m_minWidth=0;
346 m_minHeight=0;
346 m_minHeight=0;
347
347
348 switch(m_alignment) {
348 switch(m_alignment) {
349
349
350 case QLegend::AlignmentTop:
350 case QLegend::AlignmentTop:
351 case QLegend::AlignmentBottom: {
351 case QLegend::AlignmentBottom: {
352 QPointF point = m_rect.topLeft();
352 QPointF point = m_rect.topLeft();
353 m_width = 0;
353 m_width = 0;
354 foreach (QGraphicsItem *item, items) {
354 foreach (QGraphicsItem *item, items) {
355 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
355 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
356 const QRectF& rect = item->boundingRect();
356 const QRectF& rect = item->boundingRect();
357 qreal w = rect.width();
357 qreal w = rect.width();
358 m_minWidth=qMax(m_minWidth,w);
358 m_minWidth=qMax(m_minWidth,w);
359 m_minHeight=qMax(m_minHeight,rect.height());
359 m_minHeight=qMax(m_minHeight,rect.height());
360 m_width+=w;
360 m_width+=w;
361 point.setX(point.x() + w);
361 point.setX(point.x() + w);
362 }
362 }
363 if(m_width<m_rect.width()) {
363 if(m_width<m_rect.width()) {
364 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
364 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
365 }
365 }
366 else {
366 else {
367 m_markers->setPos(m_rect.topLeft());
367 m_markers->setPos(m_rect.topLeft());
368 }
368 }
369 m_height=m_minHeight;
369 m_height=m_minHeight;
370 }
370 }
371 break;
371 break;
372 case QLegend::AlignmentLeft:
372 case QLegend::AlignmentLeft:
373 case QLegend::AlignmentRight: {
373 case QLegend::AlignmentRight: {
374 QPointF point = m_rect.topLeft();
374 QPointF point = m_rect.topLeft();
375 m_height = 0;
375 m_height = 0;
376 foreach (QGraphicsItem *item, items) {
376 foreach (QGraphicsItem *item, items) {
377 item->setPos(point);
377 item->setPos(point);
378 const QRectF& rect = item->boundingRect();
378 const QRectF& rect = item->boundingRect();
379 qreal h = rect.height();
379 qreal h = rect.height();
380 m_minWidth=qMax(m_minWidth,rect.width());
380 m_minWidth=qMax(m_minWidth,rect.width());
381 m_minHeight=qMax(m_minHeight,h);
381 m_minHeight=qMax(m_minHeight,h);
382 m_height+=h;
382 m_height+=h;
383 point.setY(point.y() + h);
383 point.setY(point.y() + h);
384 }
384 }
385 if(m_height<m_rect.height()) {
385 if(m_height<m_rect.height()) {
386 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
386 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
387 }
387 }
388 else {
388 else {
389 m_markers->setPos(m_rect.topLeft());
389 m_markers->setPos(m_rect.topLeft());
390 }
390 }
391 m_width=m_minWidth;
391 m_width=m_minWidth;
392 }
392 }
393 break;
393 break;
394 }
394 }
395
395
396 m_presenter->updateLayout();
396 m_presenter->updateLayout();
397 }
397 }
398
398
399 void QLegendPrivate::handleSeriesAdded(QSeries *series, Domain *domain)
399 void QLegendPrivate::handleSeriesAdded(QSeries *series, Domain *domain)
400 {
400 {
401 Q_UNUSED(domain)
401 Q_UNUSED(domain)
402
402
403 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
403 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
404 foreach(LegendMarker* marker , markers)
404 foreach(LegendMarker* marker , markers)
405 m_markers->addToGroup(marker);
405 m_markers->addToGroup(marker);
406
406
407 if(series->type()==QSeries::SeriesTypePie)
407 if(series->type()==QSeries::SeriesTypePie)
408 {
408 {
409 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
409 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
410 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
410 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
411 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
411 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
412 }
412 }
413
413
414 updateLayout();
414 updateLayout();
415 }
415 }
416
416
417 void QLegendPrivate::handleSeriesRemoved(QSeries *series)
417 void QLegendPrivate::handleSeriesRemoved(QSeries *series)
418 {
418 {
419
419
420 QList<QGraphicsItem *> items = m_markers->childItems();
420 QList<QGraphicsItem *> items = m_markers->childItems();
421
421
422 foreach (QGraphicsItem *markers, items) {
422 foreach (QGraphicsItem *markers, items) {
423 LegendMarker *marker = static_cast<LegendMarker*>(markers);
423 LegendMarker *marker = static_cast<LegendMarker*>(markers);
424 if (marker->series() == series) {
424 if (marker->series() == series) {
425 delete marker;
425 delete marker;
426 }
426 }
427 }
427 }
428
428
429 if(series->type()==QSeries::SeriesTypePie)
429 if(series->type()==QSeries::SeriesTypePie)
430 {
430 {
431 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
431 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
432 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
432 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
433 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
433 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
434 }
434 }
435
435
436 updateLayout();
436 updateLayout();
437 }
437 }
438
438
439 void QLegendPrivate::handleUpdateSeries()
439 void QLegendPrivate::handleUpdateSeries()
440 {
440 {
441 //TODO: reimplement to be optimal
441 //TODO: reimplement to be optimal
442 QSeries* series = qobject_cast<QSeries *> (sender());
442 QSeries* series = qobject_cast<QSeries *> (sender());
443 Q_ASSERT(series);
443 Q_ASSERT(series);
444 handleSeriesRemoved(series);
444 handleSeriesRemoved(series);
445 handleSeriesAdded(series,0);
445 handleSeriesAdded(series,0);
446 }
446 }
447
447
448 #include "moc_qlegend.cpp"
448 #include "moc_qlegend.cpp"
449 #include "moc_qlegend_p.cpp"
449 #include "moc_qlegend_p.cpp"
450
450
451 QTCOMMERCIALCHART_END_NAMESPACE
451 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,116 +1,116
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlineseries.h"
21 #include "qlineseries.h"
22 #include "qlineseries_p.h"
22 #include "qlineseries_p.h"
23 #include "linechartitem_p.h"
23 #include "linechartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 /*!
30 /*!
31 \class QLineSeries
31 \class QLineSeries
32 \brief The QLineSeries class is used for making line charts.
32 \brief The QLineSeries class is used for making line charts.
33
33
34 \mainclass
34 \mainclass
35
35
36 A line chart is used to show information as a series of data points
36 A line chart is used to show information as a series of data points
37 connected by straight lines.
37 connected by straight lines.
38
38
39 \image linechart.png
39 \image linechart.png
40
40
41 Creating basic line chart is simple:
41 Creating basic line chart is simple:
42 \code
42 \code
43 QLineSeries* series = new QLineSeries();
43 QLineSeries* series = new QLineSeries();
44 series->append(0, 6);
44 series->append(0, 6);
45 series->append(2, 4);
45 series->append(2, 4);
46 ...
46 ...
47 chartView->addSeries(series);
47 chartView->addSeries(series);
48 \endcode
48 \endcode
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn virtual QSeriesType QLineSeries::type() const
52 \fn virtual QSeriesType QLineSeries::type() const
53 \brief Returns type of series.
53 \brief Returns type of series.
54 \sa QSeries, QSeriesType
54 \sa QSeries, QSeriesType
55 */
55 */
56
56
57 /*!
57 /*!
58 Constructs empty series object which is a child of \a parent.
58 Constructs empty series object which is a child of \a parent.
59 When series object is added to QChartView or QChart instance ownerships is transfered.
59 When series object is added to QChartView or QChart instance ownerships is transferred.
60 */
60 */
61 QLineSeries::QLineSeries(QObject *parent) : QXYSeries(*new QLineSeriesPrivate(this),parent)
61 QLineSeries::QLineSeries(QObject *parent) : QXYSeries(*new QLineSeriesPrivate(this),parent)
62 {
62 {
63
63
64 }
64 }
65
65
66 /*!
66 /*!
67 \internal
67 \internal
68 */
68 */
69 QLineSeries::QLineSeries(QLineSeriesPrivate &d,QObject *parent) : QXYSeries (d,parent)
69 QLineSeries::QLineSeries(QLineSeriesPrivate &d,QObject *parent) : QXYSeries (d,parent)
70 {
70 {
71
71
72 }
72 }
73 /*!
73 /*!
74 Destroys the object. Series added to QChartView or QChart instances are owned by those,
74 Destroys the object. Series added to QChartView or QChart instances are owned by those,
75 and are deleted when mentioned object are destroyed.
75 and are deleted when mentioned object are destroyed.
76 */
76 */
77 QLineSeries::~QLineSeries()
77 QLineSeries::~QLineSeries()
78 {
78 {
79 }
79 }
80
80
81 QSeries::QSeriesType QLineSeries::type() const
81 QSeries::QSeriesType QLineSeries::type() const
82 {
82 {
83 return QSeries::SeriesTypeLine;
83 return QSeries::SeriesTypeLine;
84 }
84 }
85
85
86 /*
86 /*
87 QDebug operator<< (QDebug debug, const QLineSeries series)
87 QDebug operator<< (QDebug debug, const QLineSeries series)
88 {
88 {
89 Q_ASSERT(series.d_func()->m_x.size() == series.d_func()->m_y.size());
89 Q_ASSERT(series.d_func()->m_x.size() == series.d_func()->m_y.size());
90 int size = series.d_func()->m_x.size();
90 int size = series.d_func()->m_x.size();
91 for (int i=0; i<size; i++) {
91 for (int i=0; i<size; i++) {
92 debug.nospace() << "(" << series.d_func()->m_x.at(i) << ','<< series.d_func()->m_y.at(i) << ") ";
92 debug.nospace() << "(" << series.d_func()->m_x.at(i) << ','<< series.d_func()->m_y.at(i) << ") ";
93 }
93 }
94 return debug.space();
94 return debug.space();
95 }
95 }
96 */
96 */
97
97
98 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
98 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99
99
100 QLineSeriesPrivate::QLineSeriesPrivate(QLineSeries* q):QXYSeriesPrivate(q)
100 QLineSeriesPrivate::QLineSeriesPrivate(QLineSeries* q):QXYSeriesPrivate(q)
101 {
101 {
102
102
103 };
103 };
104
104
105 Chart* QLineSeriesPrivate::createGraphics(ChartPresenter* presenter)
105 Chart* QLineSeriesPrivate::createGraphics(ChartPresenter* presenter)
106 {
106 {
107 Q_Q(QLineSeries);
107 Q_Q(QLineSeries);
108 LineChartItem* line = new LineChartItem(q,presenter);
108 LineChartItem* line = new LineChartItem(q,presenter);
109 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
109 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
110 presenter->animator()->addAnimation(line);
110 presenter->animator()->addAnimation(line);
111 }
111 }
112 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
112 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
113 return line;
113 return line;
114 }
114 }
115
115
116 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,52
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef QLINESERIES_H
21 #ifndef QLINESERIES_H
22 #define QLINESERIES_H
22 #define QLINESERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qxyseries.h>
25 #include <qxyseries.h>
26 #include <QPen>
26 #include <QPen>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 class QLineSeriesPrivate;
30 class QLineSeriesPrivate;
31
31
32 class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries
32 class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries
33 {
33 {
34 public:
34 public:
35 explicit QLineSeries(QObject *parent=0);
35 explicit QLineSeries(QObject *parent = 0);
36 ~QLineSeries();
36 ~QLineSeries();
37
37
38 QSeries::QSeriesType type() const;
38 QSeries::QSeriesType type() const;
39
39
40 protected:
40 protected:
41 QLineSeries(QLineSeriesPrivate &d,QObject *parent = 0);
41 QLineSeries(QLineSeriesPrivate &d,QObject *parent = 0);
42
42
43 private:
43 private:
44 Q_DECLARE_PRIVATE(QLineSeries);
44 Q_DECLARE_PRIVATE(QLineSeries);
45 Q_DISABLE_COPY(QLineSeries);
45 Q_DISABLE_COPY(QLineSeries);
46 friend class LineChartItem;
46 friend class LineChartItem;
47
47
48 };
48 };
49
49
50 QTCOMMERCIALCHART_END_NAMESPACE
50 QTCOMMERCIALCHART_END_NAMESPACE
51
51
52 #endif
52 #endif
@@ -1,738 +1,738
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpieseries.h"
21 #include "qpieseries.h"
22 #include "qpieseries_p.h"
22 #include "qpieseries_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include "pieslicedata_p.h"
25 #include "chartdataset_p.h"
25 #include "chartdataset_p.h"
26 #include "charttheme_p.h"
26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include <QAbstractItemModel>
29 #include <QAbstractItemModel>
30 #include <QDebug>
30 #include <QDebug>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /*!
34 /*!
35 \class QPieSeries
35 \class QPieSeries
36 \brief Pie series API for QtCommercial Charts
36 \brief Pie series API for QtCommercial Charts
37
37
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 The actual slice size is determined by that relative value.
40 The actual slice size is determined by that relative value.
41
41
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 These relate to the actual chart rectangle.
43 These relate to the actual chart rectangle.
44
44
45 By default the pie is defined as a full pie but it can also be a partial pie.
45 By default the pie is defined as a full pie but it can also be a partial pie.
46 This can be done by setting a starting angle and angle span to the series.
46 This can be done by setting a starting angle and angle span to the series.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
48 */
48 */
49
49
50 /*!
50 /*!
51 \property QPieSeries::horizontalPosition
51 \property QPieSeries::horizontalPosition
52 \brief Defines the horizontal position of the pie.
52 \brief Defines the horizontal position of the pie.
53
53
54 The value is a relative value to the chart rectangle where:
54 The value is a relative value to the chart rectangle where:
55
55
56 \list
56 \list
57 \o 0.0 is the absolute left.
57 \o 0.0 is the absolute left.
58 \o 1.0 is the absolute right.
58 \o 1.0 is the absolute right.
59 \endlist
59 \endlist
60
60
61 Default value is 0.5 (center).
61 Default value is 0.5 (center).
62 */
62 */
63
63
64 /*!
64 /*!
65 \property QPieSeries::verticalPosition
65 \property QPieSeries::verticalPosition
66 \brief Defines the vertical position of the pie.
66 \brief Defines the vertical position of the pie.
67
67
68 The value is a relative value to the chart rectangle where:
68 The value is a relative value to the chart rectangle where:
69
69
70 \list
70 \list
71 \o 0.0 is the absolute top.
71 \o 0.0 is the absolute top.
72 \o 1.0 is the absolute bottom.
72 \o 1.0 is the absolute bottom.
73 \endlist
73 \endlist
74
74
75 Default value is 0.5 (center).
75 Default value is 0.5 (center).
76 */
76 */
77
77
78 /*!
78 /*!
79 \property QPieSeries::size
79 \property QPieSeries::size
80 \brief Defines the pie size.
80 \brief Defines the pie size.
81
81
82 The value is a relative value to the chart rectangle where:
82 The value is a relative value to the chart rectangle where:
83
83
84 \list
84 \list
85 \o 0.0 is the minumum size (pie not drawn).
85 \o 0.0 is the minimum size (pie not drawn).
86 \o 1.0 is the maximum size that can fit the chart.
86 \o 1.0 is the maximum size that can fit the chart.
87 \endlist
87 \endlist
88
88
89 Default value is 0.7.
89 Default value is 0.7.
90 */
90 */
91
91
92 /*!
92 /*!
93 \property QPieSeries::startAngle
93 \property QPieSeries::startAngle
94 \brief Defines the starting angle of the pie.
94 \brief Defines the starting angle of the pie.
95
95
96 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
96 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
97
97
98 Default is value is 0.
98 Default is value is 0.
99 */
99 */
100
100
101 /*!
101 /*!
102 \property QPieSeries::endAngle
102 \property QPieSeries::endAngle
103 \brief Defines the ending angle of the pie.
103 \brief Defines the ending angle of the pie.
104
104
105 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
105 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
106
106
107 Default is value is 360.
107 Default is value is 360.
108 */
108 */
109
109
110
110
111 /*!
111 /*!
112 Constructs a series object which is a child of \a parent.
112 Constructs a series object which is a child of \a parent.
113 */
113 */
114 QPieSeries::QPieSeries(QObject *parent) :
114 QPieSeries::QPieSeries(QObject *parent) :
115 QSeries(*new QPieSeriesPrivate(this),parent)
115 QSeries(*new QPieSeriesPrivate(this),parent)
116 {
116 {
117
117
118 }
118 }
119
119
120 /*!
120 /*!
121 Destroys the series and its slices.
121 Destroys the series and its slices.
122 */
122 */
123 QPieSeries::~QPieSeries()
123 QPieSeries::~QPieSeries()
124 {
124 {
125 // NOTE: d_prt destroyed by QObject
125 // NOTE: d_prt destroyed by QObject
126 }
126 }
127
127
128 /*!
128 /*!
129 Returns QChartSeries::SeriesTypePie.
129 Returns QChartSeries::SeriesTypePie.
130 */
130 */
131 QSeries::QSeriesType QPieSeries::type() const
131 QSeries::QSeriesType QPieSeries::type() const
132 {
132 {
133 return QSeries::SeriesTypePie;
133 return QSeries::SeriesTypePie;
134 }
134 }
135
135
136 /*!
136 /*!
137 Sets an array of \a slices to the series replacing the existing slices.
137 Sets an array of \a slices to the series replacing the existing slices.
138 Slice ownership is passed to the series.
138 Slice ownership is passed to the series.
139 */
139 */
140 void QPieSeries::replace(QList<QPieSlice*> slices)
140 void QPieSeries::replace(QList<QPieSlice*> slices)
141 {
141 {
142 clear();
142 clear();
143 append(slices);
143 append(slices);
144 }
144 }
145
145
146 /*!
146 /*!
147 Appends an array of \a slices to the series.
147 Appends an array of \a slices to the series.
148 Slice ownership is passed to the series.
148 Slice ownership is passed to the series.
149 */
149 */
150 void QPieSeries::append(QList<QPieSlice*> slices)
150 void QPieSeries::append(QList<QPieSlice*> slices)
151 {
151 {
152 Q_D(QPieSeries);
152 Q_D(QPieSeries);
153
153
154 foreach (QPieSlice* s, slices) {
154 foreach (QPieSlice* s, slices) {
155 s->setParent(this);
155 s->setParent(this);
156 d->m_slices << s;
156 d->m_slices << s;
157 }
157 }
158
158
159 d->updateDerivativeData();
159 d->updateDerivativeData();
160
160
161 foreach (QPieSlice* s, slices) {
161 foreach (QPieSlice* s, slices) {
162 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
162 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
163 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
163 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
164 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
164 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
165 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
165 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
166 }
166 }
167
167
168 emit added(slices);
168 emit added(slices);
169 }
169 }
170
170
171 /*!
171 /*!
172 Appends a single \a slice to the series.
172 Appends a single \a slice to the series.
173 Slice ownership is passed to the series.
173 Slice ownership is passed to the series.
174 */
174 */
175 void QPieSeries::append(QPieSlice* slice)
175 void QPieSeries::append(QPieSlice* slice)
176 {
176 {
177 append(QList<QPieSlice*>() << slice);
177 append(QList<QPieSlice*>() << slice);
178 }
178 }
179
179
180 /*!
180 /*!
181 Appends a single \a slice to the series and returns a reference to the series.
181 Appends a single \a slice to the series and returns a reference to the series.
182 Slice ownership is passed to the series.
182 Slice ownership is passed to the series.
183 */
183 */
184 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
184 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
185 {
185 {
186 append(slice);
186 append(slice);
187 return *this;
187 return *this;
188 }
188 }
189
189
190
190
191 /*!
191 /*!
192 Appends a single slice to the series with give \a value and \a name.
192 Appends a single slice to the series with give \a value and \a name.
193 Slice ownership is passed to the series.
193 Slice ownership is passed to the series.
194 */
194 */
195 QPieSlice* QPieSeries::append(qreal value, QString name)
195 QPieSlice* QPieSeries::append(qreal value, QString name)
196 {
196 {
197 QPieSlice* slice = new QPieSlice(value, name);
197 QPieSlice* slice = new QPieSlice(value, name);
198 append(slice);
198 append(slice);
199 return slice;
199 return slice;
200 }
200 }
201
201
202 /*!
202 /*!
203 Inserts a single \a slice to the series before the slice at \a index position.
203 Inserts a single \a slice to the series before the slice at \a index position.
204 Slice ownership is passed to the series.
204 Slice ownership is passed to the series.
205 */
205 */
206 void QPieSeries::insert(int index, QPieSlice* slice)
206 void QPieSeries::insert(int index, QPieSlice* slice)
207 {
207 {
208 Q_D(QPieSeries);
208 Q_D(QPieSeries);
209 Q_ASSERT(index <= d->m_slices.count());
209 Q_ASSERT(index <= d->m_slices.count());
210 slice->setParent(this);
210 slice->setParent(this);
211 d->m_slices.insert(index, slice);
211 d->m_slices.insert(index, slice);
212
212
213 d->updateDerivativeData();
213 d->updateDerivativeData();
214
214
215 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
215 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
216 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
216 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
217 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
217 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
218 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
218 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
219
219
220 emit added(QList<QPieSlice*>() << slice);
220 emit added(QList<QPieSlice*>() << slice);
221 }
221 }
222
222
223 /*!
223 /*!
224 Removes a single \a slice from the series and deletes the slice.
224 Removes a single \a slice from the series and deletes the slice.
225
225
226 Do not reference the pointer after this call.
226 Do not reference the pointer after this call.
227 */
227 */
228 void QPieSeries::remove(QPieSlice* slice)
228 void QPieSeries::remove(QPieSlice* slice)
229 {
229 {
230 Q_D(QPieSeries);
230 Q_D(QPieSeries);
231 if (!d->m_slices.removeOne(slice)) {
231 if (!d->m_slices.removeOne(slice)) {
232 Q_ASSERT(0); // TODO: how should this be reported?
232 Q_ASSERT(0); // TODO: how should this be reported?
233 return;
233 return;
234 }
234 }
235
235
236 d->updateDerivativeData();
236 d->updateDerivativeData();
237
237
238 emit removed(QList<QPieSlice*>() << slice);
238 emit removed(QList<QPieSlice*>() << slice);
239
239
240 delete slice;
240 delete slice;
241 slice = 0;
241 slice = 0;
242 }
242 }
243
243
244 /*!
244 /*!
245 Clears all slices from the series.
245 Clears all slices from the series.
246 */
246 */
247 void QPieSeries::clear()
247 void QPieSeries::clear()
248 {
248 {
249 Q_D(QPieSeries);
249 Q_D(QPieSeries);
250 if (d->m_slices.count() == 0)
250 if (d->m_slices.count() == 0)
251 return;
251 return;
252
252
253 QList<QPieSlice*> slices = d->m_slices;
253 QList<QPieSlice*> slices = d->m_slices;
254 foreach (QPieSlice* s, d->m_slices) {
254 foreach (QPieSlice* s, d->m_slices) {
255 d->m_slices.removeOne(s);
255 d->m_slices.removeOne(s);
256 delete s;
256 delete s;
257 }
257 }
258
258
259 d->updateDerivativeData();
259 d->updateDerivativeData();
260
260
261 emit removed(slices);
261 emit removed(slices);
262 }
262 }
263
263
264 /*!
264 /*!
265 returns the number of the slices in this series.
265 returns the number of the slices in this series.
266 */
266 */
267 int QPieSeries::count() const
267 int QPieSeries::count() const
268 {
268 {
269 Q_D(const QPieSeries);
269 Q_D(const QPieSeries);
270 return d->m_slices.count();
270 return d->m_slices.count();
271 }
271 }
272
272
273 /*!
273 /*!
274 Returns true is the series is empty.
274 Returns true is the series is empty.
275 */
275 */
276 bool QPieSeries::isEmpty() const
276 bool QPieSeries::isEmpty() const
277 {
277 {
278 Q_D(const QPieSeries);
278 Q_D(const QPieSeries);
279 return d->m_slices.isEmpty();
279 return d->m_slices.isEmpty();
280 }
280 }
281
281
282 /*!
282 /*!
283 Returns a list of slices that belong to this series.
283 Returns a list of slices that belong to this series.
284 */
284 */
285 QList<QPieSlice*> QPieSeries::slices() const
285 QList<QPieSlice*> QPieSeries::slices() const
286 {
286 {
287 Q_D(const QPieSeries);
287 Q_D(const QPieSeries);
288 return d->m_slices;
288 return d->m_slices;
289 }
289 }
290
290
291 void QPieSeries::setHorizontalPosition(qreal relativePosition)
291 void QPieSeries::setHorizontalPosition(qreal relativePosition)
292 {
292 {
293 Q_D(QPieSeries);
293 Q_D(QPieSeries);
294 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
294 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
295 emit piePositionChanged();
295 emit piePositionChanged();
296 }
296 }
297
297
298 void QPieSeries::setVerticalPosition(qreal relativePosition)
298 void QPieSeries::setVerticalPosition(qreal relativePosition)
299 {
299 {
300 Q_D(QPieSeries);
300 Q_D(QPieSeries);
301 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
301 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
302 emit piePositionChanged();
302 emit piePositionChanged();
303 }
303 }
304
304
305 qreal QPieSeries::horizontalPosition() const
305 qreal QPieSeries::horizontalPosition() const
306 {
306 {
307 Q_D(const QPieSeries);
307 Q_D(const QPieSeries);
308 return d->m_pieRelativeHorPos;
308 return d->m_pieRelativeHorPos;
309 }
309 }
310
310
311 qreal QPieSeries::verticalPosition() const
311 qreal QPieSeries::verticalPosition() const
312 {
312 {
313 Q_D(const QPieSeries);
313 Q_D(const QPieSeries);
314 return d->m_pieRelativeVerPos;
314 return d->m_pieRelativeVerPos;
315 }
315 }
316
316
317 void QPieSeries::setPieSize(qreal relativeSize)
317 void QPieSeries::setPieSize(qreal relativeSize)
318 {
318 {
319 Q_D(QPieSeries);
319 Q_D(QPieSeries);
320 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
320 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
321 emit pieSizeChanged();
321 emit pieSizeChanged();
322 }
322 }
323
323
324 qreal QPieSeries::pieSize() const
324 qreal QPieSeries::pieSize() const
325 {
325 {
326 Q_D(const QPieSeries);
326 Q_D(const QPieSeries);
327 return d->m_pieRelativeSize;
327 return d->m_pieRelativeSize;
328 }
328 }
329
329
330
330
331 void QPieSeries::setPieStartAngle(qreal angle)
331 void QPieSeries::setPieStartAngle(qreal angle)
332 {
332 {
333 Q_D(QPieSeries);
333 Q_D(QPieSeries);
334 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
334 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
335 d->updateDerivativeData();
335 d->updateDerivativeData();
336 }
336 }
337
337
338 qreal QPieSeries::pieStartAngle() const
338 qreal QPieSeries::pieStartAngle() const
339 {
339 {
340 Q_D(const QPieSeries);
340 Q_D(const QPieSeries);
341 return d->m_pieStartAngle;
341 return d->m_pieStartAngle;
342 }
342 }
343
343
344 /*!
344 /*!
345 Sets the end angle of the pie.
345 Sets the end angle of the pie.
346
346
347 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
347 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
348
348
349 \a angle must be greater than start angle.
349 \a angle must be greater than start angle.
350
350
351 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
351 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
352 */
352 */
353 void QPieSeries::setPieEndAngle(qreal angle)
353 void QPieSeries::setPieEndAngle(qreal angle)
354 {
354 {
355 Q_D(QPieSeries);
355 Q_D(QPieSeries);
356
356
357 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
357 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
358 d->updateDerivativeData();
358 d->updateDerivativeData();
359 }
359 }
360
360
361 /*!
361 /*!
362 Returns the end angle of the pie.
362 Returns the end angle of the pie.
363
363
364 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
364 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
365
365
366 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
366 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
367 */
367 */
368 qreal QPieSeries::pieEndAngle() const
368 qreal QPieSeries::pieEndAngle() const
369 {
369 {
370 Q_D(const QPieSeries);
370 Q_D(const QPieSeries);
371 return d->m_pieEndAngle;
371 return d->m_pieEndAngle;
372 }
372 }
373
373
374 /*!
374 /*!
375 Sets the all the slice labels \a visible or invisible.
375 Sets the all the slice labels \a visible or invisible.
376
376
377 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
377 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
378 */
378 */
379 void QPieSeries::setLabelsVisible(bool visible)
379 void QPieSeries::setLabelsVisible(bool visible)
380 {
380 {
381 Q_D(QPieSeries);
381 Q_D(QPieSeries);
382 foreach (QPieSlice* s, d->m_slices)
382 foreach (QPieSlice* s, d->m_slices)
383 s->setLabelVisible(visible);
383 s->setLabelVisible(visible);
384 }
384 }
385
385
386 /*!
386 /*!
387 Returns the sum of all slice values in this series.
387 Returns the sum of all slice values in this series.
388
388
389 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
389 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
390 */
390 */
391 qreal QPieSeries::sum() const
391 qreal QPieSeries::sum() const
392 {
392 {
393 Q_D(const QPieSeries);
393 Q_D(const QPieSeries);
394 return d->m_sum;
394 return d->m_sum;
395 }
395 }
396
396
397 /*!
397 /*!
398 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
398 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
399
399
400 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
400 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
401
401
402 \sa QPieSlice::clicked()
402 \sa QPieSlice::clicked()
403 */
403 */
404
404
405 /*!
405 /*!
406 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
406 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
407
407
408 This signal is emitted when user has hovered over a \a slice.
408 This signal is emitted when user has hovered over a \a slice.
409
409
410 \sa QPieSlice::hoverEnter()
410 \sa QPieSlice::hoverEnter()
411 */
411 */
412
412
413 /*!
413 /*!
414 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
414 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
415
415
416 This signal is emitted when user has hovered away from a \a slice.
416 This signal is emitted when user has hovered away from a \a slice.
417
417
418 \sa QPieSlice::hoverLeave()
418 \sa QPieSlice::hoverLeave()
419 */
419 */
420
420
421 /*!
421 /*!
422 \fn void QPieSeries::added(QList<QPieSlice*> slices)
422 \fn void QPieSeries::added(QList<QPieSlice*> slices)
423
423
424 This signal is emitted when \a slices has been added to the series.
424 This signal is emitted when \a slices has been added to the series.
425
425
426 \sa append(), insert()
426 \sa append(), insert()
427 */
427 */
428
428
429 /*!
429 /*!
430 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
430 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
431
431
432 This signal is emitted when \a slices has been removed from the series.
432 This signal is emitted when \a slices has been removed from the series.
433
433
434 \sa remove(), clear()
434 \sa remove(), clear()
435 */
435 */
436
436
437 /*!
437 /*!
438 \fn void QPieSeries::piePositionChanged()
438 \fn void QPieSeries::piePositionChanged()
439
439
440 This signal is emitted when pie position has changed.
440 This signal is emitted when pie position has changed.
441
441
442 \sa verticalPosition(), setVerticalPosition(), horizontalPosition(), setHorizontalPosition()
442 \sa verticalPosition(), setVerticalPosition(), horizontalPosition(), setHorizontalPosition()
443 */
443 */
444
444
445 /*!
445 /*!
446 \fn void QPieSeries::pieSizeChanged()
446 \fn void QPieSeries::pieSizeChanged()
447
447
448 This signal is emitted when pie size has changed.
448 This signal is emitted when pie size has changed.
449
449
450 \sa pieSize(), setPieSize()
450 \sa pieSize(), setPieSize()
451 */
451 */
452
452
453 /*!
453 /*!
454 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
454 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
455 Sets the \a model to be used as a data source
455 Sets the \a model to be used as a data source
456 */
456 */
457 bool QPieSeries::setModel(QAbstractItemModel* model)
457 bool QPieSeries::setModel(QAbstractItemModel* model)
458 {
458 {
459 Q_D(QPieSeries);
459 Q_D(QPieSeries);
460 // disconnect signals from old model
460 // disconnect signals from old model
461 if(d->m_model)
461 if(d->m_model)
462 {
462 {
463 disconnect(d->m_model, 0, this, 0);
463 disconnect(d->m_model, 0, this, 0);
464 d->m_mapValues = -1;
464 d->m_mapValues = -1;
465 d->m_mapLabels = -1;
465 d->m_mapLabels = -1;
466 d->m_mapOrientation = Qt::Vertical;
466 d->m_mapOrientation = Qt::Vertical;
467 }
467 }
468
468
469 // set new model
469 // set new model
470 if(model)
470 if(model)
471 {
471 {
472 d->m_model = model;
472 d->m_model = model;
473 return true;
473 return true;
474 }
474 }
475 else
475 else
476 {
476 {
477 d->m_model = 0;
477 d->m_model = 0;
478 return false;
478 return false;
479 }
479 }
480 }
480 }
481
481
482 /*!
482 /*!
483 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
483 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
484 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
484 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
485 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
485 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
486 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
486 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
487 The \a orientation paramater specifies whether the data is in columns or in rows.
487 The \a orientation parameter specifies whether the data is in columns or in rows.
488 */
488 */
489 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
489 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
490 {
490 {
491 Q_D(QPieSeries);
491 Q_D(QPieSeries);
492
492
493 if (d->m_model == 0)
493 if (d->m_model == 0)
494 return;
494 return;
495
495
496 d->m_mapValues = modelValuesLine;
496 d->m_mapValues = modelValuesLine;
497 d->m_mapLabels = modelLabelsLine;
497 d->m_mapLabels = modelLabelsLine;
498 d->m_mapOrientation = orientation;
498 d->m_mapOrientation = orientation;
499
499
500 // connect the signals
500 // connect the signals
501 if (d->m_mapOrientation == Qt::Vertical) {
501 if (d->m_mapOrientation == Qt::Vertical) {
502 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
502 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
503 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
503 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
504 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
504 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
505 } else {
505 } else {
506 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
506 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
507 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
507 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
508 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
508 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
509 }
509 }
510
510
511 // create the initial slices set
511 // create the initial slices set
512 if (d->m_mapOrientation == Qt::Vertical) {
512 if (d->m_mapOrientation == Qt::Vertical) {
513 for (int i = 0; i < d->m_model->rowCount(); i++)
513 for (int i = 0; i < d->m_model->rowCount(); i++)
514 append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
514 append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
515 } else {
515 } else {
516 for (int i = 0; i < d->m_model->columnCount(); i++)
516 for (int i = 0; i < d->m_model->columnCount(); i++)
517 append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
517 append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
518 }
518 }
519 }
519 }
520
520
521 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
521 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
522
522
523
523
524 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
524 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
525 :QSeriesPrivate(parent),
525 :QSeriesPrivate(parent),
526 m_pieRelativeHorPos(0.5),
526 m_pieRelativeHorPos(0.5),
527 m_pieRelativeVerPos(0.5),
527 m_pieRelativeVerPos(0.5),
528 m_pieRelativeSize(0.7),
528 m_pieRelativeSize(0.7),
529 m_pieStartAngle(0),
529 m_pieStartAngle(0),
530 m_pieEndAngle(360),
530 m_pieEndAngle(360),
531 m_sum(0),
531 m_sum(0),
532 m_mapValues(0),
532 m_mapValues(0),
533 m_mapLabels(0),
533 m_mapLabels(0),
534 m_mapOrientation(Qt::Horizontal)
534 m_mapOrientation(Qt::Horizontal)
535 {
535 {
536
536
537 }
537 }
538
538
539 QPieSeriesPrivate::~QPieSeriesPrivate()
539 QPieSeriesPrivate::~QPieSeriesPrivate()
540 {
540 {
541
541
542 }
542 }
543
543
544 void QPieSeriesPrivate::updateDerivativeData()
544 void QPieSeriesPrivate::updateDerivativeData()
545 {
545 {
546 m_sum = 0;
546 m_sum = 0;
547
547
548 // nothing to do?
548 // nothing to do?
549 if (m_slices.count() == 0)
549 if (m_slices.count() == 0)
550 return;
550 return;
551
551
552 // calculate sum of all slices
552 // calculate sum of all slices
553 foreach (QPieSlice* s, m_slices)
553 foreach (QPieSlice* s, m_slices)
554 m_sum += s->value();
554 m_sum += s->value();
555
555
556 // nothing to show..
556 // nothing to show..
557 if (qFuzzyIsNull(m_sum))
557 if (qFuzzyIsNull(m_sum))
558 return;
558 return;
559
559
560 // update slice attributes
560 // update slice attributes
561 qreal sliceAngle = m_pieStartAngle;
561 qreal sliceAngle = m_pieStartAngle;
562 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
562 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
563 QVector<QPieSlice*> changed;
563 QVector<QPieSlice*> changed;
564 foreach (QPieSlice* s, m_slices) {
564 foreach (QPieSlice* s, m_slices) {
565
565
566 PieSliceData data = PieSliceData::data(s);
566 PieSliceData data = PieSliceData::data(s);
567 data.m_percentage = s->value() / m_sum;
567 data.m_percentage = s->value() / m_sum;
568 data.m_angleSpan = pieSpan * data.m_percentage;
568 data.m_angleSpan = pieSpan * data.m_percentage;
569 data.m_startAngle = sliceAngle;
569 data.m_startAngle = sliceAngle;
570 sliceAngle += data.m_angleSpan;
570 sliceAngle += data.m_angleSpan;
571
571
572 if (PieSliceData::data(s) != data) {
572 if (PieSliceData::data(s) != data) {
573 PieSliceData::data(s) = data;
573 PieSliceData::data(s) = data;
574 changed << s;
574 changed << s;
575 }
575 }
576 }
576 }
577
577
578 // emit signals
578 // emit signals
579 foreach (QPieSlice* s, changed)
579 foreach (QPieSlice* s, changed)
580 PieSliceData::data(s).emitChangedSignal(s);
580 PieSliceData::data(s).emitChangedSignal(s);
581 }
581 }
582
582
583 void QPieSeriesPrivate::sliceChanged()
583 void QPieSeriesPrivate::sliceChanged()
584 {
584 {
585 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
585 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
586 updateDerivativeData();
586 updateDerivativeData();
587 }
587 }
588
588
589 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
589 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
590 {
590 {
591 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
591 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
592 Q_ASSERT(m_slices.contains(slice));
592 Q_ASSERT(m_slices.contains(slice));
593 Q_Q(QPieSeries);
593 Q_Q(QPieSeries);
594 emit q->clicked(slice, buttons);
594 emit q->clicked(slice, buttons);
595 }
595 }
596
596
597 void QPieSeriesPrivate::sliceHoverEnter()
597 void QPieSeriesPrivate::sliceHoverEnter()
598 {
598 {
599 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
599 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
600 Q_ASSERT(m_slices.contains(slice));
600 Q_ASSERT(m_slices.contains(slice));
601 Q_Q(QPieSeries);
601 Q_Q(QPieSeries);
602 emit q->hoverEnter(slice);
602 emit q->hoverEnter(slice);
603 }
603 }
604
604
605 void QPieSeriesPrivate::sliceHoverLeave()
605 void QPieSeriesPrivate::sliceHoverLeave()
606 {
606 {
607 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
607 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
608 Q_ASSERT(m_slices.contains(slice));
608 Q_ASSERT(m_slices.contains(slice));
609 Q_Q(QPieSeries);
609 Q_Q(QPieSeries);
610 emit q->hoverLeave(slice);
610 emit q->hoverLeave(slice);
611 }
611 }
612
612
613 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
613 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
614 {
614 {
615 Q_UNUSED(bottomRight)
615 Q_UNUSED(bottomRight)
616
616
617 if (m_mapOrientation == Qt::Vertical)
617 if (m_mapOrientation == Qt::Vertical)
618 {
618 {
619 if (topLeft.column() == m_mapValues)
619 if (topLeft.column() == m_mapValues)
620 if (m_mapValues == m_mapLabels)
620 if (m_mapValues == m_mapLabels)
621 {
621 {
622 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
622 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
623 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
623 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
624 }
624 }
625 else
625 else
626 {
626 {
627 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
627 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
628 }
628 }
629 else if (topLeft.column() == m_mapLabels)
629 else if (topLeft.column() == m_mapLabels)
630 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
630 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
631 }
631 }
632 else
632 else
633 {
633 {
634 if (topLeft.row() == m_mapValues)
634 if (topLeft.row() == m_mapValues)
635 if (m_mapValues == m_mapLabels)
635 if (m_mapValues == m_mapLabels)
636 {
636 {
637 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
637 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
638 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
638 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
639 }
639 }
640 else
640 else
641 {
641 {
642 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
642 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
643 }
643 }
644 else if (topLeft.row() == m_mapLabels)
644 else if (topLeft.row() == m_mapLabels)
645 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
645 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
646 }
646 }
647 }
647 }
648
648
649 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
649 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
650 {
650 {
651 Q_UNUSED(parent)
651 Q_UNUSED(parent)
652 Q_UNUSED(end)
652 Q_UNUSED(end)
653 Q_Q(QPieSeries);
653 Q_Q(QPieSeries);
654
654
655 QPieSlice* newSlice = new QPieSlice;
655 QPieSlice* newSlice = new QPieSlice;
656 newSlice->setLabelVisible(true);
656 newSlice->setLabelVisible(true);
657 if (m_mapOrientation == Qt::Vertical)
657 if (m_mapOrientation == Qt::Vertical)
658 {
658 {
659 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
659 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
660 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
660 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
661 }
661 }
662 else
662 else
663 {
663 {
664 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
664 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
665 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
665 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
666 }
666 }
667
667
668 q->insert(start, newSlice);
668 q->insert(start, newSlice);
669 }
669 }
670
670
671 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
671 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
672 {
672 {
673 Q_UNUSED(parent)
673 Q_UNUSED(parent)
674 Q_UNUSED(end)
674 Q_UNUSED(end)
675 Q_Q(QPieSeries);
675 Q_Q(QPieSeries);
676 q->remove(m_slices.at(start));
676 q->remove(m_slices.at(start));
677 }
677 }
678
678
679 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
679 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
680 {
680 {
681 // Remove rounding errors
681 // Remove rounding errors
682 qreal roundedValue = newValue;
682 qreal roundedValue = newValue;
683 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
683 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
684 roundedValue = 0.0;
684 roundedValue = 0.0;
685 else if (qFuzzyCompare(newValue, max))
685 else if (qFuzzyCompare(newValue, max))
686 roundedValue = max;
686 roundedValue = max;
687 else if (qFuzzyCompare(newValue, min))
687 else if (qFuzzyCompare(newValue, min))
688 roundedValue = min;
688 roundedValue = min;
689
689
690 // Check if the position is valid after removing the rounding errors
690 // Check if the position is valid after removing the rounding errors
691 if (roundedValue < min || roundedValue > max) {
691 if (roundedValue < min || roundedValue > max) {
692 qWarning("QPieSeries: Illegal value");
692 qWarning("QPieSeries: Illegal value");
693 return false;
693 return false;
694 }
694 }
695
695
696 if (!qFuzzyIsNull(value - roundedValue)) {
696 if (!qFuzzyIsNull(value - roundedValue)) {
697 value = roundedValue;
697 value = roundedValue;
698 return true;
698 return true;
699 }
699 }
700
700
701 // The change was so small it is considered a rounding error
701 // The change was so small it is considered a rounding error
702 return false;
702 return false;
703 }
703 }
704
704
705 void QPieSeriesPrivate::scaleDomain(Domain& domain)
705 void QPieSeriesPrivate::scaleDomain(Domain& domain)
706 {
706 {
707 Q_UNUSED(domain);
707 Q_UNUSED(domain);
708 #ifndef QT_NO_DEBUG
708 #ifndef QT_NO_DEBUG
709 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
709 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
710 #endif
710 #endif
711 }
711 }
712
712
713 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
713 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
714 {
714 {
715 Q_Q(QPieSeries);
715 Q_Q(QPieSeries);
716 PieChartItem* pie = new PieChartItem(q,presenter);
716 PieChartItem* pie = new PieChartItem(q,presenter);
717 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
717 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
718 presenter->animator()->addAnimation(pie);
718 presenter->animator()->addAnimation(pie);
719 }
719 }
720 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
720 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
721 return pie;
721 return pie;
722 }
722 }
723
723
724 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
724 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
725 {
725 {
726 Q_Q(QPieSeries);
726 Q_Q(QPieSeries);
727 QList<LegendMarker*> markers;
727 QList<LegendMarker*> markers;
728 foreach(QPieSlice* slice, q->slices()) {
728 foreach(QPieSlice* slice, q->slices()) {
729 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
729 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
730 markers << marker;
730 markers << marker;
731 }
731 }
732 return markers;
732 return markers;
733 }
733 }
734
734
735 #include "moc_qpieseries.cpp"
735 #include "moc_qpieseries.cpp"
736 #include "moc_qpieseries_p.cpp"
736 #include "moc_qpieseries_p.cpp"
737
737
738 QTCOMMERCIALCHART_END_NAMESPACE
738 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,132 +1,133
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qseries.h"
21 #include "qseries.h"
22 #include "qseries_p.h"
22 #include "qseries_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 /*!
26 /*!
27 \class QSeries
27 \class QSeries
28 \brief Base class for all QtCommercial Chart series.
28 \brief Base class for all QtCommercial Chart series.
29 \mainclass
29 \mainclass
30
30
31 Usually you use the series type specific inherited classes instead of the base class.
31 Usually you use the series type specific inherited classes instead of the base class.
32 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QBarSeries, QStackedBarSeries,
32 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QBarSeries, QStackedBarSeries,
33 QPercentBarSeries, QPieSeries
33 QPercentBarSeries, QPieSeries
34 */
34 */
35
35
36 /*!
36 /*!
37 \enum QSeries::QSeriesType
37 \enum QSeries::QSeriesType
38
38
39 The type of the series object.
39 The type of the series object.
40
40
41 \value SeriesTypeLine
41 \value SeriesTypeLine
42 \value SeriesTypeArea
42 \value SeriesTypeArea
43 \value SeriesTypeBar
43 \value SeriesTypeBar
44 \value SeriesTypeStackedBar
44 \value SeriesTypeStackedBar
45 \value SeriesTypePercentBar
45 \value SeriesTypePercentBar
46 \value SeriesTypePie
46 \value SeriesTypePie
47 \value SeriesTypeScatter
47 \value SeriesTypeScatter
48 \value SeriesTypeSpline
48 \value SeriesTypeSpline
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn QSeriesType QSeries::type() const
52 \fn QSeriesType QSeries::type() const
53 \brief The type of the series.
53 \brief The type of the series.
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn bool QSeries::setModel(QAbstractItemModel *model)
57 \fn bool QSeries::setModel(QAbstractItemModel *model)
58 \brief Use the \a model to provide data for the series. The model overrides possible user data
58 \brief Use the \a model to provide data for the series. The model overrides possible user data
59 set with QChartSeries type specific data setters. For example if you call both
59 set with QChartSeries type specific data setters. For example if you call both
60 QScatterSeries::addData() and QScatterSeries::setModel, only the data provided by the model is
60 QScatterSeries::addData() and QScatterSeries::setModel, only the data provided by the model is
61 used by the series. Returns true if the model is valid for the series.
61 used by the series. Returns true if the model is valid for the series.
62 */
62 */
63
63
64 /*!
64 /*!
65 \property QSeries::name
65 \property QSeries::name
66 \brief name of the series property
66 \brief name of the series property
67 */
67 */
68
68
69 /*!
69 /*!
70 \fn void QSeries::setName(const QString& name)
70 \fn void QSeries::setName(const QString& name)
71 \brief Sets a \a name for the series.
71 \brief Sets a \a name for the series.
72
72
73 The name of a series is shown in the legend for QXYSeries.
73 The name of a series is shown in the legend for QXYSeries.
74 \sa QChart::setTitle()
74 \sa QChart::setTitle()
75 \sa QPieSlice::setLabel()
75 \sa QPieSlice::setLabel()
76 \sa QBarSet::setName()
76 \sa QBarSet::setName()
77 */
77 */
78
78
79 /*!
79 /*!
80 \internal
80 \internal
81 \brief Constructs ChartSeries object with \a parent.
81 \brief Constructs ChartSeries object with \a parent.
82 */
82 */
83 QSeries::QSeries(QSeriesPrivate &d, QObject *parent) :
83 QSeries::QSeries(QSeriesPrivate &d, QObject *parent) :
84 QObject(parent),
84 QObject(parent),
85 d_ptr(&d)
85 d_ptr(&d)
86 {
86 {
87 }
87 }
88
88
89 /*!
89 /*!
90 \brief Virtual destructor for the chart series.
90 \brief Virtual destructor for the chart series.
91 */
91 */
92 QSeries::~QSeries()
92 QSeries::~QSeries()
93 {
93 {
94 }
94 }
95
95
96 /*!
96 /*!
97 \brief Returns the pointer to the model that is used as the series data source
97 \brief Returns the pointer to the model that is used as the series data source
98 */
98 */
99 QAbstractItemModel* QSeries::model() const
99 QAbstractItemModel* QSeries::model() const
100 {
100 {
101 return d_ptr->m_model;
101 return d_ptr->m_model;
102 }
102 }
103
103
104 void QSeries::setName(const QString& name)
104 void QSeries::setName(const QString& name)
105 {
105 {
106 d_ptr->m_name = name;
106 d_ptr->m_name = name;
107 }
107 }
108
108
109 /*!
109 /*!
110 \brief Returns the name of the series.
110 \brief Returns the name of the series.
111 \sa setName()
111 \sa setName()
112 */
112 */
113 QString QSeries::name() const
113 QString QSeries::name() const
114 {
114 {
115 return d_ptr->m_name;
115 return d_ptr->m_name;
116 }
116 }
117
117
118 ///////////////////////////////////////////////////////////////////////////////////////////////////
118 ///////////////////////////////////////////////////////////////////////////////////////////////////
119
119
120 QSeriesPrivate::QSeriesPrivate(QSeries* q): q_ptr(q),m_model(0)
120 QSeriesPrivate::QSeriesPrivate(QSeries* q): q_ptr(q),m_model(0)
121 {
121 {
122 }
122 }
123
123
124 QSeriesPrivate::~QSeriesPrivate()
124 QSeriesPrivate::~QSeriesPrivate()
125 {
125 {
126 }
126 }
127
127
128 #include "moc_qseries.cpp"
128 #include "moc_qseries.cpp"
129 #include "moc_qseries_p.cpp"
129
130
130 QTCOMMERCIALCHART_END_NAMESPACE
131 QTCOMMERCIALCHART_END_NAMESPACE
131
132
132
133
@@ -1,65 +1,66
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QSERIES_P_H
30 #ifndef QSERIES_P_H
31 #define QSERIES_P_H
31 #define QSERIES_P_H
32
32
33 #include "qseries.h"
33 #include "qseries.h"
34
34
35 class QAbstractItemModel;
35 class QAbstractItemModel;
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class Domain;
39 class Domain;
40 class ChartPresenter;
40 class ChartPresenter;
41 class Chart;
41 class Chart;
42 class LegendMarker;
42 class LegendMarker;
43 class QLegend;
43 class QLegend;
44
44
45 class QSeriesPrivate : public QObject
45 class QSeriesPrivate : public QObject
46 {
46 {
47 Q_OBJECT
47 public:
48 public:
48 QSeriesPrivate(QSeries *q);
49 QSeriesPrivate(QSeries *q);
49 ~QSeriesPrivate();
50 ~QSeriesPrivate();
50
51
51 virtual void scaleDomain(Domain& domain) = 0;
52 virtual void scaleDomain(Domain& domain) = 0;
52 virtual Chart* createGraphics(ChartPresenter* presenter) = 0;
53 virtual Chart* createGraphics(ChartPresenter* presenter) = 0;
53 virtual QList<LegendMarker*> createLegendMarker(QLegend* legend) = 0;
54 virtual QList<LegendMarker*> createLegendMarker(QLegend* legend) = 0;
54
55
55 protected:
56 protected:
56 QSeries *q_ptr;
57 QSeries *q_ptr;
57 QAbstractItemModel *m_model;
58 QAbstractItemModel *m_model;
58 QString m_name;
59 QString m_name;
59
60
60 friend class QSeries;
61 friend class QSeries;
61 };
62 };
62
63
63 QTCOMMERCIALCHART_END_NAMESPACE
64 QTCOMMERCIALCHART_END_NAMESPACE
64
65
65 #endif
66 #endif
@@ -1,248 +1,250
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scroller_p.h"
21 #include "scroller_p.h"
22 #include "qlegend.h"
22 #include "qlegend.h"
23 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsSceneMouseEvent>
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 Scroller::Scroller():
27 Scroller::Scroller():
28 m_ticker(this),
28 m_ticker(this),
29 m_state(Idle),
29 m_state(Idle),
30 m_moveThreshold(10),
30 m_moveThreshold(10),
31 m_timeTreshold(50)
31 m_timeTreshold(50)
32 {
32 {
33
33
34 }
34 }
35
35
36 Scroller::~Scroller()
36 Scroller::~Scroller()
37 {
37 {
38 }
38 }
39
39
40 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
40 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
41 {
41 {
42 if (event->button() == Qt::LeftButton) {
42 if (event->button() == Qt::LeftButton) {
43
43
44 switch (m_state) {
44 switch (m_state) {
45 case Idle:
45 case Idle:
46 {
46 {
47 m_state = Pressed;
47 m_state = Pressed;
48 m_offset = offset();
48 m_offset = offset();
49 m_press = event->pos();
49 m_press = event->pos();
50 m_timeStamp = QTime::currentTime();
50 m_timeStamp = QTime::currentTime();
51 event->accept();
51 event->accept();
52 break;
52 break;
53 }
53 }
54 case Scroll:
54 case Scroll:
55 {
55 {
56 m_state = Stop;
56 m_state = Stop;
57 m_speed = QPoint(0, 0);
57 m_speed = QPoint(0, 0);
58 m_offset = offset();
58 m_offset = offset();
59 m_press = event->pos();
59 m_press = event->pos();
60 event->accept();
60 event->accept();
61 break;
61 break;
62 }
62 }
63 case Pressed:
63 case Pressed:
64 case Move:
64 case Move:
65 case Stop:
65 case Stop:
66 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
66 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
67 event->ignore();
67 event->ignore();
68 break;
68 break;
69 }
69 }
70 }
70 }
71 }
71 }
72
72
73 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
73 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
74 {
74 {
75 QPointF delta = event->pos() - m_press;
75 QPointF delta = event->pos() - m_press;
76
76
77 switch (m_state) {
77 switch (m_state) {
78 case Pressed:
78 case Pressed:
79 case Stop:
79 case Stop:
80 {
80 {
81 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
81 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
82 m_state = Move;
82 m_state = Move;
83 m_timeStamp = QTime::currentTime();
83 m_timeStamp = QTime::currentTime();
84 m_distance = QPointF(0, 0);
84 m_distance = QPointF(0, 0);
85 m_press = event->pos();
85 m_press = event->pos();
86 event->accept();
86 event->accept();
87 break;
87 break;
88 }
88 }
89 else {
89 else {
90 event->ignore();
90 event->ignore();
91 break;
91 break;
92 }
92 }
93 }
93 }
94 case Move:
94 case Move:
95 {
95 {
96 setOffset(m_offset - delta);
96 setOffset(m_offset - delta);
97 calculateSpeed(event->pos());
97 calculateSpeed(event->pos());
98 event->accept();
98 event->accept();
99 break;
99 break;
100 }
100 }
101 case Idle:
101 case Idle:
102 case Scroll:
102 case Scroll:
103 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
103 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
104 event->ignore();
104 event->ignore();
105 break;
105 break;
106 }
106 }
107
107
108 }
108 }
109
109
110 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
110 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
111 {
111 {
112 if (event->button() == Qt::LeftButton) {
112 if (event->button() == Qt::LeftButton) {
113
113
114 switch (m_state) {
114 switch (m_state) {
115
115
116 case Scroll:
116 case Scroll:
117 m_state = Stop;
117 m_state = Stop;
118 m_speed = QPointF(0, 0);
118 m_speed = QPointF(0, 0);
119 m_offset = offset();
119 m_offset = offset();
120 event->accept();
120 event->accept();
121 break;
121 break;
122 case Pressed:
122 case Pressed:
123 {
123 {
124 m_state = Idle;
124 m_state = Idle;
125 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
125 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
126
126
127 //emit clicked(m_offset.toPoint());
127 //emit clicked(m_offset.toPoint());
128 //}
128 //}
129 event->accept();
129 event->accept();
130 break;
130 break;
131 }
131 }
132 case Move:
132 case Move:
133 {
133 {
134 calculateSpeed(event->pos());
134 calculateSpeed(event->pos());
135 m_offset = offset();
135 m_offset = offset();
136 m_press = event->pos();
136 m_press = event->pos();
137 if (m_speed == QPointF(0, 0)) {
137 if (m_speed == QPointF(0, 0)) {
138 m_state = Idle;
138 m_state = Idle;
139 }
139 }
140 else {
140 else {
141 m_speed /= 4;
141 m_speed /= 4;
142 m_state = Scroll;
142 m_state = Scroll;
143 m_ticker.start(20);
143 m_ticker.start(20);
144 }
144 }
145 event->accept();
145 event->accept();
146 break;
146 break;
147 }
147 }
148
148
149 case Stop:
149 case Stop:
150 case Idle:
150 case Idle:
151 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
151 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
152 event->ignore();
152 event->ignore();
153 break;
153 break;
154
154
155 }
155 }
156 }
156 }
157 }
157 }
158
158
159 void Scroller::scrollTick()
159 void Scroller::scrollTick()
160 {
160 {
161 switch (m_state) {
161 switch (m_state) {
162 case Scroll:
162 case Scroll:
163 {
163 {
164 lowerSpeed(m_speed);
164 lowerSpeed(m_speed);
165 setOffset(m_offset - m_speed);
165 setOffset(m_offset - m_speed);
166 m_offset = offset();
166 m_offset = offset();
167 if (m_speed == QPointF(0, 0)) {
167 if (m_speed == QPointF(0, 0)) {
168 m_state = Idle;
168 m_state = Idle;
169 m_ticker.stop();
169 m_ticker.stop();
170 }
170 }
171 break;
171 break;
172 }
172 }
173 case Stop:
173 case Stop:
174 m_ticker.stop();
174 m_ticker.stop();
175 break;
175 break;
176 case Idle:
176 case Idle:
177 case Move:
177 case Move:
178 case Pressed:
178 case Pressed:
179 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
179 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
180 m_ticker.stop();
180 m_ticker.stop();
181 break;
181 break;
182
182
183 }
183 }
184 }
184 }
185
185
186 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
186 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
187 {
187 {
188 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
188 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
189 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
189 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
190
190
191 x = (x == 0) ? x :
191 x = (x == 0) ? x :
192 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
192 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
193 y = (y == 0) ? y :
193 y = (y == 0) ? y :
194 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
194 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
195 speed.setX(x);
195 speed.setX(x);
196 speed.setY(y);
196 speed.setY(y);
197 }
197 }
198
198
199 void Scroller::calculateSpeed(const QPointF& position)
199 void Scroller::calculateSpeed(const QPointF& position)
200 {
200 {
201 if (m_timeStamp.elapsed() > m_timeTreshold) {
201 if (m_timeStamp.elapsed() > m_timeTreshold) {
202
202
203 QPointF distance = position - m_press;
203 QPointF distance = position - m_press;
204
204
205 m_timeStamp = QTime::currentTime();
205 m_timeStamp = QTime::currentTime();
206 m_speed = distance - m_distance;
206 m_speed = distance - m_distance;
207 m_distance = distance;
207 m_distance = distance;
208
208
209 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
209 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
210
210
211 if (fraction != 0) {
211 if (fraction != 0) {
212 m_fraction.setX(qAbs(m_speed.x() / fraction));
212 m_fraction.setX(qAbs(m_speed.x() / fraction));
213 m_fraction.setY(qAbs(m_speed.y() / fraction));
213 m_fraction.setY(qAbs(m_speed.y() / fraction));
214 }
214 }
215 else {
215 else {
216 m_fraction.setX(1);
216 m_fraction.setX(1);
217 m_fraction.setY(1);
217 m_fraction.setY(1);
218 }
218 }
219 }
219 }
220 }
220 }
221
221
222 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
222 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223
223
224 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
224 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
225 m_scroller(scroller)
225 m_scroller(scroller)
226 {
226 {
227
227
228 }
228 }
229
229
230 void ScrollTicker::start(int interval)
230 void ScrollTicker::start(int interval)
231 {
231 {
232 if (!m_timer.isActive()){
232 if (!m_timer.isActive()){
233 m_timer.start(interval, this);
233 m_timer.start(interval, this);
234 }
234 }
235 }
235 }
236
236
237 void ScrollTicker::stop()
237 void ScrollTicker::stop()
238 {
238 {
239 m_timer.stop();
239 m_timer.stop();
240 }
240 }
241
241
242 void ScrollTicker::timerEvent(QTimerEvent *event)
242 void ScrollTicker::timerEvent(QTimerEvent *event)
243 {
243 {
244 Q_UNUSED(event);
244 Q_UNUSED(event);
245 m_scroller->scrollTick();
245 m_scroller->scrollTick();
246 }
246 }
247
247
248 #include "moc_scroller_p.cpp"
249
248 QTCOMMERCIALCHART_END_NAMESPACE
250 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,106 +1,107
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef SCROLLER_P_H
30 #ifndef SCROLLER_P_H
31 #define SCROLLER_P_H
31 #define SCROLLER_P_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include <QBasicTimer>
34 #include <QBasicTimer>
35 #include <QTime>
35 #include <QTime>
36 #include <QPointF>
36 #include <QPointF>
37
37
38 class QGraphicsSceneMouseEvent;
38 class QGraphicsSceneMouseEvent;
39
39
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41
41
42 class Scroller;
42 class Scroller;
43 class QLegend;
43 class QLegend;
44
44
45 class ScrollTicker : public QObject
45 class ScrollTicker : public QObject
46 {
46 {
47 Q_OBJECT
47 public:
48 public:
48 explicit ScrollTicker(Scroller *scroller,QObject *parent = 0);
49 explicit ScrollTicker(Scroller *scroller,QObject *parent = 0);
49 void start(int interval);
50 void start(int interval);
50 void stop();
51 void stop();
51 protected:
52 protected:
52 void timerEvent(QTimerEvent *event);
53 void timerEvent(QTimerEvent *event);
53
54
54 private:
55 private:
55 QBasicTimer m_timer;
56 QBasicTimer m_timer;
56 Scroller *m_scroller;
57 Scroller *m_scroller;
57 };
58 };
58
59
59 class Scroller
60 class Scroller
60 {
61 {
61 public:
62 public:
62 enum State {
63 enum State {
63 Idle,
64 Idle,
64 Pressed,
65 Pressed,
65 Move,
66 Move,
66 Scroll,
67 Scroll,
67 Stop
68 Stop
68 };
69 };
69
70
70 Scroller();
71 Scroller();
71 virtual ~Scroller();
72 virtual ~Scroller();
72
73
73 virtual void setOffset(const QPointF& point) = 0;
74 virtual void setOffset(const QPointF& point) = 0;
74 virtual QPointF offset() const = 0;
75 virtual QPointF offset() const = 0;
75
76
76 public:
77 public:
77 void scrollTick();
78 void scrollTick();
78
79
79
80
80 public:
81 public:
81 void mousePressEvent(QGraphicsSceneMouseEvent* event);
82 void mousePressEvent(QGraphicsSceneMouseEvent* event);
82 void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
83 void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
83 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
84 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
84
85
85 private:
86 private:
86 void calculateSpeed(const QPointF& position);
87 void calculateSpeed(const QPointF& position);
87 void lowerSpeed(QPointF& speed,qreal maxSpeed=100);
88 void lowerSpeed(QPointF& speed,qreal maxSpeed=100);
88
89
89 private:
90 private:
90 ScrollTicker m_ticker;
91 ScrollTicker m_ticker;
91 State m_state;
92 State m_state;
92 QTime m_timeStamp;
93 QTime m_timeStamp;
93 QPointF m_press;
94 QPointF m_press;
94 QPointF m_offset;
95 QPointF m_offset;
95 QPointF m_speed;
96 QPointF m_speed;
96 QPointF m_distance;
97 QPointF m_distance;
97 QPointF m_fraction;
98 QPointF m_fraction;
98 int m_moveThreshold;
99 int m_moveThreshold;
99 int m_timeTreshold;
100 int m_timeTreshold;
100
101
101
102
102 };
103 };
103
104
104 QTCOMMERCIALCHART_END_NAMESPACE
105 QTCOMMERCIALCHART_END_NAMESPACE
105
106
106 #endif /* SCROLLER_P_H_ */
107 #endif /* SCROLLER_P_H_ */
@@ -1,236 +1,236
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qsplineseries.h"
21 #include "qsplineseries.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "splinechartitem_p.h"
23 #include "splinechartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27
27
28 /*!
28 /*!
29 \class QSplineSeries
29 \class QSplineSeries
30 \brief Series type used to store data needed to draw a spline.
30 \brief Series type used to store data needed to draw a spline.
31
31
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
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
36 /*!
36 /*!
37 \fn QSeriesType QSplineSeries::type() const
37 \fn QSeriesType QSplineSeries::type() const
38 Returns the type of the series
38 Returns the type of the series
39 */
39 */
40
40
41 /*!
41 /*!
42 \fn QSeriesType QSplineSeries::controlPoint(int index) const
42 \fn QSeriesType QSplineSeries::controlPoint(int index) const
43 Returns the control point specified by \a index
43 Returns the control point specified by \a index
44 */
44 */
45
45
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47
47
48 /*!
48 /*!
49 Constructs empty series object which is a child of \a parent.
49 Constructs empty series object which is a child of \a parent.
50 When series object is added to QChartView or QChart instance then the ownerships is transfered.
50 When series object is added to QChartView or QChart instance then the ownerships is transferred.
51 */
51 */
52
52
53 QSplineSeries::QSplineSeries(QObject *parent) :
53 QSplineSeries::QSplineSeries(QObject *parent) :
54 QLineSeries(*new QSplineSeriesPrivate(this),parent)
54 QLineSeries(*new QSplineSeriesPrivate(this),parent)
55 {
55 {
56 }
56 }
57
57
58 QSeries::QSeriesType QSplineSeries::type() const
58 QSeries::QSeriesType QSplineSeries::type() const
59 {
59 {
60 return QSeries::SeriesTypeSpline;
60 return QSeries::SeriesTypeSpline;
61 }
61 }
62
62
63 QPointF QSplineSeries::controlPoint(int index) const
63 QPointF QSplineSeries::controlPoint(int index) const
64 {
64 {
65 Q_D(const QSplineSeries);
65 Q_D(const QSplineSeries);
66 return d->m_controlPoints[index];
66 return d->m_controlPoints[index];
67 }
67 }
68
68
69 void QSplineSeries::setModelMappingRange(int first, int count)
69 void QSplineSeries::setModelMappingRange(int first, int count)
70 {
70 {
71 Q_D(QSplineSeries);
71 Q_D(QSplineSeries);
72 QLineSeries::setModelMappingRange(first, count);
72 QLineSeries::setModelMappingRange(first, count);
73 d->calculateControlPoints();
73 d->calculateControlPoints();
74 }
74 }
75
75
76 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77
77
78 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
78 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
79 {
79 {
80 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
80 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
81 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
81 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
82 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
82 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
83 };
83 };
84
84
85 /*!
85 /*!
86 \internal
86 \internal
87 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
87 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
88 */
88 */
89 void QSplineSeriesPrivate::calculateControlPoints()
89 void QSplineSeriesPrivate::calculateControlPoints()
90 {
90 {
91
91
92 Q_Q(QSplineSeries);
92 Q_Q(QSplineSeries);
93 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
93 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
94 // CPOL License
94 // CPOL License
95
95
96 int n = q->count() - 1;
96 int n = q->count() - 1;
97 if (n == 1)
97 if (n == 1)
98 { // Special case: Bezier curve should be a straight line.
98 { // Special case: Bezier curve should be a straight line.
99 // firstControlPoints = new Point[1];
99 // firstControlPoints = new Point[1];
100 // 3P1 = 2P0 + P3
100 // 3P1 = 2P0 + P3
101 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
101 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
102
102
103 // P2 = 2P1 P0
103 // P2 = 2P1 P0
104 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
104 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
105 return;
105 return;
106 }
106 }
107
107
108 // Calculate first Bezier control points
108 // Calculate first Bezier control points
109 // Right hand side vector
109 // Right hand side vector
110 // Set of equations for P0 to Pn points.
110 // Set of equations for P0 to Pn points.
111 //
111 //
112 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
112 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
113 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
113 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
114 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
114 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
115 // | . . . . . . . . . . . . | | ... | | ... |
115 // | . . . . . . . . . . . . | | ... | | ... |
116 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
116 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
117 // | . . . . . . . . . . . . | | ... | | ... |
117 // | . . . . . . . . . . . . | | ... | | ... |
118 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
118 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
119 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
119 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
120 //
120 //
121 QList<qreal> rhs;
121 QList<qreal> rhs;
122 rhs.append(q->x(0) + 2 * q->x(1));
122 rhs.append(q->x(0) + 2 * q->x(1));
123
123
124 // Set right hand side X values
124 // Set right hand side X values
125 for (int i = 1; i < n - 1; ++i)
125 for (int i = 1; i < n - 1; ++i)
126 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
126 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
127
127
128 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
128 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
129 // Get first control points X-values
129 // Get first control points X-values
130 QList<qreal> xControl = getFirstControlPoints(rhs);
130 QList<qreal> xControl = getFirstControlPoints(rhs);
131 rhs[0] = q->y(0) + 2 * q->y(1);
131 rhs[0] = q->y(0) + 2 * q->y(1);
132
132
133 // Set right hand side Y values
133 // Set right hand side Y values
134 for (int i = 1; i < n - 1; ++i)
134 for (int i = 1; i < n - 1; ++i)
135 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
135 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
136
136
137 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
137 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
138 // Get first control points Y-values
138 // Get first control points Y-values
139 QList<qreal> yControl = getFirstControlPoints(rhs);
139 QList<qreal> yControl = getFirstControlPoints(rhs);
140
140
141 // Fill output arrays.
141 // Fill output arrays.
142 for (int i = 0; i < n; ++i) {
142 for (int i = 0; i < n; ++i) {
143 // First control point
143 // First control point
144 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
144 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
145 // Second control point
145 // Second control point
146 if (i < n - 1)
146 if (i < n - 1)
147 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
147 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
148 else
148 else
149 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
149 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
150 }
150 }
151 }
151 }
152
152
153 /*!
153 /*!
154 \internal
154 \internal
155 */
155 */
156 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
156 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
157 {
157 {
158 QList<qreal> x; // Solution vector.
158 QList<qreal> x; // Solution vector.
159 QList<qreal> tmp; // Temp workspace.
159 QList<qreal> tmp; // Temp workspace.
160
160
161 qreal b = 2.0;
161 qreal b = 2.0;
162 x.append(rhs[0] / b);
162 x.append(rhs[0] / b);
163 tmp.append(0);
163 tmp.append(0);
164 for (int i = 1; i < rhs.size(); i++) {
164 for (int i = 1; i < rhs.size(); i++) {
165 // Decomposition and forward substitution.
165 // Decomposition and forward substitution.
166 tmp.append(1 / b);
166 tmp.append(1 / b);
167 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
167 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
168 x.append((rhs[i] - x[i - 1]) / b);
168 x.append((rhs[i] - x[i - 1]) / b);
169 }
169 }
170 for (int i = 1; i < rhs.size(); i++)
170 for (int i = 1; i < rhs.size(); i++)
171 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
171 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
172
172
173 return x;
173 return x;
174 }
174 }
175
175
176 /*!
176 /*!
177 \internal
177 \internal
178 Updates the control points, besed on currently avaiable knots.
178 Updates the control points, besed on currently avaiable knots.
179 */
179 */
180 void QSplineSeriesPrivate::updateControlPoints()
180 void QSplineSeriesPrivate::updateControlPoints()
181 {
181 {
182 Q_Q(QSplineSeries);
182 Q_Q(QSplineSeries);
183 if (q->count() > 1) {
183 if (q->count() > 1) {
184 m_controlPoints.clear();
184 m_controlPoints.clear();
185 calculateControlPoints();
185 calculateControlPoints();
186 }
186 }
187 }
187 }
188
188
189 /*//!
189 /*//!
190 \fn bool QSplineSeries::setModel(QAbstractItemModel *model)
190 \fn bool QSplineSeries::setModel(QAbstractItemModel *model)
191 Sets the \a model to be used as a data source
191 Sets the \a model to be used as a data source
192 \sa setModelMapping(), setModelMappingRange()
192 \sa setModelMapping(), setModelMappingRange()
193 */
193 */
194 //bool QSplineSeries::setModel(QAbstractItemModel* model)
194 //bool QSplineSeries::setModel(QAbstractItemModel* model)
195 //{
195 //{
196 // QXYSeries::setModel(model);
196 // QXYSeries::setModel(model);
197 //// calculateControlPoints();
197 //// calculateControlPoints();
198 // return true;
198 // return true;
199 //}
199 //}
200
200
201 /*//!
201 /*//!
202 \fn bool QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
202 \fn bool QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
203 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
203 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
204 as a data source for y coordinate. The \a orientation paramater specifies whether the data
204 as a data source for y coordinate. The \a orientation parameter specifies whether the data
205 is in columns or in rows.
205 is in columns or in rows.
206 */
206 */
207 //void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
207 //void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
208 //{
208 //{
209 // QLineSeries::setModelMapping(modelX, modelY, orientation);
209 // QLineSeries::setModelMapping(modelX, modelY, orientation);
210 //// calculateControlPoints();
210 //// calculateControlPoints();
211 //}
211 //}
212
212
213 /*!
213 /*!
214 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
214 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
215 Allows limiting the model mapping.
215 Allows limiting the model mapping.
216 Parameter \a first specifies which element of the model should be used as a first one of the series.
216 Parameter \a first specifies which element of the model should be used as a first one of the series.
217 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
217 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
218 then all the items following \a first item in a model are used.
218 then all the items following \a first item in a model are used.
219 \sa setModel(), setModelMapping()
219 \sa setModel(), setModelMapping()
220 */
220 */
221
221
222 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
222 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
223 {
223 {
224 Q_Q(QSplineSeries);
224 Q_Q(QSplineSeries);
225 SplineChartItem* spline = new SplineChartItem(q,presenter);
225 SplineChartItem* spline = new SplineChartItem(q,presenter);
226 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
226 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
227 presenter->animator()->addAnimation(spline);
227 presenter->animator()->addAnimation(spline);
228 }
228 }
229 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
229 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
230 return spline;
230 return spline;
231 }
231 }
232
232
233 #include "moc_qsplineseries.cpp"
233 #include "moc_qsplineseries.cpp"
234 #include "moc_qsplineseries_p.cpp"
234 #include "moc_qsplineseries_p.cpp"
235
235
236 QTCOMMERCIALCHART_END_NAMESPACE
236 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,671 +1,671
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qxyseries.h"
21 #include "qxyseries.h"
22 #include "qxyseries_p.h"
22 #include "qxyseries_p.h"
23 #include "domain_p.h"
23 #include "domain_p.h"
24 #include "legendmarker_p.h"
24 #include "legendmarker_p.h"
25 #include <QAbstractItemModel>
25 #include <QAbstractItemModel>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 /*!
29 /*!
30 \class QXYSeries
30 \class QXYSeries
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
31 \brief The QXYSeries class is a base class for line, spline and scatter series.
32 */
32 */
33
33
34 /*!
34 /*!
35 \fn QPen QXYSeries::pen() const
35 \fn QPen QXYSeries::pen() const
36 \brief Returns pen used to draw points for series.
36 \brief Returns pen used to draw points for series.
37 \sa setPen()
37 \sa setPen()
38 */
38 */
39
39
40 /*!
40 /*!
41 \fn QBrush QXYSeries::brush() const
41 \fn QBrush QXYSeries::brush() const
42 \brief Returns brush used to draw points for series.
42 \brief Returns brush used to draw points for series.
43 \sa setBrush()
43 \sa setBrush()
44 */
44 */
45
45
46 /*!
46 /*!
47 \fn void QXYSeries::clicked(const QPointF& point)
47 \fn void QXYSeries::clicked(const QPointF& point)
48 \brief Signal is emitted when user clicks the \a point on chart.
48 \brief Signal is emitted when user clicks the \a point on chart.
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn void QXYSeries::selected()
52 \fn void QXYSeries::selected()
53
53
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
54 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
55 implemented by the user of QXYSeries API.
55 implemented by the user of QXYSeries API.
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
59 \fn void QXYSeriesPrivate::pointReplaced(int index)
60 \brief \internal \a index
60 \brief \internal \a index
61 */
61 */
62
62
63 /*!
63 /*!
64 \fn void QXYSeriesPrivate::pointAdded(int index)
64 \fn void QXYSeriesPrivate::pointAdded(int index)
65 \brief \internal \a index
65 \brief \internal \a index
66 */
66 */
67
67
68 /*!
68 /*!
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
69 \fn void QXYSeriesPrivate::pointRemoved(int index)
70 \brief \internal \a index
70 \brief \internal \a index
71 */
71 */
72
72
73 /*!
73 /*!
74 \fn void QXYSeriesPrivate::updated()
74 \fn void QXYSeriesPrivate::updated()
75 \brief \internal
75 \brief \internal
76 */
76 */
77
77
78 /*!
78 /*!
79 \fn int QXYSeries::mapFirst() const
79 \fn int QXYSeries::mapFirst() const
80 Returns the index of the model's item that is used as a first one for the series.
80 Returns the index of the model's item that is used as a first one for the series.
81 \sa mapCount()
81 \sa mapCount()
82 */
82 */
83
83
84 /*!
84 /*!
85 \fn int QXYSeries::mapCount() const
85 \fn int QXYSeries::mapCount() const
86 Returns the number of the items that are taken from the model.
86 Returns the number of the items that are taken from the model.
87 If -1 it means all the items of the model following the first one are used.
87 If -1 it means all the items of the model following the first one are used.
88 \sa mapFirst()
88 \sa mapFirst()
89 */
89 */
90
90
91 /*!
91 /*!
92 \internal
92 \internal
93
93
94 Constructs empty series object which is a child of \a parent.
94 Constructs empty series object which is a child of \a parent.
95 When series object is added to QChartView or QChart instance ownerships is transfered.
95 When series object is added to QChartView or QChart instance ownerships is transferred.
96 */
96 */
97 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent):QSeries(d,parent)
97 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent):QSeries(d,parent)
98 {
98 {
99
99
100 }
100 }
101 /*!
101 /*!
102 Destroys the object. Series added to QChartView or QChart instances are owned by those,
102 Destroys the object. Series added to QChartView or QChart instances are owned by those,
103 and are deleted when mentioned object are destroyed.
103 and are deleted when mentioned object are destroyed.
104 */
104 */
105 QXYSeries::~QXYSeries()
105 QXYSeries::~QXYSeries()
106 {
106 {
107 }
107 }
108
108
109 /*!
109 /*!
110 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
110 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
111 */
111 */
112 void QXYSeries::append(qreal x,qreal y)
112 void QXYSeries::append(qreal x,qreal y)
113 {
113 {
114 Q_D(QXYSeries);
114 Q_D(QXYSeries);
115 Q_ASSERT(d->m_x.size() == d->m_y.size());
115 Q_ASSERT(d->m_x.size() == d->m_y.size());
116 d->m_x<<x;
116 d->m_x<<x;
117 d->m_y<<y;
117 d->m_y<<y;
118 emit d->pointAdded(d->m_x.size()-1);
118 emit d->pointAdded(d->m_x.size()-1);
119 }
119 }
120
120
121 /*!
121 /*!
122 This is an overloaded function.
122 This is an overloaded function.
123 Adds data \a point to the series. Points are connected with lines on the chart.
123 Adds data \a point to the series. Points are connected with lines on the chart.
124 */
124 */
125 void QXYSeries::append(const QPointF &point)
125 void QXYSeries::append(const QPointF &point)
126 {
126 {
127 append(point.x(),point.y());
127 append(point.x(),point.y());
128 }
128 }
129
129
130 /*!
130 /*!
131 This is an overloaded function.
131 This is an overloaded function.
132 Adds list of data \a points to the series. Points are connected with lines on the chart.
132 Adds list of data \a points to the series. Points are connected with lines on the chart.
133 */
133 */
134 void QXYSeries::append(const QList<QPointF> points)
134 void QXYSeries::append(const QList<QPointF> points)
135 {
135 {
136 foreach(const QPointF& point , points) {
136 foreach(const QPointF& point , points) {
137 append(point.x(),point.y());
137 append(point.x(),point.y());
138 }
138 }
139 }
139 }
140
140
141 /*!
141 /*!
142 Modifies \a y value for given \a x a value.
142 Modifies \a y value for given \a x a value.
143 */
143 */
144 void QXYSeries::replace(qreal x,qreal y)
144 void QXYSeries::replace(qreal x,qreal y)
145 {
145 {
146 Q_D(QXYSeries);
146 Q_D(QXYSeries);
147 int index = d->m_x.indexOf(x);
147 int index = d->m_x.indexOf(x);
148 d->m_x[index] = x;
148 d->m_x[index] = x;
149 d->m_y[index] = y;
149 d->m_y[index] = y;
150 emit d->pointReplaced(index);
150 emit d->pointReplaced(index);
151 }
151 }
152
152
153 /*!
153 /*!
154 This is an overloaded function.
154 This is an overloaded function.
155 Replaces current y value of for given \a point x value with \a point y value.
155 Replaces current y value of for given \a point x value with \a point y value.
156 */
156 */
157 void QXYSeries::replace(const QPointF &point)
157 void QXYSeries::replace(const QPointF &point)
158 {
158 {
159 replace(point.x(),point.y());
159 replace(point.x(),point.y());
160 }
160 }
161
161
162 /*!
162 /*!
163 Removes first \a x value and related y value.
163 Removes first \a x value and related y value.
164 */
164 */
165 void QXYSeries::remove(qreal x)
165 void QXYSeries::remove(qreal x)
166 {
166 {
167 Q_D(QXYSeries);
167 Q_D(QXYSeries);
168 int index = d->m_x.indexOf(x);
168 int index = d->m_x.indexOf(x);
169
169
170 if (index == -1) return;
170 if (index == -1) return;
171
171
172 d->m_x.remove(index);
172 d->m_x.remove(index);
173 d->m_y.remove(index);
173 d->m_y.remove(index);
174
174
175 emit d->pointRemoved(index);
175 emit d->pointRemoved(index);
176 }
176 }
177
177
178 /*!
178 /*!
179 Removes current \a x and \a y value.
179 Removes current \a x and \a y value.
180 */
180 */
181 void QXYSeries::remove(qreal x,qreal y)
181 void QXYSeries::remove(qreal x,qreal y)
182 {
182 {
183 Q_D(QXYSeries);
183 Q_D(QXYSeries);
184 int index =-1;
184 int index =-1;
185 do {
185 do {
186 index = d->m_x.indexOf(x,index+1);
186 index = d->m_x.indexOf(x,index+1);
187 } while (index !=-1 && d->m_y.at(index)!=y);
187 } while (index !=-1 && d->m_y.at(index)!=y);
188
188
189 if (index==-1) return;
189 if (index==-1) return;
190
190
191 d->m_x.remove(index);
191 d->m_x.remove(index);
192 d->m_y.remove(index);
192 d->m_y.remove(index);
193 emit d->pointRemoved(index);
193 emit d->pointRemoved(index);
194 }
194 }
195
195
196 /*!
196 /*!
197 Removes current \a point x value. Note \a point y value is ignored.
197 Removes current \a point x value. Note \a point y value is ignored.
198 */
198 */
199 void QXYSeries::remove(const QPointF &point)
199 void QXYSeries::remove(const QPointF &point)
200 {
200 {
201 remove(point.x(),point.y());
201 remove(point.x(),point.y());
202 }
202 }
203
203
204 /*!
204 /*!
205 Removes all data points from the series.
205 Removes all data points from the series.
206 */
206 */
207 void QXYSeries::removeAll()
207 void QXYSeries::removeAll()
208 {
208 {
209 Q_D(QXYSeries);
209 Q_D(QXYSeries);
210 d->m_x.clear();
210 d->m_x.clear();
211 d->m_y.clear();
211 d->m_y.clear();
212 }
212 }
213
213
214 /*!
214 /*!
215 \internal \a pos
215 \internal \a pos
216 */
216 */
217 qreal QXYSeries::x(int pos) const
217 qreal QXYSeries::x(int pos) const
218 {
218 {
219 Q_D(const QXYSeries);
219 Q_D(const QXYSeries);
220 if (d->m_model) {
220 if (d->m_model) {
221 if (d->m_mapOrientation == Qt::Vertical)
221 if (d->m_mapOrientation == Qt::Vertical)
222 // consecutive data is read from model's column
222 // consecutive data is read from model's column
223 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapX), Qt::DisplayRole).toDouble();
223 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapX), Qt::DisplayRole).toDouble();
224 else
224 else
225 // consecutive data is read from model's row
225 // consecutive data is read from model's row
226 return d->m_model->data(d->m_model->index(d->m_mapX, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
226 return d->m_model->data(d->m_model->index(d->m_mapX, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
227 } else {
227 } else {
228 // model is not specified, return the data from series' internal data store
228 // model is not specified, return the data from series' internal data store
229 return d->m_x.at(pos);
229 return d->m_x.at(pos);
230 }
230 }
231 }
231 }
232
232
233 /*!
233 /*!
234 \internal \a pos
234 \internal \a pos
235 */
235 */
236 qreal QXYSeries::y(int pos) const
236 qreal QXYSeries::y(int pos) const
237 {
237 {
238 Q_D(const QXYSeries);
238 Q_D(const QXYSeries);
239 if (d->m_model) {
239 if (d->m_model) {
240 if (d->m_mapOrientation == Qt::Vertical)
240 if (d->m_mapOrientation == Qt::Vertical)
241 // consecutive data is read from model's column
241 // consecutive data is read from model's column
242 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapY), Qt::DisplayRole).toDouble();
242 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapY), Qt::DisplayRole).toDouble();
243 else
243 else
244 // consecutive data is read from model's row
244 // consecutive data is read from model's row
245 return d->m_model->data(d->m_model->index(d->m_mapY, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
245 return d->m_model->data(d->m_model->index(d->m_mapY, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
246 } else {
246 } else {
247 // model is not specified, return the data from series' internal data store
247 // model is not specified, return the data from series' internal data store
248 return d->m_y.at(pos);
248 return d->m_y.at(pos);
249 }
249 }
250 }
250 }
251
251
252 /*!
252 /*!
253 Returns number of data points within series.
253 Returns number of data points within series.
254 */
254 */
255 int QXYSeries::count() const
255 int QXYSeries::count() const
256 {
256 {
257 Q_D(const QXYSeries);
257 Q_D(const QXYSeries);
258
258
259 Q_ASSERT(d->m_x.size() == d->m_y.size());
259 Q_ASSERT(d->m_x.size() == d->m_y.size());
260
260
261 if (d->m_model) {
261 if (d->m_model) {
262 if (d->m_mapOrientation == Qt::Vertical) {
262 if (d->m_mapOrientation == Qt::Vertical) {
263 // data is in a column. Return the number of mapped items if the model's column have enough items
263 // data is in a column. Return the number of mapped items if the model's column have enough items
264 // or the number of items that can be mapped
264 // or the number of items that can be mapped
265 if (d->m_mapLimited)
265 if (d->m_mapLimited)
266 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
266 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
267 else
267 else
268 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
268 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
269 } else {
269 } else {
270 // data is in a row. Return the number of mapped items if the model's row have enough items
270 // data is in a row. Return the number of mapped items if the model's row have enough items
271 // or the number of items that can be mapped
271 // or the number of items that can be mapped
272 if (d->m_mapLimited)
272 if (d->m_mapLimited)
273 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
273 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
274 else
274 else
275 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
275 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
276 }
276 }
277 }
277 }
278
278
279 // model is not specified, return the number of points in the series internal data store
279 // model is not specified, return the number of points in the series internal data store
280 return d->m_x.size();
280 return d->m_x.size();
281 }
281 }
282
282
283 /*!
283 /*!
284 Returns the data points of the series.
284 Returns the data points of the series.
285 */
285 */
286 QList<QPointF> QXYSeries::data()
286 QList<QPointF> QXYSeries::data()
287 {
287 {
288 Q_D(QXYSeries);
288 Q_D(QXYSeries);
289 QList<QPointF> data;
289 QList<QPointF> data;
290 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
290 for (int i(0); i < d->m_x.count() && i < d->m_y.count(); i++)
291 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
291 data.append(QPointF(d->m_x.at(i), d->m_y.at(i)));
292 return data;
292 return data;
293 }
293 }
294
294
295
295
296 /*!
296 /*!
297 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
297 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
298 pen from chart theme is used.
298 pen from chart theme is used.
299 \sa QChart::setTheme()
299 \sa QChart::setTheme()
300 */
300 */
301 void QXYSeries::setPen(const QPen &pen)
301 void QXYSeries::setPen(const QPen &pen)
302 {
302 {
303 Q_D(QXYSeries);
303 Q_D(QXYSeries);
304 if (d->m_pen!=pen) {
304 if (d->m_pen!=pen) {
305 d->m_pen = pen;
305 d->m_pen = pen;
306 emit d->updated();
306 emit d->updated();
307 }
307 }
308 }
308 }
309
309
310 QPen QXYSeries::pen() const
310 QPen QXYSeries::pen() const
311 {
311 {
312 Q_D(const QXYSeries);
312 Q_D(const QXYSeries);
313 return d->m_pen;
313 return d->m_pen;
314 }
314 }
315
315
316 /*!
316 /*!
317 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
317 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
318 from chart theme setting is used.
318 from chart theme setting is used.
319 \sa QChart::setTheme()
319 \sa QChart::setTheme()
320 */
320 */
321 void QXYSeries::setBrush(const QBrush &brush)
321 void QXYSeries::setBrush(const QBrush &brush)
322 {
322 {
323 Q_D(QXYSeries);
323 Q_D(QXYSeries);
324 if (d->m_brush!=brush) {
324 if (d->m_brush!=brush) {
325 d->m_brush = brush;
325 d->m_brush = brush;
326 emit d->updated();
326 emit d->updated();
327 }
327 }
328 }
328 }
329
329
330 QBrush QXYSeries::brush() const
330 QBrush QXYSeries::brush() const
331 {
331 {
332 Q_D(const QXYSeries);
332 Q_D(const QXYSeries);
333 return d->m_brush;
333 return d->m_brush;
334 }
334 }
335
335
336
336
337 /*!
337 /*!
338 Sets if data points are \a visible and should be drawn on line.
338 Sets if data points are \a visible and should be drawn on line.
339 */
339 */
340 void QXYSeries::setPointsVisible(bool visible)
340 void QXYSeries::setPointsVisible(bool visible)
341 {
341 {
342 Q_D(QXYSeries);
342 Q_D(QXYSeries);
343 if (d->m_pointsVisible != visible){
343 if (d->m_pointsVisible != visible){
344 d->m_pointsVisible = visible;
344 d->m_pointsVisible = visible;
345 emit d->updated();
345 emit d->updated();
346 }
346 }
347 }
347 }
348
348
349 /*!
349 /*!
350 Returns true if drawing the data points of the series is enabled.
350 Returns true if drawing the data points of the series is enabled.
351 */
351 */
352 bool QXYSeries::pointsVisible() const
352 bool QXYSeries::pointsVisible() const
353 {
353 {
354 Q_D(const QXYSeries);
354 Q_D(const QXYSeries);
355 return d->m_pointsVisible;
355 return d->m_pointsVisible;
356 }
356 }
357
357
358
358
359 /*!
359 /*!
360 Stream operator for adding a data \a point to the series.
360 Stream operator for adding a data \a point to the series.
361 \sa append()
361 \sa append()
362 */
362 */
363 QXYSeries& QXYSeries::operator<< (const QPointF &point)
363 QXYSeries& QXYSeries::operator<< (const QPointF &point)
364 {
364 {
365 append(point);
365 append(point);
366 return *this;
366 return *this;
367 }
367 }
368
368
369
369
370 /*!
370 /*!
371 Stream operator for adding a list of \a points to the series.
371 Stream operator for adding a list of \a points to the series.
372 \sa append()
372 \sa append()
373 */
373 */
374
374
375 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
375 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
376 {
376 {
377 append(points);
377 append(points);
378 return *this;
378 return *this;
379 }
379 }
380
380
381 /*!
381 /*!
382 \internal
382 \internal
383 */
383 */
384 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
384 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
385 {
385 {
386 Q_UNUSED(bottomRight)
386 Q_UNUSED(bottomRight)
387 Q_D(QXYSeries);
387 Q_D(QXYSeries);
388 if (d->m_mapOrientation == Qt::Vertical) {
388 if (d->m_mapOrientation == Qt::Vertical) {
389 if (topLeft.row() >= d->m_mapFirst && (!d->m_mapLimited || topLeft.row() < d->m_mapFirst + d->m_mapCount))
389 if (topLeft.row() >= d->m_mapFirst && (!d->m_mapLimited || topLeft.row() < d->m_mapFirst + d->m_mapCount))
390 emit d->pointReplaced(topLeft.row() - d->m_mapFirst);
390 emit d->pointReplaced(topLeft.row() - d->m_mapFirst);
391 } else {
391 } else {
392 if (topLeft.column() >= d->m_mapFirst && (!d->m_mapLimited || topLeft.column() < d->m_mapFirst + d->m_mapCount))
392 if (topLeft.column() >= d->m_mapFirst && (!d->m_mapLimited || topLeft.column() < d->m_mapFirst + d->m_mapCount))
393 emit d->pointReplaced(topLeft.column() - d->m_mapFirst);
393 emit d->pointReplaced(topLeft.column() - d->m_mapFirst);
394 }
394 }
395 }
395 }
396
396
397 /*!
397 /*!
398 \internal
398 \internal
399 */
399 */
400 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
400 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
401 {
401 {
402 Q_UNUSED(parent)
402 Q_UNUSED(parent)
403 // Q_UNUSED(end)
403 // Q_UNUSED(end)
404 Q_D(QXYSeries);
404 Q_D(QXYSeries);
405 if (d->m_mapLimited) {
405 if (d->m_mapLimited) {
406 if (start >= d->m_mapFirst + d->m_mapCount) {
406 if (start >= d->m_mapFirst + d->m_mapCount) {
407 // the added data is below mapped area
407 // the added data is below mapped area
408 // therefore it has no relevance
408 // therefore it has no relevance
409 return;
409 return;
410 } else {
410 } else {
411 // the added data is in the mapped area or before it and update is needed
411 // the added data is in the mapped area or before it and update is needed
412
412
413 // check how many mapped items there is currently (before new items are added)
413 // check how many mapped items there is currently (before new items are added)
414 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
414 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
415 // internal storage before new ones can be added
415 // internal storage before new ones can be added
416
416
417 int itemsToRemove = qMin(count() - qMax(start - d->m_mapFirst, 0), end - start + 1);
417 int itemsToRemove = qMin(count() - qMax(start - d->m_mapFirst, 0), end - start + 1);
418 if (d->m_mapCount == count()) {
418 if (d->m_mapCount == count()) {
419 for (int i = 0; i < itemsToRemove; i++)
419 for (int i = 0; i < itemsToRemove; i++)
420 emit d->pointRemoved(qMin(end, count()) - i);
420 emit d->pointRemoved(qMin(end, count()) - i);
421 }
421 }
422 }
422 }
423 } else {
423 } else {
424 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
424 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
425 // nothing to do
425 // nothing to do
426 // emit pointAdded(qMax(start - m_mapFirst, 0));
426 // emit pointAdded(qMax(start - m_mapFirst, 0));
427 }
427 }
428 }
428 }
429
429
430 /*!
430 /*!
431 \internal
431 \internal
432 */
432 */
433 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
433 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
434 {
434 {
435 Q_UNUSED(parent)
435 Q_UNUSED(parent)
436 // Q_UNUSED(end)
436 // Q_UNUSED(end)
437 Q_D(QXYSeries);
437 Q_D(QXYSeries);
438 if (d->m_mapLimited) {
438 if (d->m_mapLimited) {
439 if (start >= d->m_mapFirst + d->m_mapCount) {
439 if (start >= d->m_mapFirst + d->m_mapCount) {
440 // the added data is below mapped area
440 // the added data is below mapped area
441 // therefore it has no relevance
441 // therefore it has no relevance
442 return;
442 return;
443 } else {
443 } else {
444 // the added data is in the mapped area or before it
444 // the added data is in the mapped area or before it
445 // update needed
445 // update needed
446 if (count() > 0) {
446 if (count() > 0) {
447 int toBeAdded = qMin(d->m_mapCount - (start - d->m_mapFirst), end - start + 1);
447 int toBeAdded = qMin(d->m_mapCount - (start - d->m_mapFirst), end - start + 1);
448 for (int i = 0; i < toBeAdded; i++)
448 for (int i = 0; i < toBeAdded; i++)
449 if (start + i >= d->m_mapFirst)
449 if (start + i >= d->m_mapFirst)
450 emit d->pointAdded(start + i);
450 emit d->pointAdded(start + i);
451 }
451 }
452 }
452 }
453 } else {
453 } else {
454 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
454 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
455 for (int i = 0; i < end - start + 1; i++)
455 for (int i = 0; i < end - start + 1; i++)
456 emit d->pointAdded(start + i);
456 emit d->pointAdded(start + i);
457 }
457 }
458 }
458 }
459
459
460 /*!
460 /*!
461 \internal
461 \internal
462 */
462 */
463 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
463 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
464 {
464 {
465 Q_UNUSED(parent)
465 Q_UNUSED(parent)
466 // Q_UNUSED(end)
466 // Q_UNUSED(end)
467 Q_D(QXYSeries);
467 Q_D(QXYSeries);
468 if (d->m_mapLimited) {
468 if (d->m_mapLimited) {
469 if (start >= d->m_mapFirst + d->m_mapCount) {
469 if (start >= d->m_mapFirst + d->m_mapCount) {
470 // the removed data is below mapped area
470 // the removed data is below mapped area
471 // therefore it has no relevance
471 // therefore it has no relevance
472 return;
472 return;
473 } else {
473 } else {
474 // the removed data is in the mapped area or before it
474 // the removed data is in the mapped area or before it
475 // update needed
475 // update needed
476
476
477 // check how many items need to be removed from the xychartitem storage
477 // check how many items need to be removed from the xychartitem storage
478 // the number equals the number of items that are removed and that lay before
478 // the number equals the number of items that are removed and that lay before
479 // or in the mapped area. Items that lay beyond the map do not count
479 // or in the mapped area. Items that lay beyond the map do not count
480 // the max is the current number of items in storage (count())
480 // the max is the current number of items in storage (count())
481 int itemsToRemove = qMin(count(), qMin(end, d->m_mapFirst + d->m_mapCount - 1) - start + 1);
481 int itemsToRemove = qMin(count(), qMin(end, d->m_mapFirst + d->m_mapCount - 1) - start + 1);
482 for (int i = 0; i < itemsToRemove; i++)
482 for (int i = 0; i < itemsToRemove; i++)
483 emit d->pointRemoved(start);
483 emit d->pointRemoved(start);
484 }
484 }
485 } else {
485 } else {
486 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
486 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
487 for (int i = 0; i < end - start + 1; i++)
487 for (int i = 0; i < end - start + 1; i++)
488 emit d->pointRemoved(start);
488 emit d->pointRemoved(start);
489 }
489 }
490 }
490 }
491
491
492 /*!
492 /*!
493 \internal
493 \internal
494 */
494 */
495 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
495 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
496 {
496 {
497
497
498 Q_UNUSED(parent)
498 Q_UNUSED(parent)
499 Q_UNUSED(end)
499 Q_UNUSED(end)
500 Q_D(QXYSeries);
500 Q_D(QXYSeries);
501 // how many items there were before data was removed
501 // how many items there were before data was removed
502 // int oldCount = count() - 1;
502 // int oldCount = count() - 1;
503
503
504 if (d->m_mapLimited) {
504 if (d->m_mapLimited) {
505 if (start >= d->m_mapFirst + d->m_mapCount) {
505 if (start >= d->m_mapFirst + d->m_mapCount) {
506 // the removed data is below mapped area
506 // the removed data is below mapped area
507 // therefore it has no relevance
507 // therefore it has no relevance
508 return;
508 return;
509 } else {
509 } else {
510 // if the current items count in the whole model is bigger than the index of the last item
510 // if the current items count in the whole model is bigger than the index of the last item
511 // that was removed than it means there are some extra items available
511 // that was removed than it means there are some extra items available
512
512
513 int removedItemsCount = qMin(count(), qMin(end, d->m_mapFirst + d->m_mapCount - 1) - start + 1);
513 int removedItemsCount = qMin(count(), qMin(end, d->m_mapFirst + d->m_mapCount - 1) - start + 1);
514 int extraItemsAvailable = 0;
514 int extraItemsAvailable = 0;
515 if (d->m_mapOrientation == Qt::Vertical) {
515 if (d->m_mapOrientation == Qt::Vertical) {
516 extraItemsAvailable = qMax(d->m_model->rowCount() + (end - start + 1) - qMax(end + 1, d->m_mapFirst + d->m_mapCount), 0);
516 extraItemsAvailable = qMax(d->m_model->rowCount() + (end - start + 1) - qMax(end + 1, d->m_mapFirst + d->m_mapCount), 0);
517 } else {
517 } else {
518 extraItemsAvailable = qMax(d->m_model->columnCount() + (end - start + 1) - qMax(end + 1, d->m_mapFirst + d->m_mapCount), 0);
518 extraItemsAvailable = qMax(d->m_model->columnCount() + (end - start + 1) - qMax(end + 1, d->m_mapFirst + d->m_mapCount), 0);
519 }
519 }
520
520
521 // if there are excess items available (below the mapped area) use them to repopulate mapped area
521 // if there are excess items available (below the mapped area) use them to repopulate mapped area
522 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
522 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
523 for (int k = 0; k < toBeAdded; k++)
523 for (int k = 0; k < toBeAdded; k++)
524 emit d->pointAdded(d->m_mapFirst + d->m_mapCount - removedItemsCount + k);
524 emit d->pointAdded(d->m_mapFirst + d->m_mapCount - removedItemsCount + k);
525 }
525 }
526 } else {
526 } else {
527 // data was removed from XYSeries interal storage. Nothing more to do
527 // data was removed from XYSeries interal storage. Nothing more to do
528 }
528 }
529 }
529 }
530
530
531 /*!
531 /*!
532 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
532 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
533 Sets the \a model to be used as a data source
533 Sets the \a model to be used as a data source
534 \sa setModelMapping(), setModelMappingRange()
534 \sa setModelMapping(), setModelMappingRange()
535 */
535 */
536 bool QXYSeries::setModel(QAbstractItemModel *model)
536 bool QXYSeries::setModel(QAbstractItemModel *model)
537 {
537 {
538 Q_D(QXYSeries);
538 Q_D(QXYSeries);
539 // disconnect signals from old model
539 // disconnect signals from old model
540 if (d->m_model) {
540 if (d->m_model) {
541 QObject::disconnect(d->m_model, 0, this, 0);
541 QObject::disconnect(d->m_model, 0, this, 0);
542 d->m_mapX = -1;
542 d->m_mapX = -1;
543 d->m_mapY = -1;
543 d->m_mapY = -1;
544 d->m_mapFirst = 0;
544 d->m_mapFirst = 0;
545 d->m_mapCount = 0;
545 d->m_mapCount = 0;
546 d->m_mapLimited = false;
546 d->m_mapLimited = false;
547 d->m_mapOrientation = Qt::Vertical;
547 d->m_mapOrientation = Qt::Vertical;
548 }
548 }
549
549
550 // set new model
550 // set new model
551 if (model) {
551 if (model) {
552 d->m_model = model;
552 d->m_model = model;
553 return true;
553 return true;
554 } else {
554 } else {
555 d->m_model = 0;
555 d->m_model = 0;
556 return false;
556 return false;
557 }
557 }
558 }
558 }
559
559
560 /*!
560 /*!
561 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
561 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
562 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
562 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
563 as a data source for y coordinate. The \a orientation paramater specifies whether the data
563 as a data source for y coordinate. The \a orientation parameter specifies whether the data
564 is in columns or in rows.
564 is in columns or in rows.
565 \sa setModel(), setModelMappingRange()
565 \sa setModel(), setModelMappingRange()
566 */
566 */
567 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
567 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
568 {
568 {
569 Q_D(QXYSeries);
569 Q_D(QXYSeries);
570 if (d->m_model == 0)
570 if (d->m_model == 0)
571 return;
571 return;
572 d->m_mapX = modelX;
572 d->m_mapX = modelX;
573 d->m_mapY = modelY;
573 d->m_mapY = modelY;
574 d->m_mapFirst = 0;
574 d->m_mapFirst = 0;
575 d->m_mapOrientation = orientation;
575 d->m_mapOrientation = orientation;
576 if (d->m_mapOrientation == Qt::Vertical) {
576 if (d->m_mapOrientation == Qt::Vertical) {
577 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
577 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
578 connect(d->m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
578 connect(d->m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
579 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
579 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
580 connect(d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
580 connect(d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
581 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
581 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
582 } else {
582 } else {
583 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
583 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
584 connect(d->m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
584 connect(d->m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
585 connect(d->m_model,SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
585 connect(d->m_model,SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
586 connect(d->m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
586 connect(d->m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
587 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
587 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
588 }
588 }
589 }
589 }
590
590
591 /*!
591 /*!
592 \fn bool QXYSeries::setModelMappingRange(int first, int count)
592 \fn bool QXYSeries::setModelMappingRange(int first, int count)
593 Allows limiting the model mapping.
593 Allows limiting the model mapping.
594 Parameter \a first specifies which element of the model should be used as a first one of the series.
594 Parameter \a first specifies which element of the model should be used as a first one of the series.
595 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
595 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
596 then all the items following \a first item in a model are used.
596 then all the items following \a first item in a model are used.
597 \sa setModel(), setModelMapping()
597 \sa setModel(), setModelMapping()
598 */
598 */
599 void QXYSeries::setModelMappingRange(int first, int count)
599 void QXYSeries::setModelMappingRange(int first, int count)
600 {
600 {
601 Q_D(QXYSeries);
601 Q_D(QXYSeries);
602 d->m_mapFirst = first;
602 d->m_mapFirst = first;
603 if (count == 0) {
603 if (count == 0) {
604 d->m_mapLimited = false;
604 d->m_mapLimited = false;
605 } else {
605 } else {
606 d->m_mapCount = count;
606 d->m_mapCount = count;
607 d->m_mapLimited = true;
607 d->m_mapLimited = true;
608 }
608 }
609 }
609 }
610
610
611 int QXYSeries::mapFirst() const
611 int QXYSeries::mapFirst() const
612 {
612 {
613 Q_D(const QXYSeries);
613 Q_D(const QXYSeries);
614 return d->m_mapFirst;
614 return d->m_mapFirst;
615 }
615 }
616
616
617 int QXYSeries::mapCount() const
617 int QXYSeries::mapCount() const
618 {
618 {
619 Q_D(const QXYSeries);
619 Q_D(const QXYSeries);
620 return d->m_mapCount;
620 return d->m_mapCount;
621 }
621 }
622
622
623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
624
624
625 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q): QSeriesPrivate(q),
625 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q): QSeriesPrivate(q),
626 m_mapX(-1),
626 m_mapX(-1),
627 m_mapY(-1),
627 m_mapY(-1),
628 m_mapFirst(0),
628 m_mapFirst(0),
629 m_mapCount(0),
629 m_mapCount(0),
630 m_mapLimited(false),
630 m_mapLimited(false),
631 m_mapOrientation( Qt::Vertical),
631 m_mapOrientation( Qt::Vertical),
632 m_pointsVisible(false)
632 m_pointsVisible(false)
633 {
633 {
634
634
635 }
635 }
636
636
637 void QXYSeriesPrivate::scaleDomain(Domain& domain)
637 void QXYSeriesPrivate::scaleDomain(Domain& domain)
638 {
638 {
639 qreal minX(domain.minX());
639 qreal minX(domain.minX());
640 qreal minY(domain.minY());
640 qreal minY(domain.minY());
641 qreal maxX(domain.maxX());
641 qreal maxX(domain.maxX());
642 qreal maxY(domain.maxY());
642 qreal maxY(domain.maxY());
643 int tickXCount(domain.tickXCount());
643 int tickXCount(domain.tickXCount());
644 int tickYCount(domain.tickYCount());
644 int tickYCount(domain.tickYCount());
645
645
646 Q_Q(QXYSeries);
646 Q_Q(QXYSeries);
647 for (int i = 0; i < q->count(); i++)
647 for (int i = 0; i < q->count(); i++)
648 {
648 {
649 qreal x = q->x(i);
649 qreal x = q->x(i);
650 qreal y = q->y(i);
650 qreal y = q->y(i);
651 minX = qMin(minX, x);
651 minX = qMin(minX, x);
652 minY = qMin(minY, y);
652 minY = qMin(minY, y);
653 maxX = qMax(maxX, x);
653 maxX = qMax(maxX, x);
654 maxY = qMax(maxY, y);
654 maxY = qMax(maxY, y);
655 }
655 }
656
656
657 domain.setRangeX(minX,maxX,tickXCount);
657 domain.setRangeX(minX,maxX,tickXCount);
658 domain.setRangeY(minY,maxY,tickYCount);
658 domain.setRangeY(minY,maxY,tickYCount);
659 }
659 }
660
660
661 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
661 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
662 {
662 {
663 Q_Q(QXYSeries);
663 Q_Q(QXYSeries);
664 QList<LegendMarker*> list;
664 QList<LegendMarker*> list;
665 return list << new XYLegendMarker(q,legend);
665 return list << new XYLegendMarker(q,legend);
666 }
666 }
667
667
668 #include "moc_qxyseries.cpp"
668 #include "moc_qxyseries.cpp"
669 #include "moc_qxyseries_p.cpp"
669 #include "moc_qxyseries_p.cpp"
670
670
671 QTCOMMERCIALCHART_END_NAMESPACE
671 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,538 +1,570
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include <QtTest/QtTest>
21 #include <QtTest/QtTest>
22 #include <qchartaxis.h>
22 #include <qchartaxis.h>
23 #include <qlineseries.h>
23 #include <qlineseries.h>
24 #include <private/chartdataset_p.h>
24 #include <private/chartdataset_p.h>
25 #include <private/domain_p.h>
25 #include <private/domain_p.h>
26
26
27 QTCOMMERCIALCHART_USE_NAMESPACE
27 QTCOMMERCIALCHART_USE_NAMESPACE
28
28
29 Q_DECLARE_METATYPE(Domain*)
29 Q_DECLARE_METATYPE(Domain*)
30 Q_DECLARE_METATYPE(QChartAxis*)
30 Q_DECLARE_METATYPE(QChartAxis*)
31 Q_DECLARE_METATYPE(QSeries*)
31 Q_DECLARE_METATYPE(QSeries*)
32 Q_DECLARE_METATYPE(QLineSeries*)
32 Q_DECLARE_METATYPE(QLineSeries*)
33
33
34 class tst_ChartDataSet: public QObject {
34 class tst_ChartDataSet: public QObject {
35
35
36 Q_OBJECT
36 Q_OBJECT
37
37
38 public Q_SLOTS:
38 public Q_SLOTS:
39 void initTestCase();
39 void initTestCase();
40 void cleanupTestCase();
40 void cleanupTestCase();
41 void init();
41 void init();
42 void cleanup();
42 void cleanup();
43
43
44 private Q_SLOTS:
44 private Q_SLOTS:
45 void chartdataset_data();
45 void chartdataset_data();
46 void chartdataset();
46 void chartdataset();
47 void addSeries_data();
47 void addSeries_data();
48 void addSeries();
48 void addSeries();
49 void removeSeries_data();
49 void removeSeries_data();
50 void removeSeries();
50 void removeSeries();
51 void removeAllSeries_data();
51 void removeAllSeries_data();
52 void removeAllSeries();
52 void removeAllSeries();
53 void axisY_data();
53 void axisY_data();
54 void axisY();
54 void axisY();
55 void seriesCount_data();
55 void seriesCount_data();
56 void seriesCount();
56 void seriesCount();
57 void seriesIndex_data();
57 void seriesIndex_data();
58 void seriesIndex();
58 void seriesIndex();
59 void domain_data();
59 void domain_data();
60 void domain();
60 void domain();
61 void zoomInDomain_data();
61 void zoomInDomain_data();
62 void zoomInDomain();
62 void zoomInDomain();
63 void zoomOutDomain_data();
63 void zoomOutDomain_data();
64 void zoomOutDomain();
64 void zoomOutDomain();
65 void scrollDomain_data();
65 void scrollDomain_data();
66 void scrollDomain();
66 void scrollDomain();
67 };
67 };
68
68
69 void tst_ChartDataSet::initTestCase()
69 void tst_ChartDataSet::initTestCase()
70 {
70 {
71 qRegisterMetaType<Domain*>();
71 qRegisterMetaType<Domain*>();
72 qRegisterMetaType<QChartAxis*>();
72 qRegisterMetaType<QChartAxis*>();
73 qRegisterMetaType<QSeries*>();
73 qRegisterMetaType<QSeries*>();
74 }
74 }
75
75
76 void tst_ChartDataSet::cleanupTestCase()
76 void tst_ChartDataSet::cleanupTestCase()
77 {
77 {
78 }
78 }
79
79
80 void tst_ChartDataSet::init()
80 void tst_ChartDataSet::init()
81 {
81 {
82 }
82 }
83
83
84 void tst_ChartDataSet::cleanup()
84 void tst_ChartDataSet::cleanup()
85 {
85 {
86 }
86 }
87
87
88 void tst_ChartDataSet::chartdataset_data()
88 void tst_ChartDataSet::chartdataset_data()
89 {
89 {
90 }
90 }
91
91
92 void tst_ChartDataSet::chartdataset()
92 void tst_ChartDataSet::chartdataset()
93 {
93 {
94 ChartDataSet dataSet;
94 ChartDataSet dataSet;
95 QVERIFY2(dataSet.axisX(), "Missing axisX.");
95 QVERIFY2(dataSet.axisX(), "Missing axisX.");
96 QVERIFY2(dataSet.axisY(), "Missing axisY.");
96 QVERIFY2(dataSet.axisY(), "Missing axisY.");
97 //check if not dangling pointer
97 //check if not dangling pointer
98 dataSet.axisX()->objectName();
98 dataSet.axisX()->objectName();
99 dataSet.axisY()->objectName();
99 dataSet.axisY()->objectName();
100 QLineSeries* series = new QLineSeries(this);
100 QLineSeries* series = new QLineSeries(this);
101 QCOMPARE(dataSet.seriesIndex(series),-1);
101 QCOMPARE(dataSet.seriesIndex(series),-1);
102 }
102 }
103
103
104 void tst_ChartDataSet::addSeries_data()
104 void tst_ChartDataSet::addSeries_data()
105 {
105 {
106 QTest::addColumn<QLineSeries*>("series0");
106 QTest::addColumn<QLineSeries*>("series0");
107 QTest::addColumn<QChartAxis*>("axis0");
107 QTest::addColumn<QChartAxis*>("axis0");
108 QTest::addColumn<QLineSeries*>("series1");
108 QTest::addColumn<QLineSeries*>("series1");
109 QTest::addColumn<QChartAxis*>("axis1");
109 QTest::addColumn<QChartAxis*>("axis1");
110 QTest::addColumn<QLineSeries*>("series2");
110 QTest::addColumn<QLineSeries*>("series2");
111 QTest::addColumn<QChartAxis*>("axis2");
111 QTest::addColumn<QChartAxis*>("axis2");
112 QTest::addColumn<int>("axisCount");
112 QTest::addColumn<int>("axisCount");
113
113
114 QLineSeries* series0 = new QLineSeries(this);
114 QLineSeries* series0 = new QLineSeries(this);
115 QLineSeries* series1 = new QLineSeries(this);
115 QLineSeries* series1 = new QLineSeries(this);
116 QLineSeries* series2 = new QLineSeries(this);
116 QLineSeries* series2 = new QLineSeries(this);
117
117
118 QChartAxis* axis0 = new QChartAxis(this);
118 QChartAxis* axis0 = new QChartAxis(this);
119 QChartAxis* axis1 = new QChartAxis(this);
119 QChartAxis* axis1 = new QChartAxis(this);
120 QChartAxis* axis2 = new QChartAxis(this);
120 QChartAxis* axis2 = new QChartAxis(this);
121
121
122 QTest::newRow("default axis Y: series0,series1,series2") << series0 << (QChartAxis*)0 << series1 << (QChartAxis*)0 << series2 << (QChartAxis*)0 << 2;
122 QTest::newRow("default axis Y: series0,series1,series2") << series0 << (QChartAxis*)0 << series1 << (QChartAxis*)0 << series2 << (QChartAxis*)0 << 2;
123 QTest::newRow("default axis Y: series0, axis 0: series1,series2") << series0 << (QChartAxis*)0 << series1 << axis0 << series2 << axis0 << 3;
123 QTest::newRow("default axis Y: series0, axis 0: series1,series2") << series0 << (QChartAxis*)0 << series1 << axis0 << series2 << axis0 << 3;
124 QTest::newRow("axis0: series0, axis1: series1, axis2: series2") << series0 << axis0 << series1 << axis1 << series2 << axis2 << 4;
124 QTest::newRow("axis0: series0, axis1: series1, axis2: series2") << series0 << axis0 << series1 << axis1 << series2 << axis2 << 4;
125 }
125 }
126
126
127 void tst_ChartDataSet::addSeries()
127 void tst_ChartDataSet::addSeries()
128 {
128 {
129 QFETCH(QLineSeries*, series0);
129 QFETCH(QLineSeries*, series0);
130 QFETCH(QChartAxis*, axis0);
130 QFETCH(QChartAxis*, axis0);
131 QFETCH(QLineSeries*, series1);
131 QFETCH(QLineSeries*, series1);
132 QFETCH(QChartAxis*, axis1);
132 QFETCH(QChartAxis*, axis1);
133 QFETCH(QLineSeries*, series2);
133 QFETCH(QLineSeries*, series2);
134 QFETCH(QChartAxis*, axis2);
134 QFETCH(QChartAxis*, axis2);
135 QFETCH(int, axisCount);
135 QFETCH(int, axisCount);
136
136
137 ChartDataSet dataSet;
137 ChartDataSet dataSet;
138
138
139 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
139 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
140 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
140 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
141 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
141 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
142 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
142 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
143
143
144 dataSet.addSeries(series0,axis0);
144 dataSet.addSeries(series0,axis0);
145 dataSet.addSeries(series1,axis1);
145 dataSet.addSeries(series1,axis1);
146 dataSet.addSeries(series2,axis2);
146 dataSet.addSeries(series2,axis2);
147
147
148 QCOMPARE(spy0.count(), axisCount);
148 QCOMPARE(spy0.count(), axisCount);
149 QCOMPARE(spy1.count(), 0);
149 QCOMPARE(spy1.count(), 0);
150 QCOMPARE(spy2.count(), 3);
150 QCOMPARE(spy2.count(), 3);
151 QCOMPARE(spy3.count(), 0);
151 QCOMPARE(spy3.count(), 0);
152
152
153 if(axis0==0) axis0 = dataSet.axisY();
154 if(axis1==0) axis1 = dataSet.axisY();
155 if(axis2==0) axis2 = dataSet.axisY();
156
157 QVERIFY(axis0 == dataSet.removeSeries(series0));
158 QVERIFY(axis1 == dataSet.removeSeries(series1));
159 QVERIFY(axis2 == dataSet.removeSeries(series2));
153 }
160 }
154
161
155 void tst_ChartDataSet::removeSeries_data()
162 void tst_ChartDataSet::removeSeries_data()
156 {
163 {
157 addSeries_data();
164 addSeries_data();
158 }
165 }
159
166
160 void tst_ChartDataSet::removeSeries()
167 void tst_ChartDataSet::removeSeries()
161 {
168 {
162 QFETCH(QLineSeries*, series0);
169 QFETCH(QLineSeries*, series0);
163 QFETCH(QChartAxis*, axis0);
170 QFETCH(QChartAxis*, axis0);
164 QFETCH(QLineSeries*, series1);
171 QFETCH(QLineSeries*, series1);
165 QFETCH(QChartAxis*, axis1);
172 QFETCH(QChartAxis*, axis1);
166 QFETCH(QLineSeries*, series2);
173 QFETCH(QLineSeries*, series2);
167 QFETCH(QChartAxis*, axis2);
174 QFETCH(QChartAxis*, axis2);
168 QFETCH(int, axisCount);
175 QFETCH(int, axisCount);
169
176
170 ChartDataSet dataSet;
177 ChartDataSet dataSet;
171
178
172 dataSet.addSeries(series0,axis0);
179 dataSet.addSeries(series0,axis0);
173 dataSet.addSeries(series1,axis1);
180 dataSet.addSeries(series1,axis1);
174 dataSet.addSeries(series2,axis2);
181 dataSet.addSeries(series2,axis2);
175
182
176 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
183 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
177 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
184 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
178 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
185 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
179 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
186 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
180
187
181 dataSet.removeSeries(series0);
188 dataSet.removeSeries(series0);
182 dataSet.removeSeries(series1);
189 dataSet.removeSeries(series1);
183 dataSet.removeSeries(series2);
190 dataSet.removeSeries(series2);
184
191
185 QCOMPARE(spy0.count(), 0);
192 QCOMPARE(spy0.count(), 0);
186 QCOMPARE(spy1.count(), axisCount);
193 QCOMPARE(spy1.count(), axisCount);
187 QCOMPARE(spy2.count(), 0);
194 QCOMPARE(spy2.count(), 0);
188 QCOMPARE(spy3.count(), 3);
195 QCOMPARE(spy3.count(), 3);
189 }
196 }
190
197
191 void tst_ChartDataSet::removeAllSeries_data()
198 void tst_ChartDataSet::removeAllSeries_data()
192 {
199 {
193 addSeries_data();
200
194 }
201 }
195
202
196 void tst_ChartDataSet::removeAllSeries()
203 void tst_ChartDataSet::removeAllSeries()
197 {
204 {
198 QFETCH(QLineSeries*, series0);
205 QLineSeries* series0 = new QLineSeries(this);
199 QFETCH(QChartAxis*, axis0);
206 QLineSeries* series1 = new QLineSeries(this);
200 QFETCH(QLineSeries*, series1);
207 QLineSeries* series2 = new QLineSeries(this);
201 QFETCH(QChartAxis*, axis1);
208
202 QFETCH(QLineSeries*, series2);
209 QChartAxis* axis0 = new QChartAxis(this);
203 QFETCH(QChartAxis*, axis2);
210 QChartAxis* axis1 = new QChartAxis(this);
204 QFETCH(int, axisCount);
211 QChartAxis* axis2 = new QChartAxis(this);
205
212
206 ChartDataSet dataSet;
213
207
214 ChartDataSet dataSet;
208 dataSet.addSeries(series0,axis0);
215
209 dataSet.addSeries(series1,axis1);
216 dataSet.addSeries(series0, axis0);
210 dataSet.addSeries(series2,axis2);
217 dataSet.addSeries(series1, axis1);
211
218 dataSet.addSeries(series2, axis2);
212 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
219
213 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
220 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
214 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
221 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
215 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
222 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
216
223 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
217 dataSet.removeAllSeries();
224
218
225 dataSet.removeAllSeries();
219 QCOMPARE(spy0.count(), 0);
226
220 QCOMPARE(spy1.count(), axisCount);
227 QCOMPARE(spy0.count(), 0);
221 QCOMPARE(spy2.count(), 0);
228 QCOMPARE(spy1.count(), 4);
222 QCOMPARE(spy3.count(), 3);
229 QCOMPARE(spy2.count(), 0);
230 QCOMPARE(spy3.count(), 3);
223 }
231 }
224
232
225
233
226 void tst_ChartDataSet::axisY_data()
234 void tst_ChartDataSet::axisY_data()
227 {
235 {
228 QTest::addColumn<QChartAxis*>("axis0");
236 QTest::addColumn<QChartAxis*>("axis0");
229 QTest::addColumn<QChartAxis*>("axis1");
237 QTest::addColumn<QChartAxis*>("axis1");
230 QTest::addColumn<QChartAxis*>("axis2");
238 QTest::addColumn<QChartAxis*>("axis2");
231 QTest::newRow("1 defualt, 2 optional") << (QChartAxis*)0 << new QChartAxis() << new QChartAxis();
239 QTest::newRow("1 defualt, 2 optional") << (QChartAxis*)0 << new QChartAxis() << new QChartAxis();
232 QTest::newRow("3 optional") << new QChartAxis() << new QChartAxis() << new QChartAxis();
240 QTest::newRow("3 optional") << new QChartAxis() << new QChartAxis() << new QChartAxis();
233 }
241 }
234
242
235 void tst_ChartDataSet::axisY()
243 void tst_ChartDataSet::axisY()
236 {
244 {
237 QFETCH(QChartAxis*, axis0);
245 QFETCH(QChartAxis*, axis0);
238 QFETCH(QChartAxis*, axis1);
246 QFETCH(QChartAxis*, axis1);
239 QFETCH(QChartAxis*, axis2);
247 QFETCH(QChartAxis*, axis2);
240
248
241 ChartDataSet dataSet;
249 ChartDataSet dataSet;
242
250
243 QChartAxis* defaultAxisY = dataSet.axisY();
251 QChartAxis* defaultAxisY = dataSet.axisY();
244
252
245 QVERIFY2(defaultAxisY, "Missing axisY.");
253 QVERIFY2(defaultAxisY, "Missing axisY.");
246
254
247 QLineSeries* series0 = new QLineSeries();
255 QLineSeries* series0 = new QLineSeries();
248 dataSet.addSeries(series0,axis0);
256 dataSet.addSeries(series0,axis0);
249
257
250 QLineSeries* series1 = new QLineSeries();
258 QLineSeries* series1 = new QLineSeries();
251 dataSet.addSeries(series1,axis1);
259 dataSet.addSeries(series1,axis1);
252
260
253 QLineSeries* series2 = new QLineSeries();
261 QLineSeries* series2 = new QLineSeries();
254 dataSet.addSeries(series2,axis2);
262 dataSet.addSeries(series2,axis2);
255
263
256 if(!axis0) axis0=defaultAxisY ;
264 if(!axis0) axis0=defaultAxisY ;
257 if(!axis1) axis1=defaultAxisY ;
265 if(!axis1) axis1=defaultAxisY ;
258 if(!axis2) axis2=defaultAxisY ;
266 if(!axis2) axis2=defaultAxisY ;
259
267
260 QVERIFY(dataSet.axisY(series0) == axis0);
268 QVERIFY(dataSet.axisY(series0) == axis0);
261 QVERIFY(dataSet.axisY(series1) == axis1);
269 QVERIFY(dataSet.axisY(series1) == axis1);
262 QVERIFY(dataSet.axisY(series2) == axis2);
270 QVERIFY(dataSet.axisY(series2) == axis2);
263
271
264 }
272 }
265
273
266 void tst_ChartDataSet::seriesCount_data()
274 void tst_ChartDataSet::seriesCount_data()
267 {
275 {
268 addSeries_data();
276 addSeries_data();
269 }
277 }
270
278
271 void tst_ChartDataSet::seriesCount()
279 void tst_ChartDataSet::seriesCount()
272 {
280 {
273 QFETCH(QLineSeries*, series0);
281 QFETCH(QLineSeries*, series0);
274 QFETCH(QChartAxis*, axis0);
282 QFETCH(QChartAxis*, axis0);
275 QFETCH(QLineSeries*, series1);
283 QFETCH(QLineSeries*, series1);
276 QFETCH(QChartAxis*, axis1);
284 QFETCH(QChartAxis*, axis1);
277 QFETCH(QLineSeries*, series2);
285 QFETCH(QLineSeries*, series2);
278 QFETCH(QChartAxis*, axis2);
286 QFETCH(QChartAxis*, axis2);
279 QFETCH(int, axisCount);
287 QFETCH(int, axisCount);
280 Q_UNUSED(axisCount);
288 Q_UNUSED(axisCount);
281
289
282 ChartDataSet dataSet;
290 ChartDataSet dataSet;
283
291
284 dataSet.addSeries(series0, axis0);
292 dataSet.addSeries(series0, axis0);
285 dataSet.addSeries(series1, axis1);
293 dataSet.addSeries(series1, axis1);
286 dataSet.addSeries(series2, axis2);
294 dataSet.addSeries(series2, axis2);
287
295
288 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
296 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
289 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
297 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
290 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
298 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
291 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
299 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
292
300
293 QCOMPARE(dataSet.seriesCount(series0->type()),3);
301 QCOMPARE(dataSet.seriesCount(series0->type()),3);
294 QCOMPARE(spy0.count(), 0);
302 QCOMPARE(spy0.count(), 0);
295 QCOMPARE(spy1.count(), 0);
303 QCOMPARE(spy1.count(), 0);
296 QCOMPARE(spy2.count(), 0);
304 QCOMPARE(spy2.count(), 0);
297 QCOMPARE(spy3.count(), 0);
305 QCOMPARE(spy3.count(), 0);
306
307 dataSet.removeSeries(series0);
308 dataSet.removeSeries(series1);
309 dataSet.removeSeries(series2);
298 }
310 }
299
311
300 void tst_ChartDataSet::seriesIndex_data()
312 void tst_ChartDataSet::seriesIndex_data()
301 {
313 {
302 addSeries_data();
314 addSeries_data();
303 }
315 }
304
316
305 void tst_ChartDataSet::seriesIndex()
317 void tst_ChartDataSet::seriesIndex()
306 {
318 {
307 //TODO: rewrite this series_index_data to match better
319 //TODO: rewrite this series_index_data to match better
308
320
309 QFETCH(QLineSeries*, series0);
321 QFETCH(QLineSeries*, series0);
310 QFETCH(QChartAxis*, axis0);
322 QFETCH(QChartAxis*, axis0);
311 QFETCH(QLineSeries*, series1);
323 QFETCH(QLineSeries*, series1);
312 QFETCH(QChartAxis*, axis1);
324 QFETCH(QChartAxis*, axis1);
313 QFETCH(QLineSeries*, series2);
325 QFETCH(QLineSeries*, series2);
314 QFETCH(QChartAxis*, axis2);
326 QFETCH(QChartAxis*, axis2);
315 QFETCH(int, axisCount);
327 QFETCH(int, axisCount);
316 Q_UNUSED(axisCount);
328 Q_UNUSED(axisCount);
317
329
318 ChartDataSet dataSet;
330 ChartDataSet dataSet;
319
331
320 dataSet.addSeries(series0, axis0);
332 dataSet.addSeries(series0, axis0);
321 dataSet.addSeries(series1, axis1);
333 dataSet.addSeries(series1, axis1);
322 dataSet.addSeries(series2, axis2);
334 dataSet.addSeries(series2, axis2);
323
335
324 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
336 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
325 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
337 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
326 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
338 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
327 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
339 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
328
340
329 QCOMPARE(dataSet.seriesIndex(series0),0);
341 QCOMPARE(dataSet.seriesIndex(series0),0);
330 QCOMPARE(dataSet.seriesIndex(series1),1);
342 QCOMPARE(dataSet.seriesIndex(series1),1);
331 QCOMPARE(dataSet.seriesIndex(series2),2);
343 QCOMPARE(dataSet.seriesIndex(series2),2);
332
344
333 QCOMPARE(spy0.count(), 0);
345 QCOMPARE(spy0.count(), 0);
334 QCOMPARE(spy1.count(), 0);
346 QCOMPARE(spy1.count(), 0);
335 QCOMPARE(spy2.count(), 0);
347 QCOMPARE(spy2.count(), 0);
336 QCOMPARE(spy3.count(), 0);
348 QCOMPARE(spy3.count(), 0);
337
349
338 dataSet.removeSeries(series0);
350 dataSet.removeSeries(series0);
339 dataSet.removeSeries(series1);
351 dataSet.removeSeries(series1);
340 dataSet.removeSeries(series2);
352 dataSet.removeSeries(series2);
341
353
342 QCOMPARE(dataSet.seriesIndex(series0),-1);
354 QCOMPARE(dataSet.seriesIndex(series0),-1);
343 QCOMPARE(dataSet.seriesIndex(series1),-1);
355 QCOMPARE(dataSet.seriesIndex(series1),-1);
344 QCOMPARE(dataSet.seriesIndex(series2),-1);
356 QCOMPARE(dataSet.seriesIndex(series2),-1);
345
357
346 dataSet.addSeries(series0, axis0);
358 dataSet.addSeries(series0, axis0);
347 dataSet.addSeries(series1, axis1);
359 dataSet.addSeries(series1, axis1);
348 dataSet.addSeries(series2, axis2);
360 dataSet.addSeries(series2, axis2);
349
361
350 QCOMPARE(dataSet.seriesIndex(series0),0);
362 QCOMPARE(dataSet.seriesIndex(series0),0);
351 QCOMPARE(dataSet.seriesIndex(series1),1);
363 QCOMPARE(dataSet.seriesIndex(series1),1);
352 QCOMPARE(dataSet.seriesIndex(series2),2);
364 QCOMPARE(dataSet.seriesIndex(series2),2);
353
365
354 dataSet.removeSeries(series1);
366 dataSet.removeSeries(series1);
355
367
356 QCOMPARE(dataSet.seriesIndex(series0),0);
368 QCOMPARE(dataSet.seriesIndex(series0),0);
357 QCOMPARE(dataSet.seriesIndex(series1),-1);
369 QCOMPARE(dataSet.seriesIndex(series1),-1);
358 QCOMPARE(dataSet.seriesIndex(series2),2);
370 QCOMPARE(dataSet.seriesIndex(series2),2);
359
371
360 dataSet.addSeries(series1, axis1);
372 dataSet.addSeries(series1, axis1);
361 QCOMPARE(dataSet.seriesIndex(series0),0);
373 QCOMPARE(dataSet.seriesIndex(series0),0);
362 QCOMPARE(dataSet.seriesIndex(series1),1);
374 QCOMPARE(dataSet.seriesIndex(series1),1);
363 QCOMPARE(dataSet.seriesIndex(series2),2);
375 QCOMPARE(dataSet.seriesIndex(series2),2);
364
376
365 dataSet.removeSeries(series2);
377 dataSet.removeSeries(series2);
366 QCOMPARE(dataSet.seriesIndex(series0),0);
378 QCOMPARE(dataSet.seriesIndex(series0),0);
367 QCOMPARE(dataSet.seriesIndex(series1),1);
379 QCOMPARE(dataSet.seriesIndex(series1),1);
368 QCOMPARE(dataSet.seriesIndex(series2),-1);
380 QCOMPARE(dataSet.seriesIndex(series2),-1);
369
381
370 dataSet.removeSeries(series0);
382 dataSet.removeSeries(series0);
371 QCOMPARE(dataSet.seriesIndex(series0),-1);
383 QCOMPARE(dataSet.seriesIndex(series0),-1);
372 QCOMPARE(dataSet.seriesIndex(series1),1);
384 QCOMPARE(dataSet.seriesIndex(series1),1);
373 QCOMPARE(dataSet.seriesIndex(series2),-1);
385 QCOMPARE(dataSet.seriesIndex(series2),-1);
374
386
375 dataSet.addSeries(series2);
387 dataSet.addSeries(series2);
376 QCOMPARE(dataSet.seriesIndex(series0),-1);
388 QCOMPARE(dataSet.seriesIndex(series0),-1);
377 QCOMPARE(dataSet.seriesIndex(series1),1);
389 QCOMPARE(dataSet.seriesIndex(series1),1);
378 QCOMPARE(dataSet.seriesIndex(series2),0);
390 QCOMPARE(dataSet.seriesIndex(series2),0);
379
391
380 dataSet.addSeries(series0);
392 dataSet.addSeries(series0);
381 QCOMPARE(dataSet.seriesIndex(series0),2);
393 QCOMPARE(dataSet.seriesIndex(series0),2);
382 QCOMPARE(dataSet.seriesIndex(series1),1);
394 QCOMPARE(dataSet.seriesIndex(series1),1);
383 QCOMPARE(dataSet.seriesIndex(series2),0);
395 QCOMPARE(dataSet.seriesIndex(series2),0);
384
396
397 dataSet.removeSeries(series0);
398 dataSet.removeSeries(series1);
399 dataSet.removeSeries(series2);
400
385 }
401 }
386
402
387 void tst_ChartDataSet::domain_data()
403 void tst_ChartDataSet::domain_data()
388 {
404 {
389 addSeries_data();
405 addSeries_data();
390 }
406 }
391
407
392 void tst_ChartDataSet::domain()
408 void tst_ChartDataSet::domain()
393 {
409 {
394 QFETCH(QLineSeries*, series0);
410 QFETCH(QLineSeries*, series0);
395 QFETCH(QChartAxis*, axis0);
411 QFETCH(QChartAxis*, axis0);
396 QFETCH(QLineSeries*, series1);
412 QFETCH(QLineSeries*, series1);
397 QFETCH(QChartAxis*, axis1);
413 QFETCH(QChartAxis*, axis1);
398 QFETCH(QLineSeries*, series2);
414 QFETCH(QLineSeries*, series2);
399 QFETCH(QChartAxis*, axis2);
415 QFETCH(QChartAxis*, axis2);
400 QFETCH(int, axisCount);
416 QFETCH(int, axisCount);
401 Q_UNUSED(axisCount);
417 Q_UNUSED(axisCount);
402
418
403 ChartDataSet dataSet;
419 ChartDataSet dataSet;
404
420
405 dataSet.addSeries(series0, axis0);
421 dataSet.addSeries(series0, axis0);
406 dataSet.addSeries(series1, axis1);
422 dataSet.addSeries(series1, axis1);
407 dataSet.addSeries(series2, axis2);
423 dataSet.addSeries(series2, axis2);
408
424
409 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
425 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*,Domain*)));
410 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
426 QSignalSpy spy1(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
411 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
427 QSignalSpy spy2(&dataSet, SIGNAL(seriesAdded(QSeries*,Domain*)));
412 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
428 QSignalSpy spy3(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
413
429
414 QVERIFY(dataSet.domain(axis0)==dataSet.domain(series0));
430 QVERIFY(dataSet.domain(axis0)==dataSet.domain(series0));
415 QVERIFY(dataSet.domain(axis1)==dataSet.domain(series1));
431 QVERIFY(dataSet.domain(axis1)==dataSet.domain(series1));
416 QVERIFY(dataSet.domain(axis2)==dataSet.domain(series2));
432 QVERIFY(dataSet.domain(axis2)==dataSet.domain(series2));
417 QCOMPARE(spy0.count(), 0);
433 QCOMPARE(spy0.count(), 0);
418 QCOMPARE(spy1.count(), 0);
434 QCOMPARE(spy1.count(), 0);
419 QCOMPARE(spy2.count(), 0);
435 QCOMPARE(spy2.count(), 0);
420 QCOMPARE(spy3.count(), 0);
436 QCOMPARE(spy3.count(), 0);
437
438 dataSet.removeSeries(series0);
439 dataSet.removeSeries(series1);
440 dataSet.removeSeries(series2);
421 }
441 }
422
442
423 void tst_ChartDataSet::zoomInDomain_data()
443 void tst_ChartDataSet::zoomInDomain_data()
424 {
444 {
425 addSeries_data();
445 addSeries_data();
426 }
446 }
427
447
428 void tst_ChartDataSet::zoomInDomain()
448 void tst_ChartDataSet::zoomInDomain()
429 {
449 {
430 QFETCH(QLineSeries*, series0);
450 QFETCH(QLineSeries*, series0);
431 QFETCH(QChartAxis*, axis0);
451 QFETCH(QChartAxis*, axis0);
432 QFETCH(QLineSeries*, series1);
452 QFETCH(QLineSeries*, series1);
433 QFETCH(QChartAxis*, axis1);
453 QFETCH(QChartAxis*, axis1);
434 QFETCH(QLineSeries*, series2);
454 QFETCH(QLineSeries*, series2);
435 QFETCH(QChartAxis*, axis2);
455 QFETCH(QChartAxis*, axis2);
436 QFETCH(int, axisCount);
456 QFETCH(int, axisCount);
437
457
438 Q_UNUSED(axisCount);
458 Q_UNUSED(axisCount);
439 ChartDataSet dataSet;
459 ChartDataSet dataSet;
440
460
441 dataSet.addSeries(series0, axis0);
461 dataSet.addSeries(series0, axis0);
442 dataSet.addSeries(series1, axis1);
462 dataSet.addSeries(series1, axis1);
443 dataSet.addSeries(series2, axis2);
463 dataSet.addSeries(series2, axis2);
444
464
445 Domain* domain0 = dataSet.domain(series0);
465 Domain* domain0 = dataSet.domain(series0);
446 Domain* domain1 = dataSet.domain(series1);
466 Domain* domain1 = dataSet.domain(series1);
447 Domain* domain2 = dataSet.domain(series2);
467 Domain* domain2 = dataSet.domain(series2);
448
468
449 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
469 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
450 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
470 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
451 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
471 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
452
472
453 dataSet.zoomInDomain(QRect(0,0,100,100),QSize(1000,1000));
473 dataSet.zoomInDomain(QRect(0,0,100,100),QSize(1000,1000));
454
474
455 QCOMPARE(spy0.count(), 1);
475 QCOMPARE(spy0.count(), 1);
456 QCOMPARE(spy1.count(), 1);
476 QCOMPARE(spy1.count(), 1);
457 QCOMPARE(spy2.count(), 1);
477 QCOMPARE(spy2.count(), 1);
478
479 dataSet.removeSeries(series0);
480 dataSet.removeSeries(series1);
481 dataSet.removeSeries(series2);
458 }
482 }
459
483
460 void tst_ChartDataSet::zoomOutDomain_data()
484 void tst_ChartDataSet::zoomOutDomain_data()
461 {
485 {
462 addSeries_data();
486 addSeries_data();
463 }
487 }
464
488
465 void tst_ChartDataSet::zoomOutDomain()
489 void tst_ChartDataSet::zoomOutDomain()
466 {
490 {
467 QFETCH(QLineSeries*, series0);
491 QFETCH(QLineSeries*, series0);
468 QFETCH(QChartAxis*, axis0);
492 QFETCH(QChartAxis*, axis0);
469 QFETCH(QLineSeries*, series1);
493 QFETCH(QLineSeries*, series1);
470 QFETCH(QChartAxis*, axis1);
494 QFETCH(QChartAxis*, axis1);
471 QFETCH(QLineSeries*, series2);
495 QFETCH(QLineSeries*, series2);
472 QFETCH(QChartAxis*, axis2);
496 QFETCH(QChartAxis*, axis2);
473 QFETCH(int, axisCount);
497 QFETCH(int, axisCount);
474
498
475 Q_UNUSED(axisCount);
499 Q_UNUSED(axisCount);
476
500
477 ChartDataSet dataSet;
501 ChartDataSet dataSet;
478
502
479 dataSet.addSeries(series0, axis0);
503 dataSet.addSeries(series0, axis0);
480 dataSet.addSeries(series1, axis1);
504 dataSet.addSeries(series1, axis1);
481 dataSet.addSeries(series2, axis2);
505 dataSet.addSeries(series2, axis2);
482
506
483 Domain* domain0 = dataSet.domain(series0);
507 Domain* domain0 = dataSet.domain(series0);
484 Domain* domain1 = dataSet.domain(series1);
508 Domain* domain1 = dataSet.domain(series1);
485 Domain* domain2 = dataSet.domain(series2);
509 Domain* domain2 = dataSet.domain(series2);
486
510
487 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
511 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
488 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
512 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
489 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
513 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
490
514
491 dataSet.zoomOutDomain(QRect(0,0,100,100),QSize(1000,1000));
515 dataSet.zoomOutDomain(QRect(0,0,100,100),QSize(1000,1000));
492
516
493 QCOMPARE(spy0.count(), 1);
517 QCOMPARE(spy0.count(), 1);
494 QCOMPARE(spy1.count(), 1);
518 QCOMPARE(spy1.count(), 1);
495 QCOMPARE(spy2.count(), 1);
519 QCOMPARE(spy2.count(), 1);
520
521 dataSet.removeSeries(series0);
522 dataSet.removeSeries(series1);
523 dataSet.removeSeries(series2);
496 }
524 }
497
525
498 void tst_ChartDataSet::scrollDomain_data()
526 void tst_ChartDataSet::scrollDomain_data()
499 {
527 {
500 addSeries_data();
528 addSeries_data();
501 }
529 }
502
530
503 void tst_ChartDataSet::scrollDomain()
531 void tst_ChartDataSet::scrollDomain()
504 {
532 {
505 QFETCH(QLineSeries*, series0);
533 QFETCH(QLineSeries*, series0);
506 QFETCH(QChartAxis*, axis0);
534 QFETCH(QChartAxis*, axis0);
507 QFETCH(QLineSeries*, series1);
535 QFETCH(QLineSeries*, series1);
508 QFETCH(QChartAxis*, axis1);
536 QFETCH(QChartAxis*, axis1);
509 QFETCH(QLineSeries*, series2);
537 QFETCH(QLineSeries*, series2);
510 QFETCH(QChartAxis*, axis2);
538 QFETCH(QChartAxis*, axis2);
511 QFETCH(int, axisCount);
539 QFETCH(int, axisCount);
512
540
513 Q_UNUSED(axisCount);
541 Q_UNUSED(axisCount);
514
542
515 ChartDataSet dataSet;
543 ChartDataSet dataSet;
516
544
517 dataSet.addSeries(series0, axis0);
545 dataSet.addSeries(series0, axis0);
518 dataSet.addSeries(series1, axis1);
546 dataSet.addSeries(series1, axis1);
519 dataSet.addSeries(series2, axis2);
547 dataSet.addSeries(series2, axis2);
520
548
521 Domain* domain0 = dataSet.domain(series0);
549 Domain* domain0 = dataSet.domain(series0);
522 Domain* domain1 = dataSet.domain(series1);
550 Domain* domain1 = dataSet.domain(series1);
523 Domain* domain2 = dataSet.domain(series2);
551 Domain* domain2 = dataSet.domain(series2);
524
552
525 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
553 QSignalSpy spy0(domain0, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
526 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
554 QSignalSpy spy1(domain1, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
527 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
555 QSignalSpy spy2(domain2, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
528
556
529 dataSet.scrollDomain(10,10,QSize(1000,1000));
557 dataSet.scrollDomain(10,10,QSize(1000,1000));
530
558
531 QCOMPARE(spy0.count(), 1);
559 QCOMPARE(spy0.count(), 1);
532 QCOMPARE(spy1.count(), 1);
560 QCOMPARE(spy1.count(), 1);
533 QCOMPARE(spy2.count(), 1);
561 QCOMPARE(spy2.count(), 1);
562
563 dataSet.removeSeries(series0);
564 dataSet.removeSeries(series1);
565 dataSet.removeSeries(series2);
534 }
566 }
535
567
536 QTEST_MAIN(tst_ChartDataSet)
568 QTEST_MAIN(tst_ChartDataSet)
537 #include "tst_chartdataset.moc"
569 #include "tst_chartdataset.moc"
538
570
@@ -1,570 +1,572
1 #include <QtTest/QtTest>
1 #include <QtTest/QtTest>
2 #include <qchartview.h>
2 #include <qchartview.h>
3 #include <qlineseries.h>
3 #include <qlineseries.h>
4 #include <qareaseries.h>
4 #include <qareaseries.h>
5 #include <qscatterseries.h>
5 #include <qscatterseries.h>
6 #include <qsplineseries.h>
6 #include <qsplineseries.h>
7 #include <qpieseries.h>
7 #include <qpieseries.h>
8 #include <qbarseries.h>
8 #include <qbarseries.h>
9 #include <qpercentbarseries.h>
9 #include <qpercentbarseries.h>
10 #include <qstackedbarseries.h>
10 #include <qstackedbarseries.h>
11
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
13
14 Q_DECLARE_METATYPE(QChartAxis*)
14 Q_DECLARE_METATYPE(QChartAxis*)
15 Q_DECLARE_METATYPE(QSeries*)
15 Q_DECLARE_METATYPE(QSeries*)
16 Q_DECLARE_METATYPE(QChart::AnimationOption)
16 Q_DECLARE_METATYPE(QChart::AnimationOption)
17 Q_DECLARE_METATYPE(QBrush)
17 Q_DECLARE_METATYPE(QBrush)
18 Q_DECLARE_METATYPE(QPen)
18 Q_DECLARE_METATYPE(QPen)
19 Q_DECLARE_METATYPE(QChart::ChartTheme)
19 Q_DECLARE_METATYPE(QChart::ChartTheme)
20
20
21 class tst_QChart : public QObject
21 class tst_QChart : public QObject
22 {
22 {
23 Q_OBJECT
23 Q_OBJECT
24
24
25 public slots:
25 public slots:
26 void initTestCase();
26 void initTestCase();
27 void cleanupTestCase();
27 void cleanupTestCase();
28 void init();
28 void init();
29 void cleanup();
29 void cleanup();
30
30
31 private slots:
31 private slots:
32 void qchart_data();
32 void qchart_data();
33 void qchart();
33 void qchart();
34
34
35 void addSeries_data();
35 void addSeries_data();
36 void addSeries();
36 void addSeries();
37 void animationOptions_data();
37 void animationOptions_data();
38 void animationOptions();
38 void animationOptions();
39 void axisX_data();
39 void axisX_data();
40 void axisX();
40 void axisX();
41 void axisY_data();
41 void axisY_data();
42 void axisY();
42 void axisY();
43 void backgroundBrush_data();
43 void backgroundBrush_data();
44 void backgroundBrush();
44 void backgroundBrush();
45 void backgroundPen_data();
45 void backgroundPen_data();
46 void backgroundPen();
46 void backgroundPen();
47 void isBackgroundVisible_data();
47 void isBackgroundVisible_data();
48 void isBackgroundVisible();
48 void isBackgroundVisible();
49 void legend_data();
49 void legend_data();
50 void legend();
50 void legend();
51 void margins_data();
51 void margins_data();
52 void margins();
52 void margins();
53 void removeAllSeries_data();
53 void removeAllSeries_data();
54 void removeAllSeries();
54 void removeAllSeries();
55 void removeSeries_data();
55 void removeSeries_data();
56 void removeSeries();
56 void removeSeries();
57 void scrollDown_data();
57 void scrollDown_data();
58 void scrollDown();
58 void scrollDown();
59 void scrollLeft_data();
59 void scrollLeft_data();
60 void scrollLeft();
60 void scrollLeft();
61 void scrollRight_data();
61 void scrollRight_data();
62 void scrollRight();
62 void scrollRight();
63 void scrollUp_data();
63 void scrollUp_data();
64 void scrollUp();
64 void scrollUp();
65 void theme_data();
65 void theme_data();
66 void theme();
66 void theme();
67 void title_data();
67 void title_data();
68 void title();
68 void title();
69 void titleBrush_data();
69 void titleBrush_data();
70 void titleBrush();
70 void titleBrush();
71 void titleFont_data();
71 void titleFont_data();
72 void titleFont();
72 void titleFont();
73 void zoomIn_data();
73 void zoomIn_data();
74 void zoomIn();
74 void zoomIn();
75 void zoomOut_data();
75 void zoomOut_data();
76 void zoomOut();
76 void zoomOut();
77
77
78 private:
78 private:
79 void createTestData();
79 void createTestData();
80
80
81 private:
81 private:
82 QChartView* m_view;
82 QChartView* m_view;
83 QChart* m_chart;
83 QChart* m_chart;
84 };
84 };
85
85
86 void tst_QChart::initTestCase()
86 void tst_QChart::initTestCase()
87 {
87 {
88
88
89 }
89 }
90
90
91 void tst_QChart::cleanupTestCase()
91 void tst_QChart::cleanupTestCase()
92 {
92 {
93
93
94 }
94 }
95
95
96 void tst_QChart::init()
96 void tst_QChart::init()
97 {
97 {
98 m_view = new QChartView(new QChart());
98 m_view = new QChartView(new QChart());
99 m_chart = m_view->chart();
99 m_chart = m_view->chart();
100 }
100 }
101
101
102 void tst_QChart::createTestData()
102 void tst_QChart::createTestData()
103 {
103 {
104 QLineSeries* series0 = new QLineSeries(this);
104 QLineSeries* series0 = new QLineSeries(this);
105 *series0 << QPointF(0, 0) << QPointF(100, 100);
105 *series0 << QPointF(0, 0) << QPointF(100, 100);
106 m_chart->addSeries(series0);
106 m_chart->addSeries(series0);
107 m_view->show();
107 m_view->show();
108 QTest::qWaitForWindowShown(m_view);
108 QTest::qWaitForWindowShown(m_view);
109 }
109 }
110
110
111 void tst_QChart::cleanup()
111 void tst_QChart::cleanup()
112 {
112 {
113 delete m_view;
113 delete m_view;
114 m_view = 0;
114 m_view = 0;
115 m_chart = 0;
115 m_chart = 0;
116 }
116 }
117
117
118 void tst_QChart::qchart_data()
118 void tst_QChart::qchart_data()
119 {
119 {
120 }
120 }
121
121
122 void tst_QChart::qchart()
122 void tst_QChart::qchart()
123 {
123 {
124 QVERIFY(m_chart);
124 QVERIFY(m_chart);
125 QVERIFY(m_chart->legend());
125 QVERIFY(m_chart->legend());
126 QVERIFY(!m_chart->legend()->isVisible());
126 QVERIFY(!m_chart->legend()->isVisible());
127
127
128 QCOMPARE(m_chart->animationOptions(), QChart::NoAnimation);
128 QCOMPARE(m_chart->animationOptions(), QChart::NoAnimation);
129 QVERIFY(m_chart->axisX());
129 QVERIFY(m_chart->axisX());
130 QVERIFY(m_chart->axisY());
130 QVERIFY(m_chart->axisY());
131 QVERIFY(m_chart->backgroundBrush()!=QBrush());
131 QVERIFY(m_chart->backgroundBrush()!=QBrush());
132 QVERIFY(m_chart->backgroundPen()!=QPen());
132 QVERIFY(m_chart->backgroundPen()!=QPen());
133 QCOMPARE(m_chart->isBackgroundVisible(), true);
133 QCOMPARE(m_chart->isBackgroundVisible(), true);
134
134
135 QVERIFY(m_chart->margins().top()>0);
135 QVERIFY(m_chart->margins().top()>0);
136 QVERIFY(m_chart->margins().left()>0);
136 QVERIFY(m_chart->margins().left()>0);
137 QVERIFY(m_chart->margins().right()>0);
137 QVERIFY(m_chart->margins().right()>0);
138 QVERIFY(m_chart->margins().bottom()>0);
138 QVERIFY(m_chart->margins().bottom()>0);
139
139
140 QCOMPARE(m_chart->theme(), QChart::ChartThemeLight);
140 QCOMPARE(m_chart->theme(), QChart::ChartThemeLight);
141 QCOMPARE(m_chart->title(), QString());
141 QCOMPARE(m_chart->title(), QString());
142
142
143 //QCOMPARE(m_chart->titleBrush(),QBrush());
143 //QCOMPARE(m_chart->titleBrush(),QBrush());
144 //QCOMPARE(m_chart->titleFont(),QFont());
144 //QCOMPARE(m_chart->titleFont(),QFont());
145
145
146 m_chart->removeAllSeries();
146 m_chart->removeAllSeries();
147 m_chart->scrollDown();
147 m_chart->scrollDown();
148 m_chart->scrollLeft();
148 m_chart->scrollLeft();
149 m_chart->scrollRight();
149 m_chart->scrollRight();
150 m_chart->scrollUp();
150 m_chart->scrollUp();
151
151
152 m_chart->zoomIn();
152 m_chart->zoomIn();
153 m_chart->zoomIn(QRectF());
153 m_chart->zoomIn(QRectF());
154 m_chart->zoomOut();
154 m_chart->zoomOut();
155 }
155 }
156
156
157 void tst_QChart::addSeries_data()
157 void tst_QChart::addSeries_data()
158 {
158 {
159 QTest::addColumn<QSeries*>("series");
159 QTest::addColumn<QSeries*>("series");
160 QTest::addColumn<QChartAxis*>("axis");
160 QTest::addColumn<QChartAxis*>("axis");
161
161
162 QSeries* series0 = new QLineSeries(this);
162 QSeries* series0 = new QLineSeries(this);
163 QSeries* series1 = new QAreaSeries(static_cast<QLineSeries*>(series0));
163 QSeries* series1 = new QAreaSeries(static_cast<QLineSeries*>(series0));
164 QSeries* series2 = new QScatterSeries(this);
164 QSeries* series2 = new QScatterSeries(this);
165 QSeries* series3 = new QSplineSeries(this);
165 QSeries* series3 = new QSplineSeries(this);
166 QSeries* series4 = new QPieSeries(this);
166 QSeries* series4 = new QPieSeries(this);
167 QSeries* series5 = new QBarSeries(QBarCategories(),this);
167 QSeries* series5 = new QBarSeries(QBarCategories(),this);
168 QSeries* series6 = new QPercentBarSeries(QBarCategories(),this);
168 QSeries* series6 = new QPercentBarSeries(QBarCategories(),this);
169 QSeries* series7 = new QStackedBarSeries(QBarCategories(),this);
169 QSeries* series7 = new QStackedBarSeries(QBarCategories(),this);
170
170
171 QChartAxis* axis = new QChartAxis(this);
171 QChartAxis* axis = new QChartAxis(this);
172
172
173 QTest::newRow("default axis: lineSeries") << series0 << (QChartAxis*) 0;
173 QTest::newRow("default axis: lineSeries") << series0 << (QChartAxis*) 0;
174 QTest::newRow("axis0: lineSeries") << series0 << axis;
174 QTest::newRow("axis0: lineSeries") << series0 << axis;
175 QTest::newRow("default axis: areaSeries") << series1 << (QChartAxis*) 0;
175 QTest::newRow("default axis: areaSeries") << series1 << (QChartAxis*) 0;
176 QTest::newRow("axis: areaSeries") << series1 << axis;
176 QTest::newRow("axis: areaSeries") << series1 << axis;
177 QTest::newRow("default axis: scatterSeries") << series2 << (QChartAxis*) 0;
177 QTest::newRow("default axis: scatterSeries") << series2 << (QChartAxis*) 0;
178 QTest::newRow("axis1: scatterSeries") << series2 << axis;
178 QTest::newRow("axis1: scatterSeries") << series2 << axis;
179 QTest::newRow("default axis: splineSeries") << series3 << (QChartAxis*) 0;
179 QTest::newRow("default axis: splineSeries") << series3 << (QChartAxis*) 0;
180 QTest::newRow("axis: splineSeries") << series3 << axis;
180 QTest::newRow("axis: splineSeries") << series3 << axis;
181 QTest::newRow("default axis: pieSeries") << series4 << (QChartAxis*) 0;
181 QTest::newRow("default axis: pieSeries") << series4 << (QChartAxis*) 0;
182 QTest::newRow("axis: pieSeries") << series4 << axis;
182 QTest::newRow("axis: pieSeries") << series4 << axis;
183 QTest::newRow("default axis: barSeries") << series5 << (QChartAxis*) 0;
183 QTest::newRow("default axis: barSeries") << series5 << (QChartAxis*) 0;
184 QTest::newRow("axis: barSeries") << series5 << axis;
184 QTest::newRow("axis: barSeries") << series5 << axis;
185 QTest::newRow("default axis: percentBarSeries") << series6 << (QChartAxis*) 0;
185 QTest::newRow("default axis: percentBarSeries") << series6 << (QChartAxis*) 0;
186 QTest::newRow("axis: barSeries") << series6 << axis;
186 QTest::newRow("axis: barSeries") << series6 << axis;
187 QTest::newRow("default axis: stackedBarSeries") << series7 << (QChartAxis*) 0;
187 QTest::newRow("default axis: stackedBarSeries") << series7 << (QChartAxis*) 0;
188 QTest::newRow("axis: barSeries") << series7 << axis;
188 QTest::newRow("axis: barSeries") << series7 << axis;
189
189
190 }
190 }
191
191
192 void tst_QChart::addSeries()
192 void tst_QChart::addSeries()
193 {
193 {
194 QFETCH(QSeries*, series);
194 QFETCH(QSeries*, series);
195 QFETCH(QChartAxis*, axis);
195 QFETCH(QChartAxis*, axis);
196 m_view->show();
196 m_view->show();
197 QTest::qWaitForWindowShown(m_view);
197 QTest::qWaitForWindowShown(m_view);
198 if(!axis) axis = m_chart->axisY();
198 if(!axis) axis = m_chart->axisY();
199 m_chart->addSeries(series,axis);
199 m_chart->addSeries(series,axis);
200 QCOMPARE(m_chart->axisY(series),axis);
200 QCOMPARE(m_chart->axisY(series),axis);
201 m_chart->removeSeries(series);
202
201 }
203 }
202
204
203 void tst_QChart::animationOptions_data()
205 void tst_QChart::animationOptions_data()
204 {
206 {
205 QTest::addColumn<QChart::AnimationOption>("animationOptions");
207 QTest::addColumn<QChart::AnimationOption>("animationOptions");
206 QTest::newRow("AllAnimations") << QChart::AllAnimations;
208 QTest::newRow("AllAnimations") << QChart::AllAnimations;
207 QTest::newRow("NoAnimation") << QChart::NoAnimation;
209 QTest::newRow("NoAnimation") << QChart::NoAnimation;
208 QTest::newRow("GridAxisAnimations") << QChart::GridAxisAnimations;
210 QTest::newRow("GridAxisAnimations") << QChart::GridAxisAnimations;
209 QTest::newRow("SeriesAnimations") << QChart::SeriesAnimations;
211 QTest::newRow("SeriesAnimations") << QChart::SeriesAnimations;
210 }
212 }
211
213
212 void tst_QChart::animationOptions()
214 void tst_QChart::animationOptions()
213 {
215 {
214 createTestData();
216 createTestData();
215 QFETCH(QChart::AnimationOption, animationOptions);
217 QFETCH(QChart::AnimationOption, animationOptions);
216 m_chart->setAnimationOptions(animationOptions);
218 m_chart->setAnimationOptions(animationOptions);
217 QCOMPARE(m_chart->animationOptions(), animationOptions);
219 QCOMPARE(m_chart->animationOptions(), animationOptions);
218 }
220 }
219
221
220 void tst_QChart::axisX_data()
222 void tst_QChart::axisX_data()
221 {
223 {
222
224
223 }
225 }
224
226
225 void tst_QChart::axisX()
227 void tst_QChart::axisX()
226 {
228 {
227 QVERIFY(m_chart->axisX());
229 QVERIFY(m_chart->axisX());
228 QChartAxis* axis = m_chart->axisX();
230 QChartAxis* axis = m_chart->axisX();
229 createTestData();
231 createTestData();
230 //it should be the same axis
232 //it should be the same axis
231 QCOMPARE(axis,m_chart->axisX());
233 QCOMPARE(axis,m_chart->axisX());
232 }
234 }
233
235
234 void tst_QChart::axisY_data()
236 void tst_QChart::axisY_data()
235 {
237 {
236 QTest::addColumn<QChartAxis*>("axis0");
238 QTest::addColumn<QChartAxis*>("axis0");
237 QTest::addColumn<QChartAxis*>("axis1");
239 QTest::addColumn<QChartAxis*>("axis1");
238 QTest::addColumn<QChartAxis*>("axis2");
240 QTest::addColumn<QChartAxis*>("axis2");
239 QTest::newRow("1 defualt, 2 optional") << (QChartAxis*)0 << new QChartAxis() << new QChartAxis();
241 QTest::newRow("1 defualt, 2 optional") << (QChartAxis*)0 << new QChartAxis() << new QChartAxis();
240 QTest::newRow("3 optional") << new QChartAxis() << new QChartAxis() << new QChartAxis();
242 QTest::newRow("3 optional") << new QChartAxis() << new QChartAxis() << new QChartAxis();
241 }
243 }
242
244
243
245
244 void tst_QChart::axisY()
246 void tst_QChart::axisY()
245 {
247 {
246 QFETCH(QChartAxis*, axis0);
248 QFETCH(QChartAxis*, axis0);
247 QFETCH(QChartAxis*, axis1);
249 QFETCH(QChartAxis*, axis1);
248 QFETCH(QChartAxis*, axis2);
250 QFETCH(QChartAxis*, axis2);
249
251
250 QChartAxis* defaultAxisY = m_chart->axisY();
252 QChartAxis* defaultAxisY = m_chart->axisY();
251
253
252 QVERIFY2(defaultAxisY, "Missing axisY.");
254 QVERIFY2(defaultAxisY, "Missing axisY.");
253
255
254 QLineSeries* series0 = new QLineSeries();
256 QLineSeries* series0 = new QLineSeries();
255 m_chart->addSeries(series0, axis0);
257 m_chart->addSeries(series0, axis0);
256
258
257 QLineSeries* series1 = new QLineSeries();
259 QLineSeries* series1 = new QLineSeries();
258 m_chart->addSeries(series1, axis1);
260 m_chart->addSeries(series1, axis1);
259
261
260 QLineSeries* series2 = new QLineSeries();
262 QLineSeries* series2 = new QLineSeries();
261 m_chart->addSeries(series2, axis2);
263 m_chart->addSeries(series2, axis2);
262
264
263 if (!axis0)
265 if (!axis0)
264 axis0 = defaultAxisY;
266 axis0 = defaultAxisY;
265 if (!axis1)
267 if (!axis1)
266 axis1 = defaultAxisY;
268 axis1 = defaultAxisY;
267 if (!axis2)
269 if (!axis2)
268 axis2 = defaultAxisY;
270 axis2 = defaultAxisY;
269
271
270 QVERIFY(m_chart->axisY(series0) == axis0);
272 QVERIFY(m_chart->axisY(series0) == axis0);
271 QVERIFY(m_chart->axisY(series1) == axis1);
273 QVERIFY(m_chart->axisY(series1) == axis1);
272 QVERIFY(m_chart->axisY(series2) == axis2);
274 QVERIFY(m_chart->axisY(series2) == axis2);
273 }
275 }
274
276
275 void tst_QChart::backgroundBrush_data()
277 void tst_QChart::backgroundBrush_data()
276 {
278 {
277 QTest::addColumn<QBrush>("backgroundBrush");
279 QTest::addColumn<QBrush>("backgroundBrush");
278 QTest::newRow("null") << QBrush();
280 QTest::newRow("null") << QBrush();
279 QTest::newRow("blue") << QBrush(Qt::blue);
281 QTest::newRow("blue") << QBrush(Qt::blue);
280 QTest::newRow("white") << QBrush(Qt::white);
282 QTest::newRow("white") << QBrush(Qt::white);
281 QTest::newRow("black") << QBrush(Qt::black);
283 QTest::newRow("black") << QBrush(Qt::black);
282 }
284 }
283
285
284 void tst_QChart::backgroundBrush()
286 void tst_QChart::backgroundBrush()
285 {
287 {
286 QFETCH(QBrush, backgroundBrush);
288 QFETCH(QBrush, backgroundBrush);
287 m_chart->setBackgroundBrush(backgroundBrush);
289 m_chart->setBackgroundBrush(backgroundBrush);
288 QCOMPARE(m_chart->backgroundBrush(), backgroundBrush);
290 QCOMPARE(m_chart->backgroundBrush(), backgroundBrush);
289 }
291 }
290
292
291 void tst_QChart::backgroundPen_data()
293 void tst_QChart::backgroundPen_data()
292 {
294 {
293 QTest::addColumn<QPen>("backgroundPen");
295 QTest::addColumn<QPen>("backgroundPen");
294 QTest::newRow("null") << QPen();
296 QTest::newRow("null") << QPen();
295 QTest::newRow("blue") << QPen(Qt::blue);
297 QTest::newRow("blue") << QPen(Qt::blue);
296 QTest::newRow("white") << QPen(Qt::white);
298 QTest::newRow("white") << QPen(Qt::white);
297 QTest::newRow("black") << QPen(Qt::black);
299 QTest::newRow("black") << QPen(Qt::black);
298 }
300 }
299
301
300
302
301 void tst_QChart::backgroundPen()
303 void tst_QChart::backgroundPen()
302 {
304 {
303 QFETCH(QPen, backgroundPen);
305 QFETCH(QPen, backgroundPen);
304 m_chart->setBackgroundPen(backgroundPen);
306 m_chart->setBackgroundPen(backgroundPen);
305 QCOMPARE(m_chart->backgroundPen(), backgroundPen);
307 QCOMPARE(m_chart->backgroundPen(), backgroundPen);
306 }
308 }
307
309
308 void tst_QChart::isBackgroundVisible_data()
310 void tst_QChart::isBackgroundVisible_data()
309 {
311 {
310 QTest::addColumn<bool>("isBackgroundVisible");
312 QTest::addColumn<bool>("isBackgroundVisible");
311 QTest::newRow("true") << true;
313 QTest::newRow("true") << true;
312 QTest::newRow("false") << false;
314 QTest::newRow("false") << false;
313 }
315 }
314
316
315 void tst_QChart::isBackgroundVisible()
317 void tst_QChart::isBackgroundVisible()
316 {
318 {
317 QFETCH(bool, isBackgroundVisible);
319 QFETCH(bool, isBackgroundVisible);
318 m_chart->setBackgroundVisible(isBackgroundVisible);
320 m_chart->setBackgroundVisible(isBackgroundVisible);
319 QCOMPARE(m_chart->isBackgroundVisible(), isBackgroundVisible);
321 QCOMPARE(m_chart->isBackgroundVisible(), isBackgroundVisible);
320
322
321 }
323 }
322
324
323 void tst_QChart::legend_data()
325 void tst_QChart::legend_data()
324 {
326 {
325
327
326 }
328 }
327
329
328 void tst_QChart::legend()
330 void tst_QChart::legend()
329 {
331 {
330 QVERIFY(m_chart->legend());
332 QVERIFY(m_chart->legend());
331 }
333 }
332
334
333 void tst_QChart::margins_data()
335 void tst_QChart::margins_data()
334 {
336 {
335
337
336 }
338 }
337
339
338 void tst_QChart::margins()
340 void tst_QChart::margins()
339 {QTest::addColumn<int>("seriesCount");
341 {QTest::addColumn<int>("seriesCount");
340 QTest::newRow("0") << 0;
342 QTest::newRow("0") << 0;
341 QTest::newRow("-1") << -1;
343 QTest::newRow("-1") << -1;
342 createTestData();
344 createTestData();
343 QRectF rect = m_chart->geometry();
345 QRectF rect = m_chart->geometry();
344
346
345 QVERIFY(m_chart->margins().top()+m_chart->margins().bottom() < rect.height());
347 QVERIFY(m_chart->margins().top()+m_chart->margins().bottom() < rect.height());
346 QVERIFY(m_chart->margins().left()+m_chart->margins().right() < rect.width());
348 QVERIFY(m_chart->margins().left()+m_chart->margins().right() < rect.width());
347
349
348 }
350 }
349
351
350 void tst_QChart::removeAllSeries_data()
352 void tst_QChart::removeAllSeries_data()
351 {
353 {
352
354
353 }
355 }
354
356
355 void tst_QChart::removeAllSeries()
357 void tst_QChart::removeAllSeries()
356 {
358 {
357 QLineSeries* series0 = new QLineSeries(this);
359 QLineSeries* series0 = new QLineSeries(this);
358 QLineSeries* series1 = new QLineSeries(this);
360 QLineSeries* series1 = new QLineSeries(this);
359 QLineSeries* series2 = new QLineSeries(this);
361 QLineSeries* series2 = new QLineSeries(this);
360
362
361 m_chart->addSeries(series0);
363 m_chart->addSeries(series0);
362 m_chart->addSeries(series1);
364 m_chart->addSeries(series1);
363 m_chart->addSeries(series2);
365 m_chart->addSeries(series2);
364 m_view->show();
366 m_view->show();
365 QTest::qWaitForWindowShown(m_view);
367 QTest::qWaitForWindowShown(m_view);
366
368
367 QVERIFY(m_chart->axisY(series0)!=0);
369 QVERIFY(m_chart->axisY(series0)!=0);
368 QVERIFY(m_chart->axisY(series1)!=0);
370 QVERIFY(m_chart->axisY(series1)!=0);
369 QVERIFY(m_chart->axisY(series2)!=0);
371 QVERIFY(m_chart->axisY(series2)!=0);
370
372
371 m_chart->removeAllSeries();
373 m_chart->removeAllSeries();
372
374
373 QVERIFY(m_chart->axisY(series0)==0);
375 QVERIFY(m_chart->axisY(series0)==0);
374 QVERIFY(m_chart->axisY(series1)==0);
376 QVERIFY(m_chart->axisY(series1)==0);
375 QVERIFY(m_chart->axisY(series2)==0);
377 QVERIFY(m_chart->axisY(series2)==0);
376 }
378 }
377
379
378 void tst_QChart::removeSeries_data()
380 void tst_QChart::removeSeries_data()
379 {
381 {
380 addSeries_data();
382 addSeries_data();
381 }
383 }
382
384
383 void tst_QChart::removeSeries()
385 void tst_QChart::removeSeries()
384 {
386 {
385 QFETCH(QSeries*, series);
387 QFETCH(QSeries*, series);
386 QFETCH(QChartAxis*, axis);
388 QFETCH(QChartAxis*, axis);
387 m_view->show();
389 m_view->show();
388 QTest::qWaitForWindowShown(m_view);
390 QTest::qWaitForWindowShown(m_view);
389 if(!axis) axis = m_chart->axisY();
391 if(!axis) axis = m_chart->axisY();
390 m_chart->addSeries(series,axis);
392 m_chart->addSeries(series,axis);
391 QCOMPARE(m_chart->axisY(series),axis);
393 QCOMPARE(m_chart->axisY(series),axis);
392 m_chart->removeSeries(series);
394 m_chart->removeSeries(series);
393 QVERIFY(m_chart->axisY(series)==0);
395 QVERIFY(m_chart->axisY(series)==0);
394 }
396 }
395
397
396 void tst_QChart::scrollDown_data()
398 void tst_QChart::scrollDown_data()
397 {
399 {
398
400
399 }
401 }
400
402
401 void tst_QChart::scrollDown()
403 void tst_QChart::scrollDown()
402 {
404 {
403 createTestData();
405 createTestData();
404 qreal min = m_chart->axisY()->min();
406 qreal min = m_chart->axisY()->min();
405 m_chart->scrollDown();
407 m_chart->scrollDown();
406 QVERIFY(m_chart->axisY()->min()<min);
408 QVERIFY(m_chart->axisY()->min()<min);
407 }
409 }
408
410
409 void tst_QChart::scrollLeft_data()
411 void tst_QChart::scrollLeft_data()
410 {
412 {
411
413
412 }
414 }
413
415
414 void tst_QChart::scrollLeft()
416 void tst_QChart::scrollLeft()
415 {
417 {
416 createTestData();
418 createTestData();
417 qreal min = m_chart->axisX()->min();
419 qreal min = m_chart->axisX()->min();
418 m_chart->scrollLeft();
420 m_chart->scrollLeft();
419 QVERIFY(m_chart->axisX()->min()<min);
421 QVERIFY(m_chart->axisX()->min()<min);
420 }
422 }
421
423
422 void tst_QChart::scrollRight_data()
424 void tst_QChart::scrollRight_data()
423 {
425 {
424
426
425 }
427 }
426
428
427 void tst_QChart::scrollRight()
429 void tst_QChart::scrollRight()
428 {
430 {
429 createTestData();
431 createTestData();
430 qreal min = m_chart->axisX()->min();
432 qreal min = m_chart->axisX()->min();
431 m_chart->scrollRight();
433 m_chart->scrollRight();
432 QVERIFY(m_chart->axisX()->min()>min);
434 QVERIFY(m_chart->axisX()->min()>min);
433 }
435 }
434
436
435 void tst_QChart::scrollUp_data()
437 void tst_QChart::scrollUp_data()
436 {
438 {
437
439
438 }
440 }
439
441
440 void tst_QChart::scrollUp()
442 void tst_QChart::scrollUp()
441 {
443 {
442 createTestData();
444 createTestData();
443 qreal min = m_chart->axisY()->min();
445 qreal min = m_chart->axisY()->min();
444 m_chart->scrollUp();
446 m_chart->scrollUp();
445 QVERIFY(m_chart->axisY()->min()>min);
447 QVERIFY(m_chart->axisY()->min()>min);
446 }
448 }
447
449
448 void tst_QChart::theme_data()
450 void tst_QChart::theme_data()
449 {
451 {
450 QTest::addColumn<QChart::ChartTheme>("theme");
452 QTest::addColumn<QChart::ChartTheme>("theme");
451 QTest::newRow("ChartThemeBlueCerulean") << QChart::ChartThemeBlueCerulean;
453 QTest::newRow("ChartThemeBlueCerulean") << QChart::ChartThemeBlueCerulean;
452 QTest::newRow("ChartThemeBlueIcy") << QChart::ChartThemeBlueIcy;
454 QTest::newRow("ChartThemeBlueIcy") << QChart::ChartThemeBlueIcy;
453 QTest::newRow("ChartThemeBlueNcs") << QChart::ChartThemeBlueNcs;
455 QTest::newRow("ChartThemeBlueNcs") << QChart::ChartThemeBlueNcs;
454 QTest::newRow("ChartThemeBrownSand") << QChart::ChartThemeBrownSand;
456 QTest::newRow("ChartThemeBrownSand") << QChart::ChartThemeBrownSand;
455 QTest::newRow("ChartThemeDark") << QChart::ChartThemeDark;
457 QTest::newRow("ChartThemeDark") << QChart::ChartThemeDark;
456 QTest::newRow("hartThemeHighContrast") << QChart::ChartThemeHighContrast;
458 QTest::newRow("hartThemeHighContrast") << QChart::ChartThemeHighContrast;
457 QTest::newRow("ChartThemeLight") << QChart::ChartThemeLight;
459 QTest::newRow("ChartThemeLight") << QChart::ChartThemeLight;
458 }
460 }
459
461
460 void tst_QChart::theme()
462 void tst_QChart::theme()
461 {
463 {
462 QFETCH(QChart::ChartTheme, theme);
464 QFETCH(QChart::ChartTheme, theme);
463 createTestData();
465 createTestData();
464 m_chart->setTheme(theme);
466 m_chart->setTheme(theme);
465 QVERIFY(m_chart->theme()==theme);
467 QVERIFY(m_chart->theme()==theme);
466 }
468 }
467
469
468 void tst_QChart::title_data()
470 void tst_QChart::title_data()
469 {
471 {
470 QTest::addColumn<QString>("title");
472 QTest::addColumn<QString>("title");
471 QTest::newRow("null") << QString();
473 QTest::newRow("null") << QString();
472 QTest::newRow("foo") << QString("foo");
474 QTest::newRow("foo") << QString("foo");
473 }
475 }
474
476
475 void tst_QChart::title()
477 void tst_QChart::title()
476 {
478 {
477 QFETCH(QString, title);
479 QFETCH(QString, title);
478 m_chart->setTitle(title);
480 m_chart->setTitle(title);
479 QCOMPARE(m_chart->title(), title);
481 QCOMPARE(m_chart->title(), title);
480 }
482 }
481
483
482 void tst_QChart::titleBrush_data()
484 void tst_QChart::titleBrush_data()
483 {
485 {
484 QTest::addColumn<QBrush>("titleBrush");
486 QTest::addColumn<QBrush>("titleBrush");
485 QTest::newRow("null") << QBrush();
487 QTest::newRow("null") << QBrush();
486 QTest::newRow("blue") << QBrush(Qt::blue);
488 QTest::newRow("blue") << QBrush(Qt::blue);
487 QTest::newRow("white") << QBrush(Qt::white);
489 QTest::newRow("white") << QBrush(Qt::white);
488 QTest::newRow("black") << QBrush(Qt::black);
490 QTest::newRow("black") << QBrush(Qt::black);
489 }
491 }
490
492
491 void tst_QChart::titleBrush()
493 void tst_QChart::titleBrush()
492 {
494 {
493 QFETCH(QBrush, titleBrush);
495 QFETCH(QBrush, titleBrush);
494 m_chart->setTitleBrush(titleBrush);
496 m_chart->setTitleBrush(titleBrush);
495 QCOMPARE(m_chart->titleBrush(), titleBrush);
497 QCOMPARE(m_chart->titleBrush(), titleBrush);
496 }
498 }
497
499
498 void tst_QChart::titleFont_data()
500 void tst_QChart::titleFont_data()
499 {
501 {
500 QTest::addColumn<QFont>("titleFont");
502 QTest::addColumn<QFont>("titleFont");
501 QTest::newRow("null") << QFont();
503 QTest::newRow("null") << QFont();
502 QTest::newRow("courier") << QFont("Courier", 8, QFont::Bold, true);
504 QTest::newRow("courier") << QFont("Courier", 8, QFont::Bold, true);
503 }
505 }
504
506
505 void tst_QChart::titleFont()
507 void tst_QChart::titleFont()
506 {
508 {
507 QFETCH(QFont, titleFont);
509 QFETCH(QFont, titleFont);
508 m_chart->setTitleFont(titleFont);
510 m_chart->setTitleFont(titleFont);
509 QCOMPARE(m_chart->titleFont(), titleFont);
511 QCOMPARE(m_chart->titleFont(), titleFont);
510 }
512 }
511
513
512 void tst_QChart::zoomIn_data()
514 void tst_QChart::zoomIn_data()
513 {
515 {
514 QTest::addColumn<QRectF>("rect");
516 QTest::addColumn<QRectF>("rect");
515 QTest::newRow("null") << QRectF();
517 QTest::newRow("null") << QRectF();
516 QTest::newRow("100x100") << QRectF(10,10,100,100);
518 QTest::newRow("100x100") << QRectF(10,10,100,100);
517 QTest::newRow("200x200") << QRectF(10,10,200,200);
519 QTest::newRow("200x200") << QRectF(10,10,200,200);
518 }
520 }
519
521
520
522
521 void tst_QChart::zoomIn()
523 void tst_QChart::zoomIn()
522 {
524 {
523 QFETCH(QRectF, rect);
525 QFETCH(QRectF, rect);
524 createTestData();
526 createTestData();
525 QRectF marigns = m_chart->margins();
527 QRectF marigns = m_chart->margins();
526 rect.adjust(marigns.left(),marigns.top(),-marigns.right(),-marigns.bottom());
528 rect.adjust(marigns.left(),marigns.top(),-marigns.right(),-marigns.bottom());
527 qreal minX = m_chart->axisX()->min();
529 qreal minX = m_chart->axisX()->min();
528 qreal minY = m_chart->axisY()->min();
530 qreal minY = m_chart->axisY()->min();
529 qreal maxX = m_chart->axisX()->max();
531 qreal maxX = m_chart->axisX()->max();
530 qreal maxY = m_chart->axisY()->max();
532 qreal maxY = m_chart->axisY()->max();
531 m_chart->zoomIn(rect);
533 m_chart->zoomIn(rect);
532 if(rect.isValid()){
534 if(rect.isValid()){
533 QVERIFY(minX<m_chart->axisX()->min());
535 QVERIFY(minX<m_chart->axisX()->min());
534 QVERIFY(maxX>m_chart->axisX()->max());
536 QVERIFY(maxX>m_chart->axisX()->max());
535 QVERIFY(minY<m_chart->axisY()->min());
537 QVERIFY(minY<m_chart->axisY()->min());
536 QVERIFY(maxY>m_chart->axisY()->max());
538 QVERIFY(maxY>m_chart->axisY()->max());
537 }
539 }
538 }
540 }
539
541
540 void tst_QChart::zoomOut_data()
542 void tst_QChart::zoomOut_data()
541 {
543 {
542
544
543 }
545 }
544
546
545 void tst_QChart::zoomOut()
547 void tst_QChart::zoomOut()
546 {
548 {
547 createTestData();
549 createTestData();
548 qreal minX = m_chart->axisX()->min();
550 qreal minX = m_chart->axisX()->min();
549 qreal minY = m_chart->axisY()->min();
551 qreal minY = m_chart->axisY()->min();
550 qreal maxX = m_chart->axisX()->max();
552 qreal maxX = m_chart->axisX()->max();
551 qreal maxY = m_chart->axisY()->max();
553 qreal maxY = m_chart->axisY()->max();
552
554
553 m_chart->zoomIn();
555 m_chart->zoomIn();
554
556
555 QVERIFY(minX<m_chart->axisX()->min());
557 QVERIFY(minX<m_chart->axisX()->min());
556 QVERIFY(maxX>m_chart->axisX()->max());
558 QVERIFY(maxX>m_chart->axisX()->max());
557 QVERIFY(minY<m_chart->axisY()->min());
559 QVERIFY(minY<m_chart->axisY()->min());
558 QVERIFY(maxY>m_chart->axisY()->max());
560 QVERIFY(maxY>m_chart->axisY()->max());
559
561
560 m_chart->zoomOut();
562 m_chart->zoomOut();
561
563
562 QVERIFY(minX==m_chart->axisX()->min());
564 QVERIFY(minX==m_chart->axisX()->min());
563 QVERIFY(maxX==m_chart->axisX()->max());
565 QVERIFY(maxX==m_chart->axisX()->max());
564 QVERIFY(minY==m_chart->axisY()->min());
566 QVERIFY(minY==m_chart->axisY()->min());
565 QVERIFY(maxY==m_chart->axisY()->max());
567 QVERIFY(maxY==m_chart->axisY()->max());
566 }
568 }
567
569
568 QTEST_MAIN(tst_QChart)
570 QTEST_MAIN(tst_QChart)
569 #include "tst_qchart.moc"
571 #include "tst_qchart.moc"
570
572
General Comments 0
You need to be logged in to leave comments. Login now