X轴动态数据显示平滑滚动
Posted
技术标签:
【中文标题】X轴动态数据显示平滑滚动【英文标题】:Dynamic data display smooth scrolling of X axis 【发布时间】:2014-11-06 11:27:59 【问题描述】:我正在尝试使用动态数据显示绘制 DateTime
与 Integer
值创建实时图表。我需要的是具有固定轴值的 X 轴平滑滚动。就像平移,即当你从中心拖动绘图时,它会随着鼠标光标流畅地流动。我想自动有类似的行为。
目前在定时器中更改数据源时,轴范围动态变化,滚动不流畅。是否有可能改变这种行为。有什么想法,请帮忙。
我尝试在 400 毫秒计时器中动态更新日期和整数数据源,这会产生一个实时图表,其中轴范围会根据数据源发生变化。
这里是测试代码:
在窗口加载时
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);
【问题讨论】:
【参考方案1】:我相信你在追求这样的事情:
// 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.Y
和newDataRect.Height
添加限制,如果您希望将它们限制在-20 520(或然而),但我将由您决定- 基本思路如上。
希望这会有所帮助!如果以上任何内容没有意义,请告诉我:)。
平滑滚动的(不一定很棒)方法:
添加另一个计时器,例如在初始化时:
animationTimer = new DispatcherTimer Interval = TimeSpan.FromMilliseconds(20) ;
animationTimer.Tick += animationTimer_Tick;
animationTimer.Start();
我使用DispatcherTimer
而不是Timer
,因为ViewPort
的移动需要在UI 线程上完成。然后只需:
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>
,但是通过 google 搜索实现应该相对简单。
祝你好运!
【讨论】:
+1..很好的答案..它工作正常...顺便说一句,我无法解决动画期间轴的奇怪行为。就我而言,我不需要在轴下方显示日期的矩形框,这会导致滚动闪烁......你知道如何隐藏它吗? 尝试添加行:dateAxis.ShowMayorLabels = false;
,或者更好的是,将属性 ShowMayorLabels = "false"
添加到 XAML 中的日期时间轴以上是关于X轴动态数据显示平滑滚动的主要内容,如果未能解决你的问题,请参考以下文章
拓端tecdat|R语言编程指导时间序列数据指数平滑法分析交互式动态可视化
winform Chart控件动态曲线图数据多了会卡,怎么解决
如何使用pyqtgraph TimeAxisItem使X轴时间动态刷新
想x轴超出隐藏,y轴超出内容显示.overflow-x:hidden; overflow-y:visible;这样写,y轴会出滚动条怎么办呢