Articles in this section
Category / Section

How to bind data from SQLite to the Flutter Cartesian chart (SfCartesianChart) ?

3 mins read

The following steps explain how to add data to the SQLite database and bind that data to the Flutter SfCartesianChart widget.

Step 1: Add the following dependencies in the pubspec.yaml file and get the packages.

dependencies:
  flutter:
    sdk: flutter
  // To process with the Syncfusion charts.
  syncfusion_flutter_charts: ^19.1.59
 // To process with the sqlite db.
  sqflite: ^2.0.0+3
 // To provide the path to store the data in the device.
  path_provider: ^2.0.1

 

Step 2: Create the new file model.dart and create the SalesData model class to process the chart’s x and y values and define the table name of SQLite and the column names to be processed with the SQLite in the separate variables.

class SalesData {
 //SQLite table name.
 static const tblSales = 'salestable';
// x and y columns of the table.
 static const salesXValue = 'xValue';
 static const salesYValue = 'yValue';
 
  SalesData({this.xValue, this.yValue});
 
  num? xValue;
  num? yValue;
}
 

 

Step 3: Since in SQLite database records are stored as a collection of map objects, declare the named constructor fromMap for initializing an instance from a given map object. And with toMap function, we will convert sales object to the corresponding map object.

  SalesData.fromMap(Map<String, dynamic> map) {
    xValue = map[salesXValue];
    yValue = map[salesYValue];
  }
 
  Map<String, dynamic> toMap() {
    var map = <String, dynamic>{salesXValue: xValue, salesYValue: yValue};
    return map;
  }

 

Step 4: Create the new file helper to handle the SQLite database-related operations by creating the class DataBaseHelper class.

class DataBaseHelper {
  static const _databaseName = 'Sales.db';
  static const _databaseVersion = 1;
 
  //Singleton class
  DataBaseHelper._();
  static final DataBaseHelper instance = DataBaseHelper._();
 
  DataBase? _database;
  Future<DataBase> get database async {
    if (_database != null) return _database!;
    _database = await _initDataBase();
    return _database!;
  }
}

 

Define the database name, database version and declare a final property instance of the type DataBaseHelper. Also declare a public property named _database, which returns the DataBase instance. If _database is not initialized _initDataBase function will be called.

 

Step 5: Define the _initDataBase method as like the below in which the data directory is initialized with getApplicationDocumentsDirectory function, which is from path_provider package. This function returns the location where the database is stored, which is handled by the path_provider package. To connect and return the database reference openDataBase function is called.

_initDataBase() async {
    Directory dataDirectory = await getApplicationDocumentsDirectory();
    String dbPath = join(dataDirectory.path, _databaseName);
    return await openDataBase(dbPath,
        version: _databaseVersion, onCreate: _onCreateDB);
  }

 

Step 6: If there is no database with the given database path, we have to create the database. That’s what we have done with onCreate property.

Future _onCreateDB(DataBase db, int version) async {
  //create table query 
  await db.execute('''
    CREATE TABLE ${SalesData.tblSales} (
      ${SalesData.salesXValue} REAL NOT NULL,
      ${SalesData.salesYValue} REAL NOT NULL
     )
  ''');
}

 

 

Step 7: Now, the table is created from the above, so define the methods to add and fetch the data from the SQLite by defining the add(), getSales() methods as below.

 // To insert data into the SQLite.
  void add(SalesData sales) async {
    var dbClient = await database;
   // Insert query to insert data into the database
    dbClient.insert(SalesData.tblSales, sales.toMap());
  }
 
  // To fetch data from the SQLite.
  Future<List<SalesData>> getSales() async {
    var dbClient = await database;
    List<Map> maps = await dbClient.query(SalesData.tblSales,
        columns: ['${SalesData.salesXValue}', '${SalesData.salesYValue}']);
   // Adding the fetched data to the list to bind to the chart.
    List<SalesData> students = [];
    if (maps.length > 0) {
      for (int i = 0; i < maps.length; i++) {
        students.add(SalesData.fromMap(maps[i] as Map<String, dynamic>));
      }
    }
    return students;
  }
 
  // To delete data from the database table which is in the given id.
  void delete(int id) async {
    var dbClient = await database;
    dbClient.execute('delete from salestable where xValue = $id');
  }

 

Now combing whole in our main file to process the operations with the SQLite database with SfCartesianChart widget.

Step 8: Declare the chart key and chart data as below,

final chartKey = GlobalKey<ChartState>();
List<SalesData> salesData = <SalesData>[];

 

Step 9: Define the SfCartesianChart widget with the required properties as below.

SfCartesianChart(series: <SplineSeries<SalesData, num>>[
  SplineSeries<SalesData, num>(
    animationDuration: 0,
    dataSource: salesData,
    xValueMapper: (SalesData sales, _) => sales.xValue,
    yValueMapper: (SalesData sales, _) => sales.yValue,
    name: 'Sales')
  ]
)

 

Step 10: Define the two buttons for performing the adding and deleting the data in the onPressed callback from the SQLite and the same in the Cartesian chart.

ElevatedButton(
  onPressed: () async {
   // Adding data to the database
    dbHelper.add(
    SalesData(xValue: count, yValue: getRandomInt(10, 20)));
   // Fetching the data from the database
    salesData = await dbHelper.getSales();
    // Calling the chart state to redraw the chart
    chartKey.currentState!.setState(() {});
    count++;
  },
  child: Text('Add')
),
 
ElevatedButton(
  onPressed: () async {
   // To fetch the data from the database
    salesData = await dbHelper.getSales();
    if (salesData.isNotEmpty) {
      data = salesData.last;
    // Delete the last data from the database
      dbHelper.delete(
      salesData[salesData.indexOf(data)].xValue!.toInt());
     // Get data after deleting the database
      salesData = await dbHelper.getSales();
     // Calling the chart state after deleting the data to redraw with the new data.
      chartKey.currentState!.setState(() {});
      count--;
    }
  },
  child: Text('Delete')
)

 

After adding data to the database and fetch data from it by calling getSales method and call the chart state method to redraw the chart with the newly fetched data from the database.

 

Thus, we have bind that data to the SfCartesianChart widget using the SQLite database.

 

adding and deleting data from the sql lite database to the chart

 

View the sample in GitHub.

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied