|
|
|
@ -194,8 +194,6 @@ ChartWidget::ChartWidget(const QString &id, const QString &sig_name, QWidget *pa |
|
|
|
|
void ChartWidget::updateState() { |
|
|
|
|
auto chart = chart_view->chart(); |
|
|
|
|
auto axis_x = dynamic_cast<QValueAxis *>(chart->axisX()); |
|
|
|
|
if (axis_x->max() <= axis_x->min()) return; |
|
|
|
|
|
|
|
|
|
int x = chart->plotArea().left() + chart->plotArea().width() * (parser->currentSec() - axis_x->min()) / (axis_x->max() - axis_x->min()); |
|
|
|
|
if (line_marker_x != x) { |
|
|
|
|
line_marker->setX(x); |
|
|
|
@ -214,7 +212,6 @@ void ChartWidget::updateSeries() { |
|
|
|
|
|
|
|
|
|
vals.clear(); |
|
|
|
|
vals.reserve(3 * 60 * 100); |
|
|
|
|
double min_y = 0, max_y = 0; |
|
|
|
|
uint64_t route_start_time = parser->replay->routeStartTime(); |
|
|
|
|
for (auto &evt : *events) { |
|
|
|
|
if (evt->which == cereal::Event::Which::CAN) { |
|
|
|
@ -226,9 +223,6 @@ void ChartWidget::updateSeries() { |
|
|
|
|
val -= ((val >> (sig->size - 1)) & 0x1) ? (1ULL << sig->size) : 0; |
|
|
|
|
} |
|
|
|
|
double value = val * sig->factor + sig->offset; |
|
|
|
|
if (value < min_y) min_y = value; |
|
|
|
|
if (value > max_y) max_y = value; |
|
|
|
|
|
|
|
|
|
double ts = (evt->mono_time - route_start_time) / (double)1e9; // seconds
|
|
|
|
|
vals.push_back({ts, value}); |
|
|
|
|
} |
|
|
|
@ -239,7 +233,7 @@ void ChartWidget::updateSeries() { |
|
|
|
|
series->replace(vals); |
|
|
|
|
auto [begin, end] = parser->range(); |
|
|
|
|
chart_view->chart()->axisX()->setRange(begin, end); |
|
|
|
|
chart_view->chart()->axisY()->setRange(min_y * 0.95, max_y * 1.05); |
|
|
|
|
updateAxisY(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartWidget::rangeChanged(qreal min, qreal max) { |
|
|
|
@ -247,17 +241,20 @@ void ChartWidget::rangeChanged(qreal min, qreal max) { |
|
|
|
|
if (axis_x->min() != min || axis_x->max() != max) { |
|
|
|
|
axis_x->setRange(min, max); |
|
|
|
|
} |
|
|
|
|
// auto zoom on yaxis
|
|
|
|
|
double min_y = 0, max_y = 0; |
|
|
|
|
for (auto &p : vals) { |
|
|
|
|
if (p.x() > max) break; |
|
|
|
|
|
|
|
|
|
if (p.x() >= min) { |
|
|
|
|
if (p.y() < min_y) min_y = p.y(); |
|
|
|
|
if (p.y() > max_y) max_y = p.y(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
chart_view->chart()->axisY()->setRange(min_y * 0.95, max_y * 1.05); |
|
|
|
|
updateAxisY(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// auto zoom on yaxis
|
|
|
|
|
void ChartWidget::updateAxisY() { |
|
|
|
|
const auto axis_x = dynamic_cast<QValueAxis *>(chart_view->chart()->axisX()); |
|
|
|
|
// vals is a sorted list
|
|
|
|
|
auto begin = std::lower_bound(vals.begin(), vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; }); |
|
|
|
|
if (begin == vals.end()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
auto end = std::upper_bound(vals.begin(), vals.end(), axis_x->max(), [](double x, auto &p) { return x < p.x(); }); |
|
|
|
|
const auto [min, max] = std::minmax_element(begin, end, [](auto &p1, auto &p2) { return p1.y() < p2.y(); }); |
|
|
|
|
chart_view->chart()->axisY()->setRange(min->y(), max->y()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// LineMarker
|
|
|
|
|