1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qcategory3daxis.h"
5#include "qquickgraphssurface_p.h"
6#include "qsurface3dseries_p.h"
7#include "qvalue3daxis.h"
8#include "qgraphs3dlogging_p.h"
9
10QT_BEGIN_NAMESPACE
11
12/*!
13 * \class QSurface3DSeries
14 * \inmodule QtGraphs
15 * \ingroup graphs_3D
16 * \brief The QSurface3DSeries class represents a data series in a 3D surface
17 * 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 * The object mesh set via the QAbstract3DSeries::mesh property defines the
34 * selection pointer shape in a surface series.
35 *
36 * QSurface3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat():
37 * \table
38 * \row
39 * \li @xTitle \li Title from x-axis
40 * \row
41 * \li @yTitle \li Title from y-axis
42 * \row
43 * \li @zTitle \li Title from z-axis
44 * \row
45 * \li @xLabel \li Item value formatted using the format of the x-axis.
46 * For more information, see
47 * \l{QValue3DAxis::labelFormat}.
48 * \row
49 * \li @yLabel \li Item value formatted using the format of the y-axis.
50 * For more information, see
51 * \l{QValue3DAxis::labelFormat}.
52 * \row
53 * \li @zLabel \li Item value formatted using the format of the z-axis.
54 * For more information, see
55 * \l{QValue3DAxis::labelFormat}.
56 * \row
57 * \li @seriesName \li Name of the series
58 * \endtable
59 *
60 * For example:
61 * \snippet doc_src_qtgraphs.cpp labelformat
62 *
63 * \sa {Qt Graphs Data Handling with 3D}
64 */
65
66/*!
67 * \qmltype Surface3DSeries
68 * \inqmlmodule QtGraphs
69 * \ingroup graphs_qml_3D
70 * \nativetype QSurface3DSeries
71 * \inherits Abstract3DSeries
72 * \brief Represents a data series in a 3D surface graph.
73 *
74 * This type manages the series specific visual elements, as well as the series
75 * data (via a data proxy).
76 *
77 * Surface3DSeries supports the following format tags for itemLabelFormat:
78 * \table
79 * \row
80 * \li @xTitle \li Title from x-axis
81 * \row
82 * \li @yTitle \li Title from y-axis
83 * \row
84 * \li @zTitle \li Title from z-axis
85 * \row
86 * \li @xLabel \li Item value formatted using the format of the x-axis.
87 * For more information, see
88 * \l{QValue3DAxis::labelFormat}{labelFormat}.
89 * \row
90 * \li @yLabel \li Item value formatted using the format of the y-axis.
91 * For more information, see
92 * \l{QValue3DAxis::labelFormat}{labelFormat}.
93 * \row
94 * \li @zLabel \li Item value formatted using the format of the z-axis.
95 * For more information, see
96 * \l{QValue3DAxis::labelFormat}{labelFormat}.
97 * \row
98 * \li @seriesName \li Name of the series
99 * \endtable
100 *
101 * For a more complete description, see QSurface3DSeries.
102 *
103 * \sa {Qt Graphs Data Handling with 3D}
104 */
105
106/*!
107 * \qmlproperty SurfaceDataProxy Surface3DSeries::dataProxy
108 *
109 * The active data proxy. The series assumes ownership of any proxy set to
110 * it and deletes any previously set proxy when a new one is added. The proxy
111 * cannot be null or set to another series.
112 */
113
114/*!
115 * \qmlproperty point Surface3DSeries::selectedPoint
116 *
117 * Sets the surface grid point in the position specified by a row and a column
118 * in the data array of the series as selected.
119 * Only one point can be selected at a time.
120 *
121 * To clear the selection from this series, assign invalidSelectionPosition as the
122 * position. If this series is added to a graph, the graph can adjust the
123 * selection according to user interaction or if it becomes invalid.
124 *
125 * Removing rows from or inserting rows into the series before the row of the
126 * selected point will adjust the selection so that the same point will stay
127 * selected.
128 *
129 * \sa GraphsItem3D::clearSelection()
130 */
131
132/*!
133 * \qmlproperty point Surface3DSeries::invalidSelectionPosition
134 * \readonly
135 *
136 * A constant property providing an invalid selection position.
137 * This position is assigned to the selectedPoint property to clear the selection
138 * from this series.
139 *
140 * \sa GraphsItem3D::clearSelection()
141 */
142
143/*!
144 * \qmlproperty Shading Surface3DSeries::shading
145 *
146 * Sets surface flat shading to visible. It is preset to \c Surface3DSeries.Shading.Flat by default.
147 * When disabled, the normals on the surface are interpolated making the edges
148 * look round. When visible, the normals are kept the same on a triangle making
149 * the color of the triangle solid. This makes the data more readable from the
150 * model. \note Flat shaded surfaces require at least GLSL version 1.2 with
151 * GL_EXT_gpu_shader4 extension. The value of the flatShadingSupported property
152 * indicates whether flat shading is supported at runtime.
153 */
154
155/*!
156 * \qmlproperty bool Surface3DSeries::flatShadingSupported
157 *
158 * Indicates whether flat shading for surfaces is supported by the current
159 * system. It requires at least GLSL version 1.2 with GL_EXT_gpu_shader4
160 * extension.
161 *
162 * \note This read-only property is set to its correct value after the first
163 * render pass. Until then it is always \c true.
164 */
165
166/*!
167 * \qmlproperty DrawFlag Surface3DSeries::drawMode
168 *
169 * Sets the drawing mode to one of
170 * \l{QSurface3DSeries::DrawFlag}{Surface3DSeries.DrawFlag}{QSurface3DSeries.DrawFilledSurface}.
171 * Either DrawWireframe or DrawSurface must be set
172 */
173
174/*!
175 * \qmlproperty string Surface3DSeries::textureFile
176 *
177 * The texture file name for the surface texture. To clear the texture, an empty
178 * file name is set.
179 */
180
181/*!
182 * \qmlproperty color Surface3DSeries::wireframeColor
183 *
184 * The color used to draw the gridlines of the surface wireframe.
185 */
186
187/*!
188 * \qmlproperty SurfaceDataArray Surface3DSeries::dataArray
189 *
190 * Holds the reference of the data array.
191 *
192 * dataArrayChanged signal is emitted when data array is set, unless \a newDataArray
193 * is identical to the previous one.
194 *
195 * \note Before doing anything regarding the dataArray, a series must be created for
196 * the relevant proxy.
197 */
198
199/*!
200 \qmlsignal Surface3DSeries::dataProxyChanged(SurfaceDataProxy proxy)
201
202 This signal is emitted when dataProxy changes to \a proxy.
203*/
204/*!
205 \qmlsignal Surface3DSeries::selectedPointChanged(point position)
206
207 This signal is emitted when selectedPoint changes to \a position.
208*/
209/*!
210 \qmlsignal Surface3DSeries::shadingChanged(const Shading shading)
211
212 This signal is emitted when \l shading changes to \a shading.
213*/
214/*!
215 \qmlsignal Surface3DSeries::flatShadingSupportedChanged(bool enable)
216
217 This signal is emitted when flatShadingSupported changes to \a enable.
218*/
219/*!
220 \qmlsignal Surface3DSeries::drawModeChanged(DrawFlag mode)
221
222 This signal is emitted when drawMode changes to \a mode.
223*/
224/*!
225 \qmlsignal Surface3DSeries::textureFileChanged(string filename)
226
227 This signal is emitted when textureFile changes to \a filename.
228*/
229/*!
230 \qmlsignal Surface3DSeries::wireframeColorChanged(color color)
231
232 This signal is emitted when wireframeColor changes to \a color.
233*/
234/*!
235 \qmlsignal Surface3DSeries::dataArrayChanged(SurfaceDataArray array)
236
237 This signal is emitted when dataArray changes to \a array.
238*/
239
240/*!
241 * \enum QSurface3DSeries::DrawFlag
242 *
243 * The drawing mode of the surface. Values of this enumeration can be combined
244 * with the OR operator.
245 *
246 * \value DrawWireframe
247 * Only the grid is drawn.
248 * \value DrawSurface
249 * Only the surface is drawn.
250 * \value DrawSurfaceAndWireframe
251 * Both the surface and grid are drawn.
252 *
253 * \value [since 6.10] DrawFilledSurface
254 * Draws a fill for a surface.
255 * Setting this mode also sets DrawSurface if it is not already set.
256 */
257
258/*!
259 * Constructs a surface 3D series with the parent \a parent.
260 */
261QSurface3DSeries::QSurface3DSeries(QObject *parent)
262 : QAbstract3DSeries(*(new QSurface3DSeriesPrivate()), parent)
263{
264 Q_D(QSurface3DSeries);
265 // Default proxy
266 d->setDataProxy(new QSurfaceDataProxy);
267}
268
269/*!
270 * Constructs a surface 3D series with the data proxy \a dataProxy and the
271 * parent \a parent.
272 */
273QSurface3DSeries::QSurface3DSeries(QSurfaceDataProxy *dataProxy, QObject *parent)
274 : QAbstract3DSeries(*(new QSurface3DSeriesPrivate()), parent)
275{
276 Q_D(QSurface3DSeries);
277 d->setDataProxy(dataProxy);
278}
279
280/*!
281 * \internal
282 */
283QSurface3DSeries::QSurface3DSeries(QSurface3DSeriesPrivate &d, QObject *parent)
284 : QAbstract3DSeries(d, parent)
285{}
286
287/*!
288 * Deletes the surface 3D series.
289 */
290QSurface3DSeries::~QSurface3DSeries() {}
291
292/*!
293 * \property QSurface3DSeries::dataProxy
294 *
295 * \brief The active data proxy.
296 *
297 * The series assumes ownership of any proxy set to it and deletes any
298 * previously set proxy when a new one is added. The proxy cannot be null or
299 * set to another series.
300 */
301void QSurface3DSeries::setDataProxy(QSurfaceDataProxy *proxy)
302{
303 Q_D(QSurface3DSeries);
304 d->setDataProxy(proxy);
305}
306
307QSurfaceDataProxy *QSurface3DSeries::dataProxy() const
308{
309 Q_D(const QSurface3DSeries);
310 return static_cast<QSurfaceDataProxy *>(d->dataProxy());
311}
312
313/*!
314 * \property QSurface3DSeries::selectedPoint
315 *
316 * \brief The surface grid point that is selected in the series.
317 *
318 * Selects a surface grid point at the position \a position in the data array of
319 * the series specified by a row and a column.
320 *
321 * Only one point can be selected at a time.
322 *
323 * To clear the selection from this series, invalidSelectionPosition() is set as \a
324 * position. If this series is added to a graph, the graph can adjust the
325 * selection according to user interaction or if it becomes invalid.
326 *
327 * Removing rows from or inserting rows into the series before the row of the
328 * selected point will adjust the selection so that the same point will stay
329 * selected.
330 *
331 * \sa Q3DGraphsWidgetItem::clearSelection()
332 */
333void QSurface3DSeries::setSelectedPoint(QPoint position)
334{
335 Q_D(QSurface3DSeries);
336 // Don't do this in private to avoid loops, as that is used for callback from
337 // graph.
338 if (d->m_graph)
339 static_cast<QQuickGraphsSurface *>(d->m_graph)->setSelectedPoint(position, series: this, enterSlice: true);
340 else
341 d->setSelectedPoint(position);
342}
343
344QPoint QSurface3DSeries::selectedPoint() const
345{
346 Q_D(const QSurface3DSeries);
347 return d->m_selectedPoint;
348}
349
350/*!
351 * Returns the QPoint signifying an invalid selection position. This is set to
352 * the selectedPoint property to clear the selection from this series.
353 *
354 * \sa Q3DGraphsWidgetItem::clearSelection()
355 */
356QPoint QSurface3DSeries::invalidSelectionPosition()
357{
358 return QQuickGraphsSurface::invalidSelectionPosition();
359}
360
361/*!
362 * \property QSurface3DSeries::shading
363 *
364 * \brief Whether surface flat shading is enabled.
365 *
366 * Preset to \c QSurface3DSeries::Shading::Flat by default.
367 *
368 * When disabled, the normals on the surface are interpolated making the edges
369 * look round. When visible, the normals are kept the same on a triangle making
370 * the color of the triangle solid. This makes the data more readable from the
371 * model. \note Flat shaded surfaces require at least GLSL version 1.2 with
372 * GL_EXT_gpu_shader4 extension. The value of the flatShadingSupported property
373 * indicates whether flat shading is supported at runtime.
374 */
375void QSurface3DSeries::setShading(const QSurface3DSeries::Shading shading)
376{
377 Q_D(QSurface3DSeries);
378 if (d->m_shading == shading) {
379 qCDebug(lcProperties3D) << __FUNCTION__
380 << "value is already set to:" << shading;
381 return;
382 }
383 d->setShading(shading);
384 emit shadingChanged(shading);
385}
386
387QSurface3DSeries::Shading QSurface3DSeries::shading() const
388{
389 Q_D(const QSurface3DSeries);
390 return d->m_shading;
391}
392
393/*!
394 * \property QSurface3DSeries::flatShadingSupported
395 *
396 * \brief Whether surface flat shading is supported by the current system.
397 *
398 * Flat shading for surfaces requires at least GLSL version 1.2 with
399 * GL_EXT_gpu_shader4 extension. If \c true, flat shading for surfaces is
400 * supported. \note This read-only property is set to its correct value after
401 * the first render pass. Until then it is always \c true.
402 */
403bool QSurface3DSeries::isFlatShadingSupported() const
404{
405 Q_D(const QSurface3DSeries);
406 if (d->m_graph)
407 return static_cast<QQuickGraphsSurface *>(d->m_graph)->isFlatShadingSupported();
408 else
409 return true;
410}
411
412/*!
413 * \property QSurface3DSeries::drawMode
414 *
415 * The drawing mode.
416 *
417 * Possible values are the values of DrawFlag. Clearing all flags is not
418 * allowed.
419 */
420void QSurface3DSeries::setDrawMode(QSurface3DSeries::DrawFlags mode)
421{
422 Q_D(QSurface3DSeries);
423 if (d->m_drawMode == mode) {
424 qCDebug(lcProperties3D) << __FUNCTION__
425 << "value is already set to:" << mode;
426 return;
427 }
428 d->setDrawMode(mode);
429 emit drawModeChanged(mode);
430}
431
432QSurface3DSeries::DrawFlags QSurface3DSeries::drawMode() const
433{
434 Q_D(const QSurface3DSeries);
435 return d->m_drawMode;
436}
437
438/*!
439 * \property QSurface3DSeries::texture
440 *
441 * \brief The texture for the surface as a QImage.
442 *
443 * Setting an empty QImage clears the texture.
444 */
445void QSurface3DSeries::setTexture(const QImage &texture)
446{
447 Q_D(QSurface3DSeries);
448 if (d->m_texture == texture) {
449 qCDebug(lcProperties3D) << __FUNCTION__
450 << "value is already set to:" << texture;
451 return;
452 }
453 d->setTexture(texture);
454
455 emit textureChanged(image: texture);
456 d->m_textureFile.clear();
457}
458
459QImage QSurface3DSeries::texture() const
460{
461 Q_D(const QSurface3DSeries);
462 return d->m_texture;
463}
464
465/*!
466 * \property QSurface3DSeries::textureFile
467 *
468 * \brief The texture for the surface as a file.
469 *
470 * Setting an empty file name clears the texture.
471 */
472void QSurface3DSeries::setTextureFile(const QString &filename)
473{
474 Q_D(QSurface3DSeries);
475 if (d->m_textureFile == filename) {
476 qCDebug(lcProperties3D, "%s value is already set to: %s",
477 qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(filename));
478 return;
479 }
480
481 if (filename.isEmpty()) {
482 setTexture(QImage());
483 } else {
484 QImage image(filename);
485 if (image.isNull()) {
486 qCWarning(lcProperties3D, "%s tried to set invalid image file as surface texture.",
487 qUtf8Printable(QLatin1String(__FUNCTION__)));
488 return;
489 }
490 setTexture(image);
491 }
492
493 d->m_textureFile = filename;
494 emit textureFileChanged(filename);
495}
496
497QString QSurface3DSeries::textureFile() const
498{
499 Q_D(const QSurface3DSeries);
500 return d->m_textureFile;
501}
502
503/*!
504 * \property QSurface3DSeries::wireframeColor
505 *
506 * \brief The color for the surface wireframe.
507 */
508void QSurface3DSeries::setWireframeColor(QColor color)
509{
510 Q_D(QSurface3DSeries);
511 if (d->m_wireframeColor == color) {
512 qCDebug(lcProperties3D) << __FUNCTION__
513 << "value is already set to:" << color;
514 return;
515 }
516 d->setWireframeColor(color);
517 emit wireframeColorChanged(color);
518}
519
520QColor QSurface3DSeries::wireframeColor() const
521{
522 Q_D(const QSurface3DSeries);
523 return d->m_wireframeColor;
524}
525
526/*!
527 * \property QSurface3DSeries::dataArray
528 *
529 * \brief Data array for the series.
530 *
531 * Holds the reference of the data array.
532 *
533 * dataArrayChanged signal is emitted when data array is set, unless \a newDataArray
534 * is identical to the previous one.
535 *
536 * \note Before doing anything regarding the dataArray, a series must be created for
537 * the relevant proxy.
538 *
539 *\sa clearRow(qsizetype rowIndex)
540 *
541 *\sa clearArray()
542 */
543void QSurface3DSeries::setDataArray(const QSurfaceDataArray &newDataArray)
544{
545 Q_D(QSurface3DSeries);
546 if (d->m_dataArray.isSharedWith(other: newDataArray)) {
547 qCDebug(lcProperties3D, "%s newDataArray is the same than the current one",
548 qUtf8Printable(QLatin1String(__FUNCTION__)));
549 return;
550 }
551 d->setDataArray(newDataArray);
552 emit dataArrayChanged(array: newDataArray);
553}
554
555/*!
556 * Clears the existing row in the array according to given \a rowIndex.
557 */
558void QSurface3DSeries::clearRow(qsizetype rowIndex)
559{
560 Q_D(QSurface3DSeries);
561 d->clearRow(rowIndex);
562}
563
564/*!
565 * Clears the existing array.
566 */
567void QSurface3DSeries::clearArray()
568{
569 Q_D(QSurface3DSeries);
570 d->clearArray();
571}
572
573const QSurfaceDataArray &QSurface3DSeries::dataArray() const &
574{
575 Q_D(const QSurface3DSeries);
576 return d->m_dataArray;
577}
578
579QSurfaceDataArray QSurface3DSeries::dataArray() &&
580{
581 Q_D(QSurface3DSeries);
582 return std::move(d->m_dataArray);
583}
584
585// QSurface3DSeriesPrivate
586
587QSurface3DSeriesPrivate::QSurface3DSeriesPrivate()
588 : QAbstract3DSeriesPrivate(QAbstract3DSeries::SeriesType::Surface)
589 , m_selectedPoint(QQuickGraphsSurface::invalidSelectionPosition())
590 , m_shading(QSurface3DSeries::Shading::Flat)
591 , m_drawMode(QSurface3DSeries::DrawSurfaceAndWireframe)
592 , m_wireframeColor(Qt::black)
593{
594 m_itemLabelFormat = QStringLiteral("@xLabel, @yLabel, @zLabel");
595 m_mesh = QAbstract3DSeries::Mesh::Sphere;
596}
597
598QSurface3DSeriesPrivate::~QSurface3DSeriesPrivate()
599{
600 clearArray();
601}
602
603void QSurface3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy)
604{
605 Q_ASSERT(proxy->type() == QAbstractDataProxy::DataType::Surface);
606 Q_Q(QSurface3DSeries);
607
608 QAbstract3DSeriesPrivate::setDataProxy(proxy);
609
610 emit q->dataProxyChanged(proxy: static_cast<QSurfaceDataProxy *>(proxy));
611}
612
613void QSurface3DSeriesPrivate::connectGraphAndProxy(QQuickGraphsItem *newGraph)
614{
615 Q_Q(QSurface3DSeries);
616 QSurfaceDataProxy *surfaceDataProxy = static_cast<QSurfaceDataProxy *>(m_dataProxy);
617
618 if (m_graph && surfaceDataProxy) {
619 // Disconnect old graph/old proxy
620 QObject::disconnect(sender: surfaceDataProxy, signal: 0, receiver: m_graph, member: 0);
621 QObject::disconnect(sender: q, signal: 0, receiver: m_graph, member: 0);
622 }
623
624 if (newGraph && surfaceDataProxy) {
625 QQuickGraphsSurface *graph = static_cast<QQuickGraphsSurface *>(newGraph);
626
627 QObject::connect(sender: surfaceDataProxy,
628 signal: &QSurfaceDataProxy::arrayReset,
629 context: graph,
630 slot: &QQuickGraphsSurface::handleArrayReset);
631 QObject::connect(sender: surfaceDataProxy,
632 signal: &QSurfaceDataProxy::rowsAdded,
633 context: graph,
634 slot: &QQuickGraphsSurface::handleRowsAdded);
635 QObject::connect(sender: surfaceDataProxy,
636 signal: &QSurfaceDataProxy::rowsChanged,
637 context: graph,
638 slot: &QQuickGraphsSurface::handleRowsChanged);
639 QObject::connect(sender: surfaceDataProxy,
640 signal: &QSurfaceDataProxy::rowsRemoved,
641 context: graph,
642 slot: &QQuickGraphsSurface::handleRowsRemoved);
643 QObject::connect(sender: surfaceDataProxy,
644 signal: &QSurfaceDataProxy::rowsInserted,
645 context: graph,
646 slot: &QQuickGraphsSurface::handleRowsInserted);
647 QObject::connect(sender: surfaceDataProxy,
648 signal: &QSurfaceDataProxy::itemChanged,
649 context: graph,
650 slot: &QQuickGraphsSurface::handleItemChanged);
651 QObject::connect(sender: q,
652 signal: &QSurface3DSeries::dataProxyChanged,
653 context: graph,
654 slot: &QQuickGraphsSurface::handleArrayReset);
655 }
656}
657
658void QSurface3DSeriesPrivate::createItemLabel()
659{
660 Q_Q(QSurface3DSeries);
661 static const QString xTitleTag(QStringLiteral("@xTitle"));
662 static const QString yTitleTag(QStringLiteral("@yTitle"));
663 static const QString zTitleTag(QStringLiteral("@zTitle"));
664 static const QString xLabelTag(QStringLiteral("@xLabel"));
665 static const QString yLabelTag(QStringLiteral("@yLabel"));
666 static const QString zLabelTag(QStringLiteral("@zLabel"));
667 static const QString seriesNameTag(QStringLiteral("@seriesName"));
668
669 if (m_selectedPoint == QSurface3DSeries::invalidSelectionPosition()) {
670 m_itemLabel = QString(hiddenLabelTag);
671 return;
672 }
673
674 QValue3DAxis *axisX = static_cast<QValue3DAxis *>(m_graph->axisX());
675 QValue3DAxis *axisY = static_cast<QValue3DAxis *>(m_graph->axisY());
676 QValue3DAxis *axisZ = static_cast<QValue3DAxis *>(m_graph->axisZ());
677 QVector3D selectedPosition
678 = q->dataProxy()->itemAt(position: QPoint(m_selectedPoint.y(), m_selectedPoint.x())).position();
679
680 m_itemLabel = m_itemLabelFormat;
681
682 m_itemLabel.replace(before: xTitleTag, after: axisX->title());
683 m_itemLabel.replace(before: yTitleTag, after: axisY->title());
684 m_itemLabel.replace(before: zTitleTag, after: axisZ->title());
685
686 if (m_itemLabel.contains(s: xLabelTag)) {
687 QString valueLabelText = axisX->formatter()->stringForValue(value: qreal(selectedPosition.x()),
688 format: axisX->labelFormat());
689 m_itemLabel.replace(before: xLabelTag, after: valueLabelText);
690 }
691 if (m_itemLabel.contains(s: yLabelTag)) {
692 QString valueLabelText = axisY->formatter()->stringForValue(value: qreal(selectedPosition.y()),
693 format: axisY->labelFormat());
694 m_itemLabel.replace(before: yLabelTag, after: valueLabelText);
695 }
696 if (m_itemLabel.contains(s: zLabelTag)) {
697 QString valueLabelText = axisZ->formatter()->stringForValue(value: qreal(selectedPosition.z()),
698 format: axisZ->labelFormat());
699 m_itemLabel.replace(before: zLabelTag, after: valueLabelText);
700 }
701 m_itemLabel.replace(before: seriesNameTag, after: m_name);
702}
703
704void QSurface3DSeriesPrivate::setSelectedPoint(QPoint position)
705{
706 Q_Q(QSurface3DSeries);
707 if (position == m_selectedPoint) {
708 qCDebug(lcProperties3D) << __FUNCTION__
709 << "value is already set to:" << position;
710 return;
711 }
712 markItemLabelDirty();
713 m_selectedPoint = position;
714 emit q->selectedPointChanged(position: m_selectedPoint);
715}
716
717void QSurface3DSeriesPrivate::setShading(const QSurface3DSeries::Shading shading)
718{
719 m_shading = shading;
720 if (m_graph)
721 m_graph->markSeriesVisualsDirty();
722}
723
724void QSurface3DSeriesPrivate::setDrawMode(QSurface3DSeries::DrawFlags mode)
725{
726 if (mode.testFlag(flag: QSurface3DSeries::DrawFilledSurface)
727 && !mode.testFlag(flag: QSurface3DSeries::DrawSurface)) {
728 qCWarning(lcProperties3D, "%s drawSurface was not set and is needed for DrawFilledSurface."
729 " Setting it automatically", qUtf8Printable(QLatin1String(__FUNCTION__)));
730 mode |= QSurface3DSeries::DrawSurface;
731 }
732 if (mode.testFlag(flag: QSurface3DSeries::DrawWireframe)
733 || mode.testFlag(flag: QSurface3DSeries::DrawSurface)) {
734 m_drawMode = mode;
735 if (m_graph)
736 m_graph->markSeriesVisualsDirty();
737 } else {
738 qCWarning(lcProperties3D, "%s drawWireframe or DrawSurface must be set. Mode not changed.",
739 qUtf8Printable(QLatin1String(__FUNCTION__)));
740 }
741}
742
743void QSurface3DSeriesPrivate::setTexture(const QImage &texture)
744{
745 Q_Q(QSurface3DSeries);
746 m_texture = texture;
747 if (static_cast<QQuickGraphsSurface *>(m_graph))
748 static_cast<QQuickGraphsSurface *>(m_graph)->updateSurfaceTexture(series: q);
749}
750
751void QSurface3DSeriesPrivate::setWireframeColor(QColor color)
752{
753 m_wireframeColor = color;
754 if (m_graph)
755 m_graph->markSeriesVisualsDirty();
756}
757
758void QSurface3DSeriesPrivate::setDataArray(const QSurfaceDataArray &newDataArray)
759{
760 m_dataArray = newDataArray;
761}
762
763void QSurface3DSeriesPrivate::clearRow(qsizetype rowIndex)
764{
765 m_dataArray[rowIndex].clear();
766}
767
768void QSurface3DSeriesPrivate::clearArray()
769{
770 m_dataArray.clear();
771}
772
773QT_END_NAMESPACE
774

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