Cabana: move the chart title into graphics view (#26389)

remove class ChartWidget
pull/26398/head
Dean Lee 3 years ago committed by GitHub
parent 529504e201
commit 3dc5dbf103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 109
      tools/cabana/chartswidget.cc
  2. 45
      tools/cabana/chartswidget.h

@ -2,9 +2,9 @@
#include <QFutureSynchronizer> #include <QFutureSynchronizer>
#include <QGraphicsLayout> #include <QGraphicsLayout>
#include <QGridLayout>
#include <QRubberBand> #include <QRubberBand>
#include <QTimer> #include <QTimer>
#include <QToolButton>
#include <QtCharts/QLineSeries> #include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis> #include <QtCharts/QValueAxis>
#include <QtConcurrent> #include <QtConcurrent>
@ -13,7 +13,6 @@
ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this); QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
// title bar // title bar
title_bar = new QWidget(this); title_bar = new QWidget(this);
@ -120,14 +119,14 @@ void ChartsWidget::updateState() {
if (prev_range != display_range) { if (prev_range != display_range) {
QFutureSynchronizer<void> future_synchronizer; QFutureSynchronizer<void> future_synchronizer;
for (auto c : charts) for (auto c : charts)
future_synchronizer.addFuture(QtConcurrent::run(c->chart_view, &ChartView::updateSeries, display_range)); future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::updateSeries, display_range));
} }
} }
const auto &range = is_zoomed ? zoomed_range : display_range; const auto &range = is_zoomed ? zoomed_range : display_range;
for (auto c : charts) { for (auto c : charts) {
c->chart_view->setRange(range.first, range.second); c->setRange(range.first, range.second);
c->chart_view->updateLineMarker(current_sec); c->updateLineMarker(current_sec);
} }
} }
@ -150,11 +149,11 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show) {
if (it != charts.end()) { if (it != charts.end()) {
if (!show) removeChart((*it)); if (!show) removeChart((*it));
} else if (show) { } else if (show) {
auto chart = new ChartWidget(id, sig, this); auto chart = new ChartView(id, sig, this);
chart->chart_view->updateSeries(display_range); chart->updateSeries(display_range);
QObject::connect(chart, &ChartWidget::remove, [=]() { removeChart(chart); }); QObject::connect(chart, &ChartView::remove, [=]() { removeChart(chart); });
QObject::connect(chart->chart_view, &ChartView::zoomIn, this, &ChartsWidget::zoomIn); QObject::connect(chart, &ChartView::zoomIn, this, &ChartsWidget::zoomIn);
QObject::connect(chart->chart_view, &ChartView::zoomReset, this, &ChartsWidget::zoomReset); QObject::connect(chart, &ChartView::zoomReset, this, &ChartsWidget::zoomReset);
charts_layout->insertWidget(0, chart); charts_layout->insertWidget(0, chart);
charts.push_back(chart); charts.push_back(chart);
emit chartOpened(chart->id, chart->signal); emit chartOpened(chart->id, chart->signal);
@ -168,7 +167,7 @@ bool ChartsWidget::isChartOpened(const QString &id, const Signal *sig) {
return it != charts.end(); return it != charts.end();
} }
void ChartsWidget::removeChart(ChartWidget *chart) { void ChartsWidget::removeChart(ChartView *chart) {
charts.removeOne(chart); charts.removeOne(chart);
chart->deleteLater(); chart->deleteLater();
updateTitleBar(); updateTitleBar();
@ -184,8 +183,8 @@ void ChartsWidget::signalUpdated(const Signal *sig) {
for (auto c : charts) { for (auto c : charts) {
if (c->signal == sig) { if (c->signal == sig) {
c->updateTitle(); c->updateTitle();
c->chart_view->updateSeries(display_range); c->updateSeries(display_range);
c->chart_view->setRange(display_range.first, display_range.second, true); c->setRange(display_range.first, display_range.second, true);
} }
} }
} }
@ -198,54 +197,6 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) {
return false; return false;
} }
// ChartWidget
ChartWidget::ChartWidget(const QString &id, const Signal *sig, QWidget *parent) : id(id), signal(sig), QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setSpacing(0);
main_layout->setContentsMargins(0, 0, 0, 0);
header = new QWidget(this);
QGridLayout *header_layout = new QGridLayout(header);
header_layout->setContentsMargins(11, 11, 11, 0);
msg_name_label = new QLabel(this);
msg_name_label->setTextFormat(Qt::RichText);
header_layout->addWidget(msg_name_label, 0, 0, Qt::AlignLeft);
sig_name_label = new QLabel(this);
header_layout->addWidget(sig_name_label, 0, 1, Qt::AlignCenter); //, 0, Qt::AlignCenter);
remove_btn = new QPushButton("", this);
remove_btn->setFixedSize(20, 20);
remove_btn->setToolTip(tr("Remove chart"));
header_layout->addWidget(remove_btn, 0, 2, Qt::AlignRight);
main_layout->addWidget(header);
chart_view = new ChartView(id, sig, this);
main_layout->addWidget(chart_view);
main_layout->addStretch();
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
updateTitle();
updateFromSettings();
QObject::connect(remove_btn, &QPushButton::clicked, [=]() { emit remove(id, sig); });
QObject::connect(&settings, &Settings::changed, this, &ChartWidget::updateFromSettings);
}
void ChartWidget::updateTitle() {
msg_name_label->setText(tr("%1 <font color=\"gray\">%2</font>").arg(dbc()->msg(id)->name.c_str()).arg(id));
sig_name_label->setText(signal->name.c_str());
}
void ChartWidget::updateFromSettings() {
header->setStyleSheet(settings.chart_theme == 0 ? "background-color:white" : "background-color:#23242c");
QString color_style = settings.chart_theme == 0 ? "color:black" : "color:white";
sig_name_label->setStyleSheet("font-weight:bold;" + color_style);
msg_name_label->setStyleSheet(color_style);
remove_btn->setStyleSheet(color_style);
chart_view->updateFromSettings();
}
// ChartView // ChartView
ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent) ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent)
@ -256,7 +207,6 @@ ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent)
chart->addSeries(series); chart->addSeries(series);
chart->createDefaultAxes(); chart->createDefaultAxes();
chart->legend()->hide(); chart->legend()->hide();
chart->setMargins({0, 0, 0, 0});
chart->layout()->setContentsMargins(0, 0, 0, 0); chart->layout()->setContentsMargins(0, 0, 0, 0);
line_marker = new QGraphicsLineItem(chart); line_marker = new QGraphicsLineItem(chart);
@ -270,26 +220,51 @@ ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent)
item_group = scene()->createItemGroup({track_line, track_ellipse, value_text}); item_group = scene()->createItemGroup({track_line, track_ellipse, value_text});
item_group->setZValue(chart->zValue() + 10); item_group->setZValue(chart->zValue() + 10);
setChart(chart); // title
msg_title = new QGraphicsTextItem(chart);
QToolButton *remove_btn = new QToolButton();
remove_btn->setText("X");
remove_btn->setAutoRaise(true);
remove_btn->setToolTip(tr("Remove Chart"));
close_btn_proxy = new QGraphicsProxyWidget(chart);
close_btn_proxy->setWidget(remove_btn);
setChart(chart);
setRenderHint(QPainter::Antialiasing); setRenderHint(QPainter::Antialiasing);
setRubberBand(QChartView::HorizontalRubberBand); setRubberBand(QChartView::HorizontalRubberBand);
updateFromSettings();
updateTitle();
QTimer *timer = new QTimer(this); QTimer *timer = new QTimer(this);
timer->setInterval(100); timer->setInterval(100);
timer->setSingleShot(true); timer->setSingleShot(true);
timer->callOnTimeout(this, &ChartView::adjustChartMargins); timer->callOnTimeout(this, &ChartView::adjustChartMargins);
QObject::connect(&settings, &Settings::changed, this, &ChartView::updateFromSettings);
QObject::connect(remove_btn, &QToolButton::clicked, [=]() { emit remove(id, sig); });
QObject::connect(chart, &QChart::plotAreaChanged, [=](const QRectF &plotArea) { QObject::connect(chart, &QChart::plotAreaChanged, [=](const QRectF &plotArea) {
// use a singleshot timer to avoid recursion call. // use a singleshot timer to avoid recursion call.
timer->start(); timer->start();
}); });
} }
void ChartView::resizeEvent(QResizeEvent *event) {
QChartView::resizeEvent(event);
msg_title->setPos(11, 6);
close_btn_proxy->setPos(event->size().width() - close_btn_proxy->size().width() - 11, 8);
}
void ChartView::updateTitle() {
chart()->setTitle(signal->name.c_str());
msg_title->setHtml(tr("%1 <font color=\"gray\">%2</font>").arg(dbc()->msg(id)->name.c_str()).arg(id));
}
void ChartView::updateFromSettings() { void ChartView::updateFromSettings() {
setFixedHeight(settings.chart_height); setFixedHeight(settings.chart_height);
chart()->setTheme(settings.chart_theme == 0 ? QChart::ChartThemeLight : QChart::QChart::ChartThemeDark); chart()->setTheme(settings.chart_theme == 0 ? QChart::ChartThemeLight : QChart::QChart::ChartThemeDark);
line_marker->setPen(QPen(settings.chart_theme == 0 ? Qt::black : Qt::white, 2)); auto color = chart()->titleBrush().color();
line_marker->setPen(QPen(color, 2));
msg_title->setDefaultTextColor(color);
} }
void ChartView::setRange(double min, double max, bool force_update) { void ChartView::setRange(double min, double max, bool force_update) {
@ -305,7 +280,7 @@ void ChartView::adjustChartMargins() {
const int aligned_pos = 60; const int aligned_pos = 60;
if (chart()->plotArea().left() != aligned_pos) { if (chart()->plotArea().left() != aligned_pos) {
const float left_margin = chart()->margins().left() + aligned_pos - chart()->plotArea().left(); const float left_margin = chart()->margins().left() + aligned_pos - chart()->plotArea().left();
chart()->setMargins(QMargins(left_margin, 0, 0, 0)); chart()->setMargins(QMargins(left_margin, 11, 0, 0));
} }
} }
@ -314,7 +289,7 @@ void ChartView::updateLineMarker(double current_sec) {
int x = chart()->plotArea().left() + int x = chart()->plotArea().left() +
chart()->plotArea().width() * (current_sec - axis_x->min()) / (axis_x->max() - axis_x->min()); chart()->plotArea().width() * (current_sec - axis_x->min()) / (axis_x->max() - axis_x->min());
if (int(line_marker->line().x1()) != x) { if (int(line_marker->line().x1()) != x) {
line_marker->setLine(x, 0, x, height()); line_marker->setLine(x, chart()->plotArea().top() - chart()->margins().top() + 3, x, height());
} }
} }
@ -402,7 +377,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) {
if (!is_zooming) { if (!is_zooming) {
const auto plot_area = chart()->plotArea(); const auto plot_area = chart()->plotArea();
auto axis_x = dynamic_cast<QValueAxis *>(chart()->axisX()); auto axis_x = dynamic_cast<QValueAxis *>(chart()->axisX());
double x = std::clamp((double)ev->pos().x(), plot_area.left(), plot_area.right()-1); double x = std::clamp((double)ev->pos().x(), plot_area.left(), plot_area.right() - 1);
double sec = axis_x->min() + (axis_x->max() - axis_x->min()) * (x - plot_area.left()) / plot_area.width(); double sec = axis_x->min() + (axis_x->max() - axis_x->min()) * (x - plot_area.left()) / plot_area.width();
auto value = std::upper_bound(vals.begin(), vals.end(), sec, [](double x, auto &p) { return x < p.x(); }); auto value = std::upper_bound(vals.begin(), vals.end(), sec, [](double x, auto &p) { return x < p.x(); });
if (value != vals.end()) { if (value != vals.end()) {

@ -1,10 +1,9 @@
#pragma once #pragma once
#include <map>
#include <QLabel> #include <QLabel>
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
#include <QGraphicsLineItem> #include <QGraphicsLineItem>
#include <QGraphicsProxyWidget>
#include <QGraphicsTextItem> #include <QGraphicsTextItem>
#include <QPushButton> #include <QPushButton>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -24,48 +23,31 @@ public:
void setRange(double min, double max, bool force_update = false); void setRange(double min, double max, bool force_update = false);
void updateLineMarker(double current_sec); void updateLineMarker(double current_sec);
void updateFromSettings(); void updateFromSettings();
void updateTitle();
QString id;
const Signal *signal;
signals: signals:
void zoomIn(double min, double max); void zoomIn(double min, double max);
void zoomReset(); void zoomReset();
void remove(const QString &msg_id, const Signal *sig);
private: private:
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *ev) override; void mouseMoveEvent(QMouseEvent *ev) override;
void leaveEvent(QEvent *event) override; void leaveEvent(QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void adjustChartMargins(); void adjustChartMargins();
void updateAxisY(); void updateAxisY();
QGraphicsItemGroup *item_group; QGraphicsItemGroup *item_group;
QGraphicsLineItem *track_line; QGraphicsLineItem *line_marker, *track_line;
QGraphicsEllipseItem *track_ellipse; QGraphicsEllipseItem *track_ellipse;
QGraphicsTextItem *value_text; QGraphicsTextItem *value_text, *msg_title;
QGraphicsLineItem *line_marker; QGraphicsProxyWidget *close_btn_proxy;
QVector<QPointF> vals; QVector<QPointF> vals;
QString id; };
const Signal *signal;
};
class ChartWidget : public QWidget {
Q_OBJECT
public:
ChartWidget(const QString &id, const Signal *sig, QWidget *parent);
void updateTitle();
void updateFromSettings();
signals:
void remove(const QString &msg_id, const Signal *sig);
public:
QString id;
const Signal *signal;
QWidget *header;
QLabel *msg_name_label;
QLabel *sig_name_label;
QPushButton *remove_btn;
ChartView *chart_view = nullptr;
};
class ChartsWidget : public QWidget { class ChartsWidget : public QWidget {
Q_OBJECT Q_OBJECT
@ -73,7 +55,7 @@ class ChartsWidget : public QWidget {
public: public:
ChartsWidget(QWidget *parent = nullptr); ChartsWidget(QWidget *parent = nullptr);
void showChart(const QString &id, const Signal *sig, bool show); void showChart(const QString &id, const Signal *sig, bool show);
void removeChart(ChartWidget *chart); void removeChart(ChartView *chart);
bool isChartOpened(const QString &id, const Signal *sig); bool isChartOpened(const QString &id, const Signal *sig);
signals: signals:
@ -100,8 +82,7 @@ private:
QPushButton *reset_zoom_btn; QPushButton *reset_zoom_btn;
QPushButton *remove_all_btn; QPushButton *remove_all_btn;
QVBoxLayout *charts_layout; QVBoxLayout *charts_layout;
QList<ChartWidget *> charts; QList<ChartView *> charts;
bool is_zoomed = false; bool is_zoomed = false;
std::pair<double, double> event_range; std::pair<double, double> event_range;
std::pair<double, double> display_range; std::pair<double, double> display_range;

Loading…
Cancel
Save