1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qbar3dseries_p.h"
5#include "qbardataproxy_p.h"
6
7QT_BEGIN_NAMESPACE
8
9/*!
10 * \class QBarDataProxy
11 * \inmodule QtGraphs
12 * \ingroup graphs_3D
13 * \brief The QBarDataProxy class is the data proxy for a 3D bars graph.
14 *
15 * A bar data proxy handles adding, inserting, changing, and removing rows of
16 * data.
17 *
18 * The data array is a list of vectors (rows) of QBarDataItem instances.
19 * Each row can contain a different number of items or even be null.
20 *
21 * QBarDataProxy takes ownership of all QtGraphs::QBarDataRow objects
22 * passed to it, whether directly or in a QtGraphs::QBarDataArray container.
23 * If bar data row pointers are used to directly modify data after adding the
24 * array to the proxy, the appropriate signal must be emitted to update the
25 * graph.
26 *
27 * QBarDataProxy optionally keeps track of row and column labels, which
28 * QCategory3DAxis can utilize to show axis labels.
29 *
30 * The row and column labels are stored in a separate array from the data in the
31 * series rather. Row processing methods are available in the proxy and provide
32 * alternative versions that do not affect row labels. This enables
33 * the option of having row labels that relate to the position of the data in
34 * the array rather than the data itself. Since the series holds the data and
35 * row and column labels, it is necessary to create a series associated with the
36 * proxy before using these functions for them.
37 *
38 * \sa {Qt Graphs Data Handling with 3D}
39 */
40
41/*!
42 * \typealias QBarDataRow
43 * \relates QBarDataProxy
44 *
45 * A list of \l {QBarDataItem} objects.
46 */
47
48/*!
49 * \typealias QBarDataArray
50 * \relates QBarDataProxy
51 *
52 * A list of pointers to \l {QBarDataRow} objects.
53 */
54
55/*!
56 * \qmltype BarDataProxy
57 * \inqmlmodule QtGraphs
58 * \ingroup graphs_qml_3D
59 * \nativetype QBarDataProxy
60 * \inherits AbstractDataProxy
61 * \brief The data proxy for a 3D bars graph.
62 *
63 * This type handles adding, inserting, changing, and removing rows of data with
64 * Qt Quick 2.
65 *
66 * This type cannot be instantiated, but contains properties that are exposed via
67 * subtypes.
68 *
69 * For a more complete description, see QBarDataProxy.
70 *
71 * \sa ItemModelBarDataProxy, {Qt Graphs Data Handling with 3D}
72 */
73
74/*!
75 * \qmlproperty int BarDataProxy::rowCount
76 * The number of rows in the array.
77 */
78
79/*!
80 * \qmlproperty int BarDataProxy::colCount
81 * The number of columns in the array.
82 */
83
84/*!
85 * \qmlproperty Bar3DSeries BarDataProxy::series
86 *
87 * The series this proxy is attached to.
88 */
89
90/*!
91 \qmlsignal BarDataProxy::itemChanged(int rowIndex, int columnIndex)
92
93 This signal is emitted when the item at the position specified by \a rowIndex
94 and \a columnIndex changes.
95 If the item is changed in the array without calling setItem(),
96 this signal needs to be emitted to update the graph.
97*/
98
99/*!
100 \qmlsignal BarDataProxy::rowCountChanged(int count)
101
102 This signal is emitted when rowCount changes to \a count.
103*/
104
105/*!
106 \qmlsignal BarDataProxy::colCountChanged(int count)
107
108 This signal is emitted when colCount changes to \a count.
109*/
110
111/*!
112 \qmlsignal BarDataProxy::seriesChanged(Bar3DSeries series)
113
114 This signal is emitted when \l series changes to \a series.
115*/
116
117/*!
118 * Constructs a bar data proxy with the given \a parent.
119 */
120QBarDataProxy::QBarDataProxy(QObject *parent)
121 : QAbstractDataProxy(*(new QBarDataProxyPrivate()), parent)
122{}
123
124/*!
125 * \internal
126 */
127QBarDataProxy::QBarDataProxy(QBarDataProxyPrivate &d, QObject *parent)
128 : QAbstractDataProxy(d, parent)
129{}
130
131/*!
132 * Deletes the bar data proxy.
133 */
134QBarDataProxy::~QBarDataProxy() {}
135
136/*!
137 * \property QBarDataProxy::series
138 *
139 * \brief The series this proxy is attached to.
140 */
141QBar3DSeries *QBarDataProxy::series() const
142{
143 Q_D(const QBarDataProxy);
144 if (!d->series())
145 qWarning(msg: "Series needs to be created to access data members");
146 return static_cast<QBar3DSeries *>(d->series());
147}
148
149/*!
150 * Clears the existing array and row and column labels.
151 */
152void QBarDataProxy::resetArray()
153{
154 Q_D(QBarDataProxy);
155 d->resetArray(newArray: QBarDataArray(), rowLabels: QStringList(), columnLabels: QStringList());
156 emit rowCountChanged(count: rowCount());
157 emit colCountChanged(count: colCount());
158}
159
160/*!
161 * Takes ownership of the array \a newArray. Clears the existing array if the
162 * new array differs from it. If the arrays are the same, this function
163 * just triggers the arrayReset() signal.
164 *
165 * Passing a null array deletes the old array and creates a new empty array.
166 * Row and column labels are not affected.
167 */
168void QBarDataProxy::resetArray(QBarDataArray newArray)
169{
170 Q_D(QBarDataProxy);
171 if (!series())
172 return;
173
174 d->resetArray(newArray: std::move(newArray), rowLabels: QStringList(), columnLabels: QStringList());
175 emit arrayReset();
176 if (rowCount() && colCount()) {
177 emit rowCountChanged(count: rowCount());
178 emit colCountChanged(count: colCount());
179 }
180}
181
182/*!
183 * Takes ownership of the array \a newArray. Clears the existing array if the
184 * new array differs from it. If the arrays are the same, this function
185 * just triggers the arrayReset() signal.
186 *
187 * Passing a null array deletes the old array and creates a new empty array.
188 *
189 * The \a rowLabels and \a columnLabels lists specify the new labels for rows
190 * and columns.
191 */
192void QBarDataProxy::resetArray(QBarDataArray newArray,
193 QStringList rowLabels,
194 QStringList columnLabels)
195{
196 Q_D(QBarDataProxy);
197 if (!series())
198 return;
199
200 d->resetArray(newArray: std::move(newArray), rowLabels: std::move(rowLabels), columnLabels: std::move(columnLabels));
201 emit arrayReset();
202 emit rowCountChanged(count: rowCount());
203 emit colCountChanged(count: colCount());
204}
205
206/*!
207 * Changes an existing row by replacing the row at the position \a rowIndex
208 * with the new row specified by \a row. The new row can be
209 * the same as the existing row already stored at \a rowIndex.
210 * Existing row labels are not affected.
211 */
212void QBarDataProxy::setRow(qsizetype rowIndex, QBarDataRow row)
213{
214 Q_D(QBarDataProxy);
215 d->setRow(rowIndex, row: std::move(row), label: QString());
216 emit rowsChanged(startIndex: rowIndex, count: 1);
217}
218
219/*!
220 * Changes an existing row by replacing the row at the position \a rowIndex
221 * with the new row specified by \a row. The new row can be
222 * the same as the existing row already stored at \a rowIndex.
223 * Changes the row label to \a label.
224 */
225void QBarDataProxy::setRow(qsizetype rowIndex, QBarDataRow row, QString label)
226{
227 Q_D(QBarDataProxy);
228 d->setRow(rowIndex, row: std::move(row), label: std::move(label));
229 emit rowsChanged(startIndex: rowIndex, count: 1);
230}
231
232/*!
233 * Changes existing rows by replacing the rows starting at the position
234 * \a rowIndex with the new rows specifies by \a rows.
235 * Existing row labels are not affected. The rows in the \a rows array can be
236 * the same as the existing rows already stored at \a rowIndex.
237 */
238void QBarDataProxy::setRows(qsizetype rowIndex, QBarDataArray rows)
239{
240 Q_D(QBarDataProxy);
241 d->setRows(rowIndex, rows: std::move(rows), labels: QStringList());
242 emit rowsChanged(startIndex: rowIndex, count: rows.size());
243}
244
245/*!
246 * Changes existing rows by replacing the rows starting at the position
247 * \a rowIndex with the new rows specifies by \a rows.
248 * The row labels are changed to \a labels. The rows in the \a rows array can be
249 * the same as the existing rows already stored at \a rowIndex.
250 */
251void QBarDataProxy::setRows(qsizetype rowIndex, QBarDataArray rows, QStringList labels)
252{
253 Q_D(QBarDataProxy);
254 d->setRows(rowIndex, rows: std::move(rows), labels: std::move(labels));
255 emit rowsChanged(startIndex: rowIndex, count: rows.size());
256}
257
258/*!
259 * Changes a single item at the position specified by \a rowIndex and
260 * \a columnIndex to the item \a item.
261 */
262void QBarDataProxy::setItem(qsizetype rowIndex, qsizetype columnIndex, QBarDataItem item)
263{
264 Q_D(QBarDataProxy);
265 d->setItem(rowIndex, columnIndex, item: std::move(item));
266 emit itemChanged(rowIndex, columnIndex);
267}
268
269/*!
270 * Changes a single item at the position \a position to the item \a item.
271 * The x-value of \a position indicates the row and the y-value indicates the
272 * column.
273 */
274void QBarDataProxy::setItem(QPoint position, QBarDataItem item)
275{
276 setItem(rowIndex: position.x(), columnIndex: position.y(), item);
277}
278
279/*!
280 * Adds the new row \a row to the end of an array.
281 * Existing row labels are not affected.
282 *
283 * Returns the index of the added row.
284 */
285qsizetype QBarDataProxy::addRow(QBarDataRow row)
286{
287 Q_D(QBarDataProxy);
288 qsizetype addIndex = d->addRow(row: std::move(row), label: QString());
289 emit rowsAdded(startIndex: addIndex, count: 1);
290 emit rowCountChanged(count: rowCount());
291 emit colCountChanged(count: colCount());
292 return addIndex;
293}
294
295/*!
296 * Adds a the new row \a row with the label \a label to the end of an array.
297 *
298 * Returns the index of the added row.
299 */
300qsizetype QBarDataProxy::addRow(QBarDataRow row, QString label)
301{
302 Q_D(QBarDataProxy);
303 qsizetype addIndex = d->addRow(row: std::move(row), label: std::move(label));
304 emit rowsAdded(startIndex: addIndex, count: 1);
305 emit rowCountChanged(count: rowCount());
306 emit colCountChanged(count: colCount());
307 return addIndex;
308}
309
310/*!
311 * Adds the new \a rows to the end of an array.
312 * Existing row labels are not affected.
313 *
314 * Returns the index of the first added row.
315 */
316qsizetype QBarDataProxy::addRows(QBarDataArray rows)
317{
318 Q_D(QBarDataProxy);
319 qsizetype addIndex = d->addRows(rows: std::move(rows), labels: QStringList());
320 emit rowsAdded(startIndex: addIndex, count: rows.size());
321 emit rowCountChanged(count: rowCount());
322 emit colCountChanged(count: colCount());
323 return addIndex;
324}
325
326/*!
327 * Adds the new \a rows with \a labels to the end of the array.
328 *
329 * Returns the index of the first added row.
330 */
331qsizetype QBarDataProxy::addRows(QBarDataArray rows, QStringList labels)
332{
333 Q_D(QBarDataProxy);
334 qsizetype addIndex = d->addRows(rows: std::move(rows), labels: std::move(labels));
335 emit rowsAdded(startIndex: addIndex, count: rows.size());
336 emit rowCountChanged(count: rowCount());
337 emit colCountChanged(count: colCount());
338 return addIndex;
339}
340
341/*!
342 * Inserts the new row \a row into \a rowIndex.
343 * If \a rowIndex is equal to the array size, the rows are added to the end of
344 * the array.
345 * The existing row labels are not affected.
346 * \note The row labels array will be out of sync with the row array after this
347 * call if there were labeled rows beyond the inserted row.
348 */
349void QBarDataProxy::insertRow(qsizetype rowIndex, QBarDataRow row)
350{
351 Q_D(QBarDataProxy);
352 d->insertRow(rowIndex, row: std::move(row), label: QString());
353 emit rowsInserted(startIndex: rowIndex, count: 1);
354 emit rowCountChanged(count: rowCount());
355 emit colCountChanged(count: colCount());
356}
357
358/*!
359 * Inserts the new row \a row with the label \a label into \a rowIndex.
360 * If \a rowIndex is equal to array size, rows are added to the end of the
361 * array.
362 */
363void QBarDataProxy::insertRow(qsizetype rowIndex, QBarDataRow row, QString label)
364{
365 Q_D(QBarDataProxy);
366 d->insertRow(rowIndex, row: std::move(row), label: std::move(label));
367 emit rowsInserted(startIndex: rowIndex, count: 1);
368 emit rowCountChanged(count: rowCount());
369 emit colCountChanged(count: colCount());
370}
371
372/*!
373 * Inserts new \a rows into \a rowIndex.
374 * If \a rowIndex is equal to the array size, the rows are added to the end of
375 * the array. The existing row labels are not affected.
376 * \note The row labels array will be out of sync with the row array after this
377 * call if there were labeled rows beyond the inserted rows.
378 */
379void QBarDataProxy::insertRows(qsizetype rowIndex, QBarDataArray rows)
380{
381 Q_D(QBarDataProxy);
382 d->insertRows(rowIndex, rows: std::move(rows), labels: QStringList());
383 emit rowsInserted(startIndex: rowIndex, count: rows.size());
384 emit rowCountChanged(count: rowCount());
385 emit colCountChanged(count: colCount());
386}
387
388/*!
389 * Inserts new \a rows with \a labels into \a rowIndex.
390 * If \a rowIndex is equal to the array size, the rows are added to the end of
391 * the array.
392 */
393void QBarDataProxy::insertRows(qsizetype rowIndex, QBarDataArray rows, QStringList labels)
394{
395 Q_D(QBarDataProxy);
396 d->insertRows(rowIndex, rows: std::move(rows), labels: std::move(labels));
397 emit rowsInserted(startIndex: rowIndex, count: rows.size());
398 emit rowCountChanged(count: rowCount());
399 emit colCountChanged(count: colCount());
400}
401
402/*!
403 * Removes the number of rows specified by \a removeCount starting at the
404 * position \a rowIndex. Attempting to remove rows past the end of the
405 * array does nothing. If \a removeLabels is \c true, the corresponding row
406 * labels are also removed. Otherwise, the row labels are not affected.
407 * \note If \a removeLabels is \c false, the row labels array will be out of
408 * sync with the row array if there are labeled rows beyond the removed rows.
409 */
410void QBarDataProxy::removeRows(qsizetype rowIndex, qsizetype removeCount, RemoveLabels removeLabels)
411{
412 Q_D(QBarDataProxy);
413 if (rowIndex < rowCount() && removeCount >= 1) {
414 d->removeRows(rowIndex, removeCount, removeLabels: removeLabels == RemoveLabels::No ? false : true);
415 emit rowsRemoved(startIndex: rowIndex, count: removeCount);
416 emit rowCountChanged(count: rowCount());
417 emit colCountChanged(count: colCount());
418 }
419}
420
421/*!
422 * \property QBarDataProxy::colCount
423 *
424 * \brief The number of columns in the array.
425 */
426qsizetype QBarDataProxy::colCount() const
427{
428 if (this->series() && this->series()->dataArray().size() > 0)
429 return this->series()->dataArray().at(i: 0).size();
430 else
431 return 0;
432}
433
434/*!
435 * \property QBarDataProxy::rowCount
436 *
437 * \brief The number of rows in the array.
438 */
439qsizetype QBarDataProxy::rowCount() const
440{
441 if (this->series())
442 return this->series()->dataArray().size();
443 else
444 return 0;
445}
446
447/*!
448 * Returns the reference to the row at the position \a rowIndex. It is
449 * guaranteed to be valid only until the next call that modifies data.
450 */
451const QBarDataRow &QBarDataProxy::rowAt(qsizetype rowIndex) const
452{
453 const QBarDataArray &dataArray = this->series()->dataArray();
454 Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
455 return dataArray[rowIndex];
456}
457
458/*!
459 * Returns the reference to the item at the position specified by \a rowIndex
460 * and \a columnIndex. It is guaranteed to be valid only until the next call
461 * that modifies data.
462 */
463const QBarDataItem &QBarDataProxy::itemAt(qsizetype rowIndex, qsizetype columnIndex) const
464{
465 const QBarDataArray &dataArray = this->series()->dataArray();
466 Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
467 const QBarDataRow &dataRow = dataArray[rowIndex];
468 Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size());
469 return dataRow.at(i: columnIndex);
470}
471
472/*!
473 * Returns the reference to the item at the position \a position. The x-value of
474 * \a position indicates the row and the y-value indicates the column. The item
475 * is guaranteed to be valid only until the next call that modifies data.
476 */
477const QBarDataItem &QBarDataProxy::itemAt(QPoint position) const
478{
479 return itemAt(rowIndex: position.x(), columnIndex: position.y());
480}
481
482/*!
483 * \fn void QBarDataProxy::arrayReset()
484 *
485 * This signal is emitted when the data array is reset.
486 * If the contents of the whole array are changed without calling resetArray(),
487 * this signal needs to be emitted to update the graph.
488 */
489
490/*!
491 * \fn void QBarDataProxy::rowsAdded(qsizetype startIndex, qsizetype count)
492 *
493 * This signal is emitted when the number of rows specified by \a count is
494 * added, starting at the position \a startIndex.
495 * If rows are added to the array without calling addRow() or addRows(),
496 * this signal needs to be emitted to update the graph.
497 */
498
499/*!
500 * \fn void QBarDataProxy::rowsChanged(qsizetype startIndex, qsizetype count)
501 *
502 * This signal is emitted when the number of rows specified by \a count is
503 * changed, starting at the position \a startIndex.
504 * If rows are changed in the array without calling setRow() or setRows(),
505 * this signal needs to be emitted to update the graph.
506 */
507
508/*!
509 * \fn void QBarDataProxy::rowsRemoved(qsizetype startIndex, qsizetype count)
510 *
511 * This signal is emitted when the number of rows specified by \a count is
512 * removed, starting at the position \a startIndex.
513 *
514 * The index is the current array size if the rows were removed from the end of
515 * the array. If rows are removed from the array without calling removeRows(),
516 * this signal needs to be emitted to update the graph.
517 */
518
519/*!
520 * \fn void QBarDataProxy::rowsInserted(qsizetype startIndex, qsizetype count)
521 *
522 * This signal is emitted when the number of rows specified by \a count is
523 * inserted at the position \a startIndex.
524 *
525 * If rows are inserted into the array without calling insertRow() or
526 * insertRows(), this signal needs to be emitted to update the graph.
527 */
528
529/*!
530 * \fn void QBarDataProxy::itemChanged(qsizetype rowIndex, qsizetype columnIndex)
531 *
532 * This signal is emitted when the item at the position specified by \a rowIndex
533 * and \a columnIndex changes.
534 * If the item is changed in the array without calling setItem(),
535 * this signal needs to be emitted to update the graph.
536 */
537
538// QBarDataProxyPrivate
539
540QBarDataProxyPrivate::QBarDataProxyPrivate()
541 : QAbstractDataProxyPrivate(QAbstractDataProxy::DataType::Bar)
542{}
543
544QBarDataProxyPrivate::~QBarDataProxyPrivate() {}
545
546void QBarDataProxyPrivate::resetArray(QBarDataArray &&newArray,
547 QStringList &&rowLabels,
548 QStringList &&columnLabels)
549{
550 auto *barSeries = static_cast<QBar3DSeries *>(series());
551 barSeries->setRowLabels(rowLabels);
552 barSeries->setColumnLabels(columnLabels);
553
554 if (newArray.data() != barSeries->dataArray().data()) {
555 barSeries->clearArray();
556 barSeries->setDataArray(newArray);
557 }
558}
559
560void QBarDataProxyPrivate::setRow(qsizetype rowIndex, QBarDataRow &&row, QString &&label)
561{
562 auto *barSeries = static_cast<QBar3DSeries *>(series());
563 Q_ASSERT(rowIndex >= 0 && rowIndex < barSeries->dataArray().size());
564
565 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: rowIndex, count: 1, newLabels: QStringList(label), isInsert: false);
566 if (row.data() != barSeries->dataArray().at(i: rowIndex).data()) {
567 barSeries->clearRow(rowIndex);
568 QBarDataArray array = barSeries->dataArray();
569 array[rowIndex] = row;
570 barSeries->setDataArray(array);
571 }
572}
573
574void QBarDataProxyPrivate::setRows(qsizetype rowIndex, QBarDataArray &&rows, QStringList &&labels)
575{
576 auto *barSeries = static_cast<QBar3DSeries *>(series());
577 Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= barSeries->dataArray().size());
578
579 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: rowIndex, count: rows.size(), newLabels: labels, isInsert: false);
580 for (int i = 0; i < rows.size(); i++) {
581 if (rows.at(i).data() != barSeries->dataArray().at(i: rowIndex).data()) {
582 barSeries->clearRow(rowIndex);
583 QBarDataArray array = barSeries->dataArray();
584 array[rowIndex] = rows.at(i);
585 barSeries->setDataArray(array);
586 }
587 rowIndex++;
588 }
589}
590
591void QBarDataProxyPrivate::setItem(qsizetype rowIndex, qsizetype columnIndex, QBarDataItem &&item)
592{
593 auto *barSeries = static_cast<QBar3DSeries *>(series());
594 Q_ASSERT(rowIndex >= 0 && rowIndex < barSeries->dataArray().size());
595 QBarDataArray array = barSeries->dataArray();
596 QBarDataRow &row = array[rowIndex];
597 Q_ASSERT(columnIndex < row.size());
598 row[columnIndex] = item;
599 barSeries->setDataArray(array);
600}
601
602qsizetype QBarDataProxyPrivate::addRow(QBarDataRow &&row, QString &&label)
603{
604 auto *barSeries = static_cast<QBar3DSeries *>(series());
605 qsizetype currentSize = barSeries->dataArray().size();
606 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: currentSize, count: 1, newLabels: QStringList(label), isInsert: false);
607 QBarDataArray array = barSeries->dataArray();
608 array.append(t: row);
609 barSeries->setDataArray(array);
610 return currentSize;
611}
612
613qsizetype QBarDataProxyPrivate::addRows(QBarDataArray &&rows, QStringList &&labels)
614{
615 auto *barSeries = static_cast<QBar3DSeries *>(series());
616 QBarDataArray array = barSeries->dataArray();
617 qsizetype currentSize = array.size();
618 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: currentSize, count: rows.size(), newLabels: labels, isInsert: false);
619 for (int i = 0; i < rows.size(); i++)
620 array.append(t: rows.at(i));
621 barSeries->setDataArray(array);
622 return currentSize;
623}
624
625void QBarDataProxyPrivate::insertRow(qsizetype rowIndex, QBarDataRow &&row, QString &&label)
626{
627 auto *barSeries = static_cast<QBar3DSeries *>(series());
628 Q_ASSERT(rowIndex >= 0 && rowIndex <= barSeries->dataArray().size());
629 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: rowIndex, count: 1, newLabels: QStringList(label), isInsert: true);
630 QBarDataArray array = barSeries->dataArray();
631 array.insert(i: rowIndex, t: row);
632 barSeries->setDataArray(array);
633}
634
635void QBarDataProxyPrivate::insertRows(qsizetype rowIndex, QBarDataArray &&rows, QStringList &&labels)
636{
637 auto *barSeries = static_cast<QBar3DSeries *>(series());
638 Q_ASSERT(rowIndex >= 0 && rowIndex <= barSeries->dataArray().size());
639 QBarDataArray array = barSeries->dataArray();
640
641 QBar3DSeriesPrivate::get(item: barSeries)->fixRowLabels(startIndex: rowIndex, count: rows.size(), newLabels: labels, isInsert: true);
642 for (int i = 0; i < rows.size(); i++)
643 array.insert(i: rowIndex++, t: rows.at(i));
644 barSeries->setDataArray(array);
645}
646
647void QBarDataProxyPrivate::removeRows(qsizetype rowIndex, qsizetype removeCount, bool removeLabels)
648{
649 auto *barSeries = static_cast<QBar3DSeries *>(series());
650 Q_ASSERT(rowIndex >= 0);
651 qsizetype maxRemoveCount = barSeries->dataArray().size() - rowIndex;
652 removeCount = qMin(a: removeCount, b: maxRemoveCount);
653 bool labelsChanged = false;
654 QBarDataArray array = barSeries->dataArray();
655 for (int i = 0; i < removeCount; i++) {
656 barSeries->clearRow(rowIndex);
657 array.removeAt(i: rowIndex);
658 if (removeLabels && barSeries->rowLabels().size() > rowIndex) {
659 auto rowLabels = barSeries->rowLabels();
660 rowLabels.removeAt(i: rowIndex);
661 barSeries->setRowLabels(rowLabels);
662 labelsChanged = true;
663 }
664 }
665 barSeries->setDataArray(array);
666 if (labelsChanged)
667 emit barSeries->rowLabelsChanged();
668}
669
670QPair<float, float> QBarDataProxyPrivate::limitValues(qsizetype startRow,
671 qsizetype endRow,
672 qsizetype startColumn,
673 qsizetype endColumn) const
674{
675 auto *barSeries = static_cast<QBar3DSeries *>(series());
676 QPair<float, float> limits = qMakePair(value1: 0.0f, value2: 0.0f);
677 endRow = qMin(a: endRow, b: barSeries->dataArray().size() - 1);
678 for (qsizetype i = startRow; i <= endRow; i++) {
679 QBarDataRow row = barSeries->dataArray().at(i);
680 qsizetype lastColumn = qMin(a: endColumn, b: row.size() - 1);
681 for (qsizetype j = startColumn; j <= lastColumn; j++) {
682 const QBarDataItem &item = row.at(i: j);
683 float itemValue = item.value();
684 if (limits.second < itemValue)
685 limits.second = itemValue;
686 if (limits.first > itemValue)
687 limits.first = itemValue;
688 }
689 }
690 return limits;
691}
692
693void QBarDataProxyPrivate::setSeries(QAbstract3DSeries *series)
694{
695 Q_Q(QBarDataProxy);
696 QAbstractDataProxyPrivate::setSeries(series);
697 QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series);
698 emit q->seriesChanged(series: barSeries);
699}
700
701QT_END_NAMESPACE
702

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtgraphs/src/graphs3d/data/qbardataproxy.cpp