@ -4,11 +4,9 @@ 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QGraphicsLayout>  
					 
					 
					 
					# include  <QGraphicsLayout>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QRubberBand>  
					 
					 
					 
					# include  <QRubberBand>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QTimer>  
					 
					 
					 
					# include  <QTimer>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					# include  <QToolBar>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QToolButton>  
					 
					 
					 
					# include  <QToolButton>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QtCharts/QLineSeries>  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QtCharts/QValueAxis>  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QtConcurrent>  
					 
					 
					 
					# include  <QtConcurrent>  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					# include  <QToolBar>  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					// ChartsWidget
  
					 
					 
					 
					// ChartsWidget
  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -19,7 +17,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // toolbar
   
					 
					 
					 
					  // toolbar
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QToolBar  * toolbar  =  new  QToolBar ( tr ( " Charts " ) ,  this ) ;   
					 
					 
					 
					  QToolBar  * toolbar  =  new  QToolBar ( tr ( " Charts " ) ,  this ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  title_label  =  new  QLabel ( ) ;   
					 
					 
					 
					  title_label  =  new  QLabel ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  title_label - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;   
					 
					 
					 
					  title_label - > setSizePolicy ( QSizePolicy : : Expanding ,   QSizePolicy : : Preferred ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  toolbar - > addWidget ( title_label ) ;   
					 
					 
					 
					  toolbar - > addWidget ( title_label ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  toolbar - > addWidget ( range_label  =  new  QLabel ( ) ) ;   
					 
					 
					 
					  toolbar - > addWidget ( range_label  =  new  QLabel ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  reset_zoom_btn  =  toolbar - > addAction ( " ⟲ " ) ;   
					 
					 
					 
					  reset_zoom_btn  =  toolbar - > addAction ( " ⟲ " ) ;   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -42,21 +40,10 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  main_layout - > addWidget ( charts_scroll ) ;   
					 
					 
					 
					  main_layout - > addWidget ( charts_scroll ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : DBCFileChanged ,  [ this ] ( )  {  removeAll ( nullptr ) ;  } ) ;   
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : DBCFileChanged ,  this ,  & ChartsWidget : : removeAll ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : signalRemoved ,  this ,  & ChartsWidget : : removeAll ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : signalUpdated ,  this ,  & ChartsWidget : : signalUpdated ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : msgRemoved ,  [ this ] ( uint32_t  address )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  ( auto  c  :  charts . toVector ( ) )   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      if  ( DBCManager : : parseId ( c - > id ) . second  = =  address )  removeChart ( c ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dbc ( ) ,  & DBCManager : : msgUpdated ,  [ this ] ( uint32_t  address )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  ( auto  c  :  charts )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      if  ( DBCManager : : parseId ( c - > id ) . second  = =  address )  c - > updateTitle ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    }   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( can ,  & CANMessages : : eventsMerged ,  this ,  & ChartsWidget : : eventsMerged ) ;   
					 
					 
					 
					  QObject : : connect ( can ,  & CANMessages : : eventsMerged ,  this ,  & ChartsWidget : : eventsMerged ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( can ,  & CANMessages : : updated ,  this ,  & ChartsWidget : : updateState ) ;   
					 
					 
					 
					  QObject : : connect ( can ,  & CANMessages : : updated ,  this ,  & ChartsWidget : : updateState ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( remove_all_btn ,  & QAction : : triggered ,  [ this ] ( )  {  removeAll ( ) ;  } ) ;   
					 
					 
					 
					  QObject : : connect ( remove_all_btn ,  & QAction : : triggered ,  this ,  & ChartsWidget : : removeAll ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( reset_zoom_btn ,  & QAction : : triggered ,  this ,  & ChartsWidget : : zoomReset ) ;   
					 
					 
					 
					  QObject : : connect ( reset_zoom_btn ,  & QAction : : triggered ,  this ,  & ChartsWidget : : zoomReset ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( dock_btn ,  & QAction : : triggered ,  [ this ] ( )  {   
					 
					 
					 
					  QObject : : connect ( dock_btn ,  & QAction : : triggered ,  [ this ] ( )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    emit  dock ( ! docking ) ;   
					 
					 
					 
					    emit  dock ( ! docking ) ;   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -81,8 +68,8 @@ void ChartsWidget::zoomIn(double min, double max) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  zoomed_range  =  { min ,  max } ;   
					 
					 
					 
					  zoomed_range  =  { min ,  max } ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  is_zoomed  =  zoomed_range  ! =  display_range ;   
					 
					 
					 
					  is_zoomed  =  zoomed_range  ! =  display_range ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  updateToolBar ( ) ;   
					 
					 
					 
					  updateToolBar ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  emit  rangeChanged ( min ,  max ,  is_zoomed ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  updateState ( ) ;   
					 
					 
					 
					  updateState ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  emit  rangeChanged ( min ,  max ,  is_zoomed ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartsWidget : : zoomReset ( )  {  
					 
					 
					 
					void  ChartsWidget : : zoomReset ( )  {  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -108,13 +95,13 @@ 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 ,  & ChartView : : updateSeries ,  display_range ) ) ;   
					 
					 
					 
					        future_synchronizer . addFuture ( QtConcurrent : : run ( c ,  & ChartView : : setEventsRange ,  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 - > setRange ( range . first ,  range . second ) ;   
					 
					 
					 
					    c - > setDisplay Range ( range . first ,  range . second ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    c - > updateLineMarker ( current_sec ) ;   
					 
					 
					 
					    c - > updateLineMarker ( current_sec ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -128,49 +115,45 @@ void ChartsWidget::updateToolBar() { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  dock_btn - > setToolTip ( docking  ?  tr ( " Undock charts " )  :  tr ( " Dock charts " ) ) ;   
					 
					 
					 
					  dock_btn - > setToolTip ( docking  ?  tr ( " Undock charts " )  :  tr ( " Dock charts " ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartsWidget : : showChart ( const  QString  & id ,  const  Signal  * sig ,  bool  show )  {  
					 
					 
					 
					ChartView  * ChartsWidget : : findChart ( const  QString  & id ,  const  Signal  * sig )  {  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  it  =  std : : find_if ( charts . begin ( ) ,  charts . end ( ) ,  [ = ] ( auto  c )  {  return  c - > id  = =  id  & &  c - > signal  = =  sig ;  } ) ;   
					 
					 
					 
					  for  ( auto  c  :  charts )   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( it  ! =  charts . end ( ) )  {   
					 
					 
					 
					    if  ( c - > hasSeries ( id ,  sig ) )  return  c ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( ! show )  removeChart ( ( * it ) ) ;   
					 
					 
					 
					  return  nullptr ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  }  else  if  ( show )  {   
					 
					 
					 
					}  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  chart  =  new  ChartView ( id ,  sig ,  this ) ;   
					 
					 
					 
					
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    chart - > updateSeries ( display_range ) ;   
					 
					 
					 
					void  ChartsWidget : : showChart ( const  QString  & id ,  const  Signal  * sig ,  bool  show ,  bool  merge )  {  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    QObject : : connect ( chart ,  & ChartView : : remove ,  [ = ] ( )  {  removeChart ( chart ) ;  } ) ;   
					 
					 
					 
					  if  ( ! show )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    QObject : : connect ( chart ,  & ChartView : : zoomIn ,  this ,  & ChartsWidget : : zoomIn ) ;   
					 
					 
					 
					    if  ( ChartView  * chart  =  findChart ( id ,  sig ) )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    QObject : : connect ( chart ,  & ChartView : : zoomReset ,  this ,  & ChartsWidget : : zoomReset ) ;   
					 
					 
					 
					      chart - > removeSeries ( id ,  sig ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    charts_layout - > insertWidget ( 0 ,  chart ) ;   
					 
					 
					 
					    }   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    charts . push_back ( chart ) ;   
					 
					 
					 
					  }  else  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    emit  chartOpened ( chart - > id ,  chart - > signal ) ;   
					 
					 
					 
					    ChartView  * chart  =  merge  & &  charts . size ( )  >  0  ?  charts . back ( )  :  nullptr ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    if  ( ! chart )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      chart  =  new  ChartView ( this ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      chart - > setEventsRange ( display_range ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      QObject : : connect ( chart ,  & ChartView : : remove ,  [ = ] ( )  {  removeChart ( chart ) ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      QObject : : connect ( chart ,  & ChartView : : zoomIn ,  this ,  & ChartsWidget : : zoomIn ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      QObject : : connect ( chart ,  & ChartView : : zoomReset ,  this ,  & ChartsWidget : : zoomReset ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      QObject : : connect ( chart ,  & ChartView : : seriesRemoved ,  this ,  & ChartsWidget : : chartClosed ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      charts_layout - > insertWidget ( 0 ,  chart ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      charts . push_back ( chart ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    chart - > addSeries ( id ,  sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    emit  chartOpened ( id ,  sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    updateState ( ) ;   
					 
					 
					 
					    updateState ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  updateToolBar ( ) ;   
					 
					 
					 
					  updateToolBar ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					bool  ChartsWidget : : isChartOpened ( const  QString  & id ,  const  Signal  * sig )  {  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  it  =  std : : find_if ( charts . begin ( ) ,  charts . end ( ) ,  [ = ] ( auto  c )  {  return  c - > id  = =  id  & &  c - > signal  = =  sig ;  } ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  return  it  ! =  charts . end ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartsWidget : : removeChart ( ChartView  * chart )  {  
					 
					 
					 
					void  ChartsWidget : : removeChart ( ChartView  * chart )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  charts . removeOne ( chart ) ;   
					 
					 
					 
					  charts . removeOne ( chart ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > deleteLater ( ) ;   
					 
					 
					 
					  chart - > deleteLater ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  updateToolBar ( ) ;   
					 
					 
					 
					  updateToolBar ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  emit  chartClosed ( chart - > id ,  chart - > signal ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartsWidget : : removeAll ( const  Signal  * sig )  {  
					 
					 
					 
					void  ChartsWidget : : removeAll ( )  {  
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto  c  :  charts . toVector ( ) )   
					 
					 
					 
					  for  ( auto  c  :  charts . toVector ( ) )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( ! sig  | |  c - > signal  = =  sig )  removeChart ( c ) ;   
					 
					 
					 
					    removeChart ( c ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartsWidget : : signalUpdated ( const  Signal  * sig )  {  
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto  c  :  charts )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( c - > signal  = =  sig )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      c - > updateTitle ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      c - > updateSeries ( display_range ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      c - > setRange ( display_range . first ,  display_range . second ,  true ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    }   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					bool  ChartsWidget : : eventFilter ( QObject  * obj ,  QEvent  * event )  {  
					 
					 
					 
					bool  ChartsWidget : : eventFilter ( QObject  * obj ,  QEvent  * event )  {  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -183,14 +166,14 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					// ChartView
  
					 
					 
					 
					// ChartView
  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					ChartView : : ChartView ( const  QString  & id ,  const  Signal  * sig ,  QWidget  * parent )  
					 
					 
					 
					ChartView : : ChartView ( QWidget  * parent )  :  QChartView ( nullptr ,  parent )  {  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    :  id ( id ) ,  signal ( sig ) ,  QChartView ( nullptr ,  parent )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QLineSeries  * series  =  new  QLineSeries ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  QChart  * chart  =  new  QChart ( ) ;   
					 
					 
					 
					  QChart  * chart  =  new  QChart ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > setBackgroundRoundness ( 0 ) ;   
					 
					 
					 
					  chart - > setBackgroundRoundness ( 0 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > addSeries ( series ) ;   
					 
					 
					 
					  axis_x  =  new  QValueAxis ( this ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > createDefaultAxes ( ) ;   
					 
					 
					 
					  axis_y  =  new  QValueAxis ( this ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > legend ( ) - > hide ( ) ;   
					 
					 
					 
					  chart - > addAxis ( axis_x ,  Qt : : AlignBottom ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  chart - > addAxis ( axis_y ,  Qt : : AlignLeft ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  chart - > legend ( ) - > setShowToolTips ( true ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > layout ( ) - > setContentsMargins ( 0 ,  0 ,  0 ,  0 ) ;   
					 
					 
					 
					  chart - > layout ( ) - > setContentsMargins ( 0 ,  0 ,  0 ,  0 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // top margin for title
   
					 
					 
					 
					  // top margin for title
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart - > setMargins ( { 0 ,  11 ,  0 ,  0 } ) ;   
					 
					 
					 
					  chart - > setMargins ( { 0 ,  11 ,  0 ,  0 } ) ;   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -213,33 +196,108 @@ ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent) 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  remove_btn - > setToolTip ( tr ( " Remove Chart " ) ) ;   
					 
					 
					 
					  remove_btn - > setToolTip ( tr ( " Remove Chart " ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  close_btn_proxy  =  new  QGraphicsProxyWidget ( chart ) ;   
					 
					 
					 
					  close_btn_proxy  =  new  QGraphicsProxyWidget ( chart ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  close_btn_proxy - > setWidget ( remove_btn ) ;   
					 
					 
					 
					  close_btn_proxy - > setWidget ( remove_btn ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  close_btn_proxy - > setZValue ( chart - > zValue ( )  +  11 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  setChart ( chart ) ;   
					 
					 
					 
					  setChart ( chart ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  setRenderHint ( QPainter : : Antialiasing ) ;   
					 
					 
					 
					  setRenderHint ( QPainter : : Antialiasing ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  setRubberBand ( QChartView : : HorizontalRubberBand ) ;   
					 
					 
					 
					  setRubberBand ( QChartView : : HorizontalRubberBand ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  updateFromSettings ( ) ;   
					 
					 
					 
					  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 ( 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 ( & settings ,  & Settings : : changed ,  this ,  & ChartView : : updateFromSettings ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QObject : : connect ( remove_btn ,  & QToolButton : : clicked ,  [ = ] ( )  {  emit  remove ( id ,  sig ) ;  } ) ;   
					 
					 
					 
					  QObject : : connect ( remove_btn ,  & QToolButton : : clicked ,  this ,  & ChartView : : remove ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  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 ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  } ) ;   
					 
					 
					 
					  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					ChartView : : ~ ChartView ( )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  for  ( auto  & s  :  sigs )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    emit  seriesRemoved ( s . msg_id ,  s . sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : addSeries ( const  QString  & msg_id ,  const  Signal  * sig )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  QLineSeries  * series  =  new  QLineSeries ( this ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  chart ( ) - > addSeries ( series ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  series - > attachAxis ( axis_x ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  series - > attachAxis ( axis_y ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  [ source ,  address ]  =  DBCManager : : parseId ( msg_id ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  sigs . push_back ( { . msg_id  =  msg_id ,  . address  =  address ,  . source  =  source ,  . sig  =  sig ,  . series  =  series } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  updateTitle ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  updateSeries ( sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : removeSeries ( const  QString  & msg_id ,  const  Signal  * sig )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  it  =  std : : find_if ( sigs . begin ( ) ,  sigs . end ( ) ,  [ & ] ( auto  & s )  {  return  s . msg_id  = =  msg_id  & &  s . sig  = =  sig ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( it  ! =  sigs . end ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    it  =  removeSeries ( it ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					bool  ChartView : : hasSeries ( const  QString  & msg_id ,  const  Signal  * sig )  const  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  it  =  std : : find_if ( sigs . begin ( ) ,  sigs . end ( ) ,  [ & ] ( auto  & s )  {  return  s . msg_id  = =  msg_id  & &  s . sig  = =  sig ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  return  it  ! =  sigs . end ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					QList < ChartView : : SigItem > : : iterator  ChartView : : removeSeries ( const  QList < ChartView : : SigItem > : : iterator  & it )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  chart ( ) - > removeSeries ( it - > series ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  it - > series - > deleteLater ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  emit  seriesRemoved ( it - > msg_id ,  it - > sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  ret  =  sigs . erase ( it ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( ! sigs . isEmpty ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    updateAxisY ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }  else  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    emit  remove ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  return  ret ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : signalUpdated ( const  Signal  * sig )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  it  =  std : : find_if ( sigs . begin ( ) ,  sigs . end ( ) ,  [ = ] ( auto  & s )  {  return  s . sig  = =  sig ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( it  ! =  sigs . end ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    updateTitle ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    // TODO: don't update series if only name changed.
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    updateSeries ( sig ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : signalRemoved ( const  Signal  * sig )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  for  ( auto  it  =  sigs . begin ( ) ;  it  ! =  sigs . end ( ) ;  /**/ )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    it  =  ( it - > sig  = =  sig )  ?  removeSeries ( it )  :  + + it ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : msgUpdated ( uint32_t  address )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  it  =  std : : find_if ( sigs . begin ( ) ,  sigs . end ( ) ,  [ = ] ( auto  & s )  {  return  s . address  = =  address ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( it  ! =  sigs . end ( ) )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    updateTitle ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : msgRemoved ( uint32_t  address )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  for  ( auto  it  =  sigs . begin ( ) ;  it  ! =  sigs . end ( ) ;  /**/ )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    it  =  ( it - > address  = =  address )  ?  removeSeries ( it )  :  + + it ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : resizeEvent ( QResizeEvent  * event )  {  
					 
					 
					 
					void  ChartView : : resizeEvent ( QResizeEvent  * event )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QChartView : : resizeEvent ( event ) ;   
					 
					 
					 
					  QChartView : : resizeEvent ( event ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  close_btn_proxy - > setPos ( event - > size ( ) . width ( )  -  close_btn_proxy - > size ( ) . width ( )  -  11 ,  8 ) ;   
					 
					 
					 
					  close_btn_proxy - > setPos ( event - > size ( ) . width ( )  -  close_btn_proxy - > size ( ) . width ( )  -  11 ,  8 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : updateTitle ( )  {  
					 
					 
					 
					void  ChartView : : updateTitle ( )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  chart ( ) - > setTitle ( tr ( " <font color= \" gray \"  text-align:left>%1 %2</font> <b>%3</b> " ) . arg ( dbc ( ) - > msg ( id ) - > name ) . arg ( id ) . arg ( signal - > name . c_str ( ) ) ) ;   
					 
					 
					 
					  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 ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : updateFromSettings ( )  {  
					 
					 
					 
					void  ChartView : : updateFromSettings ( )  {  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -249,9 +307,15 @@ void ChartView::updateFromSettings() { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  line_marker - > setPen ( QPen ( color ,  2 ) ) ;   
					 
					 
					 
					  line_marker - > setPen ( QPen ( color ,  2 ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : setRange ( double  min ,  double  max ,  bool  force_update )  {  
					 
					 
					 
					void  ChartView : : setEventsRange ( const  std : : pair < double ,  double >  & range )  {  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  axis_x  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisX ( ) ) ;   
					 
					 
					 
					  if  ( range  ! =  events_range )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( force_update  | |  ( min  ! =  axis_x - > min ( )  | |  max  ! =  axis_x - > max ( ) ) )  {   
					 
					 
					 
					    events_range  =  range ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    updateSeries ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					void  ChartView : : setDisplayRange ( double  min ,  double  max )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( min  ! =  axis_x - > min ( )  | |  max  ! =  axis_x - > max ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    axis_x - > setRange ( min ,  max ) ;   
					 
					 
					 
					    axis_x - > setRange ( min ,  max ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    updateAxisY ( ) ;   
					 
					 
					 
					    updateAxisY ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -268,7 +332,6 @@ void ChartView::adjustChartMargins() { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : updateLineMarker ( double  current_sec )  {  
					 
					 
					 
					void  ChartView : : updateLineMarker ( double  current_sec )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  axis_x  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisX ( ) ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  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 )  {   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -276,48 +339,72 @@ void ChartView::updateLineMarker(double current_sec) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : updateSeries ( const  std : : pair < double ,  double >  range )  {  
					 
					 
					 
					void  ChartView : : updateSeries ( const  Signal  * sig )  {  
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  auto  events  =  can - > events ( ) ;   
					 
					 
					 
					  auto  events  =  can - > events ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( ! events )  return ;   
					 
					 
					 
					  if  ( ! events )  return ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  vals . clear ( ) ;   
					 
					 
					 
					  for  ( int  i  =  0 ;  i  <  sigs . size ( ) ;  + + i )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  vals . reserve ( ( range . second  -  range . first )  *  1000 ) ;   // [n]seconds * 1000hz
   
					 
					 
					 
					    if  ( auto  & s  =  sigs [ i ] ;  ! sig  | |  s . sig  = =  sig )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  [ bus ,  address ]  =  DBCManager : : parseId ( id ) ;   
					 
					 
					 
					      s . vals . clear ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  double  route_start_time  =  can - > routeStartTime ( ) ;   
					 
					 
					 
					      s . vals . reserve ( ( events_range . second  -  events_range . first )  *  1000 ) ;   // [n]seconds * 1000hz
   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  Event  begin_event ( cereal : : Event : : Which : : INIT_DATA ,  ( route_start_time  +  range . first )  *  1e9 ) ;   
					 
					 
					 
					      s . min_y  =  std : : numeric_limits < double > : : max ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  begin  =  std : : lower_bound ( events - > begin ( ) ,  events - > end ( ) ,  & begin_event ,  Event : : lessThan ( ) ) ;   
					 
					 
					 
					      s . max_y  =  std : : numeric_limits < double > : : lowest ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  double  end_ns  =  ( route_start_time  +  range . second )  *  1e9 ;   
					 
					 
					 
					
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  for  ( auto  it  =  begin ;  it  ! =  events - > end ( )  & &  ( * it ) - > mono_time  < =  end_ns ;  + + it )  {   
					 
					 
					 
					      double  route_start_time  =  can - > routeStartTime ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( ( * it ) - > which  = =  cereal : : Event : : Which : : CAN )  {   
					 
					 
					 
					      Event  begin_event ( cereal : : Event : : Which : : INIT_DATA ,  ( route_start_time  +  events_range . first )  *  1e9 ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					      for  ( const  auto  & c  :  ( * it ) - > event . getCan ( ) )  {   
					 
					 
					 
					      auto  begin  =  std : : lower_bound ( events - > begin ( ) ,  events - > end ( ) ,  & begin_event ,  Event : : lessThan ( ) ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        if  ( bus  = =  c . getSrc ( )  & &  address  = =  c . getAddress ( ) )  {   
					 
					 
					 
					      double  end_ns  =  ( route_start_time  +  events_range . second )  *  1e9 ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					          auto  dat  =  c . getDat ( ) ;   
					 
					 
					 
					
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					          double  value  =  get_raw_value ( ( uint8_t  * ) dat . begin ( ) ,  dat . size ( ) ,  * signal ) ;   
					 
					 
					 
					      for  ( auto  it  =  begin ;  it  ! =  events - > end ( )  & &  ( * it ) - > mono_time  < =  end_ns ;  + + it )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					          double  ts  =  ( ( * it ) - > mono_time  /  ( double ) 1e9 )  -  route_start_time ;   // seconds
   
					 
					 
					 
					        if  ( ( * it ) - > which  = =  cereal : : Event : : Which : : CAN )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					          vals . push_back ( { ts ,  value } ) ;   
					 
					 
					 
					          for  ( const  auto  & c  :  ( * it ) - > event . getCan ( ) )  {   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					            if  ( s . source  = =  c . getSrc ( )  & &  s . address  = =  c . getAddress ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					              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
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					              s . vals . push_back ( { ts ,  value } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					              if  ( value  <  s . min_y )  s . min_y  =  value ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					              if  ( value  >  s . max_y )  s . max_y  =  value ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					            }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					          }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        }   
					 
					 
					 
					        }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      }   
					 
					 
					 
					      }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      QLineSeries  * series  =  ( QLineSeries  * ) chart ( ) - > series ( ) [ i ] ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      series - > replace ( s . vals ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    }   
					 
					 
					 
					    }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QLineSeries  * series  =  ( QLineSeries  * ) chart ( ) - > series ( ) [ 0 ] ;   
					 
					 
					 
					  updateAxisY ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  series - > replace ( vals ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					// auto zoom on yaxis
  
					 
					 
					 
					// auto zoom on yaxis
  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : updateAxisY ( )  {  
					 
					 
					 
					void  ChartView : : updateAxisY ( )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  const  auto  axis_x  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisX ( ) ) ;   
					 
					 
					 
					  double  min_y  =  std : : numeric_limits < double > : : max ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  const  auto  axis_y  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisY ( ) ) ;   
					 
					 
					 
					  double  max_y  =  std : : numeric_limits < double > : : lowest ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  begin  =  std : : lower_bound ( vals . begin ( ) ,  vals . end ( ) ,  axis_x - > min ( ) ,  [ ] ( auto  & p ,  double  x )  {  return  p . x ( )  <  x ;  } ) ;   
					 
					 
					 
					  if  ( events_range  = =  std : : pair { axis_x - > min ( ) ,  axis_x - > max ( ) } )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( begin  = =  vals . end ( ) )   
					 
					 
					 
					    for  ( auto  & s  :  sigs )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    return ;   
					 
					 
					 
					      if  ( s . min_y  <  min_y )  min_y  =  s . min_y ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					      if  ( s . max_y  >  max_y )  max_y  =  s . max_y ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  end  =  std : : upper_bound ( vals . begin ( ) ,  vals . end ( ) ,  axis_x - > max ( ) ,  [ ] ( double  x ,  auto  & p )  {  return  x  <  p . x ( ) ;  } ) ;   
					 
					 
					 
					    }   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  const  auto  [ min ,  max ]  =  std : : minmax_element ( begin ,  end ,  [ ] ( auto  & p1 ,  auto  & p2 )  {  return  p1 . y ( )  <  p2 . y ( ) ;  } ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( max - > y ( )  = =  min - > y ( ) )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    axis_y - > setRange ( min - > y ( )  -  1 ,  max - > y ( )  +  1 ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  }  else  {   
					 
					 
					 
					  }  else  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    double  range  =  max - > y ( )  -  min - > y ( ) ;   
					 
					 
					 
					    for  ( auto  & s  :  sigs )  {   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    axis_y - > setRange ( min - > y ( )  -  range  *  0.05 ,  max - > y ( )  +  range  *  0.05 ) ;   
					 
					 
					 
					      auto  begin  =  std : : lower_bound ( s . vals . begin ( ) ,  s . vals . end ( ) ,  axis_x - > min ( ) ,  [ ] ( auto  & p ,  double  x )  {  return  p . x ( )  <  x ;  } ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      if  ( begin  = =  s . vals . end ( ) )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        return ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      auto  end  =  std : : upper_bound ( s . vals . begin ( ) ,  s . vals . end ( ) ,  axis_x - > max ( ) ,  [ ] ( double  x ,  auto  & p )  {  return  x  <  p . x ( ) ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      const  auto  [ min ,  max ]  =  std : : minmax_element ( begin ,  end ,  [ ] ( auto  & p1 ,  auto  & p2 )  {  return  p1 . y ( )  <  p2 . y ( ) ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      if  ( min - > y ( )  <  min_y )  min_y  =  min - > y ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      if  ( max - > y ( )  >  max_y )  max_y  =  max - > y ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( max_y  = =  min_y )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    axis_y - > setRange ( min_y  -  1 ,  max_y  +  1 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }  else  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    double  range  =  max_y  -  min_y ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    axis_y - > setRange ( min_y  -  range  *  0.05 ,  max_y  +  range  *  0.05 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    axis_y - > applyNiceNumbers ( ) ;   
					 
					 
					 
					    axis_y - > applyNiceNumbers ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -333,7 +420,6 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    rubber - > hide ( ) ;   
					 
					 
					 
					    rubber - > hide ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    QRectF  rect  =  rubber - > geometry ( ) . normalized ( ) ;   
					 
					 
					 
					    QRectF  rect  =  rubber - > geometry ( ) . normalized ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    rect . translate ( - chart ( ) - > plotArea ( ) . topLeft ( ) ) ;   
					 
					 
					 
					    rect . translate ( - chart ( ) - > plotArea ( ) . topLeft ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    const  auto  axis_x  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisX ( ) ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    double  min  =  axis_x - > min ( )  +  ( rect . left ( )  /  chart ( ) - > plotArea ( ) . width ( ) )  *  ( axis_x - > max ( )  -  axis_x - > min ( ) ) ;   
					 
					 
					 
					    double  min  =  axis_x - > min ( )  +  ( rect . left ( )  /  chart ( ) - > plotArea ( ) . width ( ) )  *  ( axis_x - > max ( )  -  axis_x - > min ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    double  max  =  axis_x - > min ( )  +  ( rect . right ( )  /  chart ( ) - > plotArea ( ) . width ( ) )  *  ( axis_x - > max ( )  -  axis_x - > min ( ) ) ;   
					 
					 
					 
					    double  max  =  axis_x - > min ( )  +  ( rect . right ( )  /  chart ( ) - > plotArea ( ) . width ( ) )  *  ( axis_x - > max ( )  -  axis_x - > min ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( rubber - > width ( )  < =  0 )  {   
					 
					 
					 
					    if  ( rubber - > width ( )  < =  0 )  {   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -357,26 +443,40 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  ChartView : : mouseMoveEvent ( QMouseEvent  * ev )  {  
					 
					 
					 
					void  ChartView : : mouseMoveEvent ( QMouseEvent  * ev )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  rubber  =  findChild < QRubberBand  * > ( ) ;   
					 
					 
					 
					  auto  rubber  =  findChild < QRubberBand  * > ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  bool  is_zooming  =  rubber  & &  rubber - > isVisible ( ) ;   
					 
					 
					 
					  bool  is_zooming  =  rubber  & &  rubber - > isVisible ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( ! is_zooming )  {   
					 
					 
					 
					  const  auto  plot_area  =  chart ( ) - > plotArea ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    const  auto  plot_area  =  chart ( ) - > plotArea ( ) ;   
					 
					 
					 
					
  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    auto  axis_x  =  dynamic_cast < QValueAxis  * > ( chart ( ) - > axisX ( ) ) ;    
					 
					 
					 
					  if  ( ! is_zooming  & &  plot_area . contains ( ev - > pos ( ) ) )  {   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    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 ( ) ;  } ) ;   
					 
					 
					 
					    QStringList  text_list ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( value  ! =  vals . end ( ) )  {   
					 
					 
					 
					    QPointF  pos  =  plot_area . bottomRight ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					      QPointF  pos  =  chart ( ) - > mapToPosition ( ( * value ) ) ;   
					 
					 
					 
					    double  tm  =  0.0 ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    for  ( auto  & s  :  sigs )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      auto  value  =  std : : upper_bound ( s . vals . begin ( ) ,  s . vals . end ( ) ,  sec ,  [ ] ( double  x ,  auto  & p )  {  return  x  <  p . x ( ) ;  } ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      if  ( value  ! =  s . vals . end ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        text_list . push_back ( QString ( "  %1 : %2  " ) . arg ( sigs . size ( )  >  1  ?  s . sig - > name . c_str ( )  :  " Value " ) . arg ( value - > y ( ) ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        tm  =  value - > x ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        auto  y_pos  =  chart ( ) - > mapToPosition ( * value ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        if  ( y_pos . y ( )  <  pos . y ( ) )  pos  =  y_pos ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    if  ( ! text_list . isEmpty ( ) )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      value_text - > setHtml ( " <div style= \" background-color: darkGray;color: white; \" > Time:  "  +   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					                          QString : : number ( tm ,  ' f ' ,  3 )  +  "  <br /> "  +  text_list . join ( " <br /> " )  +  " </div> " ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      track_line - > setLine ( pos . x ( ) ,  plot_area . top ( ) ,  pos . x ( ) ,  plot_area . bottom ( ) ) ;   
					 
					 
					 
					      track_line - > setLine ( pos . x ( ) ,  plot_area . top ( ) ,  pos . x ( ) ,  plot_area . bottom ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      track_ellipse - > setRect ( pos . x ( )  -  5 ,  pos . y ( )  -  5 ,  10 ,  10 ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      value_text - > setHtml ( tr ( " <div style='background-color:darkGray'><font color='white'>%1, %2)</font></div> " )   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                              . arg ( value - > x ( ) ,  0 ,  ' f ' ,  3 ) . arg ( value - > y ( ) ) ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      int  text_x  =  pos . x ( )  +  8 ;   
					 
					 
					 
					      int  text_x  =  pos . x ( )  +  8 ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      if  ( ( text_x  +  value_text - > boundingRect ( ) . width ( ) )  >  plot_area . right ( ) )  {   
					 
					 
					 
					      QRectF  text_rect  =  value_text - > boundingRect ( ) ;   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					        text_x  =  pos . x ( )  -  value_text - > boundingRect ( ) . width ( )  -  8 ;   
					 
					 
					 
					      if  ( ( text_x  +  text_rect . width ( ) )  >  plot_area . right ( ) )  {   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        text_x  =  pos . x ( )  -  text_rect . width ( )  -  8 ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      }   
					 
					 
					 
					      }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      value_text - > setPos ( text_x ,  pos . y ( )  -  10 ) ;   
					 
					 
					 
					      value_text - > setPos ( text_x ,  pos . y ( )  -  text_rect . height ( )  /  2 ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      track_ellipse - > setRect ( pos . x ( )  -  5 ,  pos . y ( )  -  5 ,  10 ,  10 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    }   
					 
					 
					 
					    }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    item_group - > setVisible ( value  ! =  vals . end ( ) ) ;   
					 
					 
					 
					    item_group - > setVisible ( ! text_list . isEmpty ( ) ) ;   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					  }  else  {   
					 
					 
					 
					  }  else  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    item_group - > setVisible ( false ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    setViewportUpdateMode ( QGraphicsView : : FullViewportUpdate ) ;   
					 
					 
					 
					    setViewportUpdateMode ( QGraphicsView : : FullViewportUpdate ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  QChartView : : mouseMoveEvent ( ev ) ;   
					 
					 
					 
					  QChartView : : mouseMoveEvent ( ev ) ;