You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.9 KiB
54 lines
1.9 KiB
#include "tools/cabana/chart/sparkline.h"
|
|
|
|
#include <algorithm>
|
|
#include <limits>
|
|
#include <QPainter>
|
|
|
|
void Sparkline::update(const MessageId &msg_id, const cabana::Signal *sig, double last_msg_ts, int range, QSize size) {
|
|
points.clear();
|
|
double value = 0;
|
|
auto [first, last] = can->eventsInRange(msg_id, std::make_pair(last_msg_ts -range, last_msg_ts));
|
|
for (auto it = first; it != last; ++it) {
|
|
if (sig->getValue((*it)->dat, (*it)->size, &value)) {
|
|
points.emplace_back(((*it)->mono_time - (*first)->mono_time) / 1e9, value);
|
|
}
|
|
}
|
|
|
|
if (points.empty() || size.isEmpty()) {
|
|
pixmap = QPixmap();
|
|
return;
|
|
}
|
|
|
|
const auto [min, max] = std::minmax_element(points.begin(), points.end(),
|
|
[](auto &l, auto &r) { return l.y() < r.y(); });
|
|
min_val = min->y() == max->y() ? min->y() - 1 : min->y();
|
|
max_val = min->y() == max->y() ? max->y() + 1 : max->y();
|
|
freq_ = points.size() / std::max(points.back().x() - points.front().x(), 1.0);
|
|
render(sig->color, range, size);
|
|
}
|
|
|
|
void Sparkline::render(const QColor &color, int range, QSize size) {
|
|
const double xscale = (size.width() - 1) / (double)range;
|
|
const double yscale = (size.height() - 3) / (max_val - min_val);
|
|
for (auto &v : points) {
|
|
v = QPoint(v.x() * xscale, 1 + std::abs(v.y() - max_val) * yscale);
|
|
}
|
|
|
|
qreal dpr = qApp->devicePixelRatio();
|
|
size *= dpr;
|
|
if (size != pixmap.size()) {
|
|
pixmap = QPixmap(size);
|
|
}
|
|
pixmap.setDevicePixelRatio(dpr);
|
|
pixmap.fill(Qt::transparent);
|
|
QPainter painter(&pixmap);
|
|
painter.setRenderHint(QPainter::Antialiasing, points.size() < 500);
|
|
painter.setPen(color);
|
|
painter.drawPolyline(points.data(), points.size());
|
|
painter.setPen(QPen(color, 3));
|
|
if ((points.back().x() - points.front().x()) / points.size() > 8) {
|
|
painter.drawPoints(points.data(), points.size());
|
|
} else {
|
|
painter.drawPoint(points.back());
|
|
}
|
|
}
|
|
|