| 1 | // Copyright (C) 2025 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
| 3 | |
| 4 | #include "qcustom3ditem.h" |
| 5 | #include "qquickgraphsnode_p.h" |
| 6 | #include <qtconfigmacros.h> |
| 7 | |
| 8 | QT_BEGIN_NAMESPACE |
| 9 | |
| 10 | /*! |
| 11 | * \qmltype GraphsNode |
| 12 | * \inherits Node |
| 13 | * \qmlabstract |
| 14 | * \inqmlmodule QtGraphs |
| 15 | * \ingroup graphs_qml_3D |
| 16 | * \brief Base type for 3D graphs. |
| 17 | * |
| 18 | * The uncreatable base type for all 3D graph nodes in Qt Graphs. |
| 19 | * |
| 20 | * \sa Bars3DNode, Scatter3DNode, Surface3DNode, {Qt Graphs C++ Classes for 3D} |
| 21 | */ |
| 22 | |
| 23 | /*! |
| 24 | * \qmlproperty Graphs3D.SelectionMode GraphsNode::selectionMode |
| 25 | * The active selection mode in the graph. |
| 26 | * One of the \l graphs3d.selectionflag enum values. |
| 27 | */ |
| 28 | |
| 29 | /*! |
| 30 | * \qmlproperty GraphsTheme GraphsNode::theme |
| 31 | * The active theme of the graph. |
| 32 | * |
| 33 | * \sa GraphsTheme |
| 34 | */ |
| 35 | |
| 36 | /*! |
| 37 | * \qmlproperty list<Custom3DItem> GraphsNode::customItemList |
| 38 | * |
| 39 | * The list of \l{Custom3DItem} items added to the graph. The graph takes |
| 40 | * ownership of the added items. |
| 41 | */ |
| 42 | |
| 43 | /*! |
| 44 | * \qmlproperty bool GraphsNode::polar |
| 45 | * |
| 46 | * If \c {true}, the horizontal axes are changed into polar axes. The x-axis |
| 47 | * becomes the angular axis and the z-axis becomes the radial axis. |
| 48 | * Polar mode is not available for bar graphs. |
| 49 | * |
| 50 | * Defaults to \c{false}. |
| 51 | * |
| 52 | * \sa radialLabelOffset |
| 53 | */ |
| 54 | |
| 55 | /*! |
| 56 | * \qmlproperty real GraphsNode::labelMargin |
| 57 | * |
| 58 | * This property specifies the margin for the placement of the axis labels. |
| 59 | * |
| 60 | * Negative values place the labels inside the plot-area while positive values |
| 61 | * place them outside the plot-area. Label automatic rotation is disabled when |
| 62 | * the value is negative. Defaults to \c 0.1 |
| 63 | * |
| 64 | * \sa QAbstract3DAxis::labelAutoAngle |
| 65 | * |
| 66 | */ |
| 67 | |
| 68 | /*! |
| 69 | * \qmlproperty real GraphsNode::radialLabelOffset |
| 70 | * |
| 71 | * This property specifies the normalized horizontal offset for the axis labels |
| 72 | * of the radial polar axis. The value \c 0.0 indicates that the labels should |
| 73 | * be drawn next to the 0-angle angular axis grid line. The value \c 1.0 |
| 74 | * indicates that the labels are drawn in their usual place at the edge of the |
| 75 | * graph background. This property is ignored if the polar property value is |
| 76 | * \c{false}. Defaults to \c 1.0. |
| 77 | * |
| 78 | * \sa polar |
| 79 | */ |
| 80 | |
| 81 | /*! |
| 82 | * \qmlmethod void GraphsNode::clearSelection() |
| 83 | * Clears selection from all attached series. |
| 84 | */ |
| 85 | |
| 86 | /*! |
| 87 | * \qmlmethod bool GraphsNode::hasSeries(Abstract3DSeries series) |
| 88 | * Returns whether the \a series has already been added to the graph. |
| 89 | */ |
| 90 | |
| 91 | /*! |
| 92 | * \qmlmethod qsizetype GraphsNode::addCustomItem(Custom3DItem item) |
| 93 | * |
| 94 | * Adds a Custom3DItem \a item to the graph. Graph takes ownership of the added |
| 95 | * item. |
| 96 | * |
| 97 | * \return index to the added item if add was successful, -1 if trying to add a |
| 98 | * null item, and index of the item if trying to add an already added item. |
| 99 | * |
| 100 | * \sa removeCustomItems(), removeCustomItem(), removeCustomItemAt() |
| 101 | */ |
| 102 | |
| 103 | /*! |
| 104 | * \qmlmethod void GraphsNode::removeCustomItems() |
| 105 | * |
| 106 | * Removes all custom items. Deletes the resources allocated to them. |
| 107 | */ |
| 108 | |
| 109 | /*! |
| 110 | * \qmlmethod void GraphsNode::removeCustomItem(Custom3DItem item) |
| 111 | * |
| 112 | * Removes the custom \a {item}. Deletes the resources allocated to it. |
| 113 | */ |
| 114 | |
| 115 | /*! |
| 116 | * \qmlmethod void GraphsNode::removeCustomItemAt(vector3d position) |
| 117 | * |
| 118 | * Removes all custom items at \a {position}. Deletes the resources allocated to them. |
| 119 | */ |
| 120 | |
| 121 | /*! |
| 122 | * \qmlmethod void GraphsNode::releaseCustomItem(Custom3DItem item) |
| 123 | * |
| 124 | * Gets ownership of \a item back and removes the \a item from the graph. |
| 125 | * |
| 126 | * \note If the same item is added back to the graph, the texture file needs to |
| 127 | * be re-set. |
| 128 | * |
| 129 | * \sa Custom3DItem::textureFile |
| 130 | */ |
| 131 | |
| 132 | /*! |
| 133 | * \qmlmethod void GraphsNode::doPicking(QPoint point) |
| 134 | * |
| 135 | * Performs picking using view coordinates from \a point |
| 136 | * on the elements of the graph, selecting the first item hit. |
| 137 | * Default input handling performs this upon receiving the onTapped event. |
| 138 | * |
| 139 | * \sa selectedElement |
| 140 | */ |
| 141 | |
| 142 | /*! |
| 143 | * \qmlmethod void GraphsNode::doRayPicking(QVector3D origin, QVector3D direction) |
| 144 | * |
| 145 | * Performs picking starting from \a origin and in \a direction |
| 146 | * on the elements of the graph, selecting the first item hit. |
| 147 | * |
| 148 | * \sa selectedElement |
| 149 | */ |
| 150 | |
| 151 | /*! |
| 152 | * \qmlmethod int GraphsNode::selectedLabelIndex() |
| 153 | * |
| 154 | * Can be used to query the index of the selected label after receiving |
| 155 | * \c selectedElementChanged signal with any label type. Selection is valid |
| 156 | * until the next \c selectedElementChanged signal. |
| 157 | * |
| 158 | * \return index of the selected label, or -1. |
| 159 | * |
| 160 | * \sa selectedElement |
| 161 | */ |
| 162 | |
| 163 | /*! |
| 164 | * \qmlmethod Abstract3DAxis GraphsNode::selectedAxis() |
| 165 | * |
| 166 | * Can be used to get the selected axis after receiving \c selectedElementChanged |
| 167 | * signal with any label type. Selection is valid until the next |
| 168 | * \c selectedElementChanged signal. |
| 169 | * |
| 170 | * \return the selected axis, or null. |
| 171 | * |
| 172 | * \sa selectedElement |
| 173 | */ |
| 174 | |
| 175 | /*! |
| 176 | * \qmlmethod qsizetype GraphsNode::selectedCustomItemIndex() |
| 177 | * |
| 178 | * Can be used to query the index of the selected custom item after receiving |
| 179 | * \c selectedElementChanged signal with |
| 180 | * \l{QtGraphs3D::ElementType::CustomItem}{ElementType.CustomItem} type. |
| 181 | * Selection is valid until the next \c selectedElementChanged signal. |
| 182 | * |
| 183 | * \return index of the selected custom item, or -1. |
| 184 | * |
| 185 | * \sa selectedElement |
| 186 | */ |
| 187 | |
| 188 | /*! |
| 189 | * \qmlmethod Custom3DItem GraphsNode::selectedCustomItem() |
| 190 | * |
| 191 | * Can be used to get the selected custom item after receiving |
| 192 | * \c selectedElementChanged signal with |
| 193 | * \l{QtGraphs3D::ElementType::CustomItem}{ElementType.CustomItem} type. |
| 194 | * Ownership of the item remains with the graph. |
| 195 | * Selection is valid until the next \c selectedElementChanged signal. |
| 196 | * |
| 197 | * \return the selected custom item, or null. |
| 198 | * |
| 199 | * \sa selectedElement |
| 200 | */ |
| 201 | |
| 202 | /*! |
| 203 | * \qmlproperty Graphs3D.ElementType GraphsNode::selectedElement |
| 204 | * \readonly |
| 205 | * |
| 206 | * The element selected in the graph. |
| 207 | * |
| 208 | * This property can be used to query the selected element type. |
| 209 | * The type is valid until a new selection is made in the graph and the |
| 210 | * \c selectedElementChanged signal is emitted. |
| 211 | * |
| 212 | * The signal can be used for example for implementing customized input |
| 213 | * handling, as demonstrated by the \l {Axis Handling} example. |
| 214 | * |
| 215 | * \sa selectedLabelIndex(), selectedAxis(), selectedCustomItemIndex(), |
| 216 | * selectedCustomItem(), Bars3DNode::selectedSeries, Scatter3DNode::selectedSeries, |
| 217 | * Scene3D::selectionQueryPosition, Graphs3D.ElementType |
| 218 | */ |
| 219 | |
| 220 | /*! |
| 221 | * \qmlproperty real GraphsNode::aspectRatio |
| 222 | * |
| 223 | * The ratio of the graph scaling between the longest axis on the horizontal |
| 224 | * plane and the y-axis. Defaults to \c{2.0}. |
| 225 | * |
| 226 | * \note Has no effect on Bars3D. |
| 227 | * |
| 228 | * \sa horizontalAspectRatio |
| 229 | */ |
| 230 | |
| 231 | /*! |
| 232 | * \qmlproperty real GraphsNode::horizontalAspectRatio |
| 233 | * |
| 234 | * The ratio of the graph scaling between the x-axis and z-axis. |
| 235 | * The value of \c 0.0 indicates automatic scaling according to axis ranges. |
| 236 | * Defaults to \c{0.0}. |
| 237 | * |
| 238 | * \note Has no effect on Bars3DNode, which handles scaling on the horizontal plane |
| 239 | * via the \l{Bars3DNode::barThickness}{barThickness} and |
| 240 | * \l{Bars3DNode::barSpacing}{barSpacing} properties. Polar graphs also ignore this |
| 241 | * property. |
| 242 | * |
| 243 | * \sa aspectRatio, polar, Bars3DNode::barThickness, Bars3DNode::barSpacing |
| 244 | */ |
| 245 | |
| 246 | /*! |
| 247 | * \qmlproperty Graphs3D.OptimizationHint GraphsNode::optimizationHint |
| 248 | * |
| 249 | * \brief Specifies whether the default or legacy mode is used for rendering optimization. |
| 250 | * |
| 251 | * The default mode uses instanced rendering, and provides the full feature set |
| 252 | * at the best level of performance on most systems. The static mode optimizes |
| 253 | * graph rendering and is ideal for large non-changing data sets. It is slower |
| 254 | * with dynamic data changes and item rotations. Selection is not optimized, so |
| 255 | * using the static mode with massive data sets is not advisable. Legacy mode |
| 256 | * renders all items in th graph individually, without instancing. It should be |
| 257 | * used only if default mode does not work, that is the same as if the target |
| 258 | * system does not support instancing. Defaults to |
| 259 | * \l{QtGraphs3D::OptimizationHint::Default}{Default}. |
| 260 | * |
| 261 | * \note On some environments, large graphs using static optimization may not |
| 262 | * render, because all of the items are rendered using a single draw call, and |
| 263 | * different graphics drivers support different maximum vertice counts per call. |
| 264 | * This is mostly an issue on 32bit and OpenGL ES2 platforms. To work around |
| 265 | * this issue, choose an item mesh with a low vertex count or use the point mesh. |
| 266 | * |
| 267 | * \sa Abstract3DSeries::mesh, Graphs3D.OptimizationHint |
| 268 | */ |
| 269 | |
| 270 | /*! |
| 271 | * \qmlproperty locale GraphsNode::locale |
| 272 | * |
| 273 | * Sets the locale used for formatting various numeric labels. |
| 274 | * Defaults to the \c{"C"} locale. |
| 275 | * |
| 276 | * \sa Value3DAxis::labelFormat |
| 277 | */ |
| 278 | |
| 279 | /*! |
| 280 | * \qmlproperty vector3d GraphsNode::queriedGraphPosition |
| 281 | * \readonly |
| 282 | * |
| 283 | * This read-only property contains the latest graph position values along each |
| 284 | * axis queried using Scene3D::graphPositionQuery. The values are normalized to |
| 285 | * range \c{[-1, 1]}. If the queried position was outside the graph bounds, the |
| 286 | * values will not reflect the real position, but will instead be some undefined |
| 287 | * position outside the range \c{[-1, 1]}. The value will be undefined until a |
| 288 | * query is made. |
| 289 | * |
| 290 | * There is no single correct 3D coordinate to match a particular screen |
| 291 | * position, so to be consistent, the queries are always done against the inner |
| 292 | * sides of an invisible box surrounding the graph. |
| 293 | * |
| 294 | * \note Bar graphs only allow querying graph position at the graph floor level, |
| 295 | * so the y-value is always zero for bar graphs and valid queries can be only |
| 296 | * made at screen positions that contain the floor of the graph. |
| 297 | * |
| 298 | * \sa Scene3D::graphPositionQuery |
| 299 | */ |
| 300 | |
| 301 | /*! |
| 302 | * \qmlproperty real GraphsNode::margin |
| 303 | * |
| 304 | * The absolute value used for the space left between the edge of the |
| 305 | * plottable graph area and the edge of the graph background. |
| 306 | * |
| 307 | * If the margin value is negative, the margins are determined automatically and |
| 308 | * can vary according to the size of the items in the series and the type of the |
| 309 | * graph. The value is interpreted as a fraction of the y-axis range if the |
| 310 | * graph aspect ratios have not been changed from the default values. |
| 311 | * Defaults to \c{-1.0}. |
| 312 | * |
| 313 | * \note Setting a smaller margin for a scatter graph than the automatically |
| 314 | * determined margin can cause the scatter items at the edges of the graph to |
| 315 | * overlap with the graph background. |
| 316 | * |
| 317 | * \note On scatter and surface graphs, if the margin is small in comparison to |
| 318 | * the axis label size, the positions of the edge labels of the axes are |
| 319 | * adjusted to avoid overlap with the edge labels of the neighboring axes. |
| 320 | */ |
| 321 | |
| 322 | /*! |
| 323 | * \qmlproperty Graphs3D.GridLineType GraphsNode::gridLineType |
| 324 | * |
| 325 | * Defines whether the grid lines type is \c Graphs3D.GridLineType.Shader or |
| 326 | * \c Graphs3D.GridLineType.Geometry. |
| 327 | * |
| 328 | * This value affects all grid lines. |
| 329 | * |
| 330 | * \sa Graphs3D.GridLineType |
| 331 | */ |
| 332 | |
| 333 | QQuickGraphsNode::QQuickGraphsNode(QQuick3DNode *parent) |
| 334 | : QQuick3DNode(parent) |
| 335 | , m_selectionMode(QtGraphs3D::SelectionFlag::Item) |
| 336 | , m_aspectRatio(2.0) |
| 337 | , m_optimizationHint(QtGraphs3D::OptimizationHint::Default) |
| 338 | , m_polar(false) |
| 339 | , m_labelMargin(.1f) |
| 340 | , m_radialLabelOffset(1.0f) |
| 341 | , m_horizontalAspectRatio(0.0) |
| 342 | , m_locale(QLocale::c()) |
| 343 | , m_margin(-1.0) |
| 344 | , m_gridLineType(QtGraphs3D::GridLineType::Geometry) |
| 345 | { |
| 346 | QGraphsTheme *theme = new QGraphsTheme(this); |
| 347 | setTheme(theme); |
| 348 | } |
| 349 | |
| 350 | QQuickGraphsNode::~QQuickGraphsNode() {} |
| 351 | |
| 352 | void QQuickGraphsNode::componentComplete() |
| 353 | { |
| 354 | QQuick3DNode::componentComplete(); |
| 355 | |
| 356 | //initialize properties |
| 357 | m_graph->setTheme(m_theme); |
| 358 | m_graph->setAspectRatio(m_aspectRatio); |
| 359 | m_graph->setOptimizationHint(m_optimizationHint); |
| 360 | m_graph->setPolar(m_polar); |
| 361 | m_graph->setLabelMargin(m_labelMargin); |
| 362 | m_graph->setRadialLabelOffset(m_radialLabelOffset); |
| 363 | m_graph->setHorizontalAspectRatio(m_horizontalAspectRatio); |
| 364 | m_graph->setLocale(m_locale); |
| 365 | m_graph->setMargin(m_margin); |
| 366 | m_graph->setGridLineType(m_gridLineType); |
| 367 | |
| 368 | for (auto item : std::as_const(t&: m_customItemList)) |
| 369 | m_graph->addCustomItem(item); |
| 370 | |
| 371 | //connect signals |
| 372 | connect(sender: m_graph.get(), |
| 373 | signal: &QQuickGraphsItem::selectionModeChanged, |
| 374 | context: this, |
| 375 | slot: &QQuickGraphsNode::selectionModeChanged); |
| 376 | connect(sender: m_graph.get(), signal: &QQuickGraphsItem::themeChanged, context: this, slot: &QQuickGraphsNode::themeChanged); |
| 377 | connect(sender: m_graph.get(), |
| 378 | signal: &QQuickGraphsItem::aspectRatioChanged, |
| 379 | context: this, |
| 380 | slot: &QQuickGraphsNode::aspectRatioChanged); |
| 381 | connect(sender: m_graph.get(), |
| 382 | signal: &QQuickGraphsItem::optimizationHintChanged, |
| 383 | context: this, |
| 384 | slot: &QQuickGraphsNode::optimizationHintChanged); |
| 385 | connect(sender: m_graph.get(), signal: &QQuickGraphsItem::polarChanged, context: this, slot: &QQuickGraphsNode::polarChanged); |
| 386 | connect(sender: m_graph.get(), |
| 387 | signal: &QQuickGraphsItem::labelMarginChanged, |
| 388 | context: this, |
| 389 | slot: &QQuickGraphsNode::labelMarginChanged); |
| 390 | connect(sender: m_graph.get(), |
| 391 | signal: &QQuickGraphsItem::radialLabelOffsetChanged, |
| 392 | context: this, |
| 393 | slot: &QQuickGraphsNode::radialLabelOffsetChanged); |
| 394 | connect(sender: m_graph.get(), |
| 395 | signal: &QQuickGraphsItem::horizontalAspectRatioChanged, |
| 396 | context: this, |
| 397 | slot: &QQuickGraphsNode::horizontalAspectRatioChanged); |
| 398 | connect(sender: m_graph.get(), signal: &QQuickGraphsItem::localeChanged, context: this, slot: &QQuickGraphsNode::localeChanged); |
| 399 | connect(sender: m_graph.get(), |
| 400 | signal: &QQuickGraphsItem::queriedGraphPositionChanged, |
| 401 | context: this, |
| 402 | slot: &QQuickGraphsNode::queriedGraphPositionChanged); |
| 403 | connect(sender: m_graph.get(), signal: &QQuickGraphsItem::marginChanged, context: this, slot: &QQuickGraphsNode::marginChanged); |
| 404 | connect(sender: m_graph.get(), |
| 405 | signal: &QQuickGraphsItem::gridLineTypeChanged, |
| 406 | context: this, |
| 407 | slot: &QQuickGraphsNode::gridLineTypeChanged); |
| 408 | } |
| 409 | |
| 410 | void QQuickGraphsNode::setGraphParent() |
| 411 | { |
| 412 | if (m_graph) |
| 413 | m_graph->setParentNode(this); |
| 414 | } |
| 415 | |
| 416 | void QQuickGraphsNode::setSelectionMode(QtGraphs3D::SelectionFlags selectionMode) |
| 417 | { |
| 418 | if (m_selectionMode == selectionMode) |
| 419 | return; |
| 420 | |
| 421 | m_selectionMode = selectionMode; |
| 422 | if (m_graph) |
| 423 | m_graph->setSelectionMode(m_selectionMode); |
| 424 | } |
| 425 | |
| 426 | QtGraphs3D::SelectionFlags QQuickGraphsNode::selectionMode() const |
| 427 | { |
| 428 | if (m_graph) |
| 429 | return m_graph->selectionMode(); |
| 430 | else |
| 431 | return m_selectionMode; |
| 432 | } |
| 433 | |
| 434 | void QQuickGraphsNode::setTheme(QGraphsTheme *theme) |
| 435 | { |
| 436 | if (m_theme == theme) |
| 437 | return; |
| 438 | |
| 439 | m_theme = theme; |
| 440 | if (m_graph) |
| 441 | m_graph->setTheme(m_theme); |
| 442 | } |
| 443 | |
| 444 | QGraphsTheme *QQuickGraphsNode::theme() const |
| 445 | { |
| 446 | if (m_graph) |
| 447 | return m_graph->theme(); |
| 448 | else |
| 449 | return m_theme; |
| 450 | } |
| 451 | |
| 452 | QQmlListProperty<QCustom3DItem> QQuickGraphsNode::customItemList() const |
| 453 | { |
| 454 | if (m_graph) |
| 455 | return m_graph->customItemList(); |
| 456 | else |
| 457 | return QQmlListProperty<QCustom3DItem>(); |
| 458 | } |
| 459 | |
| 460 | |
| 461 | QtGraphs3D::ElementType QQuickGraphsNode::selectedElement() const |
| 462 | { |
| 463 | if (m_graph) |
| 464 | return m_graph->selectedElement(); |
| 465 | else |
| 466 | return QtGraphs3D::ElementType::None; |
| 467 | } |
| 468 | |
| 469 | void QQuickGraphsNode::setAspectRatio(qreal aspectRatio) |
| 470 | { |
| 471 | if (m_aspectRatio == aspectRatio) |
| 472 | return; |
| 473 | |
| 474 | m_aspectRatio = aspectRatio; |
| 475 | if (m_graph) |
| 476 | m_graph->setAspectRatio(aspectRatio); |
| 477 | } |
| 478 | |
| 479 | qreal QQuickGraphsNode::aspectRatio() const |
| 480 | { |
| 481 | if (m_graph) |
| 482 | return m_graph->aspectRatio(); |
| 483 | else |
| 484 | return m_aspectRatio; |
| 485 | } |
| 486 | |
| 487 | void QQuickGraphsNode::setOptimizationHint(QtGraphs3D::OptimizationHint optimizationHint) |
| 488 | { |
| 489 | if (m_optimizationHint == optimizationHint) |
| 490 | return; |
| 491 | |
| 492 | m_optimizationHint = optimizationHint; |
| 493 | if (m_graph) |
| 494 | m_graph->setOptimizationHint(optimizationHint); |
| 495 | } |
| 496 | QtGraphs3D::OptimizationHint QQuickGraphsNode::optimizationHint() const |
| 497 | { |
| 498 | if (m_graph) |
| 499 | return m_graph->optimizationHint(); |
| 500 | else |
| 501 | return m_optimizationHint; |
| 502 | } |
| 503 | void QQuickGraphsNode::setPolar(bool enabled) |
| 504 | { |
| 505 | if (m_polar == enabled) |
| 506 | return; |
| 507 | |
| 508 | m_polar = enabled; |
| 509 | if (m_graph) |
| 510 | m_graph->setPolar(enabled); |
| 511 | } |
| 512 | |
| 513 | bool QQuickGraphsNode::isPolar() const |
| 514 | { |
| 515 | if (m_graph) |
| 516 | return m_graph->isPolar(); |
| 517 | else |
| 518 | return m_polar; |
| 519 | } |
| 520 | |
| 521 | void QQuickGraphsNode::setLabelMargin(float labelMargin) |
| 522 | { |
| 523 | if (m_labelMargin == labelMargin) |
| 524 | return; |
| 525 | |
| 526 | m_labelMargin = labelMargin; |
| 527 | if (m_graph) |
| 528 | m_graph->setLabelMargin(labelMargin); |
| 529 | } |
| 530 | |
| 531 | float QQuickGraphsNode::labelMargin() const |
| 532 | { |
| 533 | if (m_graph) |
| 534 | return m_graph->labelMargin(); |
| 535 | else |
| 536 | return m_labelMargin; |
| 537 | } |
| 538 | |
| 539 | void QQuickGraphsNode::setRadialLabelOffset(float radialLabelOffset) |
| 540 | { |
| 541 | if (m_radialLabelOffset == radialLabelOffset) |
| 542 | return; |
| 543 | |
| 544 | m_radialLabelOffset = radialLabelOffset; |
| 545 | if (m_graph) |
| 546 | m_graph->setRadialLabelOffset(radialLabelOffset); |
| 547 | } |
| 548 | |
| 549 | float QQuickGraphsNode::radialLabelOffset() const |
| 550 | { |
| 551 | if (m_graph) |
| 552 | return m_graph->radialLabelOffset(); |
| 553 | else |
| 554 | return m_radialLabelOffset; |
| 555 | } |
| 556 | |
| 557 | void QQuickGraphsNode::setHorizontalAspectRatio(qreal horizontalAspectRatio) |
| 558 | { |
| 559 | if (m_horizontalAspectRatio == horizontalAspectRatio) |
| 560 | return; |
| 561 | |
| 562 | m_horizontalAspectRatio = horizontalAspectRatio; |
| 563 | if (m_graph) |
| 564 | m_graph->setHorizontalAspectRatio(horizontalAspectRatio); |
| 565 | } |
| 566 | |
| 567 | qreal QQuickGraphsNode::horizontalAspectRatio() const |
| 568 | { |
| 569 | if (m_graph) |
| 570 | return m_graph->horizontalAspectRatio(); |
| 571 | else |
| 572 | return m_horizontalAspectRatio; |
| 573 | } |
| 574 | |
| 575 | void QQuickGraphsNode::setLocale(QLocale locale) |
| 576 | { |
| 577 | if (m_locale == locale) |
| 578 | return; |
| 579 | |
| 580 | m_locale = locale; |
| 581 | if (m_graph) |
| 582 | m_graph->setLocale(locale); |
| 583 | } |
| 584 | |
| 585 | QLocale QQuickGraphsNode::locale() const |
| 586 | { |
| 587 | if (m_graph) |
| 588 | return m_graph->locale(); |
| 589 | else |
| 590 | return m_locale; |
| 591 | } |
| 592 | |
| 593 | QVector3D QQuickGraphsNode::queriedGraphPosition() const |
| 594 | { |
| 595 | if (m_graph) |
| 596 | return m_graph->queriedGraphPosition(); |
| 597 | else |
| 598 | return QVector3D(); |
| 599 | } |
| 600 | |
| 601 | qreal QQuickGraphsNode::margin() const |
| 602 | { |
| 603 | if (m_graph) |
| 604 | return m_graph->margin(); |
| 605 | else |
| 606 | return m_margin; |
| 607 | } |
| 608 | |
| 609 | void QQuickGraphsNode::setMargin(qreal margin) |
| 610 | { |
| 611 | if (m_margin == margin) |
| 612 | return; |
| 613 | |
| 614 | m_margin = margin; |
| 615 | if (m_graph) |
| 616 | m_graph->setMargin(margin); |
| 617 | } |
| 618 | |
| 619 | QtGraphs3D::GridLineType QQuickGraphsNode::gridLineType() const |
| 620 | { |
| 621 | if (m_graph) |
| 622 | return m_graph->gridLineType(); |
| 623 | else |
| 624 | return m_gridLineType; |
| 625 | } |
| 626 | void QQuickGraphsNode::setGridLineType(const QtGraphs3D::GridLineType &gridLineType) |
| 627 | { |
| 628 | if (m_gridLineType == gridLineType) |
| 629 | return; |
| 630 | |
| 631 | m_gridLineType = gridLineType; |
| 632 | if (m_graph) |
| 633 | m_graph->setGridLineType(gridLineType); |
| 634 | } |
| 635 | |
| 636 | bool QQuickGraphsNode::hasSeries(QAbstract3DSeries *series) |
| 637 | { |
| 638 | if (m_graph) |
| 639 | return m_graph->hasSeries(series); |
| 640 | else |
| 641 | return m_seriesList.contains(t: series); |
| 642 | } |
| 643 | void QQuickGraphsNode::addSeriesInternal(QAbstract3DSeries *series) |
| 644 | { |
| 645 | insertSeries(index: m_seriesList.size(), series); |
| 646 | } |
| 647 | |
| 648 | void QQuickGraphsNode::insertSeries(qsizetype index, QAbstract3DSeries *series) |
| 649 | { |
| 650 | if (series) { |
| 651 | if (m_seriesList.contains(t: series)) { |
| 652 | qsizetype oldIndex = m_seriesList.indexOf(t: series); |
| 653 | if (index != oldIndex) { |
| 654 | m_seriesList.removeOne(t: series); |
| 655 | if (oldIndex < index) |
| 656 | index--; |
| 657 | m_seriesList.insert(i: index, t: series); |
| 658 | } |
| 659 | } else { |
| 660 | m_seriesList.insert(i: index, t: series); |
| 661 | } |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | void QQuickGraphsNode::removeSeriesInternal(QAbstract3DSeries *series) |
| 666 | { |
| 667 | if (series) |
| 668 | m_seriesList.removeAll(t: series); |
| 669 | } |
| 670 | |
| 671 | QList<QAbstract3DSeries *> QQuickGraphsNode::seriesList() |
| 672 | { |
| 673 | return m_seriesList; |
| 674 | } |
| 675 | |
| 676 | qsizetype QQuickGraphsNode::addCustomItem(QCustom3DItem *item) |
| 677 | { |
| 678 | if (m_graph) |
| 679 | m_graph->addCustomItem(item); |
| 680 | |
| 681 | m_customItemList.append(t: item); |
| 682 | return m_customItemList.size() - 1; |
| 683 | } |
| 684 | |
| 685 | void QQuickGraphsNode::removeCustomItems() |
| 686 | { |
| 687 | if (m_graph) |
| 688 | m_graph->removeCustomItems(); |
| 689 | |
| 690 | m_customItemList.clear(); |
| 691 | } |
| 692 | |
| 693 | void QQuickGraphsNode::removeCustomItem(QCustom3DItem *item) |
| 694 | { |
| 695 | if (m_graph) |
| 696 | m_graph->deleteCustomItem(item); |
| 697 | |
| 698 | m_customItemList.removeOne(t: item); |
| 699 | } |
| 700 | |
| 701 | void QQuickGraphsNode::removeCustomItemAt(QVector3D position) |
| 702 | { |
| 703 | if (m_graph) |
| 704 | m_graph->removeCustomItemAt(position); |
| 705 | |
| 706 | for (QCustom3DItem *item : std::as_const(t&: m_customItemList)) { |
| 707 | if (item->position() == position) |
| 708 | m_customItemList.removeOne(t: item); |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | void QQuickGraphsNode::releaseCustomItem(QCustom3DItem *item) |
| 713 | { |
| 714 | if (m_graph) |
| 715 | m_graph->releaseCustomItem(item); |
| 716 | |
| 717 | m_customItemList.removeOne(t: item); |
| 718 | } |
| 719 | |
| 720 | int QQuickGraphsNode::selectedLabelIndex() const |
| 721 | { |
| 722 | if (m_graph) |
| 723 | return selectedLabelIndex(); |
| 724 | else |
| 725 | return -1; |
| 726 | } |
| 727 | |
| 728 | QAbstract3DAxis *QQuickGraphsNode::selectedAxis() const |
| 729 | { |
| 730 | if (m_graph) |
| 731 | return m_graph->selectedAxis(); |
| 732 | return nullptr; |
| 733 | } |
| 734 | |
| 735 | qsizetype QQuickGraphsNode::selectedCustomItemIndex() const |
| 736 | { |
| 737 | if (m_graph) |
| 738 | return m_graph->selectedCustomItemIndex(); |
| 739 | else |
| 740 | return -1; |
| 741 | } |
| 742 | |
| 743 | QCustom3DItem *QQuickGraphsNode::selectedCustomItem() const |
| 744 | { |
| 745 | if (m_graph) |
| 746 | return m_graph->selectedCustomItem(); |
| 747 | else |
| 748 | return nullptr; |
| 749 | } |
| 750 | |
| 751 | QT_END_NAMESPACE |
| 752 | |