Silverlight UI 滞后 - 图表上的十字线

发布于 2024-12-11 16:39:14 字数 2128 浏览 0 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文