mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-09-29 19:23:41 +08:00
Merge branch 'master' into dev-priv/master
# Conflicts: # system/version.py
This commit is contained in:
Vendored
+16
-2
@@ -13,6 +13,8 @@ export GIT_COMMIT=${env.GIT_COMMIT}
|
||||
export AZURE_TOKEN='${env.AZURE_TOKEN}'
|
||||
export MAPBOX_TOKEN='${env.MAPBOX_TOKEN}'
|
||||
|
||||
export GIT_SSH_COMMAND="ssh -i /data/gitkey"
|
||||
|
||||
source ~/.bash_profile
|
||||
if [ -f /TICI ]; then
|
||||
source /etc/profile
|
||||
@@ -56,14 +58,26 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('build release3') {
|
||||
stage('build release3-staging') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
when {
|
||||
branch 'devel-staging'
|
||||
}
|
||||
steps {
|
||||
phone_steps("tici-needs-can", [
|
||||
["build release3-staging & dashcam3-staging", "PUSH=1 $SOURCE_DIR/release/build_release.sh"],
|
||||
["build release3-staging & dashcam3-staging", "RELEASE_BRANCH=release3-staging DASHCAM_BRANCH=dashcam3-staging $SOURCE_DIR/release/build_release.sh"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('build nightly') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
when {
|
||||
branch 'master-ci'
|
||||
}
|
||||
steps {
|
||||
phone_steps("tici-needs-can", [
|
||||
["build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,19 @@ SOURCE_DIR="$(git rev-parse --show-toplevel)"
|
||||
|
||||
if [ -f /TICI ]; then
|
||||
FILES_SRC="release/files_tici"
|
||||
RELEASE_BRANCH=release3-staging
|
||||
DASHCAM_BRANCH=dashcam3-staging
|
||||
else
|
||||
exit 0
|
||||
echo "no release files set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$RELEASE_BRANCH" ]; then
|
||||
echo "RELEASE_BRANCH is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# set git identity
|
||||
source $DIR/identity.sh
|
||||
export GIT_SSH_COMMAND="ssh -i /data/gitkey"
|
||||
|
||||
echo "[-] Setting up repo T=$SECONDS"
|
||||
rm -rf $BUILD_DIR
|
||||
@@ -27,7 +31,6 @@ mkdir -p $BUILD_DIR
|
||||
cd $BUILD_DIR
|
||||
git init
|
||||
git remote add origin git@github.com:commaai/openpilot.git
|
||||
git fetch origin $RELEASE_BRANCH
|
||||
git checkout --orphan $RELEASE_BRANCH
|
||||
|
||||
# do the files copy
|
||||
@@ -48,7 +51,6 @@ echo "#define COMMA_VERSION \"$VERSION-release\"" > common/version.h
|
||||
echo "[-] committing version $VERSION T=$SECONDS"
|
||||
git add -f .
|
||||
git commit -a -m "openpilot v$VERSION release"
|
||||
git branch --set-upstream-to=origin/$RELEASE_BRANCH
|
||||
|
||||
# Build panda firmware
|
||||
pushd panda/
|
||||
@@ -105,10 +107,12 @@ RELEASE=1 selfdrive/test/test_onroad.py
|
||||
selfdrive/car/tests/test_car_interfaces.py
|
||||
rm -rf $TEST_FILES
|
||||
|
||||
if [ ! -z "$PUSH" ]; then
|
||||
echo "[-] pushing T=$SECONDS"
|
||||
git push -f origin $RELEASE_BRANCH
|
||||
if [ ! -z "$RELEASE_BRANCH" ]; then
|
||||
echo "[-] pushing release T=$SECONDS"
|
||||
git push -f origin $RELEASE_BRANCH:$RELEASE_BRANCH
|
||||
fi
|
||||
|
||||
if [ ! -z "$DASHCAM_BRANCH" ]; then
|
||||
# Create dashcam
|
||||
git rm selfdrive/car/*/carcontroller.py
|
||||
git commit -m "create dashcam release from release"
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ from functools import lru_cache
|
||||
from common.basedir import BASEDIR
|
||||
from system.swaglog import cloudlog
|
||||
|
||||
RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'release3', 'dashcam3', 'prod-c3']
|
||||
TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging', 'test-c3']
|
||||
RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'release3', 'dashcam3', 'nightly']
|
||||
TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging', 'prod-c3', 'test-c3']
|
||||
|
||||
training_version: bytes = b"0.2.0"
|
||||
terms_version: bytes = b"2"
|
||||
|
||||
@@ -8,13 +8,18 @@ Cabana is a tool developed to view raw CAN data. One use for this is creating an
|
||||
|
||||
```bash
|
||||
$ ./cabana -h
|
||||
Usage: ./cabana [options] route
|
||||
Usage: ./_cabana [options] route
|
||||
|
||||
Options:
|
||||
-h, --help Displays this help.
|
||||
--demo use a demo route instead of providing your own
|
||||
--qcam load qcamera
|
||||
--ecam load wide road camera
|
||||
--stream read can messages from live streaming
|
||||
--zmq <zmq> the ip address on which to receive zmq messages
|
||||
--data_dir <data_dir> local directory with routes
|
||||
--no-vipc do not output video
|
||||
--dbc <dbc> dbc file to open
|
||||
|
||||
Arguments:
|
||||
route the drive to replay. find your drives at
|
||||
|
||||
@@ -68,10 +68,6 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
charts_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
main_layout->addWidget(charts_scroll);
|
||||
|
||||
align_charts_timer = new QTimer(this);
|
||||
align_charts_timer->setSingleShot(true);
|
||||
align_charts_timer->callOnTimeout(this, &ChartsWidget::alignCharts);
|
||||
|
||||
// init settings
|
||||
use_dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() >
|
||||
QApplication::style()->standardPalette().color(QPalette::Background).value();
|
||||
@@ -125,9 +121,9 @@ void ChartsWidget::zoomReset() {
|
||||
void ChartsWidget::updateState() {
|
||||
if (charts.isEmpty()) return;
|
||||
|
||||
const auto events = can->events();
|
||||
if (can->liveStreaming()) {
|
||||
// appends incoming events to the end of series
|
||||
const auto events = can->events();
|
||||
for (auto c : charts) {
|
||||
c->updateSeries(nullptr, events, false);
|
||||
}
|
||||
@@ -135,33 +131,30 @@ void ChartsWidget::updateState() {
|
||||
|
||||
const double cur_sec = can->currentSec();
|
||||
if (!is_zoomed) {
|
||||
double pos = (cur_sec - display_range.first) / max_chart_range;
|
||||
double pos = (cur_sec - display_range.first) / std::max(1.0, (display_range.second - display_range.first));
|
||||
if (pos < 0 || pos > 0.8) {
|
||||
const double min_event_sec = can->events()->empty() ? 0 : (can->events()->front()->mono_time / (double)1e9 - can->routeStartTime());
|
||||
display_range.first = std::floor(std::max(min_event_sec, cur_sec - max_chart_range * 0.2));
|
||||
display_range.first = std::max(0.0, cur_sec - max_chart_range * 0.1);
|
||||
}
|
||||
display_range.second = std::floor(display_range.first + max_chart_range);
|
||||
double max_event_sec = events->empty() ? 0 : (events->back()->mono_time / 1e9 - can->routeStartTime());
|
||||
double max_sec = std::min(std::floor(display_range.first + max_chart_range), max_event_sec);
|
||||
display_range.first = std::max(0.0, max_sec - max_chart_range);
|
||||
display_range.second = display_range.first + max_chart_range;
|
||||
} else if (cur_sec < zoomed_range.first || cur_sec >= zoomed_range.second) {
|
||||
// loop in zoommed range
|
||||
can->seekTo(zoomed_range.first);
|
||||
}
|
||||
|
||||
setUpdatesEnabled(false);
|
||||
charts_layout->parentWidget()->setUpdatesEnabled(false);
|
||||
const auto &range = is_zoomed ? zoomed_range : display_range;
|
||||
for (auto c : charts) {
|
||||
c->updatePlot(cur_sec, range.first, range.second);
|
||||
}
|
||||
setUpdatesEnabled(true);
|
||||
alignCharts();
|
||||
charts_layout->parentWidget()->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void ChartsWidget::setMaxChartRange(int value) {
|
||||
max_chart_range = settings.chart_range = value;
|
||||
double current_sec = can->currentSec();
|
||||
const double min_event_sec = can->events()->empty() ? 0 : (can->events()->front()->mono_time / (double)1e9 - can->routeStartTime());
|
||||
// keep current_sec's pos
|
||||
double pos = (current_sec - display_range.first) / (display_range.second - display_range.first);
|
||||
display_range.first = std::floor(std::max(min_event_sec, current_sec - max_chart_range * (1.0 - pos)));
|
||||
display_range.second = std::floor(display_range.first + max_chart_range);
|
||||
updateToolBar();
|
||||
updateState();
|
||||
}
|
||||
@@ -200,7 +193,6 @@ ChartView *ChartsWidget::createChart() {
|
||||
QObject::connect(chart, &ChartView::zoomReset, this, &ChartsWidget::zoomReset);
|
||||
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.push_back(chart);
|
||||
updateLayout();
|
||||
return chart;
|
||||
@@ -239,9 +231,14 @@ void ChartsWidget::updateLayout() {
|
||||
columns_cb_action->setVisible(show_column_cb);
|
||||
|
||||
n = std::min(column_count, n);
|
||||
for (int i = 0; i < charts.size(); ++i) {
|
||||
charts_layout->addWidget(charts[charts.size() - i - 1], i / n, i % n);
|
||||
if (charts.size() != charts_layout->count() || n != charts_layout->columnCount()) {
|
||||
charts_layout->parentWidget()->setUpdatesEnabled(false);
|
||||
for (int i = 0; i < charts.size(); ++i) {
|
||||
charts_layout->addWidget(charts[charts.size() - i - 1], i / n, i % n);
|
||||
}
|
||||
QTimer::singleShot(0, [this]() { charts_layout->parentWidget()->setUpdatesEnabled(true); });
|
||||
}
|
||||
alignCharts(true);
|
||||
}
|
||||
|
||||
void ChartsWidget::resizeEvent(QResizeEvent *event) {
|
||||
@@ -278,13 +275,16 @@ void ChartsWidget::removeAll() {
|
||||
emit seriesChanged();
|
||||
}
|
||||
|
||||
void ChartsWidget::alignCharts() {
|
||||
void ChartsWidget::alignCharts(bool force) {
|
||||
int plot_left = 0;
|
||||
for (auto c : charts) {
|
||||
plot_left = qMax((qreal)plot_left, c->getYAsixLabelWidth());
|
||||
plot_left = std::max(plot_left, c->y_label_width);
|
||||
}
|
||||
for (auto c : charts) {
|
||||
c->setPlotAreaLeftPosition(plot_left);
|
||||
plot_left = std::max((plot_left / 10) * 10 + 10, 50);
|
||||
if (std::exchange(align_to, plot_left) != align_to || force) {
|
||||
for (auto c : charts) {
|
||||
c->updatePlotArea(align_to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,15 +302,20 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
series_type = settings.chart_series_type == 0 ? QAbstractSeries::SeriesTypeLine : QAbstractSeries::SeriesTypeScatter;
|
||||
|
||||
QChart *chart = new QChart();
|
||||
chart->setBackgroundRoundness(0);
|
||||
chart->setBackgroundVisible(false);
|
||||
axis_x = new QValueAxis(this);
|
||||
axis_y = new QValueAxis(this);
|
||||
axis_y->setLabelFormat("%.1f");
|
||||
chart->addAxis(axis_x, Qt::AlignBottom);
|
||||
chart->addAxis(axis_y, Qt::AlignLeft);
|
||||
chart->legend()->layout()->setContentsMargins(0, 0, 40, 0);
|
||||
chart->legend()->setShowToolTips(true);
|
||||
chart->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
chart->setMargins({20, 11, 11, 11});
|
||||
chart->setMargins({0, 0, 0, 0});
|
||||
|
||||
background = new QGraphicsRectItem(chart);
|
||||
background->setBrush(Qt::white);
|
||||
background->setPen(Qt::NoPen);
|
||||
background->setZValue(chart->zValue() - 1);
|
||||
|
||||
QToolButton *remove_btn = new QToolButton();
|
||||
remove_btn->setIcon(utils::icon("x"));
|
||||
@@ -351,22 +356,6 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
QObject::connect(remove_btn, &QToolButton::clicked, this, &ChartView::remove);
|
||||
}
|
||||
|
||||
qreal ChartView::getYAsixLabelWidth() const {
|
||||
if (axis_y->max() <= axis_y->min() || axis_y->tickCount() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
QFontMetrics fm(axis_y->labelsFont());
|
||||
int n = qMax(int(-qFloor(std::log10((axis_y->max() - axis_y->min()) / (axis_y->tickCount() - 1)))), 0) + 1;
|
||||
return qMax(fm.width(QString::number(axis_y->min(), 'f', n)), fm.width(QString::number(axis_y->max(), 'f', n))) + 20;
|
||||
}
|
||||
|
||||
void ChartView::setPlotAreaLeftPosition(int pos) {
|
||||
if (std::ceil(chart()->plotArea().left()) != pos) {
|
||||
const float left_margin = chart()->margins().left() + pos - chart()->plotArea().left();
|
||||
chart()->setMargins(QMargins(left_margin, 11, 11, 11));
|
||||
}
|
||||
}
|
||||
|
||||
void ChartView::addSeries(const QString &msg_id, const Signal *sig) {
|
||||
QXYSeries *series = createSeries(series_type);
|
||||
chart()->addSeries(series);
|
||||
@@ -467,11 +456,21 @@ void ChartView::manageSeries() {
|
||||
|
||||
void ChartView::resizeEvent(QResizeEvent *event) {
|
||||
QChartView::resizeEvent(event);
|
||||
updatePlotArea();
|
||||
int x = event->size().width() - close_btn_proxy->size().width() - 11;
|
||||
close_btn_proxy->setPos(x, 8);
|
||||
manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - 5, 8);
|
||||
}
|
||||
|
||||
void ChartView::updatePlotArea(int left) {
|
||||
align_to = left > 0 ? left : align_to;
|
||||
QRect r = rect();
|
||||
background->setRect(r);
|
||||
chart()->legend()->setGeometry(QRect(r.left(), r.top(), r.width(), 45));
|
||||
chart()->setPlotArea(QRect(align_to, r.top() + 45, r.width() - align_to - 22, r.height() - 80));
|
||||
chart()->layout()->invalidate();
|
||||
}
|
||||
|
||||
void ChartView::updateTitle() {
|
||||
for (auto &s : sigs) {
|
||||
s.series->setName(QString("<b>%1</b> <font color=\"gray\">%2 %3</font>").arg(s.sig->name.c_str()).arg(msgName(s.msg_id)).arg(s.msg_id));
|
||||
@@ -536,7 +535,7 @@ void ChartView::updateSeries(const Signal *sig, const std::vector<Event *> *even
|
||||
for (auto it = begin; it != events->end(); ++it) {
|
||||
if ((*it)->which == cereal::Event::Which::CAN) {
|
||||
for (const auto &c : (*it)->event.getCan()) {
|
||||
if (s.source == c.getSrc() && s.address == c.getAddress()) {
|
||||
if (s.address == c.getAddress() && s.source == c.getSrc()) {
|
||||
auto dat = c.getDat();
|
||||
double value = get_raw_value((uint8_t *)dat.begin(), dat.size(), *s.sig);
|
||||
double ts = ((*it)->mono_time / (double)1e9) - route_start_time; // seconds
|
||||
@@ -549,46 +548,47 @@ void ChartView::updateSeries(const Signal *sig, const std::vector<Event *> *even
|
||||
s.last_value_mono_time = events->back()->mono_time;
|
||||
}
|
||||
s.series->replace(s.vals);
|
||||
updateAxisY();
|
||||
}
|
||||
}
|
||||
updateAxisY();
|
||||
}
|
||||
|
||||
// auto zoom on yaxis
|
||||
void ChartView::updateAxisY() {
|
||||
if (sigs.isEmpty()) return;
|
||||
|
||||
double min_y = std::numeric_limits<double>::max();
|
||||
double max_y = std::numeric_limits<double>::lowest();
|
||||
double min = std::numeric_limits<double>::max();
|
||||
double max = std::numeric_limits<double>::lowest();
|
||||
for (auto &s : sigs) {
|
||||
auto begin = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; });
|
||||
for (auto it = begin; it != s.vals.end() && it->x() <= axis_x->max(); ++it) {
|
||||
if (it->y() < min_y) min_y = it->y();
|
||||
if (it->y() > max_y) max_y = it->y();
|
||||
auto first = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; });
|
||||
auto last = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->max(), [](auto &p, double x) { return p.x() < x; });
|
||||
for (auto it = first; it != last; ++it) {
|
||||
if (it->y() < min) min = it->y();
|
||||
if (it->y() > max) max = it->y();
|
||||
}
|
||||
}
|
||||
if (min == std::numeric_limits<double>::max()) min = 0;
|
||||
if (max == std::numeric_limits<double>::lowest()) max = 0;
|
||||
|
||||
if (min_y == std::numeric_limits<double>::max()) min_y = 0;
|
||||
if (max_y == std::numeric_limits<double>::lowest()) max_y = 0;
|
||||
if (std::abs(max_y - min_y) < 1e-3) {
|
||||
applyNiceNumbers(min_y - 1, max_y + 1);
|
||||
} else {
|
||||
double range = max_y - min_y;
|
||||
applyNiceNumbers(min_y - range * 0.05, max_y + range * 0.05);
|
||||
double delta = std::abs(max - min) < 1e-3 ? 1 : (max - min) * 0.05;
|
||||
auto [min_y, max_y, tick_count] = getNiceAxisNumbers(min - delta, max + delta, axis_y->tickCount());
|
||||
if (min_y != axis_y->min() || max_y != axis_y->max()) {
|
||||
axis_y->setRange(min_y, max_y);
|
||||
axis_y->setTickCount(tick_count);
|
||||
|
||||
QFontMetrics fm(axis_y->labelsFont());
|
||||
int n = qMax(int(-qFloor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1;
|
||||
y_label_width = qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 20; // left margin 20
|
||||
}
|
||||
emit axisYUpdated();
|
||||
}
|
||||
|
||||
void ChartView::applyNiceNumbers(qreal min, qreal max) {
|
||||
int tick_count = axis_y->tickCount();
|
||||
std::tuple<double, double, int> ChartView::getNiceAxisNumbers(qreal min, qreal max, int tick_count) {
|
||||
qreal range = niceNumber((max - min), true); // range with ceiling
|
||||
qreal step = niceNumber(range / (tick_count - 1), false);
|
||||
min = qFloor(min / step);
|
||||
max = qCeil(max / step);
|
||||
tick_count = int(max - min) + 1;
|
||||
axis_y->setRange(min * step, max * step);
|
||||
axis_y->setTickCount(tick_count);
|
||||
axis_y->setLabelFormat("%.1f");
|
||||
return {min * step, max * step, tick_count};
|
||||
}
|
||||
|
||||
// nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
|
||||
@@ -642,8 +642,8 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) {
|
||||
double max = chart()->mapToValue(rect.bottomRight()).x();
|
||||
|
||||
// Prevent zooming/seeking past the end of the route
|
||||
min = std::clamp(min, can->routeStartTime(), can->routeStartTime() + can->totalSeconds());
|
||||
max = std::clamp(max, can->routeStartTime(), can->routeStartTime() + can->totalSeconds());
|
||||
min = std::clamp(min, 0., can->totalSeconds());
|
||||
max = std::clamp(max, 0., can->totalSeconds());
|
||||
|
||||
double min_rounded = std::floor(min * 10.0) / 10.0;
|
||||
double max_rounded = std::floor(max * 10.0) / 10.0;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <QListWidget>
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QSlider>
|
||||
#include <QTimer>
|
||||
#include <QtCharts/QChartView>
|
||||
#include <QtCharts/QLineSeries>
|
||||
#include <QtCharts/QScatterSeries>
|
||||
@@ -18,6 +17,8 @@
|
||||
|
||||
using namespace QtCharts;
|
||||
|
||||
const int CHART_MIN_WIDTH = 300;
|
||||
|
||||
class ChartView : public QChartView {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -29,9 +30,8 @@ public:
|
||||
bool hasSeries(const QString &msg_id, const Signal *sig) const;
|
||||
void updateSeries(const Signal *sig = nullptr, const std::vector<Event*> *events = nullptr, bool clear = true);
|
||||
void updatePlot(double cur, double min, double max);
|
||||
void setPlotAreaLeftPosition(int pos);
|
||||
qreal getYAsixLabelWidth() const;
|
||||
void setSeriesType(QAbstractSeries::SeriesType type);
|
||||
void updatePlotArea(int left = 0);
|
||||
|
||||
struct SigItem {
|
||||
QString msg_id;
|
||||
@@ -49,7 +49,6 @@ signals:
|
||||
void zoomIn(double min, double max);
|
||||
void zoomReset();
|
||||
void remove();
|
||||
void axisYUpdated();
|
||||
|
||||
private slots:
|
||||
void msgRemoved(uint32_t address);
|
||||
@@ -67,25 +66,30 @@ private:
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
QSize sizeHint() const override { return {CHART_MIN_WIDTH, settings.chart_height}; }
|
||||
void updateAxisY();
|
||||
void updateTitle();
|
||||
void drawForeground(QPainter *painter, const QRectF &rect) override;
|
||||
void applyNiceNumbers(qreal min, qreal max);
|
||||
std::tuple<double, double, int> getNiceAxisNumbers(qreal min, qreal max, int tick_count);
|
||||
qreal niceNumber(qreal x, bool ceiling);
|
||||
QXYSeries *createSeries(QAbstractSeries::SeriesType type);
|
||||
void updateSeriesPoints();
|
||||
|
||||
int y_label_width = 50;
|
||||
int align_to = 0;
|
||||
QValueAxis *axis_x;
|
||||
QValueAxis *axis_y;
|
||||
QVector<QPointF> track_pts;
|
||||
QGraphicsProxyWidget *close_btn_proxy;
|
||||
QGraphicsProxyWidget *manage_btn_proxy;
|
||||
QGraphicsRectItem *background;
|
||||
QList<SigItem> sigs;
|
||||
double cur_sec = 0;
|
||||
const QString mime_type = "application/x-cabanachartview";
|
||||
QAbstractSeries::SeriesType series_type = QAbstractSeries::SeriesTypeLine;
|
||||
QAction *line_series_action;
|
||||
QAction *scatter_series_action;
|
||||
friend class ChartsWidget;
|
||||
};
|
||||
|
||||
class ChartsWidget : public QWidget {
|
||||
@@ -107,7 +111,7 @@ signals:
|
||||
|
||||
private:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void alignCharts();
|
||||
void alignCharts(bool force = false);
|
||||
void newChart();
|
||||
ChartView * createChart();
|
||||
void removeChart(ChartView *chart);
|
||||
@@ -129,7 +133,6 @@ private:
|
||||
QAction *dock_btn;
|
||||
QAction *reset_zoom_btn;
|
||||
QAction *remove_all_btn;
|
||||
QTimer *align_charts_timer;
|
||||
QGridLayout *charts_layout;
|
||||
QList<ChartView *> charts;
|
||||
uint32_t max_chart_range = 0;
|
||||
@@ -141,7 +144,7 @@ private:
|
||||
QAction *columns_cb_action;
|
||||
QComboBox *columns_cb;
|
||||
int column_count = 1;
|
||||
const int CHART_MIN_WIDTH = 300;
|
||||
int align_to = 0;
|
||||
};
|
||||
|
||||
class SeriesSelector : public QDialog {
|
||||
|
||||
Reference in New Issue
Block a user