2

DateTime我正在尝试使用动态数据显示绘图与Integer值创建实时图表。我需要的是具有固定轴值的 X 轴平滑滚动。就像平移一样,即当您从中心拖动绘图时,它会随着鼠标光标流畅地流动。我想自动有类似的行为。

目前在定时器中更改数据源时,轴范围动态变化,滚动不流畅。是否有可能改变这种行为。有什么想法,请帮忙。

我试图在 400 ms 计时器中动态更新日期和整数数据源,这会产生一个实时图表,其中轴范围会根据数据源发生变化。

这是测试代码:

在窗口加载

 timer = new Timer(400);
 ds = new ObservableDataSource<VoltagePoint>();
 ds.SetXMapping(x => dateAxis.ConvertToDouble(x.Date));
 ds.SetYMapping(y => y.Voltage);
 plotter.AddLineGraph(ds, 2, "Sample");
 timer.Start();

开启定时器滴答声

 Random rnd = new Random();
 TestPoint pt = new TestPoint (rnd.Next(1, 500), DateTime.Now);
 ds.AppendAsync(plotter.Viewport.Dispatcher, pt);
4

1 回答 1

2

我相信你在追求这样的事情:

// Your code (unchanged)
timer = new Timer(400);
ds = new ObservableDataSource<VoltagePoint>();
ds.SetXMapping(x => dateAxis.ConvertToDouble(x.Date));
ds.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds, 2, "Sample");
timer.Start();

// Make the Viewport not move when items are added.
plotter.Viewport.AutoFitToView = false;

// Put in your initial viewing dimensions
var xMin = dateAxis.ConvertToDouble(DateTime.Now);
var startXMax = dateAxis.ConvertToDouble(DateTime.Now.AddMinutes(1));
var startYMin = -20;
var startYMax = 520;

// Set the initial visible area.
plotter.Visible = new Rect { X = xMin, Width = startXMax - xMin, Y = startYMin, Height = startYMax - startYMin };

// If you wish, you can also restrict where the user can scroll:
plotter.Viewport.Restrictions.Add(new CustomAxisRestriction(xMin));

如果限制是控制用户所见内容的另一种方式,下面是一个非常基本的示例:

    public class CustomAxisRestriction : ViewportRestrictionBase
    {
        private double xMin;
        public CustomAxisRestriction(double xMin)
        {
            this.xMin = xMin;
        }
        public override Rect Apply(Rect oldDataRect, Rect newDataRect, Viewport2D viewport)
        {
            newDataRect.X = Math.Max(newDataRect.X, xMin);
            return newDataRect;
        }
    }

Apply基本上,您在限制中所需要的只是使用上述签名覆盖该方法。

在您的情况下,您可能还想在newDataRect.Yand上添加限制newDataRect.Height,如果您希望将它们限制在 -20 <-> 520 (或但是),但我将由您决定 - 基本思想如上所述。

希望这可以帮助!让我知道上述任何一项是否没有意义:)。

平滑滚动的(不一定很棒)方法:

添加另一个计时器,例如,在初始化时:

        animationTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(20) };
        animationTimer.Tick += animationTimer_Tick;
        animationTimer.Start();

我使用 aDispatcherTimer而不是 aTimer因为ViewPort需要在 UI Thread 上完成移动。然后只需:

    private void animationTimer_Tick(object sender, EventArgs e)
    {
        var oldRect = plotter.Visible;
        oldRect.X = Math.Max(oldRect.X, dateAxis.ConvertToDouble(DateTime.Now.AddMinutes(-0.1)));
        plotter.Visible = oldRect;
    }

当然,您需要从用户体验的角度仔细考虑用户应该如何/是否应该能够中断此滚动并重新启用它。但我会把它留给你..!

但是我上面给出的所有代码都应该可以工作(或者至少在本地工作!)如果你有任何问题,请告诉我。

我确实在动画期间轴的行为异常有一些问题,我认为这基本上是轴的一个错误TicksProvider,所以如果有必要,你可能需要实现你自己的:dateAxis.TicksProvider = new CustomTicksProvider();CustomTicksProvider继承自TimeTicksProviderBase<DateTime>,但这应该是相对的用谷歌搜索直接实现。

祝你好运!

于 2014-09-12T13:27:24.710 回答