将OxyPlot封装成用户控件后在WPF中的应用

1、文件架构
在这里插入图片描述
2、加载依赖项
Newtonsoft.Json
OxyPlot.Wpf
3、NotifyBase.cs

namespace Accurate.Common
{public class NotifyBase : INotifyPropertyChanged{public event PropertyChangedEventHandler? PropertyChanged;public void DoNotify([CallerMemberName] string prppertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prppertyName));}}
}

4、CartesianChartViewModel.cs

namespace Accurate.Controls.ViewModels
{public class CartesianChartViewModel:NotifyBase{/// <summary>/// 定义plot属性/// </summary>private PlotModel? plotModel;public PlotModel? PlotModel{get { return plotModel; }set { plotModel = value; this.DoNotify(); }}/// <summary>/// 构造函数/// </summary>public CartesianChartViewModel(){PlotModel=new PlotModel();}}
}

5、CartesianChart.xaml

<UserControl x:Class="Accurate.Controls.CartesianChart"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Accurate.Controls"xmlns:oxy="http://oxyplot.org/wpf"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Border Name="Layout" BorderBrush="#DDD" BorderThickness="1" CornerRadius="10" Background="LightBlue"><Border.Effect><DropShadowEffect Color="#F2F2F2" ShadowDepth="10" BlurRadius="10" Opacity="0.4" Direction="270"/></Border.Effect><oxy:PlotView x:Name="PlotView" Model="{Binding Path= PlotModel}"></oxy:PlotView></Border>
</UserControl>

6、CartesianChart.xaml.cs

namespace Accurate.Controls
{/// <summary>/// CartesianChart.xaml 的交互逻辑/// </summary>public partial class CartesianChart : UserControl{//Plotpublic CartesianChartViewModel? viewModel;//曲线数组public LineSeries[] lineSeries;/// <summary>/// 曲线属性设置属性/// </summary>public string ChartSetStr{get { return (string)GetValue(ChartSetStrProperty); }set { SetValue(ChartSetStrProperty, value); }}// Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...public static readonly DependencyProperty ChartSetStrProperty =DependencyProperty.Register("ChartSetStr", typeof(string), typeof(CartesianChart), new PropertyMetadata(default(string),new PropertyChangedCallback(OnSetPropertyChanged)));/// <summary>/// 设置改变处理/// </summary>/// <param name="d"></param>/// <param name="e"></param>private static void OnSetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){if(d is CartesianChart){CartesianChart chart = (CartesianChart)d;chart.CreatePlot();}}/// <summary>/// 构造函数/// </summary>public CartesianChart(){InitializeComponent();this.Loaded += CartesianChart_Loaded;Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;}/// <summary>/// 退出时释放资源/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Dispatcher_ShutdownStarted(object? sender, EventArgs e){//timer?.Stop();}/// <summary>/// 控件加载/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void CartesianChart_Loaded(object sender, RoutedEventArgs e){CreatePlot();}/// <summary>/// 获取轴名称/// </summary>/// <param name="axisType"></param>/// <returns></returns>private string GetAxisKey(AxisType axisType){string str = "";switch (axisType){case AxisType.X:str = "x";break;case AxisType.Y:str = "y";break;case AxisType.X1:str = "x1";break;case AxisType.Y1:str = "y1";break;}return str;}/// <summary>/// 轴设置/// </summary>/// <param name="axisItemModels"></param>private void LinearAxisSet(ObservableCollection<AxisItemModel> axisItemModels){if(axisItemModels != null && axisItemModels.Count > 1){for(int i = 0; i < axisItemModels.Count; i++){var axis = new LinearAxis();//设置轴类型axis.Title = axisItemModels[i].Name;axis.Key = GetAxisKey(axisItemModels[i].Type);axis.Position = axisItemModels[i].Position;//axis.Minimum = axisItemModels[i].Minimum;//axis.MajorStep = axisItemModels[i].Step;//axis.Maximum = axisItemModels[i].Maximum;viewModel?.PlotModel?.Axes.Add(axis);}}}/// <summary>/// 曲线设置/// </summary>/// <param name="curveItemModels"></param>private void LineSeriesSet(ObservableCollection<CurveItemModel> curveItemModels){if(curveItemModels != null && curveItemModels.Count > 1){lineSeries = new LineSeries[curveItemModels.Count];for (int i=0;i<curveItemModels.Count;i++){lineSeries[i]=new LineSeries();lineSeries[i].Title = curveItemModels[i].Name;lineSeries[i].YAxisKey = GetAxisKey(curveItemModels[i].Type);lineSeries[i].Color = GetOxyColor(curveItemModels[i].ItemColor);lineSeries[i].MarkerType = curveItemModels[i].MarkType;lineSeries[i].MarkerStroke = GetOxyColor(curveItemModels[i].MarkStroke);lineSeries[i].MarkerSize = curveItemModels[i].MarkSize;viewModel?.PlotModel.Series.Add(lineSeries[i]);}} }private List<ChartData> GetChartData(){var data=new List<ChartData>(){new ChartData{Date=DateTime.Now.Date.AddDays(-10),Data1=120,Data2=20},new ChartData{Date=DateTime.Now.Date.AddDays(-8),Data1=100,Data2=80},new ChartData{Date=DateTime.Now.Date.AddDays(-6),Data1=60,Data2=100},new ChartData{Date=DateTime.Now.Date.AddDays(-4),Data1=100,Data2=70},new ChartData{Date=DateTime.Now.Date.AddDays(-2),Data1=50,Data2=90}};return data;}private void LineSeriesDataSourceSet(List<ChartData> list){for(int i=0;i<2;i++){lineSeries[i].ItemsSource = list;lineSeries[i].DataFieldX = "Date";lineSeries[i].DataFieldY = "Data" + i;viewModel?.PlotModel.Series.Add(lineSeries[i]);}}/// <summary>/// 颜色转换/// </summary>/// <param name="color"></param>/// <returns></returns>private OxyColor GetOxyColor(string color){OxyColor oxyColor= OxyColors.Black;switch(color){case "Black":oxyColor = OxyColors.Black;break;case "Red":oxyColor = OxyColors.Red;break;case "Blue":oxyColor = OxyColors.Blue;break;case "Green":oxyColor = OxyColors.Green;break;case "Yellow":oxyColor = OxyColors.Yellow;break;case "Violet":oxyColor = OxyColors.Violet;break;}return oxyColor;}/// <summary>/// Chart设置/// </summary>private void CreatePlot(){if (ChartSetStr == null) return;ChartSetModel ChartSet=JsonConvert.DeserializeObject<ChartSetModel>(ChartSetStr);//曲线设置viewModel = new CartesianChartViewModel();PlotView.DataContext = viewModel;viewModel.PlotModel.Title = ChartSet.Name;viewModel.PlotModel.Legends.Add(new Legend{LegendPlacement = LegendPlacement.Outside,LegendPosition = LegendPosition.BottomCenter,LegendOrientation = LegendOrientation.Horizontal,LegendBorderThickness = 0,LegendTextColor = OxyColors.LightGray});LinearAxisSet(ChartSet.AxisItemModels);LineSeriesSet(ChartSet.CurveItemModels);//LineSeriesDataSourceSet(GetChartData());}}
}

7、AxisItemModel.cs

namespace Accurate.Model
{/// <summary>/// 曲线设置类/// </summary>public class ChartSetModel{public string Name { get; set; } = "曲线示例";public ObservableCollection<AxisItemModel> AxisItemModels { get; set; }=new ObservableCollection<AxisItemModel>();public ObservableCollection<CurveItemModel> CurveItemModels { get; set; } = new ObservableCollection<CurveItemModel>();}/// <summary>/// 坐标轴设置/// </summary>public class AxisItemModel{public string Name { get; set; } = "X";public AxisType Type { get; set; } = 0;public AxisPosition Position { get; set; } = AxisPosition.Bottom;public double Minimum { get; set; } = 0;public double Step { get; set; } = 1;public double Maximum { get; set; } = 100;}/// <summary>/// 曲线设置/// </summary>public class CurveItemModel{public string Name { get; set; } = "时间";public AxisType Type { get; set; } = 0;public string ItemColor { get; set; } = "Black";public MarkerType MarkType { get; set; } = MarkerType.Circle;public string MarkStroke { get; set; } = "Black";public double MarkSize { get; set; } = 3;}/// <summary>/// 枚举轴类型/// </summary>public enum AxisType:int{X,Y,X1,Y1}/// <summary>/// 数据Item(单点数据添加)/// </summary>public class DataItem{public double DataX { get; set; }public List<double> DataYs { get; set; }=new List<double>();}public class ChartData{public DateTime Date { get; set; }public double Data1 { get; set; }public double Data2 { get; set; }}
}

8、MainWindowViewModel。cs

namespace Accurate.ViewModel
{public class MainWindowViewModel:NotifyBase{private string chartSetString;public string ChartSetString{get { return chartSetString; }set { chartSetString = value;this.DoNotify(); }}public ChartSetModel ChartSetData { get; set; } = new ChartSetModel();public MainWindowViewModel(){RefreshChartSet();}private void RefreshChartSet(){ChartSetData.Name = "正弦和余弦曲线";//设置坐标轴ChartSetData.AxisItemModels.Add(new AxisItemModel() { Name = "X", Type = AxisType.X, Position = OxyPlot.Axes.AxisPosition.Bottom, Minimum = 0, Step = 1, Maximum = 200 });ChartSetData.AxisItemModels.Add(new AxisItemModel() { Name = "Y", Type = AxisType.Y, Position = OxyPlot.Axes.AxisPosition.Left, Minimum = -10, Step = 1, Maximum = 10 });//设置曲线ChartSetData.CurveItemModels.Add(new CurveItemModel{Name = "正弦曲线",Type = AxisType.Y,ItemColor = "Red",MarkType = MarkerType.Circle,MarkStroke = "Blue",MarkSize = 3});ChartSetData.CurveItemModels.Add(new CurveItemModel{Name = "余弦曲线",Type = AxisType.Y,ItemColor = "Green",MarkType = MarkerType.Square,MarkStroke = "Yellow",MarkSize = 3});ChartSetString = JsonConvert.SerializeObject(ChartSetData);}}
}

9、MainWindow.xaml

<Window x:Class="Accurate.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Accurate"xmlns:controls="clr-namespace:Accurate.Controls"mc:Ignorable="d"Title="MainWindow" Height="600" Width="800"><Grid><controls:CartesianChart x:Name="Cartesian" ChartSetStr="{Binding ChartSetString}"  Height="450" Width="800" HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid>
</Window>

10、MainWindow.xaml.cs

namespace Accurate
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{private DispatcherTimer? timer;public MainWindow(){InitializeComponent();this.DataContext = new MainWindowViewModel();//this.Cartesian.lineSeriestimer = new DispatcherTimer();timer.Interval = TimeSpan.FromMilliseconds(100);timer.Tick += TimerTick;timer.Start();}double x = 0;/// <summary>/// 定时更新数据/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void TimerTick(object? sender, EventArgs e){double y = 10 * Math.Sin(x / 10.0);this.Cartesian.lineSeries[0]?.Points.Add(new DataPoint(x, y));double y1 = 10 * Math.Cos(x / 10.0);this.Cartesian.lineSeries[1]?.Points.Add(new DataPoint(x, y1));x++;if (this.Cartesian.lineSeries[0]?.Points.Count > 200){this.Cartesian.lineSeries[0].Points.RemoveAt(0);}if (this.Cartesian.lineSeries[1]?.Points.Count > 200){this.Cartesian.lineSeries[1].Points.RemoveAt(0);}this.Cartesian.viewModel?.PlotModel.InvalidatePlot(true);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15996.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XR-FRAME 开始

目录 新建一个XR组件在页面中使用这个组件添加一个物体来点颜色和灯光有点寡淡&#xff0c;加上图像让场景更丰富&#xff0c;环境数据动起来&#xff0c;加入动画还是不够&#xff0c;放个模型再来点交互组件通信&#xff0c;加上HUD虚拟 x 现实&#xff0c;追加AR能力识别人脸…

抖音seo矩阵系统源码开发部署-开源分享(二)

目录 市场背景分析 一、 抖音seo矩阵系统开发部署流程 二、 源码开发功能构思 三、 抖音seo源码开发部署注意事项 四、 部分开发代码展示 市场背景分析 账号矩阵是通过不同平台不同账号之间建立联系&#xff0c;通过将同一品牌下不同平台不同账号的粉丝流量进行账号互通&a…

网络安全 log4j漏洞复现

前言&#xff1a; log4j被爆出“史诗级”漏洞。其危害非常大&#xff0c;影响非常广。该漏洞非常容易利用&#xff0c;可以执行任意代码。这个漏洞的影响可谓是重量级的。 漏洞描述&#xff1a; 由于Apache Log4j存在递归解析功能&#xff0c;未取得身份认证的用户&#xff…

每次装完 homebrew,ohmyzsh 就会报错:Insecure completion-dependent directories detected:

参考:https://zhuanlan.zhihu.com/p/313037188 这是因为在big sur安装homebrew后&#xff0c;会在/usr/local/share/生成一个zsh文件夹&#xff0c;里面包含了 因此&#xff0c;zsh文件默认设置的权限是775&#xff0c;也就是group user有writer的权利&#xff0c;zsh认为这是…

【笔记】数字电路基础1 - 门电路

目录 数字电路基础与门电路数电基础基本门电路复合门电路TTL 门电路CMOS 门电路 数字电路基础与门电路 数电基础 数字电路中常将 0 &#xff5e; 1V 范围的电压称为低电平&#xff0c;用“0”表示&#xff1b;而将 3 &#xff5e; 5V 范围的电压称为高电平&#xff0c;用“1”…

【深入浅出 Spring Security(十二)】使用第三方(Github)授权登录

使用第三方&#xff08;Github&#xff09;授权登录 一、OAuth2 简单概述二、OAuth2 四种授权模式之授权码模式三、Github 授权登录准备工作创建 Spring Boot 项目Vue 测试代码测试效果 &#xff08;Github授权登录的具体操作在目录第三“章”&#xff09; 一、OAuth2 简单概述…

【实战】 四、JWT、用户认证与异步请求(上) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(四)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求1.login2.middleware of json-server3.jira-dev-tool&#xff08;imooc-jira-tool&#xff09;安装问…

排序之玩转qsort函数——【C语言】

说起排序&#xff0c;我们会想起许多算法&#xff0c;在之前的博客中我也写到过&#xff0c;比如&#xff1a;冒泡排序法、快速排序法、选择排序法等等。其实在C语言中一直有一个可以将数组中的内容进行排序的函数且功能完善内容齐全的库函数——qsort函数。今天就让我们来探索…

SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Spring Data Spring Data是一个用于简化数据库访问和操作的开源框架&#xff0c;为开发人员提供了一种通用的方式来处理不同类型的数据存储&#xff0c;例如关系型数据…

Spring Boot中的度量指标及使用方法

Spring Boot中的度量指标及使用方法 简介 Spring Boot是目前流行的Java后端框架之一&#xff0c;它提供了许多有用的功能&#xff0c;其中包括度量指标。度量指标可以帮助我们监测应用程序的性能、稳定性和可靠性&#xff0c;以便及时发现并解决问题。本文将介绍Spring Boot中…

OpenCV——总结《车牌识别》

1.图片中的hsv hsv提取蓝色部分 # hsv提取蓝色部分 def hsv_color_find(img):img_copy img.copy()cv2.imshow(img_copy, img_copy)"""提取图中的蓝色部分 hsv范围可以自行优化cv2.inRange()参数介绍&#xff1a;第一个参数&#xff1a;hsv指的是原图第二个参…

Java后端编译与优化

如果我们将字节码看作是程序语言的一种中间表示形式&#xff0c;那编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施相关的二进制机器码&#xff0c;它都可以视为整个编译过程的后端。 1 即时编译器 即时编译器是指运行时将热点代码编译成本地机器码&#xff…