如何使用动态数据显示在 wpf 中的一个 x-y 平面中添加多个图形
Posted
技术标签:
【中文标题】如何使用动态数据显示在 wpf 中的一个 x-y 平面中添加多个图形【英文标题】:How to add mutiple graph in one x-y plane in wpf using DynamicDataDisplay 【发布时间】:2017-04-20 10:13:46 【问题描述】:我必须使用 WPF 创建多个类似 http://prntscr.com/dfn836 的图形(我们在一个平面上有 4 个不同颜色的图形)。
我有 DynamicDataDisplaySample,它只显示一个正弦曲线图,但我的情况是我必须在同一个 x-y 轴(电压-时间轴)上显示多个图(让我们在这里说)。我有一组点可以使这两个图在同一平面上。
List<double> points_x_y_Graph1 = new List<double>() 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.1, 0.2, 0.3 ;
List<double> points_x_y_Graph2 = new List<double>() 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0,0.1, 0.2, 0.3 ;
关于如何在一个电压时间轴上制作两个图表,我的想法是为两个图表添加点,如下所示:
//This is for first graph
voltagePointCollection.Add(new VoltagePoint(points_x_y_Graph2[i], points_x_y_Graph2[i]));
//This is for second Graph
voltagePointCollection.Add(new VoltagePoint(points_x_y_Graph1[i], points_x_y_Graph1[i]));
但是我发现了什么(见这里http://prntscr.com/dfsy5e)。
我的完整代码是:
public partial class MainWindow : Window, INotifyPropertyChanged
List<double> points_x_y_Graph1 = new List<double>() 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.1, 0.2, 0.3 ;
List<double> points_x_y_Graph2 = new List<double>() 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0,0.1, 0.2, 0.3 ;
private int _maxVoltage; private int _minVoltage;
public int MaxVoltage
get return _maxVoltage;
set _maxVoltage = value; this.OnPropertyChanged("MaxVoltage");
public int MinVoltage
get return _minVoltage;
set _minVoltage = value; this.OnPropertyChanged("MinVoltage");
public VoltagePointCollection voltagePointCollection;
DispatcherTimer updateCollectionTimer;
private int i = 0;
public MainWindow()
InitializeComponent();
this.DataContext = this;
voltagePointCollection = new VoltagePointCollection();
updateCollectionTimer = new DispatcherTimer();
updateCollectionTimer.Interval = TimeSpan.FromMilliseconds(10);
updateCollectionTimer.Tick += new EventHandler(updateCollectionTimer_Tick);
updateCollectionTimer.Start();
var ds = new EnumerableDataSource<VoltagePoint>(voltagePointCollection);
ds.SetXMapping(x => x.time);
ds.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds, Colors.Green, 2, "Volts");
MaxVoltage = 1;
MinVoltage = -1;
void updateCollectionTimer_Tick(object sender, EventArgs e)
if (i >= points_x_y.Count)
i = 0;
//For first graph
voltagePointCollection.Add(new VoltagePoint(points_x_y_Graph2[i], points_x_y_Graph2[i]));
//For second graph
voltagePointCollection.Add(new VoltagePoint(points_x_y_Graph1[i], points_x_y_Graph1[i])); // To add one more graph
i++;
#region INotifyPropertyChanged members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
if (PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
#endregion
Xaml 代码:
<Window x:Class="DynamicDataDisplaySample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
Title="MainWindow" Height="600" Width="800">
<Grid>
<d3:ChartPlotter x:Name="plotter" Grid.Row="1" Grid.Column="1">
<d3:ChartPlotter.HorizontalAxis>
<d3:HorizontalDateTimeAxis Name="dateAxis"/>
</d3:ChartPlotter.HorizontalAxis>
<d3:Header FontFamily="Georgia" Content="Voltage chart"/>
<d3:VerticalAxisTitle FontFamily="Georgia" Content="Voltage [V]" />
<d3:HorizontalAxisTitle FontFamily="Georgia" Content="Time"/>
<d3:HorizontalLine Value="Binding MaxVoltage" Stroke="Red" StrokeThickness="2"/>
<d3:HorizontalLine Value="Binding MinVoltage" Stroke="Red" StrokeThickness="2"/>
</d3:ChartPlotter>
</Grid>
</Window>
其他两个类:
public class VoltagePointCollection : RingArray <VoltagePoint>
private const int TOTAL_POINTS = 300;
public VoltagePointCollection()
: base(TOTAL_POINTS) // here i set how much values to show
public class VoltagePoint
public DateTime Date get; set;
public double time get; set;
public double Voltage get; set;
public VoltagePoint(double voltage, double time)
this.Voltage = voltage;
this.time = time;
如何在一个 x-y 轴上制作这两个图表,就像开始时显示的链接一样,其中包含一个 x-y 轴上的 4 个图表。
【问题讨论】:
【参考方案1】:基本上,您需要再次调用AddLineGraph
,并提供相应的关联数据。我做了一些最小的修改,足以让它工作,包括你的数据。请看下面:
XAML:
<Grid>
<d3:ChartPlotter x:Name="plotter" Grid.Row="1" Grid.Column="1">
<!--
<d3:ChartPlotter.HorizontalAxis>
<d3:HorizontalDateTimeAxis Name="dateAxis"/>
</d3:ChartPlotter.HorizontalAxis>
-->
<d3:Header FontFamily="Georgia" Content="Voltage chart"/>
<d3:VerticalAxisTitle FontFamily="Georgia" Content="Voltage [V]" />
<d3:HorizontalAxisTitle FontFamily="Georgia" Content="Time"/>
<d3:HorizontalLine Value="Binding MaxVoltage" Stroke="Red" StrokeThickness="2"/>
<d3:HorizontalLine Value="Binding MinVoltage" Stroke="Red" StrokeThickness="2"/>
</d3:ChartPlotter>
</Grid>
主窗口:
public partial class MainWindow : Window, INotifyPropertyChanged
List<double> points_x_y_Graph1 = new List<double>() 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.9, 0.8, 0.7 ;
List<double> points_x_y_Graph2 = new List<double>() 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, 0.1, 0.2, 0.3 ;
private int _maxVoltage; private int _minVoltage;
public int MaxVoltage
get return _maxVoltage;
set _maxVoltage = value; this.OnPropertyChanged("MaxVoltage");
public int MinVoltage
get return _minVoltage;
set _minVoltage = value; this.OnPropertyChanged("MinVoltage");
public VoltagePointCollection voltagePointCollection1;
public VoltagePointCollection voltagePointCollection2;
DispatcherTimer updateCollectionTimer;
private int i = 0;
public MainWindow()
InitializeComponent();
this.DataContext = this;
updateCollectionTimer = new DispatcherTimer();
updateCollectionTimer.Interval = TimeSpan.FromMilliseconds(500);
updateCollectionTimer.Tick += new EventHandler(updateCollectionTimer_Tick);
updateCollectionTimer.Start();
voltagePointCollection1 = new VoltagePointCollection();
var ds1 = new EnumerableDataSource<VoltagePoint>(voltagePointCollection1);
ds1.SetXMapping(x => x.time);
ds1.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds1, Colors.Green, 2, "Volts 1");
MaxVoltage = 1;
MinVoltage = -1;
voltagePointCollection2 = new VoltagePointCollection();
var ds2 = new EnumerableDataSource<VoltagePoint>(voltagePointCollection2);
ds2.SetXMapping(x => x.time);
ds2.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds2, Colors.Blue, 2, "Volts 2");
void updateCollectionTimer_Tick(object sender, EventArgs e)
if (i < points_x_y_Graph1.Count)
// i = 0;
//For first graph
voltagePointCollection1.Add(new VoltagePoint(points_x_y_Graph1[i], i));
//For second graph
voltagePointCollection2.Add(new VoltagePoint(points_x_y_Graph2[i], i)); // To add one more graph
i++;
#region INotifyPropertyChanged members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
if (PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
#endregion
【讨论】:
以上是关于如何使用动态数据显示在 wpf 中的一个 x-y 平面中添加多个图形的主要内容,如果未能解决你的问题,请参考以下文章
c# wpf中如何向expander中动态添加xml中的内容