##// END OF EJS Templates
Implements method to get min/max values of a dataseries giving a range (1)
Alexandre Leroux -
r569:368ab9415e5a
parent child
Show More
@@ -1,305 +1,320
1 #ifndef SCIQLOP_DATASERIES_H
1 #ifndef SCIQLOP_DATASERIES_H
2 #define SCIQLOP_DATASERIES_H
2 #define SCIQLOP_DATASERIES_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/SortUtils.h>
6 #include <Common/SortUtils.h>
7
7
8 #include <Data/ArrayData.h>
8 #include <Data/ArrayData.h>
9 #include <Data/IDataSeries.h>
9 #include <Data/IDataSeries.h>
10
10
11 #include <QLoggingCategory>
11 #include <QLoggingCategory>
12 #include <QReadLocker>
12 #include <QReadLocker>
13 #include <QReadWriteLock>
13 #include <QReadWriteLock>
14 #include <memory>
14 #include <memory>
15
15
16 // We don't use the Qt macro since the log is used in the header file, which causes multiple log
16 // We don't use the Qt macro since the log is used in the header file, which causes multiple log
17 // definitions with inheritance. Inline method is used instead
17 // definitions with inheritance. Inline method is used instead
18 inline const QLoggingCategory &LOG_DataSeries()
18 inline const QLoggingCategory &LOG_DataSeries()
19 {
19 {
20 static const QLoggingCategory category{"DataSeries"};
20 static const QLoggingCategory category{"DataSeries"};
21 return category;
21 return category;
22 }
22 }
23
23
24 template <int Dim>
24 template <int Dim>
25 class DataSeries;
25 class DataSeries;
26
26
27 namespace dataseries_detail {
27 namespace dataseries_detail {
28
28
29 template <int Dim>
29 template <int Dim>
30 class IteratorValue : public DataSeriesIteratorValue::Impl {
30 class IteratorValue : public DataSeriesIteratorValue::Impl {
31 public:
31 public:
32 explicit IteratorValue(const DataSeries<Dim> &dataSeries, bool begin)
32 explicit IteratorValue(const DataSeries<Dim> &dataSeries, bool begin)
33 : m_XIt(begin ? dataSeries.xAxisData()->cbegin() : dataSeries.xAxisData()->cend()),
33 : m_XIt(begin ? dataSeries.xAxisData()->cbegin() : dataSeries.xAxisData()->cend()),
34 m_ValuesIt(begin ? dataSeries.valuesData()->cbegin()
34 m_ValuesIt(begin ? dataSeries.valuesData()->cbegin()
35 : dataSeries.valuesData()->cend())
35 : dataSeries.valuesData()->cend())
36 {
36 {
37 }
37 }
38 IteratorValue(const IteratorValue &other) = default;
38 IteratorValue(const IteratorValue &other) = default;
39
39
40 std::unique_ptr<DataSeriesIteratorValue::Impl> clone() const override
40 std::unique_ptr<DataSeriesIteratorValue::Impl> clone() const override
41 {
41 {
42 return std::make_unique<IteratorValue<Dim> >(*this);
42 return std::make_unique<IteratorValue<Dim> >(*this);
43 }
43 }
44
44
45 bool equals(const DataSeriesIteratorValue::Impl &other) const override try {
45 bool equals(const DataSeriesIteratorValue::Impl &other) const override try {
46 const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
46 const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
47 return std::tie(m_XIt, m_ValuesIt) == std::tie(otherImpl.m_XIt, otherImpl.m_ValuesIt);
47 return std::tie(m_XIt, m_ValuesIt) == std::tie(otherImpl.m_XIt, otherImpl.m_ValuesIt);
48 }
48 }
49 catch (const std::bad_cast &) {
49 catch (const std::bad_cast &) {
50 return false;
50 return false;
51 }
51 }
52
52
53 void next() override
53 void next() override
54 {
54 {
55 ++m_XIt;
55 ++m_XIt;
56 ++m_ValuesIt;
56 ++m_ValuesIt;
57 }
57 }
58
58
59 void prev() override
59 void prev() override
60 {
60 {
61 --m_XIt;
61 --m_XIt;
62 --m_ValuesIt;
62 --m_ValuesIt;
63 }
63 }
64
64
65 double x() const override { return m_XIt->at(0); }
65 double x() const override { return m_XIt->at(0); }
66 double value() const override { return m_ValuesIt->at(0); }
66 double value() const override { return m_ValuesIt->at(0); }
67 double value(int componentIndex) const override { return m_ValuesIt->at(componentIndex); }
67 double value(int componentIndex) const override { return m_ValuesIt->at(componentIndex); }
68
68
69 private:
69 private:
70 ArrayData<1>::Iterator m_XIt;
70 ArrayData<1>::Iterator m_XIt;
71 typename ArrayData<Dim>::Iterator m_ValuesIt;
71 typename ArrayData<Dim>::Iterator m_ValuesIt;
72 };
72 };
73 } // namespace dataseries_detail
73 } // namespace dataseries_detail
74
74
75 /**
75 /**
76 * @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
76 * @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
77 *
77 *
78 * It proposes to set a dimension for the values ​​data.
78 * It proposes to set a dimension for the values ​​data.
79 *
79 *
80 * A DataSeries is always sorted on its x-axis data.
80 * A DataSeries is always sorted on its x-axis data.
81 *
81 *
82 * @tparam Dim The dimension of the values data
82 * @tparam Dim The dimension of the values data
83 *
83 *
84 */
84 */
85 template <int Dim>
85 template <int Dim>
86 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
86 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
87 public:
87 public:
88 /// @sa IDataSeries::xAxisData()
88 /// @sa IDataSeries::xAxisData()
89 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
89 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
90 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
90 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
91
91
92 /// @sa IDataSeries::xAxisUnit()
92 /// @sa IDataSeries::xAxisUnit()
93 Unit xAxisUnit() const override { return m_XAxisUnit; }
93 Unit xAxisUnit() const override { return m_XAxisUnit; }
94
94
95 /// @return the values dataset
95 /// @return the values dataset
96 std::shared_ptr<ArrayData<Dim> > valuesData() { return m_ValuesData; }
96 std::shared_ptr<ArrayData<Dim> > valuesData() { return m_ValuesData; }
97 const std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
97 const std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
98
98
99 /// @sa IDataSeries::valuesUnit()
99 /// @sa IDataSeries::valuesUnit()
100 Unit valuesUnit() const override { return m_ValuesUnit; }
100 Unit valuesUnit() const override { return m_ValuesUnit; }
101
101
102
102
103 SqpRange range() const override
103 SqpRange range() const override
104 {
104 {
105 if (!m_XAxisData->cdata().isEmpty()) {
105 if (!m_XAxisData->cdata().isEmpty()) {
106 return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
106 return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
107 }
107 }
108
108
109 return SqpRange{};
109 return SqpRange{};
110 }
110 }
111
111
112 void clear()
112 void clear()
113 {
113 {
114 m_XAxisData->clear();
114 m_XAxisData->clear();
115 m_ValuesData->clear();
115 m_ValuesData->clear();
116 }
116 }
117
117
118 /// Merges into the data series an other data series
118 /// Merges into the data series an other data series
119 /// @remarks the data series to merge with is cleared after the operation
119 /// @remarks the data series to merge with is cleared after the operation
120 void merge(IDataSeries *dataSeries) override
120 void merge(IDataSeries *dataSeries) override
121 {
121 {
122 dataSeries->lockWrite();
122 dataSeries->lockWrite();
123 lockWrite();
123 lockWrite();
124
124
125 if (auto other = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
125 if (auto other = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
126 const auto &otherXAxisData = other->xAxisData()->cdata();
126 const auto &otherXAxisData = other->xAxisData()->cdata();
127 const auto &xAxisData = m_XAxisData->cdata();
127 const auto &xAxisData = m_XAxisData->cdata();
128
128
129 // As data series are sorted, we can improve performances of merge, by call the sort
129 // As data series are sorted, we can improve performances of merge, by call the sort
130 // method only if the two data series overlap.
130 // method only if the two data series overlap.
131 if (!otherXAxisData.empty()) {
131 if (!otherXAxisData.empty()) {
132 auto firstValue = otherXAxisData.front();
132 auto firstValue = otherXAxisData.front();
133 auto lastValue = otherXAxisData.back();
133 auto lastValue = otherXAxisData.back();
134
134
135 auto xAxisDataBegin = xAxisData.cbegin();
135 auto xAxisDataBegin = xAxisData.cbegin();
136 auto xAxisDataEnd = xAxisData.cend();
136 auto xAxisDataEnd = xAxisData.cend();
137
137
138 bool prepend;
138 bool prepend;
139 bool sortNeeded;
139 bool sortNeeded;
140
140
141 if (std::lower_bound(xAxisDataBegin, xAxisDataEnd, firstValue) == xAxisDataEnd) {
141 if (std::lower_bound(xAxisDataBegin, xAxisDataEnd, firstValue) == xAxisDataEnd) {
142 // Other data series if after data series
142 // Other data series if after data series
143 prepend = false;
143 prepend = false;
144 sortNeeded = false;
144 sortNeeded = false;
145 }
145 }
146 else if (std::upper_bound(xAxisDataBegin, xAxisDataEnd, lastValue)
146 else if (std::upper_bound(xAxisDataBegin, xAxisDataEnd, lastValue)
147 == xAxisDataBegin) {
147 == xAxisDataBegin) {
148 // Other data series if before data series
148 // Other data series if before data series
149 prepend = true;
149 prepend = true;
150 sortNeeded = false;
150 sortNeeded = false;
151 }
151 }
152 else {
152 else {
153 // The two data series overlap
153 // The two data series overlap
154 prepend = false;
154 prepend = false;
155 sortNeeded = true;
155 sortNeeded = true;
156 }
156 }
157
157
158 // Makes the merge
158 // Makes the merge
159 m_XAxisData->add(*other->xAxisData(), prepend);
159 m_XAxisData->add(*other->xAxisData(), prepend);
160 m_ValuesData->add(*other->valuesData(), prepend);
160 m_ValuesData->add(*other->valuesData(), prepend);
161
161
162 if (sortNeeded) {
162 if (sortNeeded) {
163 sort();
163 sort();
164 }
164 }
165 }
165 }
166
166
167 // Clears the other data series
167 // Clears the other data series
168 other->clear();
168 other->clear();
169 }
169 }
170 else {
170 else {
171 qCWarning(LOG_DataSeries())
171 qCWarning(LOG_DataSeries())
172 << QObject::tr("Detection of a type of IDataSeries we cannot merge with !");
172 << QObject::tr("Detection of a type of IDataSeries we cannot merge with !");
173 }
173 }
174 unlock();
174 unlock();
175 dataSeries->unlock();
175 dataSeries->unlock();
176 }
176 }
177
177
178 // ///////// //
178 // ///////// //
179 // Iterators //
179 // Iterators //
180 // ///////// //
180 // ///////// //
181
181
182 DataSeriesIterator cbegin() const override
182 DataSeriesIterator cbegin() const override
183 {
183 {
184 return DataSeriesIterator{DataSeriesIteratorValue{
184 return DataSeriesIterator{DataSeriesIteratorValue{
185 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, true)}};
185 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, true)}};
186 }
186 }
187
187
188 DataSeriesIterator cend() const override
188 DataSeriesIterator cend() const override
189 {
189 {
190 return DataSeriesIterator{DataSeriesIteratorValue{
190 return DataSeriesIterator{DataSeriesIteratorValue{
191 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, false)}};
191 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, false)}};
192 }
192 }
193
193
194 /// @sa IDataSeries::minXAxisData()
194 /// @sa IDataSeries::minXAxisData()
195 DataSeriesIterator minXAxisData(double minXAxisData) const override
195 DataSeriesIterator minXAxisData(double minXAxisData) const override
196 {
196 {
197 return std::lower_bound(
197 return std::lower_bound(
198 cbegin(), cend(), minXAxisData,
198 cbegin(), cend(), minXAxisData,
199 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
199 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
200 }
200 }
201
201
202 /// @sa IDataSeries::maxXAxisData()
202 /// @sa IDataSeries::maxXAxisData()
203 DataSeriesIterator maxXAxisData(double maxXAxisData) const override
203 DataSeriesIterator maxXAxisData(double maxXAxisData) const override
204 {
204 {
205 // Gets the first element that greater than max value
205 // Gets the first element that greater than max value
206 auto it = std::upper_bound(
206 auto it = std::upper_bound(
207 cbegin(), cend(), maxXAxisData,
207 cbegin(), cend(), maxXAxisData,
208 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
208 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
209
209
210 return it == cbegin() ? cend() : --it;
210 return it == cbegin() ? cend() : --it;
211 }
211 }
212
212
213 std::pair<DataSeriesIterator, DataSeriesIterator> xAxisRange(double minXAxisData,
213 std::pair<DataSeriesIterator, DataSeriesIterator> xAxisRange(double minXAxisData,
214 double maxXAxisData) const override
214 double maxXAxisData) const override
215 {
215 {
216 if (minXAxisData > maxXAxisData) {
216 if (minXAxisData > maxXAxisData) {
217 std::swap(minXAxisData, maxXAxisData);
217 std::swap(minXAxisData, maxXAxisData);
218 }
218 }
219
219
220 auto begin = cbegin();
220 auto begin = cbegin();
221 auto end = cend();
221 auto end = cend();
222
222
223 auto lowerIt = std::lower_bound(
223 auto lowerIt = std::lower_bound(
224 begin, end, minXAxisData,
224 begin, end, minXAxisData,
225 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
225 [](const auto &itValue, const auto &value) { return itValue.x() < value; });
226 auto upperIt = std::upper_bound(
226 auto upperIt = std::upper_bound(
227 begin, end, maxXAxisData,
227 begin, end, maxXAxisData,
228 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
228 [](const auto &value, const auto &itValue) { return value < itValue.x(); });
229
229
230 return std::make_pair(lowerIt, upperIt);
230 return std::make_pair(lowerIt, upperIt);
231 }
231 }
232
232
233 std::pair<DataSeriesIterator, DataSeriesIterator>
234 valuesBounds(double minXAxisData, double maxXAxisData) const override
235 {
236 // Places iterators to the correct x-axis range
237 auto xAxisRangeIts = xAxisRange(minXAxisData, maxXAxisData);
238
239 // Returns end iterators if the range is empty
240 if (xAxisRangeIts.first == xAxisRangeIts.second) {
241 return std::make_pair(cend(), cend());
242 }
243
244 /// @todo ALX: complete
245
246 }
247
233 // /////// //
248 // /////// //
234 // Mutexes //
249 // Mutexes //
235 // /////// //
250 // /////// //
236
251
237 virtual void lockRead() { m_Lock.lockForRead(); }
252 virtual void lockRead() { m_Lock.lockForRead(); }
238 virtual void lockWrite() { m_Lock.lockForWrite(); }
253 virtual void lockWrite() { m_Lock.lockForWrite(); }
239 virtual void unlock() { m_Lock.unlock(); }
254 virtual void unlock() { m_Lock.unlock(); }
240
255
241 protected:
256 protected:
242 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
257 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
243 /// DataSeries with no values will be created.
258 /// DataSeries with no values will be created.
244 /// @remarks data series is automatically sorted on its x-axis data
259 /// @remarks data series is automatically sorted on its x-axis data
245 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
260 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
246 std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit)
261 std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit)
247 : m_XAxisData{xAxisData},
262 : m_XAxisData{xAxisData},
248 m_XAxisUnit{xAxisUnit},
263 m_XAxisUnit{xAxisUnit},
249 m_ValuesData{valuesData},
264 m_ValuesData{valuesData},
250 m_ValuesUnit{valuesUnit}
265 m_ValuesUnit{valuesUnit}
251 {
266 {
252 if (m_XAxisData->size() != m_ValuesData->size()) {
267 if (m_XAxisData->size() != m_ValuesData->size()) {
253 clear();
268 clear();
254 }
269 }
255
270
256 // Sorts data if it's not the case
271 // Sorts data if it's not the case
257 const auto &xAxisCData = m_XAxisData->cdata();
272 const auto &xAxisCData = m_XAxisData->cdata();
258 if (!std::is_sorted(xAxisCData.cbegin(), xAxisCData.cend())) {
273 if (!std::is_sorted(xAxisCData.cbegin(), xAxisCData.cend())) {
259 sort();
274 sort();
260 }
275 }
261 }
276 }
262
277
263 /// Copy ctor
278 /// Copy ctor
264 explicit DataSeries(const DataSeries<Dim> &other)
279 explicit DataSeries(const DataSeries<Dim> &other)
265 : m_XAxisData{std::make_shared<ArrayData<1> >(*other.m_XAxisData)},
280 : m_XAxisData{std::make_shared<ArrayData<1> >(*other.m_XAxisData)},
266 m_XAxisUnit{other.m_XAxisUnit},
281 m_XAxisUnit{other.m_XAxisUnit},
267 m_ValuesData{std::make_shared<ArrayData<Dim> >(*other.m_ValuesData)},
282 m_ValuesData{std::make_shared<ArrayData<Dim> >(*other.m_ValuesData)},
268 m_ValuesUnit{other.m_ValuesUnit}
283 m_ValuesUnit{other.m_ValuesUnit}
269 {
284 {
270 // Since a series is ordered from its construction and is always ordered, it is not
285 // Since a series is ordered from its construction and is always ordered, it is not
271 // necessary to call the sort method here ('other' is sorted)
286 // necessary to call the sort method here ('other' is sorted)
272 }
287 }
273
288
274 /// Assignment operator
289 /// Assignment operator
275 template <int D>
290 template <int D>
276 DataSeries &operator=(DataSeries<D> other)
291 DataSeries &operator=(DataSeries<D> other)
277 {
292 {
278 std::swap(m_XAxisData, other.m_XAxisData);
293 std::swap(m_XAxisData, other.m_XAxisData);
279 std::swap(m_XAxisUnit, other.m_XAxisUnit);
294 std::swap(m_XAxisUnit, other.m_XAxisUnit);
280 std::swap(m_ValuesData, other.m_ValuesData);
295 std::swap(m_ValuesData, other.m_ValuesData);
281 std::swap(m_ValuesUnit, other.m_ValuesUnit);
296 std::swap(m_ValuesUnit, other.m_ValuesUnit);
282
297
283 return *this;
298 return *this;
284 }
299 }
285
300
286 private:
301 private:
287 /**
302 /**
288 * Sorts data series on its x-axis data
303 * Sorts data series on its x-axis data
289 */
304 */
290 void sort() noexcept
305 void sort() noexcept
291 {
306 {
292 auto permutation = SortUtils::sortPermutation(*m_XAxisData, std::less<double>());
307 auto permutation = SortUtils::sortPermutation(*m_XAxisData, std::less<double>());
293 m_XAxisData = m_XAxisData->sort(permutation);
308 m_XAxisData = m_XAxisData->sort(permutation);
294 m_ValuesData = m_ValuesData->sort(permutation);
309 m_ValuesData = m_ValuesData->sort(permutation);
295 }
310 }
296
311
297 std::shared_ptr<ArrayData<1> > m_XAxisData;
312 std::shared_ptr<ArrayData<1> > m_XAxisData;
298 Unit m_XAxisUnit;
313 Unit m_XAxisUnit;
299 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
314 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
300 Unit m_ValuesUnit;
315 Unit m_ValuesUnit;
301
316
302 QReadWriteLock m_Lock;
317 QReadWriteLock m_Lock;
303 };
318 };
304
319
305 #endif // SCIQLOP_DATASERIES_H
320 #endif // SCIQLOP_DATASERIES_H
@@ -1,98 +1,104
1 #ifndef SCIQLOP_IDATASERIES_H
1 #ifndef SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
3
3
4 #include <Common/MetaTypes.h>
4 #include <Common/MetaTypes.h>
5 #include <Data/DataSeriesIterator.h>
5 #include <Data/DataSeriesIterator.h>
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <memory>
8 #include <memory>
9
9
10 #include <QString>
10 #include <QString>
11
11
12 template <int Dim>
12 template <int Dim>
13 class ArrayData;
13 class ArrayData;
14
14
15 struct Unit {
15 struct Unit {
16 explicit Unit(const QString &name = {}, bool timeUnit = false)
16 explicit Unit(const QString &name = {}, bool timeUnit = false)
17 : m_Name{name}, m_TimeUnit{timeUnit}
17 : m_Name{name}, m_TimeUnit{timeUnit}
18 {
18 {
19 }
19 }
20
20
21 inline bool operator==(const Unit &other) const
21 inline bool operator==(const Unit &other) const
22 {
22 {
23 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
23 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
24 }
24 }
25 inline bool operator!=(const Unit &other) const { return !(*this == other); }
25 inline bool operator!=(const Unit &other) const { return !(*this == other); }
26
26
27 QString m_Name; ///< Unit name
27 QString m_Name; ///< Unit name
28 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
28 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
29 };
29 };
30
30
31 /**
31 /**
32 * @brief The IDataSeries aims to declare a data series.
32 * @brief The IDataSeries aims to declare a data series.
33 *
33 *
34 * A data series is an entity that contains at least :
34 * A data series is an entity that contains at least :
35 * - one dataset representing the x-axis
35 * - one dataset representing the x-axis
36 * - one dataset representing the values
36 * - one dataset representing the values
37 *
37 *
38 * Each dataset is represented by an ArrayData, and is associated with a unit.
38 * Each dataset is represented by an ArrayData, and is associated with a unit.
39 *
39 *
40 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
40 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
41 * IDataSeries. The x-axis dataset is always unidimensional.
41 * IDataSeries. The x-axis dataset is always unidimensional.
42 *
42 *
43 * @sa ArrayData
43 * @sa ArrayData
44 */
44 */
45 class IDataSeries {
45 class IDataSeries {
46 public:
46 public:
47 virtual ~IDataSeries() noexcept = default;
47 virtual ~IDataSeries() noexcept = default;
48
48
49 /// Returns the x-axis dataset
49 /// Returns the x-axis dataset
50 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
50 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
51
51
52 /// Returns the x-axis dataset (as const)
52 /// Returns the x-axis dataset (as const)
53 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
53 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
54
54
55 virtual Unit xAxisUnit() const = 0;
55 virtual Unit xAxisUnit() const = 0;
56
56
57 virtual Unit valuesUnit() const = 0;
57 virtual Unit valuesUnit() const = 0;
58
58
59 virtual void merge(IDataSeries *dataSeries) = 0;
59 virtual void merge(IDataSeries *dataSeries) = 0;
60 /// @todo Review the name and signature of this method
60 /// @todo Review the name and signature of this method
61 virtual std::shared_ptr<IDataSeries> subDataSeries(const SqpRange &range) = 0;
61 virtual std::shared_ptr<IDataSeries> subDataSeries(const SqpRange &range) = 0;
62
62
63 virtual std::unique_ptr<IDataSeries> clone() const = 0;
63 virtual std::unique_ptr<IDataSeries> clone() const = 0;
64 virtual SqpRange range() const = 0;
64 virtual SqpRange range() const = 0;
65
65
66 // ///////// //
66 // ///////// //
67 // Iterators //
67 // Iterators //
68 // ///////// //
68 // ///////// //
69
69
70 virtual DataSeriesIterator cbegin() const = 0;
70 virtual DataSeriesIterator cbegin() const = 0;
71 virtual DataSeriesIterator cend() const = 0;
71 virtual DataSeriesIterator cend() const = 0;
72
72
73 /// @return the iterator to the first entry of the data series whose x-axis data is greater than
73 /// @return the iterator to the first entry of the data series whose x-axis data is greater than
74 /// or equal to the value passed in parameter, or the end iterator if there is no matching value
74 /// or equal to the value passed in parameter, or the end iterator if there is no matching value
75 virtual DataSeriesIterator minXAxisData(double minXAxisData) const = 0;
75 virtual DataSeriesIterator minXAxisData(double minXAxisData) const = 0;
76
76
77 /// @return the iterator to the last entry of the data series whose x-axis data is less than or
77 /// @return the iterator to the last entry of the data series whose x-axis data is less than or
78 /// equal to the value passed in parameter, or the end iterator if there is no matching value
78 /// equal to the value passed in parameter, or the end iterator if there is no matching value
79 virtual DataSeriesIterator maxXAxisData(double maxXAxisData) const = 0;
79 virtual DataSeriesIterator maxXAxisData(double maxXAxisData) const = 0;
80
80
81 /// @return the iterators pointing to the range of data whose x-axis values are between min and
81 /// @return the iterators pointing to the range of data whose x-axis values are between min and
82 /// max passed in parameters
82 /// max passed in parameters
83 virtual std::pair<DataSeriesIterator, DataSeriesIterator>
83 virtual std::pair<DataSeriesIterator, DataSeriesIterator>
84 xAxisRange(double minXAxisData, double maxXAxisData) const = 0;
84 xAxisRange(double minXAxisData, double maxXAxisData) const = 0;
85
85
86 /// @return two iterators pointing to the data that have respectively the min and the max value
87 /// data of a data series' range. The search is performed for a given x-axis range.
88 /// @sa xAxisRange()
89 virtual std::pair<DataSeriesIterator, DataSeriesIterator>
90 valuesBounds(double minXAxisData, double maxXAxisData) const = 0;
91
86 // /////// //
92 // /////// //
87 // Mutexes //
93 // Mutexes //
88 // /////// //
94 // /////// //
89
95
90 virtual void lockRead() = 0;
96 virtual void lockRead() = 0;
91 virtual void lockWrite() = 0;
97 virtual void lockWrite() = 0;
92 virtual void unlock() = 0;
98 virtual void unlock() = 0;
93 };
99 };
94
100
95 // Required for using shared_ptr in signals/slots
101 // Required for using shared_ptr in signals/slots
96 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
102 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
97
103
98 #endif // SCIQLOP_IDATASERIES_H
104 #endif // SCIQLOP_IDATASERIES_H
General Comments 0
You need to be logged in to leave comments. Login now