OxyPlot是.NET下一款非常强大的图表库,几乎可以涵盖各种图表的制作,且支持.net下各种平台和运行库,本文通过示例介绍该如何在Wpf中使用OxyPlot。
本文使用的开发工具是Vs2019,sdk使用的是.net5
首先,使用Vs2019创建一个wpf项目,通过包管理器添加OxyPlot.Wpf依赖或者通过命令行添加依赖:
dotnet add package OxyPlot.Wpf
讯享网
然后添加Prism.Core依赖,添加此依赖主要是为了mvvm的支持
讯享网dotnet add package Prism.Core
在项目中添加MainWindowViewModel.cs类,使其继承自BindableBase类,BindableBase是mvvm模式的viewmodel基类,它实现了INotifyPropertyChanged接口,可以通过数据绑定让UI响应viewmodel的变化
在MainWindowViewModel添加如下代码:
using OxyPlot; using OxyPlot.Axes; using OxyPlot.Legends; using OxyPlot.Series; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace WpfChart.Test { public class MainWindowViewModel : BindableBase { public MainWindowViewModel() { // 构造函数中同步生成数据,无需设置mvvm属性 // _ChartModel = CreateChartModel(data); // 异步获取图表数据 GetData().ContinueWith(x => { // 设置mvvm属性更新图表Model ChartModel = CreateChartModel(x.Result); // 不使用mvvm属性,使用下面方法通知UI // RaisePropertyChanged(nameof(ChartModel)); }); } private PlotModel _ChartModel; /// <summary> /// 图表Model的mvvm属性,可通知UI更新 /// </summary> public PlotModel ChartModel { get { return _ChartModel; } set { SetProperty(ref _ChartModel, value); } } ... ... }
在MainWindow.xaml中添加如下内容:
讯享网<Window ... xmlns:oxyWpf="http://oxyplot.org/wpf" ... > <Grid> <oxyWpf:PlotView Foreground="Black" Margin="5 5 5 0" Background="Transparent" Model="{Binding ChartModel}" /> </Grid> </Window>
在MainWindow.xaml.cs中为数据绑定添加数据上下文
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 添加数据绑定上下文 DataContext = new MainWindowViewModel(); } }
这里我们通过数据绑定的方法显示图表,需要添加实体对象类:
讯享网 public class ChartData { public DateTime Date { get; set; } public double Total { get; set; } public double PassRate { get; set; } }
添加测试数据,模拟后台查询方法:
/// <summary> /// 模拟后台异步查询表格数据 /// </summary> /// <returns></returns> private Task<List<ChartData>> GetData() { var data = new List<ChartData>() { new ChartData { Date = DateTime.Now.Date.AddDays(-15), Total = 121, PassRate = .84 }, new ChartData { Date = DateTime.Now.Date.AddDays(-14), Total = 88, PassRate = .92 }, new ChartData { Date = DateTime.Now.Date.AddDays(-13), Total = 180, PassRate = .35 }, new ChartData { Date = DateTime.Now.Date.AddDays(-12), Total = 150, PassRate = .46 }, new ChartData { Date = DateTime.Now.Date.AddDays(-11), Total = 78, PassRate = .58 }, new ChartData { Date = DateTime.Now.Date.AddDays(-10), Total = 99, PassRate = .71 }, new ChartData { Date = DateTime.Now.Date.AddDays(-9), Total = 143, PassRate = .81 }, new ChartData { Date = DateTime.Now.Date.AddDays(-8), Total = 56, PassRate = .85 }, new ChartData { Date = DateTime.Now.Date.AddDays(-7), Total = 108, PassRate = .95 }, new ChartData { Date = DateTime.Now.Date.AddDays(-6), Total = 79, PassRate = .78 }, new ChartData { Date = DateTime.Now.Date.AddDays(-5), Total = 63, PassRate = .65 }, new ChartData { Date = DateTime.Now.Date.AddDays(-4), Total = 157, PassRate = .58 }, new ChartData { Date = DateTime.Now.Date.AddDays(-3), Total = 148, PassRate = .36 }, new ChartData { Date = DateTime.Now.Date.AddDays(-2), Total = 115, PassRate = .48 }, new ChartData { Date = DateTime.Now.Date.AddDays(-1), Total = 89, PassRate = .63 }, new ChartData { Date = DateTime.Now.Date, Total = 121, PassRate = .90 }, }; return Task.FromResult(data); }
添加生成图表模型的方法,方法中创建一个图表模型,在其中添加一个日期x轴,一个数字y轴,一个百分比y轴,还添加了柱状图和折线图两个不同的图表系列,并将测试数据绑定到这两个图表系列中,代码如下:
讯享网 /// <summary> /// 根据数据生成图表模型 /// </summary> /// <param name="list"></param> /// <returns></returns> private PlotModel CreateChartModel(List<ChartData> list) { var model = new PlotModel() { Title = "测试"}; // 添加图例说明 model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.BottomCenter, LegendOrientation = LegendOrientation.Horizontal, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); // 定义第一个Y轴y1,显示数量 var ay1 = new LinearAxis() { Key = "y1", Position = AxisPosition.Left, }; // 定义第二个Y轴y2,显示百分比 var ay2 = new LinearAxis() { Key = "y2", Position = AxisPosition.Right, Minimum = 0.1, MajorStep = .1, Maximum = 1, LabelFormatter = v => $"{v:P1}" }; // 在第二Y轴坐标50%和80%处显示网格线 ay2.ExtraGridlines = new double[2] { 0.5, 0.8 }; ay2.ExtraGridlineStyle = LineStyle.DashDashDot; // 网格线样式 // 定义X轴为日期轴,从15天前到现在 var minValue = DateTimeAxis.ToDouble(DateTime.Now.Date.AddDays(-15)); var maxValue = DateTimeAxis.ToDouble(DateTime.Now.Date); var ax = new DateTimeAxis() { Minimum = minValue, Maximum = maxValue, StringFormat = "yyyy-MM-dd日", MajorStep = 2, Position = AxisPosition.Bottom, Angle = 45, IsZoomEnabled = false }; // 定义柱形图序列,指定数据轴为Y1轴 var totalBarSeries = new LinearBarSeries(); totalBarSeries.YAxisKey = "y1"; totalBarSeries.BarWidth = 10; //totalBarSeries.FillColor = OxyColor.FromArgb(69, 76, 175, 80); //totalBarSeries.StrokeThickness = 1; //totalBarSeries.StrokeColor = OxyColor.FromArgb(255, 76, 175, 80); totalBarSeries.Title = "总数"; // 点击时弹出的label内容 totalBarSeries.TrackerFormatString = "{0}\r\n{2:dd}日: {4:0}"; // 设置数据绑定源和字段 totalBarSeries.ItemsSource = list; totalBarSeries.DataFieldX = "Date"; totalBarSeries.DataFieldY = "Total"; // 下面为手动添加数据方式 //totalBarSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now.Date.AddDays(-15)), 333)); // 定义三色折线图序列,指定数据轴为Y2轴 var passedRateSeries = new ThreeColorLineSeries(); passedRateSeries.Title = "通过率"; passedRateSeries.YAxisKey = "y2"; // 点击时弹出的label内容 passedRateSeries.TrackerFormatString = "{0}\r\n{2:dd}日: {4:P1}"; // 设置颜色阈值范围 passedRateSeries.LimitHi = .8; passedRateSeries.LimitLo = .5; // 设置数据绑定源和字段 passedRateSeries.ItemsSource = list; passedRateSeries.DataFieldX = "Date"; passedRateSeries.DataFieldY = "PassRate"; // 下面为手动添加数据方式 //passedRateSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now.Date.AddDays(-15)), .750)); // 添加图标资源 model.Series.Add(totalBarSeries); model.Series.Add(passedRateSeries); model.Axes.Add(ay1); model.Axes.Add(ay2); model.Axes.Add(ax); // 设置图形边框 model.PlotAreaBorderThickness = new OxyThickness(1, 0, 1, 1); return model; }
编译运行后效果如下:

官方源码地址,里面包含上百个示例图表 GitHub - oxyplot/oxyplot: A cross-platform plotting library for .NET
本文源码下载

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/121423.html