Flutter Syncfusion Chart with Realtime Firebase

The Syncfusion charts are perfect for an app I'm writing. But i can't retrive data from firebase to show them in the syncfusion charts. I want the data is stream every minute in yValue. And the xValue defined the time (minute).

Thanks for any help!!!

import 'dart:async';
import 'dart:math';

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

class Chart extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(debugShowCheckedModeBanner: false, home: LiveChart());
  }
}

class LiveChart extends StatefulWidget {
  @override
  _LiveChartState createState() => _LiveChartState();
}

class _LiveChartState extends State<LiveChart> {
  final dbRef = FirebaseDatabase.instance.reference();

  //List<_ChartData> chartData = <_ChartData>[
  //  _ChartData(0, 42),
  //  _ChartData(1, 47),
  //  _ChartData(2, 33),
  //  _ChartData(3, 49),
  //  _ChartData(4, 54),
  //  _ChartData(5, 41),
  //  _ChartData(6, 58),
  //  _ChartData(7, 51),
  //  _ChartData(8, 98),
  //  _ChartData(9, 41),
  //  _ChartData(10, 53),
  //  _ChartData(11, 72),
  //  _ChartData(12, 86),
  //  _ChartData(13, 52),
  //  _ChartData(14, 94),
  //  _ChartData(15, 92),
  //  _ChartData(16, 86),
  //  _ChartData(17, 72),
  //  _ChartData(18, 94),
  //];
  Timer timer;
  ChartSeriesController _chartSeriesController;
  int count = 19;

  num _getRandomInt(num min, num max) {
    final Random random = Random();
    return min + random.nextInt(max - min);
  }

  //void _updateDataSource(Timer timer) {
  //  chartData.add(_ChartData(count, _getRandomInt(0, 100)));
  //  if (chartData.length == 20) {
  //    chartData.removeAt(0);
  //    _chartSeriesController.updateDataSource(
  //        addedDataIndexes: <int>[chartData.length - 1],
  //        removedDataIndexes: <int>[0]);
  //  }
  //  count = count + 1;
  //}

  @override
  Widget build(BuildContext context) {
    timer = Timer.periodic(Duration(milliseconds: 5000), _updateDataSource);
    return Scaffold(
        body: StreamBuilder<void>(
            stream: dbRef.child("Data").onValue,
            builder: (context, snapshot) {
              Widget widget;
              if (snapshot.hasData) {
                List<_ChartData> chartData = <_ChartData>[];
                for (int index = 0;
                    index < snapshot.data.snapshot.lenght;
                    index++) {
                  DataSnapshot snaps = snapshot.data.snapshot[index];
                  chartData.add(_ChartData.fromMap(snaps.data));
                }
                widget = Container(
                  child: SfCartesianChart(
                      tooltipBehavior: TooltipBehavior(enable: true),
                      primaryXAxis: DateTimeAxis(),
                      series: <LineSeries<_ChartDataint>>[
                        LineSeries<_ChartDataint>(
                            onRendererCreated:
                                (ChartSeriesController controller) {
                              _chartSeriesController = controller;
                            },
                            dataSource: chartData,
                            xValueMapper: (_ChartData data, _) => data.xValue,
                            yValueMapper: (_ChartData data, _) => data.yValue)
                      ]),
                );
              }
              return widget;
            }));
    //return Container(
    //  child: SfCartesianChart(
    //    tooltipBehavior: TooltipBehavior(enable: true),
    //primaryXAxis: DateTimeAxis();
    //    series: <LineSeries<_ChartData, int>>[
    //      LineSeries<_ChartData, int>(
    //        onRendererCreated: (ChartSeriesController controller) {
    //          _chartSeriesController = controller;
    //        },
    //        dataSource: chartData,
    //        xValueMapper: (_ChartData sales, _) => sales.first,
    //        yValueMapper: (_ChartData sales, _) => sales.second,
    //      )
    //    ],
    //  ),
    //);
  }

  @override
  void dispose() {
    super.dispose();
    timer?.cancel();
  }
}

class _ChartData {
  _ChartData({this.xValue, this.yValue});
  _ChartData.fromMap(Map<Stringint)
  //final int first;
  //final int second;
  //_ChartData(this.first, this.second);
}


13 Replies 1 reply marked as answer

DP Dharanitharan Palanisamy Syncfusion Team March 17, 2021 07:33 PM UTC

 
Hi Ayasha, 
 
Greetings from Syncfusion. We have analyzed your scenario and prepared the runnable sample with the given code and attached it with this, so please make use of it. The following procedure will explain about the sample, 
First, do the firebase database setup with your project by following the steps in the below link, 
 
The database is should like in the following screenshot, 
 
 
After done database setup with the project then, follow the below steps, 
 
For the Stream builder, assign the following code snippet to the stream, in which chartData is the root of the database and orderByChild is used to loop all the sub children and get their values and count is the variable that acts as the key for the sub-children. 
 
stream: FirebaseDatabase().reference().child('chartData')        
.orderByChild('$count').onValue, 
        
In the builder use the following code snippet to call the data and refresh the chart for every 3 seconds 
if (values != null && count < values.length) { 
  // Getting data from the firebase database and stores in the values list 
  List<dynamic> values = snapshot.data.snapshot.value; 
    if (values != null && count < values.length) { 
       //assigning each data value from database to the data object 
        data = values[count]; 
     } 
  timer = Timer.periodic(Duration(milliseconds: 3000), _updateDataSource); 
} 
  
In which the data gets from the database and stores in the list of values, then assign each data value to the data variable. And _updateDataSource method which calls for every 3 seconds which adds chart data from the database to the data source of our chart and refresh it.      
 
While data fetching we display the SfCartesianChart widget if snapshots had data and in the absence of data we display the CircularProgressIndicator widget. 
 
In the SfCartesianChart widget, we can assign our required properties and bind the data source will display the chart as the required type. Here, we refreshing and updating the data from the database as a sample model and you can change it as per your wish. 
 
 
Please revert us if you need further assistance. 
 
Thanks, 
Dharanitharan. P 



FR Fredianto May 24, 2021 05:51 AM UTC

Is it possible to display realtime hours:minutes:seconds on the X-Axis? I mean, we planned to get the data every 1 second, we want to capture the timestamp of it and display it on X-Axis. Thank you.

NP: The data on Firebase doesn't have timestamp. It only consist of two variables: "Moisture" which refreshes every 1 minute, and "Status" containing boolean.


DP Dharanitharan Palanisamy Syncfusion Team May 25, 2021 08:36 AM UTC

Hi Aysha, 
 
We investigated your situation and have included a sample for your review, please feel free to utilize it. The x-axis is used as a DateTimeAxis in this case, with data loaded every minute as per your requirements, and you can use ‘dateFormat’ property as ’DateFormat.Hms()’ to display in hours minutes seconds format and the kb is shared for your reference. 
 
 
Thanks, 
Dharanitharan. P 
 
 


Marked as answer

FW Felipe Werlang September 10, 2021 01:59 AM UTC

Please, how update a chart AreaSeries ever 5 Seconds by JSON data? 



SK Sriram Kiran Senthilkumar Syncfusion Team September 10, 2021 12:07 PM UTC

Hi Felipe Werlang, 
  
Greetings from Syncfusion. We have analyzed your scenario at our end, and we have created a simple chart area series sample which gets updated every 5 seconds and also attached the sample below for your reference.  
  
We have also posted a knowledge base document in which we have provided steps on how to render the flutter charts using JSON data stored in firebase data base and attached the link below for your reference. 
  
Please check with the above sample & KB and get back to us if you require further assistance. 
  
Regards, 
Sriram Kiran 



FW Felipe Werlang September 24, 2021 02:22 PM UTC

Please, how update a chart AreaSeries ever 5 Seconds by JSON data ( only Y axis, because they are sales values) x axis are fixed, don't need to be updated. Thanks



SK Sriram Kiran Senthilkumar Syncfusion Team September 27, 2021 08:49 AM UTC

Hi Felipe Werlang, 

We have analyzed your query at our end, and we have created a simple chart sample in which we have rendered area series whose y-values gets updated with randomly generated values dynamically every 5 seconds as per your requirement. We have also attached the sample below for your reference. 
  
We have also attached KB document link below in which we have described on how to retrieve JSON data from Realtime database and render chart using it. 

Please check with the above-attached sample and revert us if you still have further concerns. 

Regards,
Sriram Kiran 



FW Felipe Werlang replied to Sriram Kiran Senthilkumar October 4, 2021 11:18 AM UTC

Sriram Kiran, thanks for answer, but the graph is generating an error in the points.


chart.png


Attachment: main.dart_1d044310.zip


SK Sriram Kiran Senthilkumar Syncfusion Team October 5, 2021 01:02 PM UTC

Hi Felipe Werlang, 

We have analyzed your scenario at our end and on checking with the provided sample, we found that the chartData list which is used as data source for the series was getting added with data points from your API continuously every five seconds based on the periodic timer and due to which the chart was rendered in a clumsy manner as the data list lenght grows bigger and bigger on every periodic update. To avoid this issue, you need to always clear the chartData list every time before updating the data points. Also, we have modified your sample accordingly at our end and attached it below for your reference.  
  
Please check with the above sample and revert us if you still have further concerns. 
 
Regards, 
Sriram Kiran 



FW Felipe Werlang October 27, 2021 04:10 AM UTC

Please, how if data json:




Attachment: main.dart_c561d12.zip


SK Sriram Kiran Senthilkumar Syncfusion Team October 27, 2021 01:18 PM UTC

Hi Felipe Werlang, 

We have analyzed your query with the provided information at our end and on checking the attached sample, we found some errors in the json parsing part. We have resolved those issues and fetched the chart data from the JSON and rendered the chart. We have also attached the sample below for your reference. Please check with the modified sample and revert us if you still have further concerns. 
  
Regards, 
Sriram Kiran 



AN Alan Newcomer March 18, 2022 05:00 AM UTC

Can you post the above example with firebase that support current versions?  I cant get them to work.



YG Yuvaraj Gajaraj Syncfusion Team March 21, 2022 04:10 PM UTC

Hi Alan, 
 
We have updated the sample based on your request for fetching data from firebase and bind the data to chart widget. We have attached the sample below for your reference. 
 
  
Regards, 
Yuvaraj. 


Loader.
Up arrow icon