[Flutter] FL Chartで折れ線グラフ(Line Chart)を実装する

2022.11.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

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

今回は、FlutterのポピュラーなチャートライブラリであるFL Chartで折れ線グラフ(Line Chart)を実装する方法を確認してみました。

やってみた

インストール

FL Chartをインストールします。

flutter pub add fl_chart

インストールできました。

pubspec.yaml

dependencies:
  fl_chart: ^0.55.2

最低限の実装

まずLine Chart上にデータを表示するための最低限の実装です。

LineChartDatalineChartBarDataFlSpotのリストを指定します。

lib/main.dart

import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';

void main() => runApp(const MyApp());

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

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyChart(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Code Sample'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(50),
        child: LineChart(
          LineChartData(lineBarsData: [
            LineChartBarData(spots: const [
              FlSpot(1, 323),
              FlSpot(2, 538),
              FlSpot(3, 368),
              FlSpot(4, 259),
              FlSpot(5, 551),
              FlSpot(6, 226),
              FlSpot(7, 268),
              FlSpot(8, 296),
              FlSpot(9, 203),
              FlSpot(10, 246),
              FlSpot(11, 345),
            ])
          ]),
        ),
      ),
    );
  }
}

既定でマウスオーバーによるTips表示が有効となっています。

チャート周囲のタイトルの表示を制御

LineChartDatatitlesDataを指定することにより、チャートの周囲上下左右のタイトルの表示を制御することができます。

lib/main.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Code Sample'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(50),
        child: LineChart(
          LineChartData(
              lineBarsData: [
                LineChartBarData(spots: const [
                  FlSpot(1, 323),
                  FlSpot(2, 538),
                  FlSpot(3, 368),
                  FlSpot(4, 259),
                  FlSpot(5, 551),
                  FlSpot(6, 226),
                  FlSpot(7, 268),
                  FlSpot(8, 296),
                  FlSpot(9, 203),
                  FlSpot(10, 246),
                  FlSpot(11, 345),
                ])
              ],
            titlesData: FlTitlesData(
              leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
              topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
            ),
          ),
        ),
      ),
    );
  }
}

チャートの上および左のタイトルを非表示とし、見栄えをすっきりとさせられました。

Y軸の最小値および最大値を指定

既定ではY軸の最小値および最大値は、指定したデータの最小値および最大値が使われます。

LineChartDatamaxYおよびminYを指定することにより、Y軸の最小値および最大値に任意の値を指定できます。

lib/main.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Code Sample'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(50),
        child: LineChart(
          LineChartData(
            lineBarsData: [
              LineChartBarData(spots: const [
                FlSpot(1, 323),
                FlSpot(2, 538),
                FlSpot(3, 368),
                FlSpot(4, 259),
                FlSpot(5, 551),
                FlSpot(6, 226),
                FlSpot(7, 268),
                FlSpot(8, 296),
                FlSpot(9, 203),
                FlSpot(10, 246),
                FlSpot(11, 345),
              ])
            ],
            titlesData: FlTitlesData(
              leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
              topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
            ),
            maxY: 1000,
            minY: 0,
          ),
        ),
      ),
    );
  }
}

指定値はチャートで見せたい情報によるかと思いますが、今回は最大値を1000、最小値を0としてみました。

X軸のタイトルの表示間隔を制御

LineChartDatatitlesDataintervalを指定することにより、チャート周囲のタイトルの表示間隔を制御することができます。

lib/main.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Code Sample'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(50),
        child: LineChart(
          LineChartData(
            lineBarsData: [
              LineChartBarData(spots: const [
                FlSpot(1, 323),
                FlSpot(2, 538),
                FlSpot(3, 368),
                FlSpot(4, 259),
                FlSpot(5, 551),
                FlSpot(6, 226),
                FlSpot(7, 268),
                FlSpot(8, 296),
                FlSpot(9, 203),
                FlSpot(10, 246),
                FlSpot(11, 345),
              ])
            ],
            titlesData: FlTitlesData(
              bottomTitles: AxisTitles(
                  sideTitles: SideTitles(
                showTitles: true,
                interval: 1,
              )),
              leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
              topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
            ),
            maxY: 1000,
            minY: 0,
          ),
        ),
      ),
    );
  }
}

X軸のタイトルの表示間隔を1ずつにすることができました。

X軸のタイトルをカスタマイズ

SideTitlesgetTitlesWidgetを指定することにより、データの値に応じて任意の値をタイトルに表示させるようにカスタマイズすることができます。

lib/main.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Code Sample'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(50),
        child: LineChart(
          LineChartData(
            lineBarsData: [
              LineChartBarData(spots: const [
                FlSpot(1, 323),
                FlSpot(2, 538),
                FlSpot(3, 368),
                FlSpot(4, 259),
                FlSpot(5, 551),
                FlSpot(6, 226),
                FlSpot(7, 268),
                FlSpot(8, 296),
                FlSpot(9, 203),
                FlSpot(10, 246),
                FlSpot(11, 345),
              ])
            ],
            titlesData: FlTitlesData(
              bottomTitles: AxisTitles(
                sideTitles: _bottomTitles,
              ),
              leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
              topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
            ),
            maxY: 1000,
            minY: 0,
          ),
        ),
      ),
    );
  }
}

SideTitles get _bottomTitles => SideTitles(
      showTitles: true,
      interval: 1,
      getTitlesWidget: (value, meta) {
        String text = '';
        switch (value.toInt()) {
          case 1:
            text = 'Jan';
            break;
          case 2:
            text = 'Feb';
            break;
          case 3:
            text = 'Mar';
            break;
          case 4:
            text = 'Apr';
            break;
          case 5:
            text = 'May';
            break;
          case 6:
            text = 'Jun';
            break;
          case 7:
            text = 'Jul';
            break;
          case 8:
            text = 'Aug';
            break;
          case 9:
            text = 'Sep';
            break;
          case 10:
            text = 'Oct';
            break;
          case 11:
            text = 'Nov';
            break;
          case 12:
            text = 'Dec';
            break;
        }

        return Text(text);
      },
    );

X軸のタイトルを英語の月に変換して表示できました。

参考

以上