1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "scatterdatamodifier.h" |
31 | #include <QtDataVisualization/qscatterdataproxy.h> |
32 | #include <QtDataVisualization/qvalue3daxis.h> |
33 | #include <QtDataVisualization/q3dscene.h> |
34 | #include <QtDataVisualization/q3dcamera.h> |
35 | #include <QtDataVisualization/qscatter3dseries.h> |
36 | #include <QtDataVisualization/q3dtheme.h> |
37 | #include <QtCore/qmath.h> |
38 | #include <QtCore/qrandom.h> |
39 | #include <QtWidgets/QComboBox> |
40 | |
41 | using namespace QtDataVisualization; |
42 | |
43 | //#define RANDOM_SCATTER // Uncomment this to switch to random scatter |
44 | |
45 | const int numberOfItems = 3600; |
46 | const float curveDivider = 3.0f; |
47 | const int lowerNumberOfItems = 900; |
48 | const float lowerCurveDivider = 0.75f; |
49 | |
50 | ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) |
51 | : m_graph(scatter), |
52 | m_fontSize(40.0f), |
53 | m_style(QAbstract3DSeries::MeshSphere), |
54 | m_smooth(true), |
55 | m_itemCount(lowerNumberOfItems), |
56 | m_curveDivider(lowerCurveDivider) |
57 | { |
58 | //! [0] |
59 | m_graph->activeTheme()->setType(Q3DTheme::ThemeEbony); |
60 | QFont font = m_graph->activeTheme()->font(); |
61 | font.setPointSize(m_fontSize); |
62 | m_graph->activeTheme()->setFont(font); |
63 | m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow); |
64 | m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); |
65 | //! [0] |
66 | |
67 | //! [2] |
68 | QScatterDataProxy *proxy = new QScatterDataProxy; |
69 | QScatter3DSeries *series = new QScatter3DSeries(proxy); |
70 | series->setItemLabelFormat(QStringLiteral("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel" )); |
71 | series->setMeshSmooth(m_smooth); |
72 | m_graph->addSeries(series); |
73 | //! [2] |
74 | |
75 | //! [3] |
76 | addData(); |
77 | //! [3] |
78 | } |
79 | |
80 | ScatterDataModifier::~ScatterDataModifier() |
81 | { |
82 | delete m_graph; |
83 | } |
84 | |
85 | void ScatterDataModifier::addData() |
86 | { |
87 | // Configure the axes according to the data |
88 | //! [4] |
89 | m_graph->axisX()->setTitle("X" ); |
90 | m_graph->axisY()->setTitle("Y" ); |
91 | m_graph->axisZ()->setTitle("Z" ); |
92 | //! [4] |
93 | |
94 | //! [5] |
95 | QScatterDataArray *dataArray = new QScatterDataArray; |
96 | dataArray->resize(asize: m_itemCount); |
97 | QScatterDataItem *ptrToDataArray = &dataArray->first(); |
98 | //! [5] |
99 | |
100 | #ifdef RANDOM_SCATTER |
101 | for (int i = 0; i < m_itemCount; i++) { |
102 | ptrToDataArray->setPosition(randVector()); |
103 | ptrToDataArray++; |
104 | } |
105 | #else |
106 | //! [6] |
107 | float limit = qSqrt(v: m_itemCount) / 2.0f; |
108 | for (float i = -limit; i < limit; i++) { |
109 | for (float j = -limit; j < limit; j++) { |
110 | ptrToDataArray->setPosition(QVector3D(i + 0.5f, |
111 | qCos(v: qDegreesToRadians(degrees: (i * j) / m_curveDivider)), |
112 | j + 0.5f)); |
113 | ptrToDataArray++; |
114 | } |
115 | } |
116 | //! [6] |
117 | #endif |
118 | |
119 | //! [7] |
120 | m_graph->seriesList().at(i: 0)->dataProxy()->resetArray(newArray: dataArray); |
121 | //! [7] |
122 | } |
123 | |
124 | //! [8] |
125 | void ScatterDataModifier::changeStyle(int style) |
126 | { |
127 | QComboBox *comboBox = qobject_cast<QComboBox *>(object: sender()); |
128 | if (comboBox) { |
129 | m_style = QAbstract3DSeries::Mesh(comboBox->itemData(index: style).toInt()); |
130 | if (m_graph->seriesList().size()) |
131 | m_graph->seriesList().at(i: 0)->setMesh(m_style); |
132 | } |
133 | } |
134 | |
135 | void ScatterDataModifier::setSmoothDots(int smooth) |
136 | { |
137 | m_smooth = bool(smooth); |
138 | QScatter3DSeries *series = m_graph->seriesList().at(i: 0); |
139 | series->setMeshSmooth(m_smooth); |
140 | } |
141 | |
142 | void ScatterDataModifier::changeTheme(int theme) |
143 | { |
144 | Q3DTheme *currentTheme = m_graph->activeTheme(); |
145 | currentTheme->setType(Q3DTheme::Theme(theme)); |
146 | emit backgroundEnabledChanged(enabled: currentTheme->isBackgroundEnabled()); |
147 | emit gridEnabledChanged(enabled: currentTheme->isGridEnabled()); |
148 | emit fontChanged(font: currentTheme->font()); |
149 | } |
150 | |
151 | void ScatterDataModifier::changePresetCamera() |
152 | { |
153 | static int preset = Q3DCamera::CameraPresetFrontLow; |
154 | |
155 | m_graph->scene()->activeCamera()->setCameraPreset((Q3DCamera::CameraPreset)preset); |
156 | |
157 | if (++preset > Q3DCamera::CameraPresetDirectlyBelow) |
158 | preset = Q3DCamera::CameraPresetFrontLow; |
159 | } |
160 | |
161 | void ScatterDataModifier::changeLabelStyle() |
162 | { |
163 | m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled()); |
164 | } |
165 | |
166 | void ScatterDataModifier::changeFont(const QFont &font) |
167 | { |
168 | QFont newFont = font; |
169 | newFont.setPointSizeF(m_fontSize); |
170 | m_graph->activeTheme()->setFont(newFont); |
171 | } |
172 | |
173 | void ScatterDataModifier::shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality sq) |
174 | { |
175 | int quality = int(sq); |
176 | emit shadowQualityChanged(quality); // connected to a checkbox in main.cpp |
177 | } |
178 | |
179 | void ScatterDataModifier::changeShadowQuality(int quality) |
180 | { |
181 | QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality); |
182 | m_graph->setShadowQuality(sq); |
183 | } |
184 | |
185 | void ScatterDataModifier::setBackgroundEnabled(int enabled) |
186 | { |
187 | m_graph->activeTheme()->setBackgroundEnabled((bool)enabled); |
188 | } |
189 | |
190 | void ScatterDataModifier::setGridEnabled(int enabled) |
191 | { |
192 | m_graph->activeTheme()->setGridEnabled((bool)enabled); |
193 | } |
194 | //! [8] |
195 | |
196 | void ScatterDataModifier::toggleItemCount() |
197 | { |
198 | if (m_itemCount == numberOfItems) { |
199 | m_itemCount = lowerNumberOfItems; |
200 | m_curveDivider = lowerCurveDivider; |
201 | } else { |
202 | m_itemCount = numberOfItems; |
203 | m_curveDivider = curveDivider; |
204 | } |
205 | m_graph->seriesList().at(i: 0)->dataProxy()->resetArray(newArray: 0); |
206 | addData(); |
207 | } |
208 | |
209 | QVector3D ScatterDataModifier::randVector() |
210 | { |
211 | return QVector3D( |
212 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 2.0f - |
213 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 2.0f, |
214 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 100.0f - |
215 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 100.0f, |
216 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 2.0f - |
217 | (float)(QRandomGenerator::global()->bounded(highest: 100)) / 2.0f); |
218 | } |
219 | |