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

source code of qtdatavis3d/src/datavisualization/data/qbardataproxy.cpp