[Flutter]fl_chartを試す

flutterのチャートライブラリーと言ったらcharts_flutterかfl_chart。githubのstar数charts_flutterが2k、fl_chartの方が2.4kと多いということでfl_chartを試してみる。

今回はgithubのリポジトリをダウンロードした中に含まれているサンプルを動かしてみます。タップすると下の写真のようにflutterロゴの水玉模様が散らばるアニメーションになっています。チャートではないですねw

pubspec.yaml

dependencies:
 flutter:
   sdk: flutter
 cupertino_icons: ^1.0.0
 fl_chart: ^0.12.0

home.dart

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter/foundation.dart'; // *.freezed.dartで必要なのでimportしておく
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:listview/widget/card.dart';
import 'package:listview/widget/list.dart';
import 'package:listview/widget/scatter_chart.dart';

part 'home.freezed.dart';

@freezed
abstract class HomeState with _$HomeState {
 const factory HomeState({
   @Default(0) int page,
 }) = _HomeState;
}

final homeStateProvider = StateNotifierProvider((_) => HomeStateProvider());

class HomeStateProvider extends StateNotifier<HomeState> {
 HomeStateProvider() : super(const HomeState());
 void initState() {}
 void dispose() {}
 void onItemTapped(int index, PageController pageController) {
   pageController.animateToPage(index,
       duration: const Duration(milliseconds: 300), curve: Curves.ease);
 }
 void onPageChanged(int index) {
   state = state.copyWith(page: index);
 }
}

class MyHomePage extends HookWidget {
 final items = List.generate(10, (index) => 'Item: $index');
 final _pageController = PageController();
 
 @override
 Widget build(BuildContext context) {
   final hsp = useProvider(homeStateProvider);
   final homeState = useProvider(homeStateProvider.state);
   return Scaffold(
     appBar: AppBar(
       title: Text('Dev'),
     ),
     body: PageView(
       controller: _pageController,
       onPageChanged: hsp.onPageChanged,
       children: [
         ScatterChartSample1(),
         CardPage(),
         MyList1(),
         MyList2(),
         MyList3(),
       ],
     ),
     bottomNavigationBar: BottomNavigationBar(
       items: const <BottomNavigationBarItem>[
         BottomNavigationBarItem(
           icon: Icon(Icons.bar_chart),
           label: 's_chart',
         ),
         BottomNavigationBarItem(
           icon: Icon(Icons.card_membership),
           label: 'card',
         ),
         BottomNavigationBarItem(
           icon: Icon(Icons.home),
           label: '1',
         ),
         BottomNavigationBarItem(
           icon: Icon(Icons.youtube_searched_for_rounded),
           label: '2',
         ),
         BottomNavigationBarItem(
           icon: Icon(Icons.animation),
           label: '3',
         ),
       ],
       currentIndex: homeState.page,
       fixedColor: Colors.pink[300],
       iconSize: 24,
       // showSelectedLabels: true,
       showUnselectedLabels: true,
       unselectedItemColor: Colors.grey,
       onTap: (index) {
         hsp.onItemTapped(index, _pageController);
       },
     ),
   );
 }
}

scatter_chart.dart

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

class ScatterChartSample1 extends StatefulWidget {
 @override
 State<StatefulWidget> createState() => _ScatterChartSample1State();
}

class _ScatterChartSample1State extends State {
 final maxX = 50.0;
 final maxY = 50.0;
 final radius = 8.0;
 Color blue1 = const Color(0xFF0D47A1);
 Color blue2 = const Color(0xFF42A5F5).withOpacity(0.8);
 bool showFlutter = true;
 
 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: () {
       setState(() {
         showFlutter = !showFlutter;
       });
     },
     child: AspectRatio(
       aspectRatio: 1,
       child: Card(
         color: const Color(0xffffffff),
         elevation: 6,
         child: ScatterChart(
           ScatterChartData(
             scatterSpots: showFlutter ? flutterLogoData() : randomData(),
             minX: 0,
             maxX: maxX,
             minY: 0,
             maxY: maxY,
             borderData: FlBorderData(
               show: false,
             ),
             gridData: FlGridData(
               show: false,
             ),
             titlesData: FlTitlesData(
               show: false,
             ),
             scatterTouchData: ScatterTouchData(
               enabled: false,
             ),
           ),
           swapAnimationDuration: const Duration(milliseconds: 600),
         ),
       ),
     ),
   );
 }
 
 List<ScatterSpot> flutterLogoData() {
   return [
     /// section 1
     ScatterSpot(20, 14.5, color: blue1, radius: radius),
     ScatterSpot(22, 16.5, color: blue1, radius: radius),
     ScatterSpot(24, 18.5, color: blue1, radius: radius),
     ScatterSpot(22, 12.5, color: blue1, radius: radius),
     ScatterSpot(24, 14.5, color: blue1, radius: radius),
     ScatterSpot(26, 16.5, color: blue1, radius: radius),
     ScatterSpot(24, 10.5, color: blue1, radius: radius),
     ScatterSpot(26, 12.5, color: blue1, radius: radius),
     ScatterSpot(28, 14.5, color: blue1, radius: radius),
     ScatterSpot(26, 8.5, color: blue1, radius: radius),
     ScatterSpot(28, 10.5, color: blue1, radius: radius),
     ScatterSpot(30, 12.5, color: blue1, radius: radius),
     ScatterSpot(28, 6.5, color: blue1, radius: radius),
     ScatterSpot(30, 8.5, color: blue1, radius: radius),
     ScatterSpot(32, 10.5, color: blue1, radius: radius),
     ScatterSpot(30, 4.5, color: blue1, radius: radius),
     ScatterSpot(32, 6.5, color: blue1, radius: radius),
     ScatterSpot(34, 8.5, color: blue1, radius: radius),
     ScatterSpot(34, 4.5, color: blue1, radius: radius),
     ScatterSpot(36, 6.5, color: blue1, radius: radius),
     ScatterSpot(38, 4.5, color: blue1, radius: radius),
     /// section 2
     ScatterSpot(20, 14.5, color: blue2, radius: radius),
     ScatterSpot(22, 12.5, color: blue2, radius: radius),
     ScatterSpot(24, 10.5, color: blue2, radius: radius),
     ScatterSpot(22, 16.5, color: blue2, radius: radius),
     ScatterSpot(24, 14.5, color: blue2, radius: radius),
     ScatterSpot(26, 12.5, color: blue2, radius: radius),
     ScatterSpot(24, 18.5, color: blue2, radius: radius),
     ScatterSpot(26, 16.5, color: blue2, radius: radius),
     ScatterSpot(28, 14.5, color: blue2, radius: radius),
     ScatterSpot(26, 20.5, color: blue2, radius: radius),
     ScatterSpot(28, 18.5, color: blue2, radius: radius),
     ScatterSpot(30, 16.5, color: blue2, radius: radius),
     ScatterSpot(28, 22.5, color: blue2, radius: radius),
     ScatterSpot(30, 20.5, color: blue2, radius: radius),
     ScatterSpot(32, 18.5, color: blue2, radius: radius),
     ScatterSpot(30, 24.5, color: blue2, radius: radius),
     ScatterSpot(32, 22.5, color: blue2, radius: radius),
     ScatterSpot(34, 20.5, color: blue2, radius: radius),
     ScatterSpot(34, 24.5, color: blue2, radius: radius),
     ScatterSpot(36, 22.5, color: blue2, radius: radius),
     ScatterSpot(38, 24.5, color: blue2, radius: radius),
     /// section 3
     ScatterSpot(10, 25, color: blue2, radius: radius),
     ScatterSpot(12, 23, color: blue2, radius: radius),
     ScatterSpot(14, 21, color: blue2, radius: radius),
     ScatterSpot(12, 27, color: blue2, radius: radius),
     ScatterSpot(14, 25, color: blue2, radius: radius),
     ScatterSpot(16, 23, color: blue2, radius: radius),
     ScatterSpot(14, 29, color: blue2, radius: radius),
     ScatterSpot(16, 27, color: blue2, radius: radius),
     ScatterSpot(18, 25, color: blue2, radius: radius),
     ScatterSpot(16, 31, color: blue2, radius: radius),
     ScatterSpot(18, 29, color: blue2, radius: radius),
     ScatterSpot(20, 27, color: blue2, radius: radius),
     ScatterSpot(18, 33, color: blue2, radius: radius),
     ScatterSpot(20, 31, color: blue2, radius: radius),
     ScatterSpot(22, 29, color: blue2, radius: radius),
     ScatterSpot(20, 35, color: blue2, radius: radius),
     ScatterSpot(22, 33, color: blue2, radius: radius),
     ScatterSpot(24, 31, color: blue2, radius: radius),
     ScatterSpot(22, 37, color: blue2, radius: radius),
     ScatterSpot(24, 35, color: blue2, radius: radius),
     ScatterSpot(26, 33, color: blue2, radius: radius),
     ScatterSpot(24, 39, color: blue2, radius: radius),
     ScatterSpot(26, 37, color: blue2, radius: radius),
     ScatterSpot(28, 35, color: blue2, radius: radius),
     ScatterSpot(26, 41, color: blue2, radius: radius),
     ScatterSpot(28, 39, color: blue2, radius: radius),
     ScatterSpot(30, 37, color: blue2, radius: radius),
     ScatterSpot(28, 43, color: blue2, radius: radius),
     ScatterSpot(30, 41, color: blue2, radius: radius),
     ScatterSpot(32, 39, color: blue2, radius: radius),
     ScatterSpot(30, 45, color: blue2, radius: radius),
     ScatterSpot(32, 43, color: blue2, radius: radius),
     ScatterSpot(34, 41, color: blue2, radius: radius),
     ScatterSpot(34, 45, color: blue2, radius: radius),
     ScatterSpot(36, 43, color: blue2, radius: radius),
     ScatterSpot(38, 45, color: blue2, radius: radius),
   ];
 }
 
 List<ScatterSpot> randomData() {
   const blue1Count = 21;
   const blue2Count = 57;
   return List.generate(blue1Count + blue2Count, (i) {
     Color color;
     if (i < blue1Count) {
       color = blue1;
     } else {
       color = blue2;
     }
     return ScatterSpot(
       (Random().nextDouble() * (maxX - 8)) + 4,
       (Random().nextDouble() * (maxY - 8)) + 4,
       color: color,
       radius: (Random().nextDouble() * 16) + 4,
     );
   });
 }
}

この記事が気に入ったらサポートをしてみませんか?