[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,
);
});
}
}
この記事が気に入ったらサポートをしてみませんか?