##// END OF EJS Templates
Documentation...
Mika Salmela -
r2517:26c3b5c0ed1d
parent child
Show More
@@ -0,0 +1,38
1 /*!
2 \example examples/boxplotchart
3 \title Box and Whiskers Example
4 \subtitle
5
6 The example shows how to create a box-and-whiskers chart.
7
8 \image examples_barchart.png
9
10 Introduction here
11
12 \snippet ../examples/barchart/main.cpp 1
13
14 YkkοΏ½skohta
15
16 \snippet ../examples/barchart/main.cpp 2
17
18 Kakkoskohta
19
20 \snippet ../examples/barchart/main.cpp 3
21
22 Kolmoskohta
23
24 \snippet ../examples/barchart/main.cpp 4
25
26 Neloskohta
27
28 \snippet ../examples/barchart/main.cpp 5
29
30 Tarkista numerointi. Finally we add the chart onto a view. We also turn on the antialiasing for the chartView.
31
32 \snippet ../examples/barchart/main.cpp 6
33
34 Tarkista numerointi. Chart is ready to be shown. We set the chart to be central widget of the window.
35 We also set the size for the chart window and show it.
36
37 \snippet ../examples/barchart/main.cpp 7
38 */
@@ -1,248 +1,248
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qvbarmodelmapper.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 /*!
26 26 \class QVBarModelMapper
27 27 \brief Vertical model mapper for bar series
28 28 \mainclass
29 29
30 30 Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
31 31 Vertical model mapper is used to create a connection between QAbstractBarSeries and QAbstractItemModel derived model object.
32 32 Model mapper maintains equal size of all the BarSets.
33 33 Adding/removing value from the BarSet causes the the same change in the rest of the BarSets added to the same series.
34 34 Note: used model has to support adding/removing rows/columns and modifying the data of the cells.
35 35 */
36 36 /*!
37 37 \qmlclass VBarModelMapper
38 38 \mainclass
39 39
40 40 VBarModelMapper allows you to use your own QAbstractItemModel derived model with data in columns as a data source
41 41 for any bar series. It is possible to use both QAbstractItemModel and bar series data API to manipulate data.
42 42 VBarModelMapper keeps the series and the model in sync.
43 43
44 44 The following QML example would create a bar series with three bar sets (assuming the
45 45 model has at least four columns). Each bar set would contain data starting from row 1. The name of a set would be
46 46 defined by the horizontal header (of the column).
47 47 \code
48 48 BarSeries {
49 49 VBarModelMapper {
50 50 model: myCustomModel // QAbstractItemModel derived implementation
51 51 firstBarSetColumn: 1
52 52 lastBarSetColumn: 3
53 53 firstRow: 1
54 54 }
55 55 }
56 56 \endcode
57 57 */
58 58
59 59 /*!
60 60 \property QVBarModelMapper::series
61 \brief Defines the QPieSeries object that is used by the mapper.
61 \brief Defines the QBarSeries object that is used by the mapper.
62 62
63 63 All the data in the series is discarded when it is set to the mapper.
64 64 When new series is specified the old series is disconnected (it preserves its data)
65 65 */
66 66 /*!
67 67 \qmlproperty AbstractBarSeries VBarModelMapper::series
68 68 Defines the AbstractBarSeries based object that is used by the mapper. All the data in the series is discarded when it is
69 69 set to the mapper. When new series is specified the old series is disconnected (it preserves its data).
70 70 */
71 71
72 72 /*!
73 73 \property QVBarModelMapper::model
74 74 \brief Defines the model that is used by the mapper.
75 75 */
76 76 /*!
77 77 \qmlproperty SomeModel VBarModelMapper::model
78 78 The QAbstractItemModel based model that is used by the mapper. You need to implement the model and expose it to
79 79 QML as shown in \l {QML Custom Model} demo application. Note: the model has to support adding/removing rows/columns
80 80 and modifying the data of the cells.
81 81 */
82 82
83 83 /*!
84 84 \property QVBarModelMapper::firstBarSetColumn
85 85 \brief Defines which column of the model is used as the data source for the first bar set
86 86 Default value is: -1 (invalid mapping)
87 87 */
88 88 /*!
89 89 \qmlproperty int VBarModelMapper::firstBarSetColumn
90 90 Defines which column of the model is used as the data source for the first bar set. Default value
91 91 is: -1 (invalid mapping).
92 92 */
93 93
94 94 /*!
95 95 \property QVBarModelMapper::lastBarSetColumn
96 96 \brief Defines which column of the model is used as the data source for the last bar set
97 97 Default value is: -1 (invalid mapping)
98 98 */
99 99 /*!
100 100 \qmlproperty int VBarModelMapper::lastBarSetColumn
101 101 Defines which column of the model is used as the data source for the last bar set. Default
102 102 value is: -1 (invalid mapping).
103 103 */
104 104
105 105 /*!
106 106 \property QVBarModelMapper::firstRow
107 107 \brief Defines which row of the model contains the first values of the QBarSets in the series.
108 108 Minimal and default value is: 0
109 109 */
110 110 /*!
111 111 \qmlproperty int VBarModelMapper::firstRow
112 112 Defines which row of the model contains the first values of the QBarSets in the series.
113 113 The default value is 0.
114 114 */
115 115
116 116 /*!
117 117 \property QVBarModelMapper::rowCount
118 118 \brief Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries
119 119 Minimal and default value is: -1 (count limited by the number of rows in the model)
120 120 */
121 121 /*!
122 122 \qmlproperty int VBarModelMapper::rowCount
123 123 Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries. The default value is
124 124 -1 (count limited by the number of rows in the model)
125 125 */
126 126
127 127 /*!
128 128 \fn void QVBarModelMapper::seriesReplaced()
129 129
130 130 Emitted when the series to which mapper is connected to has changed.
131 131 */
132 132
133 133 /*!
134 134 \fn void QVBarModelMapper::modelReplaced()
135 135
136 136 Emitted when the model to which mapper is connected to has changed.
137 137 */
138 138
139 139 /*!
140 140 \fn void QVBarModelMapper::firstBarSetColumnChanged()
141 141 Emitted when the firstBarSetColumn has changed.
142 142 */
143 143
144 144 /*!
145 145 \fn void QVBarModelMapper::lastBarSetColumnChanged()
146 146 Emitted when the lastBarSetColumn has changed.
147 147 */
148 148
149 149 /*!
150 150 \fn void QVBarModelMapper::firstRowChanged()
151 151 Emitted when the firstRow has changed.
152 152 */
153 153
154 154 /*!
155 155 \fn void QVBarModelMapper::rowCountChanged()
156 156 Emitted when the rowCount has changed.
157 157 */
158 158
159 159 /*!
160 160 Constructs a mapper object which is a child of \a parent.
161 161 */
162 162 QVBarModelMapper::QVBarModelMapper(QObject *parent) :
163 163 QBarModelMapper(parent)
164 164 {
165 165 QBarModelMapper::setOrientation(Qt::Vertical);
166 166 }
167 167
168 168 QAbstractItemModel *QVBarModelMapper::model() const
169 169 {
170 170 return QBarModelMapper::model();
171 171 }
172 172
173 173 void QVBarModelMapper::setModel(QAbstractItemModel *model)
174 174 {
175 175 if (model != QBarModelMapper::model()) {
176 176 QBarModelMapper::setModel(model);
177 177 emit modelReplaced();
178 178 }
179 179 }
180 180
181 181 QAbstractBarSeries *QVBarModelMapper::series() const
182 182 {
183 183 return QBarModelMapper::series();
184 184 }
185 185
186 186 void QVBarModelMapper::setSeries(QAbstractBarSeries *series)
187 187 {
188 188 if (series != QBarModelMapper::series()) {
189 189 QBarModelMapper::setSeries(series);
190 190 emit seriesReplaced();
191 191 }
192 192 }
193 193
194 194 int QVBarModelMapper::firstBarSetColumn() const
195 195 {
196 196 return QBarModelMapper::firstBarSetSection();
197 197 }
198 198
199 199 void QVBarModelMapper::setFirstBarSetColumn(int firstBarSetColumn)
200 200 {
201 201 if (firstBarSetColumn != firstBarSetSection()) {
202 202 QBarModelMapper::setFirstBarSetSection(firstBarSetColumn);
203 203 emit firstBarSetColumnChanged();
204 204 }
205 205 }
206 206
207 207 int QVBarModelMapper::lastBarSetColumn() const
208 208 {
209 209 return QBarModelMapper::lastBarSetSection();
210 210 }
211 211
212 212 void QVBarModelMapper::setLastBarSetColumn(int lastBarSetColumn)
213 213 {
214 214 if (lastBarSetColumn != lastBarSetSection()) {
215 215 QBarModelMapper::setLastBarSetSection(lastBarSetColumn);
216 216 emit lastBarSetColumnChanged();
217 217 }
218 218 }
219 219
220 220 int QVBarModelMapper::firstRow() const
221 221 {
222 222 return QBarModelMapper::first();
223 223 }
224 224
225 225 void QVBarModelMapper::setFirstRow(int firstRow)
226 226 {
227 227 if (firstRow != first()) {
228 228 QBarModelMapper::setFirst(firstRow);
229 229 emit firstRowChanged();
230 230 }
231 231 }
232 232
233 233 int QVBarModelMapper::rowCount() const
234 234 {
235 235 return QBarModelMapper::count();
236 236 }
237 237
238 238 void QVBarModelMapper::setRowCount(int rowCount)
239 239 {
240 240 if (rowCount != count()) {
241 241 QBarModelMapper::setCount(rowCount);
242 242 emit rowCountChanged();
243 243 }
244 244 }
245 245
246 246 #include "moc_qvbarmodelmapper.cpp"
247 247
248 248 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,223 +1,227
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "boxplotchartitem_p.h"
22 22 #include "qboxplotseries_p.h"
23 23 #include "bar_p.h"
24 24 #include "qboxset_p.h"
25 25 #include "qabstractbarseries_p.h"
26 26 #include "qboxset.h"
27 27 #include "boxwhiskers_p.h"
28 28 #include <QPainter>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 BoxPlotChartItem::BoxPlotChartItem(QBoxPlotSeries *series, QGraphicsItem* item) :
33 33 ChartItem(series->d_func(), item),
34 34 m_series(series),
35 35 m_animation(0),
36 36 m_animate(0)
37 37 {
38 38 connect(series, SIGNAL(boxsetsRemoved(QList<QBoxSet*>)), this, SLOT(handleBoxsetRemove(QList<QBoxSet*>)));
39 39 connect(series->d_func(), SIGNAL(restructuredBoxes()), this, SLOT(handleDataStructureChanged()));
40 40 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
41 41 connect(series->d_func(), SIGNAL(updatedBoxes()), this, SLOT(handleUpdatedBars()));
42 42 connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdatedBars()));
43 43 // QBoxPlotSeriesPrivate calls handleDataStructureChanged(), don't do it here
44 44 setZValue(ChartPresenter::BoxPlotSeriesZValue);
45 45 }
46 46
47 47 BoxPlotChartItem::~BoxPlotChartItem()
48 48 {
49 49 qDebug() << "BoxPlotChartItem::~BoxPlotChartItem() " << m_seriesIndex;
50 50 }
51 51
52 52 void BoxPlotChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
53 53 {
54 54 Q_UNUSED(painter);
55 55 Q_UNUSED(option);
56 56 Q_UNUSED(widget);
57 57
58 58 //painter->setClipRect(QRectF(QPointF(0,0),domain()->size()));
59 59
60 60 //qDebug() << "ALERT EMPTY: BoxPlotChartItem::paint";
61 61 }
62 62
63 63 void BoxPlotChartItem::setAnimation(BoxPlotAnimation *animation)
64 64 {
65 65 //qDebug() << "BoxPlotChartItem::setAnimation :" << animation;
66 66
67 67 m_animation = animation;
68 68 if (m_animation) {
69 69 foreach (BoxWhiskers *item, m_boxTable.values()) {
70 70 m_animation->addBox(item);
71 71 }
72 72 handleDomainUpdated();
73 73 }
74 74 }
75 75
76 76 void BoxPlotChartItem::handleDataStructureChanged()
77 77 {
78 78 qDebug() << "BoxPlotChartItem::handleDataStructureChanged()";
79 79
80 80 int setCount = m_series->count();
81 81
82 82 for (int s = 0; s < setCount; s++) {
83 83 QBoxSet *set = m_series->d_func()->boxsetAt(s);
84 84
85 BoxWhiskers *boxWhiskersItem = m_boxTable.value(set);
86 if (boxWhiskersItem == 0) {
85 BoxWhiskers *box = m_boxTable.value(set);
86 if (!box) {
87 87 // Item is not yet created, make a box and add it to hash table
88 boxWhiskersItem = new BoxWhiskers(domain(), this);
89 m_boxTable.insert(set, boxWhiskersItem);
88 box = new BoxWhiskers(set, domain(), this);
89 m_boxTable.insert(set, box);
90 connect(box, SIGNAL(clicked(QBoxSet *)), m_series, SIGNAL(clicked(QBoxSet*)));
91 connect(box, SIGNAL(hovered(bool,QBoxSet*)), m_series, SIGNAL(hovered(bool,QBoxSet*)));
92 connect(box, SIGNAL(clicked(QBoxSet*)), set, SIGNAL(clicked()));
93 connect(box, SIGNAL(hovered(bool,QBoxSet*)), set, SIGNAL(hovered(bool)));
90 94
91 95 // Set the decorative issues for the newly created box
92 boxWhiskersItem->setBrush(m_series->brush());
93 boxWhiskersItem->setPen(m_series->pen());
96 box->setBrush(m_series->brush());
97 box->setPen(m_series->pen());
94 98 }
95 updateBoxGeometry(boxWhiskersItem, s);
99 updateBoxGeometry(box, s);
96 100
97 boxWhiskersItem->updateGeometry();
101 box->updateGeometry();
98 102
99 103 if (m_animation)
100 m_animation->addBox(boxWhiskersItem);
104 m_animation->addBox(box);
101 105 }
102 106
103 107 //
104 108 handleDomainUpdated();
105 109 }
106 110
107 111 void BoxPlotChartItem::handleUpdatedBars()
108 112 {
109 113 qDebug() << "BoxPlotChartItem::handleUpdatedBars()";
110 114
111 115 foreach (BoxWhiskers *item, m_boxTable.values()) {
112 116 item->setBrush(m_series->brush());
113 117 item->setPen(m_series->pen());
114 118 }
115 119 // Override with QBoxSet specific settings
116 120 foreach (QBoxSet *set, m_boxTable.keys()) {
117 121 if (set->brush().style() != Qt::NoBrush)
118 122 m_boxTable.value(set)->setBrush(set->brush());
119 123 if (set->pen().style() != Qt::NoPen)
120 124 m_boxTable.value(set)->setPen(set->pen());
121 125 }
122 126 }
123 127
124 128 void BoxPlotChartItem::handleBoxsetRemove(QList<QBoxSet*> barSets)
125 129 {
126 130 //qDebug() << "BoxPlotChartItem::handleBarsetRemove";
127 131
128 132 foreach (QBoxSet *set, barSets) {
129 133 BoxWhiskers *boxItem = m_boxTable.value(set);
130 134 m_boxTable.remove(set);
131 135 delete boxItem;
132 136 }
133 137
134 138 // We trust that series emits the restructuredBars, which handles restructuring
135 139 }
136 140
137 141 void BoxPlotChartItem::handleDomainUpdated()
138 142 {
139 143 //qDebug() << "BoxPlotChartItem::handleDomainUpdated() domain()->size() = " << domain()->size();
140 144
141 145 if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0))
142 146 return;
143 147
144 148 // Set my bounding rect to same as domain size
145 149 m_boundingRect.setRect(0.0, 0.0, domain()->size().width(), domain()->size().height());
146 150
147 151 foreach (BoxWhiskers *item, m_boxTable.values()) {
148 152 // Update the domain size for each BoxWhisker item
149 153 item->setDomainSize(domain()->size());
150 154
151 155 // If the animation is set, start the animation for each BoxWhisker item
152 156 if (m_animation) {
153 157 presenter()->startAnimation(m_animation->boxAnimation(item));
154 158 }
155 159 }
156 160 }
157 161
158 162 void BoxPlotChartItem::handleLayoutChanged()
159 163 {
160 164 qDebug() << "BoxPlotChartItem::handleLayoutChanged";
161 165
162 166 foreach (BoxWhiskers *item, m_boxTable.values()) {
163 167 if (m_animation)
164 168 m_animation->setAnimationStart(item);
165 169
166 170 bool dirty = updateBoxGeometry(item, item->m_data.m_index);
167 171 if (dirty && m_animation)
168 172 presenter()->startAnimation(m_animation->boxChangeAnimation(item));
169 173 else
170 174 item->updateGeometry();
171 175 }
172 176 }
173 177
174 178 QRectF BoxPlotChartItem::boundingRect() const
175 179 {
176 180 return m_boundingRect;
177 181 }
178 182
179 183 void BoxPlotChartItem::initializeLayout()
180 184 {
181 185 qDebug() << "ALERT EMPTY: BoxPlotChartItem::initializeLayout";
182 186 }
183 187
184 188 QVector<QRectF> BoxPlotChartItem::calculateLayout()
185 189 {
186 190 qDebug() << "ALERT EMPTY: BoxPlotChartItem::calculateLayout()";
187 191
188 192 return QVector<QRectF>();
189 193 }
190 194
191 195 bool BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
192 196 {
193 197 bool changed = false;
194 198
195 199 QBoxSet *set = m_series->d_func()->boxsetAt(index);
196 200 BoxWhiskersData &data = box->m_data;
197 201
198 202 if ((data.m_lowerExtreme != set->at(0)) || (data.m_lowerQuartile != set->at(1)) ||
199 203 (data.m_median != set->at(2)) || (data.m_upperQuartile != set->at(3)) || (data.m_upperExtreme != set->at(4)))
200 204 changed = true;
201 205
202 206 data.m_lowerExtreme = set->at(0);
203 207 data.m_lowerQuartile = set->at(1);
204 208 data.m_median = set->at(2);
205 209 data.m_upperQuartile = set->at(3);
206 210 data.m_upperExtreme = set->at(4);
207 211 data.m_index = index;
208 212 data.m_boxItems = m_series->count();
209 213
210 214 data.m_maxX = domain()->maxX();
211 215 data.m_minX = domain()->minX();
212 216 data.m_maxY = domain()->maxY();
213 217 data.m_minY = domain()->minY();
214 218
215 219 data.m_seriesIndex = m_seriesIndex;
216 220 data.m_seriesCount = m_seriesCount;
217 221
218 222 return changed;
219 223 }
220 224
221 225 #include "moc_boxplotchartitem_p.cpp"
222 226
223 227 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,190
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "boxwhiskers_p.h"
22 22 #include <QPainter>
23 #include <QDebug>
24 23 #include <QWidget>
25 24
25 #include <QDebug>
26
26 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 28
28 BoxWhiskers::BoxWhiskers(AbstractDomain *domain, QGraphicsObject *parent) :
29 BoxWhiskers::BoxWhiskers(QBoxSet *set, AbstractDomain *domain, QGraphicsObject *parent) :
29 30 QGraphicsObject(parent),
31 m_boxSet(set),
30 32 m_domain(domain)
31 33 {
32 //qDebug() << "BoxWhiskers::BoxWhiskers()";
34 setAcceptHoverEvents(true);
35 setAcceptedMouseButtons(Qt::MouseButtonMask);
33 36 }
34 37
35 38 BoxWhiskers::~BoxWhiskers()
36 39 {
37 //qDebug() << "BoxWhiskers::~BoxWhiskers()";
38 40 }
39 41
40 42 void BoxWhiskers::mousePressEvent(QGraphicsSceneMouseEvent *event)
41 43 {
42 44 Q_UNUSED(event)
43
44 qDebug() << "BoxWhiskers::mousePressEvent";
45 emit clicked(m_boxSet);
45 46 }
46 47
47 48 void BoxWhiskers::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
48 49 {
49 50 Q_UNUSED(event)
50
51 qDebug() << "BoxWhiskers::hoverEnterEvent";
51 emit hovered(true, m_boxSet);
52 52 }
53 53
54 54 void BoxWhiskers::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
55 55 {
56 56 Q_UNUSED(event)
57
58 qDebug() << "BoxWhiskers::hoverLeaveEvent";
57 emit hovered(false, m_boxSet);
59 58 }
60 59
61 60 void BoxWhiskers::setBrush(const QBrush &brush)
62 61 {
63 62 m_brush = brush;
64 63 update();
65 64 }
66 65
67 66 void BoxWhiskers::setPen(const QPen &pen)
68 67 {
69 68 m_pen = pen;
70 69 update();
71 70 }
72 71
73 72 void BoxWhiskers::setLayout(const BoxWhiskersData &data)
74 73 {
75 74 m_data = data;
76 75
77 76 updateGeometry();
78 77 update();
79 78 }
80 79
81 80
82 81 QSizeF BoxWhiskers::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
83 82 {
84 83 //Q_UNUSED(which)
85 84 Q_UNUSED(constraint)
86 85
87 86 qDebug() << "BoxWhiskers::sizeHint, which = " << which;
88 87
89 88 return QSizeF();
90 89 }
91 90
92 91 void BoxWhiskers::setGeometry(const QRectF &rect) // TODO: Unused?
93 92 {
94 93 Q_UNUSED(rect)
95 94
96 95 qDebug() << "BoxWhiskers::setGeometry";
97 96 }
98 97
99 98 void BoxWhiskers::setDomainSize(const QSizeF &size)
100 99 {
101 100 m_domainSize = size;
102 101
103 102 updateBoundingRect();
104 103 }
105 104
106 105 QRectF BoxWhiskers::boundingRect() const
107 106 {
108 107 return m_boundingRect;
109 108 }
110 109
111 110 void BoxWhiskers::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
112 111 {
113 112 Q_UNUSED(option)
114 113 Q_UNUSED(widget)
115 114 //Q_UNUSED(painter)
116 115
117 116 //painter->save();
118 117 //painter->setClipRect(parentItem()->boundingRect());
119 118 painter->setPen(m_pen);
120 119 painter->setBrush(m_brush);
121 120 qreal spanY = m_data.m_maxY - m_data.m_minY;
122 121 //painter->setClipRect(parentItem()->boundingRect());
123 122 painter->scale(m_domainSize.width() / m_data.m_boxItems, m_domainSize.height() / spanY);
124 123 painter->drawPath(m_boxPath);
125 124 //painter->restore();
126 125 }
127 126
128 127 void BoxWhiskers::updateGeometry()
129 128 {
130 129 prepareGeometryChange();
131 130
132 131 QPainterPath path;
133 132
134 133 qreal columnWidth = 1.0 / m_data.m_seriesCount;
135 134 qreal left = 0.25 * columnWidth + columnWidth * m_data.m_seriesIndex;
136 135 qreal right = 0.75 * columnWidth + columnWidth * m_data.m_seriesIndex;
137 136 qreal middle = 0.5 * columnWidth + columnWidth * m_data.m_seriesIndex;
138 137
139 138 //whisker = 0.35 0.75
140 139
141 140 // Upper whisker
142 141 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
143 142 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
144 143 path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
145 144 path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile);
146 145 path.closeSubpath();
147 146
148 147 // Middle Box
149 148 path.addRect(left + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile,
150 149 0.5 * columnWidth, m_data.m_upperQuartile - m_data.m_lowerQuartile);
151 150
152 151 // Median/mean line
153 152 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_median);
154 153 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_median);
155 154
156 155 // Lower whisker
157 156 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
158 157 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
159 158 path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
160 159 path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerQuartile);
161 160 path.closeSubpath();
162 161
163 162 m_boxPath = path;
164 163
165 164 updateBoundingRect();
166 165
167 166 // qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
168 167 // qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
169 168 // QRectF br = path.boundingRect();
170 169 // m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
171 170
172 171 if (m_data.m_index == 5) {
173 172 //qDebug() << "myValue = " << myValue;
174 173 //qDebug() << "m_data.m_upperExtreme" << m_data.m_upperExtreme;
175 174 //qDebug() << "m_boundingRect = " << m_boundingRect;
176 175 // qDebug() << "x = " << m_boundingRect.x() << ", y = " << m_boundingRect.y() << ", width = "
177 176 // << m_boundingRect.width() << ", height = " << m_boundingRect.height();
178 177 }
179 178 }
180 179
181 180 void BoxWhiskers::updateBoundingRect()
182 181 {
183 182 qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
184 183 qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
185 184 QRectF br = m_boxPath.boundingRect();
186 185 m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
187 186 }
188 187
189 188 #include "moc_boxwhiskers_p.cpp"
190 189
191 190 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,97
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef BOXWHISKERS_H
31 31 #define BOXWHISKERS_H
32 32
33 33 #include "boxwhiskersdata_p.h"
34 34 #include "qchartglobal.h"
35 #include "qbarset.h"
36 35 #include "abstractdomain_p.h"
36 #include <QBoxSet>
37 37 #include <QGraphicsRectItem>
38 38 #include <QGraphicsLineItem>
39 39 #include <QGraphicsLayoutItem>
40 40 #include <QPainterPath>
41 41
42 42 QTCOMMERCIALCHART_BEGIN_NAMESPACE
43 43
44 44 class QBarSet;
45 45
46 46 class BoxWhiskers : public QGraphicsObject/*, public QGraphicsLayoutItem*/
47 47 {
48 48 Q_OBJECT
49 49 //Q_INTERFACES(QGraphicsLayoutItem)
50 50 public:
51 BoxWhiskers(AbstractDomain *domain, QGraphicsObject *parent);
51 BoxWhiskers(QBoxSet *set, AbstractDomain *domain, QGraphicsObject *parent);
52 52 ~BoxWhiskers();
53 53
54 54 void setBrush(const QBrush &brush);
55 55 void setPen(const QPen &pen);
56 56 void setLayout(const BoxWhiskersData &data);
57 57 void setDomainSize(const QSizeF &size);
58 58
59 59 void mousePressEvent(QGraphicsSceneMouseEvent *event);
60 60 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
61 61 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
62 62
63 63 QRectF boundingRect() const;
64 64 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
65 65
66 66 // From QGraphicsLayoutItem // TODO tarkista nοΏ½mοΏ½ jollei ole QGraphicsLayoutItem
67 67 void updateGeometry();
68 68 protected:
69 69 QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
70 70 void setGeometry(const QRectF &rect);
71 71
72 72 private:
73 73 void updateBoundingRect();
74 74
75 75 Q_SIGNALS:
76 void clicked(int index, QBarSet *barset);
77 void hovered(bool status, QBarSet *barset);
76 void clicked(QBoxSet *boxset);
77 void hovered(bool status, QBoxSet *boxset);
78 78
79 79 private:
80 80 friend class BoxPlotChartItem;
81 81 friend class BoxPlotAnimation;
82 82
83 QBoxSet *m_boxSet;
83 84 AbstractDomain *m_domain;
84 85 QPainterPath m_boxPath;
85 86 QRectF m_boundingRect;
86 87 bool m_hovering;
87 88 bool m_validData;
88 89 QBrush m_brush;
89 90 QPen m_pen;
90 91 BoxWhiskersData m_data;
91 92 QSizeF m_domainSize;
92 93 };
93 94
94 95 QTCOMMERCIALCHART_END_NAMESPACE
95 96
96 97 #endif // BOXWHISKERS_H
@@ -1,581 +1,618
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qboxplotseries.h"
22 22 #include "qboxplotseries_p.h"
23 23 #include "qboxplotlegendmarker.h"
24 24 #include "qbarcategoryaxis.h"
25 25 #include "boxplotchartitem_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "charttheme_p.h"
28 28 #include "qvalueaxis.h"
29 29 #include "charttheme_p.h"
30 30 #include "boxplotanimation_p.h"
31 31 #include "qchart_p.h"
32 32 #include "qboxset.h"
33 33 #include "qboxset_p.h"
34 34
35 35 #include <QDebug>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 /*!
40 40 \class QBoxPlotSeries
41 \brief Series for creating stacked bar chart
41 \brief Series for creating box-and-whiskers chart
42 42 \mainclass
43 43
44 QBoxPlotSeries represents a series of data shown as bars. The purpose of this class is to draw bars
45 as stacks, where bars in same category are stacked on top of each other.
46 QBoxPlotSeries groups the data from sets to categories, which are defined by QStringList.
44 QBoxPlotSeries represents a series of data shown as box-and-whisker bars. The purpose of this class is to act as
45 a container for single box-and-whisker items. Each item is drawn to own slot. If chart includes multiple QBoxPlotSeries
46 items with the same index are drawn to same slot.
47 47
48 See the \l {BoxPlotChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
48 See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a box-and-whiskers chart.
49 49 \image examples_boxplotchart.png
50 50
51 \sa QBoxSet, QPercentBarSeries, QAbstractBarSeries
51 \sa QBoxSet
52 52 */
53 53
54 54 /*!
55 55 \qmlclass BoxPlotSeries QBoxPlotSeries
56 56 \inherits AbstractBarSeries
57 57
58 The following QML shows how to create a simple stacked bar chart:
59 \snippet ../demos/qmlchart/qml/qmlchart/View7.qml 1
58 The following QML shows how to create a simple box-and-whiskers chart:
59 \snippet ../examples/qmlboxplot/qml/qmlboxplot/main.qml 1
60 60 \beginfloatleft
61 61 \image demos_qmlchart7.png
62 62 \endfloat
63 63 \clearfloat
64 64 */
65 65
66 66 /*!
67 \fn QBoxPlotSeries::boxsetsAdded(QList<QBoxSet *> sets)
68 \brief Signal is emitted when a new \a sets of box-and-whiskers data is added to the series.
69 */
70
71 /*!
72 \fn QBoxPlotSeries::boxsetsRemoved(QList<QBoxSet *> sets)
73 \brief Signal is emitted when \a sets of box-and-whiskers data is removed from the series.
74 */
75
76 /*!
77 \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
78 \brief Signal is emitted when the user clicks the \a boxset on the chart.
79 */
80
81 /*!
82 \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
83 \brief Signal is emitted when there is change in hover \a status over \a boxset.
84 */
85
86 /*!
87 \fn QBoxPlotSeries::countChanged()
88 \brief Signal is emitted when there is change in count of box-and-whiskers items in the series.
89 */
90
91 /*!
67 92 Constructs empty QBoxPlotSeries.
68 93 QBoxPlotSeries is QObject which is a child of a \a parent.
69 94 */
70 95 QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
71 96 : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
72 97 {
73 98 }
74 99
75 100 /*!
76 101 Destructor. Removes series from chart.
77 102 */
78 103 QBoxPlotSeries::~QBoxPlotSeries()
79 104 {
80 105 qDebug() << "QBoxPlotSeries::~QBoxPlotSeries";
81 106
82 107 Q_D(QBoxPlotSeries);
83 108 if (d->m_chart)
84 109 d->m_chart->removeSeries(this);
85 110 }
86 111
87 112 /*!
88 Adds a single box and whiskers item to series. Takes ownership of \a the box. If the box is null or is already in series, it won't be appended.
113 Adds a single box and whiskers set to series. Takes ownership of the \a set. If the set is null or is already in series, it won't be appended.
89 114 Returns true, if appending succeeded.
90 115 */
91 116 bool QBoxPlotSeries::append(QBoxSet *set)
92 117 {
93 118 Q_D(QBoxPlotSeries);
94 119
95 120 bool success = d->append(set);
96 121 if (success) {
97 122 QList<QBoxSet *> sets;
98 123 sets.append(set);
99 124 set->setParent(this);
100 125 emit boxsetsAdded(sets);
101 126 emit countChanged();
102 127 }
103 128 return success;
104 129 }
105 130
106 131 /*!
107 132 Removes boxset from the series. Releases ownership of the \a set. Deletes the set, if remove
108 133 was successful.
109 134 Returns true, if the set was removed.
110 135 */
111 136 bool QBoxPlotSeries::remove(QBoxSet *set)
112 137 {
113 138 Q_D(QBoxPlotSeries);
114 139 bool success = d->remove(set);
115 140 if (success) {
116 141 QList<QBoxSet *> sets;
117 142 sets.append(set);
118 143 set->setParent(0);
119 144 emit boxsetsRemoved(sets);
120 145 emit countChanged();
121 146 delete set;
122 147 set = 0;
123 148 }
124 149 return success;
125 150 }
126 151
127 152 /*!
128 153 Takes a single \a set from the series. Does not delete the boxset object.
129 154
130 155 NOTE: The series remains as the boxset's parent object. You must set the
131 156 parent object to take full ownership.
132 157
133 158 Returns true if take was successful.
134 159 */
135 160 bool QBoxPlotSeries::take(QBoxSet *set)
136 161 {
137 162 Q_D(QBoxPlotSeries);
138 163
139 164 bool success = d->remove(set);
140 165 if (success) {
141 166 QList<QBoxSet *> sets;
142 167 sets.append(set);
143 168 emit boxsetsRemoved(sets);
144 169 emit countChanged();
145 170 }
146 171 return success;
147 172 }
148 173
149 174 /*!
150 175 Adds a list of boxsets to series. Takes ownership of the \a sets.
151 176 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
152 177 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
153 178 and function returns false.
154 179 */
155 180 bool QBoxPlotSeries::append(QList<QBoxSet *> sets)
156 181 {
157 182 Q_D(QBoxPlotSeries);
158 183 bool success = d->append(sets);
159 184 if (success) {
160 185 emit boxsetsAdded(sets);
161 186 emit countChanged();
162 187 }
163 188 return success;
164 189 }
165 190
166 191 /*!
167 192 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
168 193 Returns true, if inserting succeeded.
169 194
170 195 */
171 196 bool QBoxPlotSeries::insert(int index, QBoxSet *set)
172 197 {
173 198 Q_D(QBoxPlotSeries);
174 199 bool success = d->insert(index, set);
175 200 if (success) {
176 201 QList<QBoxSet *> sets;
177 202 sets.append(set);
178 203 emit boxsetsAdded(sets);
179 204 emit countChanged();
180 205 }
181 206 return success;
182 207 }
183 208
184 209 /*!
185 210 Removes all boxsets from the series. Deletes removed sets.
186 211 */
187 212 void QBoxPlotSeries::clear()
188 213 {
189 214 Q_D(QBoxPlotSeries);
190 215 QList<QBoxSet *> sets = boxSets();
191 216 bool success = d->remove(sets);
192 217 if (success) {
193 218 emit boxsetsRemoved(sets);
194 219 emit countChanged();
195 220 foreach (QBoxSet *set, sets)
196 221 delete set;
197 222 }
198 223 }
199 224
200 225 /*!
201 226 Returns number of sets in series.
202 227 */
203 228 int QBoxPlotSeries::count() const
204 229 {
205 230 Q_D(const QBoxPlotSeries);
206 231 return d->m_boxSets.count();
207 232 }
208 233
209 234 /*!
210 235 Returns a list of sets in series. Keeps ownership of sets.
211 236 */
212 237 QList<QBoxSet *> QBoxPlotSeries::boxSets() const
213 238 {
214 239 Q_D(const QBoxPlotSeries);
215 240 return d->m_boxSets;
216 241 }
217 242
218 243 /*!
219 244 Returns QChartSeries::SeriesTypeBoxPlot.
220 245 */
221 246 QAbstractSeries::SeriesType QBoxPlotSeries::type() const
222 247 {
223 248 return QAbstractSeries::SeriesTypeBoxPlot;
224 249 }
225 250
251 /*!
252 Sets brush for the series. Box-and-whiskers items are drawn using \a brush
253 */
226 254 void QBoxPlotSeries::setBrush(const QBrush &brush)
227 255 {
228 256 Q_D(QBoxPlotSeries);
229 257
230 258 if (d->m_brush != brush) {
231 259 d->m_brush = brush;
232 260 emit d->updated();
233 261 }
234 262 }
235 263
264 /*!
265 Returns brush of the series.
266 */
236 267 QBrush QBoxPlotSeries::brush() const
237 268 {
238 269 Q_D(const QBoxPlotSeries);
239 270
240 271 return d->m_brush;
241 272 }
242 273
274 /*!
275 Sets pen for the series. Box-and-whiskers items are drawn using \a pen
276 */
243 277 void QBoxPlotSeries::setPen(const QPen &pen)
244 278 {
245 279 Q_D(QBoxPlotSeries);
246 280
247 281 if (d->m_pen != pen) {
248 282 d->m_pen = pen;
249 283 emit d->updated();
250 284 }
251 285 }
252 286
287 /*!
288 Returns the pen of this series.
289 */
253 290 QPen QBoxPlotSeries::pen() const
254 291 {
255 292 Q_D(const QBoxPlotSeries);
256 293
257 294 return d->m_pen;
258 295 }
259 296
260 297 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
261 298
262 299 QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
263 300 : QAbstractSeriesPrivate(q),
264 301 m_pen(QPen(Qt::NoPen)),
265 302 m_brush(QBrush(Qt::NoBrush))
266 303 {
267 304 }
268 305
269 306 QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
270 307 {
271 308 qDebug() << "QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()";
272 309 disconnect(this, 0, 0, 0);
273 310 }
274 311
275 312 void QBoxPlotSeriesPrivate::initializeDomain()
276 313 {
277 314 qreal minX(domain()->minX());
278 315 qreal minY(domain()->minY());
279 316 qreal maxX(domain()->maxX());
280 317 qreal maxY(domain()->maxY());
281 318
282 319 qreal x = m_boxSets.count();
283 320 minX = qMin(minX, - (qreal)0.5);
284 321 minY = qMin(minY, bottom());
285 322 maxX = qMax(maxX, x - (qreal)0.5);
286 323 maxY = qMax(maxY, max());
287 324
288 325 domain()->setRange(minX, maxX, minY, maxY);
289 326 }
290 327
291 328 void QBoxPlotSeriesPrivate::initializeAxes()
292 329 {
293 330 foreach (QAbstractAxis* axis, m_axes) {
294 331 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
295 332 if (axis->orientation() == Qt::Horizontal)
296 333 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
297 334 else
298 335 qDebug() << "ALERT: QBoxPlotSeriesPrivate::initializeAxes implement #1";
299 336 }
300 337 }
301 338 }
302 339
303 340 QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
304 341 {
305 342 if (orientation == Qt::Horizontal)
306 343 return QAbstractAxis::AxisTypeBarCategory;
307 344
308 345 return QAbstractAxis::AxisTypeValue;
309 346 }
310 347
311 348 QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
312 349 {
313 350 Q_UNUSED(orientation);
314 351 // This is not implemented even in barseries, keep in touch if something needs this
315 352 qDebug() << "ALERT: QBoxPlotSeriesPrivate::createDefaultAxis implement";
316 353 return 0;
317 354 }
318 355
319 356 void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
320 357 {
321 358 QStringList categories;
322 359 if (axis->categories().isEmpty()) {
323 360 for (int i(1); i < m_boxSets.count() + 1; i++) {
324 361 QBoxSet *set = m_boxSets.at(i - 1);
325 362 if (set->label().isEmpty())
326 363 categories << QString::number(i);
327 364 else
328 365 categories << set->label();
329 366 }
330 367 axis->append(categories);
331 368 }
332 369 }
333 370
334 371 void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
335 372 {
336 373 Q_Q(QBoxPlotSeries);
337 374
338 375 BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q,parent);
339 376 m_item.reset(boxPlot);
340 377 QAbstractSeriesPrivate::initializeGraphics(parent);
341 378
342 379 if (m_chart) {
343 380 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesChange(QAbstractSeries*)) );
344 381 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SLOT(handleSeriesRemove(QAbstractSeries*)) );
345 382
346 383 QList<QAbstractSeries *> serieses = m_chart->series();
347 384
348 385 // Tries to find this series from the Chart's list of serieses and deduce the index
349 386 int index = 0;
350 387 foreach (QAbstractSeries *s, serieses) {
351 388 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
352 389 if (q == static_cast<QBoxPlotSeries *>(s)) {
353 390 boxPlot->m_seriesIndex = index;
354 391 m_index = index;
355 392 }
356 393 index++;
357 394 }
358 395 }
359 396 boxPlot->m_seriesCount = index;
360 397 }
361 398
362 399 // Make BoxPlotChartItem to instantiate box & whisker items
363 400 boxPlot->handleDataStructureChanged();
364 401 }
365 402
366 403 void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
367 404 {
368 405 Q_Q(QBoxPlotSeries);
369 406 qDebug() << "QBoxPlotSeriesPrivate::initializeTheme";
370 407
371 408 const QList<QGradient> gradients = theme->seriesGradients();
372 409
373 410 if (forced || m_brush == QBrush(Qt::NoBrush)) {
374 411 QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.5);
375 412 q->setBrush(brushColor);
376 413 }
377 414
378 415 if (forced || m_pen == QPen(Qt::NoPen)) {
379 416 QPen pen = theme->outlinePen();
380 417 pen.setCosmetic(true);
381 418 q->setPen(pen);
382 419 }
383 420 }
384 421
385 422 void QBoxPlotSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
386 423 {
387 424 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
388 425 Q_ASSERT(item);
389 426 if (options.testFlag(QChart::SeriesAnimations)) {
390 427 item->setAnimation(new BoxPlotAnimation(item));
391 428 }else{
392 429 item->setAnimation((BoxPlotAnimation *)0);
393 430 }
394 431 QAbstractSeriesPrivate::initializeAnimations(options);
395 432 }
396 433
397 434 QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
398 435 {
399 436 Q_Q(QBoxPlotSeries);
400 437 QList<QLegendMarker*> list;
401 438 return list << new QBoxPlotLegendMarker(q, legend);
402 439 }
403 440
404 441 void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
405 442 {
406 443 qDebug() << "QBoxPlotSeriesPrivate::handleSeriesRemove";
407 444 Q_Q(QBoxPlotSeries);
408 445
409 446 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
410 447 QObject::disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
411 448
412 449 // Test if series removed is me, then don't do anything
413 450 if (q != removedSeries) {
414 451 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
415 452 if (item) {
416 453 item->m_seriesCount = item->m_seriesCount - 1;
417 454 if (removedSeries->d_func()->m_index < m_index) {
418 455 m_index--;
419 456 item->m_seriesIndex = m_index;
420 457 }
421 458
422 459 item->handleDataStructureChanged();
423 460 }
424 461 }
425 462 }
426 463
427 464 void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
428 465 {
429 466 Q_UNUSED(series);
430 467
431 468 Q_Q(QBoxPlotSeries);
432 469
433 470 BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.data());
434 471
435 472 if (m_chart) {
436 473 QList<QAbstractSeries *> serieses = m_chart->series();
437 474
438 475 // Tries to find this series from the Chart's list of serieses and deduce the index
439 476 int index = 0;
440 477 foreach (QAbstractSeries *s, serieses) {
441 478 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
442 479 if (q == static_cast<QBoxPlotSeries *>(s)) {
443 480 boxPlot->m_seriesIndex = index;
444 481 m_index = index;
445 482 }
446 483 index++;
447 484 }
448 485 }
449 486 boxPlot->m_seriesCount = index;
450 487 }
451 488
452 489 boxPlot->handleDataStructureChanged();
453 490 }
454 491
455 492 bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
456 493 {
457 494 if ((m_boxSets.contains(set)) || (set == 0))
458 495 return false; // Fail if set is already in list or set is null.
459 496
460 497 m_boxSets.append(set);
461 498 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
462 499 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
463 500 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
464 501
465 502 emit restructuredBoxes(); // this notifies boxplotchartitem
466 503 return true;
467 504 }
468 505
469 506 bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
470 507 {
471 508 if (!m_boxSets.contains(set))
472 509 return false; // Fail if set is not in list
473 510
474 511 m_boxSets.removeOne(set);
475 512 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
476 513 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
477 514 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
478 515
479 516 emit restructuredBoxes(); // this notifies boxplotchartitem
480 517 return true;
481 518 }
482 519
483 520 bool QBoxPlotSeriesPrivate::append(QList<QBoxSet * > sets)
484 521 {
485 522 foreach (QBoxSet *set, sets) {
486 523 if ((set == 0) || (m_boxSets.contains(set)))
487 524 return false; // Fail if any of the sets is null or is already appended.
488 525 if (sets.count(set) != 1)
489 526 return false; // Also fail if same set is more than once in given list.
490 527 }
491 528
492 529 foreach (QBoxSet *set, sets) {
493 530 m_boxSets.append(set);
494 531 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
495 532 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
496 533 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
497 534 }
498 535
499 536 emit restructuredBoxes(); // this notifies boxplotchartitem
500 537 return true;
501 538 }
502 539
503 540 bool QBoxPlotSeriesPrivate::remove(QList<QBoxSet * > sets)
504 541 {
505 542 if (sets.count() == 0)
506 543 return false;
507 544
508 545 foreach (QBoxSet *set, sets) {
509 546 if ((set == 0) || (!m_boxSets.contains(set)))
510 547 return false; // Fail if any of the sets is null or is not in series
511 548 if (sets.count(set) != 1)
512 549 return false; // Also fail if same set is more than once in given list.
513 550 }
514 551
515 552 foreach (QBoxSet *set, sets) {
516 553 m_boxSets.removeOne(set);
517 554 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
518 555 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
519 556 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
520 557 }
521 558
522 559 emit restructuredBoxes(); // this notifies boxplotchartitem
523 560
524 561 return true;
525 562 }
526 563
527 564 bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
528 565 {
529 566 if ((m_boxSets.contains(set)) || (set == 0))
530 567 return false; // Fail if set is already in list or set is null.
531 568
532 569 m_boxSets.insert(index, set);
533 570 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
534 571 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
535 572 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
536 573
537 574 emit restructuredBoxes(); // this notifies boxplotchartitem
538 575 return true;
539 576 }
540 577
541 578 QBoxSet *QBoxPlotSeriesPrivate::boxsetAt(int index)
542 579 {
543 580 return m_boxSets.at(index);
544 581 }
545 582
546 583 qreal QBoxPlotSeriesPrivate::bottom()
547 584 {
548 585 // Returns bottom of all boxes
549 586 qreal bottom(0);
550 587 foreach (QBoxSet *set, m_boxSets) {
551 588 for (int i = 0; i < set->count(); i++) {
552 589 if (set->at(i) < bottom)
553 590 bottom = set->at(i);
554 591 }
555 592 }
556 593
557 594 return bottom;
558 595 }
559 596
560 597 qreal QBoxPlotSeriesPrivate::max()
561 598 {
562 599 if (m_boxSets.count() <= 0)
563 600 return 0;
564 601
565 602 qreal max = INT_MIN;
566 603
567 604 foreach (QBoxSet *set, m_boxSets) {
568 605 for (int i = 0; i < set->count(); i++) {
569 606 if (set->at(i) > max)
570 607 max = set->at(i);
571 608 }
572 609 }
573 610
574 611 return max;
575 612 }
576 613
577 614 #include "moc_qboxplotseries.cpp"
578 615 #include "moc_qboxplotseries_p.cpp"
579 616
580 617 QTCOMMERCIALCHART_END_NAMESPACE
581 618
@@ -1,78 +1,72
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QBOXPLOTSERIES_H
22 22 #define QBOXPLOTSERIES_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <qboxset.h>
26 //#include <qabstractbarseries.h>
27 26 #include <qabstractseries.h>
28 27
29 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 29
31 30 class QBoxPlotSeriesPrivate;
32 //class QBarSet;
33 31
34 32 class QTCOMMERCIALCHART_EXPORT QBoxPlotSeries : public QAbstractSeries
35 33 {
36 34 Q_OBJECT
37 35 public:
38 36 explicit QBoxPlotSeries(QObject *parent = 0);
39 37 ~QBoxPlotSeries();
40 38
41 39 bool append(QBoxSet *box);
42 40 bool remove(QBoxSet *box);
43 41 bool take(QBoxSet *box);
44 42 bool append(QList<QBoxSet *> boxes);
45 43 bool insert(int index, QBoxSet *box);
46 44 int count() const;
47 45 QList<QBoxSet *> boxSets() const;
48 46 void clear();
49 47
50 void setLabelsVisible(bool visible = true);
51 bool isLabelsVisible() const;
52
53 48 QAbstractSeries::SeriesType type() const;
54 49
55 50 void setBrush(const QBrush &brush);
56 51 QBrush brush() const;
57 52 void setPen(const QPen &pen);
58 53 QPen pen() const;
59 54
60 55 Q_SIGNALS:
61 void clicked(int index, QBoxSet *boxset);
56 void clicked(QBoxSet *boxset);
62 57 void hovered(bool status, QBoxSet *boxset);
63 58 void countChanged();
64 void labelsVisibleChanged();
65 59
66 60 void boxsetsAdded(QList<QBoxSet *> sets);
67 61 void boxsetsRemoved(QList<QBoxSet *> sets);
68 62
69 63 private:
70 64 Q_DECLARE_PRIVATE(QBoxPlotSeries)
71 65 Q_DISABLE_COPY(QBoxPlotSeries)
72 66 friend class BoxPlotChartItem;
73 67 friend class QBoxPlotLegendMarkerPrivate;
74 68 };
75 69
76 70 QTCOMMERCIALCHART_END_NAMESPACE
77 71
78 72 #endif // QBOXPLOTSERIES_H
@@ -1,395 +1,493
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qboxset.h"
22 22 #include "qboxset_p.h"
23 23 #include "charthelpers_p.h"
24 24
25 25 #include <QDebug> //TODO: remove on release
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /*!
30 Constructs QBoxSet with parent of \a parent
30 \class QBoxSet
31 \brief Building block for box-and-whiskers chart
32
33 QBoxSet represents one box-and-whiskers item. It takes fives values to create a graphical representation
34 of range and three medians. There's two type of methods to give the values. The first one is with constructor
35 or append type of methods (append and operator <<). In these the values have to be given in order lower extreme,
36 lower quartile, median, upper quartile and upper extre. Second method is to create an empty QBoxSet instance and
37 give the values using own methods.
38
39 \mainclass
40
41 \sa QBoxPlotSeries
42 */
43 /*!
44 \qmlclass BoxSet QBoxSet
45
46 BoxSet represents one box-and-whiskers item. It takes fives values to create a graphical representation
47 of range and three medians. There's two type of methods to give the values. The first one is with constructor
48 or append type of methods (append and operator <<). In these the values have to be given in order lower extreme,
49 lower quartile, median, upper quartile and upper extre. Second method is to create an empty BoxSet instance and
50 give the values using own methods.
51 \sa BoxPlotSeries
52 */
53
54 /*!
55 \property QBoxSet::pen
56 \brief Defines the pen used by the box-and-whiskers set.
57 */
58
59 /*!
60 \property QBoxSet::brush
61 \brief Defines the brush used by the box-and-whiskers set.
62 */
63
64 /*!
65 \property QBoxSet::color
66 The fill (brush) color of the box-and-whiskers set.
67 */
68
69 /*!
70 \property QBoxSet::borderColor
71 The line (pen) color of the box-and-whiskers set.
72 */
73
74 /*!
75 \fn void QBoxSet::clicked()
76 The signal is emitted if the user clicks with a mouse on top of box-and-whisker item.
77 */
78
79 /*!
80 \fn void QBoxSet::hovered(bool status)
81
82 The signal is emitted if mouse is hovered on top of box-and-whisker item.
83 Parameter \a status is true, if mouse entered on top of item, false if mouse left from top of item.
84 */
85
86 /*!
87 \fn void QBoxSet::penChanged()
88 This signal is emitted when the pen of the box-and-whisker item has changed.
89 \sa pen
90 */
91
92 /*!
93 \fn void QBoxSet::brushChanged()
94 This signal is emitted when the brush of the box-and-whisker item has changed.
95 \sa brush
96 */
97
98 /*!
99 \fn void QBoxSet::colorChanged(QColor)
100 This signal is emitted when the fill (brush) color of the box-and-whisker item has changed to \a color.
101 */
102
103 /*!
104 \fn void QBoxSet::valuesAdded(int index, int count)
105 This signal is emitted when new values have been added to the box-and-whisker item.
106 Parameter \a index indicates the position of the first inserted value.
107 Parameter \a count is the number of inserted values.
108 \sa append(), insert()
109 */
110
111 /*!
112 \fn void QBoxSet::valueChanged(int index)
113 This signal is emitted values the value in the box-and-whisker item has been modified.
114 Parameter \a index indicates the position of the modified value.
115 \sa at()
116 */
117
118 /*!
119 \fn void QBoxSet::borderColorChanged(QColor)
120 This signal is emitted when the line (pen) color of the box-and-whisker item has changed to \a color.
121 */
122
123 /*!
124 Constructs QBoxSet with optional \a label and parent of \a parent
31 125 */
32 126 QBoxSet::QBoxSet(const QString label, QObject *parent)
33 127 : QObject(parent),
34 128 d_ptr(new QBoxSetPrivate(label, this))
35 129 {
36 130 }
37 131
38 QBoxSet::QBoxSet(qreal value1, qreal value2, qreal value3, qreal value4, qreal value5, const QString label, QObject *parent)
132 /*!
133 Constructs QBoxSet with given ordered values. \a le for lower extreme, \a lq for lower quartile, \a m for median,
134 \a uq for upper quartile and \a ue for upper quartile. \a label and \a parent are optional.
135 */
136 QBoxSet::QBoxSet(const qreal le, const qreal lq, const qreal m, const qreal uq, const qreal ue, const QString label = "", QObject *parent)
39 137 : QObject(parent),
40 138 d_ptr(new QBoxSetPrivate(label, this))
41 139 {
42 d_ptr->append(value1);
43 d_ptr->append(value2);
44 d_ptr->append(value3);
45 d_ptr->append(value4);
46 d_ptr->append(value5);
140 d_ptr->append(le);
141 d_ptr->append(lq);
142 d_ptr->append(m);
143 d_ptr->append(uq);
144 d_ptr->append(ue);
47 145 }
48 146
49 147 /*!
50 148 Destroys the boxset
51 149 */
52 150 QBoxSet::~QBoxSet()
53 151 {
54 152 // NOTE: d_ptr destroyed by QObject
55 153 }
56 154
57 155 /*!
58 156 Appends new value \a value to the end of set.
59 157 */
60 158 void QBoxSet::append(const qreal value)
61 159 {
62 160 //int index = d_ptr->m_values.count();
63 161 d_ptr->append(value);
64 162
65 163 emit valuesAdded(d_ptr->m_valuesCount, 1);
66 164 }
67 165
68 166 /*!
69 167 Appends a list of reals to set. Works like append with single real value. The \a values in list
70 168 are appended to end of boxset
71 169 \sa append()
72 170 */
73 171 void QBoxSet::append(const QList<qreal> &values)
74 172 {
75 173 //int index = d_ptr->m_values.count();
76 174 d_ptr->append(values);
77 175 emit valuesAdded(d_ptr->m_valuesCount, values.count());
78 176 }
79 177
80 178 /*!
81 179 Sets new value \a value as the lower extreme for the set.
82 180 */
83 181 void QBoxSet::setLowerExtreme(const qreal value)
84 182 {
85 183 d_ptr->replace(QBoxSetPrivate::PosLowerExtreme, value);
86 184 emit d_ptr->restructuredBox();
87 185 emit valueChanged(QBoxSetPrivate::PosLowerExtreme);
88 186 }
89 187
90 188 /*!
91 189 Returns the lower extreme value of the set.
92 190 */
93 191 qreal QBoxSet::lowerExtreme()
94 192 {
95 193 return d_ptr->m_values[QBoxSetPrivate::PosLowerExtreme];
96 194 }
97 195
98 196 /*!
99 197 Sets new value \a value as the lower quartile for the set.
100 198 */
101 199 void QBoxSet::setLowerQuartile(const qreal value)
102 200 {
103 201 d_ptr->replace(QBoxSetPrivate::PosLowerQuartile, value);
104 202 emit d_ptr->restructuredBox();
105 203 emit valueChanged(QBoxSetPrivate::PosLowerQuartile);
106 204 }
107 205
108 206 /*!
109 207 Returns the lower quartile value of the set.
110 208 */
111 209 qreal QBoxSet::lowerQuartile()
112 210 {
113 211 return d_ptr->m_values[QBoxSetPrivate::PosLowerQuartile];
114 212 }
115 213
116 214 /*!
117 215 Sets new value \a value as the median for the set.
118 216 */
119 217 void QBoxSet::setMedian(const qreal value)
120 218 {
121 219 d_ptr->replace(QBoxSetPrivate::PosMedian, value);
122 220 emit d_ptr->restructuredBox();
123 221 emit valueChanged(QBoxSetPrivate::PosMedian);
124 222 }
125 223
126 224 /*!
127 225 Returns the median value of the set.
128 226 */
129 227 qreal QBoxSet::median()
130 228 {
131 229 return d_ptr->m_values[QBoxSetPrivate::PosMedian];
132 230 }
133 231
134 232 /*!
135 233 Sets new value \a value as the upper quartile for the set.
136 234 */
137 235 void QBoxSet::setUpperQuartile(const qreal value)
138 236 {
139 237 d_ptr->replace(QBoxSetPrivate::PosUpperQuartile, value);
140 238 emit d_ptr->restructuredBox();
141 239 emit valueChanged(QBoxSetPrivate::PosUpperQuartile);
142 240 }
143 241
144 242 /*!
145 243 Returns the upper quartile value of the set.
146 244 */
147 245 qreal QBoxSet::upperQuartile()
148 246 {
149 247 return d_ptr->m_values[QBoxSetPrivate::PosUpperQuartile];
150 248 }
151 249
152 250 /*!
153 251 Sets new value \a value as the upper extreme for the set.
154 252 */
155 253 void QBoxSet::setUpperExtreme(const qreal value)
156 254 {
157 255 d_ptr->replace(QBoxSetPrivate::PosUpperExtreme, value);
158 256 emit d_ptr->restructuredBox();
159 257 emit valueChanged(QBoxSetPrivate::PosUpperExtreme);
160 258 }
161 259
162 260 /*!
163 261 Returns the upper extreme value of the set.
164 262 */
165 263 qreal QBoxSet::upperExtreme()
166 264 {
167 265 return d_ptr->m_values[QBoxSetPrivate::PosUpperExtreme];
168 266 }
169 267
170 268 /*!
171 269 Sets new \a label for set.
172 270 */
173 271 void QBoxSet::setLabel(const QString label)
174 272 {
175 273 d_ptr->m_label = label;
176 274 }
177 275
178 276 /*!
179 277 Returns label of the set.
180 278 */
181 279 QString QBoxSet::label() const
182 280 {
183 281 return d_ptr->m_label;
184 282 }
185 283
186 284 /*!
187 285 Convenience operator. Same as append, with real \a value.
188 286 \sa append()
189 287 */
190 288 QBoxSet &QBoxSet::operator << (const qreal &value)
191 289 {
192 290 append(value);
193 291 return *this;
194 292 }
195 293
196 294 /*!
197 295 Inserts new \a value on the \a index position.
198 296 The value that is currently at this postion is moved to postion index + 1
199 297 */
200 298 void QBoxSet::insert(const int index, const qreal value)
201 299 {
202 300 d_ptr->insert(index, value);
203 301 emit valuesAdded(index, 1);
204 302 }
205 303
206 304 /*!
207 305 Sets a new value \a value to set, indexed by \a index
208 306 */
209 307 void QBoxSet::replace(const int index, const qreal value)
210 308 {
211 309 if (index >= 0 && index < 5) {
212 310 d_ptr->replace(index, value);
213 311 emit valueChanged(index);
214 312 }
215 313 }
216 314
217 315
218 316 /*!
219 317 Returns value of set indexed by \a index.
220 318 If the index is out of bounds 0.0 is returned.
221 319 */
222 320 qreal QBoxSet::at(const int index) const
223 321 {
224 322 if (index < 0 || index >= 5)
225 323 return 0;
226 324 return d_ptr->m_values[index];
227 325 }
228 326
229 327 /*!
230 328 Returns value of set indexed by \a index.
231 329 If the index is out of bounds 0.0 is returned.
232 330 */
233 331 qreal QBoxSet::operator [](const int index) const
234 332 {
235 333 return at(index);
236 334 }
237 335
238 336 /*!
239 337 Returns count of values in set.
240 338 */
241 339 int QBoxSet::count() const
242 340 {
243 341 return d_ptr->m_valuesCount;
244 342 }
245 343
246 344 /*!
247 345 Sets pen for set. Boxes of this set are drawn using \a pen
248 346 */
249 347 void QBoxSet::setPen(const QPen &pen)
250 348 {
251 349 if (d_ptr->m_pen != pen) {
252 350 d_ptr->m_pen = pen;
253 351 emit d_ptr->updatedBox();
254 352 emit penChanged();
255 353 }
256 354 }
257 355
258 356 /*!
259 357 Returns pen of the set.
260 358 */
261 359 QPen QBoxSet::pen() const
262 360 {
263 361 return d_ptr->m_pen;
264 362 }
265 363
266 364 /*!
267 365 Sets brush for the set. Boxes of this set are drawn using \a brush
268 366 */
269 367 void QBoxSet::setBrush(const QBrush &brush)
270 368 {
271 369 if (d_ptr->m_brush != brush) {
272 370 d_ptr->m_brush = brush;
273 371 emit d_ptr->updatedBox();
274 372 emit brushChanged();
275 373 }
276 374 }
277 375
278 376 /*!
279 377 Returns brush of the set.
280 378 */
281 379 QBrush QBoxSet::brush() const
282 380 {
283 381 return d_ptr->m_brush;
284 382 }
285 383
286 384 /*!
287 385 Returns the color of the brush of boxset.
288 386 */
289 387 QColor QBoxSet::color()
290 388 {
291 389 return brush().color();
292 390 }
293 391
294 392 /*!
295 393 Sets the \a color of brush for this boxset
296 394 */
297 395 void QBoxSet::setColor(QColor color)
298 396 {
299 397 QBrush b = brush();
300 398 if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
301 399 b.setColor(color);
302 400 if (b.style() == Qt::NoBrush) {
303 401 // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
304 402 // This prevents theme to override color defined in QML side:
305 403 // BoxSet { label: "Bob"; color:"red"; values: [1,2,3] }
306 404 // The color must be obeyed, since user wanted it.
307 405 b.setStyle(Qt::SolidPattern);
308 406 }
309 407 setBrush(b);
310 408 emit colorChanged(color);
311 409 }
312 410 }
313 411
314 412 /*!
315 413 Returns the color of pen of this boxset
316 414 */
317 415 QColor QBoxSet::borderColor()
318 416 {
319 417 return pen().color();
320 418 }
321 419
322 420 /*!
323 421 Sets the color of pen for this boxset
324 422 */
325 423 void QBoxSet::setBorderColor(QColor color)
326 424 {
327 425 QPen p = pen();
328 426 if (p.color() != color) {
329 427 p.setColor(color);
330 428 setPen(p);
331 429 emit borderColorChanged(color);
332 430 }
333 431 }
334 432
335 433 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
336 434
337 435 QBoxSetPrivate::QBoxSetPrivate(const QString label, QBoxSet *parent) : QObject(parent),
338 436 q_ptr(parent),
339 437 m_label(label),
340 438 m_valuesCount(5),
341 439 m_appendCount(0),
342 440 m_pen(QPen(Qt::NoPen)),
343 441 m_brush(QBrush(Qt::NoBrush))
344 442 {
345 443 m_values = new qreal[m_valuesCount];
346 444 }
347 445
348 446 QBoxSetPrivate::~QBoxSetPrivate()
349 447 {
350 448 }
351 449
352 450 void QBoxSetPrivate::append(qreal value)
353 451 {
354 452 if (isValidValue(value) && m_appendCount < m_valuesCount) {
355 453 m_values[m_appendCount++] = value;
356 454 emit restructuredBox();
357 455 }
358 456 }
359 457
360 458 void QBoxSetPrivate::append(QList<qreal> values)
361 459 {
362 460 for (int i = 0; i < values.count(); i++) {
363 461 if (isValidValue(values.at(i)) && m_appendCount < m_valuesCount)
364 462 m_values[m_appendCount++] = values.at(i);
365 463 }
366 464 emit restructuredBox();
367 465 }
368 466
369 467 void QBoxSetPrivate::insert(const int index, const qreal value)
370 468 {
371 469 if (isValidValue(value)) {
372 470 for (int i = 4; i > index; i--)
373 471 m_values[i] = m_values[i - 1];
374 472 m_values[index] = value;
375 473 emit restructuredBox();
376 474 }
377 475 }
378 476
379 477 void QBoxSetPrivate::replace(const int index, const qreal value)
380 478 {
381 479 m_values[index] = value;
382 480 emit updatedLayout();
383 481 }
384 482
385 483 qreal QBoxSetPrivate::value(const int index)
386 484 {
387 485 if (index < 0 || index >= m_valuesCount)
388 486 return 0;
389 487 return m_values[index];
390 488 }
391 489
392 490 #include "moc_qboxset.cpp"
393 491 #include "moc_qboxset_p.cpp"
394 492
395 493 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,107 +1,105
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QBOXSET_H
22 22 #define QBOXSET_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QPen>
26 26 #include <QBrush>
27 27 #include <QFont>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 class QBoxSetPrivate;
31 31
32 32 class QTCOMMERCIALCHART_EXPORT QBoxSet : public QObject
33 33 {
34 34 Q_OBJECT
35 35 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
36 36 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
37 37 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
38 38 Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
39 39
40 40 public:
41 41 explicit QBoxSet(const QString label = "", QObject *parent = 0);
42 explicit QBoxSet(const qreal value1, const qreal value2, const qreal value3, const qreal value4, const qreal value5, const QString label = "", QObject *parent = 0);
42 explicit QBoxSet(const qreal le, const qreal lq, const qreal m, const qreal uq, const qreal ue, const QString label = "", QObject *parent = 0);
43 43 virtual ~QBoxSet();
44 44
45 45 void append(const qreal value);
46 46 void append(const QList<qreal> &values);
47 47
48 48 void setLowerExtreme(const qreal value);
49 49 qreal lowerExtreme();
50 50 void setLowerQuartile(const qreal value);
51 51 qreal lowerQuartile();
52 52 void setMedian(const qreal value);
53 53 qreal median();
54 54 void setUpperQuartile(const qreal value);
55 55 qreal upperQuartile();
56 56 void setUpperExtreme(const qreal value);
57 57 qreal upperExtreme();
58 58
59 59 void setLabel(const QString label);
60 60 QString label() const;
61 61
62 62 QBoxSet &operator << (const qreal &value);
63 63
64 64 void insert(const int index, const qreal value);
65 void remove(const int index, const int count = 1);
66 65 void replace(const int index, const qreal value);
67 66 qreal at(const int index) const;
68 67 qreal operator [](const int index) const;
69 68 int count() const;
70 69
71 70 void setPen(const QPen &pen);
72 71 QPen pen() const;
73 72
74 73 void setBrush(const QBrush &brush);
75 74 QBrush brush() const;
76 75
77 76 QColor color();
78 77 void setColor(QColor color);
79 78
80 79 QColor borderColor();
81 80 void setBorderColor(QColor color);
82 81
83 82
84 83 Q_SIGNALS:
85 void clicked(int index);
84 void clicked();
86 85 void hovered(bool status);
87 86 void penChanged();
88 87 void brushChanged();
89 88 void colorChanged(QColor color);
90 89 void borderColorChanged(QColor color);
91 90
92 91 void valuesAdded(int index, int count);
93 void valuesRemoved(int index, int count);
94 92 void valueChanged(int index);
95 93
96 94 private:
97 95 QScopedPointer<QBoxSetPrivate> d_ptr;
98 96 Q_DISABLE_COPY(QBoxSet)
99 97 friend class BarLegendMarker;
100 98 friend class BarChartItem;
101 99 friend class BoxPlotChartItem;
102 100 friend class QBoxPlotSeriesPrivate;
103 101 };
104 102
105 103 QTCOMMERCIALCHART_END_NAMESPACE
106 104
107 105 #endif // QBOXSET_H
@@ -1,249 +1,249
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qvboxplotmodelmapper.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 /*!
26 26 \class QVBoxPlotModelMapper
27 27 \brief Vertical model mapper for bar series
28 28 \mainclass
29 29
30 30 Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
31 Vertical model mapper is used to create a connection between QAbstractBarSeries and QAbstractItemModel derived model object.
31 Vertical model mapper is used to create a connection between QBoxPlotSeries and QAbstractItemModel derived model object.
32 32 Model mapper maintains equal size of all the BarSets.
33 Adding/removing value from the BarSet causes the the same change in the rest of the BarSets added to the same series.
34 33 Note: used model has to support adding/removing rows/columns and modifying the data of the cells.
35 34 */
36 35 /*!
37 \qmlclass VBarModelMapper
36 \qmlclass VBoxPlotModelMapper
38 37 \mainclass
39 38
40 VBarModelMapper allows you to use your own QAbstractItemModel derived model with data in columns as a data source
41 for any bar series. It is possible to use both QAbstractItemModel and bar series data API to manipulate data.
42 VBarModelMapper keeps the series and the model in sync.
39 VBoxPlotModelMapper allows you to use your own QAbstractItemModel derived model with data in columns as a data source
40 for any box-and-whiskers series. It is possible to use both QAbstractItemModel and box-and-whiskers series data API to
41 manipulate data.
42 VBoxPlotModelMapper keeps the series and the model in sync.
43 43
44 The following QML example would create a bar series with three bar sets (assuming the
45 model has at least four columns). Each bar set would contain data starting from row 1. The name of a set would be
44 The following QML example would create a box-and-whiskers series with three box sets (assuming the
45 model has at least four columns). Each box set would contain data starting from row 1. The name of a set would be
46 46 defined by the horizontal header (of the column).
47 47 \code
48 48 BarSeries {
49 49 VBarModelMapper {
50 50 model: myCustomModel // QAbstractItemModel derived implementation
51 51 firstBarSetColumn: 1
52 52 lastBarSetColumn: 3
53 53 firstRow: 1
54 54 }
55 55 }
56 56 \endcode
57 57 */
58 58
59 59 /*!
60 60 \property QVBoxPlotModelMapper::series
61 \brief Defines the QPieSeries object that is used by the mapper.
61 \brief Defines the QBoxPlotSeries object that is used by the mapper.
62 62
63 63 All the data in the series is discarded when it is set to the mapper.
64 64 When new series is specified the old series is disconnected (it preserves its data)
65 65 */
66 66 /*!
67 67 \qmlproperty AbstractBarSeries VBarModelMapper::series
68 68 Defines the AbstractBarSeries based object that is used by the mapper. All the data in the series is discarded when it is
69 69 set to the mapper. When new series is specified the old series is disconnected (it preserves its data).
70 70 */
71 71
72 72 /*!
73 73 \property QVBoxPlotModelMapper::model
74 74 \brief Defines the model that is used by the mapper.
75 75 */
76 76 /*!
77 77 \qmlproperty SomeModel VBarModelMapper::model
78 78 The QAbstractItemModel based model that is used by the mapper. You need to implement the model and expose it to
79 79 QML as shown in \l {QML Custom Model} demo application. Note: the model has to support adding/removing rows/columns
80 80 and modifying the data of the cells.
81 81 */
82 82
83 83 /*!
84 \property QVBoxPlotModelMapper::firstBarSetColumn
85 \brief Defines which column of the model is used as the data source for the first bar set
84 \property QVBoxPlotModelMapper::firstBoxSetColumn
85 \brief Defines which column of the model is used as the data source for the first box-and-whiskers set
86 86 Default value is: -1 (invalid mapping)
87 87 */
88 88 /*!
89 \qmlproperty int VBarModelMapper::firstBarSetColumn
90 Defines which column of the model is used as the data source for the first bar set. Default value
89 \qmlproperty int VBarModelMapper::firstBoxSetColumn
90 Defines which column of the model is used as the data source for the first box-and-whiskers set. Default value
91 91 is: -1 (invalid mapping).
92 92 */
93 93
94 94 /*!
95 \property QVBoxPlotModelMapper::lastBarSetColumn
96 \brief Defines which column of the model is used as the data source for the last bar set
95 \property QVBoxPlotModelMapper::lastBoxSetColumn
96 \brief Defines which column of the model is used as the data source for the last box-and-whiskers set
97 97 Default value is: -1 (invalid mapping)
98 98 */
99 99 /*!
100 \qmlproperty int VBarModelMapper::lastBarSetColumn
101 Defines which column of the model is used as the data source for the last bar set. Default
100 \qmlproperty int VBarModelMapper::lastBoxSetColumn
101 Defines which column of the model is used as the data source for the last box-and-whiskers set. Default
102 102 value is: -1 (invalid mapping).
103 103 */
104 104
105 105 /*!
106 106 \property QVBoxPlotModelMapper::firstRow
107 \brief Defines which row of the model contains the first values of the QBarSets in the series.
107 \brief Defines which row of the model contains the first values of the QBoxSets in the series.
108 108 Minimal and default value is: 0
109 109 */
110 110 /*!
111 \qmlproperty int VBarModelMapper::firstRow
112 Defines which row of the model contains the first values of the QBarSets in the series.
111 \qmlproperty int VBoxPlotModelMapper::firstRow
112 Defines which row of the model contains the first values of the QBoxSets in the series.
113 113 The default value is 0.
114 114 */
115 115
116 116 /*!
117 117 \property QVBoxPlotModelMapper::rowCount
118 \brief Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries
118 \brief Defines the number of rows of the model that are mapped as the data for QBoxPlotSeries
119 119 Minimal and default value is: -1 (count limited by the number of rows in the model)
120 120 */
121 121 /*!
122 \qmlproperty int VBarModelMapper::rowCount
123 Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries. The default value is
122 \qmlproperty int VBoxModelMapper::rowCount
123 Defines the number of rows of the model that are mapped as the data for QBoxPlotSeries. The default value is
124 124 -1 (count limited by the number of rows in the model)
125 125 */
126 126
127 127 /*!
128 128 \fn void QVBoxPlotModelMapper::seriesReplaced()
129 129
130 130 Emitted when the series to which mapper is connected to has changed.
131 131 */
132 132
133 133 /*!
134 134 \fn void QVBoxPlotModelMapper::modelReplaced()
135 135
136 136 Emitted when the model to which mapper is connected to has changed.
137 137 */
138 138
139 139 /*!
140 \fn void QVBoxPlotModelMapper::firstBarSetColumnChanged()
141 Emitted when the firstBarSetColumn has changed.
140 \fn void QVBoxPlotModelMapper::firstBoxSetColumnChanged()
141 Emitted when the firstBoxSetColumn has changed.
142 142 */
143 143
144 144 /*!
145 \fn void QVBoxPlotModelMapper::lastBarSetColumnChanged()
146 Emitted when the lastBarSetColumn has changed.
145 \fn void QVBoxPlotModelMapper::lastBoxSetColumnChanged()
146 Emitted when the lastBoxSetColumn has changed.
147 147 */
148 148
149 149 /*!
150 150 \fn void QVBoxPlotModelMapper::firstRowChanged()
151 151 Emitted when the firstRow has changed.
152 152 */
153 153
154 154 /*!
155 155 \fn void QVBoxPlotModelMapper::rowCountChanged()
156 156 Emitted when the rowCount has changed.
157 157 */
158 158
159 159 /*!
160 160 Constructs a mapper object which is a child of \a parent.
161 161 */
162 162 QVBoxPlotModelMapper::QVBoxPlotModelMapper(QObject *parent) :
163 163 QBoxPlotModelMapper(parent)
164 164 {
165 165 QBoxPlotModelMapper::setOrientation(Qt::Vertical);
166 166 }
167 167
168 168 QAbstractItemModel *QVBoxPlotModelMapper::model() const
169 169 {
170 170 return QBoxPlotModelMapper::model();
171 171 }
172 172
173 173 void QVBoxPlotModelMapper::setModel(QAbstractItemModel *model)
174 174 {
175 175 if (model != QBoxPlotModelMapper::model()) {
176 176 QBoxPlotModelMapper::setModel(model);
177 177 emit modelReplaced();
178 178 }
179 179 }
180 180
181 181 QBoxPlotSeries *QVBoxPlotModelMapper::series() const
182 182 {
183 183 return QBoxPlotModelMapper::series();
184 184 }
185 185
186 186 void QVBoxPlotModelMapper::setSeries(QBoxPlotSeries *series)
187 187 {
188 188 if (series != QBoxPlotModelMapper::series()) {
189 189 QBoxPlotModelMapper::setSeries(series);
190 190 emit seriesReplaced();
191 191 }
192 192 }
193 193
194 194 int QVBoxPlotModelMapper::firstBoxSetColumn() const
195 195 {
196 196 return QBoxPlotModelMapper::firstBoxSetSection();
197 197 }
198 198
199 199 void QVBoxPlotModelMapper::setFirstBoxSetColumn(int firstBoxSetColumn)
200 200 {
201 201 if (firstBoxSetColumn != firstBoxSetSection()) {
202 202 QBoxPlotModelMapper::setFirstBoxSetSection(firstBoxSetColumn);
203 203 emit firstBoxSetColumnChanged();
204 204 }
205 205 }
206 206
207 207 int QVBoxPlotModelMapper::lastBoxSetColumn() const
208 208 {
209 209 return QBoxPlotModelMapper::lastBoxSetSection();
210 210 }
211 211
212 212 void QVBoxPlotModelMapper::setLastBoxSetColumn(int lastBoxSetColumn)
213 213 {
214 214 if (lastBoxSetColumn != lastBoxSetSection()) {
215 215 QBoxPlotModelMapper::setLastBoxSetSection(lastBoxSetColumn);
216 216 emit lastBoxSetColumnChanged();
217 217 }
218 218 }
219 219
220 220 int QVBoxPlotModelMapper::firstRow() const
221 221 {
222 222 return QBoxPlotModelMapper::first();
223 223 }
224 224
225 225 void QVBoxPlotModelMapper::setFirstRow(int firstRow)
226 226 {
227 227 if (firstRow != first()) {
228 228 QBoxPlotModelMapper::setFirst(firstRow);
229 229 emit firstRowChanged();
230 230 }
231 231 }
232 232
233 233 int QVBoxPlotModelMapper::rowCount() const
234 234 {
235 235 return QBoxPlotModelMapper::count();
236 236 }
237 237
238 238 void QVBoxPlotModelMapper::setRowCount(int rowCount)
239 239 {
240 240 if (rowCount != count()) {
241 241 QBoxPlotModelMapper::setCount(rowCount);
242 242 emit rowCountChanged();
243 243 }
244 244 }
245 245
246 246 #include "moc_qvboxplotmodelmapper.cpp"
247 247
248 248 QTCOMMERCIALCHART_END_NAMESPACE
249 249
@@ -1,292 +1,293
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qlegendmarker.h"
22 22 #include "qlegendmarker_p.h"
23 23 #include "legendmarkeritem_p.h"
24 24 #include "qlegend.h"
25 25 #include "qlegend_p.h"
26 26 #include "legendlayout_p.h"
27 27 #include <QFontMetrics>
28 28 #include <QGraphicsSceneEvent>
29 29 #include <QAbstractSeries>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QLegendMarker
35 35 \brief LegendMarker object
36 36 \mainclass
37 37
38 38 QLegendMarker is abstract object that can be used to access markers inside QLegend. Legend marker consists of two
39 39 items: The colored box, which reflects the color of series and label, which is the name of series (or label of slice/barset
40 40 in case of pie or bar series)
41 41 The QLegendMarker is always related to one series.
42 42
43 43 \image examples_percentbarchart_legend.png
44 44
45 45 \sa QLegend
46 46 */
47 47 /*!
48 48 \enum QLegendMarker::LegendMarkerType
49 49
50 50 The type of the legendmarker object.
51 51
52 52 \value LegendMarkerTypeArea
53 53 \value LegendMarkerTypeBar
54 54 \value LegendMarkerTypePie
55 55 \value LegendMarkerTypeXY
56 \value LegendMarkerTypeBoxPlot
56 57 */
57 58
58 59 /*!
59 60 \fn virtual LegendMarkerType QLegendMarker::type() = 0;
60 61 Returns the type of legendmarker. Type depends of the related series. LegendMarkerTypeXY is used for all QXYSeries derived
61 62 classes.
62 63 */
63 64
64 65 /*!
65 66 \fn virtual QAbstractSeries* QLegendMarker::series() = 0;
66 67 Returns pointer to series, which is related to this marker. Marker is always related to some series.
67 68 */
68 69
69 70 /*!
70 71 \fn void QLegendMarker::clicked();
71 72 This signal is emitted, when marker is clicked with mouse.
72 73 */
73 74
74 75 /*!
75 76 \fn void QLegendMarker::hovered(bool status);
76 77 This signal is emitted, when mouse is hovered over marker. \a status is true, when mouse enters the marker
77 78 and false when it leaves the marker.
78 79 */
79 80
80 81 /*!
81 82 \fn void QLegendMarker::labelChanged()
82 83 This signal is emitted when the label of the legend marker has changed.
83 84 */
84 85
85 86 /*!
86 87 \fn void QLegendMarker::labelBrushChanged()
87 88 This signal is emitted when the label brush of the legend marker has changed.
88 89 */
89 90
90 91 /*!
91 92 \fn void QLegendMarker::fontChanged()
92 93 This signal is emitted when the (label) font of the legend marker has changed.
93 94 */
94 95
95 96 /*!
96 97 \fn void QLegendMarker::penChanged()
97 98 This signal is emitted when the pen of the legend marker has changed.
98 99 */
99 100
100 101 /*!
101 102 \fn void QLegendMarker::brushChanged()
102 103 This signal is emitted when the brush of the legend marker has changed.
103 104 */
104 105
105 106 /*!
106 107 \fn void QLegendMarker::visibleChanged()
107 108 This signal is emitted when the visibility of the legend marker has changed.
108 109 */
109 110
110 111 /*!
111 112 \property QLegendMarker::label
112 113 Label of the marker. This is the text that is shown in legend.
113 114 */
114 115
115 116 /*!
116 117 \property QLegendMarker::labelBrush
117 118 Brush of the label
118 119 */
119 120
120 121 /*!
121 122 \property QLegendMarker::font
122 123 Font of the label
123 124 */
124 125
125 126 /*!
126 127 \property QLegendMarker::pen
127 128 Pen of the marker. This is the outline of the colored square.
128 129 */
129 130
130 131 /*!
131 132 \property QLegendMarker::brush
132 133 Brush of the marker. This is the inside of the colored square.
133 134 */
134 135
135 136 /*!
136 137 \property QLegendMarker::visible
137 138 Visibility of the legend marker. Affects label and the colored square.
138 139 */
139 140
140 141
141 142 /*!
142 143 \internal
143 144 */
144 145 QLegendMarker::QLegendMarker(QLegendMarkerPrivate &d, QObject *parent) :
145 146 QObject(parent),
146 147 d_ptr(&d)
147 148 {
148 149 d_ptr->m_item->setVisible(d_ptr->series()->isVisible());
149 150 }
150 151
151 152 /*!
152 153 Destructor of marker
153 154 */
154 155 QLegendMarker::~QLegendMarker()
155 156 {
156 157 }
157 158
158 159 /*!
159 160 Returns the label of the marker.
160 161 */
161 162 QString QLegendMarker::label() const
162 163 {
163 164 return d_ptr->m_item->label();
164 165 }
165 166
166 167 /*!
167 168 Sets the \a label of marker. Note that changing name of series will also change label of its marker.
168 169 */
169 170 void QLegendMarker::setLabel(const QString &label)
170 171 {
171 172 if (label.isEmpty()) {
172 173 d_ptr->m_customLabel = false;
173 174 } else {
174 175 d_ptr->m_customLabel = true;
175 176 d_ptr->m_item->setLabel(label);
176 177 }
177 178 }
178 179 /*!
179 180 Returns the brush which is used to draw label.
180 181 */
181 182 QBrush QLegendMarker::labelBrush() const
182 183 {
183 184 return d_ptr->m_item->labelBrush();
184 185 }
185 186
186 187 /*!
187 188 Sets the \a brush of label
188 189 */
189 190 void QLegendMarker::setLabelBrush(const QBrush &brush)
190 191 {
191 192 d_ptr->m_item->setLabelBrush(brush);
192 193 }
193 194
194 195 /*!
195 196 Retuns the font of label
196 197 */
197 198 QFont QLegendMarker::font() const
198 199 {
199 200 return d_ptr->m_item->font();
200 201 }
201 202
202 203 /*!
203 204 Sets the \a font of label
204 205 */
205 206 void QLegendMarker::setFont(const QFont &font)
206 207 {
207 208 d_ptr->m_item->setFont(font);
208 209 }
209 210
210 211 /*!
211 212 Returns the pen of marker item
212 213 */
213 214 QPen QLegendMarker::pen() const
214 215 {
215 216 return d_ptr->m_item->pen();
216 217 }
217 218
218 219 /*!
219 220 Sets the \a pen of marker item
220 221 */
221 222 void QLegendMarker::setPen(const QPen &pen)
222 223 {
223 224 if (pen == QPen(Qt::NoPen)) {
224 225 d_ptr->m_customPen = false;
225 226 } else {
226 227 d_ptr->m_customPen = true;
227 228 d_ptr->m_item->setPen(pen);
228 229 }
229 230 }
230 231
231 232 /*!
232 233 Returns the brush of marker item
233 234 */
234 235 QBrush QLegendMarker::brush() const
235 236 {
236 237 return d_ptr->m_item->brush();
237 238 }
238 239
239 240 /*!
240 241 Sets the \a brush of marker item. Note that changing color of the series also changes this.
241 242 */
242 243 void QLegendMarker::setBrush(const QBrush &brush)
243 244 {
244 245 if (brush == QBrush(Qt::NoBrush)) {
245 246 d_ptr->m_customBrush = false;
246 247 } else {
247 248 d_ptr->m_customBrush = true;
248 249 d_ptr->m_item->setBrush(brush);
249 250 }
250 251 }
251 252
252 253 /*!
253 254 Returns visibility of the marker
254 255 */
255 256 bool QLegendMarker::isVisible() const
256 257 {
257 258 return d_ptr->m_item->isVisible();
258 259 }
259 260
260 261 /*!
261 262 Sets markers visibility to \a visible
262 263 */
263 264 void QLegendMarker::setVisible(bool visible)
264 265 {
265 266 d_ptr->m_item->setVisible(visible);
266 267 }
267 268
268 269 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269 270 QLegendMarkerPrivate::QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend) :
270 271 m_legend(legend),
271 272 m_customLabel(false),
272 273 m_customBrush(false),
273 274 m_customPen(false),
274 275 q_ptr(q)
275 276 {
276 277 m_item = new LegendMarkerItem(this);
277 278 }
278 279
279 280 QLegendMarkerPrivate::~QLegendMarkerPrivate()
280 281 {
281 282 delete m_item;
282 283 }
283 284
284 285 void QLegendMarkerPrivate::invalidateLegend()
285 286 {
286 287 m_legend->d_ptr->m_layout->invalidate();
287 288 }
288 289
289 290 #include "moc_qlegendmarker.cpp"
290 291 #include "moc_qlegendmarker_p.cpp"
291 292
292 293 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,314 +1,315
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qabstractseries.h"
22 22 #include "qabstractseries_p.h"
23 23 #include "chartdataset_p.h"
24 24 #include "qchart.h"
25 25 #include "qchart_p.h"
26 26 #include "chartitem_p.h"
27 27 #include "xydomain_p.h"
28 28 #include "xlogydomain_p.h"
29 29 #include "logxydomain_p.h"
30 30 #include "logxlogydomain_p.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QAbstractSeries
36 36 \brief Base class for all QtCommercial Chart series.
37 37 \mainclass
38 38
39 39 Usually you use the series type specific inherited classes instead of the base class.
40 40 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QAbstractBarSeries, QStackedBarSeries,
41 41 QPercentBarSeries, QPieSeries
42 42 */
43 43 /*!
44 44 \qmlclass AbstractSeries
45 45 AbstractSeries is the base class for all series.
46 46 The class cannot be instantiated by the user.
47 47 */
48 48
49 49 /*!
50 50 \enum QAbstractSeries::SeriesType
51 51
52 52 The type of the series object.
53 53
54 54 \value SeriesTypeLine
55 55 \value SeriesTypeArea
56 56 \value SeriesTypeBar
57 57 \value SeriesTypeStackedBar
58 58 \value SeriesTypePercentBar
59 59 \value SeriesTypePie
60 60 \value SeriesTypeScatter
61 61 \value SeriesTypeSpline
62 62 \value SeriesTypeHorizontalBar
63 63 \value SeriesTypeHorizontalStackedBar
64 64 \value SeriesTypeHorizontalPercentBar
65 \value SeriesTypeBoxPlot
65 66 */
66 67
67 68 /*!
68 69 \property QAbstractSeries::type
69 70 The type of the series.
70 71 */
71 72 /*!
72 73 \qmlproperty ChartView.SeriesType AbstractSeries::type
73 74 The type of the series.
74 75 */
75 76
76 77 /*!
77 78 \property QAbstractSeries::name
78 79 \brief name of the series property. The name is shown in legend for QXYSeries.
79 80 */
80 81 /*!
81 82 \qmlproperty string AbstractSeries::name
82 83 Name of the series. The name is shown in legend for QXYSeries.
83 84 */
84 85
85 86 /*!
86 87 \fn void QAbstractSeries::nameChanged()
87 88 This signal is emitted when the series name changes.
88 89 */
89 90 /*!
90 91 \qmlsignal AbstractSeries::onNameChanged()
91 92 This signal is emitted when the series name changes.
92 93 */
93 94
94 95 /*!
95 96 \property QAbstractSeries::visible
96 97 \brief whether the series is visible or not; true by default.
97 98 */
98 99 /*!
99 100 \qmlproperty bool AbstractSeries::visible
100 101 Visibility of the series. True by default.
101 102 */
102 103
103 104 /*!
104 105 \fn void QAbstractSeries::visibleChanged()
105 106 Emitted when the series visibility changes.
106 107 */
107 108 /*!
108 109 \qmlsignal AbstractSeries::onVisibleChanged()
109 110 Emitted when the series visibility changes.
110 111 */
111 112
112 113 /*!
113 114 \property QAbstractSeries::opacity
114 115 \brief The opacity of the series.
115 116 By default the opacity is 1.0. The valid values range from 0.0 (transparent) to 1.0 (opaque).
116 117 */
117 118 /*!
118 119 \qmlproperty real AbstractSeries::opacity
119 120 The opacity of the series. By default the opacity is 1.0.
120 121 The valid values range from 0.0 (transparent) to 1.0 (opaque).
121 122 */
122 123
123 124 /*!
124 125 \fn void QAbstractSeries::opacityChanged()
125 126 Emitted when the opacity of the series changes.
126 127 */
127 128 /*!
128 129 \qmlsignal AbstractSeries::onOpacityChanged()
129 130 Emitted when the opacity of the series changes.
130 131 */
131 132
132 133 /*!
133 134 \internal
134 135 \brief Constructs ChartSeries object with \a parent.
135 136 */
136 137 QAbstractSeries::QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent) :
137 138 QObject(parent),
138 139 d_ptr(&d)
139 140 {
140 141 }
141 142
142 143 /*!
143 144 \brief Virtual destructor for the chart series.
144 145 */
145 146 QAbstractSeries::~QAbstractSeries()
146 147 {
147 148 if (d_ptr->m_chart)
148 149 qFatal("Still binded series detected !");
149 150 }
150 151
151 152 void QAbstractSeries::setName(const QString &name)
152 153 {
153 154 if (name != d_ptr->m_name) {
154 155 d_ptr->m_name = name;
155 156 emit nameChanged();
156 157 }
157 158 }
158 159
159 160 QString QAbstractSeries::name() const
160 161 {
161 162 return d_ptr->m_name;
162 163 }
163 164
164 165 /*!
165 166 Sets the visibility of series to \a visible
166 167 */
167 168 void QAbstractSeries::setVisible(bool visible)
168 169 {
169 170 if (visible != d_ptr->m_visible) {
170 171 d_ptr->m_visible = visible;
171 172 emit visibleChanged();
172 173 }
173 174 }
174 175
175 176 /*!
176 177 Returns the visibility of series
177 178 */
178 179 bool QAbstractSeries::isVisible() const
179 180 {
180 181 return d_ptr->m_visible;
181 182 }
182 183
183 184 qreal QAbstractSeries::opacity() const
184 185 {
185 186 return d_ptr->m_opacity;
186 187 }
187 188
188 189 void QAbstractSeries::setOpacity(qreal opacity)
189 190 {
190 191 if (opacity != d_ptr->m_opacity) {
191 192 d_ptr->m_opacity = opacity;
192 193 emit opacityChanged();
193 194 }
194 195 }
195 196
196 197 /*!
197 198 \brief Returns the chart where series belongs to.
198 199
199 200 Set automatically when the series is added to the chart
200 201 and unset when the series is removed from the chart.
201 202 */
202 203 QChart *QAbstractSeries::chart() const
203 204 {
204 205 return d_ptr->m_chart;
205 206 }
206 207
207 208 /*!
208 209 \brief Sets the visibility of the series to true
209 210
210 211 \sa setVisible(), isVisible()
211 212 */
212 213 void QAbstractSeries::show()
213 214 {
214 215 setVisible(true);
215 216 }
216 217
217 218 /*!
218 219 \brief Sets the visibility of the series to false
219 220
220 221 \sa setVisible(), isVisible()
221 222 */
222 223 void QAbstractSeries::hide()
223 224 {
224 225 setVisible(false);
225 226 }
226 227
227 228 /*!
228 229 Attach \a axis to the series.
229 230 \return true if the axis was attached successfully, false otherwise.
230 231 \sa QChart::addAxis(), QChart::createDefaultAxes()
231 232 */
232 233 bool QAbstractSeries::attachAxis(QAbstractAxis* axis)
233 234 {
234 235 if(d_ptr->m_chart) {
235 236 return d_ptr->m_chart->d_ptr->m_dataset->attachAxis(this, axis);
236 237 } else {
237 238 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
238 239 return false;
239 240 }
240 241 }
241 242
242 243 /*!
243 244 Detach \a axis from the series.
244 245 \return true if the axis was detached successfully, false otherwise.
245 246 \sa QChart::removeAxis()
246 247 */
247 248 bool QAbstractSeries::detachAxis(QAbstractAxis* axis)
248 249 {
249 250 if(d_ptr->m_chart) {
250 251 return d_ptr->m_chart->d_ptr->m_dataset->detachAxis(this, axis);
251 252 }
252 253 else {
253 254 qWarning()<<"Series not in the chart. Please addSeries to chart first.";
254 255 return false;
255 256 }
256 257 }
257 258
258 259 /*!
259 260 Returns the list of axes attached to the series. Usually there is an x-axis and a y-axis attached to a series, except
260 261 in case of a QPieSeries, which does not have any axes attached.
261 262 \sa attachAxis(), detachAxis()
262 263 */
263 264 QList<QAbstractAxis*> QAbstractSeries::attachedAxes()
264 265 {
265 266 return d_ptr->m_axes;
266 267 }
267 268
268 269 ///////////////////////////////////////////////////////////////////////////////////////////////////
269 270
270 271 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries *q)
271 272 : q_ptr(q),
272 273 m_chart(0),
273 274 m_item(0),
274 275 m_domain(new XYDomain()),
275 276 m_visible(true),
276 277 m_opacity(1.0)
277 278 {
278 279 }
279 280
280 281 QAbstractSeriesPrivate::~QAbstractSeriesPrivate()
281 282 {
282 283 }
283 284
284 285 void QAbstractSeriesPrivate::setDomain(AbstractDomain* domain)
285 286 {
286 287 Q_ASSERT(domain);
287 288 if(m_domain.data()!=domain) {
288 289 if(!m_item.isNull()) QObject::disconnect(m_domain.data(), SIGNAL(updated()), m_item.data(), SLOT(handleDomainUpdated()));
289 290 m_domain.reset(domain);
290 291 if(!m_item.isNull()) {
291 292 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
292 293 m_item->handleDomainUpdated();
293 294 }
294 295 }
295 296 }
296 297
297 298 void QAbstractSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
298 299 {
299 300 Q_ASSERT(!m_item.isNull());
300 301 Q_UNUSED(parent);
301 302 QObject::connect(m_domain.data(), SIGNAL(updated()),m_item.data(), SLOT(handleDomainUpdated()));
302 303 }
303 304
304 305 void QAbstractSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
305 306 {
306 307 Q_UNUSED(options);
307 308 }
308 309
309 310 #include "moc_qabstractseries.cpp"
310 311 #include "moc_qabstractseries_p.cpp"
311 312
312 313 QTCOMMERCIALCHART_END_NAMESPACE
313 314
314 315
@@ -1,358 +1,389
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "mainwidget.h"
22 22 #include "customtablemodel.h"
23 23 #include <QVBoxPlotModelMapper>
24 24 #include <QTableView>
25 25 #include <QHeaderView>
26 26 #include <QChartView>
27 27 #include <QBoxPlotSeries>
28 28 #include <QBoxSet>
29 29 #include <QLegend>
30 30 #include <QBarCategoryAxis>
31 31 #include <QBrush>
32 32 #include <QColor>
33 33 #include <QPushButton>
34 34 #include <QComboBox>
35 35 #include <QSpinBox>
36 36 #include <QCheckBox>
37 37 #include <QGridLayout>
38 38 #include <QHBoxLayout>
39 39 #include <QLabel>
40 40 #include <QSpacerItem>
41 41 #include <QMessageBox>
42 42 #include <cmath>
43 43 #include <QDebug>
44 44 #include <QStandardItemModel>
45 45 #include <QBarCategoryAxis>
46 46
47 47
48 48 QTCOMMERCIALCHART_USE_NAMESPACE
49 49
50 50 QString addCategories[] = {"Jul", "Aug", "Sep", "Nov", "Dec"};
51 51
52 52 MainWidget::MainWidget(QWidget *parent) :
53 53 QWidget(parent),
54 54 m_chart(0),
55 55 rowPos(0),
56 56 nSeries(0),
57 57 nNewBoxes(0)
58 58 {
59 59 m_chart = new QChart();
60 60
61 61 // Grid layout for the controls for configuring the chart widget
62 62 QGridLayout *grid = new QGridLayout();
63 63
64 64 // Create add a series button
65 65 QPushButton *addSeriesButton = new QPushButton("Add a series");
66 66 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
67 67 grid->addWidget(addSeriesButton, rowPos++, 1);
68 68
69 69 // Create remove a series button
70 70 QPushButton *removeSeriesButton = new QPushButton("Remove a series");
71 71 connect(removeSeriesButton, SIGNAL(clicked()), this, SLOT(removeSeries()));
72 72 grid->addWidget(removeSeriesButton, rowPos++, 1);
73 73
74 74 // Create add a single box button
75 75 QPushButton *addBoxButton = new QPushButton("Add a box");
76 76 connect(addBoxButton, SIGNAL(clicked()), this, SLOT(addBox()));
77 77 grid->addWidget(addBoxButton, rowPos++, 1);
78 78
79 79 // Create insert a box button
80 80 QPushButton *insertBoxButton = new QPushButton("Insert a box");
81 81 connect(insertBoxButton, SIGNAL(clicked()), this, SLOT(insertBox()));
82 82 grid->addWidget(insertBoxButton, rowPos++, 1);
83 83
84 84 // Create add a single box button
85 85 QPushButton *removeBoxButton = new QPushButton("Remove a box");
86 86 connect(removeBoxButton, SIGNAL(clicked()), this, SLOT(removeBox()));
87 87 grid->addWidget(removeBoxButton, rowPos++, 1);
88 88
89 89 // Create clear button
90 90 QPushButton *clearButton = new QPushButton("Clear");
91 91 connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
92 92 grid->addWidget(clearButton, rowPos++, 1);
93 93
94 94 // Create set brush button
95 95 QPushButton *setBrushButton = new QPushButton("Set brush");
96 96 connect(setBrushButton, SIGNAL(clicked()), this, SLOT(setBrush()));
97 97 grid->addWidget(setBrushButton, rowPos++, 1);
98 98
99 99 initThemeCombo(grid);
100 100 initCheckboxes(grid);
101 101
102 102 m_model = new CustomTableModel;
103 103 QTableView *tableView = new QTableView;
104 104 tableView->setModel(m_model);
105 105 tableView->setMaximumWidth(200);
106 106 grid->addWidget(tableView, rowPos++, 0, 3, 2, Qt::AlignLeft);
107 107 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
108 108 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
109 109 tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
110 110 #else
111 111 tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
112 112 tableView->verticalHeader()->setResizeMode(QHeaderView::Stretch);
113 113 #endif
114 114
115 115 // add row with empty label to make all the other rows static
116 116 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
117 117 grid->setRowStretch(grid->rowCount() - 1, 1);
118 118
119 119 // Create chart view with the chart
120 120 m_chartView = new QChartView(m_chart, this);
121 121 //m_chartView->setRubberBand(QChartView::HorizonalRubberBand);
122 122
123 123 // Another grid layout as a main layout
124 124 QGridLayout *mainLayout = new QGridLayout();
125 125 mainLayout->addLayout(grid, 0, 0);
126 126 mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
127 127 setLayout(mainLayout);
128 128
129 129 legendToggled(false);
130 130 animationToggled(false);
131 131 }
132 132
133 133 // Combo box for selecting theme
134 134 void MainWidget::initThemeCombo(QGridLayout *grid)
135 135 {
136 136 QComboBox *chartTheme = new QComboBox();
137 137 chartTheme->addItem("Default");
138 138 chartTheme->addItem("Light");
139 139 chartTheme->addItem("Blue Cerulean");
140 140 chartTheme->addItem("Dark");
141 141 chartTheme->addItem("Brown Sand");
142 142 chartTheme->addItem("Blue NCS");
143 143 chartTheme->addItem("High Contrast");
144 144 chartTheme->addItem("Blue Icy");
145 145 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
146 146 this, SLOT(changeChartTheme(int)));
147 147 grid->addWidget(new QLabel("Chart theme:"), rowPos, 0);
148 148 grid->addWidget(chartTheme, rowPos++, 1);
149 149 }
150 150
151 151 // Different check boxes for customizing chart
152 152 void MainWidget::initCheckboxes(QGridLayout *grid)
153 153 {
154 154 QCheckBox *animationCheckBox = new QCheckBox("Animation");
155 155 connect(animationCheckBox, SIGNAL(toggled(bool)), this, SLOT(animationToggled(bool)));
156 156 animationCheckBox->setChecked(false);
157 157 grid->addWidget(animationCheckBox, rowPos++, 0);
158 158
159 159 QCheckBox *legendCheckBox = new QCheckBox("Legend");
160 160 connect(legendCheckBox, SIGNAL(toggled(bool)), this, SLOT(legendToggled(bool)));
161 161 legendCheckBox->setChecked(false);
162 162 grid->addWidget(legendCheckBox, rowPos++, 0);
163 163
164 164 QCheckBox *titleCheckBox = new QCheckBox("Title");
165 165 connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
166 166 titleCheckBox->setChecked(false);
167 167 grid->addWidget(titleCheckBox, rowPos++, 0);
168 168
169 169 QCheckBox *modelMapperCheckBox = new QCheckBox("Use model mapper");
170 170 connect(modelMapperCheckBox, SIGNAL(toggled(bool)), this, SLOT(modelMapperToggled(bool)));
171 171 modelMapperCheckBox->setChecked(false);
172 172 grid->addWidget(modelMapperCheckBox, rowPos++, 0);
173 173
174 174 }
175 175
176 176 void MainWidget::addSeries()
177 177 {
178 178 qDebug() << "BoxPlotTester::MainWidget::addSeries()";
179 179
180 180 if (nSeries > 9)
181 181 return;
182 182
183 183 // Initial data
184 184 //![1]
185 185 QBoxSet *set0 = new QBoxSet();
186 186 QBoxSet *set1 = new QBoxSet();
187 187 QBoxSet *set2 = new QBoxSet();
188 188 QBoxSet *set3 = new QBoxSet();
189 189 QBoxSet *set4 = new QBoxSet();
190 190 QBoxSet *set5 = new QBoxSet();
191 191
192 192 // low bot med top upp
193 193 *set0 << 3 << 4 << 4.4 << 6 << 7;
194 194 *set1 << 5 << 6 << 7.5 << 8 << 12;
195 195 *set2 << 3 << 5 << 5.7 << 8 << 9;
196 196 *set3 << 5 << 6 << 6.8 << 7 << 8;
197 197 *set4 << 4 << 5 << 5.2 << 6 << 7;
198 198 *set5 << 4 << 7 << 8.2 << 9 << 10;
199 199
200 200 m_series[nSeries] = new QBoxPlotSeries();
201 201 m_series[nSeries]->append(set0);
202 202 m_series[nSeries]->append(set1);
203 203 m_series[nSeries]->append(set2);
204 204 m_series[nSeries]->append(set3);
205 205 m_series[nSeries]->append(set4);
206 206 m_series[nSeries]->append(set5);
207 207 m_series[nSeries]->setName("Box & Whiskers");
208 208
209 connect(m_series[nSeries], SIGNAL(clicked(QBoxSet*)), this, SLOT(boxClicked(QBoxSet*)));
210 connect(m_series[nSeries], SIGNAL(hovered(bool, QBoxSet*)), this, SLOT(boxHovered(bool, QBoxSet*)));
211 connect(set1, SIGNAL(clicked()), this, SLOT(singleBoxClicked()));
212 connect(set2, SIGNAL(hovered(bool)), this, SLOT(singleBoxHovered(bool)));
213
209 214 m_chart->addSeries(m_series[nSeries]);
210 215
211 216 if (nSeries == 0) {
212 217 QStringList categories;
213 218 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
214 219 m_axis = new QBarCategoryAxis();
215 220 m_axis->append(categories);
216 221 m_chart->createDefaultAxes();
217 222 m_chart->setAxisX(m_axis, m_series[nSeries]);
218 223 }
219 224
220 225 nSeries++;
221 226 }
222 227
223 228 void MainWidget::removeSeries()
224 229 {
225 230 qDebug() << "BoxPlotTester::MainWidget::removeSeries()";
226 231
227 232 if (nSeries > 0) {
228 233 nSeries--;
229 234 m_chart->removeSeries(m_series[nSeries]);
230 235 delete m_series[nSeries];
231 236 } else {
232 237 qDebug() << "Create a series first";
233 238 }
234 239 }
235 240
236 241 void MainWidget::addBox()
237 242 {
238 243 qDebug() << "BoxPlotTester::MainWidget::addBox()";
239 244
240 245 if (nSeries > 0) {
241 246 QBoxSet *newSet = new QBoxSet();
242 247 *newSet << 5 << 6 << 6.8 << 7 << 8;
243 248
244 249 m_series[0]->append(newSet);
245 250
246 251 m_axis->append(addCategories[nNewBoxes]);
247 252
248 253 nNewBoxes++;
249 254 }
250 255 }
251 256
252 257 void MainWidget::insertBox()
253 258 {
254 259 qDebug() << "BoxPlotTester::MainWidget::insertBox()";
255 260
256 261 if (nSeries > 0) {
257 262 QBoxSet *newSet = new QBoxSet();
258 263 *newSet << 2 << 6 << 6.8 << 7 << 10;
259 264
260 265 m_series[0]->insert(1, newSet);
261 266
262 267 m_axis->append(addCategories[nNewBoxes]);
263 268
264 269 nNewBoxes++;
265 270 }
266 271 }
267 272
268 273 void MainWidget::removeBox()
269 274 {
270 275 qDebug() << "BoxPlotTester::MainWidget::removeBox";
271 276
272 277 if (nSeries > 0) {
273 278 QList<QBoxSet *> sets = m_series[0]->boxSets();
274 279 m_series[0]->remove(sets.at(m_series[0]->count() - 3));
275 280 } else {
276 281 qDebug() << "Create a series first";
277 282 }
278 283 }
279 284
280 285 void MainWidget::clear()
281 286 {
282 287 qDebug() << "BoxPlotTester::MainWidget::clear";
283 288
284 289 if (nSeries > 0) {
285 290 m_series[0]->clear();
286 291 } else {
287 292 qDebug() << "Create a series first";
288 293 }
289 294 }
290 295
291 296 void MainWidget::setBrush()
292 297 {
293 298 qDebug() << "BoxPlotTester::MainWidget::setBrush";
294 299
295 300 if (nSeries > 0) {
296 301 QList<QBoxSet *> sets = m_series[0]->boxSets();
297 302 sets.at(1)->setBrush(QBrush(QColor(Qt::yellow)));
298 303 } else {
299 304 qDebug() << "Create a series first";
300 305 }
301 306 }
302 307
303 308 void MainWidget::animationToggled(bool enabled)
304 309 {
305 310 qDebug() << "BoxPlotTester::Animation toggled to " << enabled;
306 311 if (enabled)
307 312 m_chart->setAnimationOptions(QChart::SeriesAnimations);
308 313 else
309 314 m_chart->setAnimationOptions(QChart::NoAnimation);
310 315 }
311 316
312 317 void MainWidget::legendToggled(bool enabled)
313 318 {
314 319 qDebug() << "BoxPlotTester::Legend toggled to " << enabled;
315 320 m_chart->legend()->setVisible(enabled);
316 321 if (enabled)
317 322 m_chart->legend()->setAlignment(Qt::AlignBottom);
318 323 }
319 324
320 325 void MainWidget::titleToggled(bool enabled)
321 326 {
322 327 qDebug() << "BoxPlotTester::Title toggled to " << enabled;
323 328 if (enabled)
324 329 m_chart->setTitle("Simple boxplotchart example");
325 330 else
326 331 m_chart->setTitle("");
327 332 }
328 333
329 334 void MainWidget::modelMapperToggled(bool enabled)
330 335 {
331 336 if (enabled) {
332 337 m_series[nSeries] = new QBoxPlotSeries();
333 338
334 339 int first = 0;
335 340 int count = 5;
336 341 QVBoxPlotModelMapper *mapper = new QVBoxPlotModelMapper(this);
337 342 mapper->setFirstBoxSetColumn(0);
338 343 mapper->setLastBoxSetColumn(5);
339 344 mapper->setFirstRow(first);
340 345 mapper->setRowCount(count);
341 346 mapper->setSeries(m_series[nSeries]);
342 347 mapper->setModel(m_model);
343 348 m_chart->addSeries(m_series[nSeries]);
344 349
345 350 nSeries++;
346 351 } else {
347 352 removeSeries();
348 353 }
349 354 }
350 355
351 356 void MainWidget::changeChartTheme(int themeIndex)
352 357 {
353 358 qDebug() << "BoxPlotTester::changeChartTheme: " << themeIndex;
354 359 if (themeIndex == 0)
355 360 m_chart->setTheme(QChart::ChartThemeLight);
356 361 else
357 362 m_chart->setTheme((QChart::ChartTheme) (themeIndex - 1));
358 363 }
364
365 void MainWidget::boxClicked(QBoxSet *set)
366 {
367 qDebug() << "boxClicked, median = " << set->median();
368 }
369
370 void MainWidget::boxHovered(bool state, QBoxSet *set)
371 {
372 if (state)
373 qDebug() << "box median " << set->median() << " hover started";
374 else
375 qDebug() << "box median " << set->median() << " hover ended";
376 }
377
378 void MainWidget::singleBoxClicked()
379 {
380 qDebug() << "singleBoxClicked";
381 }
382
383 void MainWidget::singleBoxHovered(bool state)
384 {
385 if (state)
386 qDebug() << "single box hover started";
387 else
388 qDebug() << "single box hover ended";
389 }
@@ -1,74 +1,79
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef MAINWIDGET_H
22 22 #define MAINWIDGET_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "qchart.h"
26 26 #include "qchartview.h"
27 27 #include "customtablemodel.h"
28 28 #include <QWidget>
29 29 #include <QBoxPlotSeries>
30 30 #include <QBarCategoryAxis>
31 #include <QBoxSet>
31 32
32 33 class QGridLayout;
33 34
34 35 QTCOMMERCIALCHART_USE_NAMESPACE
35 36
36 37 class MainWidget : public QWidget
37 38 {
38 39 Q_OBJECT
39 40 public:
40 41 explicit MainWidget(QWidget *parent = 0);
41 42
42 43 signals:
43 44
44 45 private:
45 46 void initThemeCombo(QGridLayout *grid);
46 47 void initCheckboxes(QGridLayout *grid);
47 48
48 49 private slots:
49 50 void addSeries();
50 51 void removeSeries();
51 52 void addBox();
52 53 void insertBox();
53 54 void removeBox();
54 55 void clear();
55 56 void setBrush();
56 57 void animationToggled(bool enabled);
57 58 void legendToggled(bool enabled);
58 59 void titleToggled(bool enabled);
59 60 void modelMapperToggled(bool enabled);
60 61 void changeChartTheme(int themeIndex);
62 void boxClicked(QBoxSet *set);
63 void boxHovered(bool state, QBoxSet *set);
64 void singleBoxClicked();
65 void singleBoxHovered(bool state);
61 66
62 67 private:
63 68 QChart *m_chart;
64 69 QChartView *m_chartView;
65 70 QGridLayout *m_scatterLayout;
66 71 QBarCategoryAxis *m_axis;
67 72 CustomTableModel *m_model;
68 73 int rowPos;
69 74 int nSeries;
70 75 int nNewBoxes;
71 76 QBoxPlotSeries *m_series[10];
72 77 };
73 78
74 79 #endif // MAINWIDGET_H
General Comments 0
You need to be logged in to leave comments. Login now