cabana: add support for multiple columns charts (#27000)

pull/26946/head^2
Dean Lee 2 years ago committed by GitHub
parent 9131da9103
commit fd4dc109e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 68
      tools/cabana/chartswidget.cc
  2. 14
      tools/cabana/chartswidget.h
  3. 2
      tools/cabana/settings.cc
  4. 1
      tools/cabana/settings.h

@ -22,9 +22,19 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
// toolbar
QToolBar *toolbar = new QToolBar(tr("Charts"), this);
toolbar->setIconSize({16, 16});
title_label = new QLabel();
title_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolbar->addWidget(title_label);
toolbar->addWidget(title_label = new QLabel());
title_label->setContentsMargins(0 ,0, 12, 0);
columns_cb = new QComboBox(this);
columns_cb->addItems({"1", "2", "3", "4"});
columns_cb->setCurrentIndex(std::clamp(settings.chart_column_count - 1, 0, 3));
toolbar->addWidget(new QLabel(tr("Columns:")));
toolbar->addWidget(columns_cb);
QLabel *stretch_label = new QLabel(this);
stretch_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolbar->addWidget(stretch_label);
show_all_values_btn = toolbar->addAction("");
toolbar->addWidget(range_label = new QLabel());
reset_zoom_btn = toolbar->addAction(bootstrapPixmap("arrow-counterclockwise"), "");
@ -36,8 +46,11 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
// charts
QWidget *charts_container = new QWidget(this);
charts_layout = new QVBoxLayout(charts_container);
charts_layout->addStretch();
QVBoxLayout *charts_main_layout = new QVBoxLayout(charts_container);
charts_main_layout->setContentsMargins(0, 0, 0, 0);
charts_layout = new QGridLayout(charts_container);
charts_main_layout->addLayout(charts_layout);
charts_main_layout->addStretch(0);
QScrollArea *charts_scroll = new QScrollArea(this);
charts_scroll->setWidgetResizable(true);
@ -53,6 +66,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
align_charts_timer = new QTimer(this);
align_charts_timer->setSingleShot(true);
align_charts_timer->callOnTimeout(this, &ChartsWidget::alignCharts);
column_count = settings.chart_column_count;
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll);
QObject::connect(can, &CANMessages::eventsMerged, this, &ChartsWidget::eventsMerged);
@ -60,6 +74,8 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
QObject::connect(show_all_values_btn, &QAction::triggered, this, &ChartsWidget::showAllData);
QObject::connect(remove_all_btn, &QAction::triggered, this, &ChartsWidget::removeAll);
QObject::connect(reset_zoom_btn, &QAction::triggered, this, &ChartsWidget::zoomReset);
QObject::connect(columns_cb, SIGNAL(activated(int)), SLOT(setColumnCount(int)));
QObject::connect(&settings, &Settings::changed, this, &ChartsWidget::settingChanged);
QObject::connect(dock_btn, &QAction::triggered, [this]() {
emit dock(!docking);
docking = !docking;
@ -144,6 +160,14 @@ void ChartsWidget::updateToolBar() {
dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts"));
}
void ChartsWidget::settingChanged() {
for (auto c : charts) {
c->setFixedHeight(settings.chart_height);
columns_cb->setCurrentIndex(std::clamp(settings.chart_column_count - 1, 0, columns_cb->count() - 1));
setColumnCount(settings.chart_column_count);
}
}
ChartView *ChartsWidget::findChart(const QString &id, const Signal *sig) {
for (auto c : charts)
if (c->hasSeries(id, sig)) return c;
@ -157,6 +181,9 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
chart = merge && charts.size() > 0 ? charts.back() : nullptr;
if (!chart) {
chart = new ChartView(this);
chart->setFixedHeight(settings.chart_height);
chart->setMinimumWidth(CHART_MIN_WIDTH);
chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
chart->chart()->setTheme(use_dark_theme ? QChart::QChart::ChartThemeDark : QChart::ChartThemeLight);
chart->setEventsRange(display_range);
auto range = is_zoomed ? zoomed_range : display_range;
@ -167,8 +194,8 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
QObject::connect(chart, &ChartView::seriesRemoved, this, &ChartsWidget::seriesChanged);
QObject::connect(chart, &ChartView::seriesAdded, this, &ChartsWidget::seriesChanged);
QObject::connect(chart, &ChartView::axisYUpdated, [this]() { align_charts_timer->start(100); });
charts_layout->insertWidget(0, chart);
charts.push_back(chart);
updateLayout();
}
chart->addSeries(id, sig);
} else if (!show && chart) {
@ -178,6 +205,29 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
setUpdatesEnabled(true);
}
void ChartsWidget::setColumnCount(int n) {
n = std::clamp(n + 1, 1, columns_cb->count());
if (column_count != n) {
column_count = n;
updateLayout();
}
}
void ChartsWidget::updateLayout() {
int n = column_count;
for (; n >= 1; --n) {
if ((n * (CHART_MIN_WIDTH + charts_layout->spacing())) < rect().width()) break;
}
for (int i = 0; i < charts.size(); ++i) {
charts_layout->addWidget(charts[i], i / n, i % n);
}
}
void ChartsWidget::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
updateLayout();
}
void ChartsWidget::removeChart(ChartView *chart) {
charts.removeOne(chart);
chart->deleteLater();
@ -244,13 +294,11 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
setChart(chart);
setRenderHint(QPainter::Antialiasing);
setRubberBand(QChartView::HorizontalRubberBand);
updateFromSettings();
QObject::connect(dbc(), &DBCManager::signalRemoved, this, &ChartView::signalRemoved);
QObject::connect(dbc(), &DBCManager::signalUpdated, this, &ChartView::signalUpdated);
QObject::connect(dbc(), &DBCManager::msgRemoved, this, &ChartView::msgRemoved);
QObject::connect(dbc(), &DBCManager::msgUpdated, this, &ChartView::msgUpdated);
QObject::connect(&settings, &Settings::changed, this, &ChartView::updateFromSettings);
QObject::connect(remove_btn, &QToolButton::clicked, this, &ChartView::remove);
QObject::connect(manage_btn, &QToolButton::clicked, this, &ChartView::manageSeries);
}
@ -386,10 +434,6 @@ void ChartView::updateTitle() {
}
}
void ChartView::updateFromSettings() {
setFixedHeight(settings.chart_height);
}
void ChartView::setEventsRange(const std::pair<double, double> &range) {
if (range != events_range) {
events_range = range;

@ -3,11 +3,11 @@
#include <QComboBox>
#include <QDialogButtonBox>
#include <QDragEnterEvent>
#include <QGridLayout>
#include <QLabel>
#include <QListWidget>
#include <QGraphicsProxyWidget>
#include <QTimer>
#include <QVBoxLayout>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis>
@ -68,7 +68,6 @@ private:
void resizeEvent(QResizeEvent *event) override;
void updateAxisY();
void updateTitle();
void updateFromSettings();
void drawForeground(QPainter *painter, const QRectF &rect) override;
void applyNiceNumbers(qreal min, qreal max);
qreal niceNumber(qreal x, bool ceiling);
@ -92,12 +91,16 @@ public:
void showChart(const QString &id, const Signal *sig, bool show, bool merge);
inline bool hasSignal(const QString &id, const Signal *sig) { return findChart(id, sig) != nullptr; }
public slots:
void setColumnCount(int n);
signals:
void dock(bool floating);
void rangeChanged(double min, double max, bool is_zommed);
void seriesChanged();
private:
void resizeEvent(QResizeEvent *event) override;
void alignCharts();
void removeChart(ChartView *chart);
void eventsMerged();
@ -108,6 +111,8 @@ private:
void updateToolBar();
void removeAll();
void showAllData();
void updateLayout();
void settingChanged();
bool eventFilter(QObject *obj, QEvent *event) override;
ChartView *findChart(const QString &id, const Signal *sig);
@ -119,7 +124,7 @@ private:
QAction *reset_zoom_btn;
QAction *remove_all_btn;
QTimer *align_charts_timer;
QVBoxLayout *charts_layout;
QGridLayout *charts_layout;
QList<ChartView *> charts;
uint32_t max_chart_range = 0;
bool is_zoomed = false;
@ -127,6 +132,9 @@ private:
std::pair<double, double> display_range;
std::pair<double, double> zoomed_range;
bool use_dark_theme = false;
QComboBox *columns_cb;
int column_count = 1;
const int CHART_MIN_WIDTH = 300;
};
class SeriesSelector : public QDialog {

@ -18,6 +18,7 @@ void Settings::save() {
s.setValue("cached_segment", cached_segment_limit);
s.setValue("chart_height", chart_height);
s.setValue("max_chart_x_range", max_chart_x_range);
s.setValue("chart_column_count", chart_column_count);
s.setValue("last_dir", last_dir);
s.setValue("window_state", window_state);
s.setValue("geometry", geometry);
@ -30,6 +31,7 @@ void Settings::load() {
cached_segment_limit = s.value("cached_segment", 3).toInt();
chart_height = s.value("chart_height", 200).toInt();
max_chart_x_range = s.value("max_chart_x_range", 3 * 60).toInt();
chart_column_count = s.value("chart_column_count", 1).toInt();
last_dir = s.value("last_dir", QDir::homePath()).toString();
window_state = s.value("window_state").toByteArray();
geometry = s.value("geometry").toByteArray();

@ -16,6 +16,7 @@ public:
int fps = 10;
int cached_segment_limit = 3;
int chart_height = 200;
int chart_column_count = 1;
int max_chart_x_range = 3 * 60; // 3 minutes
QString last_dir;
QByteArray geometry;

Loading…
Cancel
Save