Silverlight UI 滞后 - 图表上的十字线
我有一个 Telerik radchart,它显示了一个漂亮且对最终用户非常有用的折线图。
该图表的要求之一是在图表上有一个 x 值十字准线(例如,当用户将鼠标悬停在图表上的任何点时,会出现一条水平线,并且在该线与实际图表线相交的位置,会显示一个值)在屏幕的另一个区域)。
在之前的迭代中,我使用 flotJS 来进行绘图和绘制。十字准线,效果很好,而且速度很快。在将其转换为 silverlight 的过程中,我看到了巨大的延迟,我想知道是否有人对提高性能有任何想法。
我当前公开图表的 MouseEnter/MouseLeave 事件以隐藏/显示水平线。这是通过我的视图模型中的 System.Windows.Visibility 属性(我的十字准线的可见性属性绑定到的)来完成的。然后,我使用 MouseMove 方法实际计算 x 位置。
这是运行此代码的代码(首先在我的图表视图的代码后面)
private void rad_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var plotAreaPanel = this.rad.DefaultView.ChartArea.ChildrenOfType<ClipPanel>().FirstOrDefault();
var position = e.GetPosition(plotAreaPanel);
var x = rad.DefaultView.ChartArea.AxisX.ConvertPhysicalUnitsToData(position.X);
(this.DataContext as ViewModels.DateCountsViewModel).XVolume = x;
}
private void rad_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
(this.DataContext as ViewModels.DateCountsViewModel).XVolumeVisibility = System.Windows.Visibility.Visible;
}
private void rad_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
(this.DataContext as ViewModels.DateCountsViewModel).XVolumeVisibility = System.Windows.Visibility.Collapsed;
}
然后在我的视图模型中,在 XVolume 的 setter 中(在上面的 MouseMove 方法中设置),此代码:
public double XVolume
{
get { return xVolume; }
set
{
this.xVolume = value;
decimal currentX = (decimal)Math.Round(value, 0);
var vol = this.VolumeCollection.Where(x => x.XValue == currentX).FirstOrDefault() as Models.ChartModel;
this.Volume = (vol == null) ? 0 : (int)vol.YValue;
RaisePropertyChanged("XVolume");
}
}
随着大量使用,该行滞后于比我的指针落后几英寸。我尝试限制鼠标事件 此处概述,但它仍然非常滞后。
[有关上面链接的注意事项:它使用 CompositionTarget.Rendering 事件,该事件在渲染帧之前触发。因此,为了限制鼠标事件的影响,我们设置一个标志来指示我们正在等待渲染更改,然后在渲染发生之前重置此标志...不允许同时渲染]
我可以做什么来缓解这个滞后?
I've got a telerik radchart that's displaying a beautiful and incredibly-useful-to-end-user line chart.
One of the requirements for this chart was to have a x-value crosshair on the graph (e.g. when a user hovers at any point over the graph, a horizontal line appears, and where this line intersects the actual graph line, a value is displayed in another area of the screen).
In a previous iteration, I used flotJS to do my graphing & crosshair'ing, worked great, and was blazing fast. In converting this to silverlight, I've seen a tremendous amount of lag, and I'd like to know if anyone has any ideas on improving performance.
I currently expose the chart's MouseEnter/MouseLeave events to hide/show the horizontal line. This is done via a System.Windows.Visibility property sitting in my viewmodel (which my crosshair's visibility property is bound to). I then use the MouseMove method to actually calculate the x position.
Here is the code that runs this (first in my chart view's code behind)
private void rad_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var plotAreaPanel = this.rad.DefaultView.ChartArea.ChildrenOfType<ClipPanel>().FirstOrDefault();
var position = e.GetPosition(plotAreaPanel);
var x = rad.DefaultView.ChartArea.AxisX.ConvertPhysicalUnitsToData(position.X);
(this.DataContext as ViewModels.DateCountsViewModel).XVolume = x;
}
private void rad_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
(this.DataContext as ViewModels.DateCountsViewModel).XVolumeVisibility = System.Windows.Visibility.Visible;
}
private void rad_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
(this.DataContext as ViewModels.DateCountsViewModel).XVolumeVisibility = System.Windows.Visibility.Collapsed;
}
Then in my viewmodel, in the setter for XVolume (which is being Set in the MouseMove method above), this code:
public double XVolume
{
get { return xVolume; }
set
{
this.xVolume = value;
decimal currentX = (decimal)Math.Round(value, 0);
var vol = this.VolumeCollection.Where(x => x.XValue == currentX).FirstOrDefault() as Models.ChartModel;
this.Volume = (vol == null) ? 0 : (int)vol.YValue;
RaisePropertyChanged("XVolume");
}
}
With heavy usage, the line lags up to several inches behind my pointer. I tried throttling my mouse events outlined here, but it's still really laggy.
[Note regarding link above: It uses the CompositionTarget.Rendering event, which is fired just before a frame is rendered. Therefore, to throttle the effect of the mouse event, we set a flag to indicate that we are waiting for a change to be rendered, then reset this flag just before rendering occurs... not allowing simultaneous rendering]
What can I do to mitigate this lag?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论