1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtCore/qmath.h>
5#include "qabstract3daxis_p.h"
6#include "qbar3dseries_p.h"
7#include "qcategory3daxis_p.h"
8#include "qquickgraphsbars_p.h"
9#include "qvalue3daxis_p.h"
10
11QT_BEGIN_NAMESPACE
12
13/*!
14 * \class QBar3DSeries
15 * \inmodule QtGraphs
16 * \ingroup graphs_3D
17 * \brief The QBar3DSeries class represents a data series in a 3D bar graph.
18 *
19 * This class manages the series specific visual elements, as well as the series
20 * data (via a data proxy).
21 *
22 * Regarding the proxy-series relationship, it is crucial to highlight
23 * a couple of key points. In this context, data is stored in series and
24 * users can access the dataset through the series. This series is controlled
25 * or represented by a proxy object. Thus, the proxy can be used to manage various
26 * operations on the data and update the actual dataset. However, it is necessary
27 * to create a series associated with this proxy to edit the dataset.
28 *
29 * If no data proxy is set explicitly for the series, the series creates a
30 * default proxy. Setting another proxy will destroy the existing proxy and all
31 * data added to the series.
32 *
33 * QBar3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat():
34 * \table
35 * \row
36 * \li @rowTitle \li Title from row axis
37 * \row
38 * \li @colTitle \li Title from column axis
39 * \row
40 * \li @valueTitle \li Title from value axis
41 * \row
42 * \li @rowIdx \li Visible row index. Localized using the graph locale.
43 * \row
44 * \li @colIdx \li Visible column index. Localized using the graph locale.
45 * \row
46 * \li @rowLabel \li Label from row axis
47 * \row
48 * \li @colLabel \li Label from column axis
49 * \row
50 * \li @valueLabel \li Item value formatted using the format of the value
51 * axis attached to the graph. For more information,
52 * see \l{QValue3DAxis::labelFormat}.
53 * \row
54 * \li @seriesName \li Name of the series
55 * \row
56 * \li %<format spec> \li Item value in the specified format. Formatted
57 * using the same rules as \l{QValue3DAxis::labelFormat}.
58 * \endtable
59 *
60 * For example:
61 * \snippet doc_src_qtgraphs.cpp labelformat
62 *
63 * \sa {Qt Graphs Data Handling with 3D}, Q3DGraphsWidgetItem::locale
64 */
65
66/*!
67 * \qmltype Bar3DSeries
68 * \inqmlmodule QtGraphs
69 * \ingroup graphs_qml_3D
70 * \nativetype QBar3DSeries
71 * \inherits Abstract3DSeries
72 * \brief Represents a data series in a 3D bar graph.
73 *
74 * This type manages the series specific visual elements, as well as the series
75 * data (via a data proxy).
76 *
77 * Bar3DSeries supports the following format tags for itemLabelFormat:
78 * \table
79 * \row
80 * \li @rowTitle \li Title from row axis
81 * \row
82 * \li @colTitle \li Title from column axis
83 * \row
84 * \li @valueTitle \li Title from value axis
85 * \row
86 * \li @rowIdx \li Visible row index. Localized using the graph locale.
87 * \row
88 * \li @colIdx \li Visible column index. Localized using the graph locale.
89 * \row
90 * \li @rowLabel \li Label from row axis
91 * \row
92 * \li @colLabel \li Label from column axis
93 * \row
94 * \li @valueLabel \li Item value formatted using the format of the value
95 * axis attached to the graph. For more information,
96 * see \l{QValue3DAxis::labelFormat}{labelFormat}.
97 * \row
98 * \li @seriesName \li Name of the series
99 * \row
100 * \li %<format spec> \li Item value in the specified format. Formatted
101 * using the same rules as \l{QValue3DAxis::labelFormat}{labelFormat}.
102 * \endtable
103 *
104 * For a more complete description, see QBar3DSeries.
105 *
106 * \sa {Qt Graphs Data Handling with 3D}
107 */
108
109/*!
110 * \qmlproperty BarDataProxy Bar3DSeries::dataProxy
111 *
112 * The active data proxy. The series assumes ownership of any proxy set to
113 * it and deletes any previously set proxy when a new one is added. The proxy
114 * cannot be null or set to another series.
115 */
116
117/*!
118 * \qmlproperty point Bar3DSeries::selectedBar
119 *
120 * The bar in the series that is selected.
121 *
122 * The position of the selected bar is specified as a row and column in the
123 * data array of the series.
124 *
125 * Only one bar can be selected at a time.
126 *
127 * To clear the selection from this series, assign invalidSelectionPosition as the
128 * position.
129 *
130 * If this series is added to a graph, the graph can adjust the selection
131 * according to user interaction or if it becomes invalid. Selecting a bar on
132 * another added series will also clear the selection.
133 *
134 * Removing rows from or inserting rows into the series before the row of the
135 * selected bar will adjust the selection so that the same bar will stay
136 * selected.
137 *
138 * \sa {GraphsItem3D::clearSelection()}{GraphsItem3D.clearSelection()}
139 */
140
141/*!
142 * \qmlproperty point Bar3DSeries::invalidSelectionPosition
143 * \readonly
144 *
145 * A constant property providing an invalid position for selection. This
146 * position is assigned to the selectedBar property to clear the selection from this
147 * series.
148 *
149 * \sa {GraphsItem3D::clearSelection()}{GraphsItem3D.clearSelection()}
150 */
151
152/*!
153 * \qmlproperty real Bar3DSeries::meshAngle
154 *
155 * A convenience property for defining the series rotation angle in degrees.
156 *
157 * \note When reading this property, it is calculated from the
158 * \l{Abstract3DSeries::meshRotation}{Abstract3DSeries.meshRotation} value
159 * using floating point precision and always returns a value from zero to 360
160 * degrees.
161 *
162 * \sa {Abstract3DSeries::meshRotation}{Abstract3DSeries.meshRotation}
163 */
164
165/*!
166 * \qmlproperty list<Color> Bar3DSeries::rowColors
167 * This property can be used to draw the rows of the series in different colors.
168 * The \l{QGraphsTheme::colorStyle}{GraphsTheme.colorStyle} must be set to
169 * \c Uniform to use this property.
170 * \note If the property is set and the theme is changed,
171 * the rowColors list is not cleared automatically.
172 *
173 * \sa QGraphsTheme::ColorStyle::Uniform
174 */
175
176/*!
177 * \qmlproperty list Bar3DSeries::rowLabels
178 *
179 * The optional row labels for the array. Indexes in this array match the row
180 * indexes in the data array.
181 * If the list is shorter than the number of rows, all rows will not get labels.
182 */
183
184/*!
185 * \qmlproperty list Bar3DSeries::columnLabels
186 *
187 * The optional column labels for the array. Indexes in this array match column
188 * indexes in rows. If the list is shorter than the longest row, all columns
189 * will not get labels.
190 */
191
192/*!
193 * \qmlproperty BarDataArray Bar3DSeries::dataArray
194 *
195 * Holds the reference of the data array.
196 *
197 * dataArrayChanged signal is emitted when data array is set, unless \a newDataArray
198 * is identical to the previous one.
199 *
200 * \note Before doing anything regarding the dataArray, a series must be created for
201 * the relevant proxy.
202 */
203
204/*!
205 \qmlsignal Bar3DSeries::dataProxyChanged(BarDataProxy proxy)
206
207 This signal is emitted when dataProxy changes to \a proxy.
208*/
209
210/*!
211 \qmlsignal Bar3DSeries::selectedBarChanged(point position)
212
213 This signal is emitted when selectedBar changes to \a position.
214*/
215
216/*!
217 \qmlsignal Bar3DSeries::meshAngleChanged(real angle)
218
219 This signal is emitted when meshAngle changes to \a angle.
220*/
221
222/*!
223 \qmlsignal Bar3DSeries::rowColorsChanged(list<color> rowcolors)
224
225 This signal is emitted when rowColors changes to \a rowcolors.
226*/
227
228/*!
229 \qmlsignal Bar3DSeries::rowLabelsChanged()
230
231 This signal is emitted when row labels change.
232*/
233
234/*!
235 \qmlsignal Bar3DSeries::columnLabelsChanged()
236
237 This signal is emitted when column labels change.
238*/
239
240/*!
241 \qmlsignal Bar3DSeries::dataArrayChanged(BarDataArray array)
242
243 This signal is emitted when dataArray changes to \a array.
244*/
245
246/*!
247 * Constructs a bar 3D series with the parent \a parent.
248 */
249QBar3DSeries::QBar3DSeries(QObject *parent)
250 : QAbstract3DSeries(*(new QBar3DSeriesPrivate()), parent)
251{
252 Q_D(QBar3DSeries);
253 // Default proxy
254 d->setDataProxy(new QBarDataProxy);
255 connectSignals();
256}
257
258/*!
259 * Constructs a bar 3D series with the data proxy \a dataProxy and the parent
260 * \a parent.
261 */
262QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent)
263 : QAbstract3DSeries(*(new QBar3DSeriesPrivate()), parent)
264{
265 Q_D(QBar3DSeries);
266 d->setDataProxy(dataProxy);
267 connectSignals();
268}
269
270/*!
271 * Deletes a bar 3D series.
272 */
273QBar3DSeries::~QBar3DSeries()
274{
275 clearArray();
276}
277
278/*!
279 * \property QBar3DSeries::dataProxy
280 *
281 * \brief The active data proxy.
282 *
283 * The series assumes ownership of any proxy set to it and deletes any
284 * previously set proxy when a new one is added. The proxy cannot be null or
285 * set to another series.
286 */
287void QBar3DSeries::setDataProxy(QBarDataProxy *proxy)
288{
289 Q_D(QBar3DSeries);
290 d->setDataProxy(proxy);
291}
292
293QBarDataProxy *QBar3DSeries::dataProxy() const
294{
295 Q_D(const QBar3DSeries);
296 return static_cast<QBarDataProxy *>(d->dataProxy());
297}
298
299/*!
300 * \property QBar3DSeries::selectedBar
301 *
302 * \brief The bar in the series that is selected.
303 *
304 */
305
306/*!
307 * Selects the bar at the \a position position, specified as a row and column in
308 * the data array of the series.
309 *
310 * Only one bar can be selected at a time.
311 *
312 * To clear the selection from this series, invalidSelectionPosition() is set as
313 * \a position.
314 *
315 * If this series is added to a graph, the graph can adjust the selection
316 * according to user interaction or if it becomes invalid. Selecting a bar on
317 * another added series will also clear the selection.
318 *
319 * Removing rows from or inserting rows into the series before the row of the
320 * selected bar will adjust the selection so that the same bar will stay
321 * selected.
322 *
323 * \sa Q3DGraphsWidgetItem::clearSelection()
324 */
325void QBar3DSeries::setSelectedBar(QPoint position)
326{
327 Q_D(QBar3DSeries);
328 // Don't do this in private to avoid loops, as that is used for callback from
329 // graph.
330 if (d->m_graph)
331 static_cast<QQuickGraphsBars *>(d->m_graph)->setSelectedBar(coord: position, series: this, enterSlice: true);
332 else
333 d->setSelectedBar(position);
334}
335
336QPoint QBar3DSeries::selectedBar() const
337{
338 Q_D(const QBar3DSeries);
339 return d->m_selectedBar;
340}
341
342/*!
343 * Returns an invalid position for selection. This position is set to the
344 * selectedBar property to clear the selection from this series.
345 *
346 * \sa Q3DGraphsWidgetItem::clearSelection()
347 */
348QPoint QBar3DSeries::invalidSelectionPosition()
349{
350 return QQuickGraphsBars::invalidSelectionPosition();
351}
352
353static inline float quaternionAngle(const QQuaternion &rotation)
354{
355 return qRadiansToDegrees(radians: qAcos(v: rotation.scalar())) * 2.f;
356}
357
358/*!
359 \property QBar3DSeries::meshAngle
360
361 \brief The series rotation angle in degrees.
362
363 Setting this property is equivalent to the following call:
364
365 \code
366 setMeshRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, angle))
367 \endcode
368
369 \note When reading this property, it is calculated from the
370 QAbstract3DSeries::meshRotation value using floating point precision
371 and always returns a value from zero to 360 degrees.
372
373 \sa QAbstract3DSeries::meshRotation
374 */
375void QBar3DSeries::setMeshAngle(float angle)
376{
377 setMeshRotation(QQuaternion::fromAxisAndAngle(axis: upVector, angle));
378}
379
380float QBar3DSeries::meshAngle() const
381{
382 QQuaternion rotation = meshRotation();
383
384 if (rotation.isIdentity() || rotation.x() != 0.0f || rotation.z() != 0.0f)
385 return 0.0f;
386 else
387 return quaternionAngle(rotation);
388}
389
390/*!
391 * \property QBar3DSeries::rowColors
392 *
393 * \brief The list of row colors in the series.
394 *
395 * This property can be used to color
396 * the rows of the series in different colors.
397 * The QGraphsTheme::ColorStyle must be set to
398 * QGraphsTheme::ColorStyle::Uniform to use this property.
399 *
400 * \sa QGraphsTheme::ColorStyle::Uniform
401 */
402void QBar3DSeries::setRowColors(const QList<QColor> &colors)
403{
404 Q_D(QBar3DSeries);
405 d->setRowColors(colors);
406}
407
408/*!
409 * \property QBar3DSeries::dataArray
410 *
411 * \brief Data array for the series.
412 *
413 * Holds the reference of the data array.
414 *
415 * dataArrayChanged signal is emitted when data array is set, unless \a newDataArray
416 * is identical to the previous one.
417 *
418 * \note Before doing anything regarding the dataArray, a series must be created for
419 * the relevant proxy.
420 *
421 *\sa clearRow(qsizetype rowIndex)
422 *
423 *\sa clearArray()
424 */
425void QBar3DSeries::setDataArray(const QBarDataArray &newDataArray)
426{
427 Q_D(QBar3DSeries);
428 if (d->m_dataArray.data() != newDataArray.data())
429 d->m_dataArray = newDataArray;
430}
431
432/*!
433 * Clears the existing row in the array according to given \a rowIndex.
434 */
435void QBar3DSeries::clearRow(qsizetype rowIndex)
436{
437 Q_D(QBar3DSeries);
438 d->clearRow(rowIndex);
439}
440
441/*!
442 * Clears the existing array.
443 */
444void QBar3DSeries::clearArray()
445{
446 Q_D(QBar3DSeries);
447 d->clearArray();
448}
449
450const QBarDataArray &QBar3DSeries::dataArray() const &
451{
452 Q_D(const QBar3DSeries);
453 return d->m_dataArray;
454}
455
456QBarDataArray QBar3DSeries::dataArray() &&
457{
458 Q_D(QBar3DSeries);
459 return std::move(d->m_dataArray);
460}
461
462/*!
463 * \property QBar3DSeries::rowLabels
464 *
465 * \brief The optional row labels for the array.
466 *
467 * Indexes in this array match the row indexes in the data array.
468 * If the list is shorter than the number of rows, all rows will not get labels.
469 */
470QStringList QBar3DSeries::rowLabels() const
471{
472 Q_D(const QBar3DSeries);
473 return d->m_rowLabels;
474}
475
476void QBar3DSeries::setRowLabels(const QStringList &labels)
477{
478 Q_D(QBar3DSeries);
479 if (rowLabels() != labels) {
480 d->setRowLabels(labels);
481 emit rowLabelsChanged();
482 }
483}
484
485/*!
486 * \property QBar3DSeries::columnLabels
487 *
488 * \brief The optional column labels for the array.
489 *
490 * Indexes in this array match column indexes in rows.
491 * If the list is shorter than the longest row, all columns will not get labels.
492 */
493QStringList QBar3DSeries::columnLabels() const
494{
495 Q_D(const QBar3DSeries);
496 return d->m_columnLabels;
497}
498
499void QBar3DSeries::setColumnLabels(const QStringList &labels)
500{
501 Q_D(QBar3DSeries);
502 if (columnLabels() != labels) {
503 d->setColumnLabels(labels);
504 emit columnLabelsChanged();
505 }
506}
507
508QList<QColor> QBar3DSeries::rowColors() const
509{
510 Q_D(const QBar3DSeries);
511 return d->m_rowColors;
512}
513
514/*!
515 * \internal
516 */
517void QBar3DSeries::connectSignals()
518{
519 QObject::connect(sender: this,
520 signal: &QAbstract3DSeries::meshRotationChanged,
521 context: this,
522 slot: &QBar3DSeries::handleMeshRotationChanged);
523}
524
525/*!
526 * \internal
527 */
528void QBar3DSeries::handleMeshRotationChanged(const QQuaternion &rotation)
529{
530 emit meshAngleChanged(angle: quaternionAngle(rotation));
531}
532
533// QBar3DSeriesPrivate
534
535QBar3DSeriesPrivate::QBar3DSeriesPrivate()
536 : QAbstract3DSeriesPrivate(QAbstract3DSeries::SeriesType::Bar)
537 , m_selectedBar(QQuickGraphsBars::invalidSelectionPosition())
538{
539 m_itemLabelFormat = QStringLiteral("@valueLabel");
540 m_mesh = QAbstract3DSeries::Mesh::BevelBar;
541}
542
543QBar3DSeriesPrivate::~QBar3DSeriesPrivate() {}
544
545void QBar3DSeriesPrivate::fixRowLabels(qsizetype startIndex,
546 qsizetype count,
547 const QStringList &newLabels,
548 bool isInsert)
549{
550 bool changed = false;
551 qsizetype currentSize = m_rowLabels.size();
552
553 qsizetype newSize = newLabels.size();
554 if (startIndex >= currentSize) {
555 // Adding labels past old label array, create empty strings to fill
556 // intervening space
557 if (newSize) {
558 for (qsizetype i = currentSize; i < startIndex; i++)
559 m_rowLabels << QString();
560 // Doesn't matter if insert, append, or just change when there were no
561 // existing strings, just append new strings.
562 m_rowLabels << newLabels;
563 changed = true;
564 }
565 } else {
566 if (isInsert) {
567 qsizetype insertIndex = startIndex;
568 if (count)
569 changed = true;
570 for (qsizetype i = 0; i < count; i++) {
571 if (i < newSize)
572 m_rowLabels.insert(i: insertIndex++, t: newLabels.at(i));
573 else
574 m_rowLabels.insert(i: insertIndex++, t: QString());
575 }
576 } else {
577 // Either append or change, replace labels up to array end and then add
578 // new ones
579 qsizetype lastChangeIndex = count + startIndex;
580 qsizetype newIndex = 0;
581 for (qsizetype i = startIndex; i < lastChangeIndex; i++) {
582 if (i >= currentSize) {
583 // Label past the current size, so just append the new label
584 if (newSize < newIndex) {
585 changed = true;
586 m_rowLabels << newLabels.at(i: newIndex);
587 } else {
588 break; // No point appending empty strings, so just exit
589 }
590 } else if (newSize > newIndex) {
591 // Replace existing label
592 if (m_rowLabels.at(i) != newLabels.at(i: newIndex)) {
593 changed = true;
594 m_rowLabels[i] = newLabels.at(i: newIndex);
595 }
596 } else {
597 // No more new labels, so clear existing label
598 if (!m_rowLabels.at(i).isEmpty()) {
599 changed = true;
600 m_rowLabels[i] = QString();
601 }
602 }
603 newIndex++;
604 }
605 }
606 }
607
608 if (changed) {
609 Q_Q(QBar3DSeries);
610 emit q->rowLabelsChanged();
611 }
612}
613
614void QBar3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy)
615{
616 Q_ASSERT(proxy->type() == QAbstractDataProxy::DataType::Bar);
617 Q_Q(QBar3DSeries);
618
619 QAbstract3DSeriesPrivate::setDataProxy(proxy);
620
621 emit q->dataProxyChanged(proxy: static_cast<QBarDataProxy *>(proxy));
622}
623
624void QBar3DSeriesPrivate::connectGraphAndProxy(QQuickGraphsItem *newGraph)
625{
626 Q_Q(QBar3DSeries);
627 QBarDataProxy *barDataProxy = static_cast<QBarDataProxy *>(m_dataProxy);
628
629 if (m_graph && barDataProxy) {
630 // Disconnect old graph/old proxy
631 QObject::disconnect(sender: barDataProxy, signal: 0, receiver: m_graph, member: 0);
632 QObject::disconnect(sender: q, signal: 0, receiver: m_graph, member: 0);
633 }
634
635 if (newGraph && barDataProxy) {
636 QQuickGraphsBars *graph = static_cast<QQuickGraphsBars *>(newGraph);
637 QObject::connect(sender: barDataProxy,
638 signal: &QBarDataProxy::arrayReset,
639 context: graph,
640 slot: &QQuickGraphsBars::handleArrayReset);
641 QObject::connect(sender: barDataProxy,
642 signal: &QBarDataProxy::rowsAdded,
643 context: graph,
644 slot: &QQuickGraphsBars::handleRowsAdded);
645 QObject::connect(sender: barDataProxy,
646 signal: &QBarDataProxy::rowsChanged,
647 context: graph,
648 slot: &QQuickGraphsBars::handleRowsChanged);
649 QObject::connect(sender: barDataProxy,
650 signal: &QBarDataProxy::rowsRemoved,
651 context: graph,
652 slot: &QQuickGraphsBars::handleRowsRemoved);
653 QObject::connect(sender: barDataProxy,
654 signal: &QBarDataProxy::rowsInserted,
655 context: graph,
656 slot: &QQuickGraphsBars::handleRowsInserted);
657 QObject::connect(sender: barDataProxy,
658 signal: &QBarDataProxy::itemChanged,
659 context: graph,
660 slot: &QQuickGraphsBars::handleItemChanged);
661 QObject::connect(sender: q,
662 signal: &QBar3DSeries::rowLabelsChanged,
663 context: graph,
664 slot: &QQuickGraphsBars::handleDataRowLabelsChanged);
665 QObject::connect(sender: q,
666 signal: &QBar3DSeries::columnLabelsChanged,
667 context: graph,
668 slot: &QQuickGraphsBars::handleDataColumnLabelsChanged);
669 QObject::connect(sender: q,
670 signal: &QBar3DSeries::dataProxyChanged,
671 context: graph,
672 slot: &QQuickGraphsBars::handleArrayReset);
673 QObject::connect(sender: q,
674 signal: &QBar3DSeries::rowColorsChanged,
675 context: graph,
676 slot: &QQuickGraphsBars::handleRowColorsChanged);
677 }
678}
679
680void QBar3DSeriesPrivate::createItemLabel()
681{
682 Q_Q(QBar3DSeries);
683 static const QString rowIndexTag(QStringLiteral("@rowIdx"));
684 static const QString rowLabelTag(QStringLiteral("@rowLabel"));
685 static const QString rowTitleTag(QStringLiteral("@rowTitle"));
686 static const QString colIndexTag(QStringLiteral("@colIdx"));
687 static const QString colLabelTag(QStringLiteral("@colLabel"));
688 static const QString colTitleTag(QStringLiteral("@colTitle"));
689 static const QString valueTitleTag(QStringLiteral("@valueTitle"));
690 static const QString valueLabelTag(QStringLiteral("@valueLabel"));
691 static const QString seriesNameTag(QStringLiteral("@seriesName"));
692
693 if (m_selectedBar == QBar3DSeries::invalidSelectionPosition()) {
694 m_itemLabel = QString();
695 return;
696 }
697
698 QLocale locale(QLocale::c());
699 if (m_graph)
700 locale = m_graph->locale();
701 else
702 return;
703
704 QCategory3DAxis *categoryAxisZ = static_cast<QCategory3DAxis *>(m_graph->axisZ());
705 QCategory3DAxis *categoryAxisX = static_cast<QCategory3DAxis *>(m_graph->axisX());
706 QValue3DAxis *valueAxis = static_cast<QValue3DAxis *>(m_graph->axisY());
707 qreal selectedBarValue = qreal(q->dataProxy()->itemAt(position: m_selectedBar).value());
708
709 // Custom format expects printf format specifier. There is no tag for it.
710 m_itemLabel = valueAxis->formatter()->stringForValue(value: selectedBarValue, format: m_itemLabelFormat);
711
712 int selBarPosRow = m_selectedBar.x();
713 int selBarPosCol = m_selectedBar.y();
714 m_itemLabel.replace(before: rowIndexTag, after: locale.toString(i: selBarPosRow));
715 if (categoryAxisZ->labels().size() > selBarPosRow)
716 m_itemLabel.replace(before: rowLabelTag, after: categoryAxisZ->labels().at(i: selBarPosRow));
717 else
718 m_itemLabel.replace(before: rowLabelTag, after: QString());
719 m_itemLabel.replace(before: rowTitleTag, after: categoryAxisZ->title());
720 m_itemLabel.replace(before: colIndexTag, after: locale.toString(i: selBarPosCol));
721 if (categoryAxisX->labels().size() > selBarPosCol)
722 m_itemLabel.replace(before: colLabelTag, after: categoryAxisX->labels().at(i: selBarPosCol));
723 else
724 m_itemLabel.replace(before: colLabelTag, after: QString());
725 m_itemLabel.replace(before: colTitleTag, after: categoryAxisX->title());
726 m_itemLabel.replace(before: valueTitleTag, after: valueAxis->title());
727
728 if (m_itemLabel.contains(s: valueLabelTag)) {
729 QString valueLabelText = valueAxis->formatter()->stringForValue(value: selectedBarValue,
730 format: valueAxis->labelFormat());
731 m_itemLabel.replace(before: valueLabelTag, after: valueLabelText);
732 }
733
734 m_itemLabel.replace(before: seriesNameTag, after: m_name);
735}
736
737void QBar3DSeriesPrivate::setSelectedBar(QPoint position)
738{
739 Q_Q(QBar3DSeries);
740 if (position != m_selectedBar) {
741 markItemLabelDirty();
742 m_selectedBar = position;
743 emit q->selectedBarChanged(position: m_selectedBar);
744 }
745}
746
747void QBar3DSeriesPrivate::setRowColors(const QList<QColor> &colors)
748{
749 Q_Q(QBar3DSeries);
750 if (m_rowColors != colors) {
751 m_rowColors = colors;
752 emit q->rowColorsChanged(rowcolors: m_rowColors);
753 }
754}
755
756void QBar3DSeriesPrivate::setDataArray(const QBarDataArray &newDataArray)
757{
758 m_dataArray = newDataArray;
759}
760
761void QBar3DSeriesPrivate::clearRow(qsizetype rowIndex)
762{
763 m_dataArray[rowIndex].clear();
764}
765
766void QBar3DSeriesPrivate::clearArray()
767{
768 m_dataArray.clear();
769}
770
771void QBar3DSeriesPrivate::setRowLabels(const QStringList &labels)
772{
773 m_rowLabels = labels;
774}
775
776void QBar3DSeriesPrivate::setColumnLabels(const QStringList &labels)
777{
778 m_columnLabels = labels;
779}
780
781QT_END_NAMESPACE
782

Provided by KDAB

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

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