|
|
|
@ -57,10 +57,16 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), QFrame(parent) |
|
|
|
|
range_slider->setPageStep(60); // 1 min
|
|
|
|
|
range_slider_action = toolbar->addWidget(range_slider); |
|
|
|
|
|
|
|
|
|
undo_zoom_action = toolbar->addAction(utils::icon("arrow-counterclockwise"), tr("Previous zoom")); |
|
|
|
|
qobject_cast<QToolButton*>(toolbar->widgetForAction(undo_zoom_action))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
|
|
|
|
|
|
|
|
|
reset_zoom_action = toolbar->addAction(utils::icon("zoom-out"), tr("Reset Zoom")); |
|
|
|
|
// zoom controls
|
|
|
|
|
zoom_undo_stack = new QUndoStack(this); |
|
|
|
|
undo_zoom_action = zoom_undo_stack->createUndoAction(this); |
|
|
|
|
undo_zoom_action->setIcon(utils::icon("arrow-counterclockwise")); |
|
|
|
|
toolbar->addAction(undo_zoom_action); |
|
|
|
|
redo_zoom_action = zoom_undo_stack->createRedoAction(this); |
|
|
|
|
redo_zoom_action->setIcon(utils::icon("arrow-clockwise")); |
|
|
|
|
toolbar->addAction(redo_zoom_action); |
|
|
|
|
reset_zoom_action = toolbar->addAction(utils::icon("zoom-out"), ""); |
|
|
|
|
reset_zoom_action->setToolTip(tr("Reset zoom")); |
|
|
|
|
qobject_cast<QToolButton*>(toolbar->widgetForAction(reset_zoom_action))->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
|
|
|
|
|
|
|
|
|
remove_all_btn = toolbar->addAction(utils::icon("x"), tr("Remove all charts")); |
|
|
|
@ -99,7 +105,6 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), QFrame(parent) |
|
|
|
|
QObject::connect(range_slider, &QSlider::valueChanged, this, &ChartsWidget::setMaxChartRange); |
|
|
|
|
QObject::connect(new_plot_btn, &QAction::triggered, this, &ChartsWidget::newChart); |
|
|
|
|
QObject::connect(remove_all_btn, &QAction::triggered, this, &ChartsWidget::removeAll); |
|
|
|
|
QObject::connect(undo_zoom_action, &QAction::triggered, this, &ChartsWidget::zoomUndo); |
|
|
|
|
QObject::connect(reset_zoom_action, &QAction::triggered, this, &ChartsWidget::zoomReset); |
|
|
|
|
QObject::connect(&settings, &Settings::changed, this, &ChartsWidget::settingChanged); |
|
|
|
|
QObject::connect(dock_btn, &QAction::triggered, [this]() { |
|
|
|
@ -115,14 +120,9 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), QFrame(parent) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::eventsMerged() { |
|
|
|
|
{ |
|
|
|
|
QFutureSynchronizer<void> future_synchronizer; |
|
|
|
|
for (auto c : charts) { |
|
|
|
|
future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::updateSeries, nullptr)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (can->isPaused()) { |
|
|
|
|
updateState(); |
|
|
|
|
QFutureSynchronizer<void> future_synchronizer; |
|
|
|
|
for (auto c : charts) { |
|
|
|
|
future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::updateSeries, nullptr)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -135,25 +135,12 @@ void ChartsWidget::setZoom(double min, double max) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::zoomIn(double min, double max) { |
|
|
|
|
// Save previous zoom on undo stack
|
|
|
|
|
if (is_zoomed) { |
|
|
|
|
zoom_stack.push({zoomed_range.first, zoomed_range.second}); |
|
|
|
|
} |
|
|
|
|
setZoom(min, max); |
|
|
|
|
zoom_undo_stack->push(new ZoomCommand(this, {min, max})); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::zoomReset() { |
|
|
|
|
setZoom(display_range.first, display_range.second); |
|
|
|
|
zoom_stack.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::zoomUndo() { |
|
|
|
|
if (!zoom_stack.isEmpty()) { |
|
|
|
|
auto r = zoom_stack.pop(); |
|
|
|
|
setZoom(r.first, r.second); |
|
|
|
|
} else { |
|
|
|
|
zoomReset(); |
|
|
|
|
} |
|
|
|
|
zoom_undo_stack->clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::showValueTip(double sec) { |
|
|
|
@ -199,12 +186,13 @@ void ChartsWidget::setMaxChartRange(int value) { |
|
|
|
|
void ChartsWidget::updateToolBar() { |
|
|
|
|
title_label->setText(tr("Charts: %1").arg(charts.size())); |
|
|
|
|
columns_action->setText(tr("Column: %1").arg(column_count)); |
|
|
|
|
range_lb->setText(QString("Range: %1 ").arg(utils::formatSeconds(max_chart_range))); |
|
|
|
|
range_lb->setText(utils::formatSeconds(max_chart_range)); |
|
|
|
|
range_lb_action->setVisible(!is_zoomed); |
|
|
|
|
range_slider_action->setVisible(!is_zoomed); |
|
|
|
|
undo_zoom_action->setVisible(is_zoomed); |
|
|
|
|
redo_zoom_action->setVisible(is_zoomed); |
|
|
|
|
reset_zoom_action->setVisible(is_zoomed); |
|
|
|
|
reset_zoom_action->setText(is_zoomed ? tr("Zoomin: %1-%2").arg(zoomed_range.first, 0, 'f', 1).arg(zoomed_range.second, 0, 'f', 1) : ""); |
|
|
|
|
reset_zoom_action->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 1).arg(zoomed_range.second, 0, 'f', 1) : ""); |
|
|
|
|
remove_all_btn->setEnabled(!charts.isEmpty()); |
|
|
|
|
dock_btn->setIcon(utils::icon(docking ? "arrow-up-right-square" : "arrow-down-left-square")); |
|
|
|
|
dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts")); |
|
|
|
@ -225,20 +213,21 @@ ChartView *ChartsWidget::findChart(const MessageId &id, const cabana::Signal *si |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ChartView *ChartsWidget::createChart() { |
|
|
|
|
auto chart = new ChartView(this); |
|
|
|
|
auto chart = new ChartView(is_zoomed ? zoomed_range : display_range, this); |
|
|
|
|
chart->setFixedHeight(settings.chart_height); |
|
|
|
|
chart->setMinimumWidth(CHART_MIN_WIDTH); |
|
|
|
|
chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); |
|
|
|
|
chart->chart()->setTheme(settings.theme == 2 ? QChart::QChart::ChartThemeDark : QChart::ChartThemeLight); |
|
|
|
|
QObject::connect(chart, &ChartView::remove, [=]() { removeChart(chart); }); |
|
|
|
|
QObject::connect(chart, &ChartView::zoomIn, this, &ChartsWidget::zoomIn); |
|
|
|
|
QObject::connect(chart, &ChartView::zoomUndo, this, &ChartsWidget::zoomUndo); |
|
|
|
|
QObject::connect(chart, &ChartView::zoomUndo, undo_zoom_action, &QAction::trigger); |
|
|
|
|
QObject::connect(chart, &ChartView::seriesRemoved, this, &ChartsWidget::seriesChanged); |
|
|
|
|
QObject::connect(chart, &ChartView::seriesAdded, this, &ChartsWidget::seriesChanged); |
|
|
|
|
QObject::connect(chart, &ChartView::axisYLabelWidthChanged, &align_timer, qOverload<>(&QTimer::start)); |
|
|
|
|
QObject::connect(chart, &ChartView::hovered, this, &ChartsWidget::showValueTip); |
|
|
|
|
charts.push_back(chart); |
|
|
|
|
updateLayout(); |
|
|
|
|
updateToolBar(); |
|
|
|
|
return chart; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -247,11 +236,9 @@ void ChartsWidget::showChart(const MessageId &id, const cabana::Signal *sig, boo |
|
|
|
|
if (show && !chart) { |
|
|
|
|
chart = merge && charts.size() > 0 ? charts.back() : createChart(); |
|
|
|
|
chart->addSeries(id, sig); |
|
|
|
|
updateState(); |
|
|
|
|
} else if (!show && chart) { |
|
|
|
|
chart->removeIf([&](auto &s) { return s.msg_id == id && s.sig == sig; }); |
|
|
|
|
} |
|
|
|
|
updateToolBar(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChartsWidget::setColumnCount(int n) { |
|
|
|
@ -305,8 +292,8 @@ void ChartsWidget::removeChart(ChartView *chart) { |
|
|
|
|
charts.removeOne(chart); |
|
|
|
|
chart->deleteLater(); |
|
|
|
|
updateToolBar(); |
|
|
|
|
alignCharts(); |
|
|
|
|
updateLayout(); |
|
|
|
|
alignCharts(); |
|
|
|
|
emit seriesChanged(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -366,7 +353,7 @@ bool ChartsWidget::event(QEvent *event) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (back_button) { |
|
|
|
|
zoomUndo(); |
|
|
|
|
emit undo_zoom_action->triggered(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return QFrame::event(event); |
|
|
|
@ -374,7 +361,7 @@ bool ChartsWidget::event(QEvent *event) { |
|
|
|
|
|
|
|
|
|
// ChartView
|
|
|
|
|
|
|
|
|
|
ChartView::ChartView(QWidget *parent) : tip_label(this), QChartView(nullptr, parent) { |
|
|
|
|
ChartView::ChartView(const std::pair<double, double> &x_range, QWidget *parent) : tip_label(this), QChartView(nullptr, parent) { |
|
|
|
|
series_type = (SeriesType)settings.chart_series_type; |
|
|
|
|
QChart *chart = new QChart(); |
|
|
|
|
chart->setBackgroundVisible(false); |
|
|
|
@ -386,6 +373,7 @@ ChartView::ChartView(QWidget *parent) : tip_label(this), QChartView(nullptr, par |
|
|
|
|
chart->legend()->setShowToolTips(true); |
|
|
|
|
chart->setMargins({0, 0, 0, 0}); |
|
|
|
|
|
|
|
|
|
axis_x->setRange(x_range.first, x_range.second); |
|
|
|
|
setChart(chart); |
|
|
|
|
|
|
|
|
|
createToolButtons(); |
|
|
|
|