scottplot使用2

使用DataLogger添加数据,增加多轴,多序列,2游标

XMl页面

  <UserControl.Resources>
      <BooleanToVisibilityConverter x:Key="b2v" />

      <DropShadowEffect
          x:Key="plotDSE"
          BlurRadius="15"
          Direction="0"
          Opacity="0.5"
          ShadowDepth="0"
          Color="#55FD9214" />

      <Style x:Key="NormMenuMainButtonStyle" TargetType="Button">
          <Setter Property="Foreground" Value="White" />
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="Button">
                      <Grid>
                          <Border
                              Name="back"
                              BorderThickness="0"
                              CornerRadius="3"
                              Opacity="1">
                              <Border.Background>
                                  <LinearGradientBrush StartPoint="0,1" EndPoint="1,0">
                                      <GradientStop Offset="0.3" Color="#FD9214" />
                                      <!--<GradientStop Offset="1" Color="#55FD9214" />-->
                                      <GradientStop Offset="1" Color="#FD9214" />
                                  </LinearGradientBrush>
                              </Border.Background>

                          </Border>
                          <Border
                              Margin="6,0"
                              HorizontalAlignment="Center"
                              Background="Transparent"
                              BorderBrush="{TemplateBinding BorderBrush}"
                              BorderThickness="0"
                              CornerRadius="4">
                              <ContentPresenter
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                  TextBlock.Foreground="{TemplateBinding Foreground}" />

                          </Border>
                      </Grid>
                      <ControlTemplate.Triggers>
                          <Trigger Property="IsEnabled" Value="False">
                              <Setter TargetName="back" Property="Background" Value="#ccc" />
                          </Trigger>

                          <Trigger Property="AreAnyTouchesOver" Value="True">
                              <Setter TargetName="back" Property="Opacity" Value="0.7" />
                              <Setter Property="Effect" Value="{DynamicResource plotDSE}" />
                          </Trigger>
                          <Trigger Property="IsMouseOver" Value="True">
                              <Setter TargetName="back" Property="Opacity" Value="0.7" />
                              <Setter Property="Effect" Value="{DynamicResource plotDSE}" />
                          </Trigger>

                      </ControlTemplate.Triggers>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
      </Style>


      <Style x:Key="CheckPlotBaseStyle" TargetType="CheckBox">
          <Setter Property="Foreground" Value="#212121" />
          <Setter Property="Margin" Value="0,5,10,5" />
          <Setter Property="IsChecked" Value="True" />
      </Style>
      <Style
          x:Key="SeriesItemStyle"
          BasedOn="{StaticResource CheckPlotBaseStyle}"
          TargetType="CheckBox">
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="CheckBox">
                      <Border
                          Name="root"
                          Height="30"
                          Background="#665D6B99"
                          CornerRadius="3">
                          <Grid>
                              <Grid.ColumnDefinitions>
                                  <ColumnDefinition Width="24" />
                                  <ColumnDefinition />
                              </Grid.ColumnDefinitions>
                              <Border
                                  Width="15"
                                  Height="15"
                                  Background="White">
                                  <Border
                                      Name="bor"
                                      Width="8"
                                      Height="8"
                                      Background="{TemplateBinding Background}"
                                      Visibility="Collapsed" />
                              </Border>
                              <ContentPresenter
                                  Name="txt"
                                  Grid.Column="1"
                                  Margin="8,0"
                                  VerticalAlignment="Center" />
                          </Grid>
                      </Border>
                      <ControlTemplate.Triggers>
                          <Trigger Property="IsChecked" Value="True">
                              <Setter TargetName="root" Property="Background" Value="#5D6B99" />
                              <Setter Property="Foreground" Value="White" />
                              <Setter TargetName="bor" Property="Visibility" Value="Visible" />
                          </Trigger>
                      </ControlTemplate.Triggers>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
      </Style>
  </UserControl.Resources>

  <Grid>
      <Grid.RowDefinitions>
          <RowDefinition Height="auto" />
          <RowDefinition Height="auto" />
          <RowDefinition />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition Width="auto" />
      </Grid.ColumnDefinitions>
      <!--  第一行  -->
      <Grid>

          <ItemsControl
              Margin="5,4"
              BorderBrush="#ccc"
              BorderThickness="0,0,0,1"
              ItemsSource="{Binding Serials}">
              <ItemsControl.ItemsPanel>
                  <ItemsPanelTemplate>
                      <WrapPanel />
                  </ItemsPanelTemplate>
              </ItemsControl.ItemsPanel>
              <ItemsControl.ItemTemplate>
                  <DataTemplate>
                      <Grid Margin="5,2">
                          <Grid.RowDefinitions>
                              <RowDefinition />
                              <RowDefinition />
                          </Grid.RowDefinitions>
                          <CheckBox
                              MinWidth="80"
                              HorizontalAlignment="Center"
                              Background="{Binding SerialColor}"
                              Content="{Binding SerialTitle}"
                              IsChecked="{Binding IsSelected}"
                              Style="{StaticResource SeriesItemStyle}" />

                          <Grid Grid.Row="1" Visibility="{Binding IsSelected, Converter={StaticResource b2v}}">
                              <Grid.ColumnDefinitions>
                                  <ColumnDefinition Width="20" />
                                  <ColumnDefinition />
                              </Grid.ColumnDefinitions>
                              <Border
                                  Width="10"
                                  Height="10"
                                  Margin="2"
                                  Background="{Binding SerialColor}"
                                  CornerRadius="10" />
                              <TextBlock Grid.Column="1" FontSize="14">
                                  <Run Text="当前值" />
                                  <Run Text="{Binding Unit, StringFormat={} {0} :}" />
                                  <Run Text="{Binding CurentY}" />
                              </TextBlock>

                          </Grid>

                      </Grid>


                  </DataTemplate>
              </ItemsControl.ItemTemplate>

          </ItemsControl>


      </Grid>
      <!--  第二列  -->
      <StackPanel Grid.RowSpan="3" Grid.Column="1">
          <Button
              Height="30"
              MinWidth="80"
              Margin="10,5,10,0"
              Command="{Binding LoadHistoryCommand}"
              Content="加载历史图标"
              Style="{StaticResource NormMenuMainButtonStyle}" />

          <CheckBox
              Name="noiu"
              MinWidth="80"
              Margin="10,5,10,0"
              HorizontalAlignment="Center"
              VerticalAlignment="Top"
              Background="#59A1DD"
              Content="显示游标"
              IsChecked="{Binding IsSelected}"
              Style="{StaticResource SeriesItemStyle}" />

      </StackPanel>


      <!--  第二行  -->
      <Grid
          Grid.Row="1"
          TextBlock.FontSize="14"
          Visibility="{Binding ElementName=noiu, Path=IsChecked, Converter={StaticResource b2v}}">
          <Border
              Margin="5,4"
              VerticalAlignment="Bottom"
              BorderBrush="#ccc"
              BorderThickness="0,0,0,1" />
          <WrapPanel Margin="14,0,0,4">
              <!--  x1  -->
              <Grid>
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="auto" />
                      <ColumnDefinition />
                  </Grid.ColumnDefinitions>
                  <TextBlock
                      Width="40"
                      VerticalAlignment="Center"
                      Background="{Binding NoniusLineModelX1.Color}"
                      Foreground="White"
                      Text="X1:"
                      TextAlignment="Center" />

                  <ItemsControl Grid.Column="1" ItemsSource="{Binding NoniusLineModelX1.NoinusDatas}">
                      <ItemsControl.ItemsPanel>
                          <ItemsPanelTemplate>
                              <WrapPanel />
                          </ItemsPanelTemplate>
                      </ItemsControl.ItemsPanel>
                      <ItemsControl.ItemTemplate>
                          <DataTemplate>
                              <Grid Margin="10,2">
                                  <Grid.ColumnDefinitions>
                                      <ColumnDefinition Width="auto" />
                                      <ColumnDefinition />
                                  </Grid.ColumnDefinitions>
                                  <Border
                                      Width="10"
                                      Height="10"
                                      Margin="2"
                                      Background="{Binding Color}"
                                      CornerRadius="10" />

                                  <TextBlock
                                      Grid.Column="1"
                                      VerticalAlignment="Center"
                                      Text="{Binding DataText}" />
                              </Grid>

                          </DataTemplate>
                      </ItemsControl.ItemTemplate>
                  </ItemsControl>

              </Grid>
              <!--  x2  -->
              <Grid Margin="30,0,0,0">
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="auto" />
                      <ColumnDefinition />
                  </Grid.ColumnDefinitions>
                  <TextBlock
                      Width="40"
                      VerticalAlignment="Center"
                      Background="{Binding NoniusLineModelX2.Color}"
                      Foreground="White"
                      Text="X2:"
                      TextAlignment="Center" />
                  <ItemsControl Grid.Column="1" ItemsSource="{Binding NoniusLineModelX2.NoinusDatas}">
                      <ItemsControl.ItemsPanel>
                          <ItemsPanelTemplate>
                              <WrapPanel />
                          </ItemsPanelTemplate>
                      </ItemsControl.ItemsPanel>
                      <ItemsControl.ItemTemplate>
                          <DataTemplate>
                              <Grid Margin="10,2">
                                  <Grid.ColumnDefinitions>
                                      <ColumnDefinition Width="auto" />
                                      <ColumnDefinition />
                                  </Grid.ColumnDefinitions>
                                  <Border
                                      Width="10"
                                      Height="10"
                                      Margin="2"
                                      Background="{Binding Color}"
                                      CornerRadius="10" />

                                  <TextBlock
                                      Grid.Column="1"
                                      VerticalAlignment="Center"
                                      Text="{Binding DataText}" />
                              </Grid>

                          </DataTemplate>
                      </ItemsControl.ItemTemplate>
                  </ItemsControl>
              </Grid>

          </WrapPanel>
      </Grid>

      <ContentControl
          Grid.Row="2"
          Grid.ColumnSpan="2"
          Margin="10,5"
          Padding="5"
          Content="{Binding SignalImage}" />
  </Grid>

游标类

   public class NoniusLineModel : INotifyPropertyChanged
   {
       private VerticalLine _verticalLineX;

       public VerticalLine VerticalLineX
       {
           get { return _verticalLineX; }
           set { _verticalLineX = value; }
       }
       private System.Windows.Media.Brush _color;

       public event PropertyChangedEventHandler? PropertyChanged;

       public System.Windows.Media.Brush Color
       {
           get { return _color; }
           set
           {
               _color = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Color)));
           }
       }

       public ObservableCollection<NoinusDataModel> NoinusDatas { get; set; } =
           new ObservableCollection<NoinusDataModel>();

       public NoniusLineModel() { }

       internal void InitNoinusLine(WpfPlot plot)
       {
           //初始化游标
           VerticalLineX = plot.Plot.Add.VerticalLine(10);
           VerticalLineX.IsDraggable = true;
           VerticalLineX.Text = "0000";
           VerticalLineX.LabelBold = false;
           VerticalLineX.LabelPixelPadding = new PixelPadding(15, 15, 5, 5);
           Color = ColorHelper.ConvertScottPlotColorToBrush(VerticalLineX.Color);
       }
   }

   public class NoinusDataModel : INotifyPropertyChanged
   {
       public int DataloggerID { get; set; }

       private System.Windows.Media.Brush _color;

       public System.Windows.Media.Brush Color
       {
           get { return _color; }
           set
           {
               _color = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Color)));
           }
       }
       private string _dataText;

       public event PropertyChangedEventHandler? PropertyChanged;

       public string DataText
       {
           get { return _dataText; }
           set
           {
               _dataText = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DataText)));
           }
       }
   }

图标模型类

   public class ScottModel : INotifyPropertyChanged
   {
       #region 字段
       AxisLine? PlottableBeingDragged = null;
       private bool _isRender;
       private WpfPlot _signalImage;
       private Crosshair _lineCrosshair;
       private bool _isShowLoadHisBtn;
       private bool _isSelected;
       #endregion

       #region 接口实现
       public event PropertyChangedEventHandler? PropertyChanged;
       #endregion


       #region 属性

       public bool IsRender
       {
           get { return _isRender; }
           set
           {
               _isRender = value;
               RenderAction();
           }
       }

       public bool IsSelected
       {
           get { return _isSelected; }
           set
           {
               _isSelected = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
               ShowNoniu(value);
           }
       }

       public bool IsShowLoadHisBtn
       {
           get { return _isShowLoadHisBtn; }
           set
           {
               _isShowLoadHisBtn = value;
               PropertyChanged?.Invoke(
                   this,
                   new PropertyChangedEventArgs(nameof(IsShowLoadHisBtn))
               );
               ShowNoniu(value);
           }
       }

       /// <summary>
       /// plot对象
       /// </summary>

       public WpfPlot SignalImage
       {
           get { return _signalImage; }
           private set { _signalImage = value; }
       }

       public Crosshair LineCrosshair
       {
           get { return _lineCrosshair; }
           private set { _lineCrosshair = value; }
       }

       /// <summary>
       /// 系列轴
       /// </summary>

       private ObservableCollection<SerialModel> _serials;

       public ObservableCollection<SerialModel> Serials
       {
           get { return _serials; }
           private set { _serials = value; }
       }

       public NoniusLineModel NoniusLineModelX1 { get; private set; }
       public NoniusLineModel NoniusLineModelX2 { get; private set; }

       #endregion


       /// <summary>
       /// 加载历史数据方命令.调用方自己实现
       /// </summary>
       public ICommand LoadHistoryCommand { get; set; }

       public ScottModel()
       {
           Serials = new ObservableCollection<SerialModel>();
           //添加字体
           ScottPlot.Fonts.AddFontFile(
               "Alumni Sans",
               @"../../../Fonts/AlumniSans-Regular.ttf",
               bold: false,
               italic: false
           );
           SignalImage = new WpfPlot();

           NoniusLineModelX1 = new(); //竖线1
           NoniusLineModelX1.InitNoinusLine(SignalImage);
           NoniusLineModelX2 = new(); //竖线2
           NoniusLineModelX2.InitNoinusLine(SignalImage);

           SignalImage.Plot.Legend.Alignment = Alignment.UpperLeft;
           SignalImage.Plot.Legend.Alignment = Alignment.UpperLeft;

           //初始化底部标签文本
           SignalImage.Plot.XLabel("Time / ms", 12);
           SignalImage.Plot.Axes.Bottom.Label.OffsetY = 5;

           SignalImage.Plot.Grid.MinorLineWidth = 1f; //网格

           SignalImage.MouseDown += SignalImage_MouseDown;
           SignalImage.MouseUp += SignalImage_MouseUp;
           SignalImage.MouseMove += _SignalImage_MouseMove;

           //指示线
           LineCrosshair = SignalImage.Plot.Add.Crosshair(-20, -20);
           LineCrosshair.HorizontalLine.IsVisible = false;
           LineCrosshair.LineWidth = 2f; //线宽
           LineCrosshair.MarkerSize = 0;
           LineCrosshair.MarkerLineColor = ScottPlot.Color.FromHex("#B83E52");

           SignalImage.UserInputProcessor.Disable(); //禁止交互
       }

       /// <summary>
       /// 获取轴线
       /// </summary>
       /// <param name="x"></param>
       /// <param name="y"></param>
       /// <returns></returns>
       private AxisLine? GetLineUnderMouse(float x, float y)
       {
           CoordinateRect rect = SignalImage.Plot.GetCoordinateRect(x, y, radius: 10);

           foreach (AxisLine axLine in SignalImage.Plot.GetPlottables<AxisLine>().Reverse())
           {
               if (axLine.IsUnderMouse(rect))
                   return axLine;
           }

           return null;
       }

       /// <summary>
       /// 按下事件
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void SignalImage_MouseDown(
           object sender,
           System.Windows.Input.MouseButtonEventArgs e
       )
       {
           LineCrosshair.IsVisible = false;
           var lineUnderMouse = GetLineUnderMouse(
               (float)e.GetPosition(SignalImage).X,
               (float)e.GetPosition(SignalImage).Y
           );

           if (lineUnderMouse is not null)
           {
               PlottableBeingDragged = lineUnderMouse;
               SignalImage.UserInputProcessor.Disable(); // disable panning while dragging
           }
           else
           {
               e.Handled = true;
           }
       }

       /// <summary>
       /// 抬起事件
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       /// <exception cref="NotImplementedException"></exception>
       private void SignalImage_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
       {
           PlottableBeingDragged = null;
           LineCrosshair.IsVisible = true;
           SignalImage.UserInputProcessor.Disable();
           SignalImage.Refresh();
       }

       /// <summary>
       /// 鼠标在图标上移动时
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       /// <exception cref="NotImplementedException"></exception>
       private void _SignalImage_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
       {
           if (IsRender)
           {
               return;
           }

           var mousePosition = e.GetPosition(SignalImage);
           var mousePixel = new Pixel(mousePosition.X, mousePosition.Y);
           var mouseLocation = SignalImage.Plot.GetCoordinates(mousePixel);

           if (PlottableBeingDragged == null)
           {
               UpdateCursor(mousePosition);
               MarkerFollow(mouseLocation, false);
           }
           else
           {
               UpdateDraggedPlottable(mouseLocation);
           }

           Refresh();
       }

       /// <summary>
       /// 更新鼠标指示线
       /// </summary>
       /// <param name="mousePosition"></param>
       private void UpdateCursor(Point mousePosition)
       {
           var lineUnderMouse = GetLineUnderMouse((float)mousePosition.X, (float)mousePosition.Y);
           if (lineUnderMouse == null)
           {
               SignalImage.Cursor = Cursors.Arrow;
           }
           else if (lineUnderMouse.IsDraggable)
           {
               SignalImage.Cursor =
                   lineUnderMouse is VerticalLine ? Cursors.SizeWE : Cursors.SizeNS;
           }
       }

       /// <summary>
       /// 标记点跟随
       /// </summary>
       /// <param name="mouseLocation"></param>
       /// <param name="isHiddenCros"></param>
       /// <returns></returns>
       private DataPoint MarkerFollow(Coordinates mouseLocation, bool isHiddenCros)
       {
           PixelSize size = new(SignalImage.ActualWidth, SignalImage.ActualHeight);
           PixelRect rect = new(Pixel.Zero, size);
           DataPoint point = new DataPoint();
           foreach (var serial in Serials)
           {
               if (serial.DataLogger.Data.Coordinates.Count == 0 || !serial.IsSelected)
               {
                   continue;
               }
               point = serial.DataLogger.GetNearestX(mouseLocation, rect, 40);
               serial.Marker.IsVisible = true;
               serial.CurentY = point.Y.ToString("0.###");
               serial.Marker.Axes.YAxis = serial.DataLogger.Axes.YAxis;
               serial.Marker.Coordinates = point.Coordinates;
               LineCrosshair.Position = point.Coordinates;
           }
           LineCrosshair.IsVisible = !isHiddenCros;
           return point;
       }

       /// <summary>
       /// 更新拖拽的图标点
       /// </summary>
       /// <param name="mouseLocation"></param>
       private void UpdateDraggedPlottable(Coordinates mouseLocation)
       {
           if (PlottableBeingDragged is VerticalLine vl)
           {
               var point = MarkerFollow(mouseLocation, true);
               vl.X = point.X;

               var noniusModel =
                   vl.Color == NoniusLineModelX1.VerticalLineX.Color
                       ? NoniusLineModelX1
                       : NoniusLineModelX2;
               UpdateNoniusData(noniusModel, mouseLocation);

               vl.Text = $"X{(noniusModel == NoniusLineModelX1 ? "1" : "2")}:{vl.X}";
           }
       }

       private void UpdateNoniusData(NoniusLineModel noniusModel, Coordinates mouseLocation)
       {
           var size = new PixelSize(SignalImage.ActualWidth, SignalImage.ActualHeight);
           var rect = new PixelRect(Pixel.Zero, size);

           foreach (var serial in Serials)
           {
               if (serial.DataLogger.Data.Coordinates.Count == 0 || !serial.IsSelected)
               {
                   continue;
               }

               var point = serial.DataLogger.GetNearestX(mouseLocation, rect, 40);
               var non = noniusModel.NoinusDatas.FirstOrDefault(i =>
                   i.DataloggerID == serial.DataloggerID
               );

               if (non == null)
               {
                   non = new NoinusDataModel
                   {
                       DataloggerID = serial.DataloggerID,
                       Color = serial.SerialColor,
                   };
                   noniusModel.NoinusDatas.Add(non);
               }
               else
               {
                   non.DataText = point.Y.ToString("0.###");
               }
           }

           PropertyChanged?.Invoke(
               this,
               new PropertyChangedEventArgs(
                   noniusModel == NoniusLineModelX1
                       ? nameof(NoniusLineModelX1)
                       : nameof(NoniusLineModelX2)
               )
           );
       }

       /// <summary>
       /// 刷新
       /// </summary>
       public void Refresh()
       {
           System.Windows.Application.Current.Dispatcher.Invoke(() =>
           {
               SignalImage.Plot.Axes.Margins();
               SignalImage.Plot.Axes.AutoScale();
               SignalImage.Refresh();
           });
       }

       /// <summary>
       /// 文化文字设置
       /// </summary>
       /// <param name="culture"></param>
       public void SetCulture(string culture)
       {
           //foreach (var serial in Serials)
           //{
           //    serial.Axis.Label.FontName = ScottPlot.Fonts.Detect(culture);
           //}

           SignalImage.Plot.Font.Automatic(); //自动适配文字
       }

       /// <summary>
       /// 添加序列
       /// </summary>
       /// <param name="serialName"></param>
       /// <param name="id"></param>
       /// <param name="isCheck"></param>
       /// <param name="unit"></param>
       /// <returns></returns>
       public bool AddSerial(string serialName, int id, bool isCheck = true, string unit = null)
       {
           var serial = new SerialModel(serialName, id) { IsSelected = isCheck, Unit = unit };
           return AddSerial(serial);
       }

       /// <summary>
       /// 添加序列
       /// </summary>
       /// <param name="serial"></param>
       /// <returns></returns>

       public bool AddSerial(SerialModel serial)
       {
           if (Serials == null || serial == null)
               return false;
           if (Serials.Any(s => serial.SerialTitle.Equals(s.SerialTitle)))
               return false;

           if (Serials.Count == 0)
           {
               var leftaxis = SignalImage.Plot.Axes.Left;
               serial.Axis = leftaxis;
               serial.DataLogger = SignalImage.Plot.Add.DataLogger();
               serial.DataLogger.Axes.YAxis = leftaxis;
               var ax = leftaxis as LeftAxis;
               if (ax != null)
               {
                   ax.Color(serial.DataLogger.Color);
               }
           }
           else
           {
               if (serial.Alignment == SerialAlignment.Left)
               {
                   LeftAxis leftaxis = SignalImage.Plot.Axes.AddLeftAxis();
                   serial.Axis = leftaxis;
                   serial.DataLogger = SignalImage.Plot.Add.DataLogger();
                   serial.DataLogger.Axes.YAxis = leftaxis;
                   leftaxis.Color(serial.DataLogger.Color);
                   leftaxis.LabelBorderWidth = 40;
               }
               else if (serial.Alignment == SerialAlignment.Right)
               {
                   //检查是否存在右轴的对象
                   if (!Serials.Any(x => x.Alignment == SerialAlignment.Right))
                   {
                       //不存在右轴
                       var rightaxis = SignalImage.Plot.Axes.Right;
                       serial.Axis = rightaxis;
                       serial.DataLogger = SignalImage.Plot.Add.DataLogger();
                       serial.DataLogger.Axes.YAxis = rightaxis;
                       var ax = rightaxis as RightAxis;
                       if (ax != null)
                       {
                           ax.Color(serial.DataLogger.Color);
                       }
                   }
                   else
                   {
                       RightAxis rightaxis = SignalImage.Plot.Axes.AddRightAxis();
                       serial.Axis = rightaxis;
                       serial.DataLogger = SignalImage.Plot.Add.DataLogger();
                       serial.DataLogger.Axes.YAxis = rightaxis;
                       rightaxis.Color(serial.DataLogger.Color);
                   }
               }
           }

           serial.Marker = SignalImage.Plot.Add.Marker(-20, -20); //添加高亮标记点,初始化时隐藏
           serial.Marker.Size = 10;
           serial.Marker.Shape = MarkerShape.FilledCircle; //实心圆
           serial.Marker.Color = serial.DataLogger.Color; //跟随数据记录器的颜色

           serial.DataLogger.Axes.YAxis.Label.Text = serial.LegendName ?? serial.SerialTitle; //给轴标签赋值
           serial.DataLogger.Axes.YAxis.Label.FontName = "Alumni Sans"; //选择使用的字体样式
           serial.DataLogger.Axes.YAxis.Label.FontSize = 12; //设置字体大小
           serial.DataLogger.Axes.YAxis.Label.Bold = false; //不粗

           serial.DataLogger.IsVisible = serial.IsSelected; //数据是否显示
           serial.DataLogger.Axes.YAxis.IsVisible = serial.IsSelected; //数据轴是否显示
           serial.SerialColor = ColorHelper.ConvertScottPlotColorToBrush(serial.DataLogger.Color); //颜色转换
           serial.SelectChangedEvent += Serial_SelectChangedEvent; //当前轴选中事件
           Serials.Add(serial);

           return true;
       }

       /// <summary>
       /// 渲染时的行为
       /// </summary>
       private void RenderAction()
       {
           foreach (var serial in Serials)
           {
               serial.Marker.IsVisible = !IsRender;
           }
           NoniusLineModelX1.VerticalLineX.IsVisible = IsSelected ? !IsRender : false;
           NoniusLineModelX2.VerticalLineX.IsVisible = IsSelected ? !IsRender : false;
           LineCrosshair.IsVisible = !IsRender;
       }

       /// <summary>
       /// 轴选项改变时处理plot的逻辑
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void Serial_SelectChangedEvent(object? sender, SerialModel e)
       {
           e.DataLogger.Axes.YAxis.IsVisible = e.IsSelected;
           e.DataLogger.IsVisible = e.IsSelected;
           e.Marker.IsVisible = e.IsSelected;
           Refresh();
       }

       /// <summary>
       /// 获取数据记录器,
       /// </summary>
       /// <param name="title">序列名称</param>
       /// <returns></returns>
       public SerialModel GetDataLogger(string title)
       {
           if (Serials.Any(a => a.SerialTitle.Equals(title)))
           {
               return Serials.First(x => x.SerialTitle.Equals(title));
           }
           else
               return null;
       }

       /// <summary>
       /// 获取数据记录器,
       /// </summary>
       /// <param name="title">索引</param>
       /// <returns></returns>
       public SerialModel GetDataLogger(int index)
       {
           if (Serials.Count - 1 >= index)
           {
               return Serials[index];
           }
           else
               return null;
       }

       /// <summary>
       /// 清除数据记录器
       /// </summary>
       public void ClearDataLoggerData()
       {
           if (!Serials.Any())
               return;
           foreach (var item in Serials)
           {
               item.DataLogger.Clear();
           }
       }

       /// <summary>
       /// 显示游标
       /// </summary>
       public void ShowNoniu(bool isShow)
       {
           if (NoniusLineModelX1.VerticalLineX == null || NoniusLineModelX2.VerticalLineX == null)
           {
               return;
           }

           NoniusLineModelX1.VerticalLineX.IsVisible = isShow;
           NoniusLineModelX2.VerticalLineX.IsVisible = isShow;
           if (
               NoniusLineModelX1.VerticalLineX.X < 10
               || double.IsNaN(NoniusLineModelX1.VerticalLineX.X)
           )
           {
               NoniusLineModelX1.VerticalLineX.X = 40;
               NoniusLineModelX1.VerticalLineX.Text = $"{NoniusLineModelX1.VerticalLineX.X:0.00}";
           }
           else if (
               NoniusLineModelX1.VerticalLineX.X > SignalImage.Plot.Axes.Bottom.Max
               || double.IsNaN(NoniusLineModelX1.VerticalLineX.X)
           )
           {
               NoniusLineModelX1.VerticalLineX.X = 40;
               NoniusLineModelX1.VerticalLineX.Text = $"{NoniusLineModelX1.VerticalLineX.X:0.00}";
           }
           if (
               NoniusLineModelX2.VerticalLineX.X < 10
               || double.IsNaN(NoniusLineModelX2.VerticalLineX.X)
           )
           {
               NoniusLineModelX2.VerticalLineX.X = 100;
               NoniusLineModelX2.VerticalLineX.Text = $"{NoniusLineModelX2.VerticalLineX.X:0.00}";
           }
           else if (
               NoniusLineModelX2.VerticalLineX.X > SignalImage.Plot.Axes.Bottom.Max
               || double.IsNaN(NoniusLineModelX2.VerticalLineX.X)
           )
           {
               NoniusLineModelX2.VerticalLineX.X = 100;
               NoniusLineModelX2.VerticalLineX.Text = $"{NoniusLineModelX2.VerticalLineX.X:0.00}";
           }
           Refresh();
       }
   }

序列模型类

public class SerialModel : INotifyPropertyChanged
{
    #region 字段
    private string _serialTitel;
    private Brush _serialColor;
    private bool _isSelected;
    private string _curentY;
    private string _unit;

    #endregion

    #region 事件
    public event EventHandler<SerialModel> SelectChangedEvent;
    #endregion

    #region 通知

    [field: NonSerialized]
    public event PropertyChangedEventHandler? PropertyChanged;
    #endregion

    public int DataloggerID { get; set; }

    /// <summary>
    /// 序列标题
    /// </summary>
    public string SerialTitle
    {
        get { return _serialTitel; }
        private set
        {
            _serialTitel = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SerialTitle)));
        }
    }

    /// <summary>
    /// 序列颜色
    /// </summary>
    public Brush SerialColor
    {
        get { return _serialColor; }
        set
        {
            _serialColor = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SerialColor)));
        }
    }

    /// <summary>
    /// 单位
    /// </summary>
    public string Unit
    {
        get { return _unit; }
        set
        {
            _unit = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Unit)));
        }
    }

    /// <summary>
    /// 是否选中
    /// </summary>
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
            SelectChangedEvent?.Invoke(this, this);
        }
    }

    /// <summary>
    /// 当前y值
    /// </summary>

    public string CurentY
    {
        get { return _curentY; }
        set
        {
            _curentY = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurentY)));
        }
    }

    /// <summary>
    /// 当前数据记录器的轴对象
    /// </summary>
    public IAxis Axis { get; set; }

    /// <summary>
    /// 轴停靠位置
    /// </summary>

    public SerialAlignment Alignment { get; private set; } = SerialAlignment.Left;

    /// <summary>
    /// 轴名称
    /// </summary>
    public string LegendName { get; set; }

    /// <summary>
    /// 标记点对象
    /// </summary>
    public ScottPlot.Plottables.Marker Marker { get; set; }

    /// <summary>
    /// 数据记录器对象
    /// </summary>

    public DataLogger DataLogger { get; set; }

    public SerialModel() { }

    public SerialModel(string serianame, int id)
    {
        DataloggerID = id;
        SerialTitle = serianame;
    }

    public SerialModel(string serianame, SerialAlignment serialAlignment, int id)
        : this(serianame, id)
    {
        Alignment = serialAlignment;
    }
}

public enum SerialAlignment
{
    Left,
    Right,
}

使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值