🏂

【Flutter】graphicの極座標系を用いてレーダーチャートを作成してみる

に公開

はじめに

以前にfl_cahartで複合グラフを描くと問題点があるという記事で少しgraphicが良さそうと書いたので今回はgraphicでついて書きたいと思います。graphicではレーダーチャートはサポートされていませんが「Polar Coord(極座標系)」は存在するのでそれを応用して描いていきます。
https://zenn.dev/lehm/articles/12064f2420918c

graphicの開発背景

graphicの作者はflutter_echartsを作成された方で詳細は下記リンクに「Background」として書かれていますので、ここでは簡単に抜粋をいたします。

  • fl_chart --> シンプルで人気だが複雑な内容には不向きな場合がある
  • syncfusion_flutter_charts --> 高機能で高品質だがオープンソースでない
  • flutter_echarts --> パフォーマンス性の問題がある

https://medium.com/swlh/graphic-a-flutter-data-visualization-library-base-on-grammar-of-graphics-75ca751f5cae

レーダーチャートの実装

実装方針

実装方針はStackを用いて背景のレーダーチャートと前面にメインのレーダーチャートを表示する方法を取りました。

mockデータとStack前

mockデータは5教科のテスト結果を用意しました。mockSubjectGridScoresを使って背景のグリッドを描画し、mockSubjectScoresは手前のメインになるレーダーチャートです。

subject_score_mock.dart
final List<Map<String, dynamic>> mockSubjectScores = [
  {'label': '国語', 'value': 81},
  {'label': '数学', 'value': 92},
  {'label': '英語', 'value': 68},
  {'label': '理科', 'value': 86},
  {'label': '社会', 'value': 42},
];

final subjects = ['国語', '数学', '英語', '理科', '社会'];
final groups = ['20', '40', '60', '80', '100'];

final List<Map<String, dynamic>> mockSubjectGridScores = [
  for (var group in groups)
    for (var subject in subjects)
      {'label': subject, 'value': double.parse(group), 'group': group},
];


ベースグリッドとメインチャート

Stackで描画

fl_chartではStackを使って複合グラフを実装するのに位置を調整するのが面倒でしたが、graphicでは描画範囲が同じなので簡単にピッタリ合います。

main_home.dart(一部抜粋)
Stack(
  alignment: Alignment.center,
  children: const [
    SizedBox(height: 300, child: RadarBaseChart()),
    SizedBox(height: 300, child: RadarMainChart()),
  ],
),


完成したレーダーチャート

Github

今回のサンプルアプリのリポジトリです。mockは5角形ですがデータ数を増やしても対応出来たり、点数に応じてレーティングを表示する機能も付けてみたので参考になれば幸いです。

https://github.com/Lehm-code/graphic_sample

さいごに

今回はgraphicを使ってレーダーチャートを作成してみました。最初はレーダーチャートをサポートしていなのでビックリしましたが極座標系を使う事で実質的にはあるので何とかなって良かったです。次はiPhoneの睡眠グラフをgraphicで再現してみようと思います。

Discussion