【发布时间】:2013-02-15 14:54:09
【问题描述】:
我正在尝试使用 WPF 和 C#(动态数据显示)绘制实时信号、信号与时间的关系;一旦产生信号,它应该立即显示在图表上;可以非常快地生成信号(大约毫秒(0.001 秒)); 最好的方法是什么?任何建议表示赞赏。谢谢。
编辑:一个示例代码将不胜感激。
这是我尝试过的:
剧情开始:
#region Constructor
public SignalStatsDisplay()
{
InitializeComponent();
plotter.Legend.Remove();
_initialChildrenCount = plotter.Children.Count;
int count = plotter.Children.Count;
//do not remove the initial children
if (count > _initialChildrenCount)
{
for (int i = count - 1; i >= _initialChildrenCount; i--)
{
plotter.Children.RemoveAt(i);
}
}
_nColorChannels = 4;
_lineprofileColor = new Color[4];
_lineprofileColor[0] = Colors.Transparent;
_lineprofileColor[1] = Colors.Red;
_lineprofileColor[2] = Colors.Black;
_lineprofileColor[3] = Colors.Blue;
//LineGraph lg = new LineGraph();
LineAndMarker<MarkerPointsGraph> lg = new LineAndMarker<MarkerPointsGraph>();
CirclePointMarker pm = new CirclePointMarker { Size = 10, Fill = Brushes.Green };
// MarkerPointsGraph mpg = new MarkerPointsGraph();
if (_nColorChannels > 0) // plotter init
{
_dataX = new List<int[]>();
_dataY = new List<int[]>();
int[] dataXOneCh = new int[1];
int[] dataYOneCh = new int[1];
dataXOneCh[0] = 0;
dataYOneCh[0] = 0;
/*CirclePointMarker marker = new CirclePointMarker();
marker.Fill = new SolidColorBrush(_lineprofileColor[0]);
marker.Pen = new Pen(marker.Fill, 0);
marker.Size = 2;
int lineWidth = 1;*/
for (int i = 0; i < 4; i++)
{
_dataX.Add(dataXOneCh); // data x-y mapping init
_dataY.Add(dataYOneCh);
EnumerableDataSource<int> xOneCh = new EnumerableDataSource<int>(dataXOneCh);
EnumerableDataSource<int> yOneCh = new EnumerableDataSource<int>(dataYOneCh);
xOneCh.SetXMapping(xVal => xVal);
yOneCh.SetXMapping(yVal => yVal);
CompositeDataSource dsOneCh = new CompositeDataSource(xOneCh, yOneCh);
// LineProfileColorSetup();
lg = plotter.AddLineGraph(dsOneCh,
(new Pen(Brushes.Green, 2)),
pm,
(new PenDescription("Data")));
// lg = plotter.AddLineGraph(dsOneCh,
// Colors.Transparent,
// 2,
// "Data");
// pm.FilteringEnabled = false;
}
plotter.FitToView();
}
else
{
return;
}
}
数据更新:
for (int i = 0; i < 1; i++)
{
if (_dataX[i].Length == _dataY[i].Length)
{
EnumerableDataSource<int> xOneCh = new EnumerableDataSource<int>(_dataX[i]);
xOneCh.SetXMapping(xVal => xVal);
EnumerableDataSource<int> yOneCh = new EnumerableDataSource<int>(_dataY[i]);
yOneCh.SetYMapping(yVal => yVal);
CompositeDataSource ds = new CompositeDataSource(xOneCh, yOneCh);
Action UpdateData = delegate()
{
// ((LineGraph)plotter.Children.ElementAt(startIndex + i)).DataSource = ds;
// ((LineGraph)plotter.Children.ElementAt(startIndex + i)).LinePen = new Pen(new SolidColorBrush(Colors.Green), 1);
// ((PointsGraphBase)plotter.Children.ElementAt(startIndex + i)).DataSource = ds;
((PointsGraphBase)plotter.Children.ElementAt(startIndex + i + 1)).DataSource = ds;
// }
// (plotter.Children.ElementAt(startIndex + i)).DataSource = ds;
};
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, UpdateData);
}
}
我遇到的问题是当信号非常胖时,比如每毫秒生成一个新信号,图表似乎每 1 秒生成一个新标记,我不明白。
基本思路是生成一个plotter.AddLineGraph,然后只更新DataSource。但它似乎不起作用。所以我想也许我走错了方向。
我不是 C# 或 WPF 专家。当 LineAndMarker 没有按预期工作时,我开始怀疑。所以我想知道人们使用 WPF 和 C# 显示实时信号(快速变化,样本之间的时间跨度可能是毫秒)的一般方式是什么。
【问题讨论】:
-
你说的是什么信号?你想如何产生信号?你有代码吗???
-
我想知道它是什么样的信号有关系吗?
-
@NickTsui:可能。如果您尝试每毫秒加点,那么将很难跟上。所以问题是,你需要所有的数据吗?你能画出每 nth 个点吗?您需要记录所有数据吗?所有数据都需要保存在内存中吗?
-
@NickTsui:另外,你需要绘制所有数据吗?还是只是一个滚动窗口? (例如最后 5 分钟)。
-
我假设我需要所有数据。如果用户想放大以查看 5 毫秒的窗口,我想我应该给用户这个选项。
标签: c# wpf plot dynamic-data-display real-time-data