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