标签:
创建项目后,打开管理器控制台,在提示符下键入以下命令并打(每一个命令之后),请输入:
当然你也可以使用软件包管理器用户界面右击引用,然后选择管理NuGet软件包和他们的方式。
我们将使用MVVM模式(部分)呈现在屏幕上的图表。第一步是创建视图模型为我们MainWindow.xaml。用鼠标右键单击该项目,并添加一个文件夹的ViewModels。用鼠标右键单击该文件夹并添加一个类MainWindowModel.cs。
要使用MVVM模式,我们需要使公共类和继承INotifyPropertyChanged接口。
1234567891011121314151617 |
using System.ComponentModel;
using OxyPlotDemo.Annotations;
namespace OxyPlotDemo.ViewModels
{
public class MainWindowModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
|
现在,我们可以补充一点,我们会绑定到XAML页面的一些公共属性。首先创建一个PlotModel那是OxyPlot库的一部分。在构造函数中,我们将启动PlotModel参数。设定器将调用,将通知该视图中有物体上的变化,可能有要呈现的OnPropertyChanged方法。
123456789101112131415161718192021222324252627282930 |
using System.ComponentModel;
using OxyPlot;
using OxyPlotDemo.Annotations;
namespace OxyPlotDemo.ViewModels
{
public class MainWindowModel: INotifyPropertyChanged
{
private PlotModel plotModel;
public PlotModel PlotModel
{
get { return plotModel; }
set { plotModel = value; OnPropertyChanged("PlotModel"); }
}
public MainWindowModel()
{
PlotModel = new PlotModel();
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
|
现在,我们可以将图形添加到MainWindow.xaml页面。之前,我们可以添加图形,我们将需要添加的命名空间OxyPlot库(4号线)。我们将在PlotModel参数绑定到我们在视图模型创建的PlotModel。
12345678910 |
<Window x:Class="OxyPlotDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.codeplex.com"
Title="MainWindow" Height="350" Width="525">
<Grid>
<oxy:Plot x:Name="Plot1" Title="A Graph" Model="{Binding PlotModel}" Margin="10" Grid.Row="1">
</oxy:Plot>
</Grid>
</Window>
|
最后一部分,我们的设置是视图模型绑定到视图。因为我们不使用任何的MVVM框架,我们将不得不手动绑定模型在MainWindow.xaml页面背后的代码。
123456789101112131415161718192021 |
using System.Windows;
namespace OxyPlotDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ViewModels.MainWindowModel viewModel;
public MainWindow()
{
viewModel = new ViewModels.MainWindowModel();
DataContext = viewModel
InitializeComponent();
}
}
}
|
如果我们按F5键运行该应用程序,我们会看到一个空窗口打开。我们有一些数据的过程中添加到PlotModel图将呈现前。
回到我们的视图模型来建立我们的视图模型。第一次启动将增加轴的图,从而OxyPlot知道在哪里可以绘制点。
1234567891011121314 |
private void SetUpModel()
{
PlotModel.LegendTitle = "Legend";
PlotModel.LegendOrientation = LegendOrientation.Horizontal;
PlotModel.LegendPlacement = LegendPlacement.Outside;
PlotModel.LegendPosition = LegendPosition.TopRight;
PlotModel.LegendBackground = OxyColor.FromAColor(200, OxyColors.White);
PlotModel.LegendBorder = OxyColors.Black;
var dateAxis = new DateTimeAxis(AxisPosition.Bottom, "Date", "dd/MM/yy HH:mm") { MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot, IntervalLength = 80 };
PlotModel.Axes.Add(dateAxis);
var valueAxis = new LinearAxis(AxisPosition.Left, 0) { MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot, Title = "Value" };
PlotModel.Axes.Add(valueAxis);
}
|
该设置为图形的传说是自我解释。在第10行,你会看到创建的DateTimeAxis的。我们选择的轴的位置,给它一个名称(日期)和字符串格式样式如何日期有显示。下一步,我们将添加一些参数来显示主要和次要网格线和间隔大小。创建后,我们将添加轴到PlotModel。
现在,我们有我们的图形,并准备了一些图线添加到PlotModel。在这篇文章中,我们将添加四个不同的线路,这将是情节。
1234567891011121314151617181920212223 |
private void LoadData()
{
List<Measurement> measurements = Data.GetData();
var dataPerDetector = measurements.GroupBy(m => m.DetectorId).ToList();
foreach (var data in dataPerDetector)
{
var lineSerie = new LineSeries
{
StrokeThickness = 2,
MarkerSize = 3,
MarkerStroke = colors[data.Key],
MarkerType = markerTypes[data.Key],
CanTrackerInterpolatePoints = false,
Title = string.Format("Detector {0}",data.Key),
Smooth = false,
};
data.ToList().ForEach(d=>lineSerie.Points.Add(new DataPoint(DateTimeAxis.ToDouble(d.DateTime),d.Value)));
PlotModel.Series.Add(lineSerie);
}
}
|
获取数据后,我将使用LINQ GROUPBY表达式创建一个IEnumerable的与关键的DetectorId和值和DateTime的集合作为值。 (第5行)
对于我们的客户端的第二个问题,我们必须添加实时更新。对于这个演示中,我将添加一个新的测量到图形的每一秒。该OxyPlot库将确保我们的图表将每一起我们将添加一个新的测量时间移动。
我们将添加一个新的方法到视图模型的UpdateModel。这一次,我们将它公开,因此它可以从视图中被调用,如图中的下一个篇章。
12345678910111213141516 |
public void UpdateModel()
{
List<Measurement> measurements = Data.GetUpdateData(lastUpdate);
var dataPerDetector = measurements.GroupBy(m => m.DetectorId).OrderBy(m => m.Key).ToList();
foreach (var data in dataPerDetector)
{
var lineSerie = PlotModel.Series[data.Key] as LineSeries;
if (lineSerie != null)
{
data.ToList()
.ForEach(d => lineSerie.Points.Add(new DataPoint(DateTimeAxis.ToDouble(d.DateTime), d.Value)));
}
}
lastUpdate = DateTime.Now;
}
|
我们不希望该模型的更新开始之前,前一个是完全呈现,以避免我们正在修改,同时渲染图形列表的例外。为此,我们利用一个CompositionTarget.Rendering事件。此事件会在每次视图渲染完成时触发。
123456789101112131415 |
public MainWindow()
{
viewModel = new ViewModels.MainWindowModel();
DataContext = viewModel;
CompositionTarget.Rendering += CompositionTargetRendering;
InitializeComponent();
}
private void CompositionTargetRendering(object sender, EventArgs e)
{
viewModel.UpdateModel();
Plot1.RefreshPlot(true);
}
|
123456789101112131415161718192021222324 |
public MainWindow()
{
viewModel = new ViewModels.MainWindowModel();
DataContext = viewModel;
CompositionTarget.Rendering += CompositionTargetRendering;
stopwatch.Start();
InitializeComponent();
}
private long frameCounter;
private System.Diagnostics.Stopwatch stopwatch = new Stopwatch();
private long lastUpdateMilliSeconds;
private void CompositionTargetRendering(object sender, EventArgs e)
{
if (stopwatch.ElapsedMilliseconds > lastUpdateMilliSeconds + 5000)
{
viewModel.UpdateModel();
Plot1.RefreshPlot(true);
lastUpdateMilliSeconds = stopwatch.ElapsedMilliseconds;
}
}
|
加入秒表后,我们会看到每一个(这个演示5秒),一个新的点添加到图形。
正如你所看到的,与OxyPlot你不需要写很多的代码来创建实时更新图表。
标签:
原文地址:http://www.cnblogs.com/lvdongjie/p/5659322.html