OxyPlot在wpf中绘制实时动态曲线【更新2.0去掉Smooth属性】

9 篇文章 6 订阅
9 篇文章 5 订阅

github地址:https://github.com/mzy666888/OxyPlotWpf

1、新建wpf项目:OxyPlotDemo

添加必要的package,主要有:MvvmLight,和OxyPlot.Wpf以及它们的依赖项目,添加完成后,在已安装项里面包含以下5中包。

2、在MainWindow.xaml中添加如下内容:

  • DataContent引用
  • xmlns:oxyplot内容
  • 向grid中添加OxyPlot控件信息

添加OxyPlot控件信息使用了两种方法:

  1. 直接添加<oxyplot:PlotView />,然后在代码中添加坐标轴和Series信息。直接使用Model 绑定ViewModel中的属性,在第21行
  2. 添加<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;

 


  • 11
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
WPF(Windows Presentation Foundation)是一种用于创建Windows应用程序的框架,可用于创建各种各样的图形用户界面(GUI),包括实时曲线图。 要实现实时曲线x轴的自动滚动,可以采取以下步骤: 1. 创建一个WPF应用程序并设置其主窗口。 2. 在XAML定义一个Canvas元素,它将用于绘制实时曲线图。在Canvas上,您可以添加其他需要的元素,例如坐标轴等。 3. 在代码,创建一个定时器(例如使用System.Timers.Timer类),以固定的时间间隔触发更新曲线图的操作。 4. 在定时器的Tick事件处理程序更新实时曲线图的数据,并重新绘制曲线图。 5. 在绘制曲线图时,可以通过调整x轴的坐标值来实现自动滚动的效果。例如,可以记录最后一个数据点的x轴坐标值,并将所有数据点的x轴坐标值减去该值,以实现滚动效果。 6. 然后,根据新的x轴坐标值重新绘制曲线图。 以下是一个简单示例代码: ```csharp private System.Timers.Timer timer; private double xOffset = 0; public MainWindow() { InitializeComponent(); timer = new System.Timers.Timer(100); // 设置定时器间隔为100毫秒 timer.Elapsed += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, ElapsedEventArgs e) { // 更新曲线图数据 // 调整x轴坐标值 double lastX = GetLastDataPointXValue(); xOffset += lastX; // 重新绘制曲线图 Dispatcher.BeginInvoke(new Action(() => { DrawCurve(); })); } private void DrawCurve() { // 清除Canvas上的所有图形元素 // 根据新的x轴坐标值重新绘制曲线图 double xOffset = 0; foreach (DataPoint dataPoint in dataPoints) { // 计算新的x轴坐标值 double newX = dataPoint.X - xOffset; // 绘制曲线图上的数据点 // 更新x轴坐标值为最新的值 dataPoint.X = newX; } } ``` 这样,每当定时器触发时,曲线图的x轴坐标值都会根据最新的数据进行调整,从而实现自动滚动的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值