Pre loader

Performance with lots of XYZ CustomRenderableSeries

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

1
0

Hello,

I have issues when I want to apply a custom CustomPolygonRenderableSeries.

For implementation it was used sci-chart documentation from

enter link description here
enter link description here

It takes a while to show just 10000 polygons from 40000 points! When I tried to slide or zoom main window it got some freezes for 1-1.5 seconds. The main problem is in redrawing several times(protected override void Draw). There is an example of used code:

public class CustomPolygonRenderableSeries : CustomRenderableSeries
{
    protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData)
    {
        var dataPointSeries = renderPassData.PointSeries as XyzPointSeries;

        if (dataPointSeries == null) return;
        if (dataPointSeries.XValues.All(double.IsNaN)) return;

        var xCalc = renderPassData.XCoordinateCalculator;
        var yCalc = renderPassData.YCoordinateCalculator;

        // try to filter some polygons by visible range
        var xVisibleRange = XAxis.VisibleRange;
        var yVisibleRange = YAxis.VisibleRange;

        var points = new Point[4];
        var step = 4;
        for (var index = 0; index < dataPointSeries.Count; index += step)
        {
            if (!xVisibleRange.IsValueWithinRange(dataPointSeries.XValues[index + 3]) ||
                !yVisibleRange.IsValueWithinRange(dataPointSeries.YValues[index + 3])) continue;

            for (int i = 0; i < step; ++i)
            {
                points[i].X = xCalc.GetCoordinate(dataPointSeries.XValues[index + i]);
                points[i].Y = yCalc.GetCoordinate(dataPointSeries.YValues[index + i]);
            }

            var intColor = (int)dataPointSeries.ZPoints[index];
            var color = System.Drawing.Color.FromArgb(intColor).ToMediaColor();

            var brush = new SolidColorBrush(color);
            using var sBrush = renderContext.CreateBrush(brush, Opacity);
            renderContext.FillPolygon(sBrush, points);
        }
    }
}

public class CustomPolygonRenderableSeriesViewModel : BaseRenderableSeriesViewModel
{
    public override Type ViewType => typeof(CustomPolygonRenderableSeries);
}

Is this a known performance issue? Is there some way to by-pass it?

Thank you.

Sincerely, Roman

Version
8.3.0
  • Lex
    Hi Raman, Thanks for your inquiry. I’ll discuss your question with our team and will get back to you with an update. Kind regards, Lex S., MSEE, SciChart Technical Support Engineer
  • Andrew Burnett-Thompson
    Hi Raman, I’m assuming you’ve profiled this and found the bottleneck (which lines of code) as this is custom code. One thing I will say to you is ‘renderContext.CreateBrush(brush, Opacity)’ is known to be slow, and also you are not disposing the brush. I would strongly suggest caching brushes (e.g. if you create two with the same color, then re-use the brush). These should be disposed using renderContext.DisposeResourceAfterDraw() once you have finished with them
  • Raman Sharkovich
    Thank you, will try to do this but I guess using var sBrush = renderContext.CreateBrush(brush, Opacity); should dispose it.
  • Raman Sharkovich
    I tried caching IBrush2D into a dictionary, but the problem remained the same. This probably helps by 5-10%, but no more. If I create f.e. 20000 polygons from 80000 points delays are long(1 -1.5s). is it possible some how to get access CustomPolygonRenderableSeries from CustomPolygonRenderableSeries to manually control the Draw updates. Something like protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData) { if (skipDrawing) return; ….. Thanks!
  • You must to post comments
0
0

I tried caching IBrush2D into a dictionary, but the problem remained the same. This probably helps by 5-10%, but no more. If I create f.e. 20000 polygons from 80000 points delays are long(1 -1.5s).

is it possible some how to get access CustomPolygonRenderableSeries from CustomPolygonRenderableSeries to manually control the Draw updates. like

protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData)
{
if (skipDrawing) return;
…..

Thanks!

  • You must to post comments
0
0

Hello Raman,

We discussed your inquiry and would like to provide you with a few recommendations.

  1. Draw all 10000 polygons as a single Renderable Series. Creating each one as a separate Series leads to a huge impact on performance. Additionally, you can get coordinates in one batch calling the GetCoordinates(T[],Double[],Double)) method. Please take a look:
    https://www.scichart.com/documentation/win/current/webframe.html#SciChart.Data~SciChart.Charting.Numerics.CoordinateCalculators.ICoordinateCalculator%601~GetCoordinates.html

  2. Do not allocate a new array on each redraw. You can cache the array instead or use the ArrayPool class. You can find more details in the following Microsoft Learn article:
    https://learn.microsoft.com/en-us/dotnet/api/system.buffers.arraypool-1?view=net-8.0

  3. As Andrew has mentioned, resource creation like Brush or Pen is an expensive
    operation. So you should cache such resources and recreate them only when necessary. E.g. having a collection of such resources:

    var brush = new SolidColorBrush(color);
    using var sBrush = renderContext.CreateBrush(brush, Opacity);

Hope this helps.

With best regards,
Lex S., MSEE
SciChart Technical Support Engineer

  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.