2013-02-15 84 views
-2

我试图用WPF和C#(动态数据显示器)绘制实时信号,信号与时间的关系图;一旦产生一个信号,它应该立即显示在情节图上;信号可以非常快地产生(大约为毫秒(0.001秒)); 什么是最好的办法呢?任何建议表示赞赏。谢谢。如何在WPF和C#.net 3.5中绘制实时信号?

编辑:示例代码将高度赞赏。

这是我曾尝试:

地块起始:

#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); 
        } 
       } 

我的问题是,当信号到来非常脂肪,说新信号每mili-second产生一次,似乎该图只会每隔1秒产生一个新的标记,这我不明白。

基本思路是生成一个plotter.AddLineGraph,然后只更新DataSource。但它似乎不工作。所以我想也许我在错误的方向。

我不是C#或WPF专家。当LineAndMarker没有按预期工作时,我开始怀疑。所以我想知道人们使用WPF和C#显示实时信号(快速变化,样本之间的时间间隔可能在毫秒级)的一般方法是什么。

+0

你在说什么样的信号?你想如何产生信号?你有任何代码? – 2013-02-15 14:58:19

+0

我想知道它是什么样的信号是否重要? – 2013-02-15 15:19:04

+0

@NickTsui:可能。如果你试图每ms添加点数,那么跟上很难。所以问题是,你需要所有的数据吗?你可以绘制每个* n *点吗?你需要记录所有的数据吗?所有的数据都需要保存在内存中吗? – 2013-02-15 15:42:57

回答

0

我发现我做错了。以下是发生问题的部分:

_pxlValAllChan[0, signalIndex] = pxlValue; 
               DateTime currentTime = DateTime.Now; //has to come from real file: Tiff 
               TimeSpan timeSpan = currentTime - _startTime; 

               _timeStampAllChan[0, signalIndex] = Convert.ToInt16(timeSpan.TotalSeconds); 


               _pxlValOneChan = new int[_signalLength]; // no need to new it every time 
               _timeStampOneChan = new int[_signalLength]; 
               for (int i = 0; i <= signalIndex; i++) 
               { 
                _pxlValOneChan[i] = _pxlValAllChan[0, i]; 
                //_timeStampOneChan[i] = _timeStampAllChan[0, i]; 
                _timeStampOneChan[i] = i; 
               } 

               _signalDisplay.SetData(_timeStampOneChan, _pxlValOneChan, 0, true); 

我的x数据基于时间。我基本上是以程序开始为起点,然后通过用当前时间减去开始时间来跟踪时间流逝。然后,时间流逝被保存为x轴数据(参见注释掉的行)。这实际上会导致问题。当我简单地将x轴数据更改为索引时,问题就消失了。图形更新非常快。虽然我还没有弄清楚如何改变逻辑以将时间流逝作为我的X轴数据,但这是图表上缓慢更新的罪魁祸首。