You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							123 lines
						
					
					
						
							4.2 KiB
						
					
					
				
			
		
		
	
	
							123 lines
						
					
					
						
							4.2 KiB
						
					
					
				| #pragma once
 | |
| 
 | |
| #include <tuple>
 | |
| #include <utility>
 | |
| #include <vector>
 | |
| 
 | |
| #include <QMenu>
 | |
| #include <QGraphicsPixmapItem>
 | |
| #include <QGraphicsProxyWidget>
 | |
| #include <QtCharts/QChartView>
 | |
| #include <QtCharts/QLegendMarker>
 | |
| #include <QtCharts/QLineSeries>
 | |
| #include <QtCharts/QScatterSeries>
 | |
| #include <QtCharts/QValueAxis>
 | |
| using namespace QtCharts;
 | |
| 
 | |
| #include "tools/cabana/chart/tiplabel.h"
 | |
| #include "tools/cabana/dbc/dbcmanager.h"
 | |
| #include "tools/cabana/streams/abstractstream.h"
 | |
| 
 | |
| enum class SeriesType {
 | |
|   Line = 0,
 | |
|   StepLine,
 | |
|   Scatter
 | |
| };
 | |
| 
 | |
| class ChartsWidget;
 | |
| class ChartView : public QChartView {
 | |
|   Q_OBJECT
 | |
| 
 | |
| public:
 | |
|   ChartView(const std::pair<double, double> &x_range, ChartsWidget *parent = nullptr);
 | |
|   void addSignal(const MessageId &msg_id, const cabana::Signal *sig);
 | |
|   bool hasSignal(const MessageId &msg_id, const cabana::Signal *sig) const;
 | |
|   void updateSeries(const cabana::Signal *sig = nullptr, const MessageEventsMap *msg_new_events = nullptr);
 | |
|   void updatePlot(double cur, double min, double max);
 | |
|   void setSeriesType(SeriesType type);
 | |
|   void updatePlotArea(int left, bool force = false);
 | |
|   void showTip(double sec);
 | |
|   void hideTip();
 | |
|   void startAnimation();
 | |
|   double secondsAtPoint(const QPointF &pt) const { return chart()->mapToValue(pt).x(); }
 | |
| 
 | |
|   struct SigItem {
 | |
|     MessageId msg_id;
 | |
|     const cabana::Signal *sig = nullptr;
 | |
|     QXYSeries *series = nullptr;
 | |
|     std::vector<QPointF> vals;
 | |
|     std::vector<QPointF> step_vals;
 | |
|     QPointF track_pt{};
 | |
|     SegmentTree segment_tree;
 | |
|     double min = 0;
 | |
|     double max = 0;
 | |
|   };
 | |
| 
 | |
| signals:
 | |
|   void axisYLabelWidthChanged(int w);
 | |
| 
 | |
| private slots:
 | |
|   void signalUpdated(const cabana::Signal *sig);
 | |
|   void manageSignals();
 | |
|   void handleMarkerClicked();
 | |
|   void msgUpdated(MessageId id);
 | |
|   void msgRemoved(MessageId id) { removeIf([=](auto &s) { return s.msg_id.address == id.address && !dbc()->msg(id); }); }
 | |
|   void signalRemoved(const cabana::Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); }
 | |
| 
 | |
| private:
 | |
|   void appendCanEvents(const cabana::Signal *sig, const std::vector<const CanEvent *> &events,
 | |
|                        std::vector<QPointF> &vals, std::vector<QPointF> &step_vals);
 | |
|   void createToolButtons();
 | |
|   void addSeries(QXYSeries *series);
 | |
|   void contextMenuEvent(QContextMenuEvent *event) override;
 | |
|   void mousePressEvent(QMouseEvent *event) override;
 | |
|   void mouseReleaseEvent(QMouseEvent *event) override;
 | |
|   void mouseMoveEvent(QMouseEvent *ev) override;
 | |
|   void dragEnterEvent(QDragEnterEvent *event) override;
 | |
|   void dragLeaveEvent(QDragLeaveEvent *event) override { drawDropIndicator(false); }
 | |
|   void dragMoveEvent(QDragMoveEvent *event) override;
 | |
|   void dropEvent(QDropEvent *event) override;
 | |
|   void resizeEvent(QResizeEvent *event) override;
 | |
|   QSize sizeHint() const override;
 | |
|   void updateAxisY();
 | |
|   void updateTitle();
 | |
|   void resetChartCache();
 | |
|   void setTheme(QChart::ChartTheme theme);
 | |
|   void paintEvent(QPaintEvent *event) override;
 | |
|   void drawForeground(QPainter *painter, const QRectF &rect) override;
 | |
|   void drawBackground(QPainter *painter, const QRectF &rect) override;
 | |
|   void drawDropIndicator(bool draw) { if (std::exchange(can_drop, draw) != can_drop) viewport()->update(); }
 | |
|   void drawSignalValue(QPainter *painter);
 | |
|   void drawTimeline(QPainter *painter);
 | |
|   void drawRubberBandTimeRange(QPainter *painter);
 | |
|   std::tuple<double, double, int> getNiceAxisNumbers(qreal min, qreal max, int tick_count);
 | |
|   qreal niceNumber(qreal x, bool ceiling);
 | |
|   QXYSeries *createSeries(SeriesType type, QColor color);
 | |
|   void setSeriesColor(QXYSeries *, QColor color);
 | |
|   void updateSeriesPoints();
 | |
|   void removeIf(std::function<bool(const SigItem &)> predicate);
 | |
|   inline void clearTrackPoints() { for (auto &s : sigs) s.track_pt = {}; }
 | |
| 
 | |
|   int y_label_width = 0;
 | |
|   int align_to = 0;
 | |
|   QValueAxis *axis_x;
 | |
|   QValueAxis *axis_y;
 | |
|   QMenu *menu;
 | |
|   QAction *split_chart_act;
 | |
|   QAction *close_act;
 | |
|   QGraphicsPixmapItem *move_icon;
 | |
|   QGraphicsProxyWidget *close_btn_proxy;
 | |
|   QGraphicsProxyWidget *manage_btn_proxy;
 | |
|   TipLabel *tip_label;
 | |
|   std::vector<SigItem> sigs;
 | |
|   double cur_sec = 0;
 | |
|   SeriesType series_type = SeriesType::Line;
 | |
|   bool is_scrubbing = false;
 | |
|   bool resume_after_scrub = false;
 | |
|   QPixmap chart_pixmap;
 | |
|   bool can_drop = false;
 | |
|   double tooltip_x = -1;
 | |
|   QFont signal_value_font;
 | |
|   ChartsWidget *charts_widget;
 | |
|   friend class ChartsWidget;
 | |
| };
 | |
| 
 |