##// END OF EJS Templates
Handles rendering of plottables (2)...
Alexandre Leroux -
r919:f75604dde9e3
parent child
Show More
@@ -1,65 +1,79
1 #include "Visualization/PlottablesRenderingUtils.h"
1 #include "Visualization/PlottablesRenderingUtils.h"
2
2
3 #include <Common/ColorUtils.h>
4
3 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
4 #include <Data/VectorSeries.h>
6 #include <Data/VectorSeries.h>
5
7
6 #include <Visualization/qcustomplot.h>
8 #include <Visualization/qcustomplot.h>
7
9
8 namespace {
10 namespace {
9
11
10 /**
12 /**
11 * Delegate used to set plottables properties
13 * Delegate used to set plottables properties
12 */
14 */
13 template <typename T, typename Enabled = void>
15 template <typename T, typename Enabled = void>
14 struct PlottablesSetter {
16 struct PlottablesSetter {
15 static void setProperties(T &, PlottablesMap &)
17 static void setProperties(T &, PlottablesMap &)
16 {
18 {
17 // Default implementation does nothing
19 // Default implementation does nothing
18 }
20 }
19 };
21 };
20
22
21 /**
23 /**
22 * Specialization of PlottablesSetter for scalars and vectors
24 * Specialization of PlottablesSetter for scalars and vectors
23 * @sa ScalarSeries
25 * @sa ScalarSeries
24 * @sa VectorSeries
26 * @sa VectorSeries
25 */
27 */
26 template <typename T>
28 template <typename T>
27 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
29 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
28 or std::is_base_of<VectorSeries, T>::value> > {
30 or std::is_base_of<VectorSeries, T>::value> > {
29 static void setProperties(T &dataSeries, PlottablesMap &plottables)
31 static void setProperties(T &dataSeries, PlottablesMap &plottables)
30 {
32 {
31 /// @todo ALX
33 // Gets the number of components of the data series
34 dataSeries.lockRead();
35 auto componentCount = dataSeries.valuesData()->componentCount();
36 dataSeries.unlock();
37
38 // Generates colors for each component
39 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
40
41 // For each component of the data series, creates a QCPGraph to add to the plot
42 for (auto i = 0; i < componentCount; ++i) {
43 auto graph = plottables.at(i);
44 graph->setPen(QPen{colors.at(i)});
45 }
32 }
46 }
33 };
47 };
34
48
35 /**
49 /**
36 * Default implementation of IPlottablesHelper, which takes data series to set plottables properties
50 * Default implementation of IPlottablesHelper, which takes data series to set plottables properties
37 * @tparam T the data series' type
51 * @tparam T the data series' type
38 */
52 */
39 template <typename T>
53 template <typename T>
40 struct PlottablesHelper : public IPlottablesHelper {
54 struct PlottablesHelper : public IPlottablesHelper {
41 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
55 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
42
56
43 void setProperties(PlottablesMap &plottables) override
57 void setProperties(PlottablesMap &plottables) override
44 {
58 {
45 PlottablesSetter<T>::setProperties(m_DataSeries, plottables);
59 PlottablesSetter<T>::setProperties(m_DataSeries, plottables);
46 }
60 }
47
61
48 T &m_DataSeries;
62 T &m_DataSeries;
49 };
63 };
50
64
51 } // namespace
65 } // namespace
52
66
53 std::unique_ptr<IPlottablesHelper>
67 std::unique_ptr<IPlottablesHelper>
54 IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
68 IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
55 {
69 {
56 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
70 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
57 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
71 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
58 }
72 }
59 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
73 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
60 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
74 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
61 }
75 }
62 else {
76 else {
63 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
77 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
64 }
78 }
65 }
79 }
@@ -1,342 +1,336
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Common/ColorUtils.h>
5
6 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
7 #include <Data/SpectrogramSeries.h>
5 #include <Data/SpectrogramSeries.h>
8 #include <Data/VectorSeries.h>
6 #include <Data/VectorSeries.h>
9
7
10 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
11
9
12 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
13
11
14 namespace {
12 namespace {
15
13
16 class SqpDataContainer : public QCPGraphDataContainer {
14 class SqpDataContainer : public QCPGraphDataContainer {
17 public:
15 public:
18 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
16 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
19 };
17 };
20
18
21 /**
19 /**
22 * Struct used to create plottables, depending on the type of the data series from which to create
20 * Struct used to create plottables, depending on the type of the data series from which to create
23 * them
21 * them
24 * @tparam T the data series' type
22 * @tparam T the data series' type
25 * @remarks Default implementation can't create plottables
23 * @remarks Default implementation can't create plottables
26 */
24 */
27 template <typename T, typename Enabled = void>
25 template <typename T, typename Enabled = void>
28 struct PlottablesCreator {
26 struct PlottablesCreator {
29 static PlottablesMap createPlottables(T &, QCustomPlot &)
27 static PlottablesMap createPlottables(T &, QCustomPlot &)
30 {
28 {
31 qCCritical(LOG_DataSeries())
29 qCCritical(LOG_DataSeries())
32 << QObject::tr("Can't create plottables: unmanaged data series type");
30 << QObject::tr("Can't create plottables: unmanaged data series type");
33 return {};
31 return {};
34 }
32 }
35 };
33 };
36
34
37 /**
35 /**
38 * Specialization of PlottablesCreator for scalars and vectors
36 * Specialization of PlottablesCreator for scalars and vectors
39 * @sa ScalarSeries
37 * @sa ScalarSeries
40 * @sa VectorSeries
38 * @sa VectorSeries
41 */
39 */
42 template <typename T>
40 template <typename T>
43 struct PlottablesCreator<T,
41 struct PlottablesCreator<T,
44 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
42 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
45 or std::is_base_of<VectorSeries, T>::value> > {
43 or std::is_base_of<VectorSeries, T>::value> > {
46 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
44 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
47 {
45 {
48 PlottablesMap result{};
46 PlottablesMap result{};
49
47
50 // Gets the number of components of the data series
48 // Gets the number of components of the data series
51 dataSeries.lockRead();
49 dataSeries.lockRead();
52 auto componentCount = dataSeries.valuesData()->componentCount();
50 auto componentCount = dataSeries.valuesData()->componentCount();
53 dataSeries.unlock();
51 dataSeries.unlock();
54
52
55 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
56
57 // For each component of the data series, creates a QCPGraph to add to the plot
53 // For each component of the data series, creates a QCPGraph to add to the plot
58 for (auto i = 0; i < componentCount; ++i) {
54 for (auto i = 0; i < componentCount; ++i) {
59 auto graph = plot.addGraph();
55 auto graph = plot.addGraph();
60 graph->setPen(QPen{colors.at(i)});
61
62 result.insert({i, graph});
56 result.insert({i, graph});
63 }
57 }
64
58
65 plot.replot();
59 plot.replot();
66
60
67 return result;
61 return result;
68 }
62 }
69 };
63 };
70
64
71 /**
65 /**
72 * Specialization of PlottablesCreator for spectrograms
66 * Specialization of PlottablesCreator for spectrograms
73 * @sa SpectrogramSeries
67 * @sa SpectrogramSeries
74 */
68 */
75 template <typename T>
69 template <typename T>
76 struct PlottablesCreator<T,
70 struct PlottablesCreator<T,
77 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
71 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
78 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
72 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
79 {
73 {
80 PlottablesMap result{};
74 PlottablesMap result{};
81 result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
75 result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
82
76
83 plot.replot();
77 plot.replot();
84
78
85 return result;
79 return result;
86 }
80 }
87 };
81 };
88
82
89 /**
83 /**
90 * Struct used to update plottables, depending on the type of the data series from which to update
84 * Struct used to update plottables, depending on the type of the data series from which to update
91 * them
85 * them
92 * @tparam T the data series' type
86 * @tparam T the data series' type
93 * @remarks Default implementation can't update plottables
87 * @remarks Default implementation can't update plottables
94 */
88 */
95 template <typename T, typename Enabled = void>
89 template <typename T, typename Enabled = void>
96 struct PlottablesUpdater {
90 struct PlottablesUpdater {
97 static void setPlotYAxisRange(T &, const SqpRange &, QCustomPlot &)
91 static void setPlotYAxisRange(T &, const SqpRange &, QCustomPlot &)
98 {
92 {
99 qCCritical(LOG_VisualizationGraphHelper())
93 qCCritical(LOG_VisualizationGraphHelper())
100 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
94 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
101 }
95 }
102
96
103 static void updatePlottables(T &, PlottablesMap &, const SqpRange &, bool)
97 static void updatePlottables(T &, PlottablesMap &, const SqpRange &, bool)
104 {
98 {
105 qCCritical(LOG_VisualizationGraphHelper())
99 qCCritical(LOG_VisualizationGraphHelper())
106 << QObject::tr("Can't update plottables: unmanaged data series type");
100 << QObject::tr("Can't update plottables: unmanaged data series type");
107 }
101 }
108 };
102 };
109
103
110 /**
104 /**
111 * Specialization of PlottablesUpdater for scalars and vectors
105 * Specialization of PlottablesUpdater for scalars and vectors
112 * @sa ScalarSeries
106 * @sa ScalarSeries
113 * @sa VectorSeries
107 * @sa VectorSeries
114 */
108 */
115 template <typename T>
109 template <typename T>
116 struct PlottablesUpdater<T,
110 struct PlottablesUpdater<T,
117 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
111 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
118 or std::is_base_of<VectorSeries, T>::value> > {
112 or std::is_base_of<VectorSeries, T>::value> > {
119 static void setPlotYAxisRange(T &dataSeries, const SqpRange &xAxisRange, QCustomPlot &plot)
113 static void setPlotYAxisRange(T &dataSeries, const SqpRange &xAxisRange, QCustomPlot &plot)
120 {
114 {
121 auto minValue = 0., maxValue = 0.;
115 auto minValue = 0., maxValue = 0.;
122
116
123 dataSeries.lockRead();
117 dataSeries.lockRead();
124 auto valuesBounds = dataSeries.valuesBounds(xAxisRange.m_TStart, xAxisRange.m_TEnd);
118 auto valuesBounds = dataSeries.valuesBounds(xAxisRange.m_TStart, xAxisRange.m_TEnd);
125 auto end = dataSeries.cend();
119 auto end = dataSeries.cend();
126 if (valuesBounds.first != end && valuesBounds.second != end) {
120 if (valuesBounds.first != end && valuesBounds.second != end) {
127 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
121 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
128
122
129 minValue = rangeValue(valuesBounds.first->minValue());
123 minValue = rangeValue(valuesBounds.first->minValue());
130 maxValue = rangeValue(valuesBounds.second->maxValue());
124 maxValue = rangeValue(valuesBounds.second->maxValue());
131 }
125 }
132 dataSeries.unlock();
126 dataSeries.unlock();
133
127
134 plot.yAxis->setRange(QCPRange{minValue, maxValue});
128 plot.yAxis->setRange(QCPRange{minValue, maxValue});
135 }
129 }
136
130
137 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const SqpRange &range,
131 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const SqpRange &range,
138 bool rescaleAxes)
132 bool rescaleAxes)
139 {
133 {
140
134
141 // For each plottable to update, resets its data
135 // For each plottable to update, resets its data
142 std::map<int, QSharedPointer<SqpDataContainer> > dataContainers{};
136 std::map<int, QSharedPointer<SqpDataContainer> > dataContainers{};
143 for (const auto &plottable : plottables) {
137 for (const auto &plottable : plottables) {
144 if (auto graph = dynamic_cast<QCPGraph *>(plottable.second)) {
138 if (auto graph = dynamic_cast<QCPGraph *>(plottable.second)) {
145 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
139 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
146 graph->setData(dataContainer);
140 graph->setData(dataContainer);
147
141
148 dataContainers.insert({plottable.first, dataContainer});
142 dataContainers.insert({plottable.first, dataContainer});
149 }
143 }
150 }
144 }
151 dataSeries.lockRead();
145 dataSeries.lockRead();
152
146
153 // - Gets the data of the series included in the current range
147 // - Gets the data of the series included in the current range
154 // - Updates each plottable by adding, for each data item, a point that takes x-axis data
148 // - Updates each plottable by adding, for each data item, a point that takes x-axis data
155 // and value data. The correct value is retrieved according to the index of the component
149 // and value data. The correct value is retrieved according to the index of the component
156 auto subDataIts = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
150 auto subDataIts = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
157 for (auto it = subDataIts.first; it != subDataIts.second; ++it) {
151 for (auto it = subDataIts.first; it != subDataIts.second; ++it) {
158 for (const auto &dataContainer : dataContainers) {
152 for (const auto &dataContainer : dataContainers) {
159 auto componentIndex = dataContainer.first;
153 auto componentIndex = dataContainer.first;
160 dataContainer.second->appendGraphData(
154 dataContainer.second->appendGraphData(
161 QCPGraphData(it->x(), it->value(componentIndex)));
155 QCPGraphData(it->x(), it->value(componentIndex)));
162 }
156 }
163 }
157 }
164
158
165 dataSeries.unlock();
159 dataSeries.unlock();
166
160
167 if (!plottables.empty()) {
161 if (!plottables.empty()) {
168 auto plot = plottables.begin()->second->parentPlot();
162 auto plot = plottables.begin()->second->parentPlot();
169
163
170 if (rescaleAxes) {
164 if (rescaleAxes) {
171 plot->rescaleAxes();
165 plot->rescaleAxes();
172 }
166 }
173
167
174 plot->replot();
168 plot->replot();
175 }
169 }
176 }
170 }
177 };
171 };
178
172
179 /**
173 /**
180 * Specialization of PlottablesUpdater for spectrograms
174 * Specialization of PlottablesUpdater for spectrograms
181 * @sa SpectrogramSeries
175 * @sa SpectrogramSeries
182 */
176 */
183 template <typename T>
177 template <typename T>
184 struct PlottablesUpdater<T,
178 struct PlottablesUpdater<T,
185 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
179 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
186 static void setPlotYAxisRange(T &dataSeries, const SqpRange &xAxisRange, QCustomPlot &plot)
180 static void setPlotYAxisRange(T &dataSeries, const SqpRange &xAxisRange, QCustomPlot &plot)
187 {
181 {
188 double min, max;
182 double min, max;
189 /// @todo ALX: use iterators here
183 /// @todo ALX: use iterators here
190 std::tie(min, max) = dataSeries.yAxis().bounds();
184 std::tie(min, max) = dataSeries.yAxis().bounds();
191
185
192 if (!std::isnan(min) && !std::isnan(max)) {
186 if (!std::isnan(min) && !std::isnan(max)) {
193 plot.yAxis->setRange(QCPRange{min, max});
187 plot.yAxis->setRange(QCPRange{min, max});
194 }
188 }
195 }
189 }
196
190
197 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const SqpRange &range,
191 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const SqpRange &range,
198 bool rescaleAxes)
192 bool rescaleAxes)
199 {
193 {
200 if (plottables.empty()) {
194 if (plottables.empty()) {
201 qCDebug(LOG_VisualizationGraphHelper())
195 qCDebug(LOG_VisualizationGraphHelper())
202 << QObject::tr("Can't update spectrogram: no colormap has been associated");
196 << QObject::tr("Can't update spectrogram: no colormap has been associated");
203 return;
197 return;
204 }
198 }
205
199
206 // Gets the colormap to update (normally there is only one colormap)
200 // Gets the colormap to update (normally there is only one colormap)
207 Q_ASSERT(plottables.size() == 1);
201 Q_ASSERT(plottables.size() == 1);
208 auto colormap = dynamic_cast<QCPColorMap *>(plottables.at(0));
202 auto colormap = dynamic_cast<QCPColorMap *>(plottables.at(0));
209 Q_ASSERT(colormap != nullptr);
203 Q_ASSERT(colormap != nullptr);
210
204
211 dataSeries.lockRead();
205 dataSeries.lockRead();
212
206
213 auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
207 auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
214 /// @todo ALX: use iterators here
208 /// @todo ALX: use iterators here
215 auto yAxis = dataSeries.yAxis();
209 auto yAxis = dataSeries.yAxis();
216
210
217 // Gets properties of x-axis and y-axis to set size and range of the colormap
211 // Gets properties of x-axis and y-axis to set size and range of the colormap
218 auto nbX = std::distance(its.first, its.second);
212 auto nbX = std::distance(its.first, its.second);
219 auto xMin = nbX != 0 ? its.first->x() : 0.;
213 auto xMin = nbX != 0 ? its.first->x() : 0.;
220 auto xMax = nbX != 0 ? (its.second - 1)->x() : 0.;
214 auto xMax = nbX != 0 ? (its.second - 1)->x() : 0.;
221
215
222 auto nbY = yAxis.size();
216 auto nbY = yAxis.size();
223 auto yMin = 0., yMax = 0.;
217 auto yMin = 0., yMax = 0.;
224 if (nbY != 0) {
218 if (nbY != 0) {
225 std::tie(yMin, yMax) = yAxis.bounds();
219 std::tie(yMin, yMax) = yAxis.bounds();
226 }
220 }
227
221
228 colormap->data()->setSize(nbX, nbY);
222 colormap->data()->setSize(nbX, nbY);
229 colormap->data()->setRange(QCPRange{xMin, xMax}, QCPRange{yMin, yMax});
223 colormap->data()->setRange(QCPRange{xMin, xMax}, QCPRange{yMin, yMax});
230
224
231 // Sets values
225 // Sets values
232 auto xIndex = 0;
226 auto xIndex = 0;
233 for (auto it = its.first; it != its.second; ++it, ++xIndex) {
227 for (auto it = its.first; it != its.second; ++it, ++xIndex) {
234 for (auto yIndex = 0; yIndex < nbY; ++yIndex) {
228 for (auto yIndex = 0; yIndex < nbY; ++yIndex) {
235 colormap->data()->setCell(xIndex, yIndex, it->value(yIndex));
229 colormap->data()->setCell(xIndex, yIndex, it->value(yIndex));
236 }
230 }
237 }
231 }
238
232
239 dataSeries.unlock();
233 dataSeries.unlock();
240
234
241 // Rescales axes
235 // Rescales axes
242 auto plot = colormap->parentPlot();
236 auto plot = colormap->parentPlot();
243
237
244 if (rescaleAxes) {
238 if (rescaleAxes) {
245 plot->rescaleAxes();
239 plot->rescaleAxes();
246 }
240 }
247
241
248 plot->replot();
242 plot->replot();
249 }
243 }
250 };
244 };
251
245
252 /**
246 /**
253 * Helper used to create/update plottables
247 * Helper used to create/update plottables
254 */
248 */
255 struct IPlottablesHelper {
249 struct IPlottablesHelper {
256 virtual ~IPlottablesHelper() noexcept = default;
250 virtual ~IPlottablesHelper() noexcept = default;
257 virtual PlottablesMap create(QCustomPlot &plot) const = 0;
251 virtual PlottablesMap create(QCustomPlot &plot) const = 0;
258 virtual void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const = 0;
252 virtual void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const = 0;
259 virtual void update(PlottablesMap &plottables, const SqpRange &range,
253 virtual void update(PlottablesMap &plottables, const SqpRange &range,
260 bool rescaleAxes = false) const = 0;
254 bool rescaleAxes = false) const = 0;
261 };
255 };
262
256
263 /**
257 /**
264 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
258 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
265 * @tparam T the data series' type
259 * @tparam T the data series' type
266 */
260 */
267 template <typename T>
261 template <typename T>
268 struct PlottablesHelper : public IPlottablesHelper {
262 struct PlottablesHelper : public IPlottablesHelper {
269 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
263 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
270
264
271 PlottablesMap create(QCustomPlot &plot) const override
265 PlottablesMap create(QCustomPlot &plot) const override
272 {
266 {
273 return PlottablesCreator<T>::createPlottables(m_DataSeries, plot);
267 return PlottablesCreator<T>::createPlottables(m_DataSeries, plot);
274 }
268 }
275
269
276 void update(PlottablesMap &plottables, const SqpRange &range, bool rescaleAxes) const override
270 void update(PlottablesMap &plottables, const SqpRange &range, bool rescaleAxes) const override
277 {
271 {
278 PlottablesUpdater<T>::updatePlottables(m_DataSeries, plottables, range, rescaleAxes);
272 PlottablesUpdater<T>::updatePlottables(m_DataSeries, plottables, range, rescaleAxes);
279 }
273 }
280
274
281 void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const override
275 void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const override
282 {
276 {
283 return PlottablesUpdater<T>::setPlotYAxisRange(m_DataSeries, xAxisRange, plot);
277 return PlottablesUpdater<T>::setPlotYAxisRange(m_DataSeries, xAxisRange, plot);
284 }
278 }
285
279
286 T &m_DataSeries;
280 T &m_DataSeries;
287 };
281 };
288
282
289 /// Creates IPlottablesHelper according to a data series
283 /// Creates IPlottablesHelper according to a data series
290 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<IDataSeries> dataSeries) noexcept
284 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<IDataSeries> dataSeries) noexcept
291 {
285 {
292 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
286 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
293 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
287 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
294 }
288 }
295 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
289 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
296 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries);
290 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries);
297 }
291 }
298 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
292 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
299 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
293 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
300 }
294 }
301 else {
295 else {
302 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
296 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
303 }
297 }
304 }
298 }
305
299
306 } // namespace
300 } // namespace
307
301
308 PlottablesMap VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
302 PlottablesMap VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
309 QCustomPlot &plot) noexcept
303 QCustomPlot &plot) noexcept
310 {
304 {
311 if (variable) {
305 if (variable) {
312 auto helper = createHelper(variable->dataSeries());
306 auto helper = createHelper(variable->dataSeries());
313 auto plottables = helper->create(plot);
307 auto plottables = helper->create(plot);
314 return plottables;
308 return plottables;
315 }
309 }
316 else {
310 else {
317 qCDebug(LOG_VisualizationGraphHelper())
311 qCDebug(LOG_VisualizationGraphHelper())
318 << QObject::tr("Can't create graph plottables : the variable is null");
312 << QObject::tr("Can't create graph plottables : the variable is null");
319 return PlottablesMap{};
313 return PlottablesMap{};
320 }
314 }
321 }
315 }
322
316
323 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
317 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
324 QCustomPlot &plot) noexcept
318 QCustomPlot &plot) noexcept
325 {
319 {
326 if (variable) {
320 if (variable) {
327 auto helper = createHelper(variable->dataSeries());
321 auto helper = createHelper(variable->dataSeries());
328 helper->setYAxisRange(variable->range(), plot);
322 helper->setYAxisRange(variable->range(), plot);
329 }
323 }
330 else {
324 else {
331 qCDebug(LOG_VisualizationGraphHelper())
325 qCDebug(LOG_VisualizationGraphHelper())
332 << QObject::tr("Can't set y-axis range of plot: the variable is null");
326 << QObject::tr("Can't set y-axis range of plot: the variable is null");
333 }
327 }
334 }
328 }
335
329
336 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
330 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
337 std::shared_ptr<IDataSeries> dataSeries,
331 std::shared_ptr<IDataSeries> dataSeries,
338 const SqpRange &dateTime)
332 const SqpRange &dateTime)
339 {
333 {
340 auto helper = createHelper(dataSeries);
334 auto helper = createHelper(dataSeries);
341 helper->update(plottables, dateTime);
335 helper->update(plottables, dateTime);
342 }
336 }
General Comments 0
You need to be logged in to leave comments. Login now