##// END OF EJS Templates
Implemented MultiComponent TS initial plot auto-scale...
jeandet -
r1436:0e6970dac555
parent child
Show More
@@ -1,527 +1,524
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/ScalarTimeSerie.h>
4 #include <Data/ScalarTimeSerie.h>
5 #include <Data/SpectrogramTimeSerie.h>
5 #include <Data/SpectrogramTimeSerie.h>
6 #include <Data/VectorTimeSerie.h>
6 #include <Data/VectorTimeSerie.h>
7
7
8 #include <Variable/Variable2.h>
8 #include <Variable/Variable2.h>
9
9
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
11
11
12 namespace
12 namespace
13 {
13 {
14
14
15 class SqpDataContainer : public QCPGraphDataContainer
15 class SqpDataContainer : public QCPGraphDataContainer
16 {
16 {
17 public:
17 public:
18 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
18 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
19 };
19 };
20
20
21 /**
21 /**
22 * Struct used to create plottables, depending on the type of the data series from which to create
22 * Struct used to create plottables, depending on the type of the data series from which to create
23 * them
23 * them
24 * @tparam T the data series' type
24 * @tparam T the data series' type
25 * @remarks Default implementation can't create plottables
25 * @remarks Default implementation can't create plottables
26 */
26 */
27 template <typename T, typename Enabled = void>
27 template <typename T, typename Enabled = void>
28 struct PlottablesCreator
28 struct PlottablesCreator
29 {
29 {
30 static PlottablesMap createPlottables(QCustomPlot&, const std::shared_ptr<T>& dataSeries)
30 static PlottablesMap createPlottables(QCustomPlot&, const std::shared_ptr<T>& dataSeries)
31 {
31 {
32 return {};
32 return {};
33 }
33 }
34 };
34 };
35
35
36 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
36 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
37 {
37 {
38 PlottablesMap result {};
38 PlottablesMap result {};
39
39
40 // Creates {nbGraphs} QCPGraph to add to the plot
40 // Creates {nbGraphs} QCPGraph to add to the plot
41 for (auto i = 0; i < nbGraphs; ++i)
41 for (auto i = 0; i < nbGraphs; ++i)
42 {
42 {
43 auto graph = plot.addGraph();
43 auto graph = plot.addGraph();
44 result.insert({ i, graph });
44 result.insert({ i, graph });
45 }
45 }
46
46
47 plot.replot();
47 plot.replot();
48
48
49 return result;
49 return result;
50 }
50 }
51
51
52 /**
52 /**
53 * Specialization of PlottablesCreator for scalars
53 * Specialization of PlottablesCreator for scalars
54 * @sa ScalarSeries
54 * @sa ScalarSeries
55 */
55 */
56 template <typename T>
56 template <typename T>
57 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
57 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
58 {
58 {
59 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
59 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
60 {
60 {
61 return createGraphs(plot, 1);
61 return createGraphs(plot, 1);
62 }
62 }
63 };
63 };
64
64
65 /**
65 /**
66 * Specialization of PlottablesCreator for vectors
66 * Specialization of PlottablesCreator for vectors
67 * @sa VectorSeries
67 * @sa VectorSeries
68 */
68 */
69 template <typename T>
69 template <typename T>
70 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
70 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
71 {
71 {
72 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
72 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
73 {
73 {
74 return createGraphs(plot, 3);
74 return createGraphs(plot, 3);
75 }
75 }
76 };
76 };
77
77
78 /**
78 /**
79 * Specialization of PlottablesCreator for MultiComponentTimeSeries
79 * Specialization of PlottablesCreator for MultiComponentTimeSeries
80 * @sa VectorSeries
80 * @sa VectorSeries
81 */
81 */
82 template <typename T>
82 template <typename T>
83 struct PlottablesCreator<T,
83 struct PlottablesCreator<T,
84 typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
84 typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
85 {
85 {
86 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
86 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
87 {
87 {
88 return createGraphs(plot, dataSeries->size(1));
88 return createGraphs(plot, dataSeries->size(1));
89 }
89 }
90 };
90 };
91
91
92 /**
92 /**
93 * Specialization of PlottablesCreator for spectrograms
93 * Specialization of PlottablesCreator for spectrograms
94 * @sa SpectrogramSeries
94 * @sa SpectrogramSeries
95 */
95 */
96 template <typename T>
96 template <typename T>
97 struct PlottablesCreator<T,
97 struct PlottablesCreator<T,
98 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
98 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
99 {
99 {
100 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
100 static PlottablesMap createPlottables(QCustomPlot& plot, const std::shared_ptr<T>& dataSeries)
101 {
101 {
102 PlottablesMap result {};
102 PlottablesMap result {};
103 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
103 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
104
104
105 plot.replot();
105 plot.replot();
106
106
107 return result;
107 return result;
108 }
108 }
109 };
109 };
110
110
111 /**
111 /**
112 * Struct used to update plottables, depending on the type of the data series from which to update
112 * Struct used to update plottables, depending on the type of the data series from which to update
113 * them
113 * them
114 * @tparam T the data series' type
114 * @tparam T the data series' type
115 * @remarks Default implementation can't update plottables
115 * @remarks Default implementation can't update plottables
116 */
116 */
117 template <typename T, typename Enabled = void>
117 template <typename T, typename Enabled = void>
118 struct PlottablesUpdater
118 struct PlottablesUpdater
119 {
119 {
120 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
120 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
121 {
121 {
122 qCCritical(LOG_VisualizationGraphHelper())
122 qCCritical(LOG_VisualizationGraphHelper())
123 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
123 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
124 }
124 }
125
125
126 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
126 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
127 {
127 {
128 qCCritical(LOG_VisualizationGraphHelper())
128 qCCritical(LOG_VisualizationGraphHelper())
129 << QObject::tr("Can't update plottables: unmanaged data series type");
129 << QObject::tr("Can't update plottables: unmanaged data series type");
130 }
130 }
131 };
131 };
132
132
133 /**
133 /**
134 * Specialization of PlottablesUpdater for scalars and vectors
134 * Specialization of PlottablesUpdater for scalars and vectors
135 * @sa ScalarSeries
135 * @sa ScalarSeries
136 * @sa VectorSeries
136 * @sa VectorSeries
137 */
137 */
138 template <typename T>
138 template <typename T>
139 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
139 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
140 {
140 {
141 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
141 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
142 {
142 {
143 auto minValue = 0., maxValue = 0.;
143 auto minValue = 0., maxValue = 0.;
144 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
144 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
145 {
145 {
146 if (serie->size())
146 if (serie->size())
147 {
147 {
148 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
148 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
149 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
149 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
150 }
150 }
151 }
151 }
152 plot.yAxis->setRange(QCPRange { minValue, maxValue });
152 plot.yAxis->setRange(QCPRange { minValue, maxValue });
153 }
153 }
154
154
155 static void updatePlottables(
155 static void updatePlottables(
156 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
156 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
157 {
157 {
158
158
159 // For each plottable to update, resets its data
159 // For each plottable to update, resets its data
160 for (const auto& plottable : plottables)
160 for (const auto& plottable : plottables)
161 {
161 {
162 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
162 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
163 {
163 {
164 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
164 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
165 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
165 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
166 {
166 {
167 std::for_each(
167 std::for_each(
168 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
168 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
169 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
169 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
170 });
170 });
171 }
171 }
172 graph->setData(dataContainer);
172 graph->setData(dataContainer);
173 }
173 }
174 }
174 }
175
175
176 if (!plottables.empty())
176 if (!plottables.empty())
177 {
177 {
178 auto plot = plottables.begin()->second->parentPlot();
178 auto plot = plottables.begin()->second->parentPlot();
179
179
180 if (rescaleAxes)
180 if (rescaleAxes)
181 {
181 {
182 plot->rescaleAxes();
182 plot->rescaleAxes();
183 }
183 }
184 }
184 }
185 }
185 }
186 };
186 };
187
187
188
188
189 template <typename T>
189 template <typename T>
190 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
190 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
191 {
191 {
192 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
192 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
193 {
193 {
194 double minValue = 0., maxValue = 0.;
194 double minValue = 0., maxValue = 0.;
195 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
195 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
196 {
196 {
197 std::for_each(
197 std::for_each(
198 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
198 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
199 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
199 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
200 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
200 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
201 });
201 });
202 }
202 }
203
203
204 plot.yAxis->setRange(QCPRange { minValue, maxValue });
204 plot.yAxis->setRange(QCPRange { minValue, maxValue });
205 }
205 }
206
206
207 static void updatePlottables(
207 static void updatePlottables(
208 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
208 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
209 {
209 {
210
210
211 // For each plottable to update, resets its data
211 // For each plottable to update, resets its data
212 for (const auto& plottable : plottables)
212 for (const auto& plottable : plottables)
213 {
213 {
214 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
214 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
215 {
215 {
216 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
216 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
217 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
217 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
218 {
218 {
219 switch (plottable.first)
219 switch (plottable.first)
220 {
220 {
221 case 0:
221 case 0:
222 std::for_each(std::begin(*serie), std::end(*serie),
222 std::for_each(std::begin(*serie), std::end(*serie),
223 [&dataContainer](const auto& value) {
223 [&dataContainer](const auto& value) {
224 dataContainer->appendGraphData(
224 dataContainer->appendGraphData(
225 QCPGraphData(value.t(), value.v().x));
225 QCPGraphData(value.t(), value.v().x));
226 });
226 });
227 break;
227 break;
228 case 1:
228 case 1:
229 std::for_each(std::begin(*serie), std::end(*serie),
229 std::for_each(std::begin(*serie), std::end(*serie),
230 [&dataContainer](const auto& value) {
230 [&dataContainer](const auto& value) {
231 dataContainer->appendGraphData(
231 dataContainer->appendGraphData(
232 QCPGraphData(value.t(), value.v().y));
232 QCPGraphData(value.t(), value.v().y));
233 });
233 });
234 break;
234 break;
235 case 2:
235 case 2:
236 std::for_each(std::begin(*serie), std::end(*serie),
236 std::for_each(std::begin(*serie), std::end(*serie),
237 [&dataContainer](const auto& value) {
237 [&dataContainer](const auto& value) {
238 dataContainer->appendGraphData(
238 dataContainer->appendGraphData(
239 QCPGraphData(value.t(), value.v().z));
239 QCPGraphData(value.t(), value.v().z));
240 });
240 });
241 break;
241 break;
242 default:
242 default:
243 break;
243 break;
244 }
244 }
245 }
245 }
246 graph->setData(dataContainer);
246 graph->setData(dataContainer);
247 }
247 }
248 }
248 }
249
249
250 if (!plottables.empty())
250 if (!plottables.empty())
251 {
251 {
252 auto plot = plottables.begin()->second->parentPlot();
252 auto plot = plottables.begin()->second->parentPlot();
253
253
254 if (rescaleAxes)
254 if (rescaleAxes)
255 {
255 {
256 plot->rescaleAxes();
256 plot->rescaleAxes();
257 }
257 }
258 }
258 }
259 }
259 }
260 };
260 };
261
261
262
262
263 template <typename T>
263 template <typename T>
264 struct PlottablesUpdater<T,
264 struct PlottablesUpdater<T,
265 typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
265 typename std::enable_if_t<std::is_base_of<MultiComponentTimeSerie, T>::value>>
266 {
266 {
267 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
267 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
268 {
268 {
269 double minValue = 0., maxValue = 0.;
269 double minValue = 0., maxValue = 0.;
270 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
270 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
271 {
271 {
272 // TODO
272 std::for_each(
273 // std::for_each(
273 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
274 // std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const
274 minValue = std::min( minValue, std::min_element(v.begin(), v.end())->v() );
275 // auto& v) {
275 maxValue = std::max( maxValue, std::max_element(v.begin(), v.end())->v() );
276 // minValue = std::min({ minValue,
276 });
277 // std::min_element(v.begin(),v.end()) }); maxValue = std::max({
278 // maxValue, std::max_element(v.begin(),v.end()) });
279 // });
280 }
277 }
281
278
282 plot.yAxis->setRange(QCPRange { minValue, maxValue });
279 plot.yAxis->setRange(QCPRange { minValue, maxValue });
283 }
280 }
284
281
285 static void updatePlottables(
282 static void updatePlottables(
286 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
283 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
287 {
284 {
288 for (const auto& plottable : plottables)
285 for (const auto& plottable : plottables)
289 {
286 {
290 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
287 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
291 {
288 {
292 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
289 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
293 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
290 if (auto serie = dynamic_cast<MultiComponentTimeSerie*>(&dataSeries))
294 {
291 {
295 // TODO
292 // TODO
296 std::for_each(std::begin(*serie), std::end(*serie),
293 std::for_each(std::begin(*serie), std::end(*serie),
297 [&dataContainer, component = plottable.first](const auto& value) {
294 [&dataContainer, component = plottable.first](const auto& value) {
298 dataContainer->appendGraphData(
295 dataContainer->appendGraphData(
299 QCPGraphData(value.t(), value[component]));
296 QCPGraphData(value.t(), value[component]));
300 });
297 });
301 }
298 }
302 graph->setData(dataContainer);
299 graph->setData(dataContainer);
303 }
300 }
304 }
301 }
305
302
306 if (!plottables.empty())
303 if (!plottables.empty())
307 {
304 {
308 auto plot = plottables.begin()->second->parentPlot();
305 auto plot = plottables.begin()->second->parentPlot();
309
306
310 if (rescaleAxes)
307 if (rescaleAxes)
311 {
308 {
312 plot->rescaleAxes();
309 plot->rescaleAxes();
313 }
310 }
314 }
311 }
315 }
312 }
316 };
313 };
317
314
318 /**
315 /**
319 * Specialization of PlottablesUpdater for spectrograms
316 * Specialization of PlottablesUpdater for spectrograms
320 * @sa SpectrogramSeries
317 * @sa SpectrogramSeries
321 */
318 */
322 template <typename T>
319 template <typename T>
323 struct PlottablesUpdater<T,
320 struct PlottablesUpdater<T,
324 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
321 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
325 {
322 {
326 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
323 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
327 {
324 {
328 // TODO
325 // TODO
329 // double min, max;
326 // double min, max;
330 // std::tie(min, max) = dataSeries.yBounds();
327 // std::tie(min, max) = dataSeries.yBounds();
331
328
332 // if (!std::isnan(min) && !std::isnan(max))
329 // if (!std::isnan(min) && !std::isnan(max))
333 // {
330 // {
334 // plot.yAxis->setRange(QCPRange { min, max });
331 // plot.yAxis->setRange(QCPRange { min, max });
335 // }
332 // }
336 }
333 }
337
334
338 static void updatePlottables(
335 static void updatePlottables(
339 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
336 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
340 {
337 {
341 // TODO
338 // TODO
342 // if (plottables.empty())
339 // if (plottables.empty())
343 // {
340 // {
344 // qCDebug(LOG_VisualizationGraphHelper())
341 // qCDebug(LOG_VisualizationGraphHelper())
345 // << QObject::tr("Can't update spectrogram: no colormap has been
342 // << QObject::tr("Can't update spectrogram: no colormap has been
346 // associated");
343 // associated");
347 // return;
344 // return;
348 // }
345 // }
349
346
350 // // Gets the colormap to update (normally there is only one colormap)
347 // // Gets the colormap to update (normally there is only one colormap)
351 // Q_ASSERT(plottables.size() == 1);
348 // Q_ASSERT(plottables.size() == 1);
352 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
349 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
353 // Q_ASSERT(colormap != nullptr);
350 // Q_ASSERT(colormap != nullptr);
354
351
355 // dataSeries.lockRead();
352 // dataSeries.lockRead();
356
353
357 // // Processing spectrogram data for display in QCustomPlot
354 // // Processing spectrogram data for display in QCustomPlot
358 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
355 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
359
356
360 // // Computes logarithmic y-axis resolution for the spectrogram
357 // // Computes logarithmic y-axis resolution for the spectrogram
361 // auto yData = its.first->y();
358 // auto yData = its.first->y();
362 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
359 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
363
360
364 // // Generates mesh for colormap
361 // // Generates mesh for colormap
365 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
362 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
366 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
363 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
367
364
368 // dataSeries.unlock();
365 // dataSeries.unlock();
369
366
370 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
367 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
371 // if (!mesh.isEmpty())
368 // if (!mesh.isEmpty())
372 // {
369 // {
373 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
370 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
374 // // y-axis range is converted to linear values
371 // // y-axis range is converted to linear values
375 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
372 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
376
373
377 // // Sets values
374 // // Sets values
378 // auto index = 0;
375 // auto index = 0;
379 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
376 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
380 // ++index)
377 // ++index)
381 // {
378 // {
382 // auto xIndex = index % mesh.m_NbX;
379 // auto xIndex = index % mesh.m_NbX;
383 // auto yIndex = index / mesh.m_NbX;
380 // auto yIndex = index / mesh.m_NbX;
384
381
385 // colormap->data()->setCell(xIndex, yIndex, *it);
382 // colormap->data()->setCell(xIndex, yIndex, *it);
386
383
387 // // Makes the NaN values to be transparent in the colormap
384 // // Makes the NaN values to be transparent in the colormap
388 // if (std::isnan(*it))
385 // if (std::isnan(*it))
389 // {
386 // {
390 // colormap->data()->setAlpha(xIndex, yIndex, 0);
387 // colormap->data()->setAlpha(xIndex, yIndex, 0);
391 // }
388 // }
392 // }
389 // }
393 // }
390 // }
394
391
395 // // Rescales axes
392 // // Rescales axes
396 // auto plot = colormap->parentPlot();
393 // auto plot = colormap->parentPlot();
397
394
398 // if (rescaleAxes)
395 // if (rescaleAxes)
399 // {
396 // {
400 // plot->rescaleAxes();
397 // plot->rescaleAxes();
401 // }
398 // }
402 }
399 }
403 };
400 };
404
401
405 /**
402 /**
406 * Helper used to create/update plottables
403 * Helper used to create/update plottables
407 */
404 */
408 struct IPlottablesHelper
405 struct IPlottablesHelper
409 {
406 {
410 virtual ~IPlottablesHelper() noexcept = default;
407 virtual ~IPlottablesHelper() noexcept = default;
411 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
408 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
412 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
409 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
413 virtual void update(
410 virtual void update(
414 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
411 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
415 };
412 };
416
413
417 /**
414 /**
418 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
415 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
419 * @tparam T the data series' type
416 * @tparam T the data series' type
420 */
417 */
421 template <typename T>
418 template <typename T>
422 struct PlottablesHelper : public IPlottablesHelper
419 struct PlottablesHelper : public IPlottablesHelper
423 {
420 {
424 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries { dataSeries } {}
421 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries { dataSeries } {}
425
422
426 PlottablesMap create(QCustomPlot& plot) const override
423 PlottablesMap create(QCustomPlot& plot) const override
427 {
424 {
428 return PlottablesCreator<T>::createPlottables(plot, m_DataSeries);
425 return PlottablesCreator<T>::createPlottables(plot, m_DataSeries);
429 }
426 }
430
427
431 void update(
428 void update(
432 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
429 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
433 {
430 {
434 if (m_DataSeries)
431 if (m_DataSeries)
435 {
432 {
436 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
433 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
437 }
434 }
438 else
435 else
439 {
436 {
440 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
437 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
441 "between the type of data series and the "
438 "between the type of data series and the "
442 "type supposed";
439 "type supposed";
443 }
440 }
444 }
441 }
445
442
446 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
443 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
447 {
444 {
448 if (m_DataSeries)
445 if (m_DataSeries)
449 {
446 {
450 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
447 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
451 }
448 }
452 else
449 else
453 {
450 {
454 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
451 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
455 "between the type of data series and the "
452 "between the type of data series and the "
456 "type supposed";
453 "type supposed";
457 }
454 }
458 }
455 }
459
456
460 std::shared_ptr<T> m_DataSeries;
457 std::shared_ptr<T> m_DataSeries;
461 };
458 };
462
459
463 /// Creates IPlottablesHelper according to the type of data series a variable holds
460 /// Creates IPlottablesHelper according to the type of data series a variable holds
464 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
461 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
465 {
462 {
466 switch (variable->type())
463 switch (variable->type())
467 {
464 {
468 case DataSeriesType::SCALAR:
465 case DataSeriesType::SCALAR:
469 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
466 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
470 std::dynamic_pointer_cast<ScalarTimeSerie>(variable->data()));
467 std::dynamic_pointer_cast<ScalarTimeSerie>(variable->data()));
471 case DataSeriesType::SPECTROGRAM:
468 case DataSeriesType::SPECTROGRAM:
472 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
469 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
473 std::dynamic_pointer_cast<SpectrogramTimeSerie>(variable->data()));
470 std::dynamic_pointer_cast<SpectrogramTimeSerie>(variable->data()));
474 case DataSeriesType::VECTOR:
471 case DataSeriesType::VECTOR:
475 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
472 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
476 std::dynamic_pointer_cast<VectorTimeSerie>(variable->data()));
473 std::dynamic_pointer_cast<VectorTimeSerie>(variable->data()));
477 case DataSeriesType::MULTICOMPONENT:
474 case DataSeriesType::MULTICOMPONENT:
478 return std::make_unique<PlottablesHelper<MultiComponentTimeSerie>>(
475 return std::make_unique<PlottablesHelper<MultiComponentTimeSerie>>(
479 std::dynamic_pointer_cast<MultiComponentTimeSerie>(variable->data()));
476 std::dynamic_pointer_cast<MultiComponentTimeSerie>(variable->data()));
480 default:
477 default:
481 // Creates default helper
478 // Creates default helper
482 break;
479 break;
483 }
480 }
484
481
485 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
482 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
486 }
483 }
487
484
488 } // namespace
485 } // namespace
489
486
490 PlottablesMap VisualizationGraphHelper::create(
487 PlottablesMap VisualizationGraphHelper::create(
491 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
488 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
492 {
489 {
493 if (variable)
490 if (variable)
494 {
491 {
495 auto helper = createHelper(variable);
492 auto helper = createHelper(variable);
496 auto plottables = helper->create(plot);
493 auto plottables = helper->create(plot);
497 return plottables;
494 return plottables;
498 }
495 }
499 else
496 else
500 {
497 {
501 qCDebug(LOG_VisualizationGraphHelper())
498 qCDebug(LOG_VisualizationGraphHelper())
502 << QObject::tr("Can't create graph plottables : the variable is null");
499 << QObject::tr("Can't create graph plottables : the variable is null");
503 return PlottablesMap {};
500 return PlottablesMap {};
504 }
501 }
505 }
502 }
506
503
507 void VisualizationGraphHelper::setYAxisRange(
504 void VisualizationGraphHelper::setYAxisRange(
508 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
505 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
509 {
506 {
510 if (variable)
507 if (variable)
511 {
508 {
512 auto helper = createHelper(variable);
509 auto helper = createHelper(variable);
513 helper->setYAxisRange(variable->range(), plot);
510 helper->setYAxisRange(variable->range(), plot);
514 }
511 }
515 else
512 else
516 {
513 {
517 qCDebug(LOG_VisualizationGraphHelper())
514 qCDebug(LOG_VisualizationGraphHelper())
518 << QObject::tr("Can't set y-axis range of plot: the variable is null");
515 << QObject::tr("Can't set y-axis range of plot: the variable is null");
519 }
516 }
520 }
517 }
521
518
522 void VisualizationGraphHelper::updateData(
519 void VisualizationGraphHelper::updateData(
523 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
520 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
524 {
521 {
525 auto helper = createHelper(variable);
522 auto helper = createHelper(variable);
526 helper->update(plottables, dateTime);
523 helper->update(plottables, dateTime);
527 }
524 }
@@ -1,45 +1,45
1 import sys
1 import sys
2 sys.path.append("/home/jeandet/Documents/prog/build-SciQLop-Desktop-Debug/core")
2 sys.path.append("/home/jeandet/Documents/prog/build-SciQLop-Desktop-Debug/core")
3 import PythonProviders
3 import PythonProviders
4 import pysciqlopcore
4 import pysciqlopcore
5 import numpy as np
5 import numpy as np
6 import math
6 import math
7
7
8 someglobal = 1
8 someglobal = 1
9
9
10 def make_scalar(x):
10 def make_scalar(x):
11 y = np.cos(x/10.)
11 y = np.cos(x/10.)
12 return pysciqlopcore.ScalarTimeSerie(x,y)
12 return pysciqlopcore.ScalarTimeSerie(x,y)
13
13
14 def make_vector(x):
14 def make_vector(x):
15 v=np.ones((3,len(x)))
15 v=np.ones((len(x),3))
16 for i in range(3):
16 for i in range(3):
17 v[:][i] = np.cos(x/10. + float(i))
17 v.transpose()[:][i] = np.cos(x/10. + float(i))
18 return pysciqlopcore.VectorTimeSerie(x,v)
18 return pysciqlopcore.VectorTimeSerie(x,v)
19
19
20
20
21 def make_multicomponent(x):
21 def make_multicomponent(x):
22 v=np.ones((4,len(x)))
22 v=np.ones((len(x),4))
23 for i in range(4):
23 for i in range(4):
24 v[:][i] = float(i+1) * np.cos(x/10. + float(i))
24 v.transpose()[:][i] = float(i+1) * np.cos(x/10. + float(i))
25 return pysciqlopcore.MultiComponentTimeSerie(x,v)
25 return pysciqlopcore.MultiComponentTimeSerie(x,v)
26
26
27
27
28 def get_data(metadata,start,stop):
28 def get_data(metadata,start,stop):
29 x = np.arange(math.ceil(start), math.floor(stop))
29 x = np.arange(math.ceil(start), math.floor(stop))
30 for key,value in metadata:
30 for key,value in metadata:
31 if key == 'xml:id':
31 if key == 'xml:id':
32 param_id = value
32 param_id = value
33 elif key == 'type':
33 elif key == 'type':
34 if value == 'vector':
34 if value == 'vector':
35 return make_vector(x)
35 return make_vector(x)
36 elif value == 'multicomponent':
36 elif value == 'multicomponent':
37 return make_multicomponent(x)
37 return make_multicomponent(x)
38 return make_scalar(x)
38 return make_scalar(x)
39
39
40
40
41
41
42
42
43 PythonProviders.register_product([("/tests/scalar",[],[("type","scalar")]), ("/tests/vector",[],[("type","vector")]), ("/tests/multicomponent",[],[("type","multicomponent"),('size','4')])],get_data)
43 PythonProviders.register_product([("/tests/scalar",[],[("type","scalar")]), ("/tests/vector",[],[("type","vector")]), ("/tests/multicomponent",[],[("type","multicomponent"),('size','4')])],get_data)
44
44
45
45
General Comments 0
You need to be logged in to leave comments. Login now