Many apps have a need to display some sort of data in chart form. Recently, I was tasked with implementing a chart solution on Flutter and Flutter Web and wanted to walk you through the implementation.

In this example, we are going to use the charts_flutter package.

To get started we need to add it as a dependency in our pubspec.yaml

dependencies: charts_flutter: ^0.8.1

This package has a great example gallery that includes code snippets that show how to implement each example. In this post we are going to walk through a time series chart implementation.

The end result will be an app that displays a chart on Flutter Mobile and Web.

Once we have imported our dependency, we need to get the data from our data source and transform it into a model that the chart library knows how to use. To do this, we are going to start with the repository pattern. We will create a ReportRepository class and fetch our reports from it. The data we are using comes from a sensor device and the sensor devices provides us with vibration and trip count data.

Each report entry will look like this:

{ "date": "2020-01-15T19:00:00-0500", "trips": 553, "vibration": 1.08154506437768, "doors": 1161 },

We will parse the data from a local json file and then return it as a list of reports.

https://github.com/dazza5000/flutter_chart_example/blob/master/lib/report.dart

class Report { final String date; final double vibration; Report({this.date, this.vibration}); factory Report.fromJson(Map<String, dynamic> json) { return Report( date: json['date'] as String, vibration: json['vibration'] as double); } }

For our example, we are only interested in the vibration data so that is all we will parse into the report object.

Next, we will convert our “API” data into model objects that the charts_flutter can use. charts_flutter expects a series of data associated with a domain and they provide a factory for populating the object they can use. An excerpt can be seen below.

https://github.com/google/charts/blob/master/charts_common/lib/src/data/series.dart#L108-L112

factory Series( {@required String id, @required List<T> data, @required TypedAccessorFn<T, D> domainFn, @required TypedAccessorFn<T, num> measureFn,

With this, we know we need to take our Report entries which include a date and a measurement for vibration and populate the Series factory that we can see above.

We will start by converting our report data yet again into something that we can use with the Series factory. Note: We could have done this when we got the data from the API, but sometimes it is better to keep the model for the rest of your domain pure and map it to the model that is currently being used when necessary. This helps create a separation and minimize impact should other areas of your application begin to rely on the report model. This is the model we will be mapping our entries to:

class VibrationData { final DateTime time; final double vibrationReading; VibrationData(this.time, this.vibrationReading); }

Next, we will utilize the Series factory that we talked about earlier. For this, we have created a static function that takes in a list of VibrationData and returns a Series type that we can use with charts_flutter

static List<Series> _createChartData(List<VibrationData> vibrationData) { var data = [ new Series<VibrationData, DateTime>( id: 'Desktop', colorFn: (_, __) => MaterialPalette.green.shadeDefault, domainFn: (VibrationData vibrationData, _) => vibrationData.time, measureFn: (VibrationData vibrationData, _) => vibrationData.vibrationReading, data: vibrationData, ), ]; return data; } }

Source: https://github.com/dazza5000/flutter_chart_example/blob/master/lib/chart_util.dart#L30

Once we’ve done that, we are ready to use the Series data with our chart! We’re almost there. All it has to have is our Series data

TimeSeriesChart( List<common.Series<dynamic, DateTime>> seriesList, {etc})

So with that, we plop in the Series data we created earlier and the chart will be rendered!

TimeSeriesChart(vibrationData)

Our sample implementation, sets some of the optional fields on the TimeSeriesChart and wraps it in a FractionallySizedBox

FractionallySizedBox( child: TimeSeriesChart( vibrationData, defaultRenderer: new LineRendererConfig( includeArea: true, stacked: true), animate: false, domainAxis: new DateTimeAxisSpec(renderSpec: NoneRenderSpec()), )

https://github.com/dazza5000/flutter_chart_example/blob/master/lib/main.dart

And we’re done! This will be rendered successfully on both mobile and web! 🙂

The full sample project is below. Thank you!

https://github.com/dazza5000/flutter_chart_example