##// END OF EJS Templates
Docs updated
Marek Rosa -
r908:803e57309061
parent child
Show More
@@ -1,29 +1,29
1 1 /*!
2 2 \example examples/splinechart
3 3 \title SplineChart Example
4 4 \subtitle
5 5
6 6 The example shows how to create simple spline chart.
7 7
8 8 \image splinechart_example
9 9
10 10 To create spline chart we need to put our data into QSplineSeries. QSplineSeries automatically calculates spline segment control points that are needed to properly draw the spline.
11 11
12 12 \snippet ../examples/splinechart/main.cpp 1
13 13
14 Now lets add some data points to the series.
14 Now let's add some data points to the series.
15 15
16 \snippet ../examples/splinechart/main.cpp 3
16 \snippet ../examples/splinechart/main.cpp 2
17 17
18 18 The data series has been populated. To display it on a chart we create QChart object and add the data series to it. We also set the title and the values range on y axis, so that our chart is better visible.
19 19
20 \snippet ../examples/splinechart/main.cpp 4
20 \snippet ../examples/splinechart/main.cpp 3
21 21
22 22 Then we create a QChartView object with QChart as a parameter. This way we don't need to create QGraphicsView scene ourselves. We also set the Antialiasing on to have the rendered lines look nicer.
23 23
24 \snippet ../examples/splinechart/main.cpp 5
24 \snippet ../examples/splinechart/main.cpp 4
25 25
26 26 In the end we set the QChartView as the windows's central widget.
27 27
28 \snippet ../examples/splinechart/main.cpp 6
28 \snippet ../examples/splinechart/main.cpp 5
29 29 */
@@ -1,71 +1,65
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include <QApplication>
22 22 #include <QMainWindow>
23 23 #include <QChartView>
24 24 #include <QSplineSeries>
25 25
26 26 QTCOMMERCIALCHART_USE_NAMESPACE
27 27
28 28 int main(int argc, char *argv[])
29 29 {
30 30 QApplication a(argc, argv);
31 31
32 32 //![1]
33 33 QSplineSeries* series = new QSplineSeries();
34 34 //![1]
35 35
36 36 //![2]
37 // QPen red(Qt::red);
38 // red.setWidth(3);
39 // series->setPen(red);
40 //![2]
41
42 //![3]
43 37 series->append(0, 6);
44 38 series->append(2, 4);
45 39 series->append(3, 8);
46 40 series->append(7, 4);
47 41 series->append(10, 5);
48 42 *series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);
49 //![3]
43 //![2]
50 44
51 //![4]
45 //![3]
52 46 QChart* chart = new QChart();
53 47 chart->addSeries(series);
54 48 chart->setTitle("Simple spline chart example");
55 49 chart->axisY()->setRange(0, 10);
56 //![4]
50 //![3]
57 51
58 //![5]
52 //![4]
59 53 QChartView* chartView = new QChartView(chart);
60 54 chartView->setRenderHint(QPainter::Antialiasing);
61 //![5]
55 //![4]
62 56
63 //![6]
57 //![5]
64 58 QMainWindow window;
65 59 window.setCentralWidget(chartView);
66 60 window.resize(400, 300);
67 61 window.show();
68 //![6]
62 //![5]
69 63
70 64 return a.exec();
71 65 }
@@ -1,283 +1,279
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qbarset.h"
22 22 #include <QDebug>
23 23 #include <QToolTip>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 /*!
28 28 \class QBarSet
29 29 \brief part of QtCommercial chart API.
30 30
31 31 QBarSet represents one set of bars. Set of bars contains one data value for each category.
32 32 First value of set is assumed to belong to first category, second to second category and so on.
33 33 If set has fewer values than there are categories, then the missing values are assumed to be
34 34 at the end of set. For missing values in middle of a set, numerical value of zero is used.
35 35
36 36 \mainclass
37 37
38 38 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
39 39 */
40 40
41 41 /*!
42 42 \fn void QBarSet::clicked(QString category, Qt::MouseButtons button)
43 43 \brief signals that set has been clicked
44 44 Parameter \a category describes on which category was clicked
45 45 Parameter \a button mouse button
46 46 */
47 47
48 48 /*!
49 49 \fn void QBarSet::hoverEnter(QPoint pos)
50 50 \brief signals that mouse has entered over the set at position \a pos.
51 51 */
52 52
53 53 /*!
54 54 \fn void QBarSet::hoverLeave()
55 55 \brief signals that mouse has left from the set.
56 56 */
57 57
58 58 /*!
59 \fn void QBarSet::setLabelssVisible(bool visible = true)
60 \brief Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
61 */
62
63 /*!
64 59 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
65 60 \brief \internal \a pos \a tip
66 61 */
67 62
68 63
69 64 /*!
70 65 Constructs QBarSet with a name of \a name and with parent of \a parent
71 66 */
72 67 QBarSet::QBarSet(QString name, QObject *parent)
73 68 : QObject(parent)
74 69 ,m_name(name)
75 70 ,m_labelsVisible(false)
76 71 {
77 72 }
78 73
79 74 /*!
80 75 Sets new \a name for set.
81 76 */
82 77 void QBarSet::setName(QString name)
83 78 {
84 79 m_name = name;
85 80 }
86 81
87 82 /*!
88 83 Returns name of the set.
89 84 */
90 85 QString QBarSet::name() const
91 86 {
92 87 return m_name;
93 88 }
94 89
95 90 /*!
96 91 Appends new value \a value to the end of set.
97 92 */
98 93 QBarSet& QBarSet::operator << (const qreal &value)
99 94 {
100 95 m_values.append(value);
101 96 emit structureChanged();
102 97 return *this;
103 98 }
104 99
105 100 /*!
106 101 Inserts new \a value on the \a i position.
107 102 The value that is currently at this postion is moved to postion i + 1
108 103 \sa removeValue()
109 104 */
110 105 void QBarSet::insertValue(int i, qreal value)
111 106 {
112 107 m_values.insert(i, value);
113 108 }
114 109
115 110 /*!
116 111 Removes the value specified by \a i
117 112 \sa insertValue()
118 113 */
119 114 void QBarSet::removeValue(int i)
120 115 {
121 116 m_values.removeAt(i);
122 117 }
123 118
124 119 /*!
125 120 Returns count of values in set.
126 121 */
127 122 int QBarSet::count() const
128 123 {
129 124 return m_values.count();
130 125 }
131 126
132 127 /*!
133 128 Returns value of set indexed by \a index
134 129 */
135 130 qreal QBarSet::valueAt(int index) const
136 131 {
137 132 return m_values.at(index);
138 133 }
139 134
140 135 /*!
141 136 Sets a new value \a value to set, indexed by \a index
142 137 */
143 138 void QBarSet::setValue(int index, qreal value)
144 139 {
145 140 m_values.replace(index,value);
146 141 emit valueChanged();
147 142 }
148 143
149 144 /*!
150 145 Returns total sum of all values in barset.
151 146 */
152 147 qreal QBarSet::total() const
153 148 {
154 149 qreal total(0);
155 150 for (int i=0; i < m_values.count(); i++) {
156 151 total += m_values.at(i);
157 152 }
158 153 return total;
159 154 }
160 155
161 156 /*!
162 157 Sets pen for set. Bars of this set are drawn using \a pen
163 158 */
164 159 void QBarSet::setPen(const QPen &pen)
165 160 {
166 161 m_pen = pen;
167 162 emit valueChanged();
168 163 }
169 164
170 165 /*!
171 166 Returns pen of the set.
172 167 */
173 168 QPen QBarSet::pen() const
174 169 {
175 170 return m_pen;
176 171 }
177 172
178 173 /*!
179 174 Sets brush for the set. Bars of this set are drawn using \a brush
180 175 */
181 176 void QBarSet::setBrush(const QBrush &brush)
182 177 {
183 178 m_brush = brush;
184 179 emit valueChanged();
185 180 }
186 181
187 182 /*!
188 183 Returns brush of the set.
189 184 */
190 185 QBrush QBarSet::brush() const
191 186 {
192 187 return m_brush;
193 188 }
194 189
195 190 /*!
196 191 Sets \a pen of the values that are drawn on top of this barset
197 192 */
198 193 void QBarSet::setLabelPen(const QPen &pen)
199 194 {
200 195 m_labelPen = pen;
201 196 emit valueChanged();
202 197 }
203 198
204 199 /*!
205 200 Returns pen of the values that are drawn on top of this barset
206 201 */
207 202 QPen QBarSet::labelPen() const
208 203 {
209 204 return m_labelPen;
210 205 }
211 206
212 207 /*!
213 208 Sets \a brush of the values that are drawn on top of this barset
214 209 */
215 210 void QBarSet::setLabelBrush(const QBrush &brush)
216 211 {
217 212 m_labelBrush = brush;
218 213 emit valueChanged();
219 214 }
220 215
221 216 /*!
222 217 Returns brush of the values that are drawn on top of this barset
223 218 */
224 219 QBrush QBarSet::labelBrush() const
225 220 {
226 221 return m_labelBrush;
227 222 }
228 223
229 224 /*!
230 225 Sets the \a font for values that are drawn on top of this barset
231 226 */
232 227 void QBarSet::setLabelFont(const QFont &font)
233 228 {
234 229 m_labelFont = font;
235 230 emit valueChanged();
236 231 }
237 232
238 233 /*!
239 234 Returns the pen for values that are drawn on top of this set
240 235 */
241 236 QFont QBarSet::labelFont() const
242 237 {
243 238 return m_labelFont;
244 239 }
245 240
246 241 /*!
247 Sets the visibility of barset values to \a visible
242 Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
248 243 */
244
249 245 void QBarSet::setLabelsVisible(bool visible)
250 246 {
251 247 m_labelsVisible = visible;
252 248 emit labelsVisibleChanged(visible);
253 249 }
254 250
255 251 /*!
256 252 Returns the visibility of values
257 253 */
258 254 bool QBarSet::labelsVisible() const
259 255 {
260 256 return m_labelsVisible;
261 257 }
262 258
263 259 /*!
264 260 \internal \a pos
265 261 */
266 262 void QBarSet::barHoverEnterEvent(QPoint pos)
267 263 {
268 264 emit showToolTip(pos, m_name);
269 265 emit hoverEnter(pos);
270 266 }
271 267
272 268 /*!
273 269 \internal
274 270 */
275 271 void QBarSet::barHoverLeaveEvent()
276 272 {
277 273 // Emit signal to user of charts
278 274 emit hoverLeave();
279 275 }
280 276
281 277 #include "moc_qbarset.cpp"
282 278
283 279 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,92
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qseries.h"
22 22
23 23 /*!
24 24 \class QSeries
25 25 \brief Base class for all QtCommercial Chart series.
26 26 \mainclass
27 27
28 28 Usually you use the series type specific inherited classes instead of the base class.
29 29 \sa QScatterSeries
30 30 */
31 31
32 32 /*!
33 33 \enum QSeries::QSeriesType
34 34
35 35 The type of the series object.
36 36
37 37 \value SeriesTypeLine
38 38 \value SeriesTypeArea
39 39 \value SeriesTypeBar
40 40 \value SeriesTypeStackedBar
41 41 \value SeriesTypePercentBar
42 42 \value SeriesTypePie
43 43 \value SeriesTypeScatter
44 44 \value SeriesTypeSpline
45 45 */
46 46
47 47 /*!
48 48 \fn QSeries::QSeries(QObject *parent)
49 49 \brief Constructs ChartSeries object with \a parent.
50 50 */
51 51
52 52 /*!
53 53 \fn QSeries::~QSeries()
54 54 \brief Virtual destructor for the chart series.
55 55 */
56 56
57 57 /*!
58 58 \fn QSeriesType QSeries::type() const
59 59 \brief The type of the series.
60 60 */
61 61
62 62 /*!
63 63 \fn bool QSeries::setModel(QAbstractItemModel *model)
64 64 \brief Use the \a model to provide data for the series. The model overrides possible user data
65 65 set with QChartSeries type specific data setters. For example if you call both
66 66 QScatterSeries::addData() and QScatterSeries::setModel, only the data provided by the model is
67 67 used by the series. Returns true if the model is valid for the series.
68 68 */
69 69
70 70 /*!
71 \property QString QSeries::name
72 \brief name of the series property
73 */
74
75 /*!
71 76 \fn void QSeries::setName(QString name)
72 77 \brief Sets a \a name for the series.
73 78
74 79 The name of a series is shown in the legend for QXYSeries.
75 80 \sa QChart::setTitle()
76 81 \sa QPieSlice::setLabel()
77 82 \sa QBarSet::setName()
78 83 */
79 84
80 85 /*!
81 \fn QString QSeries::name()
86 \fn QString QSeries::name() const
82 87 \brief Returns the name of the series.
88 \sa setName()
83 89 */
84 90
85 91 QTCOMMERCIALCHART_USE_NAMESPACE
86 92 #include "moc_qseries.cpp"
@@ -1,198 +1,198
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qsplineseries.h"
22 22
23 23 /*!
24 24 \class QSplineSeries
25 25 \brief Series type used to store data needed to draw a spline.
26 26
27 27 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
28 28 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
29 29 */
30 30
31 31 /*!
32 32 \fn QSeriesType QSplineSeries::type() const
33 33 Returns the type of the series
34 34 */
35 35
36 36 /*!
37 37 \fn QSeriesType QSplineSeries::controlPoint(int index) const
38 38 Returns the control point specified by \a index
39 39 */
40 40
41 41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42 42
43 43 /*!
44 44 Constructs empty series object which is a child of \a parent.
45 45 When series object is added to QChartView or QChart instance then the ownerships is transfered.
46 46 */
47 47
48 48 QSplineSeries::QSplineSeries(QObject *parent) :
49 49 QLineSeries(parent)
50 50 {
51 51 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
52 52 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
53 53 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
54 54 }
55 55
56 56 /*!
57 57 \internal
58 58 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
59 59 */
60 60 void QSplineSeries::calculateControlPoints()
61 61 {
62 62
63 63 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
64 64 // CPOL License
65 65
66 66 int n = count() - 1;
67 67 if (n == 1)
68 68 { // Special case: Bezier curve should be a straight line.
69 69 // firstControlPoints = new Point[1];
70 70 // 3P1 = 2P0 + P3
71 71 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
72 72
73 73 // P2 = 2P1 P0
74 74 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
75 75 return;
76 76 }
77 77
78 78 // Calculate first Bezier control points
79 79 // Right hand side vector
80 80 // Set of equations for P0 to Pn points.
81 81 //
82 82 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
83 83 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
84 84 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
85 85 // | . . . . . . . . . . . . | | ... | | ... |
86 86 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
87 87 // | . . . . . . . . . . . . | | ... | | ... |
88 88 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
89 89 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
90 90 //
91 91 QList<qreal> rhs;
92 92 rhs.append(x(0) + 2 * x(1));
93 93
94 94 // Set right hand side X values
95 95 for (int i = 1; i < n - 1; ++i)
96 96 rhs.append(4 * x(i) + 2 * x(i + 1));
97 97
98 98 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
99 99 // Get first control points X-values
100 100 QList<qreal> xControl = getFirstControlPoints(rhs);
101 101 rhs[0] = y(0) + 2 * y(1);
102 102
103 103 // Set right hand side Y values
104 104 for (int i = 1; i < n - 1; ++i)
105 105 rhs[i] = 4 * y(i) + 2 * y(i + 1);
106 106
107 107 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
108 108 // Get first control points Y-values
109 109 QList<qreal> yControl = getFirstControlPoints(rhs);
110 110
111 111 // Fill output arrays.
112 112 for (int i = 0; i < n; ++i) {
113 113 // First control point
114 114 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
115 115 // Second control point
116 116 if (i < n - 1)
117 117 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
118 118 else
119 119 m_controlPoints.append(QPointF((x(n) + xControl[n - 1]) / 2, (y(n) + yControl[n - 1]) / 2));
120 120 }
121 121 }
122 122
123 123 /*!
124 124 \internal
125 125 */
126 126 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
127 127 {
128 128 QList<qreal> x; // Solution vector.
129 129 QList<qreal> tmp; // Temp workspace.
130 130
131 131 qreal b = 2.0;
132 132 x.append(rhs[0] / b);
133 133 tmp.append(0);
134 134 for (int i = 1; i < rhs.size(); i++) {
135 135 // Decomposition and forward substitution.
136 136 tmp.append(1 / b);
137 137 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
138 138 x.append((rhs[i] - x[i - 1]) / b);
139 139 }
140 140 for (int i = 1; i < rhs.size(); i++)
141 141 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
142 142
143 143 return x;
144 144 }
145 145
146 146 /*!
147 147 \internal
148 148 Updates the control points, besed on currently avaiable knots.
149 149 */
150 150 void QSplineSeries::updateControlPoints()
151 151 {
152 152 if (count() > 1) {
153 153 m_controlPoints.clear();
154 154 calculateControlPoints();
155 155 }
156 156 }
157 157
158 /*!
158 /*//!
159 159 \fn bool QSplineSeries::setModel(QAbstractItemModel *model)
160 160 Sets the \a model to be used as a data source
161 161 \sa setModelMapping(), setModelMappingRange()
162 162 */
163 163 //bool QSplineSeries::setModel(QAbstractItemModel* model)
164 164 //{
165 165 // QXYSeries::setModel(model);
166 166 //// calculateControlPoints();
167 167 // return true;
168 168 //}
169 169
170 /*!
171 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
170 /*//!
171 \fn bool QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
172 172 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
173 173 as a data source for y coordinate. The \a orientation paramater specifies whether the data
174 174 is in columns or in rows.
175 175 */
176 176 //void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
177 177 //{
178 178 // QLineSeries::setModelMapping(modelX, modelY, orientation);
179 179 //// calculateControlPoints();
180 180 //}
181 181
182 182 /*!
183 183 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
184 184 Allows limiting the model mapping.
185 185 Parameter \a first specifies which element of the model should be used as a first one of the series.
186 186 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
187 187 then all the items following \a first item in a model are used.
188 188 \sa setModel(), setModelMapping()
189 189 */
190 190 void QSplineSeries::setModelMappingRange(int first, int count)
191 191 {
192 192 QLineSeries::setModelMappingRange(first, count);
193 193 calculateControlPoints();
194 194 }
195 195
196 196 #include "moc_qsplineseries.cpp"
197 197
198 198 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,564 +1,559
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qxyseries.h"
22 22 #include <QAbstractItemModel>
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \class QXYSeries
28 28 \brief The QXYSeries class is a base class for line, spline and scatter series.
29 29 */
30 30
31 31 /*!
32 32 \fn QPen QXYSeries::pen() const
33 33 \brief Returns pen used to draw points for series.
34 34 \sa setPen()
35 35 */
36 36
37 37 /*!
38 38 \fn QBrush QXYSeries::brush() const
39 39 \brief Returns brush used to draw points for series.
40 40 \sa setBrush()
41 41 */
42 42
43 43 /*!
44 44 \fn void QXYSeries::clicked(const QPointF& point)
45 45 \brief Signal is emitted when user clicks the \a point on chart.
46 46 */
47 47
48 48 /*!
49 49 \fn void QXYSeries::pointReplaced(int index)
50 50 \brief \internal \a index
51 51 */
52 52
53 53 /*!
54 54 \fn void QXYSeries::pointAdded(int index)
55 55 \brief \internal \a index
56 56 */
57 57
58 58 /*!
59 59 \fn void QXYSeries::pointRemoved(int index)
60 60 \brief \internal \a index
61 61 */
62 62
63 63 /*!
64 64 \fn void QXYSeries::updated()
65 65 \brief \internal
66 66 */
67 67
68 68 /*!
69 69 \fn int QXYSeries::mapFirst() const
70 70 Returns the index of the model's item that is used as a first one for the series.
71 71 \sa mapCount()
72 72 */
73 73
74 74 /*!
75 75 \fn int QXYSeries::mapCount() const
76 76 Returns the number of the items that are taken from the model.
77 77 If -1 it means all the items of the model following the first one are used.
78 78 \sa mapFirst()
79 79 */
80 80
81 81 /*!
82 82 Constructs empty series object which is a child of \a parent.
83 83 When series object is added to QChartView or QChart instance ownerships is transfered.
84 84 */
85 85 QXYSeries::QXYSeries(QObject *parent):QSeries(parent)
86 86 {
87 87 m_mapX = -1;
88 88 m_mapY = -1;
89 89 m_mapFirst = 0;
90 90 m_mapCount = 0;
91 91 m_mapLimited = false;
92 92 m_mapOrientation = Qt::Vertical;
93 93 // m_mapYOrientation = Qt::Vertical;
94 94 }
95 95 /*!
96 96 Destroys the object. Series added to QChartView or QChart instances are owned by those,
97 97 and are deleted when mentioned object are destroyed.
98 98 */
99 99 QXYSeries::~QXYSeries()
100 100 {
101 101 }
102 102
103 103 /*!
104 104 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
105 105 */
106 106 void QXYSeries::append(qreal x,qreal y)
107 107 {
108 108 Q_ASSERT(m_x.size() == m_y.size());
109 109 m_x<<x;
110 110 m_y<<y;
111 111 emit pointAdded(m_x.size()-1);
112 112 }
113 113
114 114 /*!
115 115 This is an overloaded function.
116 116 Adds data \a point to the series. Points are connected with lines on the chart.
117 117 */
118 118 void QXYSeries::append(const QPointF &point)
119 119 {
120 120 append(point.x(),point.y());
121 121 }
122 122
123 123 /*!
124 124 This is an overloaded function.
125 125 Adds list of data \a points to the series. Points are connected with lines on the chart.
126 126 */
127 127 void QXYSeries::append(const QList<QPointF> points)
128 128 {
129 129 foreach(const QPointF& point , points) {
130 130 append(point.x(),point.y());
131 131 }
132 132 }
133 133
134 134 /*!
135 135 Modifies \a y value for given \a x a value.
136 136 */
137 137 void QXYSeries::replace(qreal x,qreal y)
138 138 {
139 139 int index = m_x.indexOf(x);
140 140 m_x[index] = x;
141 141 m_y[index] = y;
142 142 emit pointReplaced(index);
143 143 }
144 144
145 145 /*!
146 146 This is an overloaded function.
147 147 Replaces current y value of for given \a point x value with \a point y value.
148 148 */
149 149 void QXYSeries::replace(const QPointF &point)
150 150 {
151 151 replace(point.x(),point.y());
152 152 }
153 153
154 154 /*!
155 155 Removes first \a x value and related y value.
156 156 */
157 157 void QXYSeries::remove(qreal x)
158 158 {
159 159 int index = m_x.indexOf(x);
160 160
161 161 if (index == -1) return;
162 162
163 163 m_x.remove(index);
164 164 m_y.remove(index);
165 165
166 166 emit pointRemoved(index);
167 167 }
168 168
169 169 /*!
170 170 Removes current \a x and \a y value.
171 171 */
172 172 void QXYSeries::remove(qreal x,qreal y)
173 173 {
174 174 int index =-1;
175 175 do {
176 176 index = m_x.indexOf(x,index+1);
177 177 } while (index !=-1 && m_y.at(index)!=y);
178 178
179 179 if (index==-1) return;
180 180
181 181 m_x.remove(index);
182 182 m_y.remove(index);
183 183 emit pointRemoved(index);
184 184 }
185 185
186 186 /*!
187 187 Removes current \a point x value. Note \a point y value is ignored.
188 188 */
189 189 void QXYSeries::remove(const QPointF &point)
190 190 {
191 191 remove(point.x(),point.y());
192 192 }
193 193
194 194 /*!
195 195 Removes all data points from the series.
196 196 */
197 197 void QXYSeries::removeAll()
198 198 {
199 199 m_x.clear();
200 200 m_y.clear();
201 201 }
202 202
203 203 /*!
204 204 \internal \a pos
205 205 */
206 206 qreal QXYSeries::x(int pos) const
207 207 {
208 208 if (m_model) {
209 209 if (m_mapOrientation == Qt::Vertical)
210 210 // consecutive data is read from model's column
211 211 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
212 212 else
213 213 // consecutive data is read from model's row
214 214 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
215 215 } else {
216 216 // model is not specified, return the data from series' internal data store
217 217 return m_x.at(pos);
218 218 }
219 219 }
220 220
221 221 /*!
222 222 \internal \a pos
223 223 */
224 224 qreal QXYSeries::y(int pos) const
225 225 {
226 226 if (m_model) {
227 227 if (m_mapOrientation == Qt::Vertical)
228 228 // consecutive data is read from model's column
229 229 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
230 230 else
231 231 // consecutive data is read from model's row
232 232 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
233 233 } else {
234 234 // model is not specified, return the data from series' internal data store
235 235 return m_y.at(pos);
236 236 }
237 237 }
238 238
239 239 /*!
240 240 Returns number of data points within series.
241 241 */
242 242 int QXYSeries::count() const
243 243 {
244 244 Q_ASSERT(m_x.size() == m_y.size());
245 245
246 246 if (m_model) {
247 247 if (m_mapOrientation == Qt::Vertical) {
248 248 // data is in a column. Return the number of mapped items if the model's column have enough items
249 249 // or the number of items that can be mapped
250 250 if (m_mapLimited)
251 251 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
252 252 else
253 253 return qMax(m_model->rowCount() - m_mapFirst, 0);
254 254 } else {
255 255 // data is in a row. Return the number of mapped items if the model's row have enough items
256 256 // or the number of items that can be mapped
257 257 if (m_mapLimited)
258 258 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
259 259 else
260 260 return qMax(m_model->columnCount() - m_mapFirst, 0);
261 261 }
262 262 }
263 263
264 264 // model is not specified, return the number of points in the series internal data store
265 265 return m_x.size();
266 266 }
267 267
268 268 /*!
269 269 Returns the data points of the series.
270 270 */
271 271 QList<QPointF> QXYSeries::data()
272 272 {
273 273 QList<QPointF> data;
274 274 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
275 275 data.append(QPointF(m_x.at(i), m_y.at(i)));
276 276 return data;
277 277 }
278 278
279 279
280 280 /*!
281 281 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
282 282 pen from chart theme is used.
283 283 \sa QChart::setChartTheme()
284 284 */
285 285 void QXYSeries::setPen(const QPen &pen)
286 286 {
287 287 if (pen != m_pen) {
288 288 m_pen = pen;
289 289 emit updated();
290 290 }
291 291 }
292 292
293 293 /*!
294 294 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
295 295 from chart theme setting is used.
296 296 \sa QChart::setChartTheme()
297 297 */
298 298
299 299 void QXYSeries::setBrush(const QBrush &brush)
300 300 {
301 301 if (brush != m_brush) {
302 302 m_brush = brush;
303 303 emit updated();
304 304 }
305 305 }
306 306
307 307
308 308 /*!
309 309 Stream operator for adding a data \a point to the series.
310 310 \sa append()
311 311 */
312 312
313 313 QXYSeries& QXYSeries::operator<< (const QPointF &point)
314 314 {
315 315 append(point);
316 316 return *this;
317 317 }
318 318
319 319
320 320 /*!
321 321 Stream operator for adding a list of \a points to the series.
322 322 \sa append()
323 323 */
324 324
325 325 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
326 326 {
327 327 append(points);
328 328 return *this;
329 329 }
330 330
331 331 /*!
332 332 \internal
333 333 */
334 334 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
335 335 {
336 336 Q_UNUSED(bottomRight)
337 337
338 338 if (m_mapOrientation == Qt::Vertical) {
339 339 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
340 340 emit pointReplaced(topLeft.row() - m_mapFirst);
341 341 } else {
342 342 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
343 343 emit pointReplaced(topLeft.column() - m_mapFirst);
344 344 }
345 345 }
346 346
347 347 /*!
348 348 \internal
349 349 */
350 350 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
351 351 {
352 352 Q_UNUSED(parent)
353 353 // Q_UNUSED(end)
354 354
355 355 if (m_mapLimited) {
356 356 if (start >= m_mapFirst + m_mapCount) {
357 357 // the added data is below mapped area
358 358 // therefore it has no relevance
359 359 return;
360 360 } else {
361 361 // the added data is in the mapped area or before it and update is needed
362 362
363 363 // check how many mapped items there is currently (before new items are added)
364 364 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
365 365 // internal storage before new ones can be added
366 366
367 367 int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
368 368 if (m_mapCount == count()) {
369 369 for (int i = 0; i < itemsToRemove; i++)
370 370 emit pointRemoved(qMin(end, count()) - i);
371 371 }
372 372 }
373 373 } else {
374 374 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
375 375 // nothing to do
376 376 // emit pointAdded(qMax(start - m_mapFirst, 0));
377 377 }
378 378 }
379 379
380 380 /*!
381 381 \internal
382 382 */
383 383 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
384 384 {
385 385 Q_UNUSED(parent)
386 386 // Q_UNUSED(end)
387 387
388 388 if (m_mapLimited) {
389 389 if (start >= m_mapFirst + m_mapCount) {
390 390 // the added data is below mapped area
391 391 // therefore it has no relevance
392 392 return;
393 393 } else {
394 394 // the added data is in the mapped area or before it
395 395 // update needed
396 396 if (count() > 0) {
397 397 int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
398 398 for (int i = 0; i < toBeAdded; i++)
399 399 if (start + i >= m_mapFirst)
400 400 emit pointAdded(start + i);
401 401 }
402 402 }
403 403 } else {
404 404 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
405 405 for (int i = 0; i < end - start + 1; i++)
406 406 emit pointAdded(start + i);
407 407 }
408 408 }
409 409
410 410 /*!
411 411 \internal
412 412 */
413 413 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
414 414 {
415 415 Q_UNUSED(parent)
416 416 // Q_UNUSED(end)
417 417
418 418 if (m_mapLimited) {
419 419 if (start >= m_mapFirst + m_mapCount) {
420 420 // the removed data is below mapped area
421 421 // therefore it has no relevance
422 422 return;
423 423 } else {
424 424 // the removed data is in the mapped area or before it
425 425 // update needed
426 426
427 427 // check how many items need to be removed from the xychartitem storage
428 428 // the number equals the number of items that are removed and that lay before
429 429 // or in the mapped area. Items that lay beyond the map do not count
430 430 // the max is the current number of items in storage (count())
431 431 int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
432 432 for (int i = 0; i < itemsToRemove; i++)
433 433 emit pointRemoved(start);
434 434 }
435 435 } else {
436 436 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
437 437 for (int i = 0; i < end - start + 1; i++)
438 438 emit pointRemoved(start);
439 439 }
440 440 }
441 441
442 442 /*!
443 443 \internal
444 444 */
445 445 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
446 446 {
447 447 Q_UNUSED(parent)
448 448 Q_UNUSED(end)
449 449
450 450 // how many items there were before data was removed
451 451 // int oldCount = count() - 1;
452 452
453 453 if (m_mapLimited) {
454 454 if (start >= m_mapFirst + m_mapCount) {
455 455 // the removed data is below mapped area
456 456 // therefore it has no relevance
457 457 return;
458 458 } else {
459 459 // if the current items count in the whole model is bigger than the index of the last item
460 460 // that was removed than it means there are some extra items available
461 461
462 462 int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
463 463 int extraItemsAvailable = 0;
464 464 if (m_mapOrientation == Qt::Vertical) {
465 465 extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
466 466 } else {
467 467 extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
468 468 }
469 469
470 470 // if there are excess items available (below the mapped area) use them to repopulate mapped area
471 471 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
472 472 for (int k = 0; k < toBeAdded; k++)
473 473 emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
474 474 }
475 475 } else {
476 476 // data was removed from XYSeries interal storage. Nothing more to do
477 477 }
478 478 }
479 479
480 480 /*!
481 \fn QAbstractItemModel* QXYSeries::model()
482 Returns the model from which the series takes its data.
483 */
484
485 /*!
486 481 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
487 482 Sets the \a model to be used as a data source
488 483 \sa setModelMapping(), setModelMappingRange()
489 484 */
490 485 bool QXYSeries::setModel(QAbstractItemModel *model) {
491 486
492 487 // disconnect signals from old model
493 488 if (m_model) {
494 489 disconnect(m_model, 0, this, 0);
495 490 m_mapX = -1;
496 491 m_mapY = -1;
497 492 m_mapFirst = 0;
498 493 m_mapCount = 0;
499 494 m_mapLimited = false;
500 495 m_mapOrientation = Qt::Vertical;
501 496 }
502 497
503 498 // set new model
504 499 if (model) {
505 500 m_model = model;
506 501 return true;
507 502 } else {
508 503 m_model = 0;
509 504 return false;
510 505 }
511 506 }
512 507
513 508 /*!
514 509 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
515 510 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
516 511 as a data source for y coordinate. The \a orientation paramater specifies whether the data
517 512 is in columns or in rows.
518 513 \sa setModel(), setModelMappingRange()
519 514 */
520 515 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
521 516 {
522 517 if (m_model == 0)
523 518 return;
524 519 m_mapX = modelX;
525 520 m_mapY = modelY;
526 521 m_mapFirst = 0;
527 522 m_mapOrientation = orientation;
528 523 if (m_mapOrientation == Qt::Vertical) {
529 524 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
530 525 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
531 526 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
532 527 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
533 528 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
534 529 } else {
535 530 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
536 531 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
537 532 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
538 533 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
539 534 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
540 535 }
541 536 }
542 537
543 538 /*!
544 539 \fn bool QXYSeries::setModelMappingRange(int first, int count)
545 540 Allows limiting the model mapping.
546 541 Parameter \a first specifies which element of the model should be used as a first one of the series.
547 542 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
548 543 then all the items following \a first item in a model are used.
549 544 \sa setModel(), setModelMapping()
550 545 */
551 546 void QXYSeries::setModelMappingRange(int first, int count)
552 547 {
553 548 m_mapFirst = first;
554 549 if (count == 0) {
555 550 m_mapLimited = false;
556 551 } else {
557 552 m_mapCount = count;
558 553 m_mapLimited = true;
559 554 }
560 555 }
561 556
562 557 #include "moc_qxyseries.cpp"
563 558
564 559 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now