📈

Flutterにおけるチャートパッケージ総まとめ

2023/12/23に公開
2

本記事は Flutterのカレンダー | Advent Calendar 2023 - Qiita の23日目の記事です。

CHANGELOG
  • 2023.12.25
    • コメント 頂いた fl_chart の記載を修正
    • charts_flutter が非公式のパッケージであった旨がわかるように修正

はじめに

みなさんは普段のアプリケーション開発でチャートやグラフ表現を活用していますか。
私は3年間ほど株式投資管理のアプリケーションを開発していたのですが、サービス要件に不可欠な資産増減を示す線形グラフ、ポートフォリオ、株価チャートなど、多数のチャート表現に四苦八苦しながら納得する実装を探していました。

これは個人的見解で賛否があると思いますが、JavaScript には Chart.js のような表現力の高いチャートパッケージが 多数存在している 一方で、(プラットフォームが異なるので公平な比較ではないとは思いますが)Flutter では「これを使えば万事解決」といった満足できるパッケージがないように思います。もちろん、後述する fl_chartsyncfusion_flutter_charts などは人気かつ高品質で比較的使われている印象ですが、それぞれ一長一短な部分があり、サービス要件に応じて最適なパッケージを選定するのは少し難しいです。私も、結果的には fl_chart を長く利用してきましたが、代替できるパッケージが他にないかはずっと探し続けていました。

また、Flutter 公式ドキュメントには状態管理の紹介やたくさんの Cookbook が存在する一方でチャートに関する記載は一切なく[1]、どのパッケージを利用するべきかは迷うことも多いのではないかと思います。

今回は、2023年末時点で比較的人気のあるパッケージや、個人的に良さそうと思ったパッケージを、オールインワン型と特化型に分類していくつか紹介します。ドキュメントに記載があるような実装方法には触れず、背景情報や注意点などを中心にお伝えします。

Googleの名前で提供されていた非公式パッケージ

本題へ入る前に、 Flutter におけるチャート事情を少しご紹介します。
Flutter 界隈では比較的有名な話ですが、かつて Flutter には Google の名前で提供されていた charts_flutter という非公式パッケージがありました(公式ではなく Googler によって開発されていたプロダクト)。デモサイト を見ると、良い雰囲気のシンプルなチャートが豊富に用意されていることが分かりますが、現在はもうメンテナンスされていません。私が最初にチャートパッケージを選定した2020年頃からも既に更新は滞っており、それでも当時はまだ一定数の利用者がいましたが、下記のイシューの通り2022年には正式にメンテナンス外となるアナウンスがされ Discontinued なパッケージとなりました。
https://github.com/google/charts/issues/798

現在はその Fork 版で community_charts_fluttercharts_flutter_new という名前に変えて、コミュニティや有志の開発者たちが公開しています。ただ、charts_flutter は昔から プロパティ名が難解 でかつ、Flutter フレームワークではなく独自に定義されたクラス(例: テキストスタイルの指定には TextStyleSpec を使う)を利用しています。これは学習コストもかかりますし、実装も大変で開発者体験が良くない印象を持っており、個人的には利用は控えた方が良いと思っています。

素直に、後述するサードパーティ製のパッケージを利用するのが良いでしょう。

チャートパッケージ早見表

今回は、便宜上以下の2種類に分類してパッケージを紹介します。それぞれの早見表も作成しました。

    1. 複数のチャート形式をサポートしたオールインワン型(通称: オールインワン型)
    1. 特定のチャート形式に最適化された特化型(通称: 特化型)

pub.dev でもいいね数が上位(個人的に愛用している Flutter Gems で上位結果に表示される)の人気パッケージを中心に紹介しています。

1. 複数のチャート形式をサポートしたオールインワン型

2023年現在、「Flutter でチャート実装をしたい」と思ったら以下のいずれかを利用すれば間違いないと思います。まずは簡単に扱える fl_chart で簡易実装してみて、要件が満たせないと感じたら他のパッケージを検討する形が良いと思います。各パッケージに特徴がありますので、簡単に概要へ記載しました。

パッケージ名 概要 ライセンス
fl_chart pub.dev のLIKES 5,000超えの事実上のデファクトスタンダードであるOSS。単純に利用する分には十分だが、UIやレイアウトなど細かいカスタマイズを試みると結構大変な側面もある。対応チャートは線形グラフや円グラフなど、基本的な5種類のみだが、一般的なサービス要件であれば十分事足りることが多い。 MIT
syncfusion_flutter_charts Syncfusion が提供するおそらく最も完成度が高いFlutterの商用パッケージ。独自ライセンスでプロフェッショナル向け。対応チャートは30種類以上と豊富で、さらに syncfusion_flutter_treemap など同社が開発するパッケージと組み合わせればほぼ全てのチャート形式に対応可能。Issue/PRは放置され気味。 Syncfusion License
graphic flutter_echartsApache ECharts をWebViewで描画するパッケージ)の作者がDartで新たに開発したパッケージ。Grammar of Graphics[2] の概念をベースに作成されており、ユーザーが直感的に複雑なグラフを作成できるように設計されている。Widgetは Chart のみでプロパティを使って多数のチャートを表現するため、前述の概念に慣れていない場合は学習コストが必要で難易度は高め。対応チャートは20種類以上ありカスタマイズ性が高い。 MIT

2. 特定のチャート形式に最適化された特化型

前述したオールインワン系のパッケージで事足りれば利用する機会はないですが、インタフェースやツールチップなど要件を満たした実装ができない場合に、単体のパッケージを使って補う使い方もします。私の例では、「fl_chart で基本的なチャートは実装しつつ、株価チャートは未対応なため k_chart で補う」といった具合です。個人的に利用経験があるものを中心に抜粋して紹介します。

パッケージ名 対応チャートと概要 ライセンス
pie_chart Pie Chart: PieChart というWidgetのみでシンプルに実装可能 MIT
k_chart Candlestick Chart: シンプルな実装で改変しやすく、標準でインタラクションやテクニカル指標などもサポート BSD-2-Clause
echart_flutter Line Chart: 国産パッケージで、fl_chart と似ているクラス構造で馴染みやすく、複数ラインを同時に重ねて表示することも可能 MIT

オールインワン型

オールインワン型の3パッケージについてそれぞれ詳細を記載します。

fl_chart

https://pub.dev/packages/fl_chart

チャートの操作感を確かめられるデモサイトも半年前に追加されました。
https://app.flchart.dev/#/line

特徴

  • pub.dev の LIKES 5,000超えの事実上のデファクトスタンダード
  • 全体的に可愛いテイストのデザインであり、そのまま使う分には簡単に実装できる
  • デザインやツールチップ、軸表示などのカスタマイズが必要な場合は結構大変
  • Maintainer は Iman Khoshabi のみのため大変そうで、使い勝手向上の更新は活発にされているが、大きな機能追加などはあまり進んでいない様子

詳細

おしゃれテイストなチャートを簡単に実装できます。一方で、チャート描画時の軸の計算やアニメーションの不自然さなど、使い込んでいくと気になる箇所がちらほらあります。それでも、基本的なチャートの種類は備わっておりライセンスも MIT で使いやすいのは間違いないです。
Maintainer の Iman Khoshabi 氏はイランの方で、以前に 2022年9月のイラン虐殺の際にインターネット遮断されてメンテナンスができなくなるという事態 がありました。その際に Flutter 公式へメンテナンス引き継いでほしいと懇願していましたが、今も変わらずですので進展は無かったようです。豊富なパッケージが提供されているパッケージのため嬉しい反面、メンテナンスに苦労している印象があります。

私が開発運用していた株式投資の管理アプリのコア機能でも利用しておりましたし、国内サービスでは SNS 型の米国株投資アプリの woodstock でも 株価チャートに利用 していました。

株式投資の管理アプリ資産増減 woodstock

どちらも Line Chart(woodstock については推測です)で実装されていますが、ラインのみやカラーの変更、グラデーションなど比較的自由にカスタマイズできます。これに限らず デモサイト を見ても分かる通り、線形グラフ1つとっても様々な表現を実装できます。

一方で、左側にある資産増減チャートの例に着目すると、複数のラインが重なって表示されていることがわかります。ラインを重ねて表示するだけであれば標準プロパティにリストを渡せば済みますが、「複数のラインで単位の異なる値を計算して軸の表示を調整する」や「1つのラインで実線と点線を混在させる」など少しカスタマイズ要素を追加しようとすると、実装ハードルが高くなります。ちなみに、前者は軸を算出する計算ロジックを別で処理し、minY/maxY の軸プロパティにセットして実現できます。後者は難しく、実現するには各ラインを実装しつつ Stack で重ねることになるわけですが、想定される使い方ではないためツールチップの挙動が不自然になってしまい、調整が難しかった記憶です。

改めて BaseChart のプロパティ を見てみると「基準線の表示」や「垂直/水平方向の特定部分のみのハイライト」など、私が実用していた頃と比べてかなり色々できるようになっていましたので、実現したいことはある程度できるようになっていそうです。

上記のデフォルトで用意されているプロパティのみで実現したい UI を満たせる場合は問題ないのですが、それ以外の場合では実装コストが高くなるので注意が必要です。実装前にデザイナーや PM とコミュニケーションをとり、fl_chart の実装範囲内で妥協し中間解に落とし込むことなどが良いでしょう。

syncfusion_flutter_charts

https://pub.dev/packages/syncfusion_flutter_charts

こちらは syncfusion_flutter_charts に限らず、 Syncfusion が提供するパッケージを網羅的に試せるデモサイトです。
https://flutter.syncfusion.com/

特徴

  • Syncfusion社 が提供している完成度の高い商用パッケージ
  • デザインも良く対応チャートは30種類以上と豊富で、高クオリティのため満足度は高い
  • 独自ライセンス のため利用には注意が必要
  • 同社が開発するパッケージと組み合わせればほぼ全てのチャート形式に対応可能

詳細

Syncfusion が提供する商用パッケージです。Widget名が SfXxx で統一されており、他パッケージとの競合を起こさず使い勝手が良いです。提供しているチャートの種類、品質、使い勝手含めて後述のライセンス問題を除けば fl_chart に並んで一番の候補になると思います。

Syncfusion はチャートに限らず、カレンダーや PDF ビューアなどたくさんの便利なパッケージを公開 しており、どれもクオリティが高いパッケージです。今回紹介している syncfusion_flutter_charts も筆頭パッケージですが、 syncfusion_flutter_gauges も人気で、お洒落なゲージ系のインタフェースを簡単に実装できることもあり、総合するとサポートされているチャートの種類が圧倒的に多いことがわかります。
https://pub.dev/packages/syncfusion_flutter_gauges

Syncfusion License

重要な注意点としてライセンスとコストの問題があります。Syncfusion のライセンスは、 独自ライセンス となっており、パッケージの使用には以下の2つの条件を満たしている必要があります。2.は規約同意なので良いとして、1.に注意が必要です。

    1. コミュニティライセンス(Syncfusion Community license)または商用ライセンス(Commercial License)を持っていること
    1. ライセンスの契約条件 に同意できること

コミュニティライセンスまたは商用ライセンスを持っていること

これは以下のいずれかの条件を満たすことができれば大丈夫です。

  • コミュニティライセンス
    • 年間総収益が100万ドル未満かつ組織内の開発者が5人未満であること
  • 商用ライセンス
    • デベロッパ1人あたりのライセンス使用料53,300円/年を支払う[3]
    • 弊チームでも利用検討しましたが、契約条件で会社として検討必要な部分があり NG になった経験があります

個人開発の類であればコミュニティライセンスが適用できるので、無償で自由に使えると思います。一方で、一定規模のプロジェクトで5人以上の開発者がいる体制では年間辺りの利用料を一人当たり支払う必要があります。パッケージは個人的に気に入っているのですが、ライセンスやコストの問題が足枷になり本格的にプロジェクトで使用したことはありません。

ライセンスの解釈につきましてはご自身の責任でお願いします。最新の内容は こちらのPDF からご確認できます。

graphic

https://pub.dev/packages/graphic

デモサイトはありませんが、作者のブログで詳細に説明されています。
https://medium.com/swlh/graphic-a-flutter-data-visualization-library-base-on-grammar-of-graphics-75ca751f5cae

特徴

  • WebView ベースの flutter_echarts の作者である entronad 氏によって開発
  • Grammar of Graphics の概念をベースに開発されている
  • 使用するのは Chart Widgetのみで Mark プロパティで形式を指定する方式
  • fl_chart では扱いのないヒートマップやローソク足など多数のチャートに対応している

詳細

本記事を書き始めたときは、Apache ECharts を WebView で描画できる以下の flutter_echarts を紹介しようと思ったのですが、README に graphics の利用を推奨される記載がされていたためその方針に従いました。
https://pub.dev/packages/flutter_echarts

flutter_echarts はサポート対象のチャートは多数あるのですが、Apache ECharts を Flutter から参照できるようにすべて WebView 描画でラッピングしたパッケージのため、描画速度やパフォーマンスに問題がありました。Dart の型も付けられないため、かなり特殊で使い勝手は正直あまり良くなかったと思います。

上記のような WebView 実装の課題感を持っていた作者によって、新たに開発されたパッケージが graphic です。作者の entronad 氏は中国のエンジニアで、リポジトリを見ると Flutter に限らずデータビジュアライゼーションを専門に活動しているコミッターのようです。Medium にもいくつか 記事が投稿 されています。

graphic は Grammar of Graphics の概念をベースに作成されているため、まずはこの概念を理解する必要があります。ドキュメント にも記載がある図を引用します。以下が Grammar of Graphics の重要な概念で、変数、代数、スケール、座標、シェイプなどがコンポネントのように役割を持っており、これらを組み合わせてビジュアライゼーションを実現します。

要素 説明
Data ビジュアライゼーションに使用される入力データ
Variable 入力データ内の特定の変数を選択しTupleで表現、必要に応じて変換(transform)
Scale Tupleを適切にスケーリングし、表示サイズを調整
Aesthetic グラフィックの見た目を定義(色、サイズ、形状など)
Shape 具体的な図形を定義(例:点、線、棒グラフ)

これらに加えて、アニメーションやインタラクションなどもプロパティに定義することで、多様なパターンのチャート表現が実現できるというわけです。

デモサイトは用意されていないですが、example に実装例と多数のチャート形式が用意されておりますので、クローンして動かしてみると良いかもしれません。
https://github.com/entronad/graphic/tree/main/example

特化型

前述したオールインワン型とは異なり、特定のチャート形式のみ提供するパッケージも多いです。今回紹介する以外にも、オーディオ波形の flutter_audio_waveforms や、GitHub Contribution のヒートマップのような実装ができる fl_heatmap など、用途別に様々なパッケージが公開されております。まずは、ご自身のサービス要件で好みのものがないか探してみるのがおすすめです。

pie_chart

https://pub.dev/packages/pie_chart

デモサイトもあります。
https://www.ayushpgupta.com/pie_chart/

名前の通り円グラフを提供するパッケージです。個人的に気に入っている点は、スムーズなアニメーションと凡例表示のカスタマイズ性の高さです。ドーナツ形状にもプロパティで変更できます。もちろん円グラフは良く利用されるチャート形式なので、前述したオールインワン型の全てでサポートされていますが、pie_chart は円の太さや凡例との距離など細かく調整できる印象です。使い方も簡単で PieChart という Widgetを使うだけで実装できます。

以下のようなチャートの項目に隣接させて凡例を表示することは意外と難しいですが、pie_chart を利用すると簡単に実現できます。私の開発していたアプリでも、資産ポートフォリオを表示する機能で長く愛用しておりました。

pie_chartの利用例

k_chart

https://pub.dev/packages/k_chart

k_chart は株価チャートのローソク足(Candlestick Chart とも呼ばれます)を実装するのに便利なパッケージです。
README のスクリーンショットや gif のリンクが切れていてあまり良い印象はないかもしれませんが、簡単にローソク足のチャートを実装できる点で便利です。また、移動平均線やボリンジャーバンドのような一般的な株価チャートで必要なテクニカル指標についてもプロパティ1つで表示できる構造となっており、サポート対象が広いです。インタラクションも対応されており、Drag, Scale, Long Press にも対応しています。

k_chart 単体でも使いやすいですが、コードもシンプルなため Fork して改変しやすいのも良いポイントです(改変する場合はライセンス表記をチェックしましょう)。

以下の左図は元の k_chart で、右図は陽線・陰線のカラーの変更などに対応した上で、サービスの機能要件の「ローソク足上に別の図形を描画する」機能も追加した Fork 版です。このように、比較的簡単に自分好みのローソク足を実装できます。

k_chart k_chart(Fork版)

ちなみに私はオールインワン型で fl_chart を利用しておりローソク足は未対応だったため k_chart を使って補填しましたが、syncfucion_flutter_chartsgraphic では標準サポートされているので、そちらでも十分かもしれません。

echart_flutter

https://pub.dev/packages/echart_flutter

国内企業の enechain 社 が開発しているパッケージで、現在線形グラフのみに対応しています。私はまだ本格的に利用したことはないのですが、pub.dev に上がっている唯一(?)の国産チャートパッケージとして簡単に紹介します。

利用する分にはかなり簡単で、LineChart でデータやツールチップなどの最小限のプロパティを持ち、LineChartData で軸や見た目などの設定をする実装になっています。インスパイアされているかは分かりませんが、ツールチップの扱いなど若干異なる点はありつつも、構造的には fl_chart に似ていると思いました。

実装もシンプルで読みやすいので、「線形グラフしか実装予定がない」というサービスは一度使ってみると良いかも知れません。

まとめ

今回は、2023年末時点で比較的人気のあるパッケージや、個人的に良さそうと思ったパッケージを、オールインワン型と特化型に分類していくつか紹介しました。fl_chart の活動を見て、複数のチャート全てに対応するのは非常に大変な印象で、各開発者が自分で使いたい形式のチャートを開発した結果、特化型として公開されているという構造だと思います。

私の場合は、 fl_chart をベースに要所で pie_chartk_chart の特化型パッケージを組み合わせて納得に近い実装ができていましたが、当然利用する依存関係が多いほどメンテナンスは大変ですし、名前空間の衝突やデザインの統一性も損なわれてしまうこともあります。

冒頭にも言及しましたが、パッケージそれぞれに一長一短があるため、サービス要件によって最適なパッケージ選定は異なります。オールインワン型のみで完結するか、特化型も組み合わせて表現を拘るか、皆さんの最適解を探してみてください。

今回ご紹介した以外にも、魅力的なパッケージはいくつかありますので興味がありましたらぜひ調べてみてください。
https://fluttergems.dev/plots-visualization/

参考

脚注
  1. 2023年12月時点で私が見つけられなかっただけかもしれず、記載されていましたらコメント等でご指摘いただけると嬉しいです。 ↩︎

  2. 「Grammar of Graphics」とは、データのビジュアライゼーションを作成するため理論で、 Leland Wilkinson によって同名の書籍 で紹介されました。この理論では、グラフィックスを生成するための一連の独立したコンポーネントを定義し、それらを組み合わせることで様々な種類のデータビジュアライゼーションを作成します。 ↩︎

  3. 当時2020年に Syncfusion 社へ問い合わせした際にいただいた回答です。現在は変わっている可能性もありますので、使用の際は直接ご確認ください。 ↩︎

Discussion

ndjndj

fl_chart の複数ラインチャートですが、現在では標準で対応していたはずです(当時のお話でしたらすみません)!

LineChartDatalineBarsData が配列で渡せるようになっています(↓公式のサンプルです)
https://github.com/imaNNeo/fl_chart/blob/master/example/lib/presentation/samples/line/line_chart_sample1.dart

前年比%実績金額 のように、値の大きさが異なるような2軸チャートだと、現在でも計算処理を挟んで無理やり表示する方法しかないので Stack もありかもしれないです。

積み上げ棒グラフとラインチャートを組み合わせる方法をずっと fl_chart でできないか苦戦していたのですが(同じく Stack で対応しようとしていたのですがかなり難儀でした💦)、
graphic でできそうなことを知れたのでよかったです!管理画面の記事も参考にさせていただきました!
ありがとうございました!

ツルオカツルオカ

ndjさん、ご指摘のコメントありがとうございます。
完全にうっかりしており、誤った情報を記載しておりましたので修正しました🙏
仰るとおり、単純に複数ラインを表示するだけであれば公式サンプルの通り簡単にでき、私の困難は「複数のラインで単位の異なる値を計算して軸の表示を調整する」などの内容でしたのでそちらも修正しました。

積み上げ棒グラフとラインチャートを組み合わせる方法をずっと fl_chart でできないか苦戦していたのですが(同じく Stack で対応しようとしていたのですがかなり難儀でした)

確かに異なる種類のチャートを重ねて表示するのは難しそうですね…。ndjさんの例のように、本記事では「デフォルトでサポートされていない複雑な実装を試みると途端に難易度が上がる」ことを伝えたい意図で記載しました。


他の記事も見ていただきありがとうございます。
もし気になる点などございましたら、今後もコメントにてフィードバック頂けますと嬉しいです🙌