using Arction.Wpf.Charting; using Arction.Wpf.Charting.Annotations; using Arction.Wpf.Charting.Axes; using Arction.Wpf.Charting.Maps; using Arction.Wpf.Charting.Series3D; using Arction.Wpf.Charting.SeriesXY; using Arction.Wpf.Charting.Views.ViewXY; using CapMachine.Model; using ImTools; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace CapMachine.Wpf.Models { /// /// 曲线实时系列模型 /// public class ChartRtSeries : BindableBase { /// /// 实例化函数 /// /// /// /// //public ChartRtSeries(AxisY axisY, LightningChart lightningChart, string SeriesName) //{ // //var CreateAxisY = new AxisY(); // //CreateAxisY.Title.Text = Name; // //CreateAxisY.Title.AllowDragging = false; // //CreateAxisY.SetRange(0, 100); // //CreateAxisY.MajorGrid.Visible = false; // ////取消滚轮缩放 // //CreateAxisY.ZoomingEnabled = false; // //模型赋值 // LightningChartInstance = lightningChart; // //ChartAxisY = axisY; // ChartAxisX = lightningChart.ViewXY.XAxes[0]; // Name = SeriesName; // //Unit = "℃"; // //判断别重复,因为可能共用Y轴的信息 // //绑定lightningChart // lightningChart.ViewXY.YAxes.Add(axisY); // ChartPointLineSeries = new PointLineSeries(lightningChart.ViewXY, lightningChart.ViewXY.XAxes[0], axisY); // ChartPointLineSeries.Title.Text = SeriesName; // //绑定lightningChart // lightningChart.ViewXY.PointLineSeries.Add(ChartPointLineSeries); //} /// /// 实例化函数 /// public ChartRtSeries(LightningChart lightningChart, ChartConfig chartConfig, List listchartRtSeries, ConfigChartSelect configChartSelect) { //模型赋值 LightningChartInstance = lightningChart; ChartConfigInfo = chartConfig; ChartAxisY = configChartSelect.ConfigChartYAxis; ChartAxisX = LightningChartInstance.ViewXY.XAxes[0]; Name = configChartSelect.Name; ListChartRtSeries= listchartRtSeries; AddSeries(configChartSelect.Name!, configChartSelect.ConfigChartYAxis!); } #region 基本信息 private string? _Name; /// /// 名称 /// public string? Name { get { return _Name; } set { _Name = value; RaisePropertyChanged(); } } private double _Value; /// /// 值 /// public double Value { get { return _Value; } set { _Value = value; RaisePropertyChanged(); } } //private string? _Unit; ///// ///// 单位 ///// //public string? Unit //{ // get { return _Unit; } // set { _Unit = value; RaisePropertyChanged(); } //} #endregion /// /// 删除Y轴信息 /// public void DeleteAxisY() { //删除Y轴信息 LightningChartInstance.ViewXY.YAxes.Remove(LightningChartInstance.ViewXY.YAxes.FindFirst(a => a.Title.Text == ChartAxisY.Name)); } /// /// 删除系列 /// public void DeleteSeries() { LightningChartInstance.BeginUpdate(); LightningChartInstance.ViewXY.PointLineSeries.Remove(ChartPointLineSeries); LightningChartInstance.EndUpdate(); ListChartRtSeries.Remove(ListChartRtSeries.FindFirst(a=>a.Name== Name)); } /// /// 增加系列 /// /// private void AddSeries(string SeriesName, ConfigChartYAxis configChartYAxis) { LightningChartInstance.BeginUpdate(); //判断之前的系列是否已经存在(依据名称),存在使用之前的系列,否则新增 var AxisYInfo = GetAxisY(configChartYAxis.Name); if (AxisYInfo == null) { //新增 AxisYInfo = new AxisY(); AxisYInfo.Title.Text = configChartYAxis.Name; AxisYInfo.Title.AllowDragging = false; AxisYInfo.SetRange(configChartYAxis.Min, configChartYAxis.Max); AxisYInfo.MajorGrid.Visible = false; //取消滚轮缩放 AxisYInfo.ZoomingEnabled = false; LightningChartInstance.ViewXY.YAxes.Add(AxisYInfo); } else { //使用之前 AxisYInfo.SetRange(configChartYAxis.Min, configChartYAxis.Max); } var SeriesInfo = GetPointLineSeries(SeriesName); if (SeriesInfo == null) { //新增 SeriesInfo = new PointLineSeries(LightningChartInstance.ViewXY, LightningChartInstance.ViewXY.XAxes[0], AxisYInfo); SeriesInfo.Title.Text = SeriesName; SeriesInfo.LineStyle.Color = ChartConfigInfo.ListColor[LightningChartInstance.ViewXY.YAxes.Count + 1]; SeriesInfo.AllowUserInteraction = false; LightningChartInstance.ViewXY.PointLineSeries.Add(SeriesInfo); } else { //使用之前 SeriesInfo.AssignYAxisIndex = AxisYInfo.SegmentIndex; } //赋值给当前的模型 ChartPointLineSeries = SeriesInfo; //Configure and add series to the chart LightningChartInstance.EndUpdate(); } /// /// 获取AxisY信息 /// /// /// private AxisY GetAxisY(string AxisName) { var AxisYs = LightningChartInstance.ViewXY.YAxes; if (AxisYs != null) { var findAxis = AxisYs.FindFirst(a => a.Title.Text == AxisName); if (findAxis != null) { return findAxis; } else { return null; } } else { return null; } } /// /// 获取PointLineSeries信息 /// /// /// private PointLineSeries GetPointLineSeries(string SeriesName) { var PointLineSeries = LightningChartInstance.ViewXY.PointLineSeries; if (PointLineSeries != null) { var findSeries = PointLineSeries.FindFirst(a => a.Title.Text == SeriesName); if (findSeries != null) { return findSeries; } else { return null; } } else { return null; } } /// /// 上层管理集合 /// public List ListChartRtSeries { get; set; } /// /// 曲线 /// public PointLineSeries? ChartPointLineSeries { get; set; } /// /// Y轴 /// public ConfigChartYAxis? ChartAxisY { get; set; } /// /// X轴 /// public AxisX? ChartAxisX { get; set; } /// /// LightningChart 实例 /// public LightningChart LightningChartInstance { get; set; } /// /// 曲线配置信息 /// public ChartConfig ChartConfigInfo { get; set; } /// /// X轴滚动 /// private bool ScrollEnable = true; /// /// Chart图表X轴的跨度-秒 /// private int ChartXDateTimeRange = 3600; /// /// 增加数据 /// public void AddValue(double Data) { //foreach (var item in LightningChartInstance.ViewXY.PointLineSeries) //{ //Disable updates, to prevent several extra refreshes LightningChartInstance.BeginUpdate(); //Array for 1 point SeriesPoint[] points = new SeriesPoint[1]; //Convert 'Now' to X value var _previousX = LightningChartInstance.ViewXY.XAxes[0].DateTimeToAxisValue(DateTime.Now); points[0].X = _previousX; points[0].Y = Data; //Add the new point into end of first PointLineSeries ChartPointLineSeries.AddPoints(points, false); ChartPointLineSeries.DeletePointsBeforeX(_previousX - ChartXDateTimeRange); //item.DeletePointsBeforeX(_previousX - 100); if (ScrollEnable) { LightningChartInstance.ViewXY.XAxes[0].ScrollPosition = _previousX; } //Allow updates again, and update LightningChartInstance.EndUpdate(); Value = Data; //} } /// /// Solve value from series data points array. Accurate method, but slower than SolveValueCoarse /// /// Series /// X value /// Output Y value /// Success status private bool SolveValueAccurate(PointLineSeries series, double xValue, out double yValue) { AxisY axisY = LightningChartInstance.ViewXY.YAxes[series.AssignYAxisIndex]; yValue = 0; LineSeriesValueSolveResult result = series.SolveYValueAtXValue(xValue); if (result.SolveStatus == LineSeriesSolveStatus.OK) { //PointLineSeries may have two or more points at same X value. If so, center it between min and max yValue = (result.YMax + result.YMin) / 2.0; return true; } else { return false; } } /// /// Solve value from screen coordinates. Faster method, but not less accurateValue than SolveValueAccurate /// /// Series /// X value /// Output Y value /// Success status private bool SolveValueCoarse(PointLineSeries series, double xValue, out double yValue) { AxisY axisY = LightningChartInstance.ViewXY.YAxes[series.AssignYAxisIndex]; float coordX = LightningChartInstance.ViewXY.XAxes[0].ValueToCoord(xValue); float coordY; yValue = 0; LineSeriesCoordinateSolveResult result = series.SolveYCoordAtXCoord(coordX); if (result.SolveStatus == LineSeriesSolveStatus.OK) { coordY = (result.CoordBottom + result.CoordTop) / 2f; if (axisY.CoordToValue((int)Math.Round(coordY), out yValue) == false) { return false; } } else { return false; } return true; } } }