wpf 如何在 OxyPlot 图表上绘制 MULTIPLE LineSeries?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24938689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to plot MULTIPLE LineSeries on an OxyPlot chart?
提问by John August
I apologize for asking so many OxyPlot questions, but I seem to be really struggling with using the OxyPlot chart control.
我很抱歉问了这么多 OxyPlot 问题,但我似乎真的很难使用 OxyPlot 图表控件。
My project is in WPF format so I was originally using a hosted WINFORMS chart and that worked like a charm and did absolutely everything I needed it to until I needed to overlay a WPF element on top of the hosted winform chart. Due to the "AirSpace" issue, I was not able to see the WPF element that I put on top of the hosted chart no matter what I did. That is when I decided to go with OxyPlot, which is giving me quite a few headaches so far.
我的项目采用 WPF 格式,所以我最初使用的是托管的 WINFORMS 图表,它的工作原理非常棒,并且完全满足了我的需求,直到我需要在托管的 winform 图表上覆盖一个 WPF 元素。由于“AirSpace”问题,无论我做什么,我都无法看到放在托管图表顶部的 WPF 元素。那是我决定使用 OxyPlot 的时候,到目前为止,这让我很头疼。
Here is my origional question! that I asked over at CodePlex. I don't seem to be getting much help over there so I am trying again here.
这是我的原始问题!我在 CodePlex 上问过的。我在那里似乎没有得到太多帮助,所以我在这里再试一次。
My question is:
我的问题是:
Does anyone know how to plot MULTIPLE LineSeries onto a Plot??
有谁知道如何将 MULTIPLE LineSeries 绘制到图上?
My approach so far:
到目前为止我的方法:
I am taking a c# List array and adding a new copy of the LineSeries that holds new data to be plotted. My code:
我正在使用 ac# List 数组并添加 LineSeries 的新副本,其中包含要绘制的新数据。我的代码:
// Function to plot data
private void plotData(double numWeeks, double startingSS)
{
// Initialize new Salt Split class for acess to data variables
Salt_Split_Builder calcSS = new Salt_Split_Builder();
calcSS.compute(numWeeks, startingSS, maxDegSS);
// Create the OxyPlot graph for Salt Split
OxyPlot.Wpf.PlotView plot = new OxyPlot.Wpf.PlotView();
var model = new PlotModel();
// Add Chart Title
model.Title = "Salt Split Degradation";
// Create new Line Series
LineSeries linePoints = new LineSeries() { StrokeThickness = 1, MarkerSize = 1, Title = numWeeks.ToString() + " weeks" };
// Add each point to the new series
foreach (var point in calcSS.saltSplitCurve)
{
DataPoint XYpoint = new DataPoint();
XYpoint = new DataPoint(point.Key, point.Value * 100);
linePoints.Format("%", XYpoint.Y);
linePoints.Points.Add(XYpoint);
}
listPointAray.Add(linePoints);
// Define X-Axis
var Xaxis = new OxyPlot.Axes.LinearAxis();
Xaxis.Maximum = numWeeks;
Xaxis.Minimum = 0;
Xaxis.Position = OxyPlot.Axes.AxisPosition.Bottom;
Xaxis.Title = "Number of Weeks";
model.Axes.Add(Xaxis);
//Define Y-Axis
var Yaxis = new OxyPlot.Axes.LinearAxis();
Yaxis.MajorStep = 15;
Yaxis.Maximum = calcSS.saltSplitCurve.Last().Value * 100;
Yaxis.MaximumPadding = 0;
Yaxis.Minimum = 0;
Yaxis.MinimumPadding = 0;
Yaxis.MinorStep = 5;
Yaxis.Title = "Percent Degradation";
model.Axes.Add(Yaxis);
// Add Each series to the
foreach (var series in listPointAray)
{
LineSeries newpoints = new LineSeries();
newpoints = linePoints;
model.Series.Add(newpoints);
}
// Add the plot to the window
plot.Model = model;
SaltSplitChartGrid.Children.Add(plot);
}
My code works the first time I press my "Graph Data" button, but fails on consecutive attempts with the following error:
我的代码在我第一次按下“图形数据”按钮时工作,但连续尝试失败并出现以下错误:
The element cannot be added, it already belongs to a Plot Model
无法添加元素,它已属于绘图模型
The following plot is the type of plot I would like to produce (it worked fine using WinForms Chart control):
下面的图是我想要生成的图类型(使用 WinForms Chart 控件可以正常工作):
I would like a new line with a new color to be plotted each time I run the method.
我希望每次运行该方法时都绘制一条具有新颜色的新线。
采纳答案by John August
Sucess!!!!
成功!!!!
AwkwardCoder, thank you for the help, but I realized my mistake was just me having overlooked some things!
AwkwardCoder,谢谢你的帮助,但我意识到我的错误只是我忽略了一些事情!
Here is the version of the code that works:
这是有效的代码版本:
// Make a new plotmodel
private PlotModel model = new PlotModel();
// Create the OxyPlot graph for Salt Split
private OxyPlot.Wpf.PlotView plot = new OxyPlot.Wpf.PlotView();
// Function to plot data
private void plotData(double numWeeks, double startingSS)
{
List<LineSeries> listPointAray = new List<LineSeries>();
// Initialize new Salt Split class for acess to data variables
Salt_Split_Builder calcSS = new Salt_Split_Builder();
calcSS.compute(numWeeks, startingSS, maxDegSS);
// Create new Line Series
LineSeries linePoints = new LineSeries()
{ StrokeThickness = 1, MarkerSize = 1, Title = numWeeks.ToString() + " weeks" };
// Add each point to the new series
foreach (var point in calcSS.saltSplitCurve)
{
DataPoint XYpoint = new DataPoint();
XYpoint = new DataPoint(point.Key, point.Value * 100);
linePoints.Format("%", XYpoint.Y);
linePoints.Points.Add(XYpoint);
}
listPointAray.Add(linePoints);
// Add Chart Title
model.Title = "Salt Split Degradation";
// Add Each series to the
foreach (var series in listPointAray)
{
// Define X-Axis
OxyPlot.Axes.LinearAxis Xaxis = new OxyPlot.Axes.LinearAxis();
Xaxis.Maximum = numWeeks;
Xaxis.Minimum = 0;
Xaxis.Position = OxyPlot.Axes.AxisPosition.Bottom;
Xaxis.Title = "Number of Weeks";
model.Axes.Add(Xaxis);
//Define Y-Axis
OxyPlot.Axes.LinearAxis Yaxis = new OxyPlot.Axes.LinearAxis();
Yaxis.MajorStep = 15;
Yaxis.Maximum = calcSS.saltSplitCurve.Last().Value * 100;
Yaxis.MaximumPadding = 0;
Yaxis.Minimum = 0;
Yaxis.MinimumPadding = 0;
Yaxis.MinorStep = 5;
Yaxis.Title = "Percent Degradation";
//Yaxis.StringFormat = "{0.00} %";
model.Axes.Add(Yaxis);
model.Series.Add(series);
}
// Add the plot to the window
plot.Model = model;
plot.InvalidatePlot(true);
SaltSplitChartGrid.Children.Clear();
SaltSplitChartGrid.Children.Add(plot);
}
Here are the multiple things I did wrong:
以下是我做错的多件事:
- In my foreach var series loop, I was adding the original series which had already been added and NOT the next var series in the list! (dumb!)
- I was creating a new model each time I ran the method. This means that each time the code ran, I was adding a series that already existed in the previous model. (also dumb!)
- I was creating a new plot every time and trying to add a model in the new plot that already belonged to a previous plot. (getting dummer..)
- The plot was being added to the grid each time I ran the method, so I had to CLEAR the grid's children first before re-adding the same plot.
- I was not refreshing the plot.
- 在我的 foreach var 系列循环中,我添加了已添加的原始系列,而不是列表中的下一个 var 系列!(哑的!)
- 每次运行该方法时,我都在创建一个新模型。这意味着每次运行代码时,我都会添加之前模型中已经存在的系列。(也蠢!)
- 我每次都在创建一个新图,并尝试在新图中添加一个已经属于前一个图的模型。(越来越傻了..)
- 每次运行该方法时,都会将绘图添加到网格中,因此在重新添加相同的绘图之前,我必须先清除网格的子项。
- 我没有刷新情节。
That was a lot of mistakes, but I worked through it. Hopefully this helps someone in the future. Also, I know I am not using ordinary data binding techniques, but this, at-least, works.
那是很多错误,但我克服了它。希望这对将来的人有所帮助。另外,我知道我没有使用普通的数据绑定技术,但这至少是有效的。
回答by AwkwardCoder
This is how I've created multi lines on an OxyPlot chart before, the key is creating a set of DataPoints for each series - called circlePoints & linePoints in the following example code, these are then bound to the CircleSeries and LineSeries:
这就是我之前在 OxyPlot 图表上创建多行的方式,关键是为每个系列创建一组数据点 - 在以下示例代码中称为 circlePoints 和 linePoints,然后将它们绑定到 CircleSeries 和 LineSeries:
var xAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
StringFormat = Constants.MarketData.DisplayDateFormat,
Title = "End of Day",
IntervalLength = 75,
MinorIntervalType = DateTimeIntervalType.Days,
IntervalType = DateTimeIntervalType.Days,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.None,
};
var yAxis = new LinearAxis
{
Position = AxisPosition.Left,
Title = "Value",
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.None
};
var plot = new PlotModel();
plot.Axes.Add(xAxis);
plot.Axes.Add(yAxis);
var circlePoints = new[]
{
new ScatterPoint(DateTimeAxis.ToDouble(date1), value1),
new ScatterPoint(DateTimeAxis.ToDouble(date2), value2),
};
var circleSeries = new ScatterSeries
{
MarkerSize = 7,
MarkerType = MarkerType.Circle,
ItemsSource = circlePoints
};
var linePoints = new[]
{
new DataPoint(DateTimeAxis.ToDouble(date1), value1),
new DataPoint(DateTimeAxis.ToDouble(date2), value2),
};
var lineSeries = new LineSeries
{
StrokeThickness = 2,
Color = LineDataPointColor,
ItemsSource = linePoints
};
plot.Series.Add(circleSeries);
plot.Series.Add(lineSeries);
回答by Bloggrammer
Here is how you can achieve a similar result in XAML especially if you are using the MVVM approach.
以下是在 XAML 中获得类似结果的方法,尤其是在使用 MVVM 方法时。
ViewModel:
视图模型:
public ObservableCollection<DataPoint> DataPointList1 {get;set;}
public ObservableCollection<DataPoint> DataPointList2 {get;set;}
public ObservableCollection<DataPoint> DataPointList3 {get;set;}
public ObservableCollection<DataPoint> DataPointList4 {get;set;}
Using a for loop like below populates DataPointList1 to DataPointList4 with the appropriate datasets.
使用如下所示的 for 循环,使用适当的数据集填充 DataPointList1 到 DataPointList4。
for (int i = 0; i < dataList.Count; i++)
{
DataPointList1 .Add(new DataPoint{dataList[i].XValue,dataList[i].YValue });
}
XAML:
XAML:
xmlns:oxy="http://oxyplot.org/wpf"
<oxy:Plot LegendPlacement="Outside" LegendPosition="RightMiddle" Title="Your Chart Title" >
<oxy:Plot.Axes>
<oxy:LinearAxis Title="Your X-axis Title" Position="Bottom" IsZoomEnabled="True" />
<oxy:LinearAxis Title="Your Y-axis Title" Position="Left" IsZoomEnabled="True" />
</oxy:Plot.Axes>
<oxy:Plot.Series>
<oxy:LineSeries Title="Plot1" Color="Black" ItemsSource="{Binding DataPointList1 }"/>
<oxy:LineSeries Title="Plot2" Color="Green" ItemsSource="{Binding DataPointList2 }"/>
<oxy:LineSeries Title="Plot3" Color="Blue" ItemsSource="{Binding DataPointList3 }"/>
<oxy:LineSeries Title="Plot4" Color="Red" ItemsSource="{Binding DataPointList4 }"/>
</oxy:Plot.Series>
</oxy:Plot>


