🏂

【Flutter】fl_chartにおける複合グラフの問題点と解決案

に公開

はじめに

Flutterでグラフやチャート扱おうと思って以下のリンクを見てみると、
以下の3つが候補に挙がるのですがsyncfusion_flutter_chartsは個人では無料(条件あり)で使えますが色々と面倒なので他で探していきたいと思いました。

  • fl_chart(MITライセンス)
  • syncfusion_flutter_charts(有料ライセンス)
  • graphic(MITライセンス)

https://fluttergems.dev/plots-visualization/

Githubでのissues

Githubのissuesにいくつも複合グラフについては挙がっているのですが、そのうちの1つをピックアップしてリンクを貼っておきます。そして以下で引用しましたが意訳すると「開発者の方はフルタイムで働いており問題を認識しているが忙しのでコミュニティやスポンサーになって解決してほしい」といった感じでした。そのため現状のバージョンではFlutterのstackを用いるのがベストプラクティスっぽいです。

Hi, unfortunately, I couldn't find enough free time to do that yet.
Please stay tuned, you can also be my sponsor to motivate me, then I can put more of time into this project.

https://github.com/imaNNeo/fl_chart/issues/764

複合グラフを描いてみる

まずはmockとして「1年間の工場生産数データ」を用意しました。この全く同じデータで棒グラフ折れ線グラフをStackして表示してみたいと思います。軸のオプションはなるべく最小限の構成で描いてみました。

production_mock.dart
const List<ProductionData> mockProductionData = [
  ProductionData(month: "1月", quantity: 1200),
  ProductionData(month: "2月", quantity: 1350),
  ProductionData(month: "3月", quantity: 1100),
  ProductionData(month: "4月", quantity: 1600),
  ProductionData(month: "5月", quantity: 1550),
  ProductionData(month: "6月", quantity: 1700),
  ProductionData(month: "7月", quantity: 1400),
  ProductionData(month: "8月", quantity: 1500),
  ProductionData(month: "9月", quantity: 1650),
  ProductionData(month: "10月", quantity: 1800),
  ProductionData(month: "11月", quantity:1750),
  ProductionData(month: "12月", quantity: 1600),
];

final List<int> productionQuantities = mockProductionData
    .map((data) => data.quantity)
    .toList();

単純にStackしてみる

ここでのX軸はmockをリスト化してインデックスで順番に表示しているので月表示は出てきませんが、下の様に同じインデックスに対して開始位置が違うのでズレます。描画範囲は同じ黒枠なので余白などを調整していく事が必要になります。

  • 棒グラフ --> 左右に余白を持って描画を始める
  • 折れ線グラフ --> Y軸の開始から描画を始める

    同一データの棒グラフと折れ線グラフ

余白に気を付けてStackしてみる

折れ線グラフを棒グラフの上にスタックしているのですが、グラフ自体の幅をPaddingで狭くしてY軸の表示を消しました。

line_chart.dart
 Padding(
      padding: const EdgeInsets.symmetric(horizontal: 80),
      child: LineChart(
        LinwChartData(... ),
        ),
    );
LinwChartData
    LinwChartData(...
        borderData: FlBorderData(show: false),
        gridData: FlGridData(show: false),
        titlesData: FlTitlesData(
        leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
        rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
        topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
 ),

余白調整の問題点

これの問題点ですが、とりあえず以下の内容があると思っています。どれも対応するのは面倒な気がしていますが少し対応策を考えていこうと思います。

  • データ数
    --> 表示期間(週、月、年)を選べるようにしてデータ数を固定して期間の数だけ対応する。
  • 描画幅(縦横、デバイス)
    --> レスポンシブ対応でwidthを固定して幅の数だけ対応する
  • 棒グラフの幅、間隔幅
    --> 幅も間隔幅も固定する。

Github

一応、Githubのリポジトリも参考になれば幸いです。
https://github.com/Lehm-code/fl_chart_sample

まとめ

今回はfl_chartで複合グラフを実装する際の注意点についてまとめました。Flutter Gemsで人気ではあるものの、開発者の方が忙しく開発にあまり意欲的でなさそうな感じでしたので複合グラフへの対応やグラフの種類が増えていくかは怪しところです。そんな訳で個人的にはgraphicの方が使い勝手が良い気がしています。

Discussion