按时间顺序更新折线图
LiveCharts.Wpf(0.9.7)
xaml
1 xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" 2 3 <StackPanel Margin="0,10,0,0" Background="#DCDCDC" Grid.Row="2" > 4 <GroupBox Header="设定温度/显示温度" Tag="Temperature Monitoring" Height="400" Margin="10"> 5 <Grid Margin="20"> 6 <Grid.RowDefinitions> 7 <RowDefinition Height="30"/> 8 <RowDefinition/> 9 </Grid.RowDefinitions> 10 <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left"> 11 <Border Background="#DD2BB6FE" Width="15" Height="15" Margin="3,0"/> 12 <TextBlock Text="设定温度(℃)" Foreground="#FF08113C" FontSize="14" VerticalAlignment="Center" Margin="0,0,10,0"/> 13 <Border Background="IndianRed" Width="15" Height="15" Margin="3,0"/> 14 <TextBlock Text="实际温度(℃)" Foreground="#FF08113C" FontSize="14" VerticalAlignment="Center"/> 15 <Button 16 Margin="100,0" 17 Width="100" 18 Height="28" 19 HorizontalAlignment="Center" 20 VerticalAlignment="Top" 21 Command="{Binding IsReadingCommand}" 22 Content="图表控制"/> 23 <Button 24 Margin="20,0" 25 Width="100" 26 Height="28" 27 HorizontalAlignment="Center" 28 VerticalAlignment="Top" 29 Command="{Binding SavePictureCommand}" 30 CommandParameter="{Binding ElementName=Pic}" 31 Content="保存图片"/> 32 </StackPanel> 33 <ContentControl Grid.Row="1"> 34 <lvc:CartesianChart 35 AnimationsSpeed="0:0:1" 36 Hoverable="False" 37 DataTooltip="{x:Null}" 38 Name="Pic"> 39 <lvc:CartesianChart.Series> 40 <lvc:LineSeries Values="{Binding ChartValues}" 41 PointGeometry="{x:Null}" 42 LineSmoothness="1" 43 StrokeThickness="6" 44 Stroke="#F34336" 45 Fill="Transparent"/> 46 47 </lvc:CartesianChart.Series> 48 <lvc:CartesianChart.AxisX> 49 <lvc:Axis LabelFormatter="{Binding DateTimeFormatter}" 50 Foreground="#FF08113C" 51 FontSize="14" 52 MaxValue="{Binding AxisMax}" 53 MinValue="{Binding AxisMin}" 54 Unit="{Binding AxisUnit}" 55 LabelsRotation="45"> 56 <lvc:Axis.Separator> 57 <lvc:Separator Step="{Binding AxisStep}"/> 58 </lvc:Axis.Separator> 59 </lvc:Axis> 60 </lvc:CartesianChart.AxisX> 61 <lvc:CartesianChart.AxisY> 62 <lvc:Axis Foreground="#FF08113C" FontSize="14"> 63 <lvc:Axis.Separator> 64 <lvc:Separator Step="40"/> 65 </lvc:Axis.Separator> 66 </lvc:Axis> 67 </lvc:CartesianChart.AxisY> 68 </lvc:CartesianChart> 69 </ContentControl> 70 71 72 </Grid> 73 </GroupBox> 74 75 </StackPanel>
1 //构造函数内 2 3 #region 折线图相关 4 SelectadCommand = new DelegateCommand(Selectad); 5 var mapper = Mappers.Xy<MeasureModel>() 6 .X(model => model.DateTime.Ticks)//使用 DateTime.Ticks 作为 X 7 .Y(model => model.Value); //使用 value 属性作为 Y 8 //全局保存映射器 9 Charting.For<MeasureModel>(mapper); 10 //values 属性将存储我们的 values 数组 11 ChartValues = new ChartValues<MeasureModel>(); 12 //X标签值 13 DateTimeFormatter = value => new DateTime((long)value).ToString("mm:ss"); 14 //AxisStep 强制 X 轴上每个分隔符之间的距离 15 AxisStep = TimeSpan.FromSeconds(1).Ticks; 16 ////AxisUnit force 让轴知道我们正在绘制秒数 17 //这并不总是必要的,但它可以防止错误的标签 18 AxisUnit = TimeSpan.TicksPerSecond; 19 SetAxisLimits(DateTime.Now); 20 21 IsReadingCommand = new DelegateCommand(Reading); 22 SavePictureCommand = new DelegateCommand<CartesianChart>(ExecuteSavePicture);
1 #region 折线图 2 public DelegateCommand<CartesianChart> SavePictureCommand { get; set; } 3 public DelegateCommand IsReadingCommand { get; set; } 4 public ChartValues<MeasureModel> ChartValues { get; set; } 5 public Func<double, string> DateTimeFormatter { get; set; } 6 public double AxisStep { get; set; } 7 public double AxisUnit { get; set; } 8 9 private double _trend; 10 11 private double _axisMax; 12 13 public double AxisMax 14 { 15 get { return _axisMax; } 16 set { _axisMax = value; RaisePropertyChanged(); } 17 } 18 19 private double _axisMin; 20 21 public double AxisMin 22 { 23 get { return _axisMin; } 24 set { _axisMin = value; RaisePropertyChanged(); } 25 } 26 public bool IsReading { get; set; } 27 28 private void Read() 29 { 30 var r = new Random(); 31 32 while (IsReading) 33 { 34 Thread.Sleep(150); 35 var now = DateTime.Now; 36 _trend += r.Next(-8,10); 37 38 ChartValues.Add(new MeasureModel 39 { 40 DateTime = now, 41 Value =_trend 42 }); 43 SetAxisLimits(now); 44 //只允许使用最后 150 个值 45 if (ChartValues.Count > 300) ChartValues.RemoveAt(0); 46 } 47 } 48 49 private void SetAxisLimits(DateTime now) 50 { 51 AxisMax = now.Ticks + TimeSpan.FromSeconds(1).Ticks;//让我们强制轴提前 1 秒 52 AxisMin = now.Ticks - TimeSpan.FromSeconds(40).Ticks;//落后 8 秒 53 } 54 55 /// <summary> 56 /// 图表启动停止 57 /// </summary> 58 private void Reading() 59 { 60 IsReading = !IsReading; 61 if (IsReading) 62 { 63 Task.Factory.StartNew(Read);//为指定的操作委托创建并启动任务。 64 } 65 } 66 67 /// <summary> 68 /// 实现图表截图 69 /// </summary> 70 /// <param name="chart"></param> 71 private void ExecuteSavePicture(CartesianChart chart) 72 { 73 //背景色,chart是前台按钮绑定参数传过来的 74 chart.Background = System.Windows.Media.Brushes.White; 75 ////找到lvc的父级控件 76 ContentControl groupBox = (ContentControl)chart.Parent; 77 //获取控件大小 78 groupBox.Measure(chart.RenderSize); 79 chart.Update(true,true);//强制图表更新 80 groupBox.UpdateLayout(); 81 SaveFileDialog saveFileDialog = new SaveFileDialog(); 82 saveFileDialog.Title = "图片另存为"; 83 saveFileDialog.Filter = "jpg图片|*.JPG|png图片|*.PNG|jpeg图片|*.JPEG"; 84 saveFileDialog.FilterIndex = 2; 85 saveFileDialog.RestoreDirectory = true;//保存对话框是否记忆上次打开的目录 86 bool? result = saveFileDialog.ShowDialog();//因为时WPF,相对于OK 87 if (result == true) 88 { 89 FileStream fs = new FileStream($"{saveFileDialog.FileName}",FileMode.Create);//要保存的路径 90 //对象转换成位图 91 RenderTargetBitmap bmp = new RenderTargetBitmap((int)chart.ActualWidth + 10, (int)chart.ActualHeight + 10, 96, 96, PixelFormats.Pbgra32); 92 bmp.Render(chart); 93 //对象的集合编码转成图像流 94 BitmapEncoder encoder = new PngBitmapEncoder(); 95 encoder.Frames.Add(BitmapFrame.Create(bmp)); 96 //保存路径中 97 encoder.Save(fs); 98 //释放资源 99 fs.Close(); 100 fs.Dispose(); 101 MessageBox.Show("保存成功"); 102 } 103 } 104 #endregion

浙公网安备 33010602011771号