##// END OF EJS Templates
Documentation fixes....
Tero Ahola -
r995:d52b7de4b911
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -1,58 +1,57
1 include(qchart-html.qdocconf)
1 include(qchart-html.qdocconf)
2
2
3 HTML.postheader = \
3 HTML.postheader = \
4 "<div class=\"header\" id=\"qtdocheader\">\n" \
4 "<div class=\"header\" id=\"qtdocheader\">\n" \
5 " <div class=\"content\"> \n" \
5 " <div class=\"content\"> \n" \
6 " <img src=\"images/qcharts.png\" alt=\"qcharts\"/>\n" \
6 " <img src=\"images/qcharts.png\" alt=\"qcharts\"/>\n" \
7 " <p class=\"qtref\"> \n" \
7 " <p class=\"qtref\"> \n" \
8 " <span>Reference Documentation</span>\n" \
8 " <span>Reference Documentation</span>\n" \
9 " </p>\n" \
9 " </p>\n" \
10 " </div>\n" \
10 " </div>\n" \
11 " <div class=\"breadcrumb toolblock\">\n" \
11 " <div class=\"breadcrumb toolblock\">\n" \
12 " <ul>\n" \
12 " <ul>\n" \
13 " <li class=\"first\"><a href=\"index.html\">About</a></li>\n" \
13 " <li class=\"first\"><a href=\"index.html\">About</a></li>\n" \
14 " <li><a href=\"classes.html\">API Classes</a></li>\n" \
14 " <li><a href=\"classes.html\">API Classes</a></li>\n" \
15 " <li><a href=\"tutorials.html\">Tutorials</a></li>\n" \
16 " <li><a href=\"examples.html\">Examples</a></li>\n" \
15 " <li><a href=\"examples.html\">Examples</a></li>\n" \
17 " <li><a href=\"demos.html\">Demos</a></li>\n" \
16 " <li><a href=\"demos.html\">Demos</a></li>\n" \
18 " <!-- Breadcrumbs go here -->\n"
17 " <!-- Breadcrumbs go here -->\n"
19
18
20 HTML.postpostheader = \
19 HTML.postpostheader = \
21 " </ul>\n" \
20 " </ul>\n" \
22 " </div>\n" \
21 " </div>\n" \
23 "</div>\n" \
22 "</div>\n" \
24 "<div class=\"content mainContent\">\n"
23 "<div class=\"content mainContent\">\n"
25
24
26 HTML.footer = \
25 HTML.footer = \
27 " <div class=\"ft\">\n" \
26 " <div class=\"ft\">\n" \
28 " <span></span>\n" \
27 " <span></span>\n" \
29 " </div>\n" \
28 " </div>\n" \
30 "</div> \n" \
29 "</div> \n" \
31 "<div class=\"footer\">\n" \
30 "<div class=\"footer\">\n" \
32 " <p>\n" \
31 " <p>\n" \
33 " <acronym title=\"Copyright\">&copy;</acronym> 2012 Digia ." \
32 " <acronym title=\"Copyright\">&copy;</acronym> 2012 Digia ." \
34 " Qt and Qt logos are trademarks of of Nokia Corporation \n" \
33 " Qt and Qt logos are trademarks of of Nokia Corporation \n" \
35 " in Finland and/or other countries worldwide.</p>\n" \
34 " in Finland and/or other countries worldwide.</p>\n" \
36 " <p>\n" \
35 " <p>\n" \
37 " All other trademarks are property of their respective owners.</p>\n" \
36 " All other trademarks are property of their respective owners.</p>\n" \
38 " <br />\n" \
37 " <br />\n" \
39 " <p>\n" \
38 " <p>\n" \
40 " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
39 " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
41 " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
40 " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
42 " with the terms contained in a written agreement between you and Digia.</p>\n" \
41 " with the terms contained in a written agreement between you and Digia.</p>\n" \
43 " <p>\n" \
42 " <p>\n" \
44 " <img src=\"images/digia_logo.png\" alt=\"digia\" /></p>\n" \
43 " <img src=\"images/digia_logo.png\" alt=\"digia\" /></p>\n" \
45 "</div>\n" \
44 "</div>\n" \
46
45
47 # Files not referenced in any qdoc file.
46 # Files not referenced in any qdoc file.
48 # See also extraimages.HTML
47 # See also extraimages.HTML
49 qhp.QDoc.extraFiles = index.html \
48 qhp.QDoc.extraFiles = index.html \
50 images/arrow_down.png \
49 images/arrow_down.png \
51 images/breadcrumb.png \
50 images/breadcrumb.png \
52 images/bullet_gt.png \
51 images/bullet_gt.png \
53 images/bullet_dn.png \
52 images/bullet_dn.png \
54 images/bullet_sq.png \
53 images/bullet_sq.png \
55 images/bullet_up.png \
54 images/bullet_up.png \
56 images/horBar.png \
55 images/horBar.png \
57 images/qcharts.png \
56 images/qcharts.png \
58 style/offline.css
57 style/offline.css
@@ -1,79 +1,79
1 /*!
1 /*!
2 \page classes.html
2 \page classes.html
3 \title QtCommercial Charts API
3 \title QtCommercial Charts API
4 \keyword All Classes
4 \keyword All Classes
5
5
6 Charts API is build on top of Qt Graphics View Framework. Charts can be displayed as QGraphicsWidget using QChart class. However
6 Charts API is build on top of Qt Graphics View Framework. Charts can be displayed as QGraphicsWidget using QChart class. However
7 there is also convenience class QChartView which is QWidget based. These lets quickly use QCharts as normal Qt widget.
7 there is also convenience class QChartView which is QWidget based. These lets quickly use QCharts as normal Qt widget.
8 The API supports following chart types:
8 The API supports following chart types:
9
9
10 \list
10 \list
11 \o area
11 \o area
12 \o line
12 \o line
13 \o bar
13 \o bar
14 \o percent bar
14 \o percent bar
15 \o pie
15 \o pie
16 \o scatter
16 \o scatter
17 \o spline
17 \o spline
18 \o stacked bar
18 \o stacked bar
19 \endlist
19 \endlist
20
20
21
21
22 Each chart type is represented by QSeries derived class. To create given chart type users have to use instace of releted sereis class and add it to QChart/QChartView instance.
22 Each chart type is represented by QSeries derived class. To create given chart type users have to use instace of releted sereis class and add it to QChart/QChartView instance.
23 \code
23 \code
24 QLineSeries* series = new QLineSeries();
24 QLineSeries* series = new QLineSeries();
25 series->add(0, 6);
25 series->add(0, 6);
26 series->add(2, 4);
26 series->add(2, 4);
27 ...
27 ...
28 chartView->addSeries(series);
28 chartView->addSeries(series);
29 \endcode
29 \endcode
30
30
31 \raw HTML
31 \raw HTML
32 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
32 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
33 <tr>
33 <tr>
34 <th class="titleheader" width="33%">
34 <th class="titleheader" width="33%">
35 List of classes
35 List of classes
36 </th>
36 </th>
37 </tr>
37 </tr>
38 <tr>
38 <tr>
39 <td valign="top">
39 <td valign="top">
40 <ul>
40 <ul>
41 <li><a href="qareaseries.html">QAreaSeries</a></li>
41 <li><a href="qareaseries.html">QAreaSeries</a></li>
42 <li><a href="qbarseries.html">QBarSeries</a></li>
42 <li><a href="qbarseries.html">QBarSeries</a></li>
43 <li><a href="qbarset.html">QBarSet</a></li>
43 <li><a href="qbarset.html">QBarSet</a></li>
44 <li><a href="qchart.html">QChart</a></li>
44 <li><a href="qchart.html">QChart</a></li>
45 <li><a href="qchartaxis.html">QChartAxis</a></li>
45 <li><a href="qchartaxis.html">QChartAxis</a></li>
46 <li><a href="qchartview.html">QChartView</a></li>
46 <li><a href="qchartview.html">QChartView</a></li>
47 <li><a href="qlineseries.html">QLineSeries</a></li>
47 <li><a href="qlineseries.html">QLineSeries</a></li>
48 <li><a href="qpercentbarseries.html">QPercentBarSeries</a></li>
48 <li><a href="qpercentbarseries.html">QPercentBarSeries</a></li>
49 <li><a href="qpieseries.html">QPieSeries</a></li>
49 <li><a href="qpieseries.html">QPieSeries</a></li>
50 <li><a href="qpieslice.html">QPieSlice</a></li>
50 <li><a href="qpieslice.html">QPieSlice</a></li>
51 <li><a href="qscatterseries.html">QScatterSeries</a></li>
51 <li><a href="qscatterseries.html">QScatterSeries</a></li>
52 <li><a href="qseries.html">QSeries</a></li>
52 <li><a href="qabstractseries.html">QAbstractSeries</a></li>
53 <li><a href="qsplineseries.html">QSplineSeries</a></li>
53 <li><a href="qsplineseries.html">QSplineSeries</a></li>
54 <li><a href="qstackedbarseries.html">QStackedBarSeries</a></li>
54 <li><a href="qstackedbarseries.html">QStackedBarSeries</a></li>
55 <li><a href="qxyseries.html">QXYSeries</a></li>
55 <li><a href="qxyseries.html">QXYSeries</a></li>
56 <li><a href="qlegend.html">QLegend</a></li>
56 <li><a href="qlegend.html">QLegend</a></li>
57 </ul>
57 </ul>
58 </td>
58 </td>
59 </tr>
59 </tr>
60 </table>
60 </table>
61
61
62 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
62 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
63 <tr>
63 <tr>
64 <th class="titleheader" width="33%">
64 <th class="titleheader" width="33%">
65 Other files:
65 Other files:
66 </th>
66 </th>
67 </tr>
67 </tr>
68 <tr>
68 <tr>
69 <td valign="top">
69 <td valign="top">
70 <ul>
70 <ul>
71 <li><a href="qchartglobal.html">QChartGlobal</a></li>
71 <li><a href="qchartglobal.html">QChartGlobal</a></li>
72 </ul>
72 </ul>
73 </td>
73 </td>
74 </tr>
74 </tr>
75 </table>
75 </table>
76
76
77 \endraw
77 \endraw
78
78
79 */
79 */
@@ -1,290 +1,281
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 See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart.
46
46 \image examples_areachart.png
47 Creating basic area chart is simple:
48 \code
49 QLineSeries* lineSeries = new QLineSeries();
50 series->append(0, 6);
51 series->append(2, 4);
52 QAreaSeries* areaSeries = new QAreaSeries(lineSeries);
53 ...
54 chartView->addSeries(areaSeries);
55 \endcode
56 */
47 */
57
48
58 /*!
49 /*!
59 \fn virtual QSeriesType QAreaSeries::type() const
50 \fn virtual QSeriesType QAreaSeries::type() const
60 \brief Returns type of series.
51 \brief Returns type of series.
61 \sa QAbstractSeries, QSeriesType
52 \sa QAbstractSeries, QSeriesType
62 */
53 */
63
54
64 /*!
55 /*!
65 \fn QLineSeries* QAreaSeries::upperSeries() const
56 \fn QLineSeries* QAreaSeries::upperSeries() const
66 \brief Returns upperSeries used to define one of area boundaries.
57 \brief Returns upperSeries used to define one of area boundaries.
67 */
58 */
68
59
69 /*!
60 /*!
70 \fn QLineSeries* QAreaSeries::lowerSeries() const
61 \fn QLineSeries* QAreaSeries::lowerSeries() const
71 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
62 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
72 this function return Null pointer.
63 this function return Null pointer.
73 */
64 */
74
65
75 /*!
66 /*!
76 \fn QPen QAreaSeries::pen() const
67 \fn QPen QAreaSeries::pen() const
77 \brief Returns the pen used to draw line for this series.
68 \brief Returns the pen used to draw line for this series.
78 \sa setPen()
69 \sa setPen()
79 */
70 */
80
71
81 /*!
72 /*!
82 \fn QPen QAreaSeries::brush() const
73 \fn QPen QAreaSeries::brush() const
83 \brief Returns the brush used to draw line for this series.
74 \brief Returns the brush used to draw line for this series.
84 \sa setBrush()
75 \sa setBrush()
85 */
76 */
86
77
87 /*!
78 /*!
88 \fn bool QAreaSeries::pointsVisible() const
79 \fn bool QAreaSeries::pointsVisible() const
89 \brief Returns if the points are drawn for this series.
80 \brief Returns if the points are drawn for this series.
90 \sa setPointsVisible()
81 \sa setPointsVisible()
91 */
82 */
92
83
93 /*!
84 /*!
94 \fn void QAreaSeries::clicked(const QPointF& point)
85 \fn void QAreaSeries::clicked(const QPointF& point)
95 \brief Signal is emitted when user clicks the \a point on area chart.
86 \brief Signal is emitted when user clicks the \a point on area chart.
96 */
87 */
97
88
98 /*!
89 /*!
99 \fn void QAreaSeries::selected()
90 \fn void QAreaSeries::selected()
100
91
101 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
92 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.
93 implemented by the user of QAreaSeries API.
103 */
94 */
104
95
105 /*!
96 /*!
106 \fn void QAreaSeriesPrivate::updated()
97 \fn void QAreaSeriesPrivate::updated()
107 \brief \internal
98 \brief \internal
108 */
99 */
109
100
110 /*!
101 /*!
111 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
102 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.
103 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 transferred.
104 When series object is added to QChartView or QChart instance ownerships is transferred.
114 */
105 */
115 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
106 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
116 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
107 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
117 {
108 {
118 }
109 }
119
110
120 /*!
111 /*!
121 Destroys the object. Series added to QChartView or QChart instances are owned by those,
112 Destroys the object. Series added to QChartView or QChart instances are owned by those,
122 and are deleted when mentioned object are destroyed.
113 and are deleted when mentioned object are destroyed.
123 */
114 */
124 QAreaSeries::~QAreaSeries()
115 QAreaSeries::~QAreaSeries()
125 {
116 {
126 }
117 }
127
118
128
119
129 QAbstractSeries::QSeriesType QAreaSeries::type() const
120 QAbstractSeries::QSeriesType QAreaSeries::type() const
130 {
121 {
131 return QAbstractSeries::SeriesTypeArea;
122 return QAbstractSeries::SeriesTypeArea;
132 }
123 }
133
124
134 QLineSeries* QAreaSeries::upperSeries() const
125 QLineSeries* QAreaSeries::upperSeries() const
135 {
126 {
136 Q_D(const QAreaSeries);
127 Q_D(const QAreaSeries);
137 return d->m_upperSeries;
128 return d->m_upperSeries;
138 }
129 }
139
130
140 QLineSeries* QAreaSeries::lowerSeries() const
131 QLineSeries* QAreaSeries::lowerSeries() const
141 {
132 {
142 Q_D(const QAreaSeries);
133 Q_D(const QAreaSeries);
143 return d->m_lowerSeries;
134 return d->m_lowerSeries;
144 }
135 }
145
136
146 /*!
137 /*!
147 Sets \a pen used for drawing area outline.
138 Sets \a pen used for drawing area outline.
148 */
139 */
149 void QAreaSeries::setPen(const QPen &pen)
140 void QAreaSeries::setPen(const QPen &pen)
150 {
141 {
151 Q_D(QAreaSeries);
142 Q_D(QAreaSeries);
152 if (d->m_pen != pen) {
143 if (d->m_pen != pen) {
153 d->m_pen = pen;
144 d->m_pen = pen;
154 emit d->updated();
145 emit d->updated();
155 }
146 }
156 }
147 }
157
148
158 QPen QAreaSeries::pen() const
149 QPen QAreaSeries::pen() const
159 {
150 {
160 Q_D(const QAreaSeries);
151 Q_D(const QAreaSeries);
161 return d->m_pen;
152 return d->m_pen;
162 }
153 }
163
154
164 /*!
155 /*!
165 Sets \a brush used for filling the area.
156 Sets \a brush used for filling the area.
166 */
157 */
167 void QAreaSeries::setBrush(const QBrush &brush)
158 void QAreaSeries::setBrush(const QBrush &brush)
168 {
159 {
169 Q_D(QAreaSeries);
160 Q_D(QAreaSeries);
170 if (d->m_brush != brush) {
161 if (d->m_brush != brush) {
171 d->m_brush = brush;
162 d->m_brush = brush;
172 emit d->updated();
163 emit d->updated();
173 }
164 }
174 }
165 }
175
166
176 QBrush QAreaSeries::brush() const
167 QBrush QAreaSeries::brush() const
177 {
168 {
178 Q_D(const QAreaSeries);
169 Q_D(const QAreaSeries);
179 return d->m_brush;
170 return d->m_brush;
180 }
171 }
181 /*!
172 /*!
182 Sets if data points are \a visible and should be drawn on line.
173 Sets if data points are \a visible and should be drawn on line.
183 */
174 */
184 void QAreaSeries::setPointsVisible(bool visible)
175 void QAreaSeries::setPointsVisible(bool visible)
185 {
176 {
186 Q_D(QAreaSeries);
177 Q_D(QAreaSeries);
187 if (d->m_pointsVisible != visible) {
178 if (d->m_pointsVisible != visible) {
188 d->m_pointsVisible = visible;
179 d->m_pointsVisible = visible;
189 emit d->updated();
180 emit d->updated();
190 }
181 }
191 }
182 }
192
183
193 bool QAreaSeries::pointsVisible() const
184 bool QAreaSeries::pointsVisible() const
194 {
185 {
195 Q_D(const QAreaSeries);
186 Q_D(const QAreaSeries);
196 return d->m_pointsVisible;
187 return d->m_pointsVisible;
197 }
188 }
198
189
199 /*!
190 /*!
200 Does nothing at present. Paremeter \a model is not used. Always returns false.
191 Does nothing at present. Paremeter \a model is not used. Always returns false.
201 To set the model for area series set the models for upperSeries, lowerSeries
192 To set the model for area series set the models for upperSeries, lowerSeries
202 */
193 */
203 bool QAreaSeries::setModel(QAbstractItemModel* model)
194 bool QAreaSeries::setModel(QAbstractItemModel* model)
204 {
195 {
205 Q_UNUSED(model);
196 Q_UNUSED(model);
206 qWarning()<<"Not implemented";
197 qWarning()<<"Not implemented";
207 return false;
198 return false;
208 }
199 }
209
200
210 /*!
201 /*!
211 Does nothing at present. Always returns 0;
202 Does nothing at present. Always returns 0;
212 To get the model set for area series call upperSeries->model(), lowerSeries->model()
203 To get the model set for area series call upperSeries->model(), lowerSeries->model()
213 */
204 */
214 QAbstractItemModel* QAreaSeries::model() const
205 QAbstractItemModel* QAreaSeries::model() const
215 {
206 {
216 return 0;
207 return 0;
217 }
208 }
218
209
219 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
220
211
221 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
212 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
222 QAbstractSeriesPrivate(q),
213 QAbstractSeriesPrivate(q),
223 m_upperSeries(upperSeries),
214 m_upperSeries(upperSeries),
224 m_lowerSeries(lowerSeries),
215 m_lowerSeries(lowerSeries),
225 m_pointsVisible(false)
216 m_pointsVisible(false)
226 {
217 {
227 }
218 }
228
219
229 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
220 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
230 {
221 {
231 Q_Q(QAreaSeries);
222 Q_Q(QAreaSeries);
232
223
233 qreal minX(domain.minX());
224 qreal minX(domain.minX());
234 qreal minY(domain.minY());
225 qreal minY(domain.minY());
235 qreal maxX(domain.maxX());
226 qreal maxX(domain.maxX());
236 qreal maxY(domain.maxY());
227 qreal maxY(domain.maxY());
237 int tickXCount(domain.tickXCount());
228 int tickXCount(domain.tickXCount());
238 int tickYCount(domain.tickYCount());
229 int tickYCount(domain.tickYCount());
239
230
240 QLineSeries* upperSeries = q->upperSeries();
231 QLineSeries* upperSeries = q->upperSeries();
241 QLineSeries* lowerSeries = q->lowerSeries();
232 QLineSeries* lowerSeries = q->lowerSeries();
242
233
243 for (int i = 0; i < upperSeries->count(); i++)
234 for (int i = 0; i < upperSeries->count(); i++)
244 {
235 {
245 qreal x = upperSeries->x(i);
236 qreal x = upperSeries->x(i);
246 qreal y = upperSeries->y(i);
237 qreal y = upperSeries->y(i);
247 minX = qMin(minX, x);
238 minX = qMin(minX, x);
248 minY = qMin(minY, y);
239 minY = qMin(minY, y);
249 maxX = qMax(maxX, x);
240 maxX = qMax(maxX, x);
250 maxY = qMax(maxY, y);
241 maxY = qMax(maxY, y);
251 }
242 }
252 if(lowerSeries) {
243 if(lowerSeries) {
253 for (int i = 0; i < lowerSeries->count(); i++)
244 for (int i = 0; i < lowerSeries->count(); i++)
254 {
245 {
255 qreal x = lowerSeries->x(i);
246 qreal x = lowerSeries->x(i);
256 qreal y = lowerSeries->y(i);
247 qreal y = lowerSeries->y(i);
257 minX = qMin(minX, x);
248 minX = qMin(minX, x);
258 minY = qMin(minY, y);
249 minY = qMin(minY, y);
259 maxX = qMax(maxX, x);
250 maxX = qMax(maxX, x);
260 maxY = qMax(maxY, y);
251 maxY = qMax(maxY, y);
261 }}
252 }}
262
253
263 domain.setRangeX(minX,maxX,tickXCount);
254 domain.setRangeX(minX,maxX,tickXCount);
264 domain.setRangeY(minY,maxY,tickYCount);
255 domain.setRangeY(minY,maxY,tickYCount);
265 }
256 }
266
257
267 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
258 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
268 {
259 {
269 Q_Q(QAreaSeries);
260 Q_Q(QAreaSeries);
270
261
271 AreaChartItem* area = new AreaChartItem(q,presenter);
262 AreaChartItem* area = new AreaChartItem(q,presenter);
272 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
263 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
273 presenter->animator()->addAnimation(area->upperLineItem());
264 presenter->animator()->addAnimation(area->upperLineItem());
274 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
265 if(q->lowerSeries()) presenter->animator()->addAnimation(area->lowerLineItem());
275 }
266 }
276 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
267 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
277 return area;
268 return area;
278 }
269 }
279
270
280 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
271 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
281 {
272 {
282 Q_Q(QAreaSeries);
273 Q_Q(QAreaSeries);
283 QList<LegendMarker*> list;
274 QList<LegendMarker*> list;
284 return list << new AreaLegendMarker(q,legend);
275 return list << new AreaLegendMarker(q,legend);
285 }
276 }
286
277
287 #include "moc_qareaseries.cpp"
278 #include "moc_qareaseries.cpp"
288 #include "moc_qareaseries_p.cpp"
279 #include "moc_qareaseries_p.cpp"
289
280
290 QTCOMMERCIALCHART_END_NAMESPACE
281 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,454 +1,456
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 \mainclass
40
41
41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
42 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
43 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
43 by QStringList.
44 by QStringList.
44
45
45 \mainclass
46 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
47 \image examples_barchart.png
46
48
47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
49 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 */
50 */
49
51
50 /*!
52 /*!
51 \fn void QBarSeries::clicked(QBarSet *barset, QString category, Qt::MouseButtons button)
53 \fn void QBarSeries::clicked(QBarSet *barset, QString category, Qt::MouseButtons button)
52
54
53 The signal is emitted if the user clicks with a mouse \a button on top of QBarSet \a barset of category \a category
55 The signal is emitted if the user clicks with a mouse \a button on top of QBarSet \a barset of category \a category
54 contained by the series.
56 contained by the series.
55 */
57 */
56
58
57 /*!
59 /*!
58 \fn void QBarSeries::selected()
60 \fn void QBarSeries::selected()
59
61
60 The signal is emitted if the user selects/deselects the series. The logic for storing selections should be
62 The signal is emitted if the user selects/deselects the series. The logic for storing selections should be
61 implemented by the user of QBarSeries API.
63 implemented by the user of QBarSeries API.
62 */
64 */
63
65
64 /*!
66 /*!
65 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
67 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
66
68
67 The signal is emitted if mouse is hovered on top of series.
69 The signal is emitted if mouse is hovered on top of series.
68 Parameter \a barset is the pointer of barset, where hover happened.
70 Parameter \a barset is the pointer of barset, where hover happened.
69 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
71 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
70 */
72 */
71
73
72 /*!
74 /*!
73 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
75 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
74 QBarSeries is QObject which is a child of a \a parent.
76 QBarSeries is QObject which is a child of a \a parent.
75 */
77 */
76 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
78 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
77 QAbstractSeries(*new QBarSeriesPrivate(categories, this),parent)
79 QAbstractSeries(*new QBarSeriesPrivate(categories, this),parent)
78 {
80 {
79 }
81 }
80
82
81 /*!
83 /*!
82 Destructs barseries and owned barsets.
84 Destructs barseries and owned barsets.
83 */
85 */
84 QBarSeries::~QBarSeries()
86 QBarSeries::~QBarSeries()
85 {
87 {
86 // NOTE: d_ptr destroyed by QObject
88 // NOTE: d_ptr destroyed by QObject
87 }
89 }
88
90
89 /*!
91 /*!
90 \internal
92 \internal
91 */
93 */
92 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
94 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
93 QAbstractSeries(d,parent)
95 QAbstractSeries(d,parent)
94 {
96 {
95 }
97 }
96
98
97 /*!
99 /*!
98 Returns the type of series. Derived classes override this.
100 Returns the type of series. Derived classes override this.
99 */
101 */
100 QAbstractSeries::QSeriesType QBarSeries::type() const
102 QAbstractSeries::QSeriesType QBarSeries::type() const
101 {
103 {
102 return QAbstractSeries::SeriesTypeBar;
104 return QAbstractSeries::SeriesTypeBar;
103 }
105 }
104
106
105 /*!
107 /*!
106 Adds a set of bars to series. Takes ownership of \a set.
108 Adds a set of bars to series. Takes ownership of \a set.
107 Connects the clicked(QString, Qt::MouseButtons) signal
109 Connects the clicked(QString, Qt::MouseButtons) signal
108 of \a set to this series
110 of \a set to this series
109 */
111 */
110 void QBarSeries::appendBarSet(QBarSet *set)
112 void QBarSeries::appendBarSet(QBarSet *set)
111 {
113 {
112 Q_D(QBarSeries);
114 Q_D(QBarSeries);
113 d->m_internalModel->appendBarSet(set);
115 d->m_internalModel->appendBarSet(set);
114 QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged()));
116 QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged()));
115 emit d->restructuredBars();
117 emit d->restructuredBars();
116 }
118 }
117
119
118 /*!
120 /*!
119 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
121 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
120 Disconnects the clicked(QString, Qt::MouseButtons) signal
122 Disconnects the clicked(QString, Qt::MouseButtons) signal
121 of \a set from this series
123 of \a set from this series
122 */
124 */
123 void QBarSeries::removeBarSet(QBarSet *set)
125 void QBarSeries::removeBarSet(QBarSet *set)
124 {
126 {
125 Q_D(QBarSeries);
127 Q_D(QBarSeries);
126 d->m_internalModel->removeBarSet(set);
128 d->m_internalModel->removeBarSet(set);
127 emit d->restructuredBars();
129 emit d->restructuredBars();
128 }
130 }
129
131
130 /*!
132 /*!
131 Adds a list of barsets to series. Takes ownership of \a sets.
133 Adds a list of barsets to series. Takes ownership of \a sets.
132 Connects the clicked(QString, Qt::MouseButtons) signals
134 Connects the clicked(QString, Qt::MouseButtons) signals
133 of \a sets to this series
135 of \a sets to this series
134 */
136 */
135 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
137 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
136 {
138 {
137 Q_D(QBarSeries);
139 Q_D(QBarSeries);
138 foreach (QBarSet* barset, sets) {
140 foreach (QBarSet* barset, sets) {
139 d->m_internalModel->appendBarSet(barset);
141 d->m_internalModel->appendBarSet(barset);
140 QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
142 QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
141 }
143 }
142 emit d->restructuredBars();
144 emit d->restructuredBars();
143
145
144 }
146 }
145
147
146 /*!
148 /*!
147 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
149 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
148 Disconnects the clicked(QString, Qt::MouseButtons) signal
150 Disconnects the clicked(QString, Qt::MouseButtons) signal
149 of \a sets from this series
151 of \a sets from this series
150 */
152 */
151 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
153 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
152 {
154 {
153 Q_D(QBarSeries);
155 Q_D(QBarSeries);
154
156
155 foreach (QBarSet* barset, sets) {
157 foreach (QBarSet* barset, sets) {
156 d->m_internalModel->removeBarSet(barset);
158 d->m_internalModel->removeBarSet(barset);
157 }
159 }
158 emit d->restructuredBars();
160 emit d->restructuredBars();
159 }
161 }
160
162
161 /*!
163 /*!
162 Inserts new \a set on the \a i position.
164 Inserts new \a set on the \a i position.
163 The barset that is currently at this postion is moved to postion i + 1
165 The barset that is currently at this postion is moved to postion i + 1
164 */
166 */
165 void QBarSeries::insertBarSet(int i, QBarSet *set)
167 void QBarSeries::insertBarSet(int i, QBarSet *set)
166 {
168 {
167 Q_D(QBarSeries);
169 Q_D(QBarSeries);
168 d->m_internalModel->insertBarSet(i, set);
170 d->m_internalModel->insertBarSet(i, set);
169 emit d->barsetChanged();
171 emit d->barsetChanged();
170 }
172 }
171
173
172 /*!
174 /*!
173 Returns number of sets in series.
175 Returns number of sets in series.
174 */
176 */
175 int QBarSeries::barsetCount() const
177 int QBarSeries::barsetCount() const
176 {
178 {
177 Q_D(const QBarSeries);
179 Q_D(const QBarSeries);
178 return d->m_internalModel->barsetCount();
180 return d->m_internalModel->barsetCount();
179 }
181 }
180
182
181 /*!
183 /*!
182 Returns number of categories in series
184 Returns number of categories in series
183 */
185 */
184 int QBarSeries::categoryCount() const
186 int QBarSeries::categoryCount() const
185 {
187 {
186 Q_D(const QBarSeries);
188 Q_D(const QBarSeries);
187 return d->m_internalModel->categoryCount();
189 return d->m_internalModel->categoryCount();
188 }
190 }
189
191
190 /*!
192 /*!
191 Returns a list of sets in series. Keeps ownership of sets.
193 Returns a list of sets in series. Keeps ownership of sets.
192 */
194 */
193 QList<QBarSet*> QBarSeries::barSets() const
195 QList<QBarSet*> QBarSeries::barSets() const
194 {
196 {
195 Q_D(const QBarSeries);
197 Q_D(const QBarSeries);
196 return d->m_internalModel->barSets();
198 return d->m_internalModel->barSets();
197 }
199 }
198
200
199 /*!
201 /*!
200 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
202 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
201 Sets the \a model to be used as a data source
203 Sets the \a model to be used as a data source
202 */
204 */
203 bool QBarSeries::setModel(QAbstractItemModel *model)
205 bool QBarSeries::setModel(QAbstractItemModel *model)
204 {
206 {
205 Q_D(QBarSeries);
207 Q_D(QBarSeries);
206 return d->setModel(model);
208 return d->setModel(model);
207 }
209 }
208
210
209 /*!
211 /*!
210 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
212 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
211 Sets column/row specified by \a categories to be used as a list of bar series categories.
213 Sets column/row specified by \a categories to be used as a list of bar series categories.
212 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
214 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
213 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
215 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
214 All the columns/rows inbetween those two values are also used as data for bar sets.
216 All the columns/rows inbetween those two values are also used as data for bar sets.
215 The \a orientation parameter specifies whether the data is in columns or in rows.
217 The \a orientation parameter specifies whether the data is in columns or in rows.
216 */
218 */
217 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
219 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
218 {
220 {
219 Q_D(QBarSeries);
221 Q_D(QBarSeries);
220 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
222 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
221 }
223 }
222
224
223 /*!
225 /*!
224 Returns the bar categories of the series.
226 Returns the bar categories of the series.
225 */
227 */
226 QBarCategories QBarSeries::categories() const
228 QBarCategories QBarSeries::categories() const
227 {
229 {
228 Q_D(const QBarSeries);
230 Q_D(const QBarSeries);
229
231
230 QBarCategories categories;
232 QBarCategories categories;
231 int count = d->m_internalModel->categoryCount();
233 int count = d->m_internalModel->categoryCount();
232 for (int i=1; i <= count; i++) {
234 for (int i=1; i <= count; i++) {
233 categories.insert(i, d->m_internalModel->categoryName(i - 1));
235 categories.insert(i, d->m_internalModel->categoryName(i - 1));
234 }
236 }
235 return categories;
237 return categories;
236
238
237 }
239 }
238
240
239 /*!
241 /*!
240 Sets the visibility of labels in series to \a visible
242 Sets the visibility of labels in series to \a visible
241 */
243 */
242 void QBarSeries::setLabelsVisible(bool visible)
244 void QBarSeries::setLabelsVisible(bool visible)
243 {
245 {
244 foreach (QBarSet* s, barSets()) {
246 foreach (QBarSet* s, barSets()) {
245 s->setLabelsVisible(visible);
247 s->setLabelsVisible(visible);
246 }
248 }
247 }
249 }
248
250
249 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
251 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
250
252
251 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) :
253 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) :
252 QAbstractSeriesPrivate(q),
254 QAbstractSeriesPrivate(q),
253 m_internalModel(new BarChartModel(categories,this)),
255 m_internalModel(new BarChartModel(categories,this)),
254 m_model(0),
256 m_model(0),
255 m_mapCategories(-1),
257 m_mapCategories(-1),
256 m_mapBarBottom(-1),
258 m_mapBarBottom(-1),
257 m_mapBarTop(-1),
259 m_mapBarTop(-1),
258 m_mapOrientation(Qt::Vertical)
260 m_mapOrientation(Qt::Vertical)
259 {
261 {
260 }
262 }
261
263
262 QBarSet* QBarSeriesPrivate::barsetAt(int index)
264 QBarSet* QBarSeriesPrivate::barsetAt(int index)
263 {
265 {
264 return m_internalModel->barsetAt(index);
266 return m_internalModel->barsetAt(index);
265 }
267 }
266
268
267 QString QBarSeriesPrivate::categoryName(int category)
269 QString QBarSeriesPrivate::categoryName(int category)
268 {
270 {
269 return m_internalModel->categoryName(category);
271 return m_internalModel->categoryName(category);
270 }
272 }
271
273
272 qreal QBarSeriesPrivate::min()
274 qreal QBarSeriesPrivate::min()
273 {
275 {
274 return m_internalModel->min();
276 return m_internalModel->min();
275 }
277 }
276
278
277 qreal QBarSeriesPrivate::max()
279 qreal QBarSeriesPrivate::max()
278 {
280 {
279 return m_internalModel->max();
281 return m_internalModel->max();
280 }
282 }
281
283
282 qreal QBarSeriesPrivate::valueAt(int set, int category)
284 qreal QBarSeriesPrivate::valueAt(int set, int category)
283 {
285 {
284 return m_internalModel->valueAt(set, category);
286 return m_internalModel->valueAt(set, category);
285 }
287 }
286
288
287 qreal QBarSeriesPrivate::percentageAt(int set, int category)
289 qreal QBarSeriesPrivate::percentageAt(int set, int category)
288 {
290 {
289 return m_internalModel->percentageAt(set, category);
291 return m_internalModel->percentageAt(set, category);
290 }
292 }
291
293
292 qreal QBarSeriesPrivate::categorySum(int category)
294 qreal QBarSeriesPrivate::categorySum(int category)
293 {
295 {
294 return m_internalModel->categorySum(category);
296 return m_internalModel->categorySum(category);
295 }
297 }
296
298
297 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
299 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
298 {
300 {
299 return m_internalModel->absoluteCategorySum(category);
301 return m_internalModel->absoluteCategorySum(category);
300 }
302 }
301
303
302 qreal QBarSeriesPrivate::maxCategorySum()
304 qreal QBarSeriesPrivate::maxCategorySum()
303 {
305 {
304 return m_internalModel->maxCategorySum();
306 return m_internalModel->maxCategorySum();
305 }
307 }
306
308
307 BarChartModel& QBarSeriesPrivate::modelInternal()
309 BarChartModel& QBarSeriesPrivate::modelInternal()
308 {
310 {
309 return *m_internalModel;
311 return *m_internalModel;
310 }
312 }
311
313
312 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
314 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
313 {
315 {
314 // disconnect signals from old model
316 // disconnect signals from old model
315 if(m_model)
317 if(m_model)
316 {
318 {
317 disconnect(m_model, 0, this, 0);
319 disconnect(m_model, 0, this, 0);
318 m_mapCategories = -1;
320 m_mapCategories = -1;
319 m_mapBarBottom = -1;
321 m_mapBarBottom = -1;
320 m_mapBarTop = -1;
322 m_mapBarTop = -1;
321 m_mapOrientation = Qt::Vertical;
323 m_mapOrientation = Qt::Vertical;
322 }
324 }
323
325
324 // set new model
326 // set new model
325 if(model)
327 if(model)
326 {
328 {
327 m_model = model;
329 m_model = model;
328 return true;
330 return true;
329 }
331 }
330 else
332 else
331 {
333 {
332 m_model = 0;
334 m_model = 0;
333 return false;
335 return false;
334 }
336 }
335 }
337 }
336
338
337 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
339 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
338 {
340 {
339 Q_Q(QBarSeries);
341 Q_Q(QBarSeries);
340
342
341 if (m_model == 0)
343 if (m_model == 0)
342 return;
344 return;
343
345
344 m_mapCategories = categories;
346 m_mapCategories = categories;
345 m_mapBarBottom = bottomBoundry;
347 m_mapBarBottom = bottomBoundry;
346 m_mapBarTop = topBoundry;
348 m_mapBarTop = topBoundry;
347 m_mapOrientation = orientation;
349 m_mapOrientation = orientation;
348
350
349 // connect the signals
351 // connect the signals
350 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
352 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
351 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
353 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
352
354
353 // create the initial bars
355 // create the initial bars
354 delete m_internalModel;
356 delete m_internalModel;
355 if (m_mapOrientation == Qt::Vertical) {
357 if (m_mapOrientation == Qt::Vertical) {
356 QStringList categories;
358 QStringList categories;
357 for (int k = 0; k < m_model->rowCount(); k++)
359 for (int k = 0; k < m_model->rowCount(); k++)
358 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
360 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
359 m_internalModel = new BarChartModel(categories, this);
361 m_internalModel = new BarChartModel(categories, this);
360
362
361 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
363 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
362 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
364 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
363 for(int m = 0; m < m_model->rowCount(); m++)
365 for(int m = 0; m < m_model->rowCount(); m++)
364 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
366 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
365 q->appendBarSet(barSet);
367 q->appendBarSet(barSet);
366 }
368 }
367 } else {
369 } else {
368 QStringList categories;
370 QStringList categories;
369 for (int k = 0; k < m_model->columnCount(); k++)
371 for (int k = 0; k < m_model->columnCount(); k++)
370 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
372 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
371 m_internalModel = new BarChartModel(categories, this);
373 m_internalModel = new BarChartModel(categories, this);
372
374
373 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
375 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
374 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
376 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
375 for(int m = 0; m < m_model->columnCount(); m++)
377 for(int m = 0; m < m_model->columnCount(); m++)
376 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
378 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
377 q->appendBarSet(barSet);
379 q->appendBarSet(barSet);
378 }
380 }
379 }
381 }
380 }
382 }
381
383
382 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
384 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
383 {
385 {
384 Q_UNUSED(bottomRight)
386 Q_UNUSED(bottomRight)
385
387
386 if (m_mapOrientation == Qt::Vertical)
388 if (m_mapOrientation == Qt::Vertical)
387 {
389 {
388 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
390 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
389 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop)
391 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop)
390 barsetAt(topLeft.column() - m_mapBarBottom)->replace(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
392 barsetAt(topLeft.column() - m_mapBarBottom)->replace(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
391 }
393 }
392 else
394 else
393 {
395 {
394 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
396 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
395 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop)
397 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop)
396 barsetAt(topLeft.row() - m_mapBarBottom)->replace(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
398 barsetAt(topLeft.row() - m_mapBarBottom)->replace(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
397 }
399 }
398 }
400 }
399
401
400 void QBarSeriesPrivate::barsetChanged()
402 void QBarSeriesPrivate::barsetChanged()
401 {
403 {
402 emit updatedBars();
404 emit updatedBars();
403 }
405 }
404
406
405 void QBarSeriesPrivate::scaleDomain(Domain& domain)
407 void QBarSeriesPrivate::scaleDomain(Domain& domain)
406 {
408 {
407 qreal minX(domain.minX());
409 qreal minX(domain.minX());
408 qreal minY(domain.minY());
410 qreal minY(domain.minY());
409 qreal maxX(domain.maxX());
411 qreal maxX(domain.maxX());
410 qreal maxY(domain.maxY());
412 qreal maxY(domain.maxY());
411 int tickXCount(domain.tickXCount());
413 int tickXCount(domain.tickXCount());
412 int tickYCount(domain.tickYCount());
414 int tickYCount(domain.tickYCount());
413
415
414 qreal x = m_internalModel->categoryCount();
416 qreal x = m_internalModel->categoryCount();
415 qreal y = max();
417 qreal y = max();
416 minX = qMin(minX, x);
418 minX = qMin(minX, x);
417 minY = qMin(minY, y);
419 minY = qMin(minY, y);
418 maxX = qMax(maxX, x);
420 maxX = qMax(maxX, x);
419 maxY = qMax(maxY, y);
421 maxY = qMax(maxY, y);
420 tickXCount = x+1;
422 tickXCount = x+1;
421
423
422 domain.setRangeX(minX,maxX,tickXCount);
424 domain.setRangeX(minX,maxX,tickXCount);
423 domain.setRangeY(minY,maxY,tickYCount);
425 domain.setRangeY(minY,maxY,tickYCount);
424 }
426 }
425
427
426 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
428 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
427 {
429 {
428 Q_Q(QBarSeries);
430 Q_Q(QBarSeries);
429
431
430 BarChartItem* bar = new BarChartItem(q,presenter);
432 BarChartItem* bar = new BarChartItem(q,presenter);
431 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
433 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
432 presenter->animator()->addAnimation(bar);
434 presenter->animator()->addAnimation(bar);
433 }
435 }
434 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
436 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
435 return bar;
437 return bar;
436
438
437 }
439 }
438
440
439 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
441 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
440 {
442 {
441 Q_Q(QBarSeries);
443 Q_Q(QBarSeries);
442 QList<LegendMarker*> markers;
444 QList<LegendMarker*> markers;
443 foreach(QBarSet* set, q->barSets()) {
445 foreach(QBarSet* set, q->barSets()) {
444 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
446 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
445 markers << marker;
447 markers << marker;
446 }
448 }
447
449
448 return markers;
450 return markers;
449 }
451 }
450
452
451 #include "moc_qbarseries.cpp"
453 #include "moc_qbarseries.cpp"
452 #include "moc_qbarseries_p.cpp"
454 #include "moc_qbarseries_p.cpp"
453
455
454 QTCOMMERCIALCHART_END_NAMESPACE
456 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,108 +1,110
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 \mainclass
34
35
35 QPercentBarSeries represents a series of data shown as bars. Each bar of QBarSet is shown as percentage
36 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 multiple QBarSet data sets.
37 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.
38 QBarSeries groups the data from sets to categories, which are defined by QStringList.
38
39
39 \mainclass
40 See the \l {PercentbarChart Example} {percent bar chart example} to learn how to create a percent bar chart.
41 \image examples_percentbarchart.png
40
42
41 \sa QBarSet, QStackedBarSeries, QBarSeries
43 \sa QBarSet, QStackedBarSeries, QBarSeries
42 */
44 */
43
45
44 /*!
46 /*!
45 \fn virtual QSeriesType QPercentBarSeries::type() const
47 \fn virtual QSeriesType QPercentBarSeries::type() const
46 \brief Returns type of series.
48 \brief Returns type of series.
47 \sa QAbstractSeries, QSeriesType
49 \sa QAbstractSeries, QSeriesType
48 */
50 */
49
51
50 /*!
52 /*!
51 Constructs empty QPercentBarSeries. Parameter \a categories defines the categories for chart.
53 Constructs empty QPercentBarSeries. Parameter \a categories defines the categories for chart.
52 QPercentBarSeries is QObject which is a child of a \a parent.
54 QPercentBarSeries is QObject which is a child of a \a parent.
53 */
55 */
54 QPercentBarSeries::QPercentBarSeries(QBarCategories categories, QObject *parent)
56 QPercentBarSeries::QPercentBarSeries(QBarCategories categories, QObject *parent)
55 : QBarSeries(*new QPercentBarSeriesPrivate(categories,this), parent)
57 : QBarSeries(*new QPercentBarSeriesPrivate(categories,this), parent)
56 {
58 {
57 }
59 }
58
60
59 QAbstractSeries::QSeriesType QPercentBarSeries::type() const
61 QAbstractSeries::QSeriesType QPercentBarSeries::type() const
60 {
62 {
61 return QAbstractSeries::SeriesTypePercentBar;
63 return QAbstractSeries::SeriesTypePercentBar;
62 }
64 }
63
65
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65
67
66 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QBarCategories categories, QPercentBarSeries *q) : QBarSeriesPrivate(categories,q)
68 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QBarCategories categories, QPercentBarSeries *q) : QBarSeriesPrivate(categories,q)
67 {
69 {
68
70
69 }
71 }
70
72
71 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
73 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
72 {
74 {
73 Q_Q(QPercentBarSeries);
75 Q_Q(QPercentBarSeries);
74 qreal minX(domain.minX());
76 qreal minX(domain.minX());
75 qreal minY(domain.minY());
77 qreal minY(domain.minY());
76 qreal maxX(domain.maxX());
78 qreal maxX(domain.maxX());
77 qreal maxY(domain.maxY());
79 qreal maxY(domain.maxY());
78 int tickXCount(domain.tickXCount());
80 int tickXCount(domain.tickXCount());
79 int tickYCount(domain.tickYCount());
81 int tickYCount(domain.tickYCount());
80
82
81 qreal x = q->categoryCount();
83 qreal x = q->categoryCount();
82 minX = qMin(minX, x);
84 minX = qMin(minX, x);
83 maxX = qMax(maxX, x);
85 maxX = qMax(maxX, x);
84 minY = 0;
86 minY = 0;
85 maxY = 100;
87 maxY = 100;
86 tickXCount = x+1;
88 tickXCount = x+1;
87
89
88 domain.setRangeX(minX,maxX,tickXCount);
90 domain.setRangeX(minX,maxX,tickXCount);
89 domain.setRangeY(minY,maxY,tickYCount);
91 domain.setRangeY(minY,maxY,tickYCount);
90 }
92 }
91
93
92
94
93 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
95 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
94 {
96 {
95 Q_Q(QPercentBarSeries);
97 Q_Q(QPercentBarSeries);
96
98
97 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
99 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
100 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
99 presenter->animator()->addAnimation(bar);
101 presenter->animator()->addAnimation(bar);
100 }
102 }
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
103 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
102 return bar;
104 return bar;
103 }
105 }
104
106
105 #include "moc_qpercentbarseries.cpp"
107 #include "moc_qpercentbarseries.cpp"
106
108
107 QTCOMMERCIALCHART_END_NAMESPACE
109 QTCOMMERCIALCHART_END_NAMESPACE
108
110
@@ -1,108 +1,110
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 \mainclass
34
35
35 QStackedBarSeries represents a series of data shown as bars. All bars in same category are
36 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 multiple QBarSet data sets.
37 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.
38 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
38
39
39 \mainclass
40 See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
41 \image examples_stackedbarchart.png
40
42
41 \sa QBarSet, QPercentBarSeries, QBarSeries
43 \sa QBarSet, QPercentBarSeries, QBarSeries
42 */
44 */
43
45
44 /*!
46 /*!
45 \fn virtual QSeriesType QStackedBarSeries::type() const
47 \fn virtual QSeriesType QStackedBarSeries::type() const
46 \brief Returns type of series.
48 \brief Returns type of series.
47 \sa QSeriesType
49 \sa QSeriesType
48 */
50 */
49
51
50 /*!
52 /*!
51 Constructs empty QStackedBarSeries. Parameter \a categories defines the categories for chart.
53 Constructs empty QStackedBarSeries. Parameter \a categories defines the categories for chart.
52 QStackedBarSeries is QObject which is a child of a \a parent.
54 QStackedBarSeries is QObject which is a child of a \a parent.
53 */
55 */
54 QStackedBarSeries::QStackedBarSeries(QBarCategories categories, QObject *parent)
56 QStackedBarSeries::QStackedBarSeries(QBarCategories categories, QObject *parent)
55 : QBarSeries(*new QStackedBarSeriesPrivate(categories,this), parent)
57 : QBarSeries(*new QStackedBarSeriesPrivate(categories,this), parent)
56 {
58 {
57 }
59 }
58
60
59 QAbstractSeries::QSeriesType QStackedBarSeries::type() const
61 QAbstractSeries::QSeriesType QStackedBarSeries::type() const
60 {
62 {
61 return QAbstractSeries::SeriesTypeStackedBar;
63 return QAbstractSeries::SeriesTypeStackedBar;
62 }
64 }
63
65
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65
67
66 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QBarCategories categories, QStackedBarSeries *q) : QBarSeriesPrivate(categories,q)
68 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QBarCategories categories, QStackedBarSeries *q) : QBarSeriesPrivate(categories,q)
67 {
69 {
68
70
69 }
71 }
70
72
71 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
73 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
72 {
74 {
73 qreal minX(domain.minX());
75 qreal minX(domain.minX());
74 qreal minY(domain.minY());
76 qreal minY(domain.minY());
75 qreal maxX(domain.maxX());
77 qreal maxX(domain.maxX());
76 qreal maxY(domain.maxY());
78 qreal maxY(domain.maxY());
77 int tickXCount(domain.tickXCount());
79 int tickXCount(domain.tickXCount());
78 int tickYCount(domain.tickYCount());
80 int tickYCount(domain.tickYCount());
79
81
80 qreal x = m_internalModel->categoryCount();
82 qreal x = m_internalModel->categoryCount();
81 qreal y = maxCategorySum();
83 qreal y = maxCategorySum();
82 minX = qMin(minX, x);
84 minX = qMin(minX, x);
83 minY = qMin(minY, y);
85 minY = qMin(minY, y);
84 maxX = qMax(maxX, x);
86 maxX = qMax(maxX, x);
85 maxY = qMax(maxY, y);
87 maxY = qMax(maxY, y);
86 tickXCount = x+1;
88 tickXCount = x+1;
87
89
88 domain.setRangeX(minX,maxX,tickXCount);
90 domain.setRangeX(minX,maxX,tickXCount);
89 domain.setRangeY(minY,maxY,tickYCount);
91 domain.setRangeY(minY,maxY,tickYCount);
90 }
92 }
91
93
92
94
93 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
95 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
94 {
96 {
95 Q_Q(QStackedBarSeries);
97 Q_Q(QStackedBarSeries);
96
98
97 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
99 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
98 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
100 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
99 presenter->animator()->addAnimation(bar);
101 presenter->animator()->addAnimation(bar);
100 }
102 }
101 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
103 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
102 return bar;
104 return bar;
103 }
105 }
104
106
105 #include "moc_qstackedbarseries.cpp"
107 #include "moc_qstackedbarseries.cpp"
106
108
107 QTCOMMERCIALCHART_END_NAMESPACE
109 QTCOMMERCIALCHART_END_NAMESPACE
108
110
@@ -1,451 +1,452
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 "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_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 \mainclass
51
52
52 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
53 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
54 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.
55 handle the drawing manually.
55 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
56 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
56
57
57 \mainclass
58 \image examples_percentbarchart_legend.png
58
59
59 \sa QChart, QAbstractSeries
60 \sa QChart
60 */
61 */
61
62
62 /*!
63 /*!
63 \enum QLegend::Alignment
64 \enum QLegend::Alignment
64
65
65 This enum describes the possible position for legend inside chart.
66 This enum describes the possible position for legend inside chart.
66
67
67 \value AlignmentTop
68 \value AlignmentTop
68 \value AlignmentBottom
69 \value AlignmentBottom
69 \value AlignmentLeft
70 \value AlignmentLeft
70 \value AlignmentRight
71 \value AlignmentRight
71 */
72 */
72
73
73 /*!
74 /*!
74 \fn qreal QLegend::minWidth() const
75 \fn qreal QLegend::minWidth() const
75 Returns minimum width of the legend
76 Returns minimum width of the legend
76 */
77 */
77
78
78 /*!
79 /*!
79 \fn qreal QLegend::minHeight() const
80 \fn qreal QLegend::minHeight() const
80 Returns minimum height of the legend
81 Returns minimum height of the legend
81 */
82 */
82
83
83 /*!
84 /*!
84 Constructs the legend object and sets the parent to \a parent
85 Constructs the legend object and sets the parent to \a parent
85 */
86 */
86
87
87 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
88 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
88 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
89 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
89 {
90 {
90 setZValue(ChartPresenter::LegendZValue);
91 setZValue(ChartPresenter::LegendZValue);
91 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
92 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
92 setEnabled(false); // By default legend is disabled
93 setEnabled(false); // By default legend is disabled
93 setVisible(false);
94 setVisible(false);
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries *,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries *, Domain *)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries *,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries *)));
96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries *)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries *)));
96 }
97 }
97
98
98 QLegend::~QLegend()
99 QLegend::~QLegend()
99 {
100 {
100
101
101 }
102 }
102
103
103 /*!
104 /*!
104 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
105 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
105 */
106 */
106
107
107 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
108 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
108 {
109 {
109 Q_UNUSED(option)
110 Q_UNUSED(option)
110 Q_UNUSED(widget)
111 Q_UNUSED(widget)
111 if(!d_ptr->m_backgroundVisible) return;
112 if(!d_ptr->m_backgroundVisible) return;
112
113
113 painter->setOpacity(opacity());
114 painter->setOpacity(opacity());
114 painter->setPen(d_ptr->m_pen);
115 painter->setPen(d_ptr->m_pen);
115 painter->setBrush(d_ptr->m_brush);
116 painter->setBrush(d_ptr->m_brush);
116 painter->drawRect(boundingRect());
117 painter->drawRect(boundingRect());
117 }
118 }
118
119
119 /*!
120 /*!
120 Bounding rect of legend.
121 Bounding rect of legend.
121 */
122 */
122
123
123 QRectF QLegend::boundingRect() const
124 QRectF QLegend::boundingRect() const
124 {
125 {
125 return d_ptr->m_rect;
126 return d_ptr->m_rect;
126 }
127 }
127
128
128 /*!
129 /*!
129 Sets the \a brush of legend. Brush affects the background of legend.
130 Sets the \a brush of legend. Brush affects the background of legend.
130 */
131 */
131 void QLegend::setBrush(const QBrush &brush)
132 void QLegend::setBrush(const QBrush &brush)
132 {
133 {
133 if (d_ptr->m_brush != brush) {
134 if (d_ptr->m_brush != brush) {
134 d_ptr->m_brush = brush;
135 d_ptr->m_brush = brush;
135 update();
136 update();
136 }
137 }
137 }
138 }
138
139
139 /*!
140 /*!
140 Returns the brush used by legend.
141 Returns the brush used by legend.
141 */
142 */
142 QBrush QLegend::brush() const
143 QBrush QLegend::brush() const
143 {
144 {
144 return d_ptr->m_brush;
145 return d_ptr->m_brush;
145 }
146 }
146
147
147 /*!
148 /*!
148 Sets the \a pen of legend. Pen affects the legend borders.
149 Sets the \a pen of legend. Pen affects the legend borders.
149 */
150 */
150 void QLegend::setPen(const QPen &pen)
151 void QLegend::setPen(const QPen &pen)
151 {
152 {
152 if (d_ptr->m_pen != pen) {
153 if (d_ptr->m_pen != pen) {
153 d_ptr->m_pen = pen;
154 d_ptr->m_pen = pen;
154 update();
155 update();
155 }
156 }
156 }
157 }
157
158
158 /*!
159 /*!
159 Returns the pen used by legend
160 Returns the pen used by legend
160 */
161 */
161
162
162 QPen QLegend::pen() const
163 QPen QLegend::pen() const
163 {
164 {
164 return d_ptr->m_pen;
165 return d_ptr->m_pen;
165 }
166 }
166
167
167 /*!
168 /*!
168 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
169 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
169 \sa QLegend::Alignment
170 \sa QLegend::Alignment
170 */
171 */
171 void QLegend::setAlignment(QLegend::Alignments alignment)
172 void QLegend::setAlignment(QLegend::Alignments alignment)
172 {
173 {
173 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
174 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
174 d_ptr->m_alignment = alignment;
175 d_ptr->m_alignment = alignment;
175 d_ptr->updateLayout();
176 d_ptr->updateLayout();
176 }
177 }
177 }
178 }
178
179
179 /*!
180 /*!
180 Returns the preferred layout for legend
181 Returns the preferred layout for legend
181 */
182 */
182 QLegend::Alignments QLegend::alignment() const
183 QLegend::Alignments QLegend::alignment() const
183 {
184 {
184 return d_ptr->m_alignment;
185 return d_ptr->m_alignment;
185 }
186 }
186
187
187 /*!
188 /*!
188 Detaches the legend from chart. Chart won't change layout of the legend.
189 Detaches the legend from chart. Chart won't change layout of the legend.
189 */
190 */
190 void QLegend::detachFromChart()
191 void QLegend::detachFromChart()
191 {
192 {
192 d_ptr->m_attachedToChart = false;
193 d_ptr->m_attachedToChart = false;
193 }
194 }
194
195
195 /*!
196 /*!
196 Attaches the legend to chart. Chart may change layout of the legend.
197 Attaches the legend to chart. Chart may change layout of the legend.
197 */
198 */
198 void QLegend::attachToChart()
199 void QLegend::attachToChart()
199 {
200 {
200 d_ptr->m_attachedToChart = true;
201 d_ptr->m_attachedToChart = true;
201 }
202 }
202
203
203 /*!
204 /*!
204 Returns true, if legend is attached to chart.
205 Returns true, if legend is attached to chart.
205 */
206 */
206 bool QLegend::isAttachedToChart()
207 bool QLegend::isAttachedToChart()
207 {
208 {
208 return d_ptr->m_attachedToChart;
209 return d_ptr->m_attachedToChart;
209 }
210 }
210
211
211 void QLegend::setOffset(const QPointF& point)
212 void QLegend::setOffset(const QPointF& point)
212 {
213 {
213 d_ptr->setOffset(point.x(),point.y());
214 d_ptr->setOffset(point.x(),point.y());
214 }
215 }
215
216
216 QPointF QLegend::offset() const
217 QPointF QLegend::offset() const
217 {
218 {
218 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
219 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
219 }
220 }
220
221
221 /*!
222 /*!
222 Sets the visibility of legend background to \a visible
223 Sets the visibility of legend background to \a visible
223 */
224 */
224 void QLegend::setBackgroundVisible(bool visible)
225 void QLegend::setBackgroundVisible(bool visible)
225 {
226 {
226 if(d_ptr->m_backgroundVisible!=visible)
227 if(d_ptr->m_backgroundVisible!=visible)
227 {
228 {
228 d_ptr->m_backgroundVisible=visible;
229 d_ptr->m_backgroundVisible=visible;
229 update();
230 update();
230 }
231 }
231 }
232 }
232
233
233 /*!
234 /*!
234 Returns the visibility of legend background
235 Returns the visibility of legend background
235 */
236 */
236 bool QLegend::isBackgroundVisible() const
237 bool QLegend::isBackgroundVisible() const
237 {
238 {
238 return d_ptr->m_backgroundVisible;
239 return d_ptr->m_backgroundVisible;
239 }
240 }
240
241
241 /*!
242 /*!
242 \internal \a event see QGraphicsWidget for details
243 \internal \a event see QGraphicsWidget for details
243 */
244 */
244 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
245 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
245 {
246 {
246 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
247 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
247 QGraphicsWidget::resizeEvent(event);
248 QGraphicsWidget::resizeEvent(event);
248 if(d_ptr->m_rect != rect) {
249 if(d_ptr->m_rect != rect) {
249 d_ptr->m_rect = rect;
250 d_ptr->m_rect = rect;
250 d_ptr->updateLayout();
251 d_ptr->updateLayout();
251 }
252 }
252 }
253 }
253
254
254 /*!
255 /*!
255 \internal \a event see QGraphicsWidget for details
256 \internal \a event see QGraphicsWidget for details
256 */
257 */
257 void QLegend::hideEvent(QHideEvent *event)
258 void QLegend::hideEvent(QHideEvent *event)
258 {
259 {
259 QGraphicsWidget::hideEvent(event);
260 QGraphicsWidget::hideEvent(event);
260 setEnabled(false);
261 setEnabled(false);
261 d_ptr->updateLayout();
262 d_ptr->updateLayout();
262 }
263 }
263
264
264 /*!
265 /*!
265 \internal \a event see QGraphicsWidget for details
266 \internal \a event see QGraphicsWidget for details
266 */
267 */
267 void QLegend::showEvent(QShowEvent *event)
268 void QLegend::showEvent(QShowEvent *event)
268 {
269 {
269 QGraphicsWidget::showEvent(event);
270 QGraphicsWidget::showEvent(event);
270 setEnabled(true);
271 setEnabled(true);
271 d_ptr->updateLayout();
272 d_ptr->updateLayout();
272 }
273 }
273
274
274 qreal QLegend::minWidth() const
275 qreal QLegend::minWidth() const
275 {
276 {
276 return d_ptr->m_minWidth;
277 return d_ptr->m_minWidth;
277 }
278 }
278
279
279 qreal QLegend::minHeight() const
280 qreal QLegend::minHeight() const
280 {
281 {
281 return d_ptr->m_minHeight;
282 return d_ptr->m_minHeight;
282 }
283 }
283
284
284 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
285 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
285
286
286 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
287 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
287 q_ptr(q),
288 q_ptr(q),
288 m_presenter(presenter),
289 m_presenter(presenter),
289 m_markers(new QGraphicsItemGroup(q)),
290 m_markers(new QGraphicsItemGroup(q)),
290 m_alignment(QLegend::AlignmentTop),
291 m_alignment(QLegend::AlignmentTop),
291 m_offsetX(0),
292 m_offsetX(0),
292 m_offsetY(0),
293 m_offsetY(0),
293 m_minWidth(0),
294 m_minWidth(0),
294 m_minHeight(0),
295 m_minHeight(0),
295 m_width(0),
296 m_width(0),
296 m_height(0),
297 m_height(0),
297 m_attachedToChart(true),
298 m_attachedToChart(true),
298 m_backgroundVisible(false)
299 m_backgroundVisible(false)
299 {
300 {
300
301
301 }
302 }
302
303
303 QLegendPrivate::~QLegendPrivate()
304 QLegendPrivate::~QLegendPrivate()
304 {
305 {
305
306
306 }
307 }
307
308
308 void QLegendPrivate::setOffset(qreal x, qreal y)
309 void QLegendPrivate::setOffset(qreal x, qreal y)
309 {
310 {
310
311
311 switch(m_alignment) {
312 switch(m_alignment) {
312
313
313 case QLegend::AlignmentTop:
314 case QLegend::AlignmentTop:
314 case QLegend::AlignmentBottom: {
315 case QLegend::AlignmentBottom: {
315 if(m_width<=m_rect.width()) return;
316 if(m_width<=m_rect.width()) return;
316
317
317 if (x != m_offsetX) {
318 if (x != m_offsetX) {
318 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
319 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
319 m_markers->setPos(-m_offsetX,m_rect.top());
320 m_markers->setPos(-m_offsetX,m_rect.top());
320 }
321 }
321 break;
322 break;
322 }
323 }
323 case QLegend::AlignmentLeft:
324 case QLegend::AlignmentLeft:
324 case QLegend::AlignmentRight: {
325 case QLegend::AlignmentRight: {
325
326
326 if(m_height<=m_rect.height()) return;
327 if(m_height<=m_rect.height()) return;
327
328
328 if (y != m_offsetY) {
329 if (y != m_offsetY) {
329 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
330 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
330 m_markers->setPos(m_rect.left(),-m_offsetY);
331 m_markers->setPos(m_rect.left(),-m_offsetY);
331 }
332 }
332 break;
333 break;
333 }
334 }
334 }
335 }
335 }
336 }
336
337
337
338
338 void QLegendPrivate::updateLayout()
339 void QLegendPrivate::updateLayout()
339 {
340 {
340 m_offsetX=0;
341 m_offsetX=0;
341 QList<QGraphicsItem *> items = m_markers->childItems();
342 QList<QGraphicsItem *> items = m_markers->childItems();
342
343
343 if(items.isEmpty()) return;
344 if(items.isEmpty()) return;
344
345
345 m_minWidth=0;
346 m_minWidth=0;
346 m_minHeight=0;
347 m_minHeight=0;
347
348
348 switch(m_alignment) {
349 switch(m_alignment) {
349
350
350 case QLegend::AlignmentTop:
351 case QLegend::AlignmentTop:
351 case QLegend::AlignmentBottom: {
352 case QLegend::AlignmentBottom: {
352 QPointF point = m_rect.topLeft();
353 QPointF point = m_rect.topLeft();
353 m_width = 0;
354 m_width = 0;
354 foreach (QGraphicsItem *item, items) {
355 foreach (QGraphicsItem *item, items) {
355 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
356 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
356 const QRectF& rect = item->boundingRect();
357 const QRectF& rect = item->boundingRect();
357 qreal w = rect.width();
358 qreal w = rect.width();
358 m_minWidth=qMax(m_minWidth,w);
359 m_minWidth=qMax(m_minWidth,w);
359 m_minHeight=qMax(m_minHeight,rect.height());
360 m_minHeight=qMax(m_minHeight,rect.height());
360 m_width+=w;
361 m_width+=w;
361 point.setX(point.x() + w);
362 point.setX(point.x() + w);
362 }
363 }
363 if(m_width<m_rect.width()) {
364 if(m_width<m_rect.width()) {
364 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
365 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
365 }
366 }
366 else {
367 else {
367 m_markers->setPos(m_rect.topLeft());
368 m_markers->setPos(m_rect.topLeft());
368 }
369 }
369 m_height=m_minHeight;
370 m_height=m_minHeight;
370 }
371 }
371 break;
372 break;
372 case QLegend::AlignmentLeft:
373 case QLegend::AlignmentLeft:
373 case QLegend::AlignmentRight: {
374 case QLegend::AlignmentRight: {
374 QPointF point = m_rect.topLeft();
375 QPointF point = m_rect.topLeft();
375 m_height = 0;
376 m_height = 0;
376 foreach (QGraphicsItem *item, items) {
377 foreach (QGraphicsItem *item, items) {
377 item->setPos(point);
378 item->setPos(point);
378 const QRectF& rect = item->boundingRect();
379 const QRectF& rect = item->boundingRect();
379 qreal h = rect.height();
380 qreal h = rect.height();
380 m_minWidth=qMax(m_minWidth,rect.width());
381 m_minWidth=qMax(m_minWidth,rect.width());
381 m_minHeight=qMax(m_minHeight,h);
382 m_minHeight=qMax(m_minHeight,h);
382 m_height+=h;
383 m_height+=h;
383 point.setY(point.y() + h);
384 point.setY(point.y() + h);
384 }
385 }
385 if(m_height<m_rect.height()) {
386 if(m_height<m_rect.height()) {
386 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
387 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
387 }
388 }
388 else {
389 else {
389 m_markers->setPos(m_rect.topLeft());
390 m_markers->setPos(m_rect.topLeft());
390 }
391 }
391 m_width=m_minWidth;
392 m_width=m_minWidth;
392 }
393 }
393 break;
394 break;
394 }
395 }
395
396
396 m_presenter->updateLayout();
397 m_presenter->updateLayout();
397 }
398 }
398
399
399 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
400 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
400 {
401 {
401 Q_UNUSED(domain)
402 Q_UNUSED(domain)
402
403
403 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
404 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
404 foreach(LegendMarker* marker , markers)
405 foreach(LegendMarker* marker , markers)
405 m_markers->addToGroup(marker);
406 m_markers->addToGroup(marker);
406
407
407 if(series->type() == QAbstractSeries::SeriesTypePie)
408 if(series->type() == QAbstractSeries::SeriesTypePie)
408 {
409 {
409 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
410 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
410 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
411 QObject::connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
411 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
412 QObject::connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
412 }
413 }
413
414
414 updateLayout();
415 updateLayout();
415 }
416 }
416
417
417 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
418 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
418 {
419 {
419
420
420 QList<QGraphicsItem *> items = m_markers->childItems();
421 QList<QGraphicsItem *> items = m_markers->childItems();
421
422
422 foreach (QGraphicsItem *markers, items) {
423 foreach (QGraphicsItem *markers, items) {
423 LegendMarker *marker = static_cast<LegendMarker*>(markers);
424 LegendMarker *marker = static_cast<LegendMarker*>(markers);
424 if (marker->series() == series) {
425 if (marker->series() == series) {
425 delete marker;
426 delete marker;
426 }
427 }
427 }
428 }
428
429
429 if(series->type() == QAbstractSeries::SeriesTypePie)
430 if(series->type() == QAbstractSeries::SeriesTypePie)
430 {
431 {
431 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
432 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
432 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
433 QObject::disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
433 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
434 QObject::disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleUpdateSeries()));
434 }
435 }
435
436
436 updateLayout();
437 updateLayout();
437 }
438 }
438
439
439 void QLegendPrivate::handleUpdateSeries()
440 void QLegendPrivate::handleUpdateSeries()
440 {
441 {
441 //TODO: reimplement to be optimal
442 //TODO: reimplement to be optimal
442 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
443 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
443 Q_ASSERT(series);
444 Q_ASSERT(series);
444 handleSeriesRemoved(series);
445 handleSeriesRemoved(series);
445 handleSeriesAdded(series,0);
446 handleSeriesAdded(series,0);
446 }
447 }
447
448
448 #include "moc_qlegend.cpp"
449 #include "moc_qlegend.cpp"
449 #include "moc_qlegend_p.cpp"
450 #include "moc_qlegend_p.cpp"
450
451
451 QTCOMMERCIALCHART_END_NAMESPACE
452 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 examples_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 chart->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 QAbstractSeries, QSeriesType
54 \sa QAbstractSeries, 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 transferred.
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 QAbstractSeries::QSeriesType QLineSeries::type() const
81 QAbstractSeries::QSeriesType QLineSeries::type() const
82 {
82 {
83 return QAbstractSeries::SeriesTypeLine;
83 return QAbstractSeries::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,738 +1,741
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
49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 \image examples_piechart.png
48 */
51 */
49
52
50 /*!
53 /*!
51 \property QPieSeries::horizontalPosition
54 \property QPieSeries::horizontalPosition
52 \brief Defines the horizontal position of the pie.
55 \brief Defines the horizontal position of the pie.
53
56
54 The value is a relative value to the chart rectangle where:
57 The value is a relative value to the chart rectangle where:
55
58
56 \list
59 \list
57 \o 0.0 is the absolute left.
60 \o 0.0 is the absolute left.
58 \o 1.0 is the absolute right.
61 \o 1.0 is the absolute right.
59 \endlist
62 \endlist
60
63
61 Default value is 0.5 (center).
64 Default value is 0.5 (center).
62 */
65 */
63
66
64 /*!
67 /*!
65 \property QPieSeries::verticalPosition
68 \property QPieSeries::verticalPosition
66 \brief Defines the vertical position of the pie.
69 \brief Defines the vertical position of the pie.
67
70
68 The value is a relative value to the chart rectangle where:
71 The value is a relative value to the chart rectangle where:
69
72
70 \list
73 \list
71 \o 0.0 is the absolute top.
74 \o 0.0 is the absolute top.
72 \o 1.0 is the absolute bottom.
75 \o 1.0 is the absolute bottom.
73 \endlist
76 \endlist
74
77
75 Default value is 0.5 (center).
78 Default value is 0.5 (center).
76 */
79 */
77
80
78 /*!
81 /*!
79 \property QPieSeries::size
82 \property QPieSeries::size
80 \brief Defines the pie size.
83 \brief Defines the pie size.
81
84
82 The value is a relative value to the chart rectangle where:
85 The value is a relative value to the chart rectangle where:
83
86
84 \list
87 \list
85 \o 0.0 is the minimum size (pie not drawn).
88 \o 0.0 is the minimum size (pie not drawn).
86 \o 1.0 is the maximum size that can fit the chart.
89 \o 1.0 is the maximum size that can fit the chart.
87 \endlist
90 \endlist
88
91
89 Default value is 0.7.
92 Default value is 0.7.
90 */
93 */
91
94
92 /*!
95 /*!
93 \property QPieSeries::startAngle
96 \property QPieSeries::startAngle
94 \brief Defines the starting angle of the pie.
97 \brief Defines the starting angle of the pie.
95
98
96 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
97
100
98 Default is value is 0.
101 Default is value is 0.
99 */
102 */
100
103
101 /*!
104 /*!
102 \property QPieSeries::endAngle
105 \property QPieSeries::endAngle
103 \brief Defines the ending angle of the pie.
106 \brief Defines the ending angle of the pie.
104
107
105 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
106
109
107 Default is value is 360.
110 Default is value is 360.
108 */
111 */
109
112
110
113
111 /*!
114 /*!
112 Constructs a series object which is a child of \a parent.
115 Constructs a series object which is a child of \a parent.
113 */
116 */
114 QPieSeries::QPieSeries(QObject *parent) :
117 QPieSeries::QPieSeries(QObject *parent) :
115 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
116 {
119 {
117
120
118 }
121 }
119
122
120 /*!
123 /*!
121 Destroys the series and its slices.
124 Destroys the series and its slices.
122 */
125 */
123 QPieSeries::~QPieSeries()
126 QPieSeries::~QPieSeries()
124 {
127 {
125 // NOTE: d_prt destroyed by QObject
128 // NOTE: d_prt destroyed by QObject
126 }
129 }
127
130
128 /*!
131 /*!
129 Returns QChartSeries::SeriesTypePie.
132 Returns QChartSeries::SeriesTypePie.
130 */
133 */
131 QAbstractSeries::QSeriesType QPieSeries::type() const
134 QAbstractSeries::QSeriesType QPieSeries::type() const
132 {
135 {
133 return QAbstractSeries::SeriesTypePie;
136 return QAbstractSeries::SeriesTypePie;
134 }
137 }
135
138
136 /*!
139 /*!
137 Sets an array of \a slices to the series replacing the existing slices.
140 Sets an array of \a slices to the series replacing the existing slices.
138 Slice ownership is passed to the series.
141 Slice ownership is passed to the series.
139 */
142 */
140 void QPieSeries::replace(QList<QPieSlice*> slices)
143 void QPieSeries::replace(QList<QPieSlice*> slices)
141 {
144 {
142 clear();
145 clear();
143 append(slices);
146 append(slices);
144 }
147 }
145
148
146 /*!
149 /*!
147 Appends an array of \a slices to the series.
150 Appends an array of \a slices to the series.
148 Slice ownership is passed to the series.
151 Slice ownership is passed to the series.
149 */
152 */
150 void QPieSeries::append(QList<QPieSlice*> slices)
153 void QPieSeries::append(QList<QPieSlice*> slices)
151 {
154 {
152 Q_D(QPieSeries);
155 Q_D(QPieSeries);
153
156
154 foreach (QPieSlice* s, slices) {
157 foreach (QPieSlice* s, slices) {
155 s->setParent(this);
158 s->setParent(this);
156 d->m_slices << s;
159 d->m_slices << s;
157 }
160 }
158
161
159 d->updateDerivativeData();
162 d->updateDerivativeData();
160
163
161 foreach (QPieSlice* s, slices) {
164 foreach (QPieSlice* s, slices) {
162 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
165 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
163 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
166 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
164 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
167 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
165 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
168 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
166 }
169 }
167
170
168 emit added(slices);
171 emit added(slices);
169 }
172 }
170
173
171 /*!
174 /*!
172 Appends a single \a slice to the series.
175 Appends a single \a slice to the series.
173 Slice ownership is passed to the series.
176 Slice ownership is passed to the series.
174 */
177 */
175 void QPieSeries::append(QPieSlice* slice)
178 void QPieSeries::append(QPieSlice* slice)
176 {
179 {
177 append(QList<QPieSlice*>() << slice);
180 append(QList<QPieSlice*>() << slice);
178 }
181 }
179
182
180 /*!
183 /*!
181 Appends a single \a slice to the series and returns a reference to the series.
184 Appends a single \a slice to the series and returns a reference to the series.
182 Slice ownership is passed to the series.
185 Slice ownership is passed to the series.
183 */
186 */
184 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
187 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
185 {
188 {
186 append(slice);
189 append(slice);
187 return *this;
190 return *this;
188 }
191 }
189
192
190
193
191 /*!
194 /*!
192 Appends a single slice to the series with give \a value and \a name.
195 Appends a single slice to the series with give \a value and \a name.
193 Slice ownership is passed to the series.
196 Slice ownership is passed to the series.
194 */
197 */
195 QPieSlice* QPieSeries::append(qreal value, QString name)
198 QPieSlice* QPieSeries::append(qreal value, QString name)
196 {
199 {
197 QPieSlice* slice = new QPieSlice(value, name);
200 QPieSlice* slice = new QPieSlice(value, name);
198 append(slice);
201 append(slice);
199 return slice;
202 return slice;
200 }
203 }
201
204
202 /*!
205 /*!
203 Inserts a single \a slice to the series before the slice at \a index position.
206 Inserts a single \a slice to the series before the slice at \a index position.
204 Slice ownership is passed to the series.
207 Slice ownership is passed to the series.
205 */
208 */
206 void QPieSeries::insert(int index, QPieSlice* slice)
209 void QPieSeries::insert(int index, QPieSlice* slice)
207 {
210 {
208 Q_D(QPieSeries);
211 Q_D(QPieSeries);
209 Q_ASSERT(index <= d->m_slices.count());
212 Q_ASSERT(index <= d->m_slices.count());
210 slice->setParent(this);
213 slice->setParent(this);
211 d->m_slices.insert(index, slice);
214 d->m_slices.insert(index, slice);
212
215
213 d->updateDerivativeData();
216 d->updateDerivativeData();
214
217
215 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
218 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
216 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
219 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
217 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
220 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
218 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
221 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
219
222
220 emit added(QList<QPieSlice*>() << slice);
223 emit added(QList<QPieSlice*>() << slice);
221 }
224 }
222
225
223 /*!
226 /*!
224 Removes a single \a slice from the series and deletes the slice.
227 Removes a single \a slice from the series and deletes the slice.
225
228
226 Do not reference the pointer after this call.
229 Do not reference the pointer after this call.
227 */
230 */
228 void QPieSeries::remove(QPieSlice* slice)
231 void QPieSeries::remove(QPieSlice* slice)
229 {
232 {
230 Q_D(QPieSeries);
233 Q_D(QPieSeries);
231 if (!d->m_slices.removeOne(slice)) {
234 if (!d->m_slices.removeOne(slice)) {
232 Q_ASSERT(0); // TODO: how should this be reported?
235 Q_ASSERT(0); // TODO: how should this be reported?
233 return;
236 return;
234 }
237 }
235
238
236 d->updateDerivativeData();
239 d->updateDerivativeData();
237
240
238 emit removed(QList<QPieSlice*>() << slice);
241 emit removed(QList<QPieSlice*>() << slice);
239
242
240 delete slice;
243 delete slice;
241 slice = 0;
244 slice = 0;
242 }
245 }
243
246
244 /*!
247 /*!
245 Clears all slices from the series.
248 Clears all slices from the series.
246 */
249 */
247 void QPieSeries::clear()
250 void QPieSeries::clear()
248 {
251 {
249 Q_D(QPieSeries);
252 Q_D(QPieSeries);
250 if (d->m_slices.count() == 0)
253 if (d->m_slices.count() == 0)
251 return;
254 return;
252
255
253 QList<QPieSlice*> slices = d->m_slices;
256 QList<QPieSlice*> slices = d->m_slices;
254 foreach (QPieSlice* s, d->m_slices) {
257 foreach (QPieSlice* s, d->m_slices) {
255 d->m_slices.removeOne(s);
258 d->m_slices.removeOne(s);
256 delete s;
259 delete s;
257 }
260 }
258
261
259 d->updateDerivativeData();
262 d->updateDerivativeData();
260
263
261 emit removed(slices);
264 emit removed(slices);
262 }
265 }
263
266
264 /*!
267 /*!
265 returns the number of the slices in this series.
268 returns the number of the slices in this series.
266 */
269 */
267 int QPieSeries::count() const
270 int QPieSeries::count() const
268 {
271 {
269 Q_D(const QPieSeries);
272 Q_D(const QPieSeries);
270 return d->m_slices.count();
273 return d->m_slices.count();
271 }
274 }
272
275
273 /*!
276 /*!
274 Returns true is the series is empty.
277 Returns true is the series is empty.
275 */
278 */
276 bool QPieSeries::isEmpty() const
279 bool QPieSeries::isEmpty() const
277 {
280 {
278 Q_D(const QPieSeries);
281 Q_D(const QPieSeries);
279 return d->m_slices.isEmpty();
282 return d->m_slices.isEmpty();
280 }
283 }
281
284
282 /*!
285 /*!
283 Returns a list of slices that belong to this series.
286 Returns a list of slices that belong to this series.
284 */
287 */
285 QList<QPieSlice*> QPieSeries::slices() const
288 QList<QPieSlice*> QPieSeries::slices() const
286 {
289 {
287 Q_D(const QPieSeries);
290 Q_D(const QPieSeries);
288 return d->m_slices;
291 return d->m_slices;
289 }
292 }
290
293
291 void QPieSeries::setHorizontalPosition(qreal relativePosition)
294 void QPieSeries::setHorizontalPosition(qreal relativePosition)
292 {
295 {
293 Q_D(QPieSeries);
296 Q_D(QPieSeries);
294 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
297 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
295 emit piePositionChanged();
298 emit piePositionChanged();
296 }
299 }
297
300
298 void QPieSeries::setVerticalPosition(qreal relativePosition)
301 void QPieSeries::setVerticalPosition(qreal relativePosition)
299 {
302 {
300 Q_D(QPieSeries);
303 Q_D(QPieSeries);
301 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
304 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
302 emit piePositionChanged();
305 emit piePositionChanged();
303 }
306 }
304
307
305 qreal QPieSeries::horizontalPosition() const
308 qreal QPieSeries::horizontalPosition() const
306 {
309 {
307 Q_D(const QPieSeries);
310 Q_D(const QPieSeries);
308 return d->m_pieRelativeHorPos;
311 return d->m_pieRelativeHorPos;
309 }
312 }
310
313
311 qreal QPieSeries::verticalPosition() const
314 qreal QPieSeries::verticalPosition() const
312 {
315 {
313 Q_D(const QPieSeries);
316 Q_D(const QPieSeries);
314 return d->m_pieRelativeVerPos;
317 return d->m_pieRelativeVerPos;
315 }
318 }
316
319
317 void QPieSeries::setPieSize(qreal relativeSize)
320 void QPieSeries::setPieSize(qreal relativeSize)
318 {
321 {
319 Q_D(QPieSeries);
322 Q_D(QPieSeries);
320 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
323 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
321 emit pieSizeChanged();
324 emit pieSizeChanged();
322 }
325 }
323
326
324 qreal QPieSeries::pieSize() const
327 qreal QPieSeries::pieSize() const
325 {
328 {
326 Q_D(const QPieSeries);
329 Q_D(const QPieSeries);
327 return d->m_pieRelativeSize;
330 return d->m_pieRelativeSize;
328 }
331 }
329
332
330
333
331 void QPieSeries::setPieStartAngle(qreal angle)
334 void QPieSeries::setPieStartAngle(qreal angle)
332 {
335 {
333 Q_D(QPieSeries);
336 Q_D(QPieSeries);
334 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
337 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
335 d->updateDerivativeData();
338 d->updateDerivativeData();
336 }
339 }
337
340
338 qreal QPieSeries::pieStartAngle() const
341 qreal QPieSeries::pieStartAngle() const
339 {
342 {
340 Q_D(const QPieSeries);
343 Q_D(const QPieSeries);
341 return d->m_pieStartAngle;
344 return d->m_pieStartAngle;
342 }
345 }
343
346
344 /*!
347 /*!
345 Sets the end angle of the pie.
348 Sets the end angle of the pie.
346
349
347 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
350 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
348
351
349 \a angle must be greater than start angle.
352 \a angle must be greater than start angle.
350
353
351 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
354 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
352 */
355 */
353 void QPieSeries::setPieEndAngle(qreal angle)
356 void QPieSeries::setPieEndAngle(qreal angle)
354 {
357 {
355 Q_D(QPieSeries);
358 Q_D(QPieSeries);
356
359
357 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
360 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
358 d->updateDerivativeData();
361 d->updateDerivativeData();
359 }
362 }
360
363
361 /*!
364 /*!
362 Returns the end angle of the pie.
365 Returns the end angle of the pie.
363
366
364 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
367 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
365
368
366 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
369 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
367 */
370 */
368 qreal QPieSeries::pieEndAngle() const
371 qreal QPieSeries::pieEndAngle() const
369 {
372 {
370 Q_D(const QPieSeries);
373 Q_D(const QPieSeries);
371 return d->m_pieEndAngle;
374 return d->m_pieEndAngle;
372 }
375 }
373
376
374 /*!
377 /*!
375 Sets the all the slice labels \a visible or invisible.
378 Sets the all the slice labels \a visible or invisible.
376
379
377 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
380 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
378 */
381 */
379 void QPieSeries::setLabelsVisible(bool visible)
382 void QPieSeries::setLabelsVisible(bool visible)
380 {
383 {
381 Q_D(QPieSeries);
384 Q_D(QPieSeries);
382 foreach (QPieSlice* s, d->m_slices)
385 foreach (QPieSlice* s, d->m_slices)
383 s->setLabelVisible(visible);
386 s->setLabelVisible(visible);
384 }
387 }
385
388
386 /*!
389 /*!
387 Returns the sum of all slice values in this series.
390 Returns the sum of all slice values in this series.
388
391
389 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
392 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
390 */
393 */
391 qreal QPieSeries::sum() const
394 qreal QPieSeries::sum() const
392 {
395 {
393 Q_D(const QPieSeries);
396 Q_D(const QPieSeries);
394 return d->m_sum;
397 return d->m_sum;
395 }
398 }
396
399
397 /*!
400 /*!
398 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
401 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
399
402
400 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
403 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
401
404
402 \sa QPieSlice::clicked()
405 \sa QPieSlice::clicked()
403 */
406 */
404
407
405 /*!
408 /*!
406 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
409 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
407
410
408 This signal is emitted when user has hovered over a \a slice.
411 This signal is emitted when user has hovered over a \a slice.
409
412
410 \sa QPieSlice::hoverEnter()
413 \sa QPieSlice::hoverEnter()
411 */
414 */
412
415
413 /*!
416 /*!
414 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
417 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
415
418
416 This signal is emitted when user has hovered away from a \a slice.
419 This signal is emitted when user has hovered away from a \a slice.
417
420
418 \sa QPieSlice::hoverLeave()
421 \sa QPieSlice::hoverLeave()
419 */
422 */
420
423
421 /*!
424 /*!
422 \fn void QPieSeries::added(QList<QPieSlice*> slices)
425 \fn void QPieSeries::added(QList<QPieSlice*> slices)
423
426
424 This signal is emitted when \a slices has been added to the series.
427 This signal is emitted when \a slices has been added to the series.
425
428
426 \sa append(), insert()
429 \sa append(), insert()
427 */
430 */
428
431
429 /*!
432 /*!
430 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
433 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
431
434
432 This signal is emitted when \a slices has been removed from the series.
435 This signal is emitted when \a slices has been removed from the series.
433
436
434 \sa remove(), clear()
437 \sa remove(), clear()
435 */
438 */
436
439
437 /*!
440 /*!
438 \fn void QPieSeries::piePositionChanged()
441 \fn void QPieSeries::piePositionChanged()
439
442
440 This signal is emitted when pie position has changed.
443 This signal is emitted when pie position has changed.
441
444
442 \sa verticalPosition(), setVerticalPosition(), horizontalPosition(), setHorizontalPosition()
445 \sa verticalPosition(), setVerticalPosition(), horizontalPosition(), setHorizontalPosition()
443 */
446 */
444
447
445 /*!
448 /*!
446 \fn void QPieSeries::pieSizeChanged()
449 \fn void QPieSeries::pieSizeChanged()
447
450
448 This signal is emitted when pie size has changed.
451 This signal is emitted when pie size has changed.
449
452
450 \sa pieSize(), setPieSize()
453 \sa pieSize(), setPieSize()
451 */
454 */
452
455
453 /*!
456 /*!
454 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
457 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
455 Sets the \a model to be used as a data source
458 Sets the \a model to be used as a data source
456 */
459 */
457 bool QPieSeries::setModel(QAbstractItemModel* model)
460 bool QPieSeries::setModel(QAbstractItemModel* model)
458 {
461 {
459 Q_D(QPieSeries);
462 Q_D(QPieSeries);
460 // disconnect signals from old model
463 // disconnect signals from old model
461 if(d->m_model)
464 if(d->m_model)
462 {
465 {
463 disconnect(d->m_model, 0, this, 0);
466 disconnect(d->m_model, 0, this, 0);
464 d->m_mapValues = -1;
467 d->m_mapValues = -1;
465 d->m_mapLabels = -1;
468 d->m_mapLabels = -1;
466 d->m_mapOrientation = Qt::Vertical;
469 d->m_mapOrientation = Qt::Vertical;
467 }
470 }
468
471
469 // set new model
472 // set new model
470 if(model)
473 if(model)
471 {
474 {
472 d->m_model = model;
475 d->m_model = model;
473 return true;
476 return true;
474 }
477 }
475 else
478 else
476 {
479 {
477 d->m_model = 0;
480 d->m_model = 0;
478 return false;
481 return false;
479 }
482 }
480 }
483 }
481
484
482 /*!
485 /*!
483 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
486 \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.
487 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.
488 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.
489 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
487 The \a orientation parameter specifies whether the data is in columns or in rows.
490 The \a orientation parameter specifies whether the data is in columns or in rows.
488 */
491 */
489 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
492 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
490 {
493 {
491 Q_D(QPieSeries);
494 Q_D(QPieSeries);
492
495
493 if (d->m_model == 0)
496 if (d->m_model == 0)
494 return;
497 return;
495
498
496 d->m_mapValues = modelValuesLine;
499 d->m_mapValues = modelValuesLine;
497 d->m_mapLabels = modelLabelsLine;
500 d->m_mapLabels = modelLabelsLine;
498 d->m_mapOrientation = orientation;
501 d->m_mapOrientation = orientation;
499
502
500 // connect the signals
503 // connect the signals
501 if (d->m_mapOrientation == Qt::Vertical) {
504 if (d->m_mapOrientation == Qt::Vertical) {
502 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
505 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)));
506 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)));
507 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
505 } else {
508 } else {
506 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
509 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)));
510 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)));
511 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
509 }
512 }
510
513
511 // create the initial slices set
514 // create the initial slices set
512 if (d->m_mapOrientation == Qt::Vertical) {
515 if (d->m_mapOrientation == Qt::Vertical) {
513 for (int i = 0; i < d->m_model->rowCount(); i++)
516 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());
517 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 {
518 } else {
516 for (int i = 0; i < d->m_model->columnCount(); i++)
519 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());
520 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 }
521 }
519 }
522 }
520
523
521 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
522
525
523
526
524 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
527 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
525 QAbstractSeriesPrivate(parent),
528 QAbstractSeriesPrivate(parent),
526 m_pieRelativeHorPos(0.5),
529 m_pieRelativeHorPos(0.5),
527 m_pieRelativeVerPos(0.5),
530 m_pieRelativeVerPos(0.5),
528 m_pieRelativeSize(0.7),
531 m_pieRelativeSize(0.7),
529 m_pieStartAngle(0),
532 m_pieStartAngle(0),
530 m_pieEndAngle(360),
533 m_pieEndAngle(360),
531 m_sum(0),
534 m_sum(0),
532 m_mapValues(0),
535 m_mapValues(0),
533 m_mapLabels(0),
536 m_mapLabels(0),
534 m_mapOrientation(Qt::Horizontal)
537 m_mapOrientation(Qt::Horizontal)
535 {
538 {
536
539
537 }
540 }
538
541
539 QPieSeriesPrivate::~QPieSeriesPrivate()
542 QPieSeriesPrivate::~QPieSeriesPrivate()
540 {
543 {
541
544
542 }
545 }
543
546
544 void QPieSeriesPrivate::updateDerivativeData()
547 void QPieSeriesPrivate::updateDerivativeData()
545 {
548 {
546 m_sum = 0;
549 m_sum = 0;
547
550
548 // nothing to do?
551 // nothing to do?
549 if (m_slices.count() == 0)
552 if (m_slices.count() == 0)
550 return;
553 return;
551
554
552 // calculate sum of all slices
555 // calculate sum of all slices
553 foreach (QPieSlice* s, m_slices)
556 foreach (QPieSlice* s, m_slices)
554 m_sum += s->value();
557 m_sum += s->value();
555
558
556 // nothing to show..
559 // nothing to show..
557 if (qFuzzyIsNull(m_sum))
560 if (qFuzzyIsNull(m_sum))
558 return;
561 return;
559
562
560 // update slice attributes
563 // update slice attributes
561 qreal sliceAngle = m_pieStartAngle;
564 qreal sliceAngle = m_pieStartAngle;
562 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
565 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
563 QVector<QPieSlice*> changed;
566 QVector<QPieSlice*> changed;
564 foreach (QPieSlice* s, m_slices) {
567 foreach (QPieSlice* s, m_slices) {
565
568
566 PieSliceData data = PieSliceData::data(s);
569 PieSliceData data = PieSliceData::data(s);
567 data.m_percentage = s->value() / m_sum;
570 data.m_percentage = s->value() / m_sum;
568 data.m_angleSpan = pieSpan * data.m_percentage;
571 data.m_angleSpan = pieSpan * data.m_percentage;
569 data.m_startAngle = sliceAngle;
572 data.m_startAngle = sliceAngle;
570 sliceAngle += data.m_angleSpan;
573 sliceAngle += data.m_angleSpan;
571
574
572 if (PieSliceData::data(s) != data) {
575 if (PieSliceData::data(s) != data) {
573 PieSliceData::data(s) = data;
576 PieSliceData::data(s) = data;
574 changed << s;
577 changed << s;
575 }
578 }
576 }
579 }
577
580
578 // emit signals
581 // emit signals
579 foreach (QPieSlice* s, changed)
582 foreach (QPieSlice* s, changed)
580 PieSliceData::data(s).emitChangedSignal(s);
583 PieSliceData::data(s).emitChangedSignal(s);
581 }
584 }
582
585
583 void QPieSeriesPrivate::sliceChanged()
586 void QPieSeriesPrivate::sliceChanged()
584 {
587 {
585 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
588 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
586 updateDerivativeData();
589 updateDerivativeData();
587 }
590 }
588
591
589 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
592 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
590 {
593 {
591 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
594 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
592 Q_ASSERT(m_slices.contains(slice));
595 Q_ASSERT(m_slices.contains(slice));
593 Q_Q(QPieSeries);
596 Q_Q(QPieSeries);
594 emit q->clicked(slice, buttons);
597 emit q->clicked(slice, buttons);
595 }
598 }
596
599
597 void QPieSeriesPrivate::sliceHoverEnter()
600 void QPieSeriesPrivate::sliceHoverEnter()
598 {
601 {
599 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
602 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
600 Q_ASSERT(m_slices.contains(slice));
603 Q_ASSERT(m_slices.contains(slice));
601 Q_Q(QPieSeries);
604 Q_Q(QPieSeries);
602 emit q->hoverEnter(slice);
605 emit q->hoverEnter(slice);
603 }
606 }
604
607
605 void QPieSeriesPrivate::sliceHoverLeave()
608 void QPieSeriesPrivate::sliceHoverLeave()
606 {
609 {
607 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
610 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
608 Q_ASSERT(m_slices.contains(slice));
611 Q_ASSERT(m_slices.contains(slice));
609 Q_Q(QPieSeries);
612 Q_Q(QPieSeries);
610 emit q->hoverLeave(slice);
613 emit q->hoverLeave(slice);
611 }
614 }
612
615
613 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
616 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
614 {
617 {
615 Q_UNUSED(bottomRight)
618 Q_UNUSED(bottomRight)
616
619
617 if (m_mapOrientation == Qt::Vertical)
620 if (m_mapOrientation == Qt::Vertical)
618 {
621 {
619 if (topLeft.column() == m_mapValues)
622 if (topLeft.column() == m_mapValues)
620 if (m_mapValues == m_mapLabels)
623 if (m_mapValues == m_mapLabels)
621 {
624 {
622 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
625 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());
626 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
624 }
627 }
625 else
628 else
626 {
629 {
627 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
630 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
628 }
631 }
629 else if (topLeft.column() == m_mapLabels)
632 else if (topLeft.column() == m_mapLabels)
630 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
633 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
631 }
634 }
632 else
635 else
633 {
636 {
634 if (topLeft.row() == m_mapValues)
637 if (topLeft.row() == m_mapValues)
635 if (m_mapValues == m_mapLabels)
638 if (m_mapValues == m_mapLabels)
636 {
639 {
637 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
640 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());
641 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
639 }
642 }
640 else
643 else
641 {
644 {
642 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
645 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
643 }
646 }
644 else if (topLeft.row() == m_mapLabels)
647 else if (topLeft.row() == m_mapLabels)
645 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
648 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
646 }
649 }
647 }
650 }
648
651
649 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
652 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
650 {
653 {
651 Q_UNUSED(parent)
654 Q_UNUSED(parent)
652 Q_UNUSED(end)
655 Q_UNUSED(end)
653 Q_Q(QPieSeries);
656 Q_Q(QPieSeries);
654
657
655 QPieSlice* newSlice = new QPieSlice;
658 QPieSlice* newSlice = new QPieSlice;
656 newSlice->setLabelVisible(true);
659 newSlice->setLabelVisible(true);
657 if (m_mapOrientation == Qt::Vertical)
660 if (m_mapOrientation == Qt::Vertical)
658 {
661 {
659 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
662 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());
663 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
661 }
664 }
662 else
665 else
663 {
666 {
664 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
667 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());
668 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
666 }
669 }
667
670
668 q->insert(start, newSlice);
671 q->insert(start, newSlice);
669 }
672 }
670
673
671 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
674 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
672 {
675 {
673 Q_UNUSED(parent)
676 Q_UNUSED(parent)
674 Q_UNUSED(end)
677 Q_UNUSED(end)
675 Q_Q(QPieSeries);
678 Q_Q(QPieSeries);
676 q->remove(m_slices.at(start));
679 q->remove(m_slices.at(start));
677 }
680 }
678
681
679 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
682 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
680 {
683 {
681 // Remove rounding errors
684 // Remove rounding errors
682 qreal roundedValue = newValue;
685 qreal roundedValue = newValue;
683 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
686 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
684 roundedValue = 0.0;
687 roundedValue = 0.0;
685 else if (qFuzzyCompare(newValue, max))
688 else if (qFuzzyCompare(newValue, max))
686 roundedValue = max;
689 roundedValue = max;
687 else if (qFuzzyCompare(newValue, min))
690 else if (qFuzzyCompare(newValue, min))
688 roundedValue = min;
691 roundedValue = min;
689
692
690 // Check if the position is valid after removing the rounding errors
693 // Check if the position is valid after removing the rounding errors
691 if (roundedValue < min || roundedValue > max) {
694 if (roundedValue < min || roundedValue > max) {
692 qWarning("QPieSeries: Illegal value");
695 qWarning("QPieSeries: Illegal value");
693 return false;
696 return false;
694 }
697 }
695
698
696 if (!qFuzzyIsNull(value - roundedValue)) {
699 if (!qFuzzyIsNull(value - roundedValue)) {
697 value = roundedValue;
700 value = roundedValue;
698 return true;
701 return true;
699 }
702 }
700
703
701 // The change was so small it is considered a rounding error
704 // The change was so small it is considered a rounding error
702 return false;
705 return false;
703 }
706 }
704
707
705 void QPieSeriesPrivate::scaleDomain(Domain& domain)
708 void QPieSeriesPrivate::scaleDomain(Domain& domain)
706 {
709 {
707 Q_UNUSED(domain);
710 Q_UNUSED(domain);
708 #ifndef QT_NO_DEBUG
711 #ifndef QT_NO_DEBUG
709 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
712 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
710 #endif
713 #endif
711 }
714 }
712
715
713 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
716 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
714 {
717 {
715 Q_Q(QPieSeries);
718 Q_Q(QPieSeries);
716 PieChartItem* pie = new PieChartItem(q,presenter);
719 PieChartItem* pie = new PieChartItem(q,presenter);
717 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
720 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
718 presenter->animator()->addAnimation(pie);
721 presenter->animator()->addAnimation(pie);
719 }
722 }
720 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
723 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
721 return pie;
724 return pie;
722 }
725 }
723
726
724 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
727 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
725 {
728 {
726 Q_Q(QPieSeries);
729 Q_Q(QPieSeries);
727 QList<LegendMarker*> markers;
730 QList<LegendMarker*> markers;
728 foreach(QPieSlice* slice, q->slices()) {
731 foreach(QPieSlice* slice, q->slices()) {
729 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
732 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
730 markers << marker;
733 markers << marker;
731 }
734 }
732 return markers;
735 return markers;
733 }
736 }
734
737
735 #include "moc_qpieseries.cpp"
738 #include "moc_qpieseries.cpp"
736 #include "moc_qpieseries_p.cpp"
739 #include "moc_qpieseries_p.cpp"
737
740
738 QTCOMMERCIALCHART_END_NAMESPACE
741 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,150 +1,150
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 "qscatterseries.h"
21 #include "qscatterseries.h"
22 #include "qscatterseries_p.h"
22 #include "qscatterseries_p.h"
23 #include "scatterchartitem_p.h"
23 #include "scatterchartitem_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 QScatterSeries
29 \class QScatterSeries
30 \brief The QScatterSeries class is used for making scatter charts.
30 \brief The QScatterSeries class is used for making scatter charts.
31
31
32 \mainclass
32 \mainclass
33
33
34 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
34 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
35 and the vertical axis.
35 and the vertical axis.
36
36
37 \image scatterchart.png
37 \image examples_scatterchart.png
38
38
39 Creating basic scatter chart is simple:
39 Creating basic scatter chart is simple:
40 \code
40 \code
41 QScatterSeries* series = new QScatterSeries();
41 QScatterSeries* series = new QScatterSeries();
42 series->append(0, 6);
42 series->append(0, 6);
43 series->append(2, 4);
43 series->append(2, 4);
44 ...
44 ...
45 chartView->addSeries(series);
45 chart->addSeries(series);
46 \endcode
46 \endcode
47 */
47 */
48
48
49 /*!
49 /*!
50 \enum QScatterSeries::MarkerShape
50 \enum QScatterSeries::MarkerShape
51
51
52 This enum describes the shape used when rendering marker items.
52 This enum describes the shape used when rendering marker items.
53
53
54 \value MarkerShapeCircle
54 \value MarkerShapeCircle
55 \value MarkerShapeRectangle
55 \value MarkerShapeRectangle
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn QChartSeriesType QScatterSeries::type() const
59 \fn QChartSeriesType QScatterSeries::type() const
60 \brief Returns QChartSeries::SeriesTypeScatter.
60 \brief Returns QChartSeries::SeriesTypeScatter.
61 \sa QAbstractSeries, QSeriesType
61 \sa QAbstractSeries, QSeriesType
62 */
62 */
63
63
64 QTCOMMERCIALCHART_BEGIN_NAMESPACE
64 QTCOMMERCIALCHART_BEGIN_NAMESPACE
65
65
66 /*!
66 /*!
67 Constructs a series object which is a child of \a parent.
67 Constructs a series object which is a child of \a parent.
68 */
68 */
69 QScatterSeries::QScatterSeries(QObject *parent) : QXYSeries(*new QScatterSeriesPrivate(this),parent)
69 QScatterSeries::QScatterSeries(QObject *parent) : QXYSeries(*new QScatterSeriesPrivate(this),parent)
70 {
70 {
71 }
71 }
72
72
73 /*!
73 /*!
74 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
74 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
75 */
75 */
76 QScatterSeries::~QScatterSeries()
76 QScatterSeries::~QScatterSeries()
77 {
77 {
78 }
78 }
79
79
80 QAbstractSeries::QSeriesType QScatterSeries::type() const
80 QAbstractSeries::QSeriesType QScatterSeries::type() const
81 {
81 {
82 return QAbstractSeries::SeriesTypeScatter;
82 return QAbstractSeries::SeriesTypeScatter;
83 }
83 }
84
84
85 /*!
85 /*!
86 Returns the shape used for drawing markers.
86 Returns the shape used for drawing markers.
87 */
87 */
88 QScatterSeries::MarkerShape QScatterSeries::shape() const
88 QScatterSeries::MarkerShape QScatterSeries::shape() const
89 {
89 {
90 Q_D(const QScatterSeries);
90 Q_D(const QScatterSeries);
91 return d->m_shape;
91 return d->m_shape;
92 }
92 }
93
93
94 /*!
94 /*!
95 Overrides the default shape of the marker items with a user defined \a shape. The default shape
95 Overrides the default shape of the marker items with a user defined \a shape. The default shape
96 is defined by chart theme setting.
96 is defined by chart theme setting.
97 */
97 */
98 void QScatterSeries::setShape(MarkerShape shape)
98 void QScatterSeries::setShape(MarkerShape shape)
99 {
99 {
100 Q_D(QScatterSeries);
100 Q_D(QScatterSeries);
101 if (d->m_shape != shape) {
101 if (d->m_shape != shape) {
102 d->m_shape = shape;
102 d->m_shape = shape;
103 emit d->updated();
103 emit d->updated();
104 }
104 }
105 }
105 }
106
106
107 /*!
107 /*!
108 Returns the size of the marker items.
108 Returns the size of the marker items.
109 */
109 */
110 qreal QScatterSeries::size() const
110 qreal QScatterSeries::size() const
111 {
111 {
112 Q_D(const QScatterSeries);
112 Q_D(const QScatterSeries);
113 return d->m_size;
113 return d->m_size;
114 }
114 }
115
115
116 /*!
116 /*!
117 Set the \a size of the marker items. The default size is 15.
117 Set the \a size of the marker items. The default size is 15.
118 */
118 */
119 void QScatterSeries::setSize(qreal size)
119 void QScatterSeries::setSize(qreal size)
120 {
120 {
121 Q_D(QScatterSeries);
121 Q_D(QScatterSeries);
122
122
123 if (!qFuzzyIsNull(d->m_size - size)) {
123 if (!qFuzzyIsNull(d->m_size - size)) {
124 d->m_size = size;
124 d->m_size = size;
125 emit d->updated();
125 emit d->updated();
126 }
126 }
127 }
127 }
128
128
129 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
129 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130
130
131 QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries* q):QXYSeriesPrivate(q),
131 QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries* q):QXYSeriesPrivate(q),
132 m_shape(QScatterSeries::MarkerShapeCircle),
132 m_shape(QScatterSeries::MarkerShapeCircle),
133 m_size(15.0)
133 m_size(15.0)
134 {
134 {
135
135
136 };
136 };
137
137
138 Chart* QScatterSeriesPrivate::createGraphics(ChartPresenter* presenter)
138 Chart* QScatterSeriesPrivate::createGraphics(ChartPresenter* presenter)
139 {
139 {
140 Q_Q(QScatterSeries);
140 Q_Q(QScatterSeries);
141 ScatterChartItem *scatter = new ScatterChartItem(q,presenter);
141 ScatterChartItem *scatter = new ScatterChartItem(q,presenter);
142 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
142 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
143 presenter->animator()->addAnimation(scatter);
143 presenter->animator()->addAnimation(scatter);
144 }
144 }
145 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
145 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
146 return scatter;
146 return scatter;
147 }
147 }
148
148
149
149
150 QTCOMMERCIALCHART_END_NAMESPACE
150 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,211 +1,222
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
35 \image examples_splinechart.png
36
37 Creating basic spline chart is simple:
38 \code
39 QSplineSeries* series = new QSplineSeries();
40 series->append(0, 6);
41 series->append(2, 4);
42 ...
43 chart->addSeries(series);
44 \endcode
34 */
45 */
35
46
36 /*!
47 /*!
37 \fn QSeriesType QSplineSeries::type() const
48 \fn QSeriesType QSplineSeries::type() const
38 Returns the type of the series
49 Returns the type of the series
39 */
50 */
40
51
41 /*!
52 /*!
42 \fn QSeriesType QSplineSeries::controlPoint(int index) const
53 \fn QSeriesType QSplineSeries::controlPoint(int index) const
43 Returns the control point specified by \a index
54 Returns the control point specified by \a index
44 */
55 */
45
56
46 QTCOMMERCIALCHART_BEGIN_NAMESPACE
57 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47
58
48 /*!
59 /*!
49 Constructs empty series object which is a child of \a parent.
60 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 transferred.
61 When series object is added to QChartView or QChart instance then the ownerships is transferred.
51 */
62 */
52
63
53 QSplineSeries::QSplineSeries(QObject *parent) :
64 QSplineSeries::QSplineSeries(QObject *parent) :
54 QLineSeries(*new QSplineSeriesPrivate(this),parent)
65 QLineSeries(*new QSplineSeriesPrivate(this),parent)
55 {
66 {
56 }
67 }
57
68
58 QAbstractSeries::QSeriesType QSplineSeries::type() const
69 QAbstractSeries::QSeriesType QSplineSeries::type() const
59 {
70 {
60 return QAbstractSeries::SeriesTypeSpline;
71 return QAbstractSeries::SeriesTypeSpline;
61 }
72 }
62
73
63 QPointF QSplineSeries::controlPoint(int index) const
74 QPointF QSplineSeries::controlPoint(int index) const
64 {
75 {
65 Q_D(const QSplineSeries);
76 Q_D(const QSplineSeries);
66 return d->m_controlPoints[index];
77 return d->m_controlPoints[index];
67 }
78 }
68
79
69 /*!
80 /*!
70 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
81 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
71 Allows limiting the model mapping.
82 Allows limiting the model mapping.
72 Parameter \a first specifies which element of the model should be used as a first one of the series.
83 Parameter \a first specifies which element of the model should be used as a first one of the series.
73 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
84 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
74 then all the items following \a first item in a model are used.
85 then all the items following \a first item in a model are used.
75 \sa setModel(), setModelMapping()
86 \sa setModel(), setModelMapping()
76 */
87 */
77 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
88 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
78 {
89 {
79 Q_D(QSplineSeries);
90 Q_D(QSplineSeries);
80 QXYSeries::setModelMapping(modelX, modelY, orientation);
91 QXYSeries::setModelMapping(modelX, modelY, orientation);
81 d->calculateControlPoints();
92 d->calculateControlPoints();
82 }
93 }
83
94
84 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
85
96
86 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
97 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries* q):QLineSeriesPrivate(q)
87 {
98 {
88 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
99 QObject::connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
89 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
100 QObject::connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
90 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
101 QObject::connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
91 };
102 };
92
103
93 /*!
104 /*!
94 \internal
105 \internal
95 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
106 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
96 */
107 */
97 void QSplineSeriesPrivate::calculateControlPoints()
108 void QSplineSeriesPrivate::calculateControlPoints()
98 {
109 {
99
110
100 Q_Q(QSplineSeries);
111 Q_Q(QSplineSeries);
101 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
112 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
102 // CPOL License
113 // CPOL License
103
114
104 int n = q->count() - 1;
115 int n = q->count() - 1;
105 if (n == 1)
116 if (n == 1)
106 { // Special case: Bezier curve should be a straight line.
117 { // Special case: Bezier curve should be a straight line.
107 // firstControlPoints = new Point[1];
118 // firstControlPoints = new Point[1];
108 // 3P1 = 2P0 + P3
119 // 3P1 = 2P0 + P3
109 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
120 m_controlPoints.append(QPointF((2 * q->x(0) + q->x(1)) / 3, (2 * q->y(0) + q->y(1)) / 3));
110
121
111 // P2 = 2P1 P0
122 // P2 = 2P1 P0
112 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
123 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - q->x(0), 2 * m_controlPoints[0].y() - q->y(0)));
113 return;
124 return;
114 }
125 }
115
126
116 // Calculate first Bezier control points
127 // Calculate first Bezier control points
117 // Right hand side vector
128 // Right hand side vector
118 // Set of equations for P0 to Pn points.
129 // Set of equations for P0 to Pn points.
119 //
130 //
120 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
131 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
121 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
132 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
122 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
133 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
123 // | . . . . . . . . . . . . | | ... | | ... |
134 // | . . . . . . . . . . . . | | ... | | ... |
124 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
135 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
125 // | . . . . . . . . . . . . | | ... | | ... |
136 // | . . . . . . . . . . . . | | ... | | ... |
126 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
137 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
127 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
138 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
128 //
139 //
129 QList<qreal> rhs;
140 QList<qreal> rhs;
130 rhs.append(q->x(0) + 2 * q->x(1));
141 rhs.append(q->x(0) + 2 * q->x(1));
131
142
132 // Set right hand side X values
143 // Set right hand side X values
133 for (int i = 1; i < n - 1; ++i)
144 for (int i = 1; i < n - 1; ++i)
134 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
145 rhs.append(4 * q->x(i) + 2 * q->x(i + 1));
135
146
136 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
147 rhs.append((8 * q->x(n - 1) + q->x(n)) / 2.0);
137 // Get first control points X-values
148 // Get first control points X-values
138 QList<qreal> xControl = getFirstControlPoints(rhs);
149 QList<qreal> xControl = getFirstControlPoints(rhs);
139 rhs[0] = q->y(0) + 2 * q->y(1);
150 rhs[0] = q->y(0) + 2 * q->y(1);
140
151
141 // Set right hand side Y values
152 // Set right hand side Y values
142 for (int i = 1; i < n - 1; ++i)
153 for (int i = 1; i < n - 1; ++i)
143 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
154 rhs[i] = 4 * q->y(i) + 2 * q->y(i + 1);
144
155
145 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
156 rhs[n - 1] = (8 * q->y(n - 1) + q->y(n)) / 2.0;
146 // Get first control points Y-values
157 // Get first control points Y-values
147 QList<qreal> yControl = getFirstControlPoints(rhs);
158 QList<qreal> yControl = getFirstControlPoints(rhs);
148
159
149 // Fill output arrays.
160 // Fill output arrays.
150 for (int i = 0; i < n; ++i) {
161 for (int i = 0; i < n; ++i) {
151 // First control point
162 // First control point
152 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
163 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
153 // Second control point
164 // Second control point
154 if (i < n - 1)
165 if (i < n - 1)
155 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
166 m_controlPoints.append(QPointF(2 * q->x(i + 1) - xControl[i + 1], 2 * q->y(i + 1) - yControl[i + 1]));
156 else
167 else
157 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
168 m_controlPoints.append(QPointF((q->x(n) + xControl[n - 1]) / 2, (q->y(n) + yControl[n - 1]) / 2));
158 }
169 }
159 }
170 }
160
171
161 /*!
172 /*!
162 \internal
173 \internal
163 */
174 */
164 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
175 QList<qreal> QSplineSeriesPrivate::getFirstControlPoints(QList<qreal> rhs)
165 {
176 {
166 QList<qreal> x; // Solution vector.
177 QList<qreal> x; // Solution vector.
167 QList<qreal> tmp; // Temp workspace.
178 QList<qreal> tmp; // Temp workspace.
168
179
169 qreal b = 2.0;
180 qreal b = 2.0;
170 x.append(rhs[0] / b);
181 x.append(rhs[0] / b);
171 tmp.append(0);
182 tmp.append(0);
172 for (int i = 1; i < rhs.size(); i++) {
183 for (int i = 1; i < rhs.size(); i++) {
173 // Decomposition and forward substitution.
184 // Decomposition and forward substitution.
174 tmp.append(1 / b);
185 tmp.append(1 / b);
175 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
186 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
176 x.append((rhs[i] - x[i - 1]) / b);
187 x.append((rhs[i] - x[i - 1]) / b);
177 }
188 }
178 for (int i = 1; i < rhs.size(); i++)
189 for (int i = 1; i < rhs.size(); i++)
179 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
190 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
180
191
181 return x;
192 return x;
182 }
193 }
183
194
184 /*!
195 /*!
185 \internal
196 \internal
186 Updates the control points, besed on currently avaiable knots.
197 Updates the control points, besed on currently avaiable knots.
187 */
198 */
188 void QSplineSeriesPrivate::updateControlPoints()
199 void QSplineSeriesPrivate::updateControlPoints()
189 {
200 {
190 Q_Q(QSplineSeries);
201 Q_Q(QSplineSeries);
191 if (q->count() > 1) {
202 if (q->count() > 1) {
192 m_controlPoints.clear();
203 m_controlPoints.clear();
193 calculateControlPoints();
204 calculateControlPoints();
194 }
205 }
195 }
206 }
196
207
197 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
208 Chart* QSplineSeriesPrivate::createGraphics(ChartPresenter* presenter)
198 {
209 {
199 Q_Q(QSplineSeries);
210 Q_Q(QSplineSeries);
200 SplineChartItem* spline = new SplineChartItem(q,presenter);
211 SplineChartItem* spline = new SplineChartItem(q,presenter);
201 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
212 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
202 presenter->animator()->addAnimation(spline);
213 presenter->animator()->addAnimation(spline);
203 }
214 }
204 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
215 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
205 return spline;
216 return spline;
206 }
217 }
207
218
208 #include "moc_qsplineseries.cpp"
219 #include "moc_qsplineseries.cpp"
209 #include "moc_qsplineseries_p.cpp"
220 #include "moc_qsplineseries_p.cpp"
210
221
211 QTCOMMERCIALCHART_END_NAMESPACE
222 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now