none
版主进来请教个图标问题DynamicDataDisplay-0.3这个开源控件 RRS feed

  • 问题

  • 例子代码PerfCounterSample里面,这个例子显示内存变化时如果右键Fit to view,则会动态显示内存变化,但有个大问题,动态显示之前的内容会随着时间消除掉,只是显示看得到的那一段时间中的数据,我急需的功能是显示内容不会随时间消除而只是增加内容,就是左边的不会没有,这样子怎么改?看了半天控件代码还是不清楚,请教版主,baobo应该对这个控件比较熟悉吧,帮我看看来,多谢!
    2011年11月22日 9:30

答案

  • 哈哈,不好意思,这个Dynamic Data Display项目很大,我也不是很熟。不过解决你的这个问题应该没问题,等我来看一下。

    --------------------------------------------

    OK,我看了下 0.3 版本里面的一个 Simulation 那个例子,应该就是你想要的。

    我看了下Simulation的代码,它主要是直接从一个数据源文件中读取数据,然后将所有的数据都存放入 source 这个 ObservableDataSource<Point> 集合中,然后用图表显示这个集合而已。所以图表永远会显示所有的数据点,包括之前的点。

    而 PerfCounterSample 中,通过一个PerformanceData这个集合来采集性能数据,但是我们可以看到她的源代码,他继承自 RingArray<PerformanceInfo>, 而且从RingArray<T>这个基类可以看出,他有一个范围阀值:capacity

    	public class RingArray<T> : INotifyCollectionChanged, IList<T>
    	{
    		public RingArray(int capacity)
    		{
    			this.capacity = capacity;
    			array = new T[capacity];
    		}
    

    他在构造PerformanceData对象的时候,传入了200这个阀值,所以我们得到的始终是一个范围内的集合。

    解决方法:

    1. 修改PerformanceData构造函数:

    public PerformanceData(PerformanceCounter counter)
        : base(99999)
      {
      ......
    

    2.重载一个新的构造函数

        public PerformanceData(string categoryName, string counterName, int capacity)
          : base(capacity)
        {
    
          this.counter = new PerformanceCounter(categoryName, counterName);
          timer.Tick += OnTimerTick;
          timer.Start();
        }
    

    然后这样调用创建PerformanceData对象: 

      private LineGraph CreatePerformanceGraph(string categoryName, string counterName)
      {
        PerformanceData data = new PerformanceData(categoryName, counterName, 99999);
    
        var filteredData = new FilteringDataSource<PerformanceInfo>(data, new MaxSizeFilter());
    
        var ds = new EnumerableDataSource<PerformanceInfo>(data);
        ds.SetXMapping(pi => pi.Time.TimeOfDay.TotalSeconds);
        ds.SetYMapping(pi => pi.Value);
    
        LineGraph chart = plotter.AddLineGraph(ds, 2.0, String.Format("{0} - {1}", categoryName, counterName));
        return chart;
      }
    


    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2011年11月23日 5:21
    版主
  • "左边的内容不会因为超出屏幕范围而消除,拖动后可以去看到" 难道你在ChartPlotter上用鼠标拖看不见左边超出屏幕的?  我这边测试,只要我们的数据集合容量足够大,鼠标往左托,能显示那些超出的.但是这样不是Fit to View。

    实际上,我理解你的意思是,在ChartPlotter默认模式下,数据的增加,整个图形能够随着增加的数据往右滚动,但X不要压缩。是吧?

     

    实现方法:

    找到 src\DynamicDataDisplay\Common\Auxiliary\CoordinateUtils.cs,修改 RectZoom方法 Line 27 和 Line 29:

    		public static Rect RectZoom(Rect rect, Point zoomCenter, double horizontalRatio, double verticalRatio)
    		{
    			Rect res = new Rect();
                            res.X = zoomCenter.X;
    			res.Y = zoomCenter.Y - (zoomCenter.Y - rect.Y) * verticalRatio;
    			res.Width = rect.Width;
    			res.Height = rect.Height * verticalRatio;
    			return res;
    		}
    

     

    不过这样X轴还是会压缩,我明天给你再看一下。



    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    • 已标记为答案 a013strife 2011年11月23日 14:34
    • 取消答案标记 a013strife 2011年11月23日 15:12
    • 已标记为答案 a013strife 2011年11月24日 8:25
    2011年11月23日 12:01
    版主
  •  多谢版主,我自己找出方法了,你怎么不问问题,你要问问题我来帮你回答哈,这样才公平么,以后有问题通知我下。

    看了下貌似加个Restriction就可以解决我的问题了,这样:

      ProportionsRestriction maxSizeRestriction = new ProportionsRestriction();
                maxSizeRestriction.IsActive = true;
                plotter.Viewport.Restrictions.Add(maxSizeRestriction);

    在simulation中试验成功,明天去改下单位的项目代码.


    2011年11月23日 14:33

全部回复

  • 哈哈,不好意思,这个Dynamic Data Display项目很大,我也不是很熟。不过解决你的这个问题应该没问题,等我来看一下。

    --------------------------------------------

    OK,我看了下 0.3 版本里面的一个 Simulation 那个例子,应该就是你想要的。

    我看了下Simulation的代码,它主要是直接从一个数据源文件中读取数据,然后将所有的数据都存放入 source 这个 ObservableDataSource<Point> 集合中,然后用图表显示这个集合而已。所以图表永远会显示所有的数据点,包括之前的点。

    而 PerfCounterSample 中,通过一个PerformanceData这个集合来采集性能数据,但是我们可以看到她的源代码,他继承自 RingArray<PerformanceInfo>, 而且从RingArray<T>这个基类可以看出,他有一个范围阀值:capacity

    	public class RingArray<T> : INotifyCollectionChanged, IList<T>
    	{
    		public RingArray(int capacity)
    		{
    			this.capacity = capacity;
    			array = new T[capacity];
    		}
    

    他在构造PerformanceData对象的时候,传入了200这个阀值,所以我们得到的始终是一个范围内的集合。

    解决方法:

    1. 修改PerformanceData构造函数:

    public PerformanceData(PerformanceCounter counter)
        : base(99999)
      {
      ......
    

    2.重载一个新的构造函数

        public PerformanceData(string categoryName, string counterName, int capacity)
          : base(capacity)
        {
    
          this.counter = new PerformanceCounter(categoryName, counterName);
          timer.Tick += OnTimerTick;
          timer.Start();
        }
    

    然后这样调用创建PerformanceData对象: 

      private LineGraph CreatePerformanceGraph(string categoryName, string counterName)
      {
        PerformanceData data = new PerformanceData(categoryName, counterName, 99999);
    
        var filteredData = new FilteringDataSource<PerformanceInfo>(data, new MaxSizeFilter());
    
        var ds = new EnumerableDataSource<PerformanceInfo>(data);
        ds.SetXMapping(pi => pi.Time.TimeOfDay.TotalSeconds);
        ds.SetYMapping(pi => pi.Value);
    
        LineGraph chart = plotter.AddLineGraph(ds, 2.0, String.Format("{0} - {1}", categoryName, counterName));
        return chart;
      }
    


    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2011年11月23日 5:21
    版主
  • 确实这样,版主看得很仔细,我开始也没说明白,Simulation这个例子显示的数据样子确实是我需要的,但是这个例子中它会把所有数据显示在一个屏幕上,x坐标会被不断挤压,我单位项目中需要的效果是Simulation和performance这两个例子的集合:需要有全部数据显示出来,移动的时候x坐标不会被挤压,可以向左拖动看到以前留下的记录,

    版主提供的方法我也用过了,显示的时候始终会把屏幕之外的数据取消掉,我把容量变成了10000000都没用.

    这个真麻烦,再说具体点我想要的效果就是Simulation里面手动拖动屏幕和绘画的线一起移动那样的状态,手动拖动屏幕时他的x坐标是不会被压缩的.不知道怎么实现这个功能,再继续看看.

    2011年11月23日 5:39
  • ChartPlotter 默认就支持手动拖拽的,而且可以用鼠标滚轮缩放,在移动拖动的时候,X是不会被压缩的,可以显示之前的数据。

    不过对于这个容量问题,因为是int32类型,而且RingArray会直接开辟一个你指定容量大小的数据,所以不能支持很大,我选择了 99999 已经可以满足你几个小时的检测用量了,过大的话会有异常抛出。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    2011年11月23日 6:57
    版主
  • 9999  我也试过貌似fit to view的时候不会因为容量而停止清楚左边屏幕看不到的地方,

    项目要求的功能是左边的内容不会因为超出屏幕范围而消除,拖动后可以去看到,目前不知道这个功能如何实现呀,

    2011年11月23日 7:50
  • "左边的内容不会因为超出屏幕范围而消除,拖动后可以去看到" 难道你在ChartPlotter上用鼠标拖看不见左边超出屏幕的?  我这边测试,只要我们的数据集合容量足够大,鼠标往左托,能显示那些超出的.但是这样不是Fit to View。

    实际上,我理解你的意思是,在ChartPlotter默认模式下,数据的增加,整个图形能够随着增加的数据往右滚动,但X不要压缩。是吧?

     

    实现方法:

    找到 src\DynamicDataDisplay\Common\Auxiliary\CoordinateUtils.cs,修改 RectZoom方法 Line 27 和 Line 29:

    		public static Rect RectZoom(Rect rect, Point zoomCenter, double horizontalRatio, double verticalRatio)
    		{
    			Rect res = new Rect();
                            res.X = zoomCenter.X;
    			res.Y = zoomCenter.Y - (zoomCenter.Y - rect.Y) * verticalRatio;
    			res.Width = rect.Width;
    			res.Height = rect.Height * verticalRatio;
    			return res;
    		}
    

     

    不过这样X轴还是会压缩,我明天给你再看一下。



    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    • 已标记为答案 a013strife 2011年11月23日 14:34
    • 取消答案标记 a013strife 2011年11月23日 15:12
    • 已标记为答案 a013strife 2011年11月24日 8:25
    2011年11月23日 12:01
    版主
  •  多谢版主,我自己找出方法了,你怎么不问问题,你要问问题我来帮你回答哈,这样才公平么,以后有问题通知我下。

    看了下貌似加个Restriction就可以解决我的问题了,这样:

      ProportionsRestriction maxSizeRestriction = new ProportionsRestriction();
                maxSizeRestriction.IsActive = true;
                plotter.Viewport.Restrictions.Add(maxSizeRestriction);

    在simulation中试验成功,明天去改下单位的项目代码.


    2011年11月23日 14:33
  • 不过这样还有个问题,图标显示的不是最新的数据而是中间一段数据真麻烦.
    2011年11月23日 15:13
  • 我还没来得及看呢, 今天可能时间不够了。 我看情况,争取晚上给你看下。
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    2011年11月24日 9:17
    版主
  • 多谢,这个帖子结了给分,我新开一个帖子,主要要解决的问题就是实现平滑移动,显示时显示最新数据,x,y轴坐标正常,并且之前x轴的数据不会消失。

    2011年11月24日 9:44
  • 请教下是如何做到的,显示时显示最新数据,x,y轴坐标正常,并且之前x轴的数据不会消失
    2014年10月23日 10:56