Pre loader

Multiple Line Chart Performance

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

0
0

Hi,

I’m trying to evaluate the reality of creating multiple realtime charts and I’m hitting a huge performance brick wall.

My application will have high speed streamed data coming in over ethernet. Currently I’m simulating this with a thread timer that updates 100 data objects at 60Hz. Screen data and chart updates I’ve got throttled to 30Hz but it’s still grinding my charts are still struggling. If I move the mouse pointer the charts freeze entirely until the mouse is still.

I want the end user to be able to choose any data object and chart it however they want. Adding charts and adding plots to charts etc. To enable this I’ve created a chart template as a user control and at runtime the charts are added to a panel on a tab control. Event one chart on one tab chugs though. Move the mouse over it and it locks up.

I have a single overview chart with a scrollbar over the top on the parent control. I need this to control the cursor (vertical line) and shared X visible range. Live data is Fifo limited to a 10 second range. All this works, just painfully slowly.

SharedXVisible range is MVVM bound. Renderable series is LineRenderableSeriesViewModel and data is pushed at 30Hz from a Data provider as per this tutorial:
https://www.scichart.com/documentation/win/current/Tutorial%2006b%20-%20Adding%20Realtime%20Updates%20with%20MVVM.html

CPU usage is sub 20%. Max frame rate is 30fps. Render priority doesn’t seem to make much difference, though “immediate” will lock up the whole app. I’m no expert at performance profiling but I’m not getting any clues from ReShaper dotTrace so far.

I tried creating a version that hand almost no binding and used codebehind to update the data. It didn’t seem to help. I’d rather not do this though as I have a lot of things working that I like such as vertical slice, annotations, templates etc.

I’ve got a list of all the live data on the right of the screen and it all updates rapidly, even while the mouse is moving and the charts are frozen.

I’m also using some Syncfusion controls and theming, if it matters.

I must be missing something obvious surely.

<!--  Define Chart  -->
        <s:SciChartSurface x:Name="chart" Grid.Row="0" Grid.Column="0"
                           Background="Black"
                           RenderPriority="low"
                           MaxFrameRate="30"
                           RenderableSeries="{s:SeriesBinding RenderableSeriesCollection}"
                           >

            <!--  Define X and Y Axis  -->
            <s:SciChartSurface.YAxis>
                <s:NumericAxis AutoRange="{Binding AxisYRangeMode}" 
                               DrawMajorBands="False" 
                               DrawMinorGridLines="false" 
                               DrawMajorGridLines="True" 
                               DrawMajorTicks="False" 
                               DrawMinorTicks="False" 
                               VisibleRange="{Binding AxisYVisibleRange}" />
            </s:SciChartSurface.YAxis>

            <s:SciChartSurface.XAxis>
                <s:NumericAxis AutoRange="{Binding AxisXRangeMode}" 
                               BorderBrush="{StaticResource BorderBrushGray}" 
                               BorderThickness="1" 
                               DrawMajorBands="False" 
                               DrawMinorGridLines="False" 
                               DrawMajorGridLines="True" 
                               DrawMajorTicks="False" 
                               DrawMinorTicks="False" 
                               TextFormatting="0" 
                               VisibleRange="{Binding SharedXVisibleRange, Mode=TwoWay}" 
                               s:VerticalSliceModifier.AxisLabelContainerStyle="{x:Null}"/>
            </s:SciChartSurface.XAxis>

            <!--  Modifiers  -->
            <s:SciChartSurface.ChartModifier>
                <s:ModifierGroup>
                    <s:RubberBandXyZoomModifier 
                        IsXAxisOnly="True" 
                        ZoomExtentsY="True" 
                        IsAnimated="True" 
                        RubberBandFill="#20FFFFFF" 
                        RubberBandStroke="GreenYellow" 
                        RubberBandStrokeDashArray="2 2">
                    </s:RubberBandXyZoomModifier>

                    <s:ZoomExtentsModifier IsAnimated="True"/>

                    <s:MouseWheelZoomModifier IsEnabled="True"/>

                    <s:XAxisDragModifier IsEnabled="True" DragMode="Pan"/>

                    <s:LegendModifier x:Name="legendModifier"
                                      Background="Transparent" 
                                      Margin="10" 
                                      GetLegendDataFor="AllSeries" 
                                      LegendItemTemplate="{StaticResource CustomLegendTemplate}" 
                                      ShowLegend="True" ShowVisibilityCheckboxes="True"/>

                    <s:VerticalSliceModifier Name="sliceModifier">

                    <s:VerticalSliceModifier.VerticalLines>
                            <s:VerticalLineAnnotation Style="{StaticResource sliceStyle}" 
                                                      X1="{Binding SlicePosition, Mode=TwoWay}"/>
                        </s:VerticalSliceModifier.VerticalLines>
                    </s:VerticalSliceModifier>

                </s:ModifierGroup>
            </s:SciChartSurface.ChartModifier>
        </s:SciChartSurface>

Thanks in advance,
Declan.

PS. I’m trying to attach a screenshot but it keeps saying “Forbidden”.

Version
.NET Core 3.1 v6.4.0.13629
  • You must to post comments
0
0

Hi Declan

Best way to solve this is send over a solution to reproduce which our team can profile.

Some very common problems

  • When updating chart DataSeries in background threads, SciChart schedules drawing on UI thread but must use lock synchronisation between the two
  • Our drawing is scheduled at 1/60th of a second (and may be modified)
  • Cursor updates are also UI threaded
  • Sometimes too fast updates on the DataSeries can therefore trigger too many draws, and you get lock contention between the different threads

Hence: low CPU usage but poor performance.

We have a number of simple tweaks such as:

  • Adjusting SciChartSurface.RenderPriority. Believe it or not RenderPriority.Low means fewer draws, placing drawing priority just below WPF input, and gives the UI thread more space for cursors, and can reduce lock contention
  • Using SciChartSurface.SuspendUpdates() block around updates to the series or the chart to ensure one redraw at the end
  • Appending in batches not 1 point at a time. If you append data to DataSeries in a background thread 1 data-point at a time, it increases the synchronisation & lock contention. We recommend using small buffers

We have a long performance tips & tricks here with some of these enhancements and more
https://www.scichart.com/documentation/win/current/webframe.html#Performance_Tips_&_Tricks.html

Anyway send over a solution to repro. We can profile it and suggest a resolution. Performance tuning is a fine art but our team is very good at it!

Best regards
Andrew

  • Declan Walsh
    Hi Andrew, Thanks for the reply! I persisted with it last night and had a small amount of success though I feel it can be a lot better. I found that I had to remove any kind of change to render priority or max frame rate. if I applied either or both the charts would chug and freeze. They run reasonably well without either but there is a slight but quite noticeable cost to UI responsiveness. Is it possible to append in batches when using a data provider via MVVM as in the tutorial I referenced? In other areas of my application where charts are updated in code-behind I’m using the SuspendUpdates method. I’m not sure how to implement this from a subscriber though. I’ll see if I can put together a simple sample app for you to look at. I’d love to get your suggestions. I must say, I’m very impressed by scichart overall. Thanks!
  • Andrew Burnett-Thompson
    Hi Declan, It is possible to SuspendUpdates in MVVM (search it on our forums). Also possible to batch updates from a Viewmodel. I’d love to be able to profile this app to suggest what to do. Performance tuning sometimes requires an expert eye. Our team is very good at it and has managed to tune applications for all kinds of demanding applications!
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies