首先,声明,我用的是CommunityToolkit.Mvvm框架,大家可以根据自己的实际情况来改
[ObservableProperty]
PlotModel _PM;
/// <summary>
/// 原始数据
/// </summary>
[ObservableProperty]
private ObservableCollection<DataPoint> _Series1Points = new();
/// <summary>
/// 计算数据
/// </summary>
[ObservableProperty]
private ObservableCollection<DataPoint> _Series2Points = new();
/// <summary>
/// 未知数据
/// </summary>
[ObservableProperty]
private ObservableCollection<DataPoint> _Series3Points = new();
我是初始化页面的时候初始化控件
/// <summary>
/// 初始化页面 显示空白轴
/// </summary>
/// <returns></returns>
public void InitPlotModel()
{
try
{
PM = new PlotModel
{
PlotType = PlotType.Cartesian,
PlotAreaBorderThickness = new OxyThickness(1, 0, 0, 1),
};
var series1 = new LineSeries
{
Color = OxyColors.Transparent,
MarkerType = MarkerType.Circle,
MarkerSize = 4,
MarkerStroke = OxyColors.Green,
MarkerStrokeThickness = 1.5,
CanTrackerInterpolatePoints = false,
ItemsSource = Series1Points,
};
var series2 = new LineSeries
{
StrokeThickness = 4,
MarkerType = MarkerType.None,
CanTrackerInterpolatePoints = false,
ItemsSource = Series2Points,
};
var series3 = new LineSeries
{
Color = OxyColors.Transparent,
MarkerType = MarkerType.Circle,
MarkerSize = 4,
MarkerStroke = OxyColors.DeepPink,
MarkerStrokeThickness = 1.5,
CanTrackerInterpolatePoints = false,
ItemsSource = Series3Points,
};
XMax = 1; XMin = 0; YMax = 1; YMin = 0;
var linearAxis1 = new OxyPlot.Axes.LinearAxis()
{
AbsoluteMaximum = YMax,
AbsoluteMinimum = YMin,
Maximum = YMax,
Minimum = YMin,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.Dot,
Title = "Y",
Position = OxyPlot.Axes.AxisPosition.Left,
IsZoomEnabled = false,//坐标轴缩放关闭
IsPanEnabled = false,//图表缩放功能关闭
};
var linearAxis2 = new OxyPlot.Axes.LinearAxis()
{
AbsoluteMaximum = XMax,
AbsoluteMinimum = XMin,
Maximum = XMax,
Minimum = XMin,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.Dot,
Position = OxyPlot.Axes.AxisPosition.Bottom,
Title = $"X",
IsZoomEnabled = false,//坐标轴缩放关闭
IsPanEnabled = false,//图表缩放功能关闭
};
PM.Axes.Add(linearAxis1);
PM.Axes.Add(linearAxis2);
PM.Series.Add(series1);//将线添加到图标的容器中
PM.Series.Add(series2);//将线添加到图标的容器中
PM.Series.Add(series3);//将线添加到图标的容器中
PM.InvalidatePlot(true);
}
catch (Exception ex)
{
LogHelper.GetSingleObj().WriteLog(ex);
}
}
/// <summary>
/// 选择拟合类型
/// </summary>
[RelayCommand]
private async void Type()
{
new LoadingWin().Show();//这是我的加载动画,大家可以忽略
try
{
await Task.Run(() =>
{
xxx();
});
WeakReferenceMessenger.Default.Send("CloseLoading");//关闭加载动画
}
catch (Exception ex)
{
WeakReferenceMessenger.Default.Send("CloseLoading");
LogHelper.GetSingleObj().WriteLog(ex);//日志.这里大家可以替换成自己写日志的方案
}
}
/// <summary>
/// 更新数据
/// </summary>
/// <returns></returns>
public void xxxx()
{
try
{
Formula = string.Empty;
var series = PM.Series.OfType<LineSeries>().ToList();
series[1].InterpolationAlgorithm = InterpolationAlgorithms.CatmullRomSpline;//平滑曲线
series?.Clear();
if (TempList?.Count > 0)
{
var list = TempList.Where(x => x.a!= null);
if (list.Any() == false)
{
InitPlotModel();
return;
}
}
else
{
InitPlotModel();
return;
}
Ydoubles.Clear();
Xdoubles.Clear();
if (TempList?.Count > 0)
{
Series1Points.Clear();
Series2Points.Clear();
Parallel.ForEach(TempList, item =>
{
if (double.TryParse(item.a, out var a) && double.TryParse(item.b, out var b))
{
Series1Points.Add(new DataPoint(a, b));
}
});
for (int i = 0; i < 1000; i++)
{
Series2Points.Add(new DataPoint(i, xxx.xxx(i)));
}
Ydoubles.AddRange(Series2Points.Select(x => x.Y));
Xdoubles.AddRange(Series2Points.Select(x => x.X));
}
if (UnKnowList?.Count > 0)
{
Series3Points.Clear();
UnKnowList.ForEach(x =>
{
var Y = double.Parse(x.a);
var X = xxx.xxxx(Y);//这是我用来计算x值的方法
Ydoubles.Add(Y);
Xdoubles.Add(X);
Series3Points.Add(new DataPoint(X, Y));//添加线的第二个点的坐标
});
}
SetValues();
}
catch (Exception ex)
{
LogHelper.GetSingleObj().WriteLog(ex);
}
}
//这是个公用方法,每次更新数据之后,x轴和y轴都要更新
private void SetValues()
{
if (Ydoubles?.Count > 0)
{
YMax = Ydoubles.Max();
BaseValue = Math.Abs(YMax * 0.2);
YMin = Ydoubles.Min();
YMax += BaseValue;
YMin -= BaseValue;
if (YMax == YMin)
{
YMax++;
YMin--;
}
}
else
{
//Y_Max =1;Y_Min =0;
BaseValue = Math.Abs(Y_Max * 0.1);
YMax = Y_Max + BaseValue;
YMin = Y_Min - BaseValue;
if (YMax == YMin)
{
YMax++;
YMin--;
}
}
if (Xdoubles?.Count > 0)
{
XMax = Xdoubles.Max();
BaseValue = Math.Abs(XMax * 0.1);
XMin = Xdoubles.Min();
XMax += BaseValue;
XMin -= BaseValue;
if (XMax == XMin)
{
XMax++;
XMin--;
}
}
else
{
//X_Max =1;X_Min =0;
BaseValue = Math.Abs(X_Max * 0.1);
XMax = X_Max + BaseValue;
XMin = X_Min - BaseValue;
if (XMax == XMin)
{
XMax++;
XMin--;
}
}
PM.Axes[0].AbsoluteMaximum = YMax;
PM.Axes[0].AbsoluteMinimum = YMin;
PM.Axes[0].Maximum = YMax;
PM.Axes[0].Minimum = YMin;
PM.Axes[0].Reset();
PM.Axes[1].AbsoluteMaximum = XMax;
PM.Axes[1].AbsoluteMinimum = XMin;
PM.Axes[1].Maximum = XMax;
PM.Axes[1].Minimum = XMin;
PM.Axes[1].Title = $"xxx";
PM.Axes[1].Reset();
// 更新图表数据
PM.InvalidatePlot(true);
}
页面plotview双向绑定是这样的
xmlns:oxy="http://oxyplot.org/wpf"
<oxy:PlotView Model="{Binding PM}" Margin="0,0,0,20"
VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True" />
我是根据combobox的选择,来更新plotview的数据
<TextBlock Text="刷新plot" Margin="0,12,0,12" DockPanel.Dock="Top" />
<ComboBox ItemsSource="{Binding xxxxxx}" Margin="0,0,0,30" Width="190" Height="56" DockPanel.Dock="Top" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TypeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>