##// END OF EJS Templates
Update candlestick chart model mappers API...
Alexander Mishin -
r2897:f5164ec8f20d dev
parent child
Show More
@@ -1,347 +1,347
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QCandlestickSeries>
31 31 #include <QtCharts/QCandlestickSet>
32 32 #include <private/candlestickchartitem_p.h>
33 33 #include <private/candlestick_p.h>
34 34 #include <private/candlestickdata_p.h>
35 35 #include <private/qcandlestickseries_p.h>
36 36 #include <private/candlestickanimation_p.h>
37 37
38 38 QT_CHARTS_BEGIN_NAMESPACE
39 39
40 40 CandlestickChartItem::CandlestickChartItem(QCandlestickSeries *series, QGraphicsItem *item)
41 41 : ChartItem(series->d_func(), item),
42 42 m_series(series),
43 43 m_seriesIndex(0),
44 44 m_seriesCount(0),
45 45 m_timePeriod(0.0),
46 46 m_animation(nullptr)
47 47 {
48 48 connect(series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)),
49 49 this, SLOT(handleCandlestickSetsAdd(QList<QCandlestickSet *>)));
50 50 connect(series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet *>)),
51 51 this, SLOT(handleCandlestickSetsRemove(QList<QCandlestickSet *>)));
52 52
53 53 connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleCandlesticksUpdated()));
54 54 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutUpdated()));
55 55 connect(series->d_func(), SIGNAL(updatedCandlesticks()),
56 56 this, SLOT(handleCandlesticksUpdated()));
57 57
58 58 setZValue(ChartPresenter::CandlestickSeriesZValue);
59 59
60 handleCandlestickSetsAdd(m_series->candlestickSets());
60 handleCandlestickSetsAdd(m_series->sets());
61 61 }
62 62
63 63 CandlestickChartItem::~CandlestickChartItem()
64 64 {
65 65 }
66 66
67 67 void CandlestickChartItem::setAnimation(CandlestickAnimation *animation)
68 68 {
69 69 m_animation = animation;
70 70
71 71 if (m_animation) {
72 72 foreach (Candlestick *item, m_candlesticks.values())
73 73 m_animation->addCandlestick(item);
74 74
75 75 handleDomainUpdated();
76 76 }
77 77 }
78 78
79 79 QRectF CandlestickChartItem::boundingRect() const
80 80 {
81 81 return m_boundingRect;
82 82 }
83 83
84 84 void CandlestickChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
85 85 QWidget *widget)
86 86 {
87 87 Q_UNUSED(painter);
88 88 Q_UNUSED(option);
89 89 Q_UNUSED(widget);
90 90 }
91 91
92 92 void CandlestickChartItem::handleDomainUpdated()
93 93 {
94 94 if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0))
95 95 return;
96 96
97 97 // Set bounding rectangle to same as domain size. Add one pixel at the top (-1.0) and the bottom
98 98 // as 0.0 would snip a bit off from the wick at the grid line.
99 99 m_boundingRect.setRect(0.0, -1.0, domain()->size().width(), domain()->size().height() + 1.0);
100 100
101 101 foreach (Candlestick *item, m_candlesticks.values()) {
102 102 item->updateGeometry(domain());
103 103
104 104 if (m_animation)
105 105 presenter()->startAnimation(m_animation->candlestickAnimation(item));
106 106 }
107 107 }
108 108
109 109 void CandlestickChartItem::handleLayoutUpdated()
110 110 {
111 111 bool timestampChanged = false;
112 112 foreach (QCandlestickSet *set, m_candlesticks.keys()) {
113 113 qreal oldTimestamp = m_candlesticks.value(set)->m_data.m_timestamp;
114 114 qreal newTimestamp = set->timestamp();
115 115 if (Q_UNLIKELY(oldTimestamp != newTimestamp)) {
116 116 removeTimestamp(oldTimestamp);
117 117 addTimestamp(newTimestamp);
118 118 timestampChanged = true;
119 119 }
120 120 }
121 121 if (timestampChanged)
122 122 updateTimePeriod();
123 123
124 124 foreach (Candlestick *item, m_candlesticks.values()) {
125 125 if (m_animation)
126 126 m_animation->setAnimationStart(item);
127 127
128 128 item->setTimePeriod(m_timePeriod);
129 129 item->setMaximumColumnWidth(m_series->maximumColumnWidth());
130 130 item->setMinimumColumnWidth(m_series->minimumColumnWidth());
131 131 item->setBodyWidth(m_series->bodyWidth());
132 132 item->setCapsWidth(m_series->capsWidth());
133 133
134 134 bool dirty = updateCandlestickGeometry(item, item->m_data.m_index);
135 135 if (dirty && m_animation)
136 136 presenter()->startAnimation(m_animation->candlestickChangeAnimation(item));
137 137 else
138 138 item->updateGeometry(domain());
139 139 }
140 140 }
141 141
142 142 void CandlestickChartItem::handleCandlesticksUpdated()
143 143 {
144 144 foreach (QCandlestickSet *set, m_candlesticks.keys())
145 145 updateCandlestickAppearance(m_candlesticks.value(set), set);
146 146 }
147 147
148 148 void CandlestickChartItem::handleCandlestickSeriesChange()
149 149 {
150 150 int seriesIndex = 0;
151 151 int seriesCount = 0;
152 152
153 153 int index = 0;
154 154 foreach (QAbstractSeries *series, m_series->chart()->series()) {
155 155 if (series->type() == QAbstractSeries::SeriesTypeCandlestick) {
156 156 if (m_series == static_cast<QCandlestickSeries *>(series))
157 157 seriesIndex = index;
158 158 index++;
159 159 }
160 160 }
161 161 seriesCount = index;
162 162
163 163 bool changed;
164 164 if ((m_seriesIndex != seriesIndex) || (m_seriesCount != seriesCount))
165 165 changed = true;
166 166 else
167 167 changed = false;
168 168
169 169 if (changed) {
170 170 m_seriesIndex = seriesIndex;
171 171 m_seriesCount = seriesCount;
172 172 handleDataStructureChanged();
173 173 }
174 174 }
175 175
176 176 void CandlestickChartItem::handleCandlestickSetsAdd(const QList<QCandlestickSet *> &sets)
177 177 {
178 178 foreach (QCandlestickSet *set, sets) {
179 179 Candlestick *item = m_candlesticks.value(set, 0);
180 180 if (item) {
181 181 qWarning() << "There is already a candlestick for this set in the hash";
182 182 continue;
183 183 }
184 184
185 185 item = new Candlestick(set, domain(), this);
186 186 m_candlesticks.insert(set, item);
187 187 addTimestamp(set->timestamp());
188 188
189 189 connect(item, SIGNAL(clicked(QCandlestickSet *)),
190 190 m_series, SIGNAL(clicked(QCandlestickSet *)));
191 191 connect(item, SIGNAL(hovered(bool, QCandlestickSet *)),
192 192 m_series, SIGNAL(hovered(bool, QCandlestickSet *)));
193 193 connect(item, SIGNAL(pressed(QCandlestickSet *)),
194 194 m_series, SIGNAL(pressed(QCandlestickSet *)));
195 195 connect(item, SIGNAL(released(QCandlestickSet *)),
196 196 m_series, SIGNAL(released(QCandlestickSet *)));
197 197 connect(item, SIGNAL(doubleClicked(QCandlestickSet *)),
198 198 m_series, SIGNAL(doubleClicked(QCandlestickSet *)));
199 199 connect(item, SIGNAL(clicked(QCandlestickSet *)), set, SIGNAL(clicked()));
200 200 connect(item, SIGNAL(hovered(bool, QCandlestickSet *)), set, SIGNAL(hovered(bool)));
201 201 connect(item, SIGNAL(pressed(QCandlestickSet *)), set, SIGNAL(pressed()));
202 202 connect(item, SIGNAL(released(QCandlestickSet *)), set, SIGNAL(released()));
203 203 connect(item, SIGNAL(doubleClicked(QCandlestickSet *)), set, SIGNAL(doubleClicked()));
204 204 }
205 205
206 206 handleDataStructureChanged();
207 207 }
208 208
209 209 void CandlestickChartItem::handleCandlestickSetsRemove(const QList<QCandlestickSet *> &sets)
210 210 {
211 211 foreach (QCandlestickSet *set, sets) {
212 212 Candlestick *item = m_candlesticks.value(set);
213 213
214 214 m_candlesticks.remove(set);
215 215 removeTimestamp(set->timestamp());
216 216
217 217 if (m_animation) {
218 218 ChartAnimation *animation = m_animation->candlestickAnimation(item);
219 219 if (animation) {
220 220 animation->stop();
221 221 delete animation;
222 222 }
223 223 }
224 224
225 225 delete item;
226 226 }
227 227
228 228 handleDataStructureChanged();
229 229 }
230 230
231 231 void CandlestickChartItem::handleDataStructureChanged()
232 232 {
233 233 updateTimePeriod();
234 234
235 235 for (int i = 0; i < m_series->count(); ++i) {
236 QCandlestickSet *set = m_series->candlestickSets().at(i);
236 QCandlestickSet *set = m_series->sets().at(i);
237 237 Candlestick *item = m_candlesticks.value(set);
238 238
239 239 updateCandlestickGeometry(item, i);
240 240 updateCandlestickAppearance(item, set);
241 241
242 242 item->updateGeometry(domain());
243 243
244 244 if (m_animation)
245 245 m_animation->addCandlestick(item);
246 246 }
247 247
248 248 handleDomainUpdated();
249 249 }
250 250
251 251 bool CandlestickChartItem::updateCandlestickGeometry(Candlestick *item, int index)
252 252 {
253 253 bool changed = false;
254 254
255 QCandlestickSet *set = m_series->candlestickSets().at(index);
255 QCandlestickSet *set = m_series->sets().at(index);
256 256 CandlestickData &data = item->m_data;
257 257
258 258 if ((data.m_open != set->open())
259 259 || (data.m_high != set->high())
260 260 || (data.m_low != set->low())
261 261 || (data.m_close != set->close())) {
262 262 changed = true;
263 263 }
264 264
265 265 data.m_timestamp = set->timestamp();
266 266 data.m_open = set->open();
267 267 data.m_high = set->high();
268 268 data.m_low = set->low();
269 269 data.m_close = set->close();
270 270 data.m_index = index;
271 271
272 272 data.m_maxX = domain()->maxX();
273 273 data.m_minX = domain()->minX();
274 274 data.m_maxY = domain()->maxY();
275 275 data.m_minY = domain()->minY();
276 276
277 277 data.m_series = m_series;
278 278 data.m_seriesIndex = m_seriesIndex;
279 279 data.m_seriesCount = m_seriesCount;
280 280
281 281 return changed;
282 282 }
283 283
284 284 void CandlestickChartItem::updateCandlestickAppearance(Candlestick *item, QCandlestickSet *set)
285 285 {
286 286 item->setTimePeriod(m_timePeriod);
287 287 item->setMaximumColumnWidth(m_series->maximumColumnWidth());
288 288 item->setMinimumColumnWidth(m_series->minimumColumnWidth());
289 289 item->setBodyWidth(m_series->bodyWidth());
290 290 item->setBodyOutlineVisible(m_series->bodyOutlineVisible());
291 291 item->setCapsWidth(m_series->capsWidth());
292 292 item->setCapsVisible(m_series->capsVisible());
293 293 item->setIncreasingColor(m_series->increasingColor());
294 294 item->setDecreasingColor(m_series->decreasingColor());
295 295
296 296 // Set the decorative issues for the candlestick so that
297 297 // the brush and pen already defined for the set are kept.
298 298 if (set->brush() == Qt::NoBrush)
299 299 item->setBrush(m_series->brush());
300 300 else
301 301 item->setBrush(set->brush());
302 302
303 303 if (set->pen() == Qt::NoPen)
304 304 item->setPen(m_series->pen());
305 305 else
306 306 item->setPen(set->pen());
307 307 }
308 308
309 309 void CandlestickChartItem::addTimestamp(qreal timestamp)
310 310 {
311 311 int index = 0;
312 312 for (int i = m_timestamps.count() - 1; i >= 0; --i) {
313 313 if (timestamp > m_timestamps.at(i)) {
314 314 index = i + 1;
315 315 break;
316 316 }
317 317 }
318 318 m_timestamps.insert(index, timestamp);
319 319 }
320 320
321 321 void CandlestickChartItem::removeTimestamp(qreal timestamp)
322 322 {
323 323 m_timestamps.removeOne(timestamp);
324 324 }
325 325
326 326 void CandlestickChartItem::updateTimePeriod()
327 327 {
328 328 if (m_timestamps.count() == 0) {
329 329 m_timePeriod = 0;
330 330 return;
331 331 }
332 332
333 333 if (m_timestamps.count() == 1) {
334 334 m_timePeriod = qAbs(domain()->maxX() - domain()->minX());
335 335 return;
336 336 }
337 337
338 338 qreal timePeriod = qAbs(m_timestamps.at(1) - m_timestamps.at(0));
339 339 for (int i = 1; i < m_timestamps.count(); ++i) {
340 340 timePeriod = qMin(timePeriod, qAbs(m_timestamps.at(i) - m_timestamps.at(i - 1)));
341 341 }
342 342 m_timePeriod = timePeriod;
343 343 }
344 344
345 345 #include "moc_candlestickchartitem_p.cpp"
346 346
347 347 QT_CHARTS_END_NAMESPACE
@@ -1,706 +1,706
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QCandlestickModelMapper>
31 31 #include <QtCharts/QCandlestickSeries>
32 32 #include <QtCharts/QCandlestickSet>
33 33 #include <QtCore/QAbstractItemModel>
34 34 #include <private/qcandlestickmodelmapper_p.h>
35 35
36 36 QT_CHARTS_BEGIN_NAMESPACE
37 37
38 38 /*!
39 39 \class QCandlestickModelMapper
40 40 \since 5.8
41 41 \inmodule Qt Charts
42 42 \brief Abstract model mapper class for candlestick series.
43 43
44 44 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
45 45 series, creating a connection between a QCandlestickSeries and the model object. A model mapper
46 46 maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}.
47 47
48 48 \note The model used must support adding and removing rows/columns and modifying the data of the
49 49 cells.
50 50 */
51 51
52 52 /*!
53 53 \property QCandlestickModelMapper::model
54 54 \brief Defines the model that is used by the mapper.
55 55 */
56 56
57 57 /*!
58 58 \property QCandlestickModelMapper::series
59 59 \brief Defines the QCandlestickSeries object that is used by the mapper.
60 60
61 61 \note All data in the series is discarded when it is set to the mapper. When a new series is
62 62 specified, the old series is disconnected (preserving its data).
63 63 */
64 64
65 65 /*!
66 66 \fn Qt::Orientation QCandlestickModelMapper::orientation() const
67 67 Returns the orientation that is used when QCandlestickModelMapper accesses the model. This
68 68 determines whether the consecutive values of the set are read from rows (Qt::Horizontal) or from
69 69 columns (Qt::Vertical).
70 70 */
71 71
72 72 /*!
73 73 \fn void QCandlestickModelMapper::modelReplaced()
74 74 \brief Emitted when the model, to which the mapper is connected, has changed.
75 75 \sa model
76 76 */
77 77
78 78 /*!
79 79 \fn void QCandlestickModelMapper::seriesReplaced()
80 80 \brief Emitted when the series to which mapper is connected to has changed.
81 81 \sa series
82 82 */
83 83
84 84 /*!
85 85 Constructs a model mapper object as a child of \a parent.
86 86 */
87 87 QCandlestickModelMapper::QCandlestickModelMapper(QObject *parent)
88 88 : QObject(parent),
89 89 d_ptr(new QCandlestickModelMapperPrivate(this))
90 90 {
91 91 }
92 92
93 93 void QCandlestickModelMapper::setModel(QAbstractItemModel *model)
94 94 {
95 95 Q_D(QCandlestickModelMapper);
96 96
97 97 if (d->m_model == model)
98 98 return;
99 99
100 100 if (d->m_model)
101 101 disconnect(d->m_model, 0, d, 0);
102 102
103 103 d->m_model = model;
104 104 emit modelReplaced();
105 105
106 106 if (!d->m_model)
107 107 return;
108 108
109 109 d->initializeCandlestickFromModel();
110 110 // connect signals from the model
111 111 connect(d->m_model, SIGNAL(modelReset()), d, SLOT(initializeCandlestickFromModel()));
112 112 connect(d->m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
113 113 d, SLOT(modelDataUpdated(QModelIndex, QModelIndex)));
114 114 connect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)),
115 115 d, SLOT(modelHeaderDataUpdated(Qt::Orientation, int, int)));
116 116 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)),
117 117 d, SLOT(modelRowsInserted(QModelIndex, int, int)));
118 118 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
119 119 d, SLOT(modelRowsRemoved(QModelIndex, int, int)));
120 120 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)),
121 121 d, SLOT(modelColumnsInserted(QModelIndex, int, int)));
122 122 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
123 123 d, SLOT(modelColumnsRemoved(QModelIndex, int, int)));
124 124 connect(d->m_model, SIGNAL(destroyed()), d, SLOT(modelDestroyed()));
125 125 }
126 126
127 127 QAbstractItemModel *QCandlestickModelMapper::model() const
128 128 {
129 129 Q_D(const QCandlestickModelMapper);
130 130
131 131 return d->m_model;
132 132 }
133 133
134 134 void QCandlestickModelMapper::setSeries(QCandlestickSeries *series)
135 135 {
136 136 Q_D(QCandlestickModelMapper);
137 137
138 138 if (d->m_series == series)
139 139 return;
140 140
141 141 if (d->m_series)
142 142 disconnect(d->m_series, 0, d, 0);
143 143
144 144 d->m_series = series;
145 145 emit seriesReplaced();
146 146
147 147 if (!d->m_series)
148 148 return;
149 149
150 150 d->initializeCandlestickFromModel();
151 151 // connect the signals from the series
152 152 connect(d->m_series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)),
153 153 d, SLOT(candlestickSetsAdded(QList<QCandlestickSet *>)));
154 154 connect(d->m_series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet*>)),
155 155 d, SLOT(candlestickSetsRemoved(QList<QCandlestickSet *>)));
156 156 connect(d->m_series, SIGNAL(destroyed()), d, SLOT(seriesDestroyed()));
157 157 }
158 158
159 159 QCandlestickSeries *QCandlestickModelMapper::series() const
160 160 {
161 161 Q_D(const QCandlestickModelMapper);
162 162
163 163 return d->m_series;
164 164 }
165 165
166 166 /*!
167 167 Sets the row/column of the model that contains the \a timestamp values of the sets in the
168 168 series. Default value is -1 (invalid mapping).
169 169 */
170 170 void QCandlestickModelMapper::setTimestamp(int timestamp)
171 171 {
172 172 Q_D(QCandlestickModelMapper);
173 173
174 174 timestamp = qMax(timestamp, -1);
175 175
176 176 if (d->m_timestamp == timestamp)
177 177 return;
178 178
179 179 d->m_timestamp = timestamp;
180 180 emit d->timestampChanged();
181 181 d->initializeCandlestickFromModel();
182 182 }
183 183
184 184 /*!
185 185 Returns the row/column of the model that contains the timestamp values of the sets in the
186 186 series. Default value is -1 (invalid mapping).
187 187 */
188 188 int QCandlestickModelMapper::timestamp() const
189 189 {
190 190 Q_D(const QCandlestickModelMapper);
191 191
192 192 return d->m_timestamp;
193 193 }
194 194
195 195 /*!
196 196 Sets the row/column of the model that contains the \a open values of the sets in the series.
197 197 Default value is -1 (invalid mapping).
198 198 */
199 199 void QCandlestickModelMapper::setOpen(int open)
200 200 {
201 201 Q_D(QCandlestickModelMapper);
202 202
203 203 open = qMax(open, -1);
204 204
205 205 if (d->m_open == open)
206 206 return;
207 207
208 208 d->m_open = open;
209 209 emit d->openChanged();
210 210 d->initializeCandlestickFromModel();
211 211 }
212 212
213 213 /*!
214 214 Returns the row/column of the model that contains the open values of the sets in the series.
215 215 Default value is -1 (invalid mapping).
216 216 */
217 217 int QCandlestickModelMapper::open() const
218 218 {
219 219 Q_D(const QCandlestickModelMapper);
220 220
221 221 return d->m_open;
222 222 }
223 223
224 224 /*!
225 225 Sets the row/column of the model that contains the \a high values of the sets in the series.
226 226 Default value is -1 (invalid mapping).
227 227 */
228 228 void QCandlestickModelMapper::setHigh(int high)
229 229 {
230 230 Q_D(QCandlestickModelMapper);
231 231
232 232 high = qMax(high, -1);
233 233
234 234 if (d->m_high == high)
235 235 return;
236 236
237 237 d->m_high = high;
238 238 emit d->highChanged();
239 239 d->initializeCandlestickFromModel();
240 240 }
241 241
242 242 /*!
243 243 Returns the row/column of the model that contains the high values of the sets in the series.
244 244 Default value is -1 (invalid mapping).
245 245 */
246 246 int QCandlestickModelMapper::high() const
247 247 {
248 248 Q_D(const QCandlestickModelMapper);
249 249
250 250 return d->m_high;
251 251 }
252 252
253 253 /*!
254 254 Sets the row/column of the model that contains the \a low values of the sets in the series.
255 255 Default value is -1 (invalid mapping).
256 256 */
257 257 void QCandlestickModelMapper::setLow(int low)
258 258 {
259 259 Q_D(QCandlestickModelMapper);
260 260
261 261 low = qMax(low, -1);
262 262
263 263 if (d->m_low == low)
264 264 return;
265 265
266 266 d->m_low = low;
267 267 emit d->lowChanged();
268 268 d->initializeCandlestickFromModel();
269 269 }
270 270
271 271 /*!
272 272 Returns the row/column of the model that contains the low values of the sets in the series.
273 273 Default value is -1 (invalid mapping).
274 274 */
275 275 int QCandlestickModelMapper::low() const
276 276 {
277 277 Q_D(const QCandlestickModelMapper);
278 278
279 279 return d->m_low;
280 280 }
281 281
282 282 /*!
283 283 Sets the row/column of the model that contains the \a close values of the sets in the series.
284 284 Default value is -1 (invalid mapping).
285 285 */
286 286 void QCandlestickModelMapper::setClose(int close)
287 287 {
288 288 Q_D(QCandlestickModelMapper);
289 289
290 290 close = qMax(close, -1);
291 291
292 292 if (d->m_close == close)
293 293 return;
294 294
295 295 d->m_close = close;
296 296 emit d->closeChanged();
297 297 d->initializeCandlestickFromModel();
298 298 }
299 299
300 300 /*!
301 301 Returns the row/column of the model that contains the close values of the sets in the series.
302 302 Default value is -1 (invalid mapping).
303 303 */
304 304 int QCandlestickModelMapper::close() const
305 305 {
306 306 Q_D(const QCandlestickModelMapper);
307 307
308 308 return d->m_close;
309 309 }
310 310
311 311 /*!
312 312 Sets the section of the model that is used as the data source for the first candlestick set.
313 Parameter \a firstCandlestickSetSection specifies the section of the model. Default value is -1.
313 Parameter \a firstSetSection specifies the section of the model. Default value is -1.
314 314 */
315 void QCandlestickModelMapper::setFirstCandlestickSetSection(int firstCandlestickSetSection)
315 void QCandlestickModelMapper::setFirstSetSection(int firstSetSection)
316 316 {
317 317 Q_D(QCandlestickModelMapper);
318 318
319 firstCandlestickSetSection = qMax(firstCandlestickSetSection, -1);
319 firstSetSection = qMax(firstSetSection, -1);
320 320
321 if (d->m_firstCandlestickSetSection == firstCandlestickSetSection)
321 if (d->m_firstSetSection == firstSetSection)
322 322 return;
323 323
324 d->m_firstCandlestickSetSection = firstCandlestickSetSection;
325 emit d->firstCandlestickSetSectionChanged();
324 d->m_firstSetSection = firstSetSection;
325 emit d->firstSetSectionChanged();
326 326 d->initializeCandlestickFromModel();
327 327 }
328 328
329 329 /*!
330 330 Returns the section of the model that is used as the data source for the first candlestick set.
331 331 Default value is -1 (invalid mapping).
332 332 */
333 int QCandlestickModelMapper::firstCandlestickSetSection() const
333 int QCandlestickModelMapper::firstSetSection() const
334 334 {
335 335 Q_D(const QCandlestickModelMapper);
336 336
337 return d->m_firstCandlestickSetSection;
337 return d->m_firstSetSection;
338 338 }
339 339
340 340 /*!
341 341 Sets the section of the model that is used as the data source for the last candlestick set.
342 Parameter \a lastCandlestickSetSection specifies the section of the model. Default value is -1.
342 Parameter \a lastSetSection specifies the section of the model. Default value is -1.
343 343 */
344 void QCandlestickModelMapper::setLastCandlestickSetSection(int lastCandlestickSetSection)
344 void QCandlestickModelMapper::setLastSetSection(int lastSetSection)
345 345 {
346 346 Q_D(QCandlestickModelMapper);
347 347
348 lastCandlestickSetSection = qMax(lastCandlestickSetSection, -1);
348 lastSetSection = qMax(lastSetSection, -1);
349 349
350 if (d->m_lastCandlestickSetSection == lastCandlestickSetSection)
350 if (d->m_lastSetSection == lastSetSection)
351 351 return;
352 352
353 d->m_lastCandlestickSetSection = lastCandlestickSetSection;
354 emit d->lastCandlestickSetSectionChanged();
353 d->m_lastSetSection = lastSetSection;
354 emit d->lastSetSectionChanged();
355 355 d->initializeCandlestickFromModel();
356 356 }
357 357
358 358 /*!
359 359 Returns the section of the model that is used as the data source for the last candlestick set.
360 360 Default value is -1 (invalid mapping).
361 361 */
362 int QCandlestickModelMapper::lastCandlestickSetSection() const
362 int QCandlestickModelMapper::lastSetSection() const
363 363 {
364 364 Q_D(const QCandlestickModelMapper);
365 365
366 return d->m_lastCandlestickSetSection;
366 return d->m_lastSetSection;
367 367 }
368 368
369 369 ////////////////////////////////////////////////////////////////////////////////////////////////////
370 370
371 371 QCandlestickModelMapperPrivate::QCandlestickModelMapperPrivate(QCandlestickModelMapper *q)
372 372 : QObject(q),
373 373 m_model(nullptr),
374 374 m_series(nullptr),
375 375 m_timestamp(-1),
376 376 m_open(-1),
377 377 m_high(-1),
378 378 m_low(-1),
379 379 m_close(-1),
380 m_firstCandlestickSetSection(-1),
381 m_lastCandlestickSetSection(-1),
380 m_firstSetSection(-1),
381 m_lastSetSection(-1),
382 382 m_modelSignalsBlock(false),
383 383 m_seriesSignalsBlock(false),
384 384 q_ptr(q)
385 385 {
386 386 }
387 387
388 388 void QCandlestickModelMapperPrivate::initializeCandlestickFromModel()
389 389 {
390 390 if (!m_model || !m_series)
391 391 return;
392 392
393 393 blockSeriesSignals();
394 394 // clear current content
395 395 m_series->clear();
396 m_candlestickSets.clear();
396 m_sets.clear();
397 397
398 398 // create the initial candlestick sets
399 QList<QCandlestickSet *> candlestickSets;
400 for (int i = m_firstCandlestickSetSection; i <= m_lastCandlestickSetSection; ++i) {
399 QList<QCandlestickSet *> sets;
400 for (int i = m_firstSetSection; i <= m_lastSetSection; ++i) {
401 401 QModelIndex timestampIndex = candlestickModelIndex(i, m_timestamp);
402 402 QModelIndex openIndex = candlestickModelIndex(i, m_open);
403 403 QModelIndex highIndex = candlestickModelIndex(i, m_high);
404 404 QModelIndex lowIndex = candlestickModelIndex(i, m_low);
405 405 QModelIndex closeIndex = candlestickModelIndex(i, m_close);
406 406 if (timestampIndex.isValid()
407 407 && openIndex.isValid()
408 408 && highIndex.isValid()
409 409 && lowIndex.isValid()
410 410 && closeIndex.isValid()) {
411 411 QCandlestickSet *set = new QCandlestickSet();
412 412 set->setTimestamp(m_model->data(timestampIndex, Qt::DisplayRole).toReal());
413 413 set->setOpen(m_model->data(openIndex, Qt::DisplayRole).toReal());
414 414 set->setHigh(m_model->data(highIndex, Qt::DisplayRole).toReal());
415 415 set->setLow(m_model->data(lowIndex, Qt::DisplayRole).toReal());
416 416 set->setClose(m_model->data(closeIndex, Qt::DisplayRole).toReal());
417 417
418 418 connect(set, SIGNAL(timestampChanged()), this, SLOT(candlestickSetChanged()));
419 419 connect(set, SIGNAL(openChanged()), this, SLOT(candlestickSetChanged()));
420 420 connect(set, SIGNAL(highChanged()), this, SLOT(candlestickSetChanged()));
421 421 connect(set, SIGNAL(lowChanged()), this, SLOT(candlestickSetChanged()));
422 422 connect(set, SIGNAL(closeChanged()), this, SLOT(candlestickSetChanged()));
423 423
424 candlestickSets.append(set);
424 sets.append(set);
425 425 } else {
426 426 break;
427 427 }
428 428 }
429 m_series->append(candlestickSets);
430 m_candlestickSets.append(candlestickSets);
429 m_series->append(sets);
430 m_sets.append(sets);
431 431 blockSeriesSignals(false);
432 432 }
433 433
434 434 void QCandlestickModelMapperPrivate::modelDataUpdated(QModelIndex topLeft, QModelIndex bottomRight)
435 435 {
436 436 Q_Q(QCandlestickModelMapper);
437 437
438 438 if (!m_model || !m_series)
439 439 return;
440 440
441 441 if (m_modelSignalsBlock)
442 442 return;
443 443
444 444 blockSeriesSignals();
445 445 QModelIndex index;
446 446 for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
447 447 for (int column = topLeft.column(); column <= bottomRight.column(); ++column) {
448 448 index = topLeft.sibling(row, column);
449 449 QCandlestickSet *set = candlestickSet(index);
450 450 if (set) {
451 451 int pos = (q->orientation() == Qt::Vertical) ? row : column;
452 452 if (pos == m_timestamp)
453 453 set->setTimestamp(m_model->data(index).toReal());
454 454 else if (pos == m_open)
455 455 set->setOpen(m_model->data(index).toReal());
456 456 else if (pos == m_high)
457 457 set->setHigh(m_model->data(index).toReal());
458 458 else if (pos == m_low)
459 459 set->setLow(m_model->data(index).toReal());
460 460 else if (pos == m_close)
461 461 set->setClose(m_model->data(index).toReal());
462 462 }
463 463 }
464 464 }
465 465 blockSeriesSignals(false);
466 466 }
467 467
468 468 void QCandlestickModelMapperPrivate::modelHeaderDataUpdated(Qt::Orientation orientation, int first,
469 469 int last)
470 470 {
471 471 Q_UNUSED(orientation);
472 472 Q_UNUSED(first);
473 473 Q_UNUSED(last);
474 474 }
475 475
476 476 void QCandlestickModelMapperPrivate::modelRowsInserted(QModelIndex parent, int start, int end)
477 477 {
478 478 Q_UNUSED(parent)
479 479
480 480 Q_Q(QCandlestickModelMapper);
481 481
482 482 if (m_modelSignalsBlock)
483 483 return;
484 484
485 485 blockSeriesSignals();
486 486 if (q->orientation() == Qt::Vertical)
487 487 insertData(start, end);
488 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
488 else if (start <= m_firstSetSection || start <= m_lastSetSection)
489 489 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
490 490 blockSeriesSignals(false);
491 491 }
492 492
493 493 void QCandlestickModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
494 494 {
495 495 Q_UNUSED(parent)
496 496
497 497 Q_Q(QCandlestickModelMapper);
498 498
499 499 if (m_modelSignalsBlock)
500 500 return;
501 501
502 502 blockSeriesSignals();
503 503 if (q->orientation() == Qt::Vertical)
504 504 removeData(start, end);
505 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
505 else if (start <= m_firstSetSection || start <= m_lastSetSection)
506 506 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
507 507 blockSeriesSignals(false);
508 508 }
509 509
510 510 void QCandlestickModelMapperPrivate::modelColumnsInserted(QModelIndex parent, int start, int end)
511 511 {
512 512 Q_UNUSED(parent)
513 513
514 514 Q_Q(QCandlestickModelMapper);
515 515
516 516 if (m_modelSignalsBlock)
517 517 return;
518 518
519 519 blockSeriesSignals();
520 520 if (q->orientation() == Qt::Horizontal)
521 521 insertData(start, end);
522 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
522 else if (start <= m_firstSetSection || start <= m_lastSetSection)
523 523 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
524 524 blockSeriesSignals(false);
525 525 }
526 526
527 527 void QCandlestickModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
528 528 {
529 529 Q_UNUSED(parent)
530 530
531 531 Q_Q(QCandlestickModelMapper);
532 532
533 533 if (m_modelSignalsBlock)
534 534 return;
535 535
536 536 blockSeriesSignals();
537 537 if (q->orientation() == Qt::Horizontal)
538 538 removeData(start, end);
539 else if (start <= m_firstCandlestickSetSection || start <= m_lastCandlestickSetSection)
539 else if (start <= m_firstSetSection || start <= m_lastSetSection)
540 540 initializeCandlestickFromModel(); // if the changes affect the map - reinitialize
541 541 blockSeriesSignals(false);
542 542 }
543 543
544 544 void QCandlestickModelMapperPrivate::modelDestroyed()
545 545 {
546 546 m_model = 0;
547 547 }
548 548
549 549 void QCandlestickModelMapperPrivate::candlestickSetsAdded(const QList<QCandlestickSet *> &sets)
550 550 {
551 551 Q_Q(QCandlestickModelMapper);
552 552
553 553 if (m_seriesSignalsBlock)
554 554 return;
555 555
556 556 if (sets.isEmpty())
557 557 return;
558 558
559 int firstIndex = m_series->candlestickSets().indexOf(sets.at(0));
559 int firstIndex = m_series->sets().indexOf(sets.at(0));
560 560 if (firstIndex == -1)
561 561 return;
562 562
563 m_lastCandlestickSetSection += sets.count();
563 m_lastSetSection += sets.count();
564 564
565 565 blockModelSignals();
566 566 if (q->orientation() == Qt::Vertical)
567 m_model->insertColumns(firstIndex + m_firstCandlestickSetSection, sets.count());
567 m_model->insertColumns(firstIndex + m_firstSetSection, sets.count());
568 568 else
569 m_model->insertRows(firstIndex + m_firstCandlestickSetSection, sets.count());
569 m_model->insertRows(firstIndex + m_firstSetSection, sets.count());
570 570
571 571 for (int i = 0; i < sets.count(); ++i) {
572 int section = i + firstIndex + m_firstCandlestickSetSection;
572 int section = i + firstIndex + m_firstSetSection;
573 573 m_model->setData(candlestickModelIndex(section, m_timestamp), sets.at(i)->timestamp());
574 574 m_model->setData(candlestickModelIndex(section, m_open), sets.at(i)->open());
575 575 m_model->setData(candlestickModelIndex(section, m_high), sets.at(i)->high());
576 576 m_model->setData(candlestickModelIndex(section, m_low), sets.at(i)->low());
577 577 m_model->setData(candlestickModelIndex(section, m_close), sets.at(i)->close());
578 578 }
579 579 blockModelSignals(false);
580 580 initializeCandlestickFromModel();
581 581 }
582 582
583 583 void QCandlestickModelMapperPrivate::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets)
584 584 {
585 585 Q_Q(QCandlestickModelMapper);
586 586
587 587 if (m_seriesSignalsBlock)
588 588 return;
589 589
590 590 if (sets.isEmpty())
591 591 return;
592 592
593 int firstIndex = m_candlestickSets.indexOf(sets.at(0));
593 int firstIndex = m_sets.indexOf(sets.at(0));
594 594 if (firstIndex == -1)
595 595 return;
596 596
597 m_lastCandlestickSetSection -= sets.count();
597 m_lastSetSection -= sets.count();
598 598
599 599 for (int i = firstIndex + sets.count() - 1; i >= firstIndex; --i)
600 m_candlestickSets.removeAt(i);
600 m_sets.removeAt(i);
601 601
602 602 blockModelSignals();
603 603 if (q->orientation() == Qt::Vertical)
604 m_model->removeColumns(firstIndex + m_firstCandlestickSetSection, sets.count());
604 m_model->removeColumns(firstIndex + m_firstSetSection, sets.count());
605 605 else
606 m_model->removeRows(firstIndex + m_firstCandlestickSetSection, sets.count());
606 m_model->removeRows(firstIndex + m_firstSetSection, sets.count());
607 607 blockModelSignals(false);
608 608 initializeCandlestickFromModel();
609 609 }
610 610
611 611 void QCandlestickModelMapperPrivate::candlestickSetChanged()
612 612 {
613 613 if (m_seriesSignalsBlock)
614 614 return;
615 615
616 616 QCandlestickSet *set = qobject_cast<QCandlestickSet *>(QObject::sender());
617 617 if (!set)
618 618 return;
619 619
620 int section = m_series->candlestickSets().indexOf(set);
620 int section = m_series->sets().indexOf(set);
621 621 if (section < 0)
622 622 return;
623 623
624 section += m_firstCandlestickSetSection;
624 section += m_firstSetSection;
625 625
626 626 blockModelSignals();
627 627 m_model->setData(candlestickModelIndex(section, m_timestamp), set->timestamp());
628 628 m_model->setData(candlestickModelIndex(section, m_open), set->open());
629 629 m_model->setData(candlestickModelIndex(section, m_high), set->high());
630 630 m_model->setData(candlestickModelIndex(section, m_low), set->low());
631 631 m_model->setData(candlestickModelIndex(section, m_close), set->close());
632 632 blockModelSignals(false);
633 633 }
634 634
635 635 void QCandlestickModelMapperPrivate::seriesDestroyed()
636 636 {
637 637 m_series = 0;
638 638 }
639 639
640 640 QCandlestickSet *QCandlestickModelMapperPrivate::candlestickSet(QModelIndex index)
641 641 {
642 642 Q_Q(QCandlestickModelMapper);
643 643
644 644 if (!index.isValid())
645 645 return 0;
646 646
647 647 int section = (q->orientation() == Qt::Vertical) ? index.column() : index.row();
648 648 int pos = (q->orientation() == Qt::Vertical) ? index.row() : index.column();
649 649
650 if (section < m_firstCandlestickSetSection || section > m_lastCandlestickSetSection)
650 if (section < m_firstSetSection || section > m_lastSetSection)
651 651 return 0; // This part of model has not been mapped to any candlestick set.
652 652
653 653 if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close)
654 654 return 0; // This part of model has not been mapped to any candlestick set.
655 655
656 return m_series->candlestickSets().at(section - m_firstCandlestickSetSection);
656 return m_series->sets().at(section - m_firstSetSection);
657 657 }
658 658
659 659 QModelIndex QCandlestickModelMapperPrivate::candlestickModelIndex(int section, int pos)
660 660 {
661 661 Q_Q(QCandlestickModelMapper);
662 662
663 if (section < m_firstCandlestickSetSection || section > m_lastCandlestickSetSection)
663 if (section < m_firstSetSection || section > m_lastSetSection)
664 664 return QModelIndex(); // invalid
665 665
666 666 if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close)
667 667 return QModelIndex(); // invalid
668 668
669 669 if (q->orientation() == Qt::Vertical)
670 670 return m_model->index(pos, section);
671 671 else
672 672 return m_model->index(section, pos);
673 673 }
674 674
675 675 void QCandlestickModelMapperPrivate::insertData(int start, int end)
676 676 {
677 677 Q_UNUSED(start)
678 678 Q_UNUSED(end)
679 679
680 680 // Currently candlestickchart needs to be fully recalculated when change is made.
681 681 initializeCandlestickFromModel();
682 682 }
683 683
684 684 void QCandlestickModelMapperPrivate::removeData(int start, int end)
685 685 {
686 686 Q_UNUSED(start)
687 687 Q_UNUSED(end)
688 688
689 689 // Currently candlestickchart needs to be fully recalculated when change is made.
690 690 initializeCandlestickFromModel();
691 691 }
692 692
693 693 void QCandlestickModelMapperPrivate::blockModelSignals(bool block)
694 694 {
695 695 m_modelSignalsBlock = block;
696 696 }
697 697
698 698 void QCandlestickModelMapperPrivate::blockSeriesSignals(bool block)
699 699 {
700 700 m_seriesSignalsBlock = block;
701 701 }
702 702
703 703 #include "moc_qcandlestickmodelmapper.cpp"
704 704 #include "moc_qcandlestickmodelmapper_p.cpp"
705 705
706 706 QT_CHARTS_END_NAMESPACE
@@ -1,95 +1,95
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QCANDLESTICKMODELMAPPER_H
31 31 #define QCANDLESTICKMODELMAPPER_H
32 32
33 33 #include <QtCharts/QChartGlobal>
34 34 #include <QtCore/QObject>
35 35
36 36 QT_BEGIN_NAMESPACE
37 37 class QAbstractItemModel;
38 38 QT_END_NAMESPACE
39 39
40 40 QT_CHARTS_BEGIN_NAMESPACE
41 41
42 42 class QCandlestickModelMapperPrivate;
43 43 class QCandlestickSeries;
44 44
45 45 class QT_CHARTS_EXPORT QCandlestickModelMapper : public QObject
46 46 {
47 47 Q_OBJECT
48 48 Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelReplaced)
49 49 Q_PROPERTY(QCandlestickSeries *series READ series WRITE setSeries NOTIFY seriesReplaced)
50 50
51 51 public:
52 52 explicit QCandlestickModelMapper(QObject *parent = nullptr);
53 53
54 54 void setModel(QAbstractItemModel *model);
55 55 QAbstractItemModel *model() const;
56 56
57 57 void setSeries(QCandlestickSeries *series);
58 58 QCandlestickSeries *series() const;
59 59
60 60 virtual Qt::Orientation orientation() const = 0;
61 61
62 62 Q_SIGNALS:
63 63 void modelReplaced();
64 64 void seriesReplaced();
65 65
66 66 protected:
67 67 void setTimestamp(int timestamp);
68 68 int timestamp() const;
69 69
70 70 void setOpen(int open);
71 71 int open() const;
72 72
73 73 void setHigh(int high);
74 74 int high() const;
75 75
76 76 void setLow(int low);
77 77 int low() const;
78 78
79 79 void setClose(int close);
80 80 int close() const;
81 81
82 void setFirstCandlestickSetSection(int firstCandlestickSetSection);
83 int firstCandlestickSetSection() const;
82 void setFirstSetSection(int firstSetSection);
83 int firstSetSection() const;
84 84
85 void setLastCandlestickSetSection(int lastCandlestickSetSection);
86 int lastCandlestickSetSection() const;
85 void setLastSetSection(int lastSetSection);
86 int lastSetSection() const;
87 87
88 88 protected:
89 89 QCandlestickModelMapperPrivate * const d_ptr;
90 90 Q_DECLARE_PRIVATE(QCandlestickModelMapper)
91 91 };
92 92
93 93 QT_CHARTS_END_NAMESPACE
94 94
95 95 #endif // QCANDLESTICKMODELMAPPER_H
@@ -1,116 +1,116
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 // W A R N I N G
31 31 // -------------
32 32 //
33 33 // This file is not part of the Qt Chart API. It exists purely as an
34 34 // implementation detail. This header file may change from version to
35 35 // version without notice, or even be removed.
36 36 //
37 37 // We mean it.
38 38
39 39 #ifndef QCANDLESTICKMODELMAPPER_P_H
40 40 #define QCANDLESTICKMODELMAPPER_P_H
41 41
42 42 #include <QtCharts/QCandlestickModelMapper>
43 43 #include <QtCore/QObject>
44 44
45 45 QT_BEGIN_NAMESPACE
46 46 class QModelIndex;
47 47 QT_END_NAMESPACE
48 48
49 49 QT_CHARTS_BEGIN_NAMESPACE
50 50
51 51 class QCandlestickSet;
52 52
53 53 class QCandlestickModelMapperPrivate : public QObject
54 54 {
55 55 Q_OBJECT
56 56
57 57 public:
58 58 explicit QCandlestickModelMapperPrivate(QCandlestickModelMapper *q);
59 59
60 60 Q_SIGNALS:
61 61 void timestampChanged();
62 62 void openChanged();
63 63 void highChanged();
64 64 void lowChanged();
65 65 void closeChanged();
66 void firstCandlestickSetSectionChanged();
67 void lastCandlestickSetSectionChanged();
66 void firstSetSectionChanged();
67 void lastSetSectionChanged();
68 68
69 69 private Q_SLOTS:
70 70 void initializeCandlestickFromModel();
71 71
72 72 // for the model
73 73 void modelDataUpdated(QModelIndex topLeft, QModelIndex bottomRight);
74 74 void modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last);
75 75 void modelRowsInserted(QModelIndex parent, int start, int end);
76 76 void modelRowsRemoved(QModelIndex parent, int start, int end);
77 77 void modelColumnsInserted(QModelIndex parent, int start, int end);
78 78 void modelColumnsRemoved(QModelIndex parent, int start, int end);
79 79 void modelDestroyed();
80 80
81 81 // for the series
82 82 void candlestickSetsAdded(const QList<QCandlestickSet *> &sets);
83 83 void candlestickSetsRemoved(const QList<QCandlestickSet *> &sets);
84 84 void candlestickSetChanged();
85 85 void seriesDestroyed();
86 86
87 87 private:
88 88 QCandlestickSet *candlestickSet(QModelIndex index);
89 89 QModelIndex candlestickModelIndex(int section, int pos);
90 90 void insertData(int start, int end);
91 91 void removeData(int start, int end);
92 92 void blockModelSignals(bool block = true);
93 93 void blockSeriesSignals(bool block = true);
94 94
95 95 private:
96 96 QAbstractItemModel *m_model;
97 97 QCandlestickSeries *m_series;
98 98 int m_timestamp;
99 99 int m_open;
100 100 int m_high;
101 101 int m_low;
102 102 int m_close;
103 int m_firstCandlestickSetSection;
104 int m_lastCandlestickSetSection;
105 QList<QCandlestickSet *> m_candlestickSets;
103 int m_firstSetSection;
104 int m_lastSetSection;
105 QList<QCandlestickSet *> m_sets;
106 106 bool m_modelSignalsBlock;
107 107 bool m_seriesSignalsBlock;
108 108
109 109 private:
110 110 QCandlestickModelMapper *q_ptr;
111 111 Q_DECLARE_PUBLIC(QCandlestickModelMapper)
112 112 };
113 113
114 114 QT_CHARTS_END_NAMESPACE
115 115
116 116 #endif // QCANDLESTICKMODELMAPPER_P_H
@@ -1,1138 +1,1138
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QBarCategoryAxis>
31 31 #include <QtCharts/QCandlestickLegendMarker>
32 32 #include <QtCharts/QCandlestickSeries>
33 33 #include <QtCharts/QCandlestickSet>
34 34 #include <QtCharts/QValueAxis>
35 35 #include <QtCore/QDateTime>
36 36 #include <private/candlestickanimation_p.h>
37 37 #include <private/candlestickchartitem_p.h>
38 38 #include <private/chartdataset_p.h>
39 39 #include <private/charttheme_p.h>
40 40 #include <private/qcandlestickseries_p.h>
41 41 #include <private/qcandlestickset_p.h>
42 42 #include <private/qchart_p.h>
43 43
44 44 QT_CHARTS_BEGIN_NAMESPACE
45 45
46 46 /*!
47 47 \class QCandlestickSeries
48 48 \since 5.8
49 49 \inmodule Qt Charts
50 50 \brief Series for creating a candlestick chart.
51 51
52 52 QCandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
53 53 is to act as a container for single candlestick items. Each item is drawn to its own category
54 54 when using QBarCategoryAxis. QDateTimeAxis and QValueAxis can be used as alternatives to
55 55 QBarCategoryAxis. In this case, each candlestick item is drawn according to its timestamp value.
56 56
57 57 \note The timestamps must be unique within a QCandlestickSeries. When using QBarCategoryAxis,
58 58 only the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
59 59 multiple instances of QCandlestickSeries, items from different series sharing a timestamp are
60 60 drawn to the same category. When using QValueAxis or QDateTimeAxis, candlestick items sharing a
61 61 timestamp will overlap each other.
62 62
63 63 See the \l {Candlestick Chart Example} {candlestick chart example} to learn how to create
64 64 a candlestick chart.
65 65 \image examples_candlestickchart.png
66 66
67 67 \sa QCandlestickSet, QBarCategoryAxis, QDateTimeAxis, QValueAxis
68 68 */
69 69
70 70 /*!
71 71 \qmltype CandlestickSeries
72 72 \since 2.2
73 73 \instantiates QCandlestickSeries
74 74 \inqmlmodule QtCharts
75 75 \inherits AbstractSeries
76 76 \brief Series for creating a candlestick chart.
77 77
78 78 CandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
79 79 is to act as a container for single candlestick items. Each item is drawn to its own category
80 80 when using BarCategoryAxis. DateTimeAxis and ValueAxis can be used as an alternative to
81 81 BarCategoryAxis. In this case each candlestick item is drawn according to its timestamp value.
82 82
83 83 \note The timestamps must be unique within a CandlestickSeries. When using BarCategoryAxis, only
84 84 the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
85 85 multiple instances of CandlestickSeries, items from different series sharing a timestamp are
86 86 drawn to the same category. When using ValueAxis or DateTimeAxis, candlestick items sharing a
87 87 timestamp will overlap each other.
88 88
89 89 The following QML shows how to create a simple candlestick chart:
90 90 \code
91 91 import QtQuick 2.5
92 92 import QtCharts 2.2
93 93
94 94 ChartView {
95 95 title: "Candlestick Series"
96 96 width: 400
97 97 height: 300
98 98
99 99 CandlestickSeries {
100 100 name: "Acme Ltd."
101 101 increasingColor: "green"
102 102 decreasingColor: "red"
103 103
104 104 CandlestickSet { timestamp: 1435708800000; open: 690; high: 694; low: 599; close: 660 }
105 105 CandlestickSet { timestamp: 1435795200000; open: 669; high: 669; low: 669; close: 669 }
106 106 CandlestickSet { timestamp: 1436140800000; open: 485; high: 623; low: 485; close: 600 }
107 107 CandlestickSet { timestamp: 1436227200000; open: 589; high: 615; low: 377; close: 569 }
108 108 CandlestickSet { timestamp: 1436313600000; open: 464; high: 464; low: 254; close: 254 }
109 109 }
110 110 }
111 111 \endcode
112 112
113 113 \beginfloatleft
114 114 \image examples_qmlcandlestick.png
115 115 \endfloat
116 116 \clearfloat
117 117
118 118 \sa CandlestickSet, BarCategoryAxis, DateTimeAxis, ValueAxis
119 119 */
120 120
121 121 /*!
122 122 \property QCandlestickSeries::count
123 123 \brief The count of sets in series.
124 124 */
125 125
126 126 /*!
127 127 \qmlproperty int CandlestickSeries::count
128 128 The count of sets in series.
129 129 */
130 130
131 131 /*!
132 132 \property QCandlestickSeries::maximumColumnWidth
133 133 \brief The maximum width of the candlestick items in pixels. Setting a negative value means
134 134 there is no maximum width. All negative values are converted to -1.0.
135 135 */
136 136
137 137 /*!
138 138 \qmlproperty qreal CandlestickSeries::maximumColumnWidth
139 139 \brief The maximum width of the candlestick items in pixels. Setting a negative value means
140 140 there is no maximum width. All negative values are converted to -1.0.
141 141 */
142 142
143 143 /*!
144 144 \property QCandlestickSeries::minimumColumnWidth
145 145 \brief The minimum width of the candlestick items in pixels. Setting a negative value means
146 146 there is no minimum width. All negative values are converted to -1.0.
147 147 */
148 148
149 149 /*!
150 150 \qmlproperty qreal CandlestickSeries::minimumColumnWidth
151 151 \brief The minimum width of the candlestick items in pixels. Setting a negative value means
152 152 there is no minimum width. All negative values are converted to -1.0.
153 153 */
154 154
155 155 /*!
156 156 \property QCandlestickSeries::bodyWidth
157 157 \brief The width of the candlestick items.
158 158
159 159 The value signifies the relative width of the candlestick item inside its own slot, in the range
160 160 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
161 161 */
162 162
163 163 /*!
164 164 \qmlproperty qreal CandlestickSeries::bodyWidth
165 165 \brief The width of the candlestick items.
166 166
167 167 The value signifies the relative width of the candlestick item inside its own slot, in the range
168 168 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
169 169 */
170 170
171 171 /*!
172 172 \property QCandlestickSeries::bodyOutlineVisible
173 173 \brief The visibility of the candlestick body outlines.
174 174 */
175 175
176 176 /*!
177 177 \qmlproperty bool CandlestickSeries::bodyOutlineVisible
178 178 \brief The visibility of the candlestick body outlines.
179 179 */
180 180
181 181 /*!
182 182 \property QCandlestickSeries::capsWidth
183 183 \brief The width of the caps.
184 184
185 185 The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
186 186 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
187 187 */
188 188
189 189 /*!
190 190 \qmlproperty qreal CandlestickSeries::capsWidth
191 191 \brief The width of the caps.
192 192
193 193 The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
194 194 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
195 195 */
196 196
197 197 /*!
198 198 \property QCandlestickSeries::capsVisible
199 199 \brief The visibility of the caps.
200 200 */
201 201
202 202 /*!
203 203 \qmlproperty bool CandlestickSeries::capsVisible
204 204 \brief The visibility of the caps.
205 205 */
206 206
207 207 /*!
208 208 \property QCandlestickSeries::increasingColor
209 209 \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
210 210 close value is higher than the open value. By default this property is set to brush color.
211 211 Default color is used also when the property is set to an invalid color value.
212 212 */
213 213
214 214 /*!
215 215 \qmlproperty QColor CandlestickSeries::increasingColor
216 216 \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
217 217 close value is higher than the open value. By default this property is set to brush color.
218 218 Default color is used also when the property is set to an invalid color value.
219 219 */
220 220
221 221 /*!
222 222 \property QCandlestickSeries::decreasingColor
223 223 \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
224 224 open value is higher than the close value. By default this property is set to brush color with
225 225 alpha channel set to 128. Default color is used also when the property is set to an invalid
226 226 color value.
227 227 */
228 228
229 229 /*!
230 230 \qmlproperty QColor CandlestickSeries::decreasingColor
231 231 \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
232 232 open value is higher than the close value. By default this property is set to brush color with
233 233 alpha channel set to 128. Default color is used also when the property is set to an invalid
234 234 color value.
235 235 */
236 236
237 237 /*!
238 238 \property QCandlestickSeries::brush
239 239 \brief The brush of the candlestick items.
240 240 */
241 241
242 242 /*!
243 243 \property QCandlestickSeries::pen
244 244 \brief The pen of the candlestick items.
245 245 */
246 246
247 247 /*!
248 248 \qmlproperty QString CandlestickSeries::brushFilename
249 249 \brief The name of the file used as a brush for the series.
250 250 */
251 251
252 252 /*!
253 253 \fn void QCandlestickSeries::clicked(QCandlestickSet *set)
254 254 \brief Emitted when a \a set is clicked (pressed and released) on the chart.
255 255 */
256 256
257 257 /*!
258 258 \qmlsignal CandlestickSeries::clicked(CandlestickSet set)
259 259 \brief Emitted when a \a set is clicked (pressed and released) on the chart.
260 260
261 261 The corresponding signal handler is \c {onClicked}.
262 262 */
263 263
264 264 /*!
265 265 \fn void QCandlestickSeries::hovered(bool status, QCandlestickSet *set)
266 266 \brief Emitted when there is change in hover \a status over the \a set.
267 267 */
268 268
269 269 /*!
270 270 \qmlsignal CandlestickSeries::hovered(bool status, CandlestickSet set)
271 271 \brief Emitted when there is change in hover \a status over the \a set.
272 272
273 273 The corresponding signal handler is \c {onHovered}.
274 274 */
275 275
276 276 /*!
277 277 \fn void QCandlestickSeries::pressed(QCandlestickSet *set)
278 278 \brief Emitted when a \a set is pressed on the chart.
279 279 */
280 280
281 281 /*!
282 282 \qmlsignal CandlestickSeries::pressed(CandlestickSet set)
283 283 \brief Emitted when a \a set is pressed on the chart.
284 284
285 285 The corresponding signal handler is \c {onPressed}.
286 286 */
287 287
288 288 /*!
289 289 \fn void QCandlestickSeries::released(QCandlestickSet *set)
290 290 \brief Emitted when a \a set is released on the chart.
291 291 */
292 292
293 293 /*!
294 294 \qmlsignal CandlestickSeries::released(CandlestickSet set)
295 295 \brief Emitted when a \a set is released on the chart.
296 296
297 297 The corresponding signal handler is \c {onReleased}.
298 298 */
299 299
300 300 /*!
301 301 \fn void QCandlestickSeries::doubleClicked(QCandlestickSet *set)
302 302 \brief Emitted when a \a set is double-clicked on the chart.
303 303 */
304 304
305 305 /*!
306 306 \qmlsignal CandlestickSeries::doubleClicked(CandlestickSet set)
307 307 \brief Emitted when a \a set is double-clicked on the chart.
308 308
309 309 The corresponding signal handler is \c {onDoubleClicked}.
310 310 */
311 311
312 312 /*!
313 313 \fn void QCandlestickSeries::candlestickSetsAdded(const QList<QCandlestickSet *> &sets)
314 314 \brief Emitted when new \a sets are added to the series.
315 315 */
316 316
317 317 /*!
318 318 \qmlsignal CandlestickSeries::candlestickSetsAdded(list<CandlestickSet> sets)
319 319 \brief Emitted when new \a sets are added to the series.
320 320
321 321 The corresponding signal handler is \c {onCandlestickSetsAdded}.
322 322 */
323 323
324 324 /*!
325 325 \fn void QCandlestickSeries::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets)
326 326 \brief Emitted when \a sets are removed from the series.
327 327 */
328 328
329 329 /*!
330 330 \qmlsignal CandlestickSeries::candlestickSetsRemoved(list<CandlestickSet> sets)
331 331 \brief Emitted when \a sets are removed from the series.
332 332
333 333 The corresponding signal handler is \c {onCandlestickSetsRemoved}.
334 334 */
335 335
336 336 /*!
337 337 \fn void QCandlestickSeries::countChanged()
338 338 \brief Emitted when there is a change in the count of candlestick items in the series.
339 339 \sa count
340 340 */
341 341
342 342 /*!
343 343 \qmlsignal CandlestickSeries::countChanged()
344 344 \brief Emitted when there is a change in the count of candlestick items in the series.
345 345 \sa count
346 346
347 347 The corresponding signal handler is \c {onCountChanged}.
348 348 */
349 349
350 350 /*!
351 351 \fn void QCandlestickSeries::maximumColumnWidthChanged()
352 352 \brief Emitted when there is a change in the maximum column width of candlestick items.
353 353 \sa maximumColumnWidth
354 354 */
355 355
356 356 /*!
357 357 \qmlsignal CandlestickSeries::maximumColumnWidthChanged()
358 358 \brief Emitted when there is a change in the maximum column width of candlestick items.
359 359 \sa maximumColumnWidth
360 360
361 361 The corresponding signal handler is \c {onMaximumColumnWidthChanged}.
362 362 */
363 363
364 364 /*!
365 365 \fn void QCandlestickSeries::minimumColumnWidthChanged()
366 366 \brief Emitted when there is a change in the minimum column width of candlestick items.
367 367 \sa minimumColumnWidth
368 368 */
369 369
370 370 /*!
371 371 \qmlsignal CandlestickSeries::minimumColumnWidthChanged()
372 372 \brief Emitted when there is a change in the minimum column width of candlestick items.
373 373 \sa minimumColumnWidth
374 374
375 375 The corresponding signal handler is \c {onMinimumColumnWidthChanged}.
376 376 */
377 377
378 378 /*!
379 379 \fn void QCandlestickSeries::bodyWidthChanged()
380 380 \brief Emitted when the candlestick item width is changed.
381 381 \sa bodyWidth
382 382 */
383 383
384 384 /*!
385 385 \qmlsignal CandlestickSeries::bodyWidthChanged()
386 386 \brief Emitted when the candlestick item width is changed.
387 387 \sa bodyWidth
388 388
389 389 The corresponding signal handler is \c {onBodyWidthChanged}.
390 390 */
391 391
392 392 /*!
393 393 \fn void QCandlestickSeries::bodyOutlineVisibilityChanged()
394 394 \brief Emitted when the visibility of the candlestick item body outline is changed.
395 395 \sa bodyOutlineVisible
396 396 */
397 397
398 398 /*!
399 399 \qmlsignal CandlestickSeries::bodyOutlineVisibilityChanged()
400 400 \brief Emitted when the visibility of the candlestick item body outline is changed.
401 401 \sa bodyOutlineVisible
402 402
403 403 The corresponding signal handler is \c {onBodyOutlineVisibilityChanged}.
404 404 */
405 405
406 406 /*!
407 407 \fn void QCandlestickSeries::capsWidthChanged()
408 408 \brief Emitted when the candlestick item caps width is changed.
409 409 \sa capsWidth
410 410 */
411 411
412 412 /*!
413 413 \qmlsignal CandlestickSeries::capsWidthChanged()
414 414 \brief Emitted when the candlestick item caps width is changed.
415 415 \sa capsWidth
416 416
417 417 The corresponding signal handler is \c {onCapsWidthChanged}.
418 418 */
419 419
420 420 /*!
421 421 \fn void QCandlestickSeries::capsVisibilityChanged()
422 422 \brief Emitted when the visibility of the candlestick item caps is changed.
423 423 \sa capsVisible
424 424 */
425 425
426 426 /*!
427 427 \qmlsignal CandlestickSeries::capsVisibilityChanged()
428 428 \brief Emitted when the visibility of the candlestick item caps is changed.
429 429 \sa capsVisible
430 430
431 431 The corresponding signal handler is \c {onCapsVisibilityChanged}.
432 432 */
433 433
434 434 /*!
435 435 \fn void QCandlestickSeries::increasingColorChanged()
436 436 \brief Emitted when the candlestick item increasing color is changed.
437 437 \sa increasingColor
438 438 */
439 439
440 440 /*!
441 441 \qmlsignal CandlestickSeries::increasingColorChanged()
442 442 \brief Emitted when the candlestick item increasing color is changed.
443 443 \sa increasingColor
444 444
445 445 The corresponding signal handler is \c {onIncreasingColorChanged}.
446 446 */
447 447
448 448 /*!
449 449 \fn void QCandlestickSeries::decreasingColorChanged()
450 450 \brief Emitted when the candlestick item decreasing color is changed.
451 451 \sa decreasingColor
452 452 */
453 453
454 454 /*!
455 455 \qmlsignal CandlestickSeries::decreasingColorChanged()
456 456 \brief Emitted when the candlestick item decreasing color is changed.
457 457 \sa decreasingColor
458 458
459 459 The corresponding signal handler is \c {onDecreasingColorChanged}.
460 460 */
461 461
462 462 /*!
463 463 \fn void QCandlestickSeries::brushChanged()
464 464 \brief Emitted when the candlestick item brush is changed.
465 465 \sa brush
466 466 */
467 467
468 468 /*!
469 469 \fn void QCandlestickSeries::penChanged()
470 470 \brief Emitted when the candlestick item pen is changed.
471 471 \sa pen
472 472 */
473 473
474 474 /*!
475 475 Constructs an empty QCandlestickSeries. The \a parent is optional.
476 476 */
477 477 QCandlestickSeries::QCandlestickSeries(QObject *parent)
478 478 : QAbstractSeries(*new QCandlestickSeriesPrivate(this), parent)
479 479 {
480 480 }
481 481
482 482 /*!
483 483 Destroys the series. Removes the series from the chart.
484 484 */
485 485 QCandlestickSeries::~QCandlestickSeries()
486 486 {
487 487 Q_D(QCandlestickSeries);
488 488 if (d->m_chart)
489 489 d->m_chart->removeSeries(this);
490 490 }
491 491
492 492 /*!
493 493 Adds a single set to the series. Takes ownership of the \a set. If the set is \e null or is
494 494 already in the series, it won't be appended.
495 495 Returns \c true if appending succeeded, \c false otherwise.
496 496 */
497 497 bool QCandlestickSeries::append(QCandlestickSet *set)
498 498 {
499 499 QList<QCandlestickSet *> sets;
500 500 sets.append(set);
501 501
502 502 return append(sets);
503 503 }
504 504
505 505 /*!
506 506 Removes a single set from the series.
507 507 Returns \c true if the \a set is successfully deleted, \c false otherwise.
508 508 */
509 509 bool QCandlestickSeries::remove(QCandlestickSet *set)
510 510 {
511 511 QList<QCandlestickSet *> sets;
512 512 sets.append(set);
513 513
514 514 return remove(sets);
515 515 }
516 516
517 517 /*!
518 518 Adds a list of sets to the series. Takes ownership of the \a sets. If any of the sets are
519 519 \e null, already appended to the series, or the list contains duplicated sets, nothing is
520 520 appended.
521 521 Returns \c true if all sets were appended successfully, \c false otherwise.
522 522 */
523 523 bool QCandlestickSeries::append(const QList<QCandlestickSet *> &sets)
524 524 {
525 525 Q_D(QCandlestickSeries);
526 526
527 527 bool success = d->append(sets);
528 528 if (success) {
529 529 emit candlestickSetsAdded(sets);
530 530 emit countChanged();
531 531 }
532 532
533 533 return success;
534 534 }
535 535
536 536 /*!
537 537 Removes a list of sets from the series. If any of the \a sets are \e null, already removed from
538 538 the series, or the list contains duplicated sets, nothing is removed.
539 539 Returns \c true if all sets were removed successfully, \c false otherwise.
540 540 */
541 541 bool QCandlestickSeries::remove(const QList<QCandlestickSet *> &sets)
542 542 {
543 543 Q_D(QCandlestickSeries);
544 544
545 545 bool success = d->remove(sets);
546 546 if (success) {
547 547 emit candlestickSetsRemoved(sets);
548 548 emit countChanged();
549 549 foreach (QCandlestickSet *set, sets)
550 550 set->deleteLater();
551 551 }
552 552
553 553 return success;
554 554 }
555 555
556 556 /*!
557 557 Inserts a set to the series at \a index position. Takes ownership of the \a set. If the set is
558 558 \e null or already in the series, it won't be appended.
559 559 Returns \c true if inserting succeeded, \c false otherwise.
560 560 */
561 561 bool QCandlestickSeries::insert(int index, QCandlestickSet *set)
562 562 {
563 563 Q_D(QCandlestickSeries);
564 564
565 565 bool success = d->insert(index, set);
566 566 if (success) {
567 567 QList<QCandlestickSet *> sets;
568 568 sets.append(set);
569 569 emit candlestickSetsAdded(sets);
570 570 emit countChanged();
571 571 }
572 572
573 573 return success;
574 574 }
575 575
576 576 /*!
577 577 Takes a single \a set from the series. Does not delete the set object.
578 578 Returns \c true if take was successful, \c false otherwise.
579 579 \note The series remains as the set's parent object. You must set the parent object to take full
580 580 ownership.
581 581 */
582 582 bool QCandlestickSeries::take(QCandlestickSet *set)
583 583 {
584 584 Q_D(QCandlestickSeries);
585 585
586 586 QList<QCandlestickSet *> sets;
587 587 sets.append(set);
588 588
589 589 bool success = d->remove(sets);
590 590 if (success) {
591 591 emit candlestickSetsRemoved(sets);
592 592 emit countChanged();
593 593 }
594 594
595 595 return success;
596 596 }
597 597
598 598 /*!
599 599 Removes all sets from the series, and deletes them.
600 600 */
601 601 void QCandlestickSeries::clear()
602 602 {
603 603 Q_D(QCandlestickSeries);
604 604
605 QList<QCandlestickSet *> sets = candlestickSets();
605 QList<QCandlestickSet *> sets = this->sets();
606 606
607 607 bool success = d->remove(sets);
608 608 if (success) {
609 609 emit candlestickSetsRemoved(sets);
610 610 emit countChanged();
611 611 foreach (QCandlestickSet *set, sets)
612 612 set->deleteLater();
613 613 }
614 614 }
615 615
616 616 /*!
617 617 Returns the list of sets in the series. Ownership of the sets is unchanged.
618 618 */
619 QList<QCandlestickSet *> QCandlestickSeries::candlestickSets() const
619 QList<QCandlestickSet *> QCandlestickSeries::sets() const
620 620 {
621 621 Q_D(const QCandlestickSeries);
622 622
623 return d->m_candlestickSets;
623 return d->m_sets;
624 624 }
625 625
626 626 /*!
627 627 Returns the number of the sets in the series.
628 628 */
629 629 int QCandlestickSeries::count() const
630 630 {
631 return candlestickSets().count();
631 return sets().count();
632 632 }
633 633
634 634 /*!
635 635 Returns the type of the series (QAbstractSeries::SeriesTypeCandlestick).
636 636 */
637 637 QAbstractSeries::SeriesType QCandlestickSeries::type() const
638 638 {
639 639 return QAbstractSeries::SeriesTypeCandlestick;
640 640 }
641 641
642 642 void QCandlestickSeries::setMaximumColumnWidth(qreal maximumColumnWidth)
643 643 {
644 644 Q_D(QCandlestickSeries);
645 645
646 646 if (maximumColumnWidth < 0.0 && maximumColumnWidth != -1.0)
647 647 maximumColumnWidth = -1.0;
648 648
649 649 if (d->m_maximumColumnWidth == maximumColumnWidth)
650 650 return;
651 651
652 652 d->m_maximumColumnWidth = maximumColumnWidth;
653 653
654 654 emit d->updatedLayout();
655 655 emit maximumColumnWidthChanged();
656 656 }
657 657
658 658 qreal QCandlestickSeries::maximumColumnWidth() const
659 659 {
660 660 Q_D(const QCandlestickSeries);
661 661
662 662 return d->m_maximumColumnWidth;
663 663 }
664 664
665 665 void QCandlestickSeries::setMinimumColumnWidth(qreal minimumColumnWidth)
666 666 {
667 667 Q_D(QCandlestickSeries);
668 668
669 669 if (minimumColumnWidth < 0.0 && minimumColumnWidth != -1.0)
670 670 minimumColumnWidth = -1.0;
671 671
672 672 if (d->m_minimumColumnWidth == minimumColumnWidth)
673 673 return;
674 674
675 675 d->m_minimumColumnWidth = minimumColumnWidth;
676 676
677 677 d->updatedLayout();
678 678 emit minimumColumnWidthChanged();
679 679 }
680 680
681 681 qreal QCandlestickSeries::minimumColumnWidth() const
682 682 {
683 683 Q_D(const QCandlestickSeries);
684 684
685 685 return d->m_minimumColumnWidth;
686 686 }
687 687
688 688 void QCandlestickSeries::setBodyWidth(qreal bodyWidth)
689 689 {
690 690 Q_D(QCandlestickSeries);
691 691
692 692 if (bodyWidth < 0.0)
693 693 bodyWidth = 0.0;
694 694 else if (bodyWidth > 1.0)
695 695 bodyWidth = 1.0;
696 696
697 697 if (d->m_bodyWidth == bodyWidth)
698 698 return;
699 699
700 700 d->m_bodyWidth = bodyWidth;
701 701
702 702 emit d->updatedLayout();
703 703 emit bodyWidthChanged();
704 704 }
705 705
706 706 qreal QCandlestickSeries::bodyWidth() const
707 707 {
708 708 Q_D(const QCandlestickSeries);
709 709
710 710 return d->m_bodyWidth;
711 711 }
712 712
713 713 void QCandlestickSeries::setBodyOutlineVisible(bool bodyOutlineVisible)
714 714 {
715 715 Q_D(QCandlestickSeries);
716 716
717 717 if (d->m_bodyOutlineVisible == bodyOutlineVisible)
718 718 return;
719 719
720 720 d->m_bodyOutlineVisible = bodyOutlineVisible;
721 721
722 722 emit d->updated();
723 723 emit bodyOutlineVisibilityChanged();
724 724 }
725 725
726 726 bool QCandlestickSeries::bodyOutlineVisible() const
727 727 {
728 728 Q_D(const QCandlestickSeries);
729 729
730 730 return d->m_bodyOutlineVisible;
731 731 }
732 732
733 733 void QCandlestickSeries::setCapsWidth(qreal capsWidth)
734 734 {
735 735 Q_D(QCandlestickSeries);
736 736
737 737 if (capsWidth < 0.0)
738 738 capsWidth = 0.0;
739 739 else if (capsWidth > 1.0)
740 740 capsWidth = 1.0;
741 741
742 742 if (d->m_capsWidth == capsWidth)
743 743 return;
744 744
745 745 d->m_capsWidth = capsWidth;
746 746
747 747 emit d->updatedLayout();
748 748 emit capsWidthChanged();
749 749 }
750 750
751 751 qreal QCandlestickSeries::capsWidth() const
752 752 {
753 753 Q_D(const QCandlestickSeries);
754 754
755 755 return d->m_capsWidth;
756 756 }
757 757
758 758 void QCandlestickSeries::setCapsVisible(bool capsVisible)
759 759 {
760 760 Q_D(QCandlestickSeries);
761 761
762 762 if (d->m_capsVisible == capsVisible)
763 763 return;
764 764
765 765 d->m_capsVisible = capsVisible;
766 766
767 767 emit d->updated();
768 768 emit capsVisibilityChanged();
769 769 }
770 770
771 771 bool QCandlestickSeries::capsVisible() const
772 772 {
773 773 Q_D(const QCandlestickSeries);
774 774
775 775 return d->m_capsVisible;
776 776 }
777 777
778 778 void QCandlestickSeries::setIncreasingColor(const QColor &increasingColor)
779 779 {
780 780 Q_D(QCandlestickSeries);
781 781
782 782 QColor color;
783 783 if (increasingColor.isValid()) {
784 784 color = increasingColor;
785 785 d->m_customIncreasingColor = true;
786 786 } else {
787 787 color = d->m_brush.color();
788 788 color.setAlpha(128);
789 789 d->m_customIncreasingColor = false;
790 790 }
791 791
792 792 if (d->m_increasingColor == color)
793 793 return;
794 794
795 795 d->m_increasingColor = color;
796 796
797 797 emit d->updated();
798 798 emit increasingColorChanged();
799 799 }
800 800
801 801 QColor QCandlestickSeries::increasingColor() const
802 802 {
803 803 Q_D(const QCandlestickSeries);
804 804
805 805 return d->m_increasingColor;
806 806 }
807 807
808 808 void QCandlestickSeries::setDecreasingColor(const QColor &decreasingColor)
809 809 {
810 810 Q_D(QCandlestickSeries);
811 811
812 812 QColor color;
813 813 if (decreasingColor.isValid()) {
814 814 color = decreasingColor;
815 815 d->m_customDecreasingColor = true;
816 816 } else {
817 817 color = d->m_brush.color();
818 818 d->m_customDecreasingColor = false;
819 819 }
820 820
821 821 if (d->m_decreasingColor == color)
822 822 return;
823 823
824 824 d->m_decreasingColor = color;
825 825
826 826 emit d->updated();
827 827 emit decreasingColorChanged();
828 828 }
829 829
830 830 QColor QCandlestickSeries::decreasingColor() const
831 831 {
832 832 Q_D(const QCandlestickSeries);
833 833
834 834 return d->m_decreasingColor;
835 835 }
836 836
837 837 void QCandlestickSeries::setBrush(const QBrush &brush)
838 838 {
839 839 Q_D(QCandlestickSeries);
840 840
841 841 if (d->m_brush == brush)
842 842 return;
843 843
844 844 d->m_brush = brush;
845 845 if (!d->m_customIncreasingColor) {
846 846 QColor color = d->m_brush.color();
847 847 color.setAlpha(128);
848 848 if (d->m_increasingColor != color) {
849 849 d->m_increasingColor = color;
850 850 emit increasingColorChanged();
851 851 }
852 852 }
853 853 if (!d->m_customDecreasingColor && d->m_decreasingColor != d->m_brush.color()) {
854 854 d->m_decreasingColor = d->m_brush.color();
855 855 emit decreasingColorChanged();
856 856 }
857 857
858 858 emit d->updated();
859 859 emit brushChanged();
860 860 }
861 861
862 862 QBrush QCandlestickSeries::brush() const
863 863 {
864 864 Q_D(const QCandlestickSeries);
865 865
866 866 return d->m_brush;
867 867 }
868 868
869 869 void QCandlestickSeries::setPen(const QPen &pen)
870 870 {
871 871 Q_D(QCandlestickSeries);
872 872
873 873 if (d->m_pen == pen)
874 874 return;
875 875
876 876 d->m_pen = pen;
877 877
878 878 emit d->updated();
879 879 emit penChanged();
880 880 }
881 881
882 882 QPen QCandlestickSeries::pen() const
883 883 {
884 884 Q_D(const QCandlestickSeries);
885 885
886 886 return d->m_pen;
887 887 }
888 888
889 889 ////////////////////////////////////////////////////////////////////////////////////////////////////
890 890
891 891 QCandlestickSeriesPrivate::QCandlestickSeriesPrivate(QCandlestickSeries *q)
892 892 : QAbstractSeriesPrivate(q),
893 893 m_maximumColumnWidth(-1.0),
894 894 m_minimumColumnWidth(5.0),
895 895 m_bodyWidth(0.5),
896 896 m_bodyOutlineVisible(true),
897 897 m_capsWidth(0.5),
898 898 m_capsVisible(false),
899 899 m_increasingColor(QColor(Qt::transparent)),
900 900 m_decreasingColor(QChartPrivate::defaultBrush().color()),
901 901 m_customIncreasingColor(false),
902 902 m_customDecreasingColor(false),
903 903 m_brush(QChartPrivate::defaultBrush()),
904 904 m_pen(QChartPrivate::defaultPen()),
905 905 m_animation(nullptr)
906 906 {
907 907 }
908 908
909 909 QCandlestickSeriesPrivate::~QCandlestickSeriesPrivate()
910 910 {
911 911 disconnect(this, 0, 0, 0);
912 912 }
913 913
914 914 void QCandlestickSeriesPrivate::initializeDomain()
915 915 {
916 916 qreal minX(domain()->minX());
917 917 qreal maxX(domain()->maxX());
918 918 qreal minY(domain()->minY());
919 919 qreal maxY(domain()->maxY());
920 920
921 if (m_candlestickSets.count()) {
922 QCandlestickSet *set = m_candlestickSets.first();
921 if (m_sets.count()) {
922 QCandlestickSet *set = m_sets.first();
923 923 minX = set->timestamp();
924 924 maxX = set->timestamp();
925 925 minY = set->low();
926 926 maxY = set->high();
927 for (int i = 1; i < m_candlestickSets.count(); ++i) {
928 set = m_candlestickSets.at(i);
927 for (int i = 1; i < m_sets.count(); ++i) {
928 set = m_sets.at(i);
929 929 minX = qMin(minX, qreal(set->timestamp()));
930 930 maxX = qMax(maxX, qreal(set->timestamp()));
931 931 minY = qMin(minY, set->low());
932 932 maxY = qMax(maxY, set->high());
933 933 }
934 qreal extra = (maxX - minX) / m_candlestickSets.count() / 2;
934 qreal extra = (maxX - minX) / m_sets.count() / 2;
935 935 minX = minX - extra;
936 936 maxX = maxX + extra;
937 937 }
938 938
939 939 domain()->setRange(minX, maxX, minY, maxY);
940 940 }
941 941
942 942 void QCandlestickSeriesPrivate::initializeAxes()
943 943 {
944 944 foreach (QAbstractAxis* axis, m_axes) {
945 945 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
946 946 if (axis->orientation() == Qt::Horizontal)
947 947 populateBarCategories(qobject_cast<QBarCategoryAxis *>(axis));
948 948 }
949 949 }
950 950 }
951 951
952 952 void QCandlestickSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
953 953 {
954 954 Q_Q(QCandlestickSeries);
955 955
956 956 if (forced || QChartPrivate::defaultBrush() == m_brush) {
957 957 const QList<QGradient> gradients = theme->seriesGradients();
958 958 const QGradient gradient = gradients.at(index % gradients.size());
959 959 const QBrush brush(ChartThemeManager::colorAt(gradient, 0.5));
960 960 q->setBrush(brush);
961 961 }
962 962
963 963 if (forced || QChartPrivate::defaultPen() == m_pen) {
964 964 QPen pen = theme->outlinePen();
965 965 pen.setCosmetic(true);
966 966 q->setPen(pen);
967 967 }
968 968 }
969 969
970 970 void QCandlestickSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
971 971 {
972 972 Q_Q(QCandlestickSeries);
973 973
974 974 CandlestickChartItem *item = new CandlestickChartItem(q, parent);
975 975 m_item.reset(item);
976 976 QAbstractSeriesPrivate::initializeGraphics(parent);
977 977
978 978 if (m_chart) {
979 979 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries *)),
980 980 this, SLOT(handleSeriesChange(QAbstractSeries *)));
981 981 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)),
982 982 this, SLOT(handleSeriesRemove(QAbstractSeries *)));
983 983
984 984 item->handleCandlestickSeriesChange();
985 985 }
986 986 }
987 987
988 988 void QCandlestickSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
989 989 QEasingCurve &curve)
990 990 {
991 991 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
992 992 Q_ASSERT(item);
993 993
994 994 if (item->animation())
995 995 item->animation()->stopAndDestroyLater();
996 996
997 997 if (options.testFlag(QChart::SeriesAnimations))
998 998 m_animation = new CandlestickAnimation(item, duration, curve);
999 999 else
1000 1000 m_animation = nullptr;
1001 1001 item->setAnimation(m_animation);
1002 1002
1003 1003 QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
1004 1004 }
1005 1005
1006 1006 QList<QLegendMarker *> QCandlestickSeriesPrivate::createLegendMarkers(QLegend *legend)
1007 1007 {
1008 1008 Q_Q(QCandlestickSeries);
1009 1009
1010 1010 QList<QLegendMarker *> list;
1011 1011
1012 1012 return list << new QCandlestickLegendMarker(q, legend);
1013 1013 }
1014 1014
1015 1015 QAbstractAxis::AxisType QCandlestickSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
1016 1016 {
1017 1017 if (orientation == Qt::Horizontal)
1018 1018 return QAbstractAxis::AxisTypeBarCategory;
1019 1019
1020 1020 if (orientation == Qt::Vertical)
1021 1021 return QAbstractAxis::AxisTypeValue;
1022 1022
1023 1023 return QAbstractAxis::AxisTypeNoAxis;
1024 1024 }
1025 1025
1026 1026 QAbstractAxis* QCandlestickSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
1027 1027 {
1028 1028 const QAbstractAxis::AxisType axisType = defaultAxisType(orientation);
1029 1029
1030 1030 if (axisType == QAbstractAxis::AxisTypeBarCategory)
1031 1031 return new QBarCategoryAxis;
1032 1032
1033 1033 if (axisType == QAbstractAxis::AxisTypeValue)
1034 1034 return new QValueAxis;
1035 1035
1036 1036 return 0; // axisType == QAbstractAxis::AxisTypeNoAxis
1037 1037 }
1038 1038
1039 1039 bool QCandlestickSeriesPrivate::append(const QList<QCandlestickSet *> &sets)
1040 1040 {
1041 1041 foreach (QCandlestickSet *set, sets) {
1042 if ((set == 0) || m_candlestickSets.contains(set) || set->d_ptr->m_series)
1042 if ((set == 0) || m_sets.contains(set) || set->d_ptr->m_series)
1043 1043 return false; // Fail if any of the sets is null or is already appended.
1044 1044 if (sets.count(set) != 1)
1045 1045 return false; // Also fail if the same set occurs more than once in the given list.
1046 1046 }
1047 1047
1048 1048 foreach (QCandlestickSet *set, sets) {
1049 m_candlestickSets.append(set);
1049 m_sets.append(set);
1050 1050 connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1051 1051 connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
1052 1052 set->d_ptr->m_series = this;
1053 1053 }
1054 1054
1055 1055 return true;
1056 1056 }
1057 1057
1058 1058 bool QCandlestickSeriesPrivate::remove(const QList<QCandlestickSet *> &sets)
1059 1059 {
1060 1060 if (sets.count() == 0)
1061 1061 return false;
1062 1062
1063 1063 foreach (QCandlestickSet *set, sets) {
1064 if ((set == 0) || (!m_candlestickSets.contains(set)))
1064 if ((set == 0) || (!m_sets.contains(set)))
1065 1065 return false; // Fail if any of the sets is null or is not in series.
1066 1066 if (sets.count(set) != 1)
1067 1067 return false; // Also fail if the same set occurs more than once in the given list.
1068 1068 }
1069 1069
1070 1070 foreach (QCandlestickSet *set, sets) {
1071 1071 set->d_ptr->m_series = nullptr;
1072 m_candlestickSets.removeOne(set);
1072 m_sets.removeOne(set);
1073 1073 disconnect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1074 1074 disconnect(set->d_func(), SIGNAL(updatedCandlestick()),this, SIGNAL(updatedCandlesticks()));
1075 1075 }
1076 1076
1077 1077 return true;
1078 1078 }
1079 1079
1080 1080 bool QCandlestickSeriesPrivate::insert(int index, QCandlestickSet *set)
1081 1081 {
1082 if ((m_candlestickSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
1082 if ((m_sets.contains(set)) || (set == 0) || set->d_ptr->m_series)
1083 1083 return false; // Fail if set is already in list or set is null.
1084 1084
1085 m_candlestickSets.insert(index, set);
1085 m_sets.insert(index, set);
1086 1086 connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
1087 1087 connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
1088 1088 set->d_ptr->m_series = this;
1089 1089
1090 1090 return true;
1091 1091 }
1092 1092
1093 1093 void QCandlestickSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
1094 1094 {
1095 1095 Q_UNUSED(series);
1096 1096
1097 1097 if (m_chart) {
1098 1098 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
1099 1099 if (item)
1100 1100 item->handleCandlestickSeriesChange();
1101 1101 }
1102 1102 }
1103 1103
1104 1104 void QCandlestickSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
1105 1105 {
1106 1106 Q_Q(const QCandlestickSeries);
1107 1107
1108 1108 QCandlestickSeries *removedSeries = static_cast<QCandlestickSeries *>(series);
1109 1109
1110 1110 if (q == removedSeries && m_animation) {
1111 1111 m_animation->stopAll();
1112 1112 disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
1113 1113 }
1114 1114
1115 1115 if (q != removedSeries) {
1116 1116 CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
1117 1117 if (item)
1118 1118 item->handleCandlestickSeriesChange();
1119 1119 }
1120 1120 }
1121 1121
1122 1122 void QCandlestickSeriesPrivate::populateBarCategories(QBarCategoryAxis *axis)
1123 1123 {
1124 1124 if (axis->categories().isEmpty()) {
1125 1125 QStringList categories;
1126 for (int i = 0; i < m_candlestickSets.count(); ++i) {
1127 const qint64 timestamp = qRound64(m_candlestickSets.at(i)->timestamp());
1126 for (int i = 0; i < m_sets.count(); ++i) {
1127 const qint64 timestamp = qRound64(m_sets.at(i)->timestamp());
1128 1128 const QString timestampFormat = m_chart->locale().dateTimeFormat(QLocale::ShortFormat);
1129 1129 categories << QDateTime::fromMSecsSinceEpoch(timestamp).toString(timestampFormat);
1130 1130 }
1131 1131 axis->append(categories);
1132 1132 }
1133 1133 }
1134 1134
1135 1135 #include "moc_qcandlestickseries.cpp"
1136 1136 #include "moc_qcandlestickseries_p.cpp"
1137 1137
1138 1138 QT_CHARTS_END_NAMESPACE
@@ -1,131 +1,131
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QCANDLESTICKSERIES_H
31 31 #define QCANDLESTICKSERIES_H
32 32
33 33 #include <QtCharts/QAbstractSeries>
34 34
35 35 QT_CHARTS_BEGIN_NAMESPACE
36 36
37 37 class QCandlestickSeriesPrivate;
38 38 class QCandlestickSet;
39 39
40 40 class QT_CHARTS_EXPORT QCandlestickSeries : public QAbstractSeries
41 41 {
42 42 Q_OBJECT
43 43 Q_PROPERTY(int count READ count NOTIFY countChanged)
44 44 Q_PROPERTY(qreal maximumColumnWidth READ maximumColumnWidth WRITE setMaximumColumnWidth NOTIFY maximumColumnWidthChanged)
45 45 Q_PROPERTY(qreal minimumColumnWidth READ minimumColumnWidth WRITE setMinimumColumnWidth NOTIFY minimumColumnWidthChanged)
46 46 Q_PROPERTY(qreal bodyWidth READ bodyWidth WRITE setBodyWidth NOTIFY bodyWidthChanged)
47 47 Q_PROPERTY(bool bodyOutlineVisible READ bodyOutlineVisible WRITE setBodyOutlineVisible NOTIFY bodyOutlineVisibilityChanged)
48 48 Q_PROPERTY(qreal capsWidth READ capsWidth WRITE setCapsWidth NOTIFY capsWidthChanged)
49 49 Q_PROPERTY(bool capsVisible READ capsVisible WRITE setCapsVisible NOTIFY capsVisibilityChanged)
50 50 Q_PROPERTY(QColor increasingColor READ increasingColor WRITE setIncreasingColor NOTIFY increasingColorChanged)
51 51 Q_PROPERTY(QColor decreasingColor READ decreasingColor WRITE setDecreasingColor NOTIFY decreasingColorChanged)
52 52 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
53 53 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
54 54
55 55 public:
56 56 explicit QCandlestickSeries(QObject *parent = nullptr);
57 57 ~QCandlestickSeries();
58 58
59 59 bool append(QCandlestickSet *set);
60 60 bool remove(QCandlestickSet *set);
61 61 bool append(const QList<QCandlestickSet *> &sets);
62 62 bool remove(const QList<QCandlestickSet *> &sets);
63 63 bool insert(int index, QCandlestickSet *set);
64 64 bool take(QCandlestickSet *set);
65 65 void clear();
66 66
67 QList<QCandlestickSet *> candlestickSets() const;
67 QList<QCandlestickSet *> sets() const;
68 68 int count() const;
69 69
70 70 QAbstractSeries::SeriesType type() const;
71 71
72 72 void setMaximumColumnWidth(qreal maximumColumnWidth);
73 73 qreal maximumColumnWidth() const;
74 74
75 75 void setMinimumColumnWidth(qreal minimumColumnWidth);
76 76 qreal minimumColumnWidth() const;
77 77
78 78 void setBodyWidth(qreal bodyWidth);
79 79 qreal bodyWidth() const;
80 80
81 81 void setBodyOutlineVisible(bool bodyOutlineVisible);
82 82 bool bodyOutlineVisible() const;
83 83
84 84 void setCapsWidth(qreal capsWidth);
85 85 qreal capsWidth() const;
86 86
87 87 void setCapsVisible(bool capsVisible);
88 88 bool capsVisible() const;
89 89
90 90 void setIncreasingColor(const QColor &increasingColor);
91 91 QColor increasingColor() const;
92 92
93 93 void setDecreasingColor(const QColor &decreasingColor);
94 94 QColor decreasingColor() const;
95 95
96 96 void setBrush(const QBrush &brush);
97 97 QBrush brush() const;
98 98
99 99 void setPen(const QPen &pen);
100 100 QPen pen() const;
101 101
102 102 Q_SIGNALS:
103 103 void clicked(QCandlestickSet *set);
104 104 void hovered(bool status, QCandlestickSet *set);
105 105 void pressed(QCandlestickSet *set);
106 106 void released(QCandlestickSet *set);
107 107 void doubleClicked(QCandlestickSet *set);
108 108 void candlestickSetsAdded(const QList<QCandlestickSet *> &sets);
109 109 void candlestickSetsRemoved(const QList<QCandlestickSet *> &sets);
110 110 void countChanged();
111 111 void maximumColumnWidthChanged();
112 112 void minimumColumnWidthChanged();
113 113 void bodyWidthChanged();
114 114 void bodyOutlineVisibilityChanged();
115 115 void capsWidthChanged();
116 116 void capsVisibilityChanged();
117 117 void increasingColorChanged();
118 118 void decreasingColorChanged();
119 119 void brushChanged();
120 120 void penChanged();
121 121
122 122 private:
123 123 Q_DISABLE_COPY(QCandlestickSeries)
124 124 Q_DECLARE_PRIVATE(QCandlestickSeries)
125 125 friend class CandlestickChartItem;
126 126 friend class QCandlestickLegendMarkerPrivate;
127 127 };
128 128
129 129 QT_CHARTS_END_NAMESPACE
130 130
131 131 #endif // QCANDLESTICKSERIES_H
@@ -1,113 +1,113
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 // W A R N I N G
31 31 // -------------
32 32 //
33 33 // This file is not part of the Qt Chart API. It exists purely as an
34 34 // implementation detail. This header file may change from version to
35 35 // version without notice, or even be removed.
36 36 //
37 37 // We mean it.
38 38
39 39 #ifndef QCANDLESTICKSERIES_P_H
40 40 #define QCANDLESTICKSERIES_P_H
41 41
42 42 #include <private/qabstractseries_p.h>
43 43
44 44 QT_CHARTS_BEGIN_NAMESPACE
45 45
46 46 class CandlestickAnimation;
47 47 class QBarCategoryAxis;
48 48 class QCandlestickSeries;
49 49 class QCandlestickSet;
50 50 class QDateTimeAxis;
51 51
52 52 class QCandlestickSeriesPrivate : public QAbstractSeriesPrivate
53 53 {
54 54 Q_OBJECT
55 55
56 56 public:
57 57 QCandlestickSeriesPrivate(QCandlestickSeries *q);
58 58 ~QCandlestickSeriesPrivate();
59 59
60 60 void initializeDomain();
61 61 void initializeAxes();
62 62 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
63 63 void initializeGraphics(QGraphicsItem* parent);
64 64 void initializeAnimations(QChart::AnimationOptions options, int duration, QEasingCurve &curve);
65 65
66 66 QList<QLegendMarker *> createLegendMarkers(QLegend *legend);
67 67
68 68 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
69 69 QAbstractAxis *createDefaultAxis(Qt::Orientation orientation) const;
70 70
71 71 bool append(const QList<QCandlestickSet *> &sets);
72 72 bool remove(const QList<QCandlestickSet *> &sets);
73 73 bool insert(int index, QCandlestickSet *set);
74 74
75 75 Q_SIGNALS:
76 76 void clicked(int index, QCandlestickSet *set);
77 77 void pressed(int index, QCandlestickSet *set);
78 78 void released(int index, QCandlestickSet *set);
79 79 void doubleClicked(int index, QCandlestickSet *set);
80 80 void updated();
81 81 void updatedLayout();
82 82 void updatedCandlesticks();
83 83
84 84 private Q_SLOTS:
85 85 void handleSeriesChange(QAbstractSeries *series);
86 86 void handleSeriesRemove(QAbstractSeries *series);
87 87
88 88 private:
89 89 void populateBarCategories(QBarCategoryAxis *axis);
90 90
91 91 protected:
92 QList<QCandlestickSet *> m_candlestickSets;
92 QList<QCandlestickSet *> m_sets;
93 93 qreal m_maximumColumnWidth;
94 94 qreal m_minimumColumnWidth;
95 95 qreal m_bodyWidth;
96 96 bool m_bodyOutlineVisible;
97 97 qreal m_capsWidth;
98 98 bool m_capsVisible;
99 99 QColor m_increasingColor;
100 100 QColor m_decreasingColor;
101 101 bool m_customIncreasingColor;
102 102 bool m_customDecreasingColor;
103 103 QBrush m_brush;
104 104 QPen m_pen;
105 105 CandlestickAnimation *m_animation;
106 106
107 107 private:
108 108 Q_DECLARE_PUBLIC(QCandlestickSeries)
109 109 };
110 110
111 111 QT_CHARTS_END_NAMESPACE
112 112
113 113 #endif // QCANDLESTICKSERIES_P_H
@@ -1,322 +1,320
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QHCandlestickModelMapper>
31 31 #include <private/qcandlestickmodelmapper_p.h>
32 32
33 33 QT_CHARTS_BEGIN_NAMESPACE
34 34
35 35 /*!
36 36 \class QHCandlestickModelMapper
37 37 \since 5.8
38 38 \inmodule Qt Charts
39 39 \brief Horizontal model mapper for a candlestick series.
40 40
41 41 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
42 42 series, creating a connection between a QCandlestickSeries and the model object. A horizontal
43 43 model mapper maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}, and
44 44 reads the values of the set from the model's rows.
45 45
46 46 \note The model used must support adding and removing rows/columns and modifying the data of the
47 47 cells.
48 48 */
49 49
50 50 /*!
51 51 \qmltype HCandlestickModelMapper
52 52 \since 2.2
53 53 \instantiates QHCandlestickModelMapper
54 54 \inqmlmodule QtCharts
55 55 \brief Horizontal model mapper for a candlestick series.
56 56
57 57 HCandlestickModelMapper allows the use of a QAbstractItemModel-derived model with data in rows
58 58 as a data source for a candlestick series. It's possible to manipulate the data either through
59 59 QAbstractItemModel or QCandlestickSeries.
60 60
61 61 The following QML example creates a candlestick series with three candlestick sets (assuming the
62 62 model has at least four rows). Each candlestick set would contain data defined by timestamp,
63 63 open, high, low and close columns. The name of a set would be defined by the vertical header of
64 64 the row.
65 65 \qml
66 66 CandlestickSeries {
67 67 HCandlestickModelMapper {
68 68 model: myCustomModel // QAbstractItemModel derived implementation
69 69 timestampColumn: 1
70 70 openColumn: 2
71 71 highColumn: 3
72 72 lowColumn: 4
73 73 closeColumn: 5
74 firstCandlestickSetRow: 1
75 lastCandlestickSetRow: 3
74 firstSetRow: 1
75 lastSetRow: 3
76 76 }
77 77 }
78 78 \endqml
79 79
80 80 \note HCandlestickModelMapper keeps the series and the model in sync.
81 81 */
82 82
83 83 /*!
84 84 \qmlproperty QAbstractItemModel HCandlestickModelMapper::model
85 85 \brief The QAbstractItemModel-based model that is used by the mapper. The model must be
86 86 implemented and exposed to QML.
87 87
88 88 \note The model used must support adding and removing rows/columns and modifying the data of the
89 89 cells.
90 90 */
91 91
92 92 /*!
93 93 \qmlproperty CandlestickSeries HCandlestickModelMapper::series
94 94 \brief Defines the CandlestickSeries based object that is used by the mapper.
95 95
96 96 All the data in the series is discarded when it is set to the mapper. When a new series is
97 97 specified, the old series is disconnected (preserving its data).
98 98 */
99 99
100 100 /*!
101 101 \property QHCandlestickModelMapper::timestampColumn
102 102 \brief Defines the column of the model that contains the timestamp values of the
103 103 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
104 104 */
105 105
106 106 /*!
107 107 \qmlproperty int HCandlestickModelMapper::timestampColumn
108 108 \brief Defines the column of the model that contains the timestamp values of the
109 109 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
110 110 */
111 111
112 112 /*!
113 113 \property QHCandlestickModelMapper::openColumn
114 114 \brief Defines the column of the model that contains the open values of the
115 115 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
116 116 */
117 117
118 118 /*!
119 119 \qmlproperty int HCandlestickModelMapper::openColumn
120 120 \brief Defines the column of the model that contains the open values of the
121 121 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
122 122 */
123 123
124 124 /*!
125 125 \property QHCandlestickModelMapper::highColumn
126 126 \brief Defines the column of the model that contains the high values of the
127 127 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
128 128 */
129 129
130 130 /*!
131 131 \qmlproperty int HCandlestickModelMapper::highColumn
132 132 \brief Defines the column of the model that contains the high values of the
133 133 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
134 134 */
135 135
136 136 /*!
137 137 \property QHCandlestickModelMapper::lowColumn
138 138 \brief Defines the column of the model that contains the low values of the
139 139 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
140 140 */
141 141
142 142 /*!
143 143 \qmlproperty int HCandlestickModelMapper::lowColumn
144 144 \brief Defines the column of the model that contains the low values of the
145 145 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
146 146 */
147 147
148 148 /*!
149 149 \property QHCandlestickModelMapper::closeColumn
150 150 \brief Defines the column of the model that contains the close values of the
151 151 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
152 152 */
153 153
154 154 /*!
155 155 \qmlproperty int HCandlestickModelMapper::closeColumn
156 156 \brief Defines the column of the model that contains the close values of the
157 157 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
158 158 */
159 159
160 160 /*!
161 \property QHCandlestickModelMapper::firstCandlestickSetRow
161 \property QHCandlestickModelMapper::firstSetRow
162 162 \brief Defines the row of the model that is used as the data source for the first set. Default
163 163 value is -1 (invalid mapping).
164 164 */
165 165
166 166 /*!
167 \qmlproperty int HCandlestickModelMapper::firstCandlestickSetRow
167 \qmlproperty int HCandlestickModelMapper::firstSetRow
168 168 \brief Defines the row of the model that is used as the data source for the first set. Default
169 169 value is -1 (invalid mapping).
170 170 */
171 171
172 172 /*!
173 \property QHCandlestickModelMapper::lastCandlestickSetRow
173 \property QHCandlestickModelMapper::lastSetRow
174 174 \brief Defines the row of the model that is used as the data source for the last set. Default
175 175 value is -1 (invalid mapping).
176 176 */
177 177
178 178 /*!
179 \qmlproperty int HCandlestickModelMapper::lastCandlestickSetRow
179 \qmlproperty int HCandlestickModelMapper::lastSetRow
180 180 \brief Defines the row of the model that is used as the data source for the last set. Default
181 181 value is -1 (invalid mapping).
182 182 */
183 183
184 184 /*!
185 185 \fn void QHCandlestickModelMapper::timestampColumnChanged()
186 186 \brief Emitted when the column of the model that contains timestamp values is changed
187 187 \sa timestampColumn
188 188 */
189 189
190 190 /*!
191 191 \fn void QHCandlestickModelMapper::openColumnChanged()
192 192 \brief Emitted when the column of the model that contains open values is changed.
193 193 \sa openColumn
194 194 */
195 195 /*!
196 196 \fn void QHCandlestickModelMapper::highColumnChanged()
197 197 \brief Emitted when the column of the model that contains high values is changed.
198 198 \sa highColumn
199 199 */
200 200
201 201 /*!
202 202 \fn void QHCandlestickModelMapper::lowColumnChanged()
203 203 \brief Emitted when the column of the model that contains low values is changed.
204 204 \sa lowColumn
205 205 */
206 206
207 207 /*!
208 208 \fn void QHCandlestickModelMapper::closeColumnChanged()
209 209 \brief Emitted when the column of the model that contains close values is changed.
210 210 \sa closeColumn
211 211 */
212 212
213 213 /*!
214 \fn void QHCandlestickModelMapper::firstCandlestickSetRowChanged()
214 \fn void QHCandlestickModelMapper::firstSetRowChanged()
215 215 \brief Emitted when the row of the model that contains the data of the first set is changed.
216 \sa firstCandlestickSetRow
216 \sa firstSetRow
217 217 */
218 218
219 219 /*!
220 \fn void QHCandlestickModelMapper::lastCandlestickSetRowChanged()
220 \fn void QHCandlestickModelMapper::lastSetRowChanged()
221 221 \brief Emitted when the row of the model that contains the data of the last set is changed.
222 \sa lastCandlestickSetRow
222 \sa lastSetRow
223 223 */
224 224
225 225 /*!
226 226 Constructs a horizontal model mapper object which is a child of \a parent.
227 227 */
228 228 QHCandlestickModelMapper::QHCandlestickModelMapper(QObject *parent)
229 229 : QCandlestickModelMapper(parent)
230 230 {
231 231 connect(d_ptr, SIGNAL(timestampChanged()), this, SIGNAL(timestampColumnChanged()));
232 232 connect(d_ptr, SIGNAL(openChanged()), this, SIGNAL(openColumnChanged()));
233 233 connect(d_ptr, SIGNAL(highChanged()), this, SIGNAL(highColumnChanged()));
234 234 connect(d_ptr, SIGNAL(lowChanged()), this, SIGNAL(lowColumnChanged()));
235 235 connect(d_ptr, SIGNAL(closeChanged()), this, SIGNAL(closeColumnChanged()));
236 connect(d_ptr, SIGNAL(firstCandlestickSetSectionChanged()),
237 this, SIGNAL(firstCandlestickSetRowChanged()));
238 connect(d_ptr, SIGNAL(lastCandlestickSetSectionChanged()),
239 this, SIGNAL(lastCandlestickSetRowChanged()));
236 connect(d_ptr, SIGNAL(firstSetSectionChanged()), this, SIGNAL(firstSetRowChanged()));
237 connect(d_ptr, SIGNAL(lastSetSectionChanged()), this, SIGNAL(lastSetRowChanged()));
240 238 }
241 239
242 240 /*!
243 241 Returns Qt::Horizontal. This means that values of the set are read from rows.
244 242 */
245 243 Qt::Orientation QHCandlestickModelMapper::orientation() const
246 244 {
247 245 return Qt::Horizontal;
248 246 }
249 247
250 248 void QHCandlestickModelMapper::setTimestampColumn(int timestampColumn)
251 249 {
252 250 QCandlestickModelMapper::setTimestamp(timestampColumn);
253 251 }
254 252
255 253 int QHCandlestickModelMapper::timestampColumn() const
256 254 {
257 255 return QCandlestickModelMapper::timestamp();
258 256 }
259 257
260 258 void QHCandlestickModelMapper::setOpenColumn(int openColumn)
261 259 {
262 260 QCandlestickModelMapper::setOpen(openColumn);
263 261 }
264 262
265 263 int QHCandlestickModelMapper::openColumn() const
266 264 {
267 265 return QCandlestickModelMapper::open();
268 266 }
269 267
270 268 void QHCandlestickModelMapper::setHighColumn(int highColumn)
271 269 {
272 270 QCandlestickModelMapper::setHigh(highColumn);
273 271 }
274 272
275 273 int QHCandlestickModelMapper::highColumn() const
276 274 {
277 275 return QCandlestickModelMapper::high();
278 276 }
279 277
280 278 void QHCandlestickModelMapper::setLowColumn(int lowColumn)
281 279 {
282 280 QCandlestickModelMapper::setLow(lowColumn);
283 281 }
284 282
285 283 int QHCandlestickModelMapper::lowColumn() const
286 284 {
287 285 return QCandlestickModelMapper::low();
288 286 }
289 287
290 288 void QHCandlestickModelMapper::setCloseColumn(int closeColumn)
291 289 {
292 290 QCandlestickModelMapper::setClose(closeColumn);
293 291 }
294 292
295 293 int QHCandlestickModelMapper::closeColumn() const
296 294 {
297 295 return QCandlestickModelMapper::close();
298 296 }
299 297
300 void QHCandlestickModelMapper::setFirstCandlestickSetRow(int firstCandlestickSetRow)
298 void QHCandlestickModelMapper::setFirstSetRow(int firstSetRow)
301 299 {
302 QCandlestickModelMapper::setFirstCandlestickSetSection(firstCandlestickSetRow);
300 QCandlestickModelMapper::setFirstSetSection(firstSetRow);
303 301 }
304 302
305 int QHCandlestickModelMapper::firstCandlestickSetRow() const
303 int QHCandlestickModelMapper::firstSetRow() const
306 304 {
307 return QCandlestickModelMapper::firstCandlestickSetSection();
305 return QCandlestickModelMapper::firstSetSection();
308 306 }
309 307
310 void QHCandlestickModelMapper::setLastCandlestickSetRow(int lastCandlestickSetRow)
308 void QHCandlestickModelMapper::setLastSetRow(int lastSetRow)
311 309 {
312 QCandlestickModelMapper::setLastCandlestickSetSection(lastCandlestickSetRow);
310 QCandlestickModelMapper::setLastSetSection(lastSetRow);
313 311 }
314 312
315 int QHCandlestickModelMapper::lastCandlestickSetRow() const
313 int QHCandlestickModelMapper::lastSetRow() const
316 314 {
317 return QCandlestickModelMapper::lastCandlestickSetSection();
315 return QCandlestickModelMapper::lastSetSection();
318 316 }
319 317
320 318 #include "moc_qhcandlestickmodelmapper.cpp"
321 319
322 320 QT_CHARTS_END_NAMESPACE
@@ -1,86 +1,86
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QHCANDLESTICKMODELMAPPER_H
31 31 #define QHCANDLESTICKMODELMAPPER_H
32 32
33 33 #include <QtCharts/QCandlestickModelMapper>
34 34
35 35 QT_CHARTS_BEGIN_NAMESPACE
36 36 /* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
37 37 class QT_CHARTS_EXPORT QHCandlestickModelMapper : public QCandlestickModelMapper
38 38 {
39 39 Q_OBJECT
40 40 Q_PROPERTY(int timestampColumn READ timestampColumn WRITE setTimestampColumn NOTIFY timestampColumnChanged)
41 41 Q_PROPERTY(int openColumn READ openColumn WRITE setOpenColumn NOTIFY openColumnChanged)
42 42 Q_PROPERTY(int highColumn READ highColumn WRITE setHighColumn NOTIFY highColumnChanged)
43 43 Q_PROPERTY(int lowColumn READ lowColumn WRITE setLowColumn NOTIFY lowColumnChanged)
44 44 Q_PROPERTY(int closeColumn READ closeColumn WRITE setCloseColumn NOTIFY closeColumnChanged)
45 Q_PROPERTY(int firstCandlestickSetRow READ firstCandlestickSetRow WRITE setFirstCandlestickSetRow NOTIFY firstCandlestickSetRowChanged)
46 Q_PROPERTY(int lastCandlestickSetRow READ lastCandlestickSetRow WRITE setLastCandlestickSetRow NOTIFY lastCandlestickSetRowChanged)
45 Q_PROPERTY(int firstSetRow READ firstSetRow WRITE setFirstSetRow NOTIFY firstSetRowChanged)
46 Q_PROPERTY(int lastSetRow READ lastSetRow WRITE setLastSetRow NOTIFY lastSetRowChanged)
47 47
48 48 public:
49 49 explicit QHCandlestickModelMapper(QObject *parent = nullptr);
50 50
51 51 Qt::Orientation orientation() const;
52 52
53 53 void setTimestampColumn(int timestampColumn);
54 54 int timestampColumn() const;
55 55
56 56 void setOpenColumn(int openColumn);
57 57 int openColumn() const;
58 58
59 59 void setHighColumn(int highColumn);
60 60 int highColumn() const;
61 61
62 62 void setLowColumn(int lowColumn);
63 63 int lowColumn() const;
64 64
65 65 void setCloseColumn(int closeColumn);
66 66 int closeColumn() const;
67 67
68 void setFirstCandlestickSetRow(int firstCandlestickSetRow);
69 int firstCandlestickSetRow() const;
68 void setFirstSetRow(int firstSetRow);
69 int firstSetRow() const;
70 70
71 void setLastCandlestickSetRow(int lastCandlestickSetRow);
72 int lastCandlestickSetRow() const;
71 void setLastSetRow(int lastSetRow);
72 int lastSetRow() const;
73 73
74 74 Q_SIGNALS:
75 75 void timestampColumnChanged();
76 76 void openColumnChanged();
77 77 void highColumnChanged();
78 78 void lowColumnChanged();
79 79 void closeColumnChanged();
80 void firstCandlestickSetRowChanged();
81 void lastCandlestickSetRowChanged();
80 void firstSetRowChanged();
81 void lastSetRowChanged();
82 82 };
83 83
84 84 QT_CHARTS_END_NAMESPACE
85 85
86 86 #endif // QHCANDLESTICKMODELMAPPER_H
@@ -1,323 +1,321
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QVCandlestickModelMapper>
31 31 #include <private/qcandlestickmodelmapper_p.h>
32 32
33 33 QT_CHARTS_BEGIN_NAMESPACE
34 34
35 35 /*!
36 36 \class QVCandlestickModelMapper
37 37 \since 5.8
38 38 \inmodule Qt Charts
39 39 \brief Vertical model mapper for a candlestick series.
40 40
41 41 Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart
42 42 series, creating a connection between a QCandlestickSeries and the model object. A vertical
43 43 model mapper maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}, and
44 44 reads the values of the set from the model's columns.
45 45
46 46 \note The model used must support adding and removing rows/columns and modifying the data of the
47 47 cells.
48 48 */
49 49
50 50 /*!
51 51 \qmltype VCandlestickModelMapper
52 52 \since 2.2
53 53 \instantiates QVCandlestickModelMapper
54 54 \inqmlmodule QtCharts
55 55 \brief Vertical model mapper for a candlestick series.
56 56
57 57 VCandlestickModelMapper allows the use of a QAbstractItemModel-derived model with data in
58 58 columns as a data source for a candlestick series. It's possible to manipulate the data either
59 59 through QAbstractItemModel or QCandlestickSeries.
60 60
61 61 The following QML example creates a candlestick series with three candlestick sets (assuming the
62 62 model has at least four columns). Each candlestick set would contain data defined by timestamp,
63 63 open, high, low and close rows. The name of a set would be defined by the horizontal header of
64 64 the column.
65 65 \qml
66 66 CandlestickSeries {
67 67 VCandlestickModelMapper {
68 68 model: myCustomModel // QAbstractItemModel derived implementation
69 69 timestampRow: 1
70 70 openRow: 2
71 71 highRow: 3
72 72 lowRow: 4
73 73 closeRow: 5
74 firstCandlestickSetColumn: 1
75 lastCandlestickSetColumn: 3
74 firstSetColumn: 1
75 lastSetColumn: 3
76 76 }
77 77 }
78 78 \endqml
79 79
80 80 \note VCandlestickModelMapper keeps the series and the model in sync.
81 81 */
82 82
83 83 /*!
84 84 \qmlproperty QAbstractItemModel VCandlestickModelMapper::model
85 85 \brief The QAbstractItemModel-based model that is used by the mapper. The model must be
86 86 implemented and exposed to QML.
87 87
88 88 \note The model used must support adding and removing rows/columns and modifying the data of the
89 89 cells.
90 90 */
91 91
92 92 /*!
93 93 \qmlproperty CandlestickSeries VCandlestickModelMapper::series
94 94 \brief Defines the CandlestickSeries based object that is used by the mapper.
95 95
96 96 All the data in the series is discarded when it is set to the mapper. When a new series is
97 97 specified, the old series is disconnected (preserving its data).
98 98 */
99 99
100 100 /*!
101 101 \property QVCandlestickModelMapper::timestampRow
102 102 \brief Defines the row of the model that contains the timestamp values of the
103 103 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
104 104 */
105 105
106 106 /*!
107 107 \qmlproperty int VCandlestickModelMapper::timestampRow
108 108 \brief Defines the row of the model that contains the timestamp values of the
109 109 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
110 110 */
111 111
112 112 /*!
113 113 \property QVCandlestickModelMapper::openRow
114 114 \brief Defines the row of the model that contains the open values of the
115 115 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
116 116 */
117 117
118 118 /*!
119 119 \qmlproperty int VCandlestickModelMapper::openRow
120 120 \brief Defines the row of the model that contains the open values of the
121 121 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
122 122 */
123 123
124 124 /*!
125 125 \property QVCandlestickModelMapper::highRow
126 126 \brief Defines the row of the model that contains the high values of the
127 127 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
128 128 */
129 129
130 130 /*!
131 131 \qmlproperty int VCandlestickModelMapper::highRow
132 132 \brief Defines the row of the model that contains the high values of the
133 133 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
134 134 */
135 135
136 136 /*!
137 137 \property QVCandlestickModelMapper::lowRow
138 138 \brief Defines the row of the model that contains the low values of the
139 139 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
140 140 */
141 141
142 142 /*!
143 143 \qmlproperty int VCandlestickModelMapper::lowRow
144 144 \brief Defines the row of the model that contains the low values of the
145 145 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
146 146 */
147 147
148 148 /*!
149 149 \property QVCandlestickModelMapper::closeRow
150 150 \brief Defines the row of the model that contains the close values of the
151 151 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
152 152 */
153 153
154 154 /*!
155 155 \qmlproperty int VCandlestickModelMapper::closeRow
156 156 \brief Defines the row of the model that contains the close values of the
157 157 \l {QCandlestickSet} {QCandlestickSets} in the series. Default value is -1 (invalid mapping).
158 158 */
159 159
160 160 /*!
161 \property QVCandlestickModelMapper::firstCandlestickSetColumn
161 \property QVCandlestickModelMapper::firstSetColumn
162 162 \brief Defines the column of the model that is used as the data source for the first set.
163 163 Default value is -1 (invalid mapping).
164 164 */
165 165
166 166 /*!
167 \qmlproperty int VCandlestickModelMapper::firstCandlestickSetColumn
167 \qmlproperty int VCandlestickModelMapper::firstSetColumn
168 168 \brief Defines the column of the model that is used as the data source for the first set.
169 169 Default value is -1 (invalid mapping).
170 170 */
171 171
172 172 /*!
173 \property QVCandlestickModelMapper::lastCandlestickSetColumn
173 \property QVCandlestickModelMapper::lastSetColumn
174 174 \brief Defines the column of the model that is used as the data source for the last set. Default
175 175 value is -1 (invalid mapping).
176 176 */
177 177
178 178 /*!
179 \qmlproperty int VCandlestickModelMapper::lastCandlestickSetColumn
179 \qmlproperty int VCandlestickModelMapper::lastSetColumn
180 180 \brief Defines the column of the model that is used as the data source for the last set. Default
181 181 value is -1 (invalid mapping).
182 182 */
183 183
184 184 /*!
185 185 \fn void QVCandlestickModelMapper::timestampRowChanged()
186 186 \brief Emitted when the row of the model that contains timestamp values is changed.
187 187 \sa timestampRow
188 188 */
189 189
190 190 /*!
191 191 \fn void QVCandlestickModelMapper::openRowChanged()
192 192 \brief Emitted when the row of the model that contains open values is changed.
193 193 \sa openRow
194 194 */
195 195
196 196 /*!
197 197 \fn void QVCandlestickModelMapper::highRowChanged()
198 198 \brief Emitted when the row of the model that contains high values is changed.
199 199 \sa highRow
200 200 */
201 201
202 202 /*!
203 203 \fn void QVCandlestickModelMapper::lowRowChanged()
204 204 \brief Emitted when the row of the model that contains low values is changed.
205 205 \sa lowRow
206 206 */
207 207
208 208 /*!
209 209 \fn void QVCandlestickModelMapper::closeRowChanged()
210 210 \brief Emitted when the row of the model that contains close values is changed.
211 211 \sa closeRow
212 212 */
213 213
214 214 /*!
215 \fn void QVCandlestickModelMapper::firstCandlestickSetColumnChanged()
215 \fn void QVCandlestickModelMapper::firstSetColumnChanged()
216 216 \brief Emitted when the column of the model that contains the data of the first set is changed.
217 \sa firstCandlestickSetColumn
217 \sa firstSetColumn
218 218 */
219 219
220 220 /*!
221 \fn void QVCandlestickModelMapper::lastCandlestickSetColumnChanged()
221 \fn void QVCandlestickModelMapper::lastSetColumnChanged()
222 222 \brief Emitted when the column of the model that contains the data of the last set is changed.
223 \sa lastCandlestickSetColumn
223 \sa lastSetColumn
224 224 */
225 225
226 226 /*!
227 227 Constructs a vertical model mapper object which is a child of \a parent.
228 228 */
229 229 QVCandlestickModelMapper::QVCandlestickModelMapper(QObject *parent)
230 230 : QCandlestickModelMapper(parent)
231 231 {
232 232 connect(d_ptr, SIGNAL(timestampChanged()), this, SIGNAL(timestampRowChanged()));
233 233 connect(d_ptr, SIGNAL(openChanged()), this, SIGNAL(openRowChanged()));
234 234 connect(d_ptr, SIGNAL(highChanged()), this, SIGNAL(highRowChanged()));
235 235 connect(d_ptr, SIGNAL(lowChanged()), this, SIGNAL(lowRowChanged()));
236 236 connect(d_ptr, SIGNAL(closeChanged()), this, SIGNAL(closeRowChanged()));
237 connect(d_ptr, SIGNAL(firstCandlestickSetSectionChanged()),
238 this, SIGNAL(firstCandlestickSetColumnChanged()));
239 connect(d_ptr, SIGNAL(lastCandlestickSetSectionChanged()),
240 this, SIGNAL(lastCandlestickSetColumnChanged()));
237 connect(d_ptr, SIGNAL(firstSetSectionChanged()), this, SIGNAL(firstSetColumnChanged()));
238 connect(d_ptr, SIGNAL(lastSetSectionChanged()), this, SIGNAL(lastSetColumnChanged()));
241 239 }
242 240
243 241 /*!
244 242 Returns Qt::Vertical. This means that values of the set are read from columns.
245 243 */
246 244 Qt::Orientation QVCandlestickModelMapper::orientation() const
247 245 {
248 246 return Qt::Vertical;
249 247 }
250 248
251 249 void QVCandlestickModelMapper::setTimestampRow(int timestampRow)
252 250 {
253 251 QCandlestickModelMapper::setTimestamp(timestampRow);
254 252 }
255 253
256 254 int QVCandlestickModelMapper::timestampRow() const
257 255 {
258 256 return QCandlestickModelMapper::timestamp();
259 257 }
260 258
261 259 void QVCandlestickModelMapper::setOpenRow(int openRow)
262 260 {
263 261 QCandlestickModelMapper::setOpen(openRow);
264 262 }
265 263
266 264 int QVCandlestickModelMapper::openRow() const
267 265 {
268 266 return QCandlestickModelMapper::open();
269 267 }
270 268
271 269 void QVCandlestickModelMapper::setHighRow(int highRow)
272 270 {
273 271 QCandlestickModelMapper::setHigh(highRow);
274 272 }
275 273
276 274 int QVCandlestickModelMapper::highRow() const
277 275 {
278 276 return QCandlestickModelMapper::high();
279 277 }
280 278
281 279 void QVCandlestickModelMapper::setLowRow(int lowRow)
282 280 {
283 281 QCandlestickModelMapper::setLow(lowRow);
284 282 }
285 283
286 284 int QVCandlestickModelMapper::lowRow() const
287 285 {
288 286 return QCandlestickModelMapper::low();
289 287 }
290 288
291 289 void QVCandlestickModelMapper::setCloseRow(int closeRow)
292 290 {
293 291 QCandlestickModelMapper::setClose(closeRow);
294 292 }
295 293
296 294 int QVCandlestickModelMapper::closeRow() const
297 295 {
298 296 return QCandlestickModelMapper::close();
299 297 }
300 298
301 void QVCandlestickModelMapper::setFirstCandlestickSetColumn(int firstCandlestickSetColumn)
299 void QVCandlestickModelMapper::setFirstSetColumn(int firstSetColumn)
302 300 {
303 QCandlestickModelMapper::setFirstCandlestickSetSection(firstCandlestickSetColumn);
301 QCandlestickModelMapper::setFirstSetSection(firstSetColumn);
304 302 }
305 303
306 int QVCandlestickModelMapper::firstCandlestickSetColumn() const
304 int QVCandlestickModelMapper::firstSetColumn() const
307 305 {
308 return QCandlestickModelMapper::firstCandlestickSetSection();
306 return QCandlestickModelMapper::firstSetSection();
309 307 }
310 308
311 void QVCandlestickModelMapper::setLastCandlestickSetColumn(int lastCandlestickSetColumn)
309 void QVCandlestickModelMapper::setLastSetColumn(int lastSetColumn)
312 310 {
313 QCandlestickModelMapper::setLastCandlestickSetSection(lastCandlestickSetColumn);
311 QCandlestickModelMapper::setLastSetSection(lastSetColumn);
314 312 }
315 313
316 int QVCandlestickModelMapper::lastCandlestickSetColumn() const
314 int QVCandlestickModelMapper::lastSetColumn() const
317 315 {
318 return QCandlestickModelMapper::lastCandlestickSetSection();
316 return QCandlestickModelMapper::lastSetSection();
319 317 }
320 318
321 319 #include "moc_qvcandlestickmodelmapper.cpp"
322 320
323 321 QT_CHARTS_END_NAMESPACE
@@ -1,86 +1,86
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #ifndef QVCANDLESTICKMODELMAPPER_H
31 31 #define QVCANDLESTICKMODELMAPPER_H
32 32
33 33 #include <QtCharts/QCandlestickModelMapper>
34 34
35 35 QT_CHARTS_BEGIN_NAMESPACE
36 36 /* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
37 37 class QT_CHARTS_EXPORT QVCandlestickModelMapper : public QCandlestickModelMapper
38 38 {
39 39 Q_OBJECT
40 40 Q_PROPERTY(int timestampRow READ timestampRow WRITE setTimestampRow NOTIFY timestampRowChanged)
41 41 Q_PROPERTY(int openRow READ openRow WRITE setOpenRow NOTIFY openRowChanged)
42 42 Q_PROPERTY(int highRow READ highRow WRITE setHighRow NOTIFY highRowChanged)
43 43 Q_PROPERTY(int lowRow READ lowRow WRITE setLowRow NOTIFY lowRowChanged)
44 44 Q_PROPERTY(int closeRow READ closeRow WRITE setCloseRow NOTIFY closeRowChanged)
45 Q_PROPERTY(int firstCandlestickSetColumn READ firstCandlestickSetColumn WRITE setFirstCandlestickSetColumn NOTIFY firstCandlestickSetColumnChanged)
46 Q_PROPERTY(int lastCandlestickSetColumn READ lastCandlestickSetColumn WRITE setLastCandlestickSetColumn NOTIFY lastCandlestickSetColumnChanged)
45 Q_PROPERTY(int firstSetColumn READ firstSetColumn WRITE setFirstSetColumn NOTIFY firstSetColumnChanged)
46 Q_PROPERTY(int lastSetColumn READ lastSetColumn WRITE setLastSetColumn NOTIFY lastSetColumnChanged)
47 47
48 48 public:
49 49 explicit QVCandlestickModelMapper(QObject *parent = nullptr);
50 50
51 51 Qt::Orientation orientation() const;
52 52
53 53 void setTimestampRow(int timestampRow);
54 54 int timestampRow() const;
55 55
56 56 void setOpenRow(int openRow);
57 57 int openRow() const;
58 58
59 59 void setHighRow(int highRow);
60 60 int highRow() const;
61 61
62 62 void setLowRow(int lowRow);
63 63 int lowRow() const;
64 64
65 65 void setCloseRow(int closeRow);
66 66 int closeRow() const;
67 67
68 void setFirstCandlestickSetColumn(int firstCandlestickSetColumn);
69 int firstCandlestickSetColumn() const;
68 void setFirstSetColumn(int firstSetColumn);
69 int firstSetColumn() const;
70 70
71 void setLastCandlestickSetColumn(int lastCandlestickSetColumn);
72 int lastCandlestickSetColumn() const;
71 void setLastSetColumn(int lastSetColumn);
72 int lastSetColumn() const;
73 73
74 74 Q_SIGNALS:
75 75 void timestampRowChanged();
76 76 void openRowChanged();
77 77 void highRowChanged();
78 78 void lowRowChanged();
79 79 void closeRowChanged();
80 void firstCandlestickSetColumnChanged();
81 void lastCandlestickSetColumnChanged();
80 void firstSetColumnChanged();
81 void lastSetColumnChanged();
82 82 };
83 83
84 84 QT_CHARTS_END_NAMESPACE
85 85
86 86 #endif // QVCANDLESTICKMODELMAPPER_H
@@ -1,244 +1,244
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QHCandlestickModelMapper>
31 31 #include <QtCharts/QVCandlestickModelMapper>
32 32 #include "declarativeaxes.h"
33 33 #include "declarativecandlestickseries.h"
34 34
35 35 QT_CHARTS_BEGIN_NAMESPACE
36 36
37 37 DeclarativeCandlestickSet::DeclarativeCandlestickSet(qreal timestamp, QObject *parent)
38 38 : QCandlestickSet(timestamp, parent)
39 39 {
40 40 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
41 41 }
42 42
43 43 void DeclarativeCandlestickSet::setBrushFilename(const QString &brushFilename)
44 44 {
45 45 QImage brushImage(brushFilename);
46 46 if (QCandlestickSet::brush().textureImage() != brushImage) {
47 47 QBrush brush = QCandlestickSet::brush();
48 48 brush.setTextureImage(brushImage);
49 49
50 50 QCandlestickSet::setBrush(brush);
51 51
52 52 m_brushFilename = brushFilename;
53 53 m_brushImage = brushImage;
54 54
55 55 emit brushFilenameChanged(brushFilename);
56 56 }
57 57 }
58 58
59 59 QString DeclarativeCandlestickSet::brushFilename() const
60 60 {
61 61 return m_brushFilename;
62 62 }
63 63
64 64 void DeclarativeCandlestickSet::handleBrushChanged()
65 65 {
66 66 // If the texture image of the brush has changed along the brush
67 67 // the brush file name needs to be cleared.
68 68 if (!m_brushFilename.isEmpty() && QCandlestickSet::brush().textureImage() != m_brushImage) {
69 69 m_brushFilename.clear();
70 70 emit brushFilenameChanged(QString());
71 71 }
72 72 }
73 73
74 74 // Declarative candlestick series ==================================================================
75 75
76 76 DeclarativeCandlestickSeries::DeclarativeCandlestickSeries(QQuickItem *parent)
77 77 : QCandlestickSeries(parent),
78 78 m_axes(new DeclarativeAxes(this))
79 79 {
80 80 connect(m_axes, SIGNAL(axisXChanged(QAbstractAxis*)),
81 81 this, SIGNAL(axisXChanged(QAbstractAxis*)));
82 82 connect(m_axes, SIGNAL(axisYChanged(QAbstractAxis*)),
83 83 this, SIGNAL(axisYChanged(QAbstractAxis*)));
84 84 connect(m_axes, SIGNAL(axisXTopChanged(QAbstractAxis*)),
85 85 this, SIGNAL(axisXTopChanged(QAbstractAxis*)));
86 86 connect(m_axes, SIGNAL(axisYRightChanged(QAbstractAxis*)),
87 87 this, SIGNAL(axisYRightChanged(QAbstractAxis*)));
88 88
89 89 connect(this, SIGNAL(hovered(bool, QCandlestickSet *)),
90 90 this, SLOT(onHovered(bool, QCandlestickSet *)));
91 91 connect(this, SIGNAL(clicked(QCandlestickSet *)), this, SLOT(onClicked(QCandlestickSet *)));
92 92 connect(this, SIGNAL(pressed(QCandlestickSet *)), this, SLOT(onPressed(QCandlestickSet *)));
93 93 connect(this, SIGNAL(released(QCandlestickSet *)), this, SLOT(onReleased(QCandlestickSet *)));
94 94 connect(this, SIGNAL(doubleClicked(QCandlestickSet *)),
95 95 this, SLOT(onDoubleClicked(QCandlestickSet *)));
96 96
97 97 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
98 98 }
99 99
100 100 QQmlListProperty<QObject> DeclarativeCandlestickSeries::seriesChildren()
101 101 {
102 102 return QQmlListProperty<QObject>(this, 0, &DeclarativeCandlestickSeries::appendSeriesChildren,
103 103 0, 0, 0);
104 104 }
105 105
106 106 void DeclarativeCandlestickSeries::setBrushFilename(const QString &brushFilename)
107 107 {
108 108 QImage brushImage(brushFilename);
109 109 if (QCandlestickSeries::brush().textureImage() != brushImage) {
110 110 QBrush brush = QCandlestickSeries::brush();
111 111 brush.setTextureImage(brushImage);
112 112
113 113 QCandlestickSeries::setBrush(brush);
114 114
115 115 m_brushFilename = brushFilename;
116 116 m_brushImage = brushImage;
117 117
118 118 emit brushFilenameChanged(brushFilename);
119 119 }
120 120 }
121 121
122 122 QString DeclarativeCandlestickSeries::brushFilename() const
123 123 {
124 124 return m_brushFilename;
125 125 }
126 126
127 127 DeclarativeCandlestickSet *DeclarativeCandlestickSeries::at(int index)
128 128 {
129 QList<QCandlestickSet *> sets = candlestickSets();
129 QList<QCandlestickSet *> sets = this->sets();
130 130 if (index >= 0 && index < sets.count())
131 131 return qobject_cast<DeclarativeCandlestickSet *>(sets[index]);
132 132
133 133 return 0;
134 134 }
135 135
136 136 bool DeclarativeCandlestickSeries::append(DeclarativeCandlestickSet *set)
137 137 {
138 138 return QCandlestickSeries::append(qobject_cast<QCandlestickSet *>(set));
139 139 }
140 140
141 141 bool DeclarativeCandlestickSeries::remove(DeclarativeCandlestickSet *set)
142 142 {
143 143 return QCandlestickSeries::remove(qobject_cast<QCandlestickSet *>(set));
144 144 }
145 145
146 146 bool DeclarativeCandlestickSeries::append(qreal open, qreal high, qreal low, qreal close,
147 147 qreal timestamp)
148 148 {
149 149 QCandlestickSet *set = new QCandlestickSet(open, high, low, close, timestamp);
150 150 if (!QCandlestickSeries::append(set)) {
151 151 delete set;
152 152 return false;
153 153 }
154 154
155 155 return true;
156 156 }
157 157
158 158 bool DeclarativeCandlestickSeries::remove(qreal timestamp)
159 159 {
160 160 for (int i = 0; i < count(); ++i) {
161 QCandlestickSet *set = candlestickSets().at(i);
161 QCandlestickSet *set = sets().at(i);
162 162 if (set->timestamp() == timestamp)
163 163 return QCandlestickSeries::remove(set);
164 164 }
165 165
166 166 return false;
167 167 }
168 168
169 169 bool DeclarativeCandlestickSeries::insert(int index, DeclarativeCandlestickSet *set)
170 170 {
171 171 return QCandlestickSeries::insert(index, qobject_cast<QCandlestickSet *>(set));
172 172 }
173 173
174 174 void DeclarativeCandlestickSeries::clear()
175 175 {
176 176 QCandlestickSeries::clear();
177 177 }
178 178
179 179 void DeclarativeCandlestickSeries::classBegin()
180 180 {
181 181 // do nothing
182 182 }
183 183
184 184 void DeclarativeCandlestickSeries::componentComplete()
185 185 {
186 186 foreach (QObject *child, children()) {
187 187 if (qobject_cast<DeclarativeCandlestickSet *>(child)) {
188 188 QCandlestickSeries::append(qobject_cast<DeclarativeCandlestickSet *>(child));
189 189 } else if (qobject_cast<QHCandlestickModelMapper *>(child)) {
190 190 QHCandlestickModelMapper *mapper = qobject_cast<QHCandlestickModelMapper *>(child);
191 191 mapper->setSeries(this);
192 192 } else if (qobject_cast<QVCandlestickModelMapper *>(child)) {
193 193 QVCandlestickModelMapper *mapper = qobject_cast<QVCandlestickModelMapper *>(child);
194 194 mapper->setSeries(this);
195 195 } // else: do nothing
196 196 }
197 197 }
198 198
199 199 void DeclarativeCandlestickSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
200 200 QObject *element)
201 201 {
202 202 // Empty implementation; the children are parsed in componentComplete instead
203 203 Q_UNUSED(list);
204 204 Q_UNUSED(element);
205 205 }
206 206
207 207 void DeclarativeCandlestickSeries::onClicked(QCandlestickSet *set)
208 208 {
209 209 emit clicked(qobject_cast<DeclarativeCandlestickSet *>(set));
210 210 }
211 211
212 212 void DeclarativeCandlestickSeries::onHovered(bool status, QCandlestickSet *set)
213 213 {
214 214 emit hovered(status, qobject_cast<DeclarativeCandlestickSet *>(set));
215 215 }
216 216
217 217 void DeclarativeCandlestickSeries::onPressed(QCandlestickSet *set)
218 218 {
219 219 emit pressed(qobject_cast<DeclarativeCandlestickSet *>(set));
220 220 }
221 221
222 222 void DeclarativeCandlestickSeries::onReleased(QCandlestickSet *set)
223 223 {
224 224 emit released(qobject_cast<DeclarativeCandlestickSet *>(set));
225 225 }
226 226
227 227 void DeclarativeCandlestickSeries::onDoubleClicked(QCandlestickSet *set)
228 228 {
229 229 emit doubleClicked(qobject_cast<DeclarativeCandlestickSet *>(set));
230 230 }
231 231
232 232 void DeclarativeCandlestickSeries::handleBrushChanged()
233 233 {
234 234 // If the texture image of the brush has changed along the brush
235 235 // the brush file name needs to be cleared.
236 236 if (!m_brushFilename.isEmpty() && QCandlestickSeries::brush().textureImage() != m_brushImage) {
237 237 m_brushFilename.clear();
238 238 emit brushFilenameChanged(QString());
239 239 }
240 240 }
241 241
242 242 #include "moc_declarativecandlestickseries.cpp"
243 243
244 244 QT_CHARTS_END_NAMESPACE
@@ -1,632 +1,632
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QCandlestickSeries>
31 31 #include <QtCharts/QCandlestickSet>
32 32 #include <QtCharts/QChartView>
33 33 #include <QtCharts/QHCandlestickModelMapper>
34 34 #include <QtCharts/QVCandlestickModelMapper>
35 35 #include <QtCore/QString>
36 36 #include <QtGui/QStandardItemModel>
37 37 #include <QtTest/QtTest>
38 38
39 39 QT_CHARTS_USE_NAMESPACE
40 40
41 41 class tst_qcandlestickmodelmapper : public QObject
42 42 {
43 43 Q_OBJECT
44 44
45 45 public:
46 46 tst_qcandlestickmodelmapper();
47 47
48 48 void createVerticalMapper();
49 49 void createHorizontalMapper();
50 50
51 51 public Q_SLOTS:
52 52 void initTestCase();
53 53 void cleanupTestCase();
54 54 void init();
55 55 void cleanup();
56 56
57 57 private Q_SLOTS:
58 58 void verticalMapper_data();
59 59 void verticalMapper();
60 60 void verticalMapperCustomMapping_data();
61 61 void verticalMapperCustomMapping();
62 62 void horizontalMapper_data();
63 63 void horizontalMapper();
64 64 void horizontalMapperCustomMapping_data();
65 65 void horizontalMapperCustomMapping();
66 66 void seriesUpdated();
67 67 void verticalModelInsertRows();
68 68 void verticalModelRemoveRows();
69 69 void verticalModelInsertColumns();
70 70 void verticalModelRemoveColumns();
71 71 void horizontalModelInsertRows();
72 72 void horizontalModelRemoveRows();
73 73 void horizontalModelInsertColumns();
74 74 void horizontalModelRemoveColumns();
75 75 void modelUpdateCell();
76 76 void verticalMapperSignals();
77 77 void horizontalMapperSignals();
78 78
79 79 private:
80 80 QStandardItemModel *m_model;
81 81 int m_modelRowCount;
82 82 int m_modelColumnCount;
83 83
84 84 QCandlestickSeries *m_series;
85 85 QChart *m_chart;
86 86 QChartView *m_chartView;
87 87
88 88 QHCandlestickModelMapper *m_hMapper;
89 89 QVCandlestickModelMapper *m_vMapper;
90 90 };
91 91
92 92 tst_qcandlestickmodelmapper::tst_qcandlestickmodelmapper()
93 93 : m_model(nullptr),
94 94 m_modelRowCount(10),
95 95 m_modelColumnCount(8),
96 96 m_series(nullptr),
97 97 m_chart(nullptr),
98 98 m_chartView(nullptr),
99 99 m_hMapper(nullptr),
100 100 m_vMapper(nullptr)
101 101 {
102 102 }
103 103
104 104 void tst_qcandlestickmodelmapper::createHorizontalMapper()
105 105 {
106 106 m_hMapper = new QHCandlestickModelMapper;
107 107 QVERIFY(m_hMapper->model() == nullptr);
108 108 m_hMapper->setTimestampColumn(0);
109 109 m_hMapper->setOpenColumn(1);
110 110 m_hMapper->setHighColumn(3);
111 111 m_hMapper->setLowColumn(5);
112 112 m_hMapper->setCloseColumn(6);
113 m_hMapper->setFirstCandlestickSetRow(0);
114 m_hMapper->setLastCandlestickSetRow(4);
113 m_hMapper->setFirstSetRow(0);
114 m_hMapper->setLastSetRow(4);
115 115 m_hMapper->setModel(m_model);
116 116 m_hMapper->setSeries(m_series);
117 117 }
118 118
119 119 void tst_qcandlestickmodelmapper::createVerticalMapper()
120 120 {
121 121 m_vMapper = new QVCandlestickModelMapper;
122 122 QVERIFY(m_vMapper->model() == nullptr);
123 123 m_vMapper->setTimestampRow(0);
124 124 m_vMapper->setOpenRow(1);
125 125 m_vMapper->setHighRow(3);
126 126 m_vMapper->setLowRow(5);
127 127 m_vMapper->setCloseRow(6);
128 m_vMapper->setFirstCandlestickSetColumn(0);
129 m_vMapper->setLastCandlestickSetColumn(4);
128 m_vMapper->setFirstSetColumn(0);
129 m_vMapper->setLastSetColumn(4);
130 130 m_vMapper->setModel(m_model);
131 131 m_vMapper->setSeries(m_series);
132 132 }
133 133
134 134 void tst_qcandlestickmodelmapper::initTestCase()
135 135 {
136 136 m_chart = new QChart();
137 137 m_chartView = new QChartView(m_chart);
138 138 m_chartView->show();
139 139 }
140 140
141 141 void tst_qcandlestickmodelmapper::cleanupTestCase()
142 142 {
143 143 delete m_chartView;
144 144 QTest::qWait(1); // Allow final deleteLaters to run
145 145 }
146 146
147 147 void tst_qcandlestickmodelmapper::init()
148 148 {
149 149 m_series = new QCandlestickSeries();
150 150 m_chart->addSeries(m_series);
151 151
152 152 m_model = new QStandardItemModel(m_modelRowCount, m_modelColumnCount, this);
153 153 for (int row = 0; row < m_modelRowCount; ++row) {
154 154 for (int column = 0; column < m_modelColumnCount; ++column)
155 155 m_model->setData(m_model->index(row, column), row * column);
156 156 }
157 157 }
158 158
159 159 void tst_qcandlestickmodelmapper::cleanup()
160 160 {
161 161 m_chart->removeSeries(m_series);
162 162 delete m_series;
163 163 m_series = nullptr;
164 164
165 165 m_model->clear();
166 166 m_model->deleteLater();
167 167 m_model = nullptr;
168 168
169 169 if (m_vMapper) {
170 170 m_vMapper->deleteLater();
171 171 m_vMapper = nullptr;
172 172 }
173 173
174 174 if (m_hMapper) {
175 175 m_hMapper->deleteLater();
176 176 m_hMapper = nullptr;
177 177 }
178 178 }
179 179
180 180 void tst_qcandlestickmodelmapper::verticalMapper_data()
181 181 {
182 QTest::addColumn<int>("firstCandlestickSetColumn");
183 QTest::addColumn<int>("lastCandlestickSetColumn");
184 QTest::addColumn<int>("expectedCandlestickSetCount");
182 QTest::addColumn<int>("firstSetColumn");
183 QTest::addColumn<int>("lastSetColumn");
184 QTest::addColumn<int>("expectedSetCount");
185 185
186 186 QTest::newRow("last column greater than first column") << 0 << 1 << 2;
187 187 QTest::newRow("last column equal to first column") << 1 << 1 << 1;
188 188 QTest::newRow("last column lesser than first column") << 1 << 0 << 0;
189 189 QTest::newRow("invalid first column and correct last column") << -3 << 1 << 0;
190 190 QTest::newRow("first column beyond the size of model and correct last column") << m_modelColumnCount << 1 << 0;
191 191 QTest::newRow("first column beyond the size of model and invalid last column") << m_modelColumnCount << -1 << 0;
192 192 }
193 193
194 194 void tst_qcandlestickmodelmapper::verticalMapper()
195 195 {
196 QFETCH(int, firstCandlestickSetColumn);
197 QFETCH(int, lastCandlestickSetColumn);
198 QFETCH(int, expectedCandlestickSetCount);
196 QFETCH(int, firstSetColumn);
197 QFETCH(int, lastSetColumn);
198 QFETCH(int, expectedSetCount);
199 199
200 200 QCandlestickSeries *series = new QCandlestickSeries();
201 201 m_chart->addSeries(series);
202 202
203 203 createVerticalMapper();
204 m_vMapper->setFirstCandlestickSetColumn(firstCandlestickSetColumn);
205 m_vMapper->setLastCandlestickSetColumn(lastCandlestickSetColumn);
204 m_vMapper->setFirstSetColumn(firstSetColumn);
205 m_vMapper->setLastSetColumn(lastSetColumn);
206 206 m_vMapper->setSeries(series);
207 207
208 QCOMPARE(m_vMapper->firstCandlestickSetColumn(), qMax(firstCandlestickSetColumn, -1));
209 QCOMPARE(m_vMapper->lastCandlestickSetColumn(), qMax(lastCandlestickSetColumn, -1));
210 QCOMPARE(series->count(), expectedCandlestickSetCount);
208 QCOMPARE(m_vMapper->firstSetColumn(), qMax(firstSetColumn, -1));
209 QCOMPARE(m_vMapper->lastSetColumn(), qMax(lastSetColumn, -1));
210 QCOMPARE(series->count(), expectedSetCount);
211 211
212 212 m_chart->removeSeries(series);
213 213 delete series;
214 214 }
215 215
216 216 void tst_qcandlestickmodelmapper::verticalMapperCustomMapping_data()
217 217 {
218 218 QTest::addColumn<int>("timestampRow");
219 219 QTest::addColumn<int>("openRow");
220 220 QTest::addColumn<int>("highRow");
221 221 QTest::addColumn<int>("lowRow");
222 222 QTest::addColumn<int>("closeRow");
223 223
224 224 QTest::newRow("all rows are correct") << 0 << 1 << 2 << 3 << 4;
225 225 QTest::newRow("all rows are invalid") << -3 << -3 << -3 << -3 << -3;
226 226 QTest::newRow("timestamp: -1 (invalid)") << -1 << 1 << 2 << 3 << 4;
227 227 QTest::newRow("timestamp: -3 (invalid - should default to -1)") << -3 << 1 << 2 << 3 << 4;
228 228 QTest::newRow("timestamp: +1 greater than the number of rows in the model") << m_modelRowCount + 1 << 1 << 2 << 3 << 4;
229 229 QTest::newRow("open: -1 (invalid)") << 0 << -1 << 2 << 3 << 4;
230 230 QTest::newRow("open: -3 (invalid - should default to -1)") << 0 << -3 << 2 << 3 << 4;
231 231 QTest::newRow("open: +1 greater than the number of rows in the model") << 0 << m_modelRowCount + 1 << 2 << 3 << 4;
232 232 QTest::newRow("high: -1 (invalid)") << 0 << 1 << -1 << 3 << 4;
233 233 QTest::newRow("high: -3 (invalid - should default to -1)") << 0 << 1 << -3 << 3 << 4;
234 234 QTest::newRow("high: +1 greater than the number of rows in the model") << 0 << 1 << m_modelRowCount + 1 << 3 << 4;
235 235 QTest::newRow("low: -1 (invalid)") << 0 << 1 << 2 << -1 << 4;
236 236 QTest::newRow("low: -3 (invalid - should default to -1)") << 0 << 1 << 2 << -3 << 4;
237 237 QTest::newRow("low: +1 greater than the number of rows in the model") << 0 << 1 << 2 << m_modelRowCount + 1 << 4;
238 238 QTest::newRow("close: -1 (invalid)") << 0 << 1 << 2 << 3 << -1;
239 239 QTest::newRow("close: -3 (invalid - should default to -1)") << 0 << 1 << 2 << 3 << -3;
240 240 QTest::newRow("close: +1 greater than the number of rows in the model") << 0 << 1 << 2 << 3 << m_modelRowCount + 1;
241 241 }
242 242
243 243 void tst_qcandlestickmodelmapper::verticalMapperCustomMapping()
244 244 {
245 245 QFETCH(int, timestampRow);
246 246 QFETCH(int, openRow);
247 247 QFETCH(int, highRow);
248 248 QFETCH(int, lowRow);
249 249 QFETCH(int, closeRow);
250 250
251 251 QCandlestickSeries *series = new QCandlestickSeries();
252 252 m_chart->addSeries(series);
253 253 QCOMPARE(series->count(), 0);
254 254
255 255 createVerticalMapper();
256 256 m_vMapper->setTimestampRow(timestampRow);
257 257 m_vMapper->setOpenRow(openRow);
258 258 m_vMapper->setHighRow(highRow);
259 259 m_vMapper->setLowRow(lowRow);
260 260 m_vMapper->setCloseRow(closeRow);
261 261 m_vMapper->setSeries(series);
262 262
263 263 QCOMPARE(m_vMapper->timestampRow(), qMax(timestampRow, -1));
264 264 QCOMPARE(m_vMapper->openRow(), qMax(openRow, -1));
265 265 QCOMPARE(m_vMapper->highRow(), qMax(highRow, -1));
266 266 QCOMPARE(m_vMapper->lowRow(), qMax(lowRow, -1));
267 267 QCOMPARE(m_vMapper->closeRow(), qMax(closeRow, -1));
268 268
269 269 int count;
270 270 if ((m_vMapper->timestampRow() >= 0 && m_vMapper->timestampRow() < m_modelRowCount)
271 271 && (m_vMapper->openRow() >= 0 && m_vMapper->openRow() < m_modelRowCount)
272 272 && (m_vMapper->highRow() >= 0 && m_vMapper->highRow() < m_modelRowCount)
273 273 && (m_vMapper->lowRow() >= 0 && m_vMapper->lowRow() < m_modelRowCount)
274 274 && (m_vMapper->closeRow() >= 0 && m_vMapper->closeRow() < m_modelRowCount))
275 count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
275 count = m_vMapper->lastSetColumn() - m_vMapper->firstSetColumn() + 1;
276 276 else
277 277 count = 0;
278 278 QCOMPARE(series->count(), count);
279 279
280 280 // change values column mapping to invalid
281 m_vMapper->setFirstCandlestickSetColumn(-1);
282 m_vMapper->setLastCandlestickSetColumn(1);
281 m_vMapper->setFirstSetColumn(-1);
282 m_vMapper->setLastSetColumn(1);
283 283 QCOMPARE(series->count(), 0);
284 284
285 285 m_chart->removeSeries(series);
286 286 delete series;
287 287 }
288 288
289 289 void tst_qcandlestickmodelmapper::horizontalMapper_data()
290 290 {
291 QTest::addColumn<int>("firstCandlestickSetRow");
292 QTest::addColumn<int>("lastCandlestickSetRow");
293 QTest::addColumn<int>("expectedCandlestickSetCount");
291 QTest::addColumn<int>("firstSetRow");
292 QTest::addColumn<int>("lastSetRow");
293 QTest::addColumn<int>("expectedSetCount");
294 294
295 295 QTest::newRow("last row greater than first row") << 0 << 1 << 2;
296 296 QTest::newRow("last row equal to first row") << 1 << 1 << 1;
297 297 QTest::newRow("last row lesser than first row") << 1 << 0 << 0;
298 298 QTest::newRow("invalid first row and correct last row") << -3 << 1 << 0;
299 299 QTest::newRow("first row beyond the size of model and correct last row") << m_modelRowCount << 1 << 0;
300 300 QTest::newRow("first row beyond the size of model and invalid last row") << m_modelRowCount << -1 << 0;
301 301 }
302 302
303 303 void tst_qcandlestickmodelmapper::horizontalMapper()
304 304 {
305 QFETCH(int, firstCandlestickSetRow);
306 QFETCH(int, lastCandlestickSetRow);
307 QFETCH(int, expectedCandlestickSetCount);
305 QFETCH(int, firstSetRow);
306 QFETCH(int, lastSetRow);
307 QFETCH(int, expectedSetCount);
308 308
309 309 QCandlestickSeries *series = new QCandlestickSeries();
310 310 m_chart->addSeries(series);
311 311
312 312 createHorizontalMapper();
313 m_hMapper->setFirstCandlestickSetRow(firstCandlestickSetRow);
314 m_hMapper->setLastCandlestickSetRow(lastCandlestickSetRow);
313 m_hMapper->setFirstSetRow(firstSetRow);
314 m_hMapper->setLastSetRow(lastSetRow);
315 315 m_hMapper->setSeries(series);
316 316
317 QCOMPARE(m_hMapper->firstCandlestickSetRow(), qMax(firstCandlestickSetRow, -1));
318 QCOMPARE(m_hMapper->lastCandlestickSetRow(), qMax(lastCandlestickSetRow, -1));
319 QCOMPARE(series->count(), expectedCandlestickSetCount);
317 QCOMPARE(m_hMapper->firstSetRow(), qMax(firstSetRow, -1));
318 QCOMPARE(m_hMapper->lastSetRow(), qMax(lastSetRow, -1));
319 QCOMPARE(series->count(), expectedSetCount);
320 320
321 321 m_chart->removeSeries(series);
322 322 delete series;
323 323 }
324 324
325 325 void tst_qcandlestickmodelmapper::horizontalMapperCustomMapping_data()
326 326 {
327 327 QTest::addColumn<int>("timestampColumn");
328 328 QTest::addColumn<int>("openColumn");
329 329 QTest::addColumn<int>("highColumn");
330 330 QTest::addColumn<int>("lowColumn");
331 331 QTest::addColumn<int>("closeColumn");
332 332
333 333 QTest::newRow("all columns are correct") << 0 << 1 << 2 << 3 << 4;
334 334 QTest::newRow("all columns are invalid") << -3 << -3 << -3 << -3 << -3;
335 335 QTest::newRow("timestamp: -1 (invalid)") << -1 << 1 << 2 << 3 << 4;
336 336 QTest::newRow("timestamp: -3 (invalid - should default to -1)") << -3 << 1 << 2 << 3 << 4;
337 337 QTest::newRow("timestamp: +1 greater than the number of columns in the model") << m_modelColumnCount + 1 << 1 << 2 << 3 << 4;
338 338 QTest::newRow("open: -1 (invalid)") << 0 << -1 << 2 << 3 << 4;
339 339 QTest::newRow("open: -3 (invalid - should default to -1)") << 0 << -3 << 2 << 3 << 4;
340 340 QTest::newRow("open: +1 greater than the number of columns in the model") << 0 << m_modelColumnCount + 1 << 2 << 3 << 4;
341 341 QTest::newRow("high: -1 (invalid)") << 0 << 1 << -1 << 3 << 4;
342 342 QTest::newRow("high: -3 (invalid - should default to -1)") << 0 << 1 << -3 << 3 << 4;
343 343 QTest::newRow("high: +1 greater than the number of columns in the model") << 0 << 1 << m_modelColumnCount + 1 << 3 << 4;
344 344 QTest::newRow("low: -1 (invalid)") << 0 << 1 << 2 << -1 << 4;
345 345 QTest::newRow("low: -3 (invalid - should default to -1)") << 0 << 1 << 2 << -3 << 4;
346 346 QTest::newRow("low: +1 greater than the number of columns in the model") << 0 << 1 << 2 << m_modelColumnCount + 1 << 4;
347 347 QTest::newRow("close: -1 (invalid)") << 0 << 1 << 2 << 3 << -1;
348 348 QTest::newRow("close: -3 (invalid - should default to -1)") << 0 << 1 << 2 << 3 << -3;
349 349 QTest::newRow("close: +1 greater than the number of columns in the model") << 0 << 1 << 2 << 3 << m_modelColumnCount + 1;
350 350 }
351 351
352 352 void tst_qcandlestickmodelmapper::horizontalMapperCustomMapping()
353 353 {
354 354 QFETCH(int, timestampColumn);
355 355 QFETCH(int, openColumn);
356 356 QFETCH(int, highColumn);
357 357 QFETCH(int, lowColumn);
358 358 QFETCH(int, closeColumn);
359 359
360 360 QCandlestickSeries *series = new QCandlestickSeries();
361 361 m_chart->addSeries(series);
362 362 QCOMPARE(series->count(), 0);
363 363
364 364 createHorizontalMapper();
365 365 m_hMapper->setTimestampColumn(timestampColumn);
366 366 m_hMapper->setOpenColumn(openColumn);
367 367 m_hMapper->setHighColumn(highColumn);
368 368 m_hMapper->setLowColumn(lowColumn);
369 369 m_hMapper->setCloseColumn(closeColumn);
370 370 m_hMapper->setSeries(series);
371 371
372 372 QCOMPARE(m_hMapper->timestampColumn(), qMax(timestampColumn, -1));
373 373 QCOMPARE(m_hMapper->openColumn(), qMax(openColumn, -1));
374 374 QCOMPARE(m_hMapper->highColumn(), qMax(highColumn, -1));
375 375 QCOMPARE(m_hMapper->lowColumn(), qMax(lowColumn, -1));
376 376 QCOMPARE(m_hMapper->closeColumn(), qMax(closeColumn, -1));
377 377
378 378 int count;
379 379 if ((m_hMapper->timestampColumn() >= 0 && m_hMapper->timestampColumn() < m_modelColumnCount)
380 380 && (m_hMapper->openColumn() >= 0 && m_hMapper->openColumn() < m_modelColumnCount)
381 381 && (m_hMapper->highColumn() >= 0 && m_hMapper->highColumn() < m_modelColumnCount)
382 382 && (m_hMapper->lowColumn() >= 0 && m_hMapper->lowColumn() < m_modelColumnCount)
383 383 && (m_hMapper->closeColumn() >= 0 && m_hMapper->closeColumn() < m_modelColumnCount))
384 count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
384 count = m_hMapper->lastSetRow() - m_hMapper->firstSetRow() + 1;
385 385 else
386 386 count = 0;
387 387 QCOMPARE(series->count(), count);
388 388
389 389 // change values row mapping to invalid
390 m_hMapper->setFirstCandlestickSetRow(-1);
391 m_hMapper->setLastCandlestickSetRow(1);
390 m_hMapper->setFirstSetRow(-1);
391 m_hMapper->setLastSetRow(1);
392 392 QCOMPARE(series->count(), 0);
393 393
394 394 m_chart->removeSeries(series);
395 395 delete series;
396 396 }
397 397
398 398 void tst_qcandlestickmodelmapper::seriesUpdated()
399 399 {
400 400 createVerticalMapper();
401 401 QVERIFY(m_vMapper->model() != nullptr);
402 402
403 QCandlestickSet *set = m_series->candlestickSets().value(0, 0);
403 QCandlestickSet *set = m_series->sets().value(0, 0);
404 404 QVERIFY(set != nullptr);
405 405
406 406 // update values
407 407 QCOMPARE(m_model->data(m_model->index(m_vMapper->timestampRow(), 0)).toReal(),set->timestamp());
408 408 QCOMPARE(m_model->data(m_model->index(m_vMapper->openRow(), 0)).toReal(), set->open());
409 409 QCOMPARE(m_model->data(m_model->index(m_vMapper->highRow(), 0)).toReal(), set->high());
410 410 QCOMPARE(m_model->data(m_model->index(m_vMapper->lowRow(), 0)).toReal(), set->low());
411 411 QCOMPARE(m_model->data(m_model->index(m_vMapper->closeRow(), 0)).toReal(), set->close());
412 412 set->setTimestamp(set->timestamp() + 5.0);
413 413 set->setOpen(set->open() + 6.0);
414 414 set->setHigh(set->high() + 7.0);
415 415 set->setLow(set->low() + 8.0);
416 416 set->setClose(set->close() + 9.0);
417 417 QCOMPARE(m_model->data(m_model->index(m_vMapper->timestampRow(), 0)).toReal(),set->timestamp());
418 418 QCOMPARE(m_model->data(m_model->index(m_vMapper->openRow(), 0)).toReal(), set->open());
419 419 QCOMPARE(m_model->data(m_model->index(m_vMapper->highRow(), 0)).toReal(), set->high());
420 420 QCOMPARE(m_model->data(m_model->index(m_vMapper->lowRow(), 0)).toReal(), set->low());
421 421 QCOMPARE(m_model->data(m_model->index(m_vMapper->closeRow(), 0)).toReal(), set->close());
422 422
423 423 // append new sets
424 424 QList<QCandlestickSet *> newCandlestickSets;
425 425 newCandlestickSets << new QCandlestickSet(3.0, 5.0, 2.0, 4.0, 1234);
426 426 newCandlestickSets << new QCandlestickSet(5.0, 7.0, 4.0, 6.0, 5678);
427 427 m_series->append(newCandlestickSets);
428 428 QCOMPARE(m_model->columnCount(), m_modelColumnCount + newCandlestickSets.count());
429 429
430 430 // remove sets
431 431 newCandlestickSets.clear();
432 newCandlestickSets << m_series->candlestickSets().at(m_series->count() - 1);
433 newCandlestickSets << m_series->candlestickSets().at(m_series->count() - 2);
432 newCandlestickSets << m_series->sets().at(m_series->count() - 1);
433 newCandlestickSets << m_series->sets().at(m_series->count() - 2);
434 434 m_series->remove(newCandlestickSets);
435 435 QCOMPARE(m_model->columnCount(), m_modelColumnCount);
436 436 }
437 437
438 438 void tst_qcandlestickmodelmapper::verticalModelInsertRows()
439 439 {
440 440 createVerticalMapper();
441 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
441 int count = m_vMapper->lastSetColumn() - m_vMapper->firstSetColumn() + 1;
442 442 QVERIFY(m_vMapper->model() != 0);
443 443 QCOMPARE(m_series->count(), count);
444 444
445 445 m_model->insertRows(3, 4);
446 446 QCOMPARE(m_series->count(), count);
447 447 }
448 448
449 449 void tst_qcandlestickmodelmapper::verticalModelRemoveRows()
450 450 {
451 451 createVerticalMapper();
452 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
452 int count = m_vMapper->lastSetColumn() - m_vMapper->firstSetColumn() + 1;
453 453 QVERIFY(m_vMapper->model() != 0);
454 454 QCOMPARE(m_series->count(), count);
455 455
456 456 m_model->removeRows(m_modelRowCount - 1, 1);
457 457 QCOMPARE(m_series->count(), count);
458 458
459 459 int removeCount = m_model->rowCount() - m_vMapper->closeRow();
460 460 m_model->removeRows(m_vMapper->closeRow(), removeCount);
461 461 QCOMPARE(m_series->count(), 0);
462 462 }
463 463
464 464 void tst_qcandlestickmodelmapper::verticalModelInsertColumns()
465 465 {
466 466 createVerticalMapper();
467 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
467 int count = m_vMapper->lastSetColumn() - m_vMapper->firstSetColumn() + 1;
468 468 QVERIFY(m_vMapper->model() != 0);
469 469 QCOMPARE(m_series->count(), count);
470 470
471 471 m_model->insertColumns(3, 4);
472 472 QCOMPARE(m_series->count(), count);
473 473 }
474 474
475 475 void tst_qcandlestickmodelmapper::verticalModelRemoveColumns()
476 476 {
477 477 createVerticalMapper();
478 int count = m_vMapper->lastCandlestickSetColumn() - m_vMapper->firstCandlestickSetColumn() + 1;
478 int count = m_vMapper->lastSetColumn() - m_vMapper->firstSetColumn() + 1;
479 479 QVERIFY(m_vMapper->model() != 0);
480 480 QCOMPARE(m_series->count(), count);
481 481
482 482 int removeCount = m_modelColumnCount - 2;
483 483 m_model->removeColumns(0, removeCount);
484 484 QCOMPARE(m_series->count(), qMin(m_model->columnCount(), count));
485 485
486 486 // leave all the columns
487 487 m_model->removeColumns(0, m_modelColumnCount - removeCount);
488 488 QCOMPARE(m_series->count(), 0);
489 489 }
490 490
491 491 void tst_qcandlestickmodelmapper::horizontalModelInsertRows()
492 492 {
493 493 createHorizontalMapper();
494 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
494 int count = m_hMapper->lastSetRow() - m_hMapper->firstSetRow() + 1;
495 495 QVERIFY(m_hMapper->model() != 0);
496 496 QCOMPARE(m_series->count(), count);
497 497
498 498 m_model->insertRows(3, 4);
499 499 QCOMPARE(m_series->count(), count);
500 500 }
501 501
502 502 void tst_qcandlestickmodelmapper::horizontalModelRemoveRows()
503 503 {
504 504 createHorizontalMapper();
505 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
505 int count = m_hMapper->lastSetRow() - m_hMapper->firstSetRow() + 1;
506 506 QVERIFY(m_hMapper->model() != 0);
507 507 QCOMPARE(m_series->count(), qMin(m_model->rowCount(), count));
508 508
509 509 int removeCount = m_modelRowCount - 2;
510 510 m_model->removeRows(0, removeCount);
511 511 QCOMPARE(m_series->count(), qMin(m_model->rowCount(), count));
512 512
513 513 // leave all the columns
514 514 m_model->removeRows(0, m_modelRowCount - removeCount);
515 515 QCOMPARE(m_series->count(), 0);
516 516 }
517 517
518 518 void tst_qcandlestickmodelmapper::horizontalModelInsertColumns()
519 519 {
520 520 createHorizontalMapper();
521 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
521 int count = m_hMapper->lastSetRow() - m_hMapper->firstSetRow() + 1;
522 522 QVERIFY(m_hMapper->model() != 0);
523 523 QCOMPARE(m_series->count(), count);
524 524
525 525 m_model->insertColumns(3, 4);
526 526 QCOMPARE(m_series->count(), count);
527 527 }
528 528
529 529 void tst_qcandlestickmodelmapper::horizontalModelRemoveColumns()
530 530 {
531 531 createHorizontalMapper();
532 int count = m_hMapper->lastCandlestickSetRow() - m_hMapper->firstCandlestickSetRow() + 1;
532 int count = m_hMapper->lastSetRow() - m_hMapper->firstSetRow() + 1;
533 533 QVERIFY(m_hMapper->model() != 0);
534 534 QCOMPARE(m_series->count(), count);
535 535
536 536 m_model->removeColumns(m_modelColumnCount - 1, 1);
537 537 QCOMPARE(m_series->count(), count);
538 538
539 539 int removeCount = m_model->columnCount() - m_hMapper->closeColumn();
540 540 m_model->removeColumns(m_hMapper->closeColumn(), removeCount);
541 541 QCOMPARE(m_series->count(), 0);
542 542 }
543 543
544 544 void tst_qcandlestickmodelmapper::modelUpdateCell()
545 545 {
546 546 createVerticalMapper();
547 547 QVERIFY(m_vMapper->model() != 0);
548 548
549 549 QModelIndex index = m_model->index(m_vMapper->timestampRow(), 0);
550 550 qreal newValue = 44.0;
551 551 QVERIFY(m_model->setData(index, newValue));
552 552 QCOMPARE(m_model->data(index).toReal(), newValue);
553 QCOMPARE(m_series->candlestickSets().at(index.row())->timestamp(), newValue);
553 QCOMPARE(m_series->sets().at(index.row())->timestamp(), newValue);
554 554 }
555 555
556 556 void tst_qcandlestickmodelmapper::verticalMapperSignals()
557 557 {
558 558 QVCandlestickModelMapper *mapper = new QVCandlestickModelMapper();
559 559
560 560 QSignalSpy spy0(mapper, SIGNAL(modelReplaced()));
561 561 QSignalSpy spy1(mapper, SIGNAL(seriesReplaced()));
562 562 QSignalSpy spy2(mapper, SIGNAL(timestampRowChanged()));
563 563 QSignalSpy spy3(mapper, SIGNAL(openRowChanged()));
564 564 QSignalSpy spy4(mapper, SIGNAL(highRowChanged()));
565 565 QSignalSpy spy5(mapper, SIGNAL(lowRowChanged()));
566 566 QSignalSpy spy6(mapper, SIGNAL(closeRowChanged()));
567 QSignalSpy spy7(mapper, SIGNAL(firstCandlestickSetColumnChanged()));
568 QSignalSpy spy8(mapper, SIGNAL(lastCandlestickSetColumnChanged()));
567 QSignalSpy spy7(mapper, SIGNAL(firstSetColumnChanged()));
568 QSignalSpy spy8(mapper, SIGNAL(lastSetColumnChanged()));
569 569
570 570 mapper->setModel(m_model);
571 571 mapper->setSeries(m_series);
572 572 mapper->setTimestampRow(1);
573 573 mapper->setOpenRow(2);
574 574 mapper->setHighRow(3);
575 575 mapper->setLowRow(4);
576 576 mapper->setCloseRow(5);
577 mapper->setFirstCandlestickSetColumn(0);
578 mapper->setLastCandlestickSetColumn(1);
577 mapper->setFirstSetColumn(0);
578 mapper->setLastSetColumn(1);
579 579
580 580 QCOMPARE(spy0.count(), 1);
581 581 QCOMPARE(spy1.count(), 1);
582 582 QCOMPARE(spy2.count(), 1);
583 583 QCOMPARE(spy3.count(), 1);
584 584 QCOMPARE(spy4.count(), 1);
585 585 QCOMPARE(spy5.count(), 1);
586 586 QCOMPARE(spy6.count(), 1);
587 587 QCOMPARE(spy7.count(), 1);
588 588 QCOMPARE(spy8.count(), 1);
589 589
590 590 delete mapper;
591 591 }
592 592
593 593 void tst_qcandlestickmodelmapper::horizontalMapperSignals()
594 594 {
595 595 QHCandlestickModelMapper *mapper = new QHCandlestickModelMapper();
596 596
597 597 QSignalSpy spy0(mapper, SIGNAL(modelReplaced()));
598 598 QSignalSpy spy1(mapper, SIGNAL(seriesReplaced()));
599 599 QSignalSpy spy2(mapper, SIGNAL(timestampColumnChanged()));
600 600 QSignalSpy spy3(mapper, SIGNAL(openColumnChanged()));
601 601 QSignalSpy spy4(mapper, SIGNAL(highColumnChanged()));
602 602 QSignalSpy spy5(mapper, SIGNAL(lowColumnChanged()));
603 603 QSignalSpy spy6(mapper, SIGNAL(closeColumnChanged()));
604 QSignalSpy spy7(mapper, SIGNAL(firstCandlestickSetRowChanged()));
605 QSignalSpy spy8(mapper, SIGNAL(lastCandlestickSetRowChanged()));
604 QSignalSpy spy7(mapper, SIGNAL(firstSetRowChanged()));
605 QSignalSpy spy8(mapper, SIGNAL(lastSetRowChanged()));
606 606
607 607 mapper->setModel(m_model);
608 608 mapper->setSeries(m_series);
609 609 mapper->setTimestampColumn(1);
610 610 mapper->setOpenColumn(2);
611 611 mapper->setHighColumn(3);
612 612 mapper->setLowColumn(4);
613 613 mapper->setCloseColumn(5);
614 mapper->setFirstCandlestickSetRow(0);
615 mapper->setLastCandlestickSetRow(1);
614 mapper->setFirstSetRow(0);
615 mapper->setLastSetRow(1);
616 616
617 617 QCOMPARE(spy0.count(), 1);
618 618 QCOMPARE(spy1.count(), 1);
619 619 QCOMPARE(spy2.count(), 1);
620 620 QCOMPARE(spy3.count(), 1);
621 621 QCOMPARE(spy4.count(), 1);
622 622 QCOMPARE(spy5.count(), 1);
623 623 QCOMPARE(spy6.count(), 1);
624 624 QCOMPARE(spy7.count(), 1);
625 625 QCOMPARE(spy8.count(), 1);
626 626
627 627 delete mapper;
628 628 }
629 629
630 630 QTEST_MAIN(tst_qcandlestickmodelmapper)
631 631
632 632 #include "tst_qcandlestickmodelmapper.moc"
@@ -1,936 +1,936
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QCandlestickSeries>
31 31 #include <QtCharts/QCandlestickSet>
32 32 #include <QtCharts/QChartView>
33 33 #include <QtTest/QtTest>
34 34 #include "tst_definitions.h"
35 35
36 36 QT_CHARTS_USE_NAMESPACE
37 37
38 38 Q_DECLARE_METATYPE(QCandlestickSet *)
39 39 Q_DECLARE_METATYPE(QList<QCandlestickSet *>)
40 40
41 41 class tst_QCandlestickSeries : public QObject
42 42 {
43 43 Q_OBJECT
44 44
45 45 public Q_SLOTS:
46 46 void initTestCase();
47 47 void cleanupTestCase();
48 48 void init();
49 49 void cleanup();
50 50
51 51 private Q_SLOTS:
52 52 void qCandlestickSeries();
53 53 void append();
54 54 void remove();
55 55 void appendList();
56 56 void removeList();
57 57 void insert();
58 58 void take();
59 59 void clear();
60 void candlestickSets();
60 void sets();
61 61 void count();
62 62 void type();
63 63 void maximumColumnWidth_data();
64 64 void maximumColumnWidth();
65 65 void minimumColumnWidth_data();
66 66 void minimumColumnWidth();
67 67 void bodyWidth_data();
68 68 void bodyWidth();
69 69 void bodyOutlineVisible();
70 70 void capsWidth_data();
71 71 void capsWidth();
72 72 void capsVisible();
73 73 void increasingColor();
74 74 void decreasingColor();
75 75 void brush();
76 76 void pen();
77 77 void mouseClicked();
78 78 void mouseHovered();
79 79 void mousePressed();
80 80 void mouseReleased();
81 81 void mouseDoubleClicked();
82 82
83 83 private:
84 84 QCandlestickSeries *m_series;
85 85 QList<QCandlestickSet *> m_sets;
86 86 };
87 87
88 88 void tst_QCandlestickSeries::initTestCase()
89 89 {
90 90 qRegisterMetaType<QCandlestickSet *>("QCandlestickSet *");
91 91 qRegisterMetaType<QList<QCandlestickSet *>>("QList<QCandlestickSet *>");
92 92 }
93 93
94 94 void tst_QCandlestickSeries::cleanupTestCase()
95 95 {
96 96 QTest::qWait(1); // Allow final deleteLaters to run
97 97 }
98 98
99 99 void tst_QCandlestickSeries::init()
100 100 {
101 101 m_series = new QCandlestickSeries();
102 102 m_series->setMaximumColumnWidth(5432.1);
103 103 m_series->setMinimumColumnWidth(2.0);
104 104 m_series->setBodyWidth(0.99);
105 105 m_series->setCapsWidth(0.99);
106 106
107 107 for (int i = 0; i < 5; ++i) {
108 108 qreal timestamp = QDateTime::currentMSecsSinceEpoch() + i * 1000000;
109 109
110 110 QCandlestickSet *set = new QCandlestickSet(timestamp);
111 111 set->setOpen(4);
112 112 set->setHigh(4);
113 113 set->setLow(1);
114 114 set->setClose(1);
115 115
116 116 m_sets.append(set);
117 117 }
118 118 }
119 119
120 120 void tst_QCandlestickSeries::cleanup()
121 121 {
122 122 foreach (QCandlestickSet *set, m_sets) {
123 123 m_series->remove(set);
124 124 m_sets.removeAll(set);
125 125 delete set;
126 126 }
127 127
128 128 delete m_series;
129 129 m_series = nullptr;
130 130 }
131 131
132 132 void tst_QCandlestickSeries::qCandlestickSeries()
133 133 {
134 134 QCandlestickSeries *series = new QCandlestickSeries();
135 135
136 136 QVERIFY(series != nullptr);
137 137
138 138 delete series;
139 139 series = nullptr;
140 140 }
141 141
142 142 void tst_QCandlestickSeries::append()
143 143 {
144 144 QCOMPARE(m_series->count(), 0);
145 145
146 146 // Try adding set
147 147 QCandlestickSet *set1 = new QCandlestickSet(1234.0);
148 148 QVERIFY(m_series->append(set1));
149 149 QCOMPARE(m_series->count(), 1);
150 150
151 151 // Try adding another set
152 152 QCandlestickSet *set2 = new QCandlestickSet(2345.0);
153 153 QVERIFY(m_series->append(set2));
154 154 QCOMPARE(m_series->count(), 2);
155 155
156 156 // Try adding same set again
157 157 QVERIFY(!m_series->append(set2));
158 158 QCOMPARE(m_series->count(), 2);
159 159
160 160 // Try adding null set
161 161 QVERIFY(!m_series->append(nullptr));
162 162 QCOMPARE(m_series->count(), 2);
163 163 }
164 164
165 165 void tst_QCandlestickSeries::remove()
166 166 {
167 167 m_series->append(m_sets);
168 168 QCOMPARE(m_series->count(), m_sets.count());
169 169
170 170 // Try to remove null pointer (should not remove, should not crash)
171 171 QVERIFY(!m_series->remove(nullptr));
172 172 QCOMPARE(m_series->count(), m_sets.count());
173 173
174 174 // Try to remove invalid pointer (should not remove, should not crash)
175 175 QVERIFY(!m_series->remove((QCandlestickSet *)(m_sets.at(0) + 1)));
176 176 QCOMPARE(m_series->count(), m_sets.count());
177 177
178 178 // Remove some sets
179 179 const int removeCount = 3;
180 180 for (int i = 0; i < removeCount; ++i)
181 181 QVERIFY(m_series->remove(m_sets.at(i)));
182 182 QCOMPARE(m_series->count(), m_sets.count() - removeCount);
183 183
184 184 for (int i = removeCount; i < m_sets.count(); ++i)
185 QCOMPARE(m_series->candlestickSets().at(i - removeCount), m_sets.at(i));
185 QCOMPARE(m_series->sets().at(i - removeCount), m_sets.at(i));
186 186
187 187 // Try removing all sets again (should be ok, even if some sets have already been removed)
188 188 for (int i = 0; i < m_sets.count(); ++i)
189 189 m_series->remove(m_sets.at(i));
190 190 QCOMPARE(m_series->count(), 0);
191 191 }
192 192
193 193 void tst_QCandlestickSeries::appendList()
194 194 {
195 195 QCOMPARE(m_series->count(), 0);
196 196
197 197 // Append new sets (should succeed, count should match the count of sets)
198 198 QVERIFY(m_series->append(m_sets));
199 199 QCOMPARE(m_series->count(), m_series->count());
200 200
201 201 // Append same sets again (should fail, count should remain same)
202 202 QVERIFY(!m_series->append(m_sets));
203 203 QCOMPARE(m_series->count(), m_series->count());
204 204
205 205 // Try append empty list (should succeed, but count should remain same)
206 206 QList<QCandlestickSet *> invalidList;
207 207 QVERIFY(m_series->append(invalidList));
208 208 QCOMPARE(m_series->count(), m_sets.count());
209 209
210 210 // Try append list with one new and one existing set (should fail, count remains same)
211 211 invalidList.append(new QCandlestickSet());
212 212 invalidList.append(m_sets.at(0));
213 213 QVERIFY(!m_series->append(invalidList));
214 214 QCOMPARE(m_series->count(), m_sets.count());
215 215 delete invalidList.at(0);
216 216 invalidList.clear();
217 217
218 218 // Try append list with null pointers (should fail, count remains same)
219 219 QVERIFY(invalidList.isEmpty());
220 220 invalidList.append(nullptr);
221 221 invalidList.append(nullptr);
222 222 invalidList.append(nullptr);
223 223 QVERIFY(!m_series->append(invalidList));
224 224 QCOMPARE(m_series->count(), m_sets.count());
225 225 }
226 226
227 227 void tst_QCandlestickSeries::removeList()
228 228 {
229 229 m_series->append(m_sets);
230 230 QCOMPARE(m_series->count(), m_sets.count());
231 231
232 232 // Try remove empty list (should fail, but count should remain same)
233 233 QList<QCandlestickSet *> invalidList;
234 234 QVERIFY(!m_series->remove(invalidList));
235 235 QCOMPARE(m_series->count(), m_sets.count());
236 236
237 237 // Try remove list with one new and one existing set (should fail, count remains same)
238 238 invalidList.append(new QCandlestickSet());
239 239 invalidList.append(m_sets.at(0));
240 240 QVERIFY(!m_series->remove(invalidList));
241 241 QCOMPARE(m_series->count(), m_sets.count());
242 242 delete invalidList.at(0);
243 243 invalidList.clear();
244 244
245 245 // Try remove list with null pointers (should fail, count remains same)
246 246 QVERIFY(invalidList.isEmpty());
247 247 invalidList.append(nullptr);
248 248 invalidList.append(nullptr);
249 249 invalidList.append(nullptr);
250 250 QVERIFY(!m_series->remove(invalidList));
251 251 QCOMPARE(m_series->count(), m_sets.count());
252 252
253 253 // Remove all sets (should succeed, count should be zero)
254 254 QVERIFY(m_series->remove(m_sets));
255 255 QCOMPARE(m_series->count(), 0);
256 256
257 257 // Remove same sets again (should fail, count should remain zero)
258 258 QVERIFY(!m_series->remove(m_sets));
259 259 QCOMPARE(m_series->count(), 0);
260 260 }
261 261
262 262 void tst_QCandlestickSeries::insert()
263 263 {
264 264 QCOMPARE(m_series->count(), 0);
265 265
266 266 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
267 267 QSignalSpy addedSpy(m_series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)));
268 268
269 269 for (int i = 0; i < m_sets.count(); ++i) {
270 270 QCandlestickSet *set = m_sets.at(i);
271 271 QVERIFY(m_series->insert(0, set));
272 272 QCOMPARE(m_series->count(), i + 1);
273 273 QTRY_COMPARE(countSpy.count(), i + 1);
274 274 QTRY_COMPARE(addedSpy.count(), i + 1);
275 275
276 276 QList<QVariant> args = addedSpy.value(i);
277 277 QCOMPARE(args.count(), 1);
278 278 QList<QCandlestickSet *> sets = qvariant_cast<QList<QCandlestickSet *>>(args.at(0));
279 279 QCOMPARE(sets.count(), 1);
280 280 QCOMPARE(sets.first(), set);
281 281 }
282 282 }
283 283
284 284 void tst_QCandlestickSeries::take()
285 285 {
286 286 m_series->append(m_sets);
287 287 QCOMPARE(m_series->count(), m_sets.count());
288 288
289 289 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
290 290 QSignalSpy removedSpy(m_series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet *>)));
291 291
292 292 for (int i = 0; i < m_sets.count(); ++i) {
293 293 QCandlestickSet *set = m_sets.at(i);
294 294 QVERIFY(m_series->take(set));
295 295 QCOMPARE(m_series->count(), m_sets.count() - i - 1);
296 296 QTRY_COMPARE(countSpy.count(), i + 1);
297 297 QTRY_COMPARE(removedSpy.count(), i + 1);
298 298
299 299 QList<QVariant> args = removedSpy.value(i);
300 300 QCOMPARE(args.count(), 1);
301 301 QList<QCandlestickSet *> sets = qvariant_cast<QList<QCandlestickSet *>>(args.at(0));
302 302 QCOMPARE(sets.count(), 1);
303 303 QCOMPARE(sets.first(), set);
304 304 }
305 305 }
306 306
307 307 void tst_QCandlestickSeries::clear()
308 308 {
309 309 m_series->append(m_sets);
310 310 QCOMPARE(m_series->count(), m_sets.count());
311 311
312 312 m_series->clear();
313 313 QCOMPARE(m_series->count(), 0);
314 314 }
315 315
316 void tst_QCandlestickSeries::candlestickSets()
316 void tst_QCandlestickSeries::sets()
317 317 {
318 318 m_series->append(m_sets);
319 QCOMPARE(m_series->candlestickSets(), m_sets);
319 QCOMPARE(m_series->sets(), m_sets);
320 320
321 321 for (int i = 0; i < m_sets.count(); ++i)
322 QCOMPARE(m_series->candlestickSets().at(i), m_sets.at(i));
322 QCOMPARE(m_series->sets().at(i), m_sets.at(i));
323 323
324 324 m_series->clear();
325 QCOMPARE(m_series->candlestickSets(), QList<QCandlestickSet *>());
325 QCOMPARE(m_series->sets(), QList<QCandlestickSet *>());
326 326 }
327 327
328 328 void tst_QCandlestickSeries::count()
329 329 {
330 330 m_series->append(m_sets);
331 331 QCOMPARE(m_series->count(), m_sets.count());
332 QCOMPARE(m_series->count(), m_series->candlestickSets().count());
332 QCOMPARE(m_series->count(), m_series->sets().count());
333 333 }
334 334
335 335 void tst_QCandlestickSeries::type()
336 336 {
337 337 QCOMPARE(m_series->type(), QAbstractSeries::SeriesTypeCandlestick);
338 338 }
339 339
340 340 void tst_QCandlestickSeries::maximumColumnWidth_data()
341 341 {
342 342 QTest::addColumn<qreal>("maximumColumnWidth");
343 343 QTest::addColumn<qreal>("expectedMaximumColumnWidth");
344 344
345 345 QTest::newRow("maximum column width less than -1.0") << -3.0 << -1.0;
346 346 QTest::newRow("maximum column equals to -1.0") << -1.0 << -1.0;
347 347 QTest::newRow("maximum column width greater than -1.0, but less than zero") << -0.5 << -1.0;
348 348 QTest::newRow("maximum column width equals zero") << 0.0 << 0.0;
349 349 QTest::newRow("maximum column width greater than zero") << 1.0 << 1.0;
350 350 QTest::newRow("maximum column width contains a fractional part") << 3.4 << 3.4;
351 351 }
352 352
353 353 void tst_QCandlestickSeries::maximumColumnWidth()
354 354 {
355 355 QFETCH(qreal, maximumColumnWidth);
356 356 QFETCH(qreal, expectedMaximumColumnWidth);
357 357
358 358 QSignalSpy spy(m_series, SIGNAL(maximumColumnWidthChanged()));
359 359
360 360 m_series->setMaximumColumnWidth(maximumColumnWidth);
361 361 QCOMPARE(m_series->maximumColumnWidth(), expectedMaximumColumnWidth);
362 362 QCOMPARE(spy.count(), 1);
363 363
364 364 // Try set same maximum column width
365 365 m_series->setMaximumColumnWidth(expectedMaximumColumnWidth);
366 366 QCOMPARE(m_series->maximumColumnWidth(), expectedMaximumColumnWidth);
367 367 QCOMPARE(spy.count(), 1);
368 368 }
369 369
370 370 void tst_QCandlestickSeries::minimumColumnWidth_data()
371 371 {
372 372 QTest::addColumn<qreal>("minimumColumnWidth");
373 373 QTest::addColumn<qreal>("expectedMinimumColumnWidth");
374 374
375 375 QTest::newRow("minimum column width less than -1.0") << -3.0 << -1.0;
376 376 QTest::newRow("minimum column equals to -1.0") << -1.0 << -1.0;
377 377 QTest::newRow("minimum column width greater than -1.0, but less than zero") << -0.5 << -1.0;
378 378 QTest::newRow("minimum column width equals zero") << 0.0 << 0.0;
379 379 QTest::newRow("minimum column width greater than zero") << 1.0 << 1.0;
380 380 QTest::newRow("minimum column width contains a fractional part") << 3.4 << 3.4;
381 381 }
382 382
383 383 void tst_QCandlestickSeries::minimumColumnWidth()
384 384 {
385 385 QFETCH(qreal, minimumColumnWidth);
386 386 QFETCH(qreal, expectedMinimumColumnWidth);
387 387
388 388 QSignalSpy spy(m_series, SIGNAL(minimumColumnWidthChanged()));
389 389
390 390 m_series->setMinimumColumnWidth(minimumColumnWidth);
391 391 QCOMPARE(m_series->minimumColumnWidth(), expectedMinimumColumnWidth);
392 392 QCOMPARE(spy.count(), 1);
393 393
394 394 // Try set same minimum column width
395 395 m_series->setMinimumColumnWidth(expectedMinimumColumnWidth);
396 396 QCOMPARE(m_series->minimumColumnWidth(), expectedMinimumColumnWidth);
397 397 QCOMPARE(spy.count(), 1);
398 398 }
399 399
400 400 void tst_QCandlestickSeries::bodyWidth_data()
401 401 {
402 402 QTest::addColumn<qreal>("bodyWidth");
403 403 QTest::addColumn<qreal>("expectedBodyWidth");
404 404
405 405 QTest::newRow("body width less than zero") << -1.0 << 0.0;
406 406 QTest::newRow("body width equals zero") << 0.0 << 0.0;
407 407 QTest::newRow("body width greater than zero and less than one") << 0.5 << 0.5;
408 408 QTest::newRow("body width equals one") << 1.0 << 1.0;
409 409 QTest::newRow("body width greater than one") << 2.0 << 1.0;
410 410 }
411 411
412 412 void tst_QCandlestickSeries::bodyWidth()
413 413 {
414 414 QFETCH(qreal, bodyWidth);
415 415 QFETCH(qreal, expectedBodyWidth);
416 416
417 417 QSignalSpy spy(m_series, SIGNAL(bodyWidthChanged()));
418 418
419 419 m_series->setBodyWidth(bodyWidth);
420 420 QCOMPARE(m_series->bodyWidth(), expectedBodyWidth);
421 421 QCOMPARE(spy.count(), 1);
422 422
423 423 // Try set same body width
424 424 m_series->setBodyWidth(bodyWidth);
425 425 QCOMPARE(m_series->bodyWidth(), expectedBodyWidth);
426 426 QCOMPARE(spy.count(), 1);
427 427 }
428 428
429 429 void tst_QCandlestickSeries::bodyOutlineVisible()
430 430 {
431 431 QSignalSpy spy(m_series, SIGNAL(bodyOutlineVisibilityChanged()));
432 432
433 433 bool visible = !m_series->bodyOutlineVisible();
434 434 m_series->setBodyOutlineVisible(visible);
435 435 QCOMPARE(m_series->bodyOutlineVisible(), visible);
436 436 QCOMPARE(spy.count(), 1);
437 437
438 438 // Try set same body outline visibility
439 439 m_series->setBodyOutlineVisible(visible);
440 440 QCOMPARE(m_series->bodyOutlineVisible(), visible);
441 441 QCOMPARE(spy.count(), 1);
442 442 }
443 443
444 444 void tst_QCandlestickSeries::capsWidth_data()
445 445 {
446 446 QTest::addColumn<qreal>("capsWidth");
447 447 QTest::addColumn<qreal>("expectedCapsWidth");
448 448
449 449 QTest::newRow("caps width less than zero") << -1.0 << 0.0;
450 450 QTest::newRow("caps width equals zero") << 0.0 << 0.0;
451 451 QTest::newRow("caps width greater than zero and less than one") << 0.5 << 0.5;
452 452 QTest::newRow("caps width equals one") << 1.0 << 1.0;
453 453 QTest::newRow("caps width greater than one") << 2.0 << 1.0;
454 454 }
455 455
456 456 void tst_QCandlestickSeries::capsWidth()
457 457 {
458 458 QFETCH(qreal, capsWidth);
459 459 QFETCH(qreal, expectedCapsWidth);
460 460
461 461 QSignalSpy spy(m_series, SIGNAL(capsWidthChanged()));
462 462
463 463 m_series->setCapsWidth(capsWidth);
464 464 QCOMPARE(m_series->capsWidth(), expectedCapsWidth);
465 465 QCOMPARE(spy.count(), 1);
466 466
467 467 // Try set same caps width
468 468 m_series->setCapsWidth(capsWidth);
469 469 QCOMPARE(m_series->capsWidth(), expectedCapsWidth);
470 470 QCOMPARE(spy.count(), 1);
471 471 }
472 472
473 473 void tst_QCandlestickSeries::capsVisible()
474 474 {
475 475 QSignalSpy spy(m_series, SIGNAL(capsVisibilityChanged()));
476 476
477 477 bool visible = !m_series->capsVisible();
478 478 m_series->setCapsVisible(visible);
479 479 QCOMPARE(m_series->capsVisible(), visible);
480 480 QCOMPARE(spy.count(), 1);
481 481
482 482 // Try set same caps visibility
483 483 m_series->setCapsVisible(visible);
484 484 QCOMPARE(m_series->capsVisible(), visible);
485 485 QCOMPARE(spy.count(), 1);
486 486 }
487 487
488 488 void tst_QCandlestickSeries::increasingColor()
489 489 {
490 490 QSignalSpy spy(m_series, SIGNAL(increasingColorChanged()));
491 491
492 492 // Try set new increasing color
493 493 QColor newColor(200, 200, 200, 200);
494 494 m_series->setIncreasingColor(newColor);
495 495 QCOMPARE(m_series->increasingColor(), newColor);
496 496 QCOMPARE(spy.count(), 1);
497 497
498 498 // Try set same increasing color again
499 499 m_series->setIncreasingColor(newColor);
500 500 QCOMPARE(m_series->increasingColor(), newColor);
501 501 QCOMPARE(spy.count(), 1);
502 502
503 503 // Try set invalid increasing color (should change to default color)
504 504 QColor defaultColor = m_series->brush().color();
505 505 defaultColor.setAlpha(128);
506 506 m_series->setIncreasingColor(QColor());
507 507 QCOMPARE(m_series->increasingColor(), defaultColor);
508 508 QCOMPARE(spy.count(), 2);
509 509
510 510 // Set new brush, increasing color should change accordingly
511 511 QBrush brush(newColor);
512 512 defaultColor = brush.color();
513 513 defaultColor.setAlpha(128);
514 514 m_series->setBrush(brush);
515 515 QCOMPARE(m_series->increasingColor(), defaultColor);
516 516 QCOMPARE(spy.count(), 3);
517 517 }
518 518
519 519 void tst_QCandlestickSeries::decreasingColor()
520 520 {
521 521 QSignalSpy spy(m_series, SIGNAL(decreasingColorChanged()));
522 522
523 523 // Try set new decreasing color
524 524 QColor newColor(200, 200, 200, 200);
525 525 m_series->setDecreasingColor(newColor);
526 526 QCOMPARE(m_series->decreasingColor(), newColor);
527 527 QCOMPARE(spy.count(), 1);
528 528
529 529 // Try set same decreasing color again
530 530 m_series->setDecreasingColor(newColor);
531 531 QCOMPARE(m_series->decreasingColor(), newColor);
532 532 QCOMPARE(spy.count(), 1);
533 533
534 534 // Try set invalid decreasing color (should change to default color)
535 535 m_series->setDecreasingColor(QColor());
536 536 QCOMPARE(m_series->decreasingColor(), m_series->brush().color());
537 537 QCOMPARE(spy.count(), 2);
538 538
539 539 // Set new brush, decreasing color should change accordingly
540 540 m_series->setBrush(QBrush(newColor));
541 541 QCOMPARE(m_series->decreasingColor(), m_series->brush().color());
542 542 QCOMPARE(spy.count(), 3);
543 543 }
544 544
545 545 void tst_QCandlestickSeries::brush()
546 546 {
547 547 QSignalSpy spy(m_series, SIGNAL(brushChanged()));
548 548
549 549 QBrush brush(QColor(128, 128, 128, 128));
550 550 QColor increasingColor(brush.color());
551 551 increasingColor.setAlpha(128);
552 552 QColor decreasingColor(brush.color());
553 553 m_series->setBrush(brush);
554 554 QCOMPARE(m_series->brush(), brush);
555 555 QCOMPARE(m_series->increasingColor(), increasingColor);
556 556 QCOMPARE(m_series->decreasingColor(), decreasingColor);
557 557 QCOMPARE(spy.count(), 1);
558 558
559 559 // Try set same brush
560 560 m_series->setBrush(brush);
561 561 QCOMPARE(m_series->brush(), brush);
562 562 QCOMPARE(m_series->increasingColor(), increasingColor);
563 563 QCOMPARE(m_series->decreasingColor(), decreasingColor);
564 564 QCOMPARE(spy.count(), 1);
565 565 }
566 566
567 567 void tst_QCandlestickSeries::pen()
568 568 {
569 569 QSignalSpy spy(m_series, SIGNAL(penChanged()));
570 570
571 571 QPen pen(QColor(128, 128, 128, 128));
572 572 m_series->setPen(pen);
573 573 QCOMPARE(m_series->pen(), pen);
574 574 QCOMPARE(spy.count(), 1);
575 575
576 576 // Try set same pen
577 577 m_series->setPen(pen);
578 578 QCOMPARE(m_series->pen(), pen);
579 579 QCOMPARE(spy.count(), 1);
580 580 }
581 581
582 582 void tst_QCandlestickSeries::mouseClicked()
583 583 {
584 584 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
585 585
586 586 QVERIFY(m_series->append(m_sets));
587 587 QCOMPARE(m_series->count(), m_sets.count());
588 588
589 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
590 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
589 QCandlestickSet *set1 = m_series->sets().at(1);
590 QCandlestickSet *set2 = m_series->sets().at(2);
591 591
592 592 QSignalSpy seriesSpy(m_series, SIGNAL(clicked(QCandlestickSet *)));
593 593 QSignalSpy setSpy1(set1, SIGNAL(clicked()));
594 594 QSignalSpy setSpy2(set2, SIGNAL(clicked()));
595 595
596 596 QChartView view(new QChart());
597 597 view.resize(400, 300);
598 598 view.chart()->addSeries(m_series);
599 599 view.chart()->createDefaultAxes();
600 600 view.show();
601 601 QTest::qWaitForWindowShown(&view);
602 602
603 603 // Calculate expected layout for candlesticks
604 604 QRectF plotArea = view.chart()->plotArea();
605 605 qreal candlestickWidth = plotArea.width() / m_series->count();
606 606 qreal candlestickHeight = plotArea.height();
607 607
608 608 QMap<QCandlestickSet *, QRectF> layout;
609 609 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
610 610 plotArea.top(), candlestickWidth, candlestickHeight));
611 611 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
612 612 plotArea.top(), candlestickWidth, candlestickHeight));
613 613
614 614 // Click set 1
615 615 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
616 616 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
617 617
618 618 QCOMPARE(seriesSpy.count(), 1);
619 619 QCOMPARE(setSpy1.count(), 1);
620 620 QCOMPARE(setSpy2.count(), 0);
621 621
622 622 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
623 623 QCOMPARE(seriesSpyArgs.count(), 1);
624 624 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
625 625 seriesSpyArgs.clear();
626 626
627 627 QVERIFY(setSpy1.takeFirst().isEmpty());
628 628
629 629 // Click set 2
630 630 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
631 631 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
632 632
633 633 QCOMPARE(seriesSpy.count(), 1);
634 634 QCOMPARE(setSpy1.count(), 0);
635 635 QCOMPARE(setSpy2.count(), 1);
636 636
637 637 seriesSpyArgs = seriesSpy.takeFirst();
638 638 QCOMPARE(seriesSpyArgs.count(), 1);
639 639 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
640 640 seriesSpyArgs.clear();
641 641
642 642 QVERIFY(setSpy2.takeFirst().isEmpty());
643 643 }
644 644
645 645 void tst_QCandlestickSeries::mouseHovered()
646 646 {
647 647 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
648 648
649 649 QVERIFY(m_series->append(m_sets));
650 650 QCOMPARE(m_series->count(), m_sets.count());
651 651
652 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
653 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
652 QCandlestickSet *set1 = m_series->sets().at(1);
653 QCandlestickSet *set2 = m_series->sets().at(2);
654 654
655 655 QSignalSpy seriesSpy(m_series, SIGNAL(hovered(bool, QCandlestickSet *)));
656 656 QSignalSpy setSpy1(set1, SIGNAL(hovered(bool)));
657 657 QSignalSpy setSpy2(set2, SIGNAL(hovered(bool)));
658 658
659 659 QChartView view(new QChart());
660 660 view.resize(400, 300);
661 661 view.chart()->addSeries(m_series);
662 662 view.chart()->createDefaultAxes();
663 663 view.show();
664 664 QTest::qWaitForWindowShown(&view);
665 665
666 666 // This is hack since view does not get events otherwise
667 667 view.setMouseTracking(true);
668 668
669 669 // Calculate expected layout for candlesticks
670 670 QRectF plotArea = view.chart()->plotArea();
671 671 qreal candlestickWidth = plotArea.width() / m_series->count();
672 672 qreal candlestickHeight = plotArea.height();
673 673
674 674 QMap<QCandlestickSet *, QRectF> layout;
675 675 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
676 676 plotArea.top(), candlestickWidth, candlestickHeight));
677 677 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
678 678 plotArea.top(), candlestickWidth, candlestickHeight));
679 679
680 680 // Move mouse to left border
681 681 QTest::mouseMove(view.viewport(), QPoint(0, layout.value(set1).center().y()));
682 682 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
683 683
684 684 QCOMPARE(seriesSpy.count(), 0);
685 685 QCOMPARE(setSpy1.count(), 0);
686 686 QCOMPARE(setSpy2.count(), 0);
687 687
688 688 // Move mouse on top of set 1
689 689 QTest::mouseMove(view.viewport(), layout.value(set1).center().toPoint());
690 690 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
691 691
692 692 QCOMPARE(seriesSpy.count(), 1);
693 693 QCOMPARE(setSpy1.count(), 1);
694 694 QCOMPARE(setSpy2.count(), 0);
695 695
696 696 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
697 697 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set1);
698 698 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
699 699 QCOMPARE(seriesSpyArgs.at(0).toBool(), true);
700 700 seriesSpyArgs.clear();
701 701
702 702 QList<QVariant> setSpyArgs = setSpy1.takeFirst();
703 703 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
704 704 QCOMPARE(setSpyArgs.at(0).toBool(), true);
705 705 setSpyArgs.clear();
706 706
707 707 // Move mouse from top of set 1 to top of set 2
708 708 QTest::mouseMove(view.viewport(), layout.value(set2).center().toPoint());
709 709 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
710 710
711 711 QCOMPARE(seriesSpy.count(), 2);
712 712 QCOMPARE(setSpy1.count(), 1);
713 713 QCOMPARE(setSpy2.count(), 1);
714 714
715 715 // Should leave set 1
716 716 seriesSpyArgs = seriesSpy.takeFirst();
717 717 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set1);
718 718 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
719 719 QCOMPARE(seriesSpyArgs.at(0).toBool(), false);
720 720 // Don't call seriesSpyArgs.clear() here
721 721
722 722 setSpyArgs = setSpy1.takeFirst();
723 723 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
724 724 QCOMPARE(setSpyArgs.at(0).toBool(), false);
725 725 // Don't call setSpyArgs.clear() here
726 726
727 727 // Should enter set 2
728 728 seriesSpyArgs = seriesSpy.takeFirst();
729 729 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set2);
730 730 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
731 731 QCOMPARE(seriesSpyArgs.at(0).toBool(), true);
732 732 seriesSpyArgs.clear();
733 733
734 734 setSpyArgs = setSpy2.takeFirst();
735 735 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
736 736 QCOMPARE(setSpyArgs.at(0).toBool(), true);
737 737 setSpyArgs.clear();
738 738
739 739 // Move mouse from top of set 2 to background
740 740 QTest::mouseMove(view.viewport(), QPoint(layout.value(set2).center().x(), 0));
741 741 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
742 742
743 743 QCOMPARE(seriesSpy.count(), 1);
744 744 QCOMPARE(setSpy1.count(), 0);
745 745 QCOMPARE(setSpy2.count(), 1);
746 746
747 747 // Should leave set 2
748 748 seriesSpyArgs = seriesSpy.takeFirst();
749 749 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(1)), set2);
750 750 QCOMPARE(seriesSpyArgs.at(0).type(), QVariant::Bool);
751 751 QCOMPARE(seriesSpyArgs.at(0).toBool(), false);
752 752 seriesSpyArgs.clear();
753 753
754 754 setSpyArgs = setSpy2.takeFirst();
755 755 QCOMPARE(setSpyArgs.at(0).type(), QVariant::Bool);
756 756 QCOMPARE(setSpyArgs.at(0).toBool(), false);
757 757 setSpyArgs.clear();
758 758 }
759 759
760 760 void tst_QCandlestickSeries::mousePressed()
761 761 {
762 762 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
763 763
764 764 QVERIFY(m_series->append(m_sets));
765 765 QCOMPARE(m_series->count(), m_sets.count());
766 766
767 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
768 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
767 QCandlestickSet *set1 = m_series->sets().at(1);
768 QCandlestickSet *set2 = m_series->sets().at(2);
769 769
770 770 QSignalSpy seriesSpy(m_series, SIGNAL(pressed(QCandlestickSet *)));
771 771 QSignalSpy setSpy1(set1, SIGNAL(pressed()));
772 772 QSignalSpy setSpy2(set2, SIGNAL(pressed()));
773 773
774 774 QChartView view(new QChart());
775 775 view.resize(400, 300);
776 776 view.chart()->addSeries(m_series);
777 777 view.chart()->createDefaultAxes();
778 778 view.show();
779 779 QTest::qWaitForWindowShown(&view);
780 780
781 781 // Calculate expected layout for candlesticks
782 782 QRectF plotArea = view.chart()->plotArea();
783 783 qreal candlestickWidth = plotArea.width() / m_series->count();
784 784 qreal candlestickHeight = plotArea.height();
785 785
786 786 QMap<QCandlestickSet *, QRectF> layout;
787 787 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
788 788 plotArea.top(), candlestickWidth, candlestickHeight));
789 789 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
790 790 plotArea.top(), candlestickWidth, candlestickHeight));
791 791
792 792 // Press set 1
793 793 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
794 794 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
795 795
796 796 QCOMPARE(seriesSpy.count(), 1);
797 797 QCOMPARE(setSpy1.count(), 1);
798 798 QCOMPARE(setSpy2.count(), 0);
799 799
800 800 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
801 801 QCOMPARE(seriesSpyArgs.count(), 1);
802 802 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
803 803 seriesSpyArgs.clear();
804 804
805 805 QVERIFY(setSpy1.takeFirst().isEmpty());
806 806
807 807 // Press set 2
808 808 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
809 809 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
810 810
811 811 QCOMPARE(seriesSpy.count(), 1);
812 812 QCOMPARE(setSpy1.count(), 0);
813 813 QCOMPARE(setSpy2.count(), 1);
814 814
815 815 seriesSpyArgs = seriesSpy.takeFirst();
816 816 QCOMPARE(seriesSpyArgs.count(), 1);
817 817 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
818 818 seriesSpyArgs.clear();
819 819
820 820 QVERIFY(setSpy2.takeFirst().isEmpty());
821 821 }
822 822
823 823 void tst_QCandlestickSeries::mouseReleased()
824 824 {
825 825 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
826 826
827 827 QVERIFY(m_series->append(m_sets));
828 828 QCOMPARE(m_series->count(), m_sets.count());
829 829
830 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
831 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
830 QCandlestickSet *set1 = m_series->sets().at(1);
831 QCandlestickSet *set2 = m_series->sets().at(2);
832 832
833 833 QSignalSpy seriesSpy(m_series, SIGNAL(released(QCandlestickSet *)));
834 834 QSignalSpy setSpy1(set1, SIGNAL(released()));
835 835 QSignalSpy setSpy2(set2, SIGNAL(released()));
836 836
837 837 QChartView view(new QChart());
838 838 view.resize(400, 300);
839 839 view.chart()->addSeries(m_series);
840 840 view.chart()->createDefaultAxes();
841 841 view.show();
842 842 QTest::qWaitForWindowShown(&view);
843 843
844 844 // Calculate expected layout for candlesticks
845 845 QRectF plotArea = view.chart()->plotArea();
846 846 qreal candlestickWidth = plotArea.width() / m_series->count();
847 847 qreal candlestickHeight = plotArea.height();
848 848
849 849 QMap<QCandlestickSet *, QRectF> layout;
850 850 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
851 851 plotArea.top(), candlestickWidth, candlestickHeight));
852 852 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
853 853 plotArea.top(), candlestickWidth, candlestickHeight));
854 854
855 855 // Release mouse over set 1
856 856 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
857 857 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
858 858
859 859 QCOMPARE(seriesSpy.count(), 1);
860 860 QCOMPARE(setSpy1.count(), 1);
861 861 QCOMPARE(setSpy2.count(), 0);
862 862
863 863 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
864 864 QCOMPARE(seriesSpyArgs.count(), 1);
865 865 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
866 866 seriesSpyArgs.clear();
867 867
868 868 QVERIFY(setSpy1.takeFirst().isEmpty());
869 869
870 870 // Release mouse over set 2
871 871 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, layout.value(set2).center().toPoint());
872 872 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
873 873
874 874 QCOMPARE(seriesSpy.count(), 1);
875 875 QCOMPARE(setSpy1.count(), 0);
876 876 QCOMPARE(setSpy2.count(), 1);
877 877
878 878 seriesSpyArgs = seriesSpy.takeFirst();
879 879 QCOMPARE(seriesSpyArgs.count(), 1);
880 880 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set2);
881 881 seriesSpyArgs.clear();
882 882
883 883 QVERIFY(setSpy2.takeFirst().isEmpty());
884 884 }
885 885
886 886 void tst_QCandlestickSeries::mouseDoubleClicked()
887 887 {
888 888 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
889 889
890 890 QVERIFY(m_series->append(m_sets));
891 891 QCOMPARE(m_series->count(), m_sets.count());
892 892
893 QCandlestickSet *set1 = m_series->candlestickSets().at(1);
894 QCandlestickSet *set2 = m_series->candlestickSets().at(2);
893 QCandlestickSet *set1 = m_series->sets().at(1);
894 QCandlestickSet *set2 = m_series->sets().at(2);
895 895
896 896 QSignalSpy seriesSpy(m_series, SIGNAL(doubleClicked(QCandlestickSet *)));
897 897 QSignalSpy setSpy1(set1, SIGNAL(doubleClicked()));
898 898 QSignalSpy setSpy2(set2, SIGNAL(doubleClicked()));
899 899
900 900 QChartView view(new QChart());
901 901 view.resize(400, 300);
902 902 view.chart()->addSeries(m_series);
903 903 view.chart()->createDefaultAxes();
904 904 view.show();
905 905 QTest::qWaitForWindowShown(&view);
906 906
907 907 // Calculate expected layout for candlesticks
908 908 QRectF plotArea = view.chart()->plotArea();
909 909 qreal candlestickWidth = plotArea.width() / m_series->count();
910 910 qreal candlestickHeight = plotArea.height();
911 911
912 912 QMap<QCandlestickSet *, QRectF> layout;
913 913 layout.insert(set1, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set1),
914 914 plotArea.top(), candlestickWidth, candlestickHeight));
915 915 layout.insert(set2, QRectF(plotArea.left() + candlestickWidth * m_sets.indexOf(set2),
916 916 plotArea.top(), candlestickWidth, candlestickHeight));
917 917
918 918 // Double-click set 1
919 919 QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, layout.value(set1).center().toPoint());
920 920 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
921 921
922 922 QCOMPARE(seriesSpy.count(), 1);
923 923 QCOMPARE(setSpy1.count(), 1);
924 924 QCOMPARE(setSpy2.count(), 0);
925 925
926 926 QList<QVariant> seriesSpyArgs = seriesSpy.takeFirst();
927 927 QCOMPARE(seriesSpyArgs.count(), 1);
928 928 QCOMPARE(qvariant_cast<QCandlestickSet *>(seriesSpyArgs.at(0)), set1);
929 929 seriesSpyArgs.clear();
930 930
931 931 QVERIFY(setSpy1.takeFirst().isEmpty());
932 932 }
933 933
934 934 QTEST_MAIN(tst_QCandlestickSeries)
935 935
936 936 #include "tst_qcandlestickseries.moc"
@@ -1,691 +1,691
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the 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 The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QBarCategoryAxis>
31 31 #include <QtCharts/QCandlestickSeries>
32 32 #include <QtCharts/QCandlestickSet>
33 33 #include <QtCharts/QDateTimeAxis>
34 34 #include <QtCharts/QHCandlestickModelMapper>
35 35 #include <QtCharts/QValueAxis>
36 36 #include <QtCore/QDateTime>
37 37 #include <QtCore/QDebug>
38 38 #include <QtWidgets/QCheckBox>
39 39 #include <QtWidgets/QComboBox>
40 40 #include <QtWidgets/QDoubleSpinBox>
41 41 #include <QtWidgets/QGridLayout>
42 42 #include <QtWidgets/QHeaderView>
43 43 #include <QtWidgets/QLabel>
44 44 #include <QtWidgets/QPushButton>
45 45 #include <QtWidgets/QTableView>
46 46 #include "customtablemodel.h"
47 47 #include "mainwidget.h"
48 48
49 49 QT_CHARTS_USE_NAMESPACE
50 50
51 51 MainWidget::MainWidget(QWidget *parent)
52 52 : QWidget(parent),
53 53 m_chart(new QChart()),
54 54 m_chartView(new QChartView(m_chart, this)),
55 55 m_axisX(nullptr),
56 56 m_axisY(nullptr),
57 57 m_maximumColumnWidth(-1.0),
58 58 m_minimumColumnWidth(5.0),
59 59 m_bodyOutlineVisible(true),
60 60 m_capsVisible(false),
61 61 m_bodyWidth(0.5),
62 62 m_capsWidth(0.5),
63 63 m_customIncreasingColor(false),
64 64 m_customDecreasingColor(false),
65 65 m_hModelMapper(new QHCandlestickModelMapper(this))
66 66 {
67 67 qsrand(QDateTime::currentDateTime().toTime_t());
68 68
69 69 m_chartView->setRenderHint(QPainter::Antialiasing, false);
70 70
71 71 m_hModelMapper->setModel(new CustomTableModel(this));
72 72 m_hModelMapper->setTimestampColumn(0);
73 73 m_hModelMapper->setOpenColumn(1);
74 74 m_hModelMapper->setHighColumn(2);
75 75 m_hModelMapper->setLowColumn(3);
76 76 m_hModelMapper->setCloseColumn(4);
77 77
78 78 QGridLayout *mainLayout = new QGridLayout();
79 79 mainLayout->addLayout(createSeriesControlsLayout(), 0, 0);
80 80 mainLayout->addLayout(createSetsControlsLayout(), 1, 0);
81 81 mainLayout->addLayout(createCandlestickControlsLayout(), 2, 0);
82 82 mainLayout->addLayout(createMiscellaneousControlsLayout(), 3, 0);
83 83 mainLayout->addWidget(m_chartView, 0, 1, mainLayout->rowCount() + 1, 1);
84 84 mainLayout->addLayout(createModelMapperControlsLayout(), 0, 2, mainLayout->rowCount(), 1);
85 85 setLayout(mainLayout);
86 86
87 87 addSeries();
88 88 }
89 89
90 90 MainWidget::~MainWidget()
91 91 {
92 92 }
93 93
94 94 QGridLayout *MainWidget::createSeriesControlsLayout()
95 95 {
96 96 QGridLayout *layout = new QGridLayout();
97 97 int row = 0;
98 98
99 99 layout->addWidget(new QLabel(QStringLiteral("Series controls:")), row, 0, Qt::AlignLeft);
100 100
101 101 QPushButton *addSeriesButton = new QPushButton(QStringLiteral("Add a series"));
102 102 connect(addSeriesButton, SIGNAL(clicked(bool)), this, SLOT(addSeries()));
103 103 layout->addWidget(addSeriesButton, row++, 1, Qt::AlignLeft);
104 104
105 105 QPushButton *removeSeriesButton = new QPushButton(QStringLiteral("Remove a series"));
106 106 connect(removeSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeSeries()));
107 107 layout->addWidget(removeSeriesButton, row++, 1, Qt::AlignLeft);
108 108
109 109 QPushButton *removeAllSeriesButton = new QPushButton(QStringLiteral("Remove all series"));
110 110 connect(removeAllSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSeries()));
111 111 layout->addWidget(removeAllSeriesButton, row++, 1, Qt::AlignLeft);
112 112
113 113 return layout;
114 114 }
115 115
116 116 QGridLayout *MainWidget::createSetsControlsLayout()
117 117 {
118 118 QGridLayout *layout = new QGridLayout();
119 119 int row = 0;
120 120
121 121 layout->addWidget(new QLabel(QStringLiteral("Sets controls:")), row, 0, Qt::AlignLeft);
122 122
123 123 QPushButton *addSetButton = new QPushButton(QStringLiteral("Add a set"));
124 124 connect(addSetButton, SIGNAL(clicked(bool)), this, SLOT(addSet()));
125 125 layout->addWidget(addSetButton, row++, 1, Qt::AlignLeft);
126 126
127 127 QPushButton *insertSetButton = new QPushButton(QStringLiteral("Insert a set"));
128 128 connect(insertSetButton, SIGNAL(clicked(bool)), this, SLOT(insertSet()));
129 129 layout->addWidget(insertSetButton, row++, 1, Qt::AlignLeft);
130 130
131 131 QPushButton *removeSetButton = new QPushButton(QStringLiteral("Remove a set"));
132 132 connect(removeSetButton, SIGNAL(clicked(bool)), this, SLOT(removeSet()));
133 133 layout->addWidget(removeSetButton, row++, 1, Qt::AlignLeft);
134 134
135 135 QPushButton *removeAllSetsButton = new QPushButton(QStringLiteral("Remove all sets"));
136 136 connect(removeAllSetsButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSets()));
137 137 layout->addWidget(removeAllSetsButton, row++, 1, Qt::AlignLeft);
138 138
139 139 return layout;
140 140 }
141 141
142 142 QGridLayout *MainWidget::createCandlestickControlsLayout()
143 143 {
144 144 QGridLayout *layout = new QGridLayout();
145 145 int row = 0;
146 146
147 147 layout->addWidget(new QLabel(QStringLiteral("Maximum column width:")), row, 0, Qt::AlignLeft);
148 148 QDoubleSpinBox *maximumColumnWidthSpinBox = new QDoubleSpinBox();
149 149 maximumColumnWidthSpinBox->setRange(-1.0, 1024.0);
150 150 maximumColumnWidthSpinBox->setDecimals(0);
151 151 maximumColumnWidthSpinBox->setValue(m_maximumColumnWidth);
152 152 maximumColumnWidthSpinBox->setSingleStep(1.0);
153 153 connect(maximumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
154 154 this, SLOT(changeMaximumColumnWidth(double)));
155 155 layout->addWidget(maximumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
156 156
157 157 layout->addWidget(new QLabel(QStringLiteral("Minimum column width:")), row, 0, Qt::AlignLeft);
158 158 QDoubleSpinBox *minimumColumnWidthSpinBox = new QDoubleSpinBox();
159 159 minimumColumnWidthSpinBox->setRange(-1.0, 1024.0);
160 160 minimumColumnWidthSpinBox->setDecimals(0);
161 161 minimumColumnWidthSpinBox->setValue(m_minimumColumnWidth);
162 162 minimumColumnWidthSpinBox->setSingleStep(1.0);
163 163 connect(minimumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
164 164 this, SLOT(changeMinimumColumnWidth(double)));
165 165 layout->addWidget(minimumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);
166 166
167 167 QCheckBox *bodyOutlineVisible = new QCheckBox(QStringLiteral("Body outline visible"));
168 168 connect(bodyOutlineVisible, SIGNAL(toggled(bool)), this, SLOT(bodyOutlineVisibleToggled(bool)));
169 169 bodyOutlineVisible->setChecked(m_bodyOutlineVisible);
170 170 layout->addWidget(bodyOutlineVisible, row++, 0, Qt::AlignLeft);
171 171
172 172 QCheckBox *capsVisible = new QCheckBox(QStringLiteral("Caps visible"));
173 173 connect(capsVisible, SIGNAL(toggled(bool)), this, SLOT(capsVisibleToggled(bool)));
174 174 capsVisible->setChecked(m_capsVisible);
175 175 layout->addWidget(capsVisible, row++, 0, Qt::AlignLeft);
176 176
177 177 layout->addWidget(new QLabel(QStringLiteral("Candlestick body width:")), row, 0, Qt::AlignLeft);
178 178 QDoubleSpinBox *bodyWidthSpinBox = new QDoubleSpinBox();
179 179 bodyWidthSpinBox->setRange(-1.0, 2.0);
180 180 bodyWidthSpinBox->setValue(m_bodyWidth);
181 181 bodyWidthSpinBox->setSingleStep(0.1);
182 182 connect(bodyWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeBodyWidth(double)));
183 183 layout->addWidget(bodyWidthSpinBox, row++, 1, Qt::AlignLeft);
184 184
185 185 layout->addWidget(new QLabel(QStringLiteral("Candlestick caps width:")), row, 0, Qt::AlignLeft);
186 186 QDoubleSpinBox *capsWidthSpinBox = new QDoubleSpinBox();
187 187 capsWidthSpinBox->setRange(-1.0, 2.0);
188 188 capsWidthSpinBox->setValue(m_capsWidth);
189 189 capsWidthSpinBox->setSingleStep(0.1);
190 190 connect(capsWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeCapsWidth(double)));
191 191 layout->addWidget(capsWidthSpinBox, row++, 1, Qt::AlignLeft);
192 192
193 193 QCheckBox *increasingColor = new QCheckBox(QStringLiteral("Custom increasing color (only S1)"));
194 194 connect(increasingColor, SIGNAL(toggled(bool)), this, SLOT(customIncreasingColorToggled(bool)));
195 195 increasingColor->setChecked(m_customIncreasingColor);
196 196 layout->addWidget(increasingColor, row++, 0, 1, 2, Qt::AlignLeft);
197 197
198 198 QCheckBox *decreasingColor = new QCheckBox(QStringLiteral("Custom decreasing color (only S1)"));
199 199 connect(decreasingColor, SIGNAL(toggled(bool)), this, SLOT(customDecreasingColorToggled(bool)));
200 200 decreasingColor->setChecked(m_customDecreasingColor);
201 201 layout->addWidget(decreasingColor, row++, 0, 1, 2, Qt::AlignLeft);
202 202
203 203 return layout;
204 204 }
205 205
206 206 QGridLayout *MainWidget::createMiscellaneousControlsLayout()
207 207 {
208 208 QGridLayout *layout = new QGridLayout();
209 209 int row = 0;
210 210
211 211 layout->addWidget(new QLabel(QStringLiteral("Miscellaneous:")), row, 0, Qt::AlignLeft);
212 212
213 213 QCheckBox *antialiasingCheckBox = new QCheckBox(QStringLiteral("Antialiasing"));
214 214 connect(antialiasingCheckBox, SIGNAL(toggled(bool)), this, SLOT(antialiasingToggled(bool)));
215 215 antialiasingCheckBox->setChecked(false);
216 216 layout->addWidget(antialiasingCheckBox, row++, 1, Qt::AlignLeft);
217 217
218 218 QCheckBox *animationCheckBox = new QCheckBox(QStringLiteral("Animation"));
219 219 connect(animationCheckBox, SIGNAL(toggled(bool)), this, SLOT(animationToggled(bool)));
220 220 animationCheckBox->setChecked(false);
221 221 layout->addWidget(animationCheckBox, row++, 1, Qt::AlignLeft);
222 222
223 223 QCheckBox *legendCheckBox = new QCheckBox(QStringLiteral("Legend"));
224 224 connect(legendCheckBox, SIGNAL(toggled(bool)), this, SLOT(legendToggled(bool)));
225 225 legendCheckBox->setChecked(true);
226 226 layout->addWidget(legendCheckBox, row++, 1, Qt::AlignLeft);
227 227
228 228 QCheckBox *titleCheckBox = new QCheckBox(QStringLiteral("Title"));
229 229 connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
230 230 titleCheckBox->setChecked(true);
231 231 layout->addWidget(titleCheckBox, row++, 1, Qt::AlignLeft);
232 232
233 233 layout->addWidget(new QLabel(QStringLiteral("Chart theme:")), row, 0, Qt::AlignLeft);
234 234 QComboBox *chartThemeComboBox = new QComboBox();
235 235 chartThemeComboBox->addItem(QStringLiteral("Light"));
236 236 chartThemeComboBox->addItem(QStringLiteral("Blue Cerulean"));
237 237 chartThemeComboBox->addItem(QStringLiteral("Dark"));
238 238 chartThemeComboBox->addItem(QStringLiteral("Brown Sand"));
239 239 chartThemeComboBox->addItem(QStringLiteral("Blue Ncs"));
240 240 chartThemeComboBox->addItem(QStringLiteral("High Contrast"));
241 241 chartThemeComboBox->addItem(QStringLiteral("Blue Icy"));
242 242 chartThemeComboBox->addItem(QStringLiteral("Qt"));
243 243 connect(chartThemeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeChartTheme(int)));
244 244 layout->addWidget(chartThemeComboBox, row++, 1, Qt::AlignLeft);
245 245
246 246 layout->addWidget(new QLabel(QStringLiteral("Axis X:")), row, 0, Qt::AlignLeft);
247 247 QComboBox *axisXComboBox = new QComboBox();
248 248 axisXComboBox->addItem(QStringLiteral("BarCategory"));
249 249 axisXComboBox->addItem(QStringLiteral("DateTime"));
250 250 axisXComboBox->addItem(QStringLiteral("Value"));
251 251 connect(axisXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAxisX(int)));
252 252 layout->addWidget(axisXComboBox, row++, 1, Qt::AlignLeft);
253 253
254 254 return layout;
255 255 }
256 256
257 257 QGridLayout *MainWidget::createModelMapperControlsLayout()
258 258 {
259 259 QGridLayout *layout = new QGridLayout();
260 260 int row = 0;
261 261
262 262 layout->addWidget(new QLabel(QStringLiteral("First series:")), row, 0, Qt::AlignLeft);
263 263
264 264 QPushButton *attachModelMapperButton = new QPushButton(QStringLiteral("Attach model mapper"));
265 265 connect(attachModelMapperButton, SIGNAL(clicked(bool)), this, SLOT(attachModelMapper()));
266 266 layout->addWidget(attachModelMapperButton, row++, 1, Qt::AlignLeft);
267 267
268 268 QPushButton *detachModelMappeButton = new QPushButton(QStringLiteral("Detach model mapper"));
269 269 connect(detachModelMappeButton, SIGNAL(clicked(bool)), this, SLOT(detachModelMapper()));
270 270 layout->addWidget(detachModelMappeButton, row++, 1, Qt::AlignLeft);
271 271
272 272 QTableView *tableView = new QTableView();
273 273 tableView->setMinimumSize(320, 480);
274 274 tableView->setMaximumSize(320, 480);
275 275 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
276 276 tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
277 277 Q_ASSERT_X(m_hModelMapper->model(), Q_FUNC_INFO, "Model is not initialized");
278 278 tableView->setModel(m_hModelMapper->model());
279 279 layout->addWidget(tableView, row++, 0, 1, 2, Qt::AlignLeft);
280 280
281 281 layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);
282 282
283 283 return layout;
284 284 }
285 285
286 286 qreal MainWidget::randomValue(int min, int max) const
287 287 {
288 288 return (qrand() / (qreal(RAND_MAX) + 1)) * ((qMax(min, max) - qMin(min, max)) + qMin(min, max));
289 289 }
290 290
291 291 QCandlestickSet *MainWidget::randomSet(qreal timestamp)
292 292 {
293 293 QCandlestickSet *set = new QCandlestickSet(timestamp);
294 294 set->setOpen(randomValue(4, 11));
295 295 set->setHigh(randomValue(12, 15));
296 296 set->setLow(randomValue(0, 3));
297 297 set->setClose(randomValue(4, 11));
298 298
299 299 return set;
300 300 }
301 301
302 302 void MainWidget::updateAxes()
303 303 {
304 304 if (m_chart->axes().isEmpty())
305 305 m_chart->createDefaultAxes();
306 306
307 307 QCandlestickSeries *series;
308 308 if (!m_chart->series().isEmpty())
309 309 series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
310 310 else
311 311 series = nullptr;
312 312
313 313 m_axisX = m_chart->axes(Qt::Horizontal).first();
314 if (series && !series->candlestickSets().isEmpty()) {
314 if (series && !series->sets().isEmpty()) {
315 315 if (m_axisX->type() == QAbstractAxis::AxisTypeBarCategory) {
316 316 QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(m_axisX);
317 317 QStringList categories;
318 for (int i = 0; i < series->candlestickSets().count(); ++i)
318 for (int i = 0; i < series->sets().count(); ++i)
319 319 categories.append(QString::number(i));
320 320 axisX->setCategories(categories);
321 321 } else { // QAbstractAxis::AxisTypeDateTime || QAbstractAxis::AxisTypeValue
322 322 qreal msInMonth = 31.0 * 24.0 * 60.0 * 60.0 * 1000.0;
323 qreal min = series->candlestickSets().first()->timestamp() - msInMonth;
324 qreal max = series->candlestickSets().last()->timestamp() + msInMonth;
323 qreal min = series->sets().first()->timestamp() - msInMonth;
324 qreal max = series->sets().last()->timestamp() + msInMonth;
325 325 QDateTime minDateTime = QDateTime::fromMSecsSinceEpoch(min);
326 326 QDateTime maxDateTime = QDateTime::fromMSecsSinceEpoch(max);
327 327
328 328 if (m_axisX->type() == QAbstractAxis::AxisTypeDateTime)
329 329 m_axisX->setRange(minDateTime, maxDateTime);
330 330 else
331 331 m_axisX->setRange(min, max);
332 332 }
333 333 }
334 334
335 335 m_axisY = m_chart->axes(Qt::Vertical).first();
336 336 m_axisY->setMax(15);
337 337 m_axisY->setMin(0);
338 338 }
339 339
340 340 void MainWidget::addSeries()
341 341 {
342 342 if (m_chart->series().count() > 9) {
343 343 qDebug() << "Maximum series count is 10";
344 344 return;
345 345 }
346 346
347 347 QCandlestickSeries *series = new QCandlestickSeries();
348 348 series->setName(QStringLiteral("S%1").arg(m_chart->series().count() + 1));
349 349 series->setMaximumColumnWidth(m_maximumColumnWidth);
350 350 series->setMinimumColumnWidth(m_minimumColumnWidth);
351 351 series->setBodyOutlineVisible(m_bodyOutlineVisible);
352 352 series->setBodyWidth(m_bodyWidth);
353 353 series->setCapsVisible(m_capsVisible);
354 354 series->setCapsWidth(m_capsWidth);
355 355
356 356 if (m_chart->series().isEmpty()) {
357 357 if (m_customIncreasingColor)
358 358 series->setIncreasingColor(QColor(Qt::green));
359 359 if (m_customDecreasingColor)
360 360 series->setDecreasingColor(QColor(Qt::red));
361 361
362 362 for (int month = 1; month <= 12; ++month) {
363 363 QDateTime dateTime;
364 364 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), month, 1));
365 365 dateTime.setTime(QTime(12, 34, 56, 789));
366 366
367 367 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
368 368 series->append(set);
369 369 }
370 370 } else {
371 371 QCandlestickSeries *s = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
372 for (int i = 0; i < s->candlestickSets().count(); ++i) {
373 QCandlestickSet *set = randomSet(s->candlestickSets().at(i)->timestamp());
372 for (int i = 0; i < s->sets().count(); ++i) {
373 QCandlestickSet *set = randomSet(s->sets().at(i)->timestamp());
374 374 series->append(set);
375 375 }
376 376 }
377 377
378 378 m_chart->addSeries(series);
379 379
380 380 updateAxes();
381 381 if (!series->attachedAxes().contains(m_axisX))
382 382 series->attachAxis(m_axisX);
383 383 if (!series->attachedAxes().contains(m_axisY))
384 384 series->attachAxis(m_axisY);
385 385 }
386 386
387 387 void MainWidget::removeSeries()
388 388 {
389 389 if (m_chart->series().isEmpty()) {
390 390 qDebug() << "Create a series first";
391 391 return;
392 392 }
393 393
394 394 if (m_chart->series().count() == 1)
395 395 detachModelMapper();
396 396
397 397 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().last());
398 398 m_chart->removeSeries(series);
399 399 delete series;
400 400 series = nullptr;
401 401 }
402 402
403 403 void MainWidget::removeAllSeries()
404 404 {
405 405 if (m_chart->series().isEmpty()) {
406 406 qDebug() << "Create a series first";
407 407 return;
408 408 }
409 409
410 410 detachModelMapper();
411 411
412 412 m_chart->removeAllSeries();
413 413 }
414 414
415 415 void MainWidget::addSet()
416 416 {
417 417 if (m_chart->series().isEmpty()) {
418 418 qDebug() << "Create a series first";
419 419 return;
420 420 }
421 421
422 422 foreach (QAbstractSeries *s, m_chart->series()) {
423 423 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
424 424
425 425 QDateTime dateTime;
426 426 if (series->count()) {
427 dateTime.setMSecsSinceEpoch(series->candlestickSets().last()->timestamp());
427 dateTime.setMSecsSinceEpoch(series->sets().last()->timestamp());
428 428 dateTime = dateTime.addMonths(1);
429 429 } else {
430 430 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
431 431 dateTime.setTime(QTime(12, 34, 56, 789));
432 432 }
433 433
434 434 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
435 435 series->append(set);
436 436 }
437 437
438 438 updateAxes();
439 439 }
440 440
441 441 void MainWidget::insertSet()
442 442 {
443 443 if (m_chart->series().isEmpty()) {
444 444 qDebug() << "Create a series first";
445 445 return;
446 446 }
447 447
448 448 foreach (QAbstractSeries *s, m_chart->series()) {
449 449 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
450 450
451 451 QDateTime dateTime;
452 452 if (series->count()) {
453 dateTime.setMSecsSinceEpoch(series->candlestickSets().first()->timestamp());
453 dateTime.setMSecsSinceEpoch(series->sets().first()->timestamp());
454 454 dateTime = dateTime.addMonths(-1);
455 455 } else {
456 456 dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
457 457 dateTime.setTime(QTime(12, 34, 56, 789));
458 458 }
459 459
460 460 QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
461 461 series->insert(0, set);
462 462 }
463 463
464 464 updateAxes();
465 465 }
466 466
467 467 void MainWidget::removeSet()
468 468 {
469 469 if (m_chart->series().isEmpty()) {
470 470 qDebug() << "Create a series first";
471 471 return;
472 472 }
473 473
474 474 foreach (QAbstractSeries *s, m_chart->series()) {
475 475 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
476 if (series->candlestickSets().isEmpty())
476 if (series->sets().isEmpty())
477 477 qDebug() << "Create a set first";
478 478 else
479 series->remove(series->candlestickSets().last());
479 series->remove(series->sets().last());
480 480 }
481 481
482 482 updateAxes();
483 483 }
484 484
485 485 void MainWidget::removeAllSets()
486 486 {
487 487 if (m_chart->series().isEmpty()) {
488 488 qDebug() << "Create a series first";
489 489 return;
490 490 }
491 491
492 492 foreach (QAbstractSeries *s, m_chart->series()) {
493 493 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
494 if (series->candlestickSets().isEmpty())
494 if (series->sets().isEmpty())
495 495 qDebug() << "Create a set first";
496 496 else
497 497 series->clear();
498 498 }
499 499
500 500 updateAxes();
501 501 }
502 502
503 503 void MainWidget::changeMaximumColumnWidth(double width)
504 504 {
505 505 m_maximumColumnWidth = width;
506 506 foreach (QAbstractSeries *s, m_chart->series()) {
507 507 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
508 508 series->setMaximumColumnWidth(m_maximumColumnWidth);
509 509 }
510 510 }
511 511
512 512 void MainWidget::changeMinimumColumnWidth(double width)
513 513 {
514 514 m_minimumColumnWidth = width;
515 515 foreach (QAbstractSeries *s, m_chart->series()) {
516 516 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
517 517 series->setMinimumColumnWidth(m_minimumColumnWidth);
518 518 }
519 519 }
520 520
521 521 void MainWidget::bodyOutlineVisibleToggled(bool visible)
522 522 {
523 523 m_bodyOutlineVisible = visible;
524 524 foreach (QAbstractSeries *s, m_chart->series()) {
525 525 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
526 526 series->setBodyOutlineVisible(m_bodyOutlineVisible);
527 527 }
528 528 }
529 529
530 530 void MainWidget::capsVisibleToggled(bool visible)
531 531 {
532 532 m_capsVisible = visible;
533 533 foreach (QAbstractSeries *s, m_chart->series()) {
534 534 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
535 535 series->setCapsVisible(m_capsVisible);
536 536 }
537 537 }
538 538
539 539 void MainWidget::changeBodyWidth(double width)
540 540 {
541 541 m_bodyWidth = width;
542 542 foreach (QAbstractSeries *s, m_chart->series()) {
543 543 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
544 544 series->setBodyWidth(m_bodyWidth);
545 545 }
546 546 }
547 547
548 548 void MainWidget::changeCapsWidth(double width)
549 549 {
550 550 m_capsWidth = width;
551 551 foreach (QAbstractSeries *s, m_chart->series()) {
552 552 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
553 553 series->setCapsWidth(m_capsWidth);
554 554 }
555 555 }
556 556
557 557 void MainWidget::customIncreasingColorToggled(bool custom)
558 558 {
559 559 m_customIncreasingColor = custom;
560 560
561 561 if (m_chart->series().isEmpty())
562 562 return;
563 563
564 564 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
565 565 if (series) {
566 566 QColor color = m_customIncreasingColor ? QColor(Qt::green) : QColor();
567 567 series->setIncreasingColor(color);
568 568 }
569 569 }
570 570
571 571 void MainWidget::customDecreasingColorToggled(bool custom)
572 572 {
573 573 m_customDecreasingColor = custom;
574 574
575 575 if (m_chart->series().isEmpty())
576 576 return;
577 577
578 578 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
579 579 if (series) {
580 580 QColor color = m_customDecreasingColor ? QColor(Qt::red) : QColor();
581 581 series->setDecreasingColor(color);
582 582 }
583 583 }
584 584
585 585 void MainWidget::antialiasingToggled(bool enabled)
586 586 {
587 587 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
588 588 }
589 589
590 590 void MainWidget::animationToggled(bool enabled)
591 591 {
592 592 if (enabled)
593 593 m_chart->setAnimationOptions(QChart::SeriesAnimations);
594 594 else
595 595 m_chart->setAnimationOptions(QChart::NoAnimation);
596 596 }
597 597
598 598 void MainWidget::legendToggled(bool visible)
599 599 {
600 600 m_chart->legend()->setVisible(visible);
601 601 if (visible)
602 602 m_chart->legend()->setAlignment(Qt::AlignBottom);
603 603 }
604 604
605 605 void MainWidget::titleToggled(bool visible)
606 606 {
607 607 if (visible)
608 608 m_chart->setTitle(QStringLiteral("Candlestick Chart"));
609 609 else
610 610 m_chart->setTitle(QString());
611 611 }
612 612
613 613 void MainWidget::changeChartTheme(int themeIndex)
614 614 {
615 615 if (themeIndex < QChart::ChartThemeLight || themeIndex > QChart::ChartThemeQt) {
616 616 qDebug() << "Invalid chart theme index:" << themeIndex;
617 617 return;
618 618 }
619 619
620 620 m_chart->setTheme((QChart::ChartTheme)(themeIndex));
621 621 }
622 622
623 623 void MainWidget::changeAxisX(int axisXIndex)
624 624 {
625 625 if (m_axisX) {
626 626 m_chart->removeAxis(m_axisX);
627 627 delete m_axisX;
628 628 }
629 629
630 630 switch (axisXIndex) {
631 631 case 0:
632 632 m_axisX = new QBarCategoryAxis();
633 633 break;
634 634 case 1:
635 635 m_axisX = new QDateTimeAxis();
636 636 break;
637 637 case 2:
638 638 m_axisX = new QValueAxis();
639 639 break;
640 640 default:
641 641 qDebug() << "Invalid axis x index:" << axisXIndex;
642 642 return;
643 643 }
644 644
645 645 m_chart->addAxis(m_axisX, Qt::AlignBottom);
646 646
647 647 updateAxes();
648 648
649 649 foreach (QAbstractSeries *series, m_chart->series())
650 650 series->attachAxis(m_axisX);
651 651 }
652 652
653 653 void MainWidget::attachModelMapper()
654 654 {
655 655 if (m_hModelMapper->series()) {
656 656 qDebug() << "Model mapper is already attached";
657 657 return;
658 658 }
659 659
660 660 if (m_chart->series().isEmpty())
661 661 addSeries();
662 662
663 663 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
664 664 Q_ASSERT(series);
665 665 series->setName(QStringLiteral("SWMM")); // Series With Model Mapper
666 666
667 667 CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
668 foreach (QCandlestickSet *set, series->candlestickSets())
668 foreach (QCandlestickSet *set, series->sets())
669 669 model->addRow(set);
670 670
671 m_hModelMapper->setFirstCandlestickSetRow(0);
672 m_hModelMapper->setLastCandlestickSetRow(model->rowCount() - 1);
671 m_hModelMapper->setFirstSetRow(0);
672 m_hModelMapper->setLastSetRow(model->rowCount() - 1);
673 673 m_hModelMapper->setSeries(series);
674 674 }
675 675
676 676 void MainWidget::detachModelMapper()
677 677 {
678 678 if (!m_hModelMapper->series())
679 679 return;
680 680
681 681 QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_hModelMapper->series());
682 682 Q_ASSERT(series);
683 683 series->setName(QStringLiteral("S1"));
684 684
685 685 m_hModelMapper->setSeries(nullptr);
686 m_hModelMapper->setFirstCandlestickSetRow(-1);
687 m_hModelMapper->setLastCandlestickSetRow(-1);
686 m_hModelMapper->setFirstSetRow(-1);
687 m_hModelMapper->setLastSetRow(-1);
688 688
689 689 CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
690 690 model->clearRows();
691 691 }
General Comments 0
You need to be logged in to leave comments. Login now