using System;namespace Wpf.CartesianChart.ConstantChanges
{publicclassMeasureModel{publicDateTime DateTime {get;set;}publicdouble Value {get;set;}}}
后台:
using System;using System.ComponentModel;using System.Threading;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using LiveCharts;using LiveCharts.Configurations;namespace Wpf.CartesianChart.ConstantChanges
{publicpartialclassConstantChangesChart:UserControl, INotifyPropertyChanged
{privatedouble _axisMax;privatedouble _axisMin;privatedouble _trend;publicConstantChangesChart(){InitializeComponent();//To handle live data easily, in this case we built a specialized type//the MeasureModel class, it only contains 2 properties//DateTime and Value//We need to configure LiveCharts to handle MeasureModel class//The next code configures MeasureModel globally, this means//that LiveCharts learns to plot MeasureModel and will use this config every time//a IChartValues instance uses this type.//this code ideally should only run once//you can configure series in many ways, learn more at //http://lvcharts.net/App/examples/v1/wpf/Types%20and%20Configurationvar mapper = Mappers.Xy<MeasureModel>().X(model => model.DateTime.Ticks)//use DateTime.Ticks as X.Y(model => model.Value);//use the value property as Y//lets save the mapper globally.
Charting.For<MeasureModel>(mapper);//the values property will store our values array
ChartValues =newChartValues<MeasureModel>();//lets set how to display the X Labels
DateTimeFormatter =value=>newDateTime((long)value).ToString("mm:ss");//AxisStep forces the distance between each separator in the X axis
AxisStep = TimeSpan.FromSeconds(1).Ticks;//AxisUnit forces lets the axis know that we are plotting seconds//this is not always necessary, but it can prevent wrong labeling
AxisUnit = TimeSpan.TicksPerSecond;SetAxisLimits(DateTime.Now);//The next code simulates data changes every 300 ms
IsReading =false;
DataContext =this;}public ChartValues<MeasureModel> ChartValues {get;set;}public Func<double,string> DateTimeFormatter {get;set;}publicdouble AxisStep {get;set;}publicdouble AxisUnit {get;set;}publicdouble AxisMax
{get{return _axisMax;}set{
_axisMax =value;OnPropertyChanged("AxisMax");}}publicdouble AxisMin
{get{return _axisMin;}set{
_axisMin =value;OnPropertyChanged("AxisMin");}}publicbool IsReading {get;set;}privatevoidRead(){var r =newRandom();while(IsReading){
Thread.Sleep(150);var now = DateTime.Now;
_trend += r.Next(-8,10);
ChartValues.Add(newMeasureModel{
DateTime = now,
Value = _trend
});SetAxisLimits(now);//lets only use the last 150 valuesif(ChartValues.Count >150) ChartValues.RemoveAt(0);}}privatevoidSetAxisLimits(DateTime now){
AxisMax = now.Ticks + TimeSpan.FromSeconds(1).Ticks;// lets force the axis to be 1 second ahead
AxisMin = now.Ticks - TimeSpan.FromSeconds(8).Ticks;// and 8 seconds behind}privatevoidInjectStopOnClick(object sender,RoutedEventArgs e){
IsReading =!IsReading;if(IsReading) Task.Factory.StartNew(Read);}#region INotifyPropertyChanged implementationpubliceventPropertyChangedEventHandler PropertyChanged;protectedvirtualvoidOnPropertyChanged(string propertyName =null){if(PropertyChanged !=null)
PropertyChanged.Invoke(this,newPropertyChangedEventArgs(propertyName));}#endregion}}
前台:
<UserControlx:Class="Wpf.CartesianChart.ConstantChanges.ConstantChangesChart"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:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"xmlns:constantChanges="clr-namespace:Wpf.CartesianChart.ConstantChanges"mc:Ignorable="d"d:DesignHeight="300"d:DesignWidth="300"d:DataContext="{d:DesignInstance constantChanges:ConstantChangesChart}"><Grid><Grid.RowDefinitions><RowDefinitionHeight="Auto"></RowDefinition><RowDefinitionHeight="*"></RowDefinition></Grid.RowDefinitions><ButtonGrid.Row="0"Click="InjectStopOnClick">
Inject/Stop Data
</Button><!--Here we disable tooltips and hovering to get a better performance--><lvc:CartesianChartGrid.Row="1"AnimationsSpeed="0:0:0.5"Hoverable="False"DataTooltip="{x:Null}"><lvc:CartesianChart.Series><lvc:LineSeriesValues="{Binding ChartValues}"PointGeometry="{x:Null}"LineSmoothness="1"StrokeThickness="6"Stroke="#F34336"Fill="Transparent"/></lvc:CartesianChart.Series><lvc:CartesianChart.AxisX><lvc:AxisLabelFormatter="{Binding DateTimeFormatter}"MaxValue="{Binding AxisMax}"MinValue="{Binding AxisMin}"Unit="{Binding AxisUnit}"><lvc:Axis.Separator><lvc:SeparatorStep="{Binding AxisStep}"/></lvc:Axis.Separator></lvc:Axis></lvc:CartesianChart.AxisX></lvc:CartesianChart></Grid></UserControl>