OxyPlot图表使用

1.添加OxyPlot库;

image

2.Xaml中添加引用;

xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"

3.Xaml中使用控件;

<oxy:PlotView x:Name="MyPlotView"/>

4.隐藏代码中

初始化图表

var newModel = new PlotModel
 {
     //Title = _viewModel.DeviceSN,
     IsLegendVisible = false,

 };
 /*
 // 图例
 var l = new Legend
 {
     LegendBorder = OxyColors.Transparent, // 隐藏边框
     LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
     LegendPosition = LegendPosition.LeftTop,
     LegendPlacement = LegendPlacement.Inside,
     LegendOrientation = LegendOrientation.Vertical,
     LegendItemOrder = LegendItemOrder.Normal,
     LegendItemAlignment = OxyPlot.HorizontalAlignment.Left,
     LegendSymbolPlacement = LegendSymbolPlacement.Left,
     //LegendMaxWidth = 200,
     //LegendMaxHeight = 400
 };
 newModel.Legends.Add(l);
 */

 // xy轴
 // 初始化时间轴 (X轴)
 DateTimeAxis timeXAxis = new DateTimeAxis
 {
     Position = AxisPosition.Bottom,
     Title = "Time", // 轻易不要改,注意修改后要对应修改线条的X轴名称
     TitleFormatString = "{0} [{1}]",
     TitlePosition = 0.5,
     Unit = "ms",
     StringFormat = "HH:mm:ss.fff",
     //Angle = 45,
     IntervalType = DateTimeIntervalType.Milliseconds,
     //IntervalLength = 100,
     //MajorStep = 100, // 100ms间隔
     IsZoomEnabled = false,
     IsPanEnabled = false,
     MinimumRange = 0,      // 避免自动范围计算过于频繁
     // 默认显示范围10秒,修改的话需要同步修改PlotXTimeWidth
     Minimum = DateTimeAxis.ToDouble(DateTime.Now.AddSeconds(-9)),
     Maximum = DateTimeAxis.ToDouble(DateTime.Now.AddSeconds(1)),
     MajorGridlineStyle = LineStyle.Solid,
     //MajorGridlineStyle = LineStyle.None,  // 禁用网格线
     //MinorGridlineStyle = LineStyle.Dot,
     MinorGridlineStyle = LineStyle.None,  // 禁用次网格线
     MajorGridlineColor = OxyColor.FromAColor(40, OxyColors.Black),
     //MinorGridlineColor = OxyColor.FromAColor(20, OxyColors.Black),
     MinorGridlineColor = OxyColors.Transparent
 };
 // 初始化数值轴 (Y轴)
 LinearAxis valueYAxis = new LinearAxis
 {
     Position = AxisPosition.Left,
     Title = "Value",// 轻易不要改,注意修改后要对应修改线条的Y轴名称
     TitleFormatString = "{0} [{1}]",
     TitlePosition = 0.5,
     Unit = "mV",
     //Minimum = 0,
     //Maximum = 100,
     // MajorStep = 5, //主网格线每0.5mv一条
     // 启用自适应范围
     MinimumPadding = 0.05,  // 上下留5%空隙
     MaximumPadding = 0.05,
     // 禁用缩放和拖拽,保持自适应
     IsZoomEnabled = false,
     IsPanEnabled = false,
     AbsoluteMaximum = 12000, // 设置绝对最小最大值,限制缩放和平移的极限
     AbsoluteMinimum = -12000,
     MinimumRange = 10, //最小范围10mv
     MajorGridlineStyle = LineStyle.Solid,
     MinorGridlineStyle = LineStyle.Solid, // 实线最省性能
     MajorGridlineColor = OxyColor.FromAColor(40, OxyColors.Black),
     MinorGridlineColor = OxyColor.FromAColor(20, OxyColors.Black)
 };

 newModel.Axes.Add(timeXAxis);
 newModel.Axes.Add(valueYAxis);

 MyPlotView.Model = newModel;

// 添加对应颜色的通道线

uint color = (uint)channelColor.ToInt32() | 0xFF000000;
        OxyColor oxyColor = OxyColor.FromUInt32(color);
        var chnLine = new LineSeries {
            Title = "Ch " + channelNum,
            //BrokenLineColor = OxyPlot.OxyColors.Automatic,
            Color = oxyColor,
            MarkerType = MarkerType.None, // 动态波形通常不需要数据点标记
            StrokeThickness = 1,
            LineStyle = LineStyle.Solid,
            //DataFieldX = "Time", // 要跟X轴名称一样,或者删除不写
            //DataFieldY = "Value", // 要跟Y轴名称一样,或者删除不写
            //ItemsSource = _viewModel.LineDataPointsList[channelNum - 1],
            //Decimator = null, // 或者使用一个高效的Decimator
            Decimator = Decimator.Decimate,
            CanTrackerInterpolatePoints = false, // 关闭跟踪器插值
        };
        
        MyPlotView.Model.Series.Add(chnLine);
        MyPlotView.Model.InvalidatePlot(false);
        //chnLine.InvalidatePlot(true); // 只刷新这个系列,在循环任务里面会刷新的`

// 删除通道线

MyPlotView.Model.Series.Remove(chnLine);
      MyPlotView.Model.InvalidatePlot(false);

// 清除通道线

`	  MyPlotView.Model.Series.Clear();
  	  MyPlotView.Model.InvalidatePlot(false);`

// 通道线中添加点

`chnLine.Points.Add(new DataPoint(timeStamp, val));
	// 限制数据点数量以提高性能
	if (chnLine.Points.Count > MaxDataPoints)
	{
		chnLine.Points.RemoveAt(0);
	}
private static uint MaxDataPoints = 700; // 最大数据点数量,图表显示10秒,1ms抽样1次,共10000个数据点,留1秒的余量 ---实测,屏幕最大化时,700就能够布满全屏了`

// 更新时间轴范围,保持窗口显示宽度不变,时间轴移动20ms,保持滚动效果

private static double PlotXTimeWidth = 10.0 / (24 * 60 * 60); //  窗口宽度10秒,10秒是约 ‌0.0001157 天
	newMaxTime = DateTimeAxis.ToDouble(LastPointsTimeStamp.AddMilliseconds(20));
	newMinTime = newMaxTime - PlotXTimeWidth;
Dispatcher.Invoke(() =>
	{
		MyPlotView.Model.Axes[0].Minimum = newMinTime;
		MyPlotView.Model.Axes[0].Maximum = newMaxTime;
		// 判断Y轴当前显示的最大值小于点中的最大值时,需要刷新所有图表
		if (MyPlotView.Model.Axes[1].ActualMaximum < maxVal || MyPlotView.Model.Axes[1].ActualMinimum > minVal)
		{
			isRefreshAll = true;
		}
		MyPlotView.Model.InvalidatePlot(isRefreshAll); //  false只更新数据点,不更新轴、标签等,性能好很多
		//MyPlotView.Model.InvalidatePlot(true);
		stopwatch.Stop();
		Debug.WriteLine("更新一次图表耗时:" + stopwatch.ElapsedMilliseconds + "ms");

		//_viewModel.Res_ChannelItemCollection();
		foreach (var item in ChannelDataItem_Dict.Values)
		{
			item.Res_ValueChange();
		}
	});
```

	
posted @ 2026-04-27 17:03  nap117  阅读(87)  评论(0)    收藏  举报