syncfusion/flutter-examples

Can this plot more than 3,000 new data points per seconds in realtime?

Doopin opened this issue · 3 comments

Doopin commented

Hi all,
I have heard a lot about this package and I would like to get some insights from you before I can choose it for my new upcoming project.
Can this plot more than 3,000 new data points per seconds?
I need that performance for my project and I would like to input up to that 3,000 data point per second. These are data that come from a real time system and we need to visualize that in real time.
At the same time we will need to keep up to 124,000 data point on the chart before we start clearing older data. Which means we should be able to process more than 100,000 data point in realtime.

So, I would like to know if it can achieve this performance? If not by default, do we have solution to boost performance? for example like tweaking GPU acceleration?

Thank you in advance for you reply.

Doopin commented

I did lot of tests since then...
I've noticed that this package gets slower and slower redraw speed when I add 100, 1000, 10000 data points. Is this library GPU accelerated? If so, how is this handled in a cross-platform sense? Does anyone have any benchmarks for this library on an iPhone 16 vs Windows Desktop with and RTX 4060 for example?

Hi @Doopin,

We have prepared a sample to plot a FastLine Series with a real-time update of 3000 data points per second using the updateDataSource method. Here, we add 3000 random data points per second and pass the indexes to be updated to the addedDataIndexes property in the updateDataSource method. We clear the data when it exceeds more than 124,000 based on your mentioned requirement as shown in the code snippet below.

class _MainAppState extends State<MainApp> {
  late List<ChartSampleData> _chartData;
  late ChartSeriesController _seriesController;
  late Random _random;
  int _targetValue = 3000;
  int _index = 0;
  Timer? timer;

  @override
  void initState() {
    super.initState();
    _random = Random();
    _chartData = <ChartSampleData>[
      ChartSampleData(
        x: 0,
        y: 0,
      ),
    ];
    Timer.periodic(const Duration(seconds: 1), _updateDataSource);
  }

  void _updateDataSource(Timer timer) {
    if (_chartData.length > 124000) {
      _chartData.clear();
      _targetValue = 3000;
      _index = 0;
    }
    while (_index < _targetValue) {
      _chartData.add(
        ChartSampleData(
          x: _index,
          y: _random.nextInt(1000),
        ),
      );
      _index++;
    }
    _seriesController.updateDataSource(
      addedDataIndexes: _getIndexes(3000),
    );
    _targetValue += 3000;
  }

  List<int> _getIndexes(int length) {
    final int startIndex = _chartData.length - length;
    final List<int> indexes = List.generate(length, (index) => startIndex + index);
    return indexes;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SfCartesianChart(
          primaryXAxis: NumericAxis(),
          primaryYAxis: NumericAxis(),
          series: <CartesianSeries<ChartSampleData, num>>[
            FastLineSeries<ChartSampleData, num>(
              dataSource: _chartData,
              xValueMapper: (ChartSampleData data, _) => data.x,
              yValueMapper: (ChartSampleData data, _) => data.y,
              onRendererCreated: (ChartSeriesController controller) {
                _seriesController = controller;
              },
              color: Colors.accents[_random.nextInt(14)],
            ),
          ],
        ),
      ),
    );
  }
}

However, we have shared some key points below that can be used to boost the performance of the chart when there is a need to plot high-volume data:

  1. Load and store the required data points in the initState method itself, and then set the data points to the chart series.
  2. Use NumericAxis or DateTimeAxis instead of CategoryAxis and DateTimeCategoryAxis.
  3. When there is a large number of points to load in a line series, you can use the FastLine series instead of LineSeries.
  4. Instead of enabling data markers and labels when there is a large number of data points, you can use Trackball to view the point information.
  5. Set the series animationDuration as 0 to disable the animation while loading a large number of data points.
  6. Use the updateDataSource method while updating dynamic data points instead of calling setState. For more details, refer to the user guide at https://help.syncfusion.com/flutter/cartesian-charts/methods#updatedatasource.

Also attached the recording and sample below for your reference and you can modify the sample according to your needs. If you have further queries, please get back to us.

Regards,
Hari Hara Sudhan. K.
491065.zip
_491065.zip

Doopin commented

Thank you for your help!