github地址:https://github.com/mzy666888/OxyPlotWpf
1、新建wpf项目:OxyPlotDemo
添加必要的package,主要有:MvvmLight,和OxyPlot.Wpf以及它们的依赖项目,添加完成后,在已安装项里面包含以下5中包。
2、在MainWindow.xaml中添加如下内容:
- DataContent引用
- xmlns:oxyplot内容
- 向grid中添加OxyPlot控件信息
添加OxyPlot控件信息使用了两种方法:
- 直接添加<oxyplot:PlotView />,然后在代码中添加坐标轴和Series信息。直接使用Model 绑定ViewModel中的属性,在第21行
- 添加<oxyplot:Plot />,然后在Plot中添加坐标轴和Series信息,并将Series中的ItemsSource 绑定ViewModel中的属性,在第22-39行。注意使用Plot时,添加Axes和Series的方式
<Window
x:Class="OxyPlotDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OxyPlotDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:oxyplot="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}" />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<oxyplot:PlotView Model="{Binding Model}" />
<oxyplot:Plot Title="实时曲线" Grid.Row="1">
<oxyplot:Plot.Axes>
<oxyplot:DateTimeAxis Title="时间" />
<oxyplot:LinearAxis Title="数值" />
</oxyplot:Plot.Axes>
<oxyplot:Plot.Series>
<oxyplot:LineSeries
Title="温度"
ItemsSource="{Binding TempDataPoints}"
MarkerType="Circle"
Smooth="True" />
<oxyplot:LineSeries
Title="温度"
ItemsSource="{Binding HumiDataPoints}"
MarkerType="Circle"
Smooth="True" />
</oxyplot:Plot.Series>
</oxyplot:Plot>
</Grid>
</Window>
3、在ViewModel实现动态数据添加
第一种方式:第57-65行为定义PlotModel,第10-17行为PlotModel初始化处理的PlotModel信息,第19-35行为动态添加曲线数据的功能
第二种方式:第67-85行为定义数据集合信息,第36行-54行为动态添加数据信息功能。
注意:ObservableCollection<>数据的更新一定要在主线程进行,因此第二种方式使用了代理的方式进行添加数据功能
namespace OxyPlotDemo.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
TempDataPoints = new ObservableCollection<DataPoint>();
HumiDataPoints = new ObservableCollection<DataPoint>();
Model = new PlotModel(){Title = "Simple Example",Subtitle = "using OxyPlot"};
var series1 = new LineSeries { Title = "温度", MarkerType = MarkerType.Circle,Smooth = true};
var series2 = new LineSeries { Title = "湿度", MarkerType = MarkerType.Star, Smooth = true ,MarkerStroke = OxyColors.Red};
var dateTimeAxis1 = new DateTimeAxis();
dateTimeAxis1.Title = "Time";
Model.Axes.Add(dateTimeAxis1);
Model.Series.Add(series1);
Model.Series.Add(series2);
Random rd = new Random();
Task.Run(
() =>
{
while (true)
{
series1.Points.Add(DateTimeAxis.CreateDataPoint(DateTime.Now, rd.Next(10, 30)));
series2.Points.Add(DateTimeAxis.CreateDataPoint(DateTime.Now, rd.Next(10, 30)));
if (series1.Points.Count > 100)
{
series1.Points.RemoveAt(0);
series2.Points.RemoveAt(0);
}
Model.InvalidatePlot(true);
Thread.Sleep(1000);
}
});
Task.Run(
() =>
{
while (true)
{
var date = DateTime.Now;
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
TempDataPoints.Add(DateTimeAxis.CreateDataPoint(date, (double)(rd.Next(100, 500) / 10.0)));
HumiDataPoints.Add(DateTimeAxis.CreateDataPoint(date, (double)(rd.Next(500, 800) / 10.0)));
if (TempDataPoints.Count > 300)
{
TempDataPoints.RemoveAt(0);
HumiDataPoints.RemoveAt(0);
}
}));
Thread.Sleep(1000);
}
});
}
private PlotModel _model;
/// <summary>
/// PlotModel
/// </summary>
public PlotModel Model
{
get { return _model; }
set { Set(ref _model, value); }
}
private ObservableCollection<DataPoint> _tempDataPoints;
/// <summary>
/// 温度
/// </summary>
public ObservableCollection<DataPoint> TempDataPoints
{
get { return _tempDataPoints; }
set { Set(ref _tempDataPoints, value); }
}
private ObservableCollection<DataPoint> _humiDataPoints;
/// <summary>
/// 湿度
/// </summary>
public ObservableCollection<DataPoint> HumiDataPoints
{
get { return _humiDataPoints; }
set { Set(ref _humiDataPoints, value); }
}
}
}
4、两种方式对比
第一种方式,布局文件相对简单,大量代码都需要在ViewModel类中进行处理
第二种方式,布局文件相对复杂,但是在ViewModel类中的代码量相对较少
5、运行效果
上图为第一种方式,下图为第二种方式
注:目前oxyplot 2.0已经发布,首先遇到的一个问题就是在LineSeries and PolylineAnnotation中去掉了Smooth属性,取而代之的为:InterpolationAlgorithm
在2.0版本中要设置光滑曲线时需要使用如下代码:
series1.InterpolationAlgorithm = InterpolationAlgorithms.CanonicalSpline;