🍆

fl_chartにFireStoreの値を入れる

2023/01/17に公開

グラフアプリでどう使う

以前、fl_chartとFirebaseを組み合わせたアプリの記事を書くと言っていて書いておりませんでした🙇‍♂️
今回は、ログインがないので、ランダムにドキュメントidを書いて使っているやり方ですが、Flutterで棒グラフとFirebaseを組み合わせたデモアプリを作成することができました。

今回使用したpackage
https://pub.dev/packages/fl_chart

こちらが完成したアプリの画面

FireStoreのデータはこんな風になってます。予めダミーのデータを作成しておいてください!

array型を指定して、numberをListの数だけ入れる.
今回だと0〜数えて、8個ですね。8だけど、0〜7なので、お間違いなく!

ランダムに生成されたドキュメントIDをコピーしておきます。
後ほど、ハードコーディングして使います。こんな感じですね。

// ハードコーディングでuidを指定する.
    final uid = 'rkoqDMhR6BynStA6AyXI';
    final docRef =
        FirebaseFirestore.instance.collection('barchart').doc(uid).get();

今回使用したコード

アプリを実行するコード
.toDouble()なるメソッドがあるのですが、これはコードの保管機能で出てこないので、注意!
Listは.toDouble()を使ってdouble型に変換する
https://api.flutter.dev/flutter/dart-core/num/toDouble.html

main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:timelineview_app/barchart_page.dart';
import 'package:timelineview_app/firebase_options.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(
    const ProviderScope(child: MyApp()),
  );
}

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const LineChartSample(),
    );
  }
}

グラフのコード

barchart_page.dart
import 'dart:async';
import 'dart:ffi';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;

import 'package:flutter_riverpod/flutter_riverpod.dart';

class LineChartSample extends ConsumerWidget {
  const LineChartSample({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    // 棒グラフの棒の横幅
    const double barWidth = 20.0;

    // グラフタイトルのラベル書式
    final TextStyle _labelStyle =
        const TextStyle(fontSize: 16, fontWeight: FontWeight.w800);
    // ハードコーディングでuidを指定する.
    final uid = 'rkoqDMhR6BynStA6AyXI';
    final docRef =
        FirebaseFirestore.instance.collection('barchart').doc(uid).get();
    return Scaffold(
        appBar: AppBar(
            centerTitle: true,
            automaticallyImplyLeading: false,
            title: const Text(
              'ブログの棒グラフ',
              style: TextStyle(color: Colors.white),
            )),
        body: FutureBuilder<DocumentSnapshot>(
          // FutureBuilderで画面に描画する.
          future: docRef,
          builder:
              (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return const SizedBox(
                  height: 50,
                  width: 50,
                  child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation(Colors.blue),
                    strokeWidth: 8.0,
                  ));
            }

            if (snapshot.hasData && !snapshot.data!.exists) {
              return Text("データを入力するとグラフが表示されます");
            }

            if (snapshot.connectionState == ConnectionState.done) {
              Map<String, dynamic> data =
                  snapshot.data!.data() as Map<String, dynamic>;
              return Column(
                // FutureBuilderの中に、Widgetを組み込む.
                children: [
                  const SizedBox(height: 50),
                  AspectRatio(
                      // ここから棒グラフのWidget.
                      aspectRatio: 2,
                      child: BarChart(
                        BarChartData(
                            maxY: 20, //Y軸の最大値を指定.

                            // 棒グラフの位置
                            alignment: BarChartAlignment.spaceEvenly,

                            // 棒グラフタッチ時の動作設定
                            barTouchData: BarTouchData(
                                touchTooltipData: BarTouchTooltipData(
                              tooltipBgColor: Colors.black,
                            )),

                            // グラフタイトルのパラメータ
                            titlesData: FlTitlesData(
                              show: true,
                              //右タイトル
                              rightTitles: AxisTitles(
                                  sideTitles: SideTitles(showTitles: false)),
                              //上タイトル
                              topTitles: AxisTitles(
                                sideTitles: SideTitles(showTitles: false),
                              ),
                              //下タイトル
                              bottomTitles: AxisTitles(
                                axisNameWidget: Text(
                                  'ブログ運営年月',
                                  style: _labelStyle,
                                ),
                                axisNameSize: 40,
                                sideTitles: SideTitles(
                                  showTitles: true,
                                ),
                              ),
                              // 左タイトル
                              leftTitles: AxisTitles(
                                axisNameWidget: Container(
                                    alignment: Alignment.topCenter,
                                    child: Text(
                                      '記事数',
                                      style: _labelStyle,
                                    )),
                                axisNameSize: 25,
                                sideTitles: SideTitles(
                                  showTitles: true,
                                ),
                              ),
                            ),

                            // 外枠表の線を表示/非表示
                            borderData: FlBorderData(
                                border: const Border(
                              top: BorderSide.none,
                              right: BorderSide.none,
                              left: BorderSide(width: 1),
                              bottom: BorderSide(width: 1),
                            )),

                            // barGroups: 棒グラフのグループを表す
                            // BarChartGroupData: 棒グラフの1つのグループを表す
                            // X : 横軸
                            // barRods: 棒グラフのデータを含むBarRodクラスのリスト
                            // BarChartRodData
                            // toY : 高さ
                            // width : 棒の幅
                            /// [DartのListを使って、値をグラフに入れる]
                            barGroups: [
                              BarChartGroupData(x: 2, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][0].toDouble(), // 0番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 3, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][1].toDouble(), // 1番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 4, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][2].toDouble(), // 2番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 5, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][3].toDouble(), // 3番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 6, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][4].toDouble(), // 4番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 7, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][5].toDouble(), // 5番目.
                                    width: barWidth),
                              ]),
                              BarChartGroupData(x: 8, barRods: [
                                BarChartRodData(
                                    toY: data['blogLog'][6].toDouble(), // 6番目.
                                    width: barWidth),
                              ]),
                            ]),
                      )),
                ],
              );
            }
            return Text("loading");
          },
        ));
  }
}

Listの要素の取得

Listの中の値を特定の値を取得したいときは、[]を使って要素の位置を指定します。

void main() {
  List<int> values = [1, 2, 3];
  print(values);
  print(values[0]);
  print(values[2]);
}

実行結果

[1, 2, 3]
1
3

最後に

最近、グラフや他のページに値を渡すコードを書いていると、必ずListを書かなくては、ならない状況に遭遇します。まずは、Flutterは簡単にアプリを作れるけど、作りたいもを作ろうとすると、Dartの文法への理解が必要になります。

Discussion