14 #include <type_traits> 17 #include <unordered_map> 30 template <
typename Value>
48 MAX_CAPACITY = 1024 * 1024,
49 ASYNC_BUFFER_CAPACITY = 1024
56 typedef typename std::deque<Point>::iterator
Iterator;
61 _color_hint(Qt::black),
87 const std::string&
name()
const 92 virtual size_t size()
const 94 return _points.size();
97 const Point&
at(
size_t index)
const 99 return _points[index];
102 Point&
at(
size_t index)
104 return _points[index];
120 _range_x_dirty =
true;
121 _range_y_dirty =
true;
136 return _points.front();
141 return _points.back();
146 return _points.begin();
151 return _points.end();
156 return _points.begin();
161 return _points.end();
166 if( _points.empty() ){
171 _range_x.min = front().x;
172 _range_x.max = _range_x.min;
173 for(
const auto& p: _points)
175 _range_x.min =
std::min(_range_x.min, p.x);
176 _range_x.max =
std::max(_range_x.max, p.x);
178 _range_x_dirty =
false;
185 if( _points.empty() ){
190 _range_y.min = front().y;
191 _range_y.max = _range_y.min;
192 for(
const auto& p: _points)
194 _range_y.min =
std::min(_range_y.min, p.y);
195 _range_y.max =
std::max(_range_y.max, p.y);
197 _range_y_dirty =
false;
210 if( _points.empty() )
212 _range_x_dirty =
false;
219 if( !_range_x_dirty )
221 if( p.x > _range_x.max ){
224 else if( p.x < _range_x.min ){
228 _range_x_dirty =
true;
232 if( !_range_y_dirty )
234 if( p.y > _range_y.max ){
237 else if( p.y < _range_y.min ){
241 _range_y_dirty =
true;
244 _points.emplace_back(p);
249 const auto& p = _points.front();
251 if( !_range_x_dirty && (p.x == _range_x.max || p.x == _range_x.min) )
253 _range_x_dirty =
true;
255 if( !_range_y_dirty && (p.y == _range_y.max || p.y == _range_y.min) )
257 _range_y_dirty =
true;
277 template <
typename Value>
294 _max_range_x(
std::numeric_limits<double>::
max() )
296 _range_x_dirty =
false;
301 _max_range_x = max_range;
310 int getIndexFromX(
double x)
const;
316 const auto& p = _points.front();
318 if( !_range_y_dirty && (p.y == _range_y.max || p.y == _range_y.min) )
320 _range_y_dirty =
true;
324 if( !_points.empty() )
326 _range_x.min = _points.front().x;
342 bool need_sorting =
false;
344 if( _points.empty() )
346 _range_x_dirty =
false;
354 if( p.x < this->back().x ){
360 auto it = std::upper_bound(_points.begin(), _points.end(), p,
361 [](
const Point& a,
const Point& b) {
return a.x < b.x; });
363 _points.insert(it, p);
366 _points.emplace_back(p);
371 if( !_range_y_dirty )
373 if( p.y > _range_y.max ){
376 else if( p.y < _range_y.min ){
380 _range_y_dirty =
true;
389 if( _points.empty() ){
394 _range_x.min = _points.front().x;
395 _range_x.max = _points.back().x;
396 _range_x_dirty =
false;
404 while (_points.size() > 2 && (_points.back().x - _points.front().x) > _max_range_x)
418 if( !_points.empty() )
420 _range_x.min = _points.front().x;
427 const auto& p = _points.front();
428 if( !_range_x_dirty && (p.x == _range_x.max || p.x == _range_x.min) )
430 _range_x_dirty =
true;
444 if( _points.empty() )
446 _range_x_dirty =
false;
450 if( !_range_x_dirty )
452 if( p.x > _range_x.max ){
455 else if( p.x < _range_x.min ){
459 _range_x_dirty =
true;
462 _points.emplace_back(p);
468 if( _points.empty() )
470 _range_x_dirty =
false;
475 if( p.x < this->back().x ){
476 _range_x_dirty =
true;
478 if( !_range_x_dirty ){
483 _points.emplace_back(p);
495 std::unordered_map<std::string, PlotData>
numeric;
498 std::unordered_map<std::string, PlotData>::iterator
addNumeric(
const std::string& name)
500 return numeric.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(name)).first;
503 std::unordered_map<std::string, PlotDataAny>::iterator
addUserDefined(
const std::string& name)
505 return user_defined.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(name))
512 template <
typename Value>
514 std::unordered_map<std::string, Value>&
data)
520 std::unordered_map<std::string, Value> temp;
522 for (
auto& it : data)
525 key.reserve(prefix.size() + 2 + it.first.size());
526 if (it.first.front() ==
'/')
528 key = prefix + it.first;
532 key = prefix +
"/" + it.first;
536 temp.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(key)).first;
538 new_plot->second.swapData(it.second);
544 template <
typename Value>
547 if (_points.size() == 0)
551 auto lower = std::lower_bound(_points.begin(), _points.end(),
Point(x, 0),
552 [](
const Point& a,
const Point& b) {
return a.x < b.x; });
553 auto index = std::distance(_points.begin(),
lower);
555 if (index >= _points.size())
557 return _points.size() - 1;
566 if (std::abs(_points[index - 1].x - x) < std::abs(_points[index].x - x))
578 template <
typename Value>
581 int index = getIndexFromX(x);
586 return _points.at(index).y;
const Point & back() const
RangeOpt rangeX() const override
const Point & at(size_t index) const
const Point & front() const
TimeseriesBase(const std::string &name)
nonstd::optional< Range > RangeOpt
std::unordered_map< std::string, PlotData > numeric
std::deque< Point > _points
void swapData(PlotDataBase &other)
void setColorHint(QColor color)
std::deque< Point >::iterator Iterator
ConstIterator end() const
std::unordered_map< std::string, PlotDataAny >::iterator addUserDefined(const std::string &name)
Point(double _x, Value _y)
double maximumRangeX() const
ConstIterator begin() const
QColor getColorHint() const
PlotDataBase(const std::string &name)
nonstd::optional< Value > getYfromX(double x) const
int getIndexFromX(double x) const
void pushBack(Point &&p) override
void setMaximumRangeX(double max_range)
Point & operator[](size_t index)
virtual size_t size() const
const Point & operator[](size_t index) const
const T & move(const T &v)
const std::string & name() const
std::unordered_map< std::string, PlotDataAny > user_defined
void pushBack(const Point &p)
virtual RangeOpt rangeX() const
PlotDataBase(PlotDataBase &&other)
void AddPrefixToPlotData(const std::string &prefix, std::unordered_map< std::string, Value > &data)
std::unordered_map< std::string, PlotData >::iterator addNumeric(const std::string &name)
void pushBack(const Point &p)
std::deque< Point >::const_iterator ConstIterator
virtual void pushBack(Point &&p)
const nullopt_t nullopt((nullopt_t::init()))
typename PlotDataBase< Value >::Point Point