Flutterのチャートライブラリsyncfusion_flutter_chartsを試してみた(ラインチャート)

2022.04.14

こんにちは、CX事業本部 IoT事業部の若槻です。

Flutterで使えるチャートライブラリを探していたところsyncfusion_flutter_chartsがおすすめだと聞きました。

そこで今回は、syncfusion_flutter_chartsでラインチャート(LineSeries)を試してみます。

料金

syncfusion_flutter_chartsはSyncfusion社が提供するライブラリですが、利用にはPlatformごとに料金が掛かります。

モバイル向けFlutterでの利用であれば、開発者1人につき1年毎に$995とのこと。(サポート付き)

$ 995
Per developer 1st year

ただし、年間売上が100万USD以下かつ開発者が5人以下であれば、無償のCommunity Licenseが使えるようです。

Community License
*Companies or individuals with a gross annual revenue of less than 1 million USD and 5 or fewer developers are eligible

ライセンスを購入すれば、今回試すチャート以外にも、dataGridやdatepickerなど様々なパッケージを利用可能となります。

やってみた

こちらのGetting startedを参考にしてみます。

下記エントリの内容を実施済みである前提とします。

環境は以下の通りです。

  • MacOS Big Sur Version 11.6
  • Visual Studio Code 1.66.1
  • Google Chrome 100.0.4896.75(Official Build) (x86_64)
  • iOS Simulator 13.2 (972.2)
  • Flutter 2.10.4

インストール

flutter pub addコマンドでsyncfusion_flutter_chartsをインストールします。

$ flutter pub add syncfusion_flutter_charts

チャートの初期化

syncfusion_flutter_chartsのパッケージをImportしたら、Widgetの子要素としてチャートを初期化します。SfCartesianChart()によりデカルト座標を表示できます。

lib/main.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyGraph(),
    );
  }
}

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                //Initialize chart
                child: SfCartesianChart())));
  }
}

デカルト座標を表示できました。

データソースのバインド

SfCartesianChart()を使用するとデカルト座標上にLine Chart(線グラフ)を表示できます。SfCartesianChart()でline seriesを初期化します。dataSourceにデータを指定してバインドします。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

Line chartを表示できました。

ChartSeriesに複数のデータをバインドして、複数のチャートを表示することも可能です。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          (LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)),
          (LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 5),
                ChartData('Feb', 13),
                ChartData('Mar', 28),
                ChartData('Apr', 12),
                ChartData('May', 7)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y))
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

タイトルの追加

titleプロパティを指定してチャートのタイトルを設定できます。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    // Chart title text
                    title: ChartTitle(text: 'Half yearly sales analysis'),
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

タイトルを表示できました。

また、組み込み関数のChartTitle()ではスタイルの変更も可能です。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    // Chart title text
                    title: ChartTitle(
                        text: 'Half yearly sales analysis',
                        textStyle: TextStyle(
                            height: 10, fontSize: 20, color: Colors.blue)),
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

ラベルの有効化

dataLabelSettingsプロパティを指定して各データのラベルの表示を有効化することができます。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    title: ChartTitle(text: 'Half yearly sales analysis'),
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y,
              // Render the data label
              dataLabelSettings: DataLabelSettings(isVisible: true))
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

ラベルを表示できました。

Legendの有効化

チャートのlegendプロパティを指定して、Legend(凡例)を表示することができます。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    // Enables the legend
                    legend: Legend(isVisible: true),
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          LineSeries<ChartData, String>(
            dataSource: [
              // Bind data source
              ChartData('Jan', 35),
              ChartData('Feb', 28),
              ChartData('Mar', 34),
              ChartData('Apr', 32),
              ChartData('May', 40)
            ],
            xValueMapper: (ChartData data, _) => data.x,
            yValueMapper: (ChartData data, _) => data.y,
          )
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

Legendを表示できました。

チャートが複数表示されていればLegendも複数表示できます。

lib/main.dart

class MyGraph extends StatelessWidget {
  const MyGraph({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: Container(
                child: SfCartesianChart(
                    legend: Legend(isVisible: true),
                    // Initialize category axis
                    primaryXAxis: CategoryAxis(),
                    series: <ChartSeries>[
          // Initialize line series
          (LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 35),
                ChartData('Feb', 28),
                ChartData('Mar', 34),
                ChartData('Apr', 32),
                ChartData('May', 40)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)),
          (LineSeries<ChartData, String>(
              dataSource: [
                // Bind data source
                ChartData('Jan', 5),
                ChartData('Feb', 13),
                ChartData('Mar', 28),
                ChartData('Apr', 12),
                ChartData('May', 7)
              ],
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y))
        ]))));
  }
}

class ChartData {
  ChartData(this.x, this.y);
  final String x;
  final double? y;
}

おわりに

syncfusion_flutter_chartsでラインチャート(LineSeries)を試してみました。

チャートで表現したいことは大体できそうな感じでした。またラインチャート以外にも様々なチャートに対応しているので、チャート画面の作成はこれがあれば困らなさそうです。また、POPULALITYは99%と非常に高く、パッケージのアップデートも数週間以内毎には行われており、さすが有料提供のパッケージと言ったところでした。予算が許せば是非とも導入したいですね。

以上