diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 3e1a8b8410..5caa8d5a43 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -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(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(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 diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 0413d65e09..81df2237bc 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -37,6 +37,7 @@ private: void addData(const CanData &can_data, const Signal &sig); void updateSeries(); void rangeChanged(qreal min, qreal max); + void updateAxisY(); QString id; QString sig_name;