1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3//
4// W A R N I N G
5// -------------
6//
7// This file is not part of the QtGraphs API. It exists purely as an
8// implementation detail. This header file may change from version to
9// version without notice, or even be removed.
10//
11// We mean it.
12#ifndef QQUICKGRAPHSSCATTER_P_H
13#define QQUICKGRAPHSSCATTER_P_H
14
15#include "qquickgraphsitem_p.h"
16#include "qscatter3dseries.h"
17#include "qspline3dseries.h"
18#include "qvalue3daxis.h"
19#include <private/scatterinstancing_p.h>
20
21#include <private/qgraphsglobal_p.h>
22#include <private/qqmldelegatemodel_p.h>
23
24QT_BEGIN_NAMESPACE
25
26struct Scatter3DChangeBitField
27{
28 bool selectedItemChanged : 1;
29 bool itemChanged : 1;
30
31 Scatter3DChangeBitField()
32 : selectedItemChanged(true)
33 , itemChanged(false)
34 {}
35};
36
37class Q_GRAPHS_EXPORT QQuickGraphsScatter : public QQuickGraphsItem
38{
39 Q_OBJECT
40 Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
41 Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
42 Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
43 Q_PROPERTY(QScatter3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
44 Q_PROPERTY(QQmlListProperty<QScatter3DSeries> seriesList READ seriesList CONSTANT)
45 Q_CLASSINFO("DefaultProperty", "seriesList")
46
47 QML_NAMED_ELEMENT(Scatter3D)
48
49public:
50 explicit QQuickGraphsScatter(QQuickItem *parent = 0);
51 ~QQuickGraphsScatter() override;
52
53 struct ChangeItem
54 {
55 QScatter3DSeries *series;
56 qsizetype index;
57 };
58
59 void setAxisX(QValue3DAxis *axis);
60 QValue3DAxis *axisX() const;
61 void setAxisY(QValue3DAxis *axis);
62 QValue3DAxis *axisY() const;
63 void setAxisZ(QValue3DAxis *axis);
64 QValue3DAxis *axisZ() const;
65
66 QQmlListProperty<QScatter3DSeries> seriesList();
67 static void appendSeriesFunc(QQmlListProperty<QScatter3DSeries> *list, QScatter3DSeries *series);
68 static qsizetype countSeriesFunc(QQmlListProperty<QScatter3DSeries> *list);
69 static QScatter3DSeries *atSeriesFunc(QQmlListProperty<QScatter3DSeries> *list, qsizetype index);
70 static void clearSeriesFunc(QQmlListProperty<QScatter3DSeries> *list);
71 Q_INVOKABLE void clearSelection() override;
72 Q_INVOKABLE void addSeries(QScatter3DSeries *series);
73 Q_INVOKABLE void removeSeries(QScatter3DSeries *series);
74 QList<QScatter3DSeries *> scatterSeriesList();
75
76 QScatter3DSeries *selectedSeries() const;
77 void setSelectedItem(qsizetype index, QScatter3DSeries *series);
78
79 static constexpr qsizetype invalidSelectionIndex() { return -1; }
80 void setSelectionMode(QtGraphs3D::SelectionFlags mode) override;
81
82 bool hasSelectedItemChanged() const { return m_changeTracker.selectedItemChanged; }
83 void setSelectedItemChanged(bool changed) { m_changeTracker.selectedItemChanged = changed; }
84 bool hasItemChanged() const { return m_changeTracker.itemChanged; }
85 void setItemChanged(bool changed) { m_changeTracker.itemChanged = changed; }
86
87 void handleAxisAutoAdjustRangeChangedInOrientation(QAbstract3DAxis::AxisOrientation orientation,
88 bool autoAdjust) override;
89 void handleAxisRangeChangedBySender(QObject *sender) override;
90 void adjustAxisRanges() override;
91 bool hasChangedSeriesList() const { return !m_changedSeriesList.empty(); }
92 bool isSeriesVisualsDirty() const { return m_isSeriesVisualsDirty; }
93 void setSeriesVisualsDirty() { m_isSeriesVisualsDirty = true; }
94 bool isDataDirty() const { return m_isDataDirty; }
95
96 void handleLightingModeChanged() override;
97
98public Q_SLOTS:
99 void handleAxisXChanged(QAbstract3DAxis *axis) override;
100 void handleAxisYChanged(QAbstract3DAxis *axis) override;
101 void handleAxisZChanged(QAbstract3DAxis *axis) override;
102 void handleSeriesMeshChanged();
103 void handleMeshSmoothChanged(bool enable);
104
105 void handleArrayReset();
106 void handleItemsAdded(qsizetype startIndex, qsizetype count);
107 void handleItemsChanged(qsizetype startIndex, qsizetype count);
108 void handleItemsRemoved(qsizetype startIndex, qsizetype count);
109 void handleItemsInserted(qsizetype startIndex, qsizetype count);
110
111Q_SIGNALS:
112 void axisXChanged(QValue3DAxis *axis);
113 void axisYChanged(QValue3DAxis *axis);
114 void axisZChanged(QValue3DAxis *axis);
115 void selectedSeriesChanged(QScatter3DSeries *series);
116
117protected:
118 void calculateSceneScalingFactors() override;
119 void componentComplete() override;
120 bool doPicking(QPointF position) override;
121 bool doRayPicking(QVector3D origin, QVector3D direction) override;
122 void updateShadowQuality(QtGraphs3D::ShadowQuality quality) override;
123 void updateLightStrength() override;
124 void startRecordingRemovesAndInserts() override;
125
126private:
127 Scatter3DChangeBitField m_changeTracker;
128 QList<ChangeItem> m_changedItems;
129
130 struct InsertRemoveRecord
131 {
132 bool m_isInsert;
133 qsizetype m_startIndex;
134 qsizetype m_count;
135 QAbstract3DSeries *m_series;
136
137 InsertRemoveRecord()
138 : m_isInsert(false)
139 , m_startIndex(0)
140 , m_count(0)
141 , m_series(0)
142 {}
143
144 InsertRemoveRecord(bool isInsert, qsizetype startIndex, qsizetype count, QAbstract3DSeries *series)
145 : m_isInsert(isInsert)
146 , m_startIndex(startIndex)
147 , m_count(count)
148 , m_series(series)
149 {}
150 };
151
152 QList<InsertRemoveRecord> m_insertRemoveRecords;
153 bool m_recordInsertsAndRemoves;
154
155 struct SplineVertex
156 {
157 QVector3D position;
158 QVector2D uv;
159 };
160
161 struct ScatterModel
162 {
163 QList<QQuick3DModel *> dataItems;
164 QQuick3DTexture *seriesTexture;
165 QQuick3DTexture *highlightTexture;
166 QScatter3DSeries *series;
167
168 //Legacy optimiaztion material reference models
169 QQuick3DModel *baseRef = nullptr;
170 QQuick3DModel *selectionRef = nullptr;
171 // For instanced, i.e. Default optimization
172 ScatterInstancing *instancing = nullptr;
173 QQuick3DModel *instancingRootItem = nullptr;
174 QQuick3DModel *selectionIndicator = nullptr;
175
176 QQuick3DModel *splineModel = nullptr;
177 };
178
179 float m_maxItemSize = 0.0f;
180
181 const float m_defaultMinSize = 0.01f;
182 const float m_defaultMaxSize = 0.1f;
183 const float m_itemScaler = 3.0f;
184 float m_pointScale = 0;
185
186 const float m_indicatorScaleAdjustment = 1.1f;
187 const float m_rangeGradientYHelper = 0.5f;
188
189 bool m_polarGraph = false;
190
191 float m_selectedGradientPos = 0.0f;
192 qsizetype m_selectedItem = invalidSelectionIndex();
193 QScatter3DSeries *m_selectedItemSeries = nullptr; // Points to the series for which the bar is
194 // selected in single series selection cases.
195 QQuick3DModel *m_selected = nullptr;
196 QQuick3DModel *m_previousSelected = nullptr;
197
198 QList<ScatterModel *> m_scatterGraphs;
199
200 bool m_optimizationChanged = false;
201
202 void connectSeries(QScatter3DSeries *series);
203 void disconnectSeries(QScatter3DSeries *series);
204 qsizetype getItemIndex(QQuick3DModel *item);
205 QVector3D selectedItemPosition();
206
207 float m_dotSizedScale = 1.0f;
208
209 void updateMaterialReference(ScatterModel *model);
210 void updateInstancedMaterialProperties(ScatterModel *graphModel,
211 const bool isHighlight = false,
212 QQuick3DTexture *seriesTexture = nullptr,
213 QQuick3DTexture *highlightTexture = nullptr,
214 const bool transparency = false);
215 void updateItemMaterial(QQuick3DModel *item,
216 bool useGradient,
217 bool rangeGradient,
218 bool usePoint,
219 const QString &materialName);
220 void updateMaterialProperties(QQuick3DModel *item,
221 QQuick3DTexture *texture,
222 QColor color = Qt::white,
223 const bool transparency = false,
224 const bool shaded = true);
225 QQuick3DTexture *createTexture();
226 QQuick3DModel *createDataItemModel(QAbstract3DSeries::Mesh meshType);
227 QQuick3DNode *createSeriesRoot();
228 QQuick3DModel *createDataItem(QAbstract3DSeries *series);
229 void removeDataItems(ScatterModel *graphModel, QtGraphs3D::OptimizationHint optimizationHint);
230 void fixMeshFileName(QString &fileName, QAbstract3DSeries *series);
231 QString getMeshFileName(QAbstract3DSeries *series);
232
233 void deleteDataItem(QQuick3DModel *item);
234 void removeDataItems(QList<QQuick3DModel *> &items, qsizetype count);
235 void recreateDataItems();
236 void recreateDataItems(const QList<ScatterModel *> &);
237 void addPointsToScatterModel(ScatterModel *graphModel, qsizetype count);
238 qsizetype sizeDifference(qsizetype size1, qsizetype size2);
239 void handleSeriesChanged(QList<QAbstract3DSeries *> changedSeries);
240
241 QColor m_selectedSeriesColor;
242 bool selectedItemInSeries(const QScatter3DSeries *series);
243
244 bool isDotPositionInAxisRange(QVector3D dotPos);
245
246 QQmlComponent *createRepeaterDelegate(QAbstract3DSeries::Mesh MeshType);
247 float calculatePointScaleSize();
248 void updatePointScaleSize();
249 void calculatePolarXZ(const float posX, const float posZ, float &x, float &z) const;
250
251 void updateSpline(ScatterModel *model);
252 void createSplineModel(ScatterModel *model);
253 void handleSplineChanged();
254
255 void generatePointsForScatterModel(ScatterModel *series);
256 void updateScatterGraphItemPositions(ScatterModel *graphModel);
257 void updateScatterGraphItemVisuals(ScatterModel *graphModel);
258
259 QQuick3DModel *selected() const;
260 void setSelected(QQuick3DModel *newSelected);
261 void setSelected(QQuick3DModel *root, qsizetype index);
262 void clearSelectionModel();
263 void clearAllSelectionInstanced();
264
265 void optimizationChanged(QtGraphs3D::OptimizationHint toOptimization);
266
267 void updateGraph() override;
268 void synchData() override;
269 void handleOptimizationHintChange(QtGraphs3D::OptimizationHint hint) override;
270 void handleSeriesVisibilityChangedBySender(QObject *sender) override;
271
272 bool selectedItemInRange(const ScatterModel *graphModel);
273 ScatterModel *findGraphModel(QScatter3DSeries *series);
274
275private slots:
276 void cameraRotationChanged();
277
278 friend class Q3DScatterWidgetItem;
279 friend class QQuickGraphsScatterNode;
280};
281
282QT_END_NAMESPACE
283#endif // QQUICKGRAPHSSCATTER_P_H
284

source code of qtgraphs/src/graphs3d/qml/qquickgraphsscatter_p.h