Pre loader

How to preserve the performance of the graph when it is inspected by the cursor?

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

Answered
1
0

I tried to create an WPF application that used a graph with LineRenderableSeriesViewModel and XYDataSeries to display real-time data. Cursor inspection was added to the chart as shown in the picture to make it easier to view the data. After some time I found out that when inspecting the cursor, if you move it quickly inside the chart, the CPU load increases several times.

Is there any elegant way to preserve performance with such manipulations?

My computer has a pretty good build but on weaker computers it causes some problems.

  • Processor: AMD Ryzen 7 5825U with Radeon Graphics 2.00 GHz
  • RAM: 16.0 GB (14.8 GB usable)
  • System: Windows 11 Pro (21H2)
Version
7.0.1.27055, net 6.0 windows
Images
  • Andrew Burnett-Thompson
    Good morning Kostiantyn, other than slightly higher cpu usage, are there any other negative effects when scrubbing the cursor on your application? CPU can be 100% but as long as the application(s) perform well it’s not a problem.
  • Kostiantyn Britikov
    Yes, it only affects CPU load, the program runs as smoothly as before the actions. Problems may start only if it is run by a slow computer, then with increased CPU load and old graphics core the program starts to run slower. Is there any way to optimize this for slow devices?
  • Andrew Burnett-Thompson
    OK got it. Optimising the hit-test is possible (there are still some optimisations we haven’t done here), but a more effective method may just be throttling the mouse-events (having fewer inspections per second of the cursor/tooltip). Let me circle back to the team and ask – Andrew
  • You must to post comments
Great Answer
0
0

Hi Kostiantyn,

Thanks for your question. I belive you are referring to RolloverModifier since it is shown on the screenshots – please correct me if Im wrong.

Using RolloverModifier may cause performance issues because it perfroms multiple hit-test operations (for every RenderableSeries) on every Mouse Move event.

As Andrew mentioned in the comments, the most obvious solution would be adding mouse events throttling for RolloverModifier. It should be not hard to implement. You could try doing that on your side by deriving a class from RolloverModifier and overridding OnModifierMouseMove(…) method in it. Then, debounce all method calls (or hit-test operations) until there is a pause long enough.

This can be implemented using Reactive Extensions or simply a timer. The implementation below should demostrate the idea:

 public class RolloverModifierEx : RolloverModifier
{
    private ModifierMouseArgs _last = null;
    private bool _isUpdating = false;
    private System.Timers.Timer _timer = new()
    {
        Interval = 100,
        AutoReset = false
    };

    public RolloverModifierEx()
    {
        _timer.Elapsed += OnTimerElapsed;
    }

    private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        _isUpdating = false;
        Dispatcher.InvokeAsync(() => base.OnModifierMouseMove(_last), DispatcherPriority.Send);
    }

    public override void OnModifierMouseMove(ModifierMouseArgs e)
    {
        _last = e;

        // Restart updating timer 
        _timer.Stop();
        _timer.Start();
        _isUpdating = true;

        base.OnModifierMouseMove(e);

        // Alternatively, hide Rollover by passing in an invalid location
        //base.OnModifierMouseMove(new ModifierMouseArgs(new Point(double.NaN, double.NaN), e.MouseButtons, e.Modifier, e.IsMaster, e.Source));
    }

    protected override IEnumerable<SeriesInfo> GetSeriesInfoAt(Point point)
    {
        // Prevent hit-test while mouse is moving
        return _isUpdating ? Enumerable.Empty<SeriesInfo>() : base.GetSeriesInfoAt(point);
    }
}

Please try this solution and let me know if it works as expected.

Best Regards,
Joeri

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.