Skip to content

Instantly share code, notes, and snippets.

@imaNNeo
Created July 2, 2021 10:04
Show Gist options
  • Select an option

  • Save imaNNeo/b8b020c682fc1a697b4992277ff8890c to your computer and use it in GitHub Desktop.

Select an option

Save imaNNeo/b8b020c682fc1a697b4992277ff8890c to your computer and use it in GitHub Desktop.
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
const maleColor = Color(0xff00acc7);
const femaleColor = Color(0xfff62a68);
const borderColor = Color(0xffafafaf);
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
const hardCodedData = [
MyData(6, 7, 'Jan.,20'),
MyData(2, 5, 'Feb.,20'),
MyData(5, 8, 'Mar.,20'),
MyData(7, 9, 'Apr.,20'),
MyData(5, 7, 'May.,20'),
MyData(2, 5, 'Jun.,20'),
MyData(2, 6, 'Jul.,20'),
MyData(7, 5, 'Aug.,20'),
MyData(8, 2, 'Sep.,20'),
MyData(4, 2, 'Oct.,20'),
MyData(5, 8, 'Nov.,20'),
MyData(9, 4, 'Dec.,20'),
];
enum ShowingState {
SHOW_ALL,
SHOW_MALE,
SHOW_FEMALE,
}
extension on ShowingState {
bool isMaleSelected() => this == ShowingState.SHOW_ALL || this == ShowingState.SHOW_MALE;
bool isFemaleSelected() => this == ShowingState.SHOW_ALL || this == ShowingState.SHOW_FEMALE;
}
class _MyHomePageState extends State<MyHomePage> {
late ShowingState _showingState;
@override
void initState() {
_showingState = ShowingState.SHOW_ALL;
super.initState();
}
@override
Widget build(BuildContext context) {
final chartWidth = MediaQuery.of(context).size.shortestSide / 1.5;
final chartHeight = chartWidth * 0.65;
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: chartWidth,
height: chartHeight,
child: MaleFemaleChart(
data: hardCodedData,
showingState: _showingState,
),
),
SizedBox(
height: 28,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ChartLegend(
color: maleColor,
isSelected: _showingState.isMaleSelected(),
title: 'Male',
onTap: () {
setState(() {
if (_showingState == ShowingState.SHOW_MALE) {
_showingState = ShowingState.SHOW_ALL;
} else {
_showingState = ShowingState.SHOW_MALE;
}
});
},
),
SizedBox(
width: 28,
),
ChartLegend(
color: femaleColor,
isSelected: _showingState.isFemaleSelected(),
title: 'Female',
onTap: () {
setState(() {
if (_showingState == ShowingState.SHOW_FEMALE) {
_showingState = ShowingState.SHOW_ALL;
} else {
_showingState = ShowingState.SHOW_FEMALE;
}
});
},
),
],
)
],
),
),
),
);
}
}
class MyData {
final double maleNumber;
final double femaleNumber;
final String date;
const MyData(this.maleNumber, this.femaleNumber, this.date);
}
class MaleFemaleChart extends StatefulWidget {
final List<MyData> data;
final ShowingState showingState;
const MaleFemaleChart({
Key? key,
required this.data,
required this.showingState,
}) : super(key: key);
@override
_MaleFemaleChartState createState() => _MaleFemaleChartState();
}
class _MaleFemaleChartState extends State<MaleFemaleChart> {
@override
Widget build(BuildContext context) {
return BarChart(
BarChartData(
barGroups: widget.data.asMap().entries.map((entry) {
final index = entry.key;
final data = entry.value;
return BarChartGroupData(
x: index,
barsSpace: 4,
barRods: [
if (widget.showingState.isMaleSelected())
BarChartRodData(y: data.maleNumber, colors: [maleColor], borderRadius: BorderRadius.zero),
if (widget.showingState.isFemaleSelected())
BarChartRodData(y: data.femaleNumber, colors: [femaleColor], borderRadius: BorderRadius.zero),
],
);
}).toList(),
alignment: BarChartAlignment.spaceAround,
gridData: FlGridData(
show: true,
drawVerticalLine: false,
drawHorizontalLine: true,
getDrawingHorizontalLine: (y) => FlLine(color: borderColor, strokeWidth: 1),
),
borderData: FlBorderData(
show: true,
border: Border.all(
color: borderColor,
width: 1,
)),
titlesData: FlTitlesData(
show: true,
leftTitles: SideTitles(
showTitles: true,
reservedSize: 18,
getTextStyles: (y) => TextStyle(
color: Colors.black,
fontSize: 16,
),
),
bottomTitles: SideTitles(
showTitles: true,
getTitles: (x) => widget.data[x.toInt()].date,
rotateAngle: -60,
reservedSize: 68,
getTextStyles: (x) => TextStyle(
color: Colors.black,
fontSize: 16,
),
),
),
axisTitleData: FlAxisTitleData(
show: true,
leftTitle: AxisTitle(
showTitle: true,
titleText: '# of Members',
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
bottomTitle: AxisTitle(
showTitle: true,
titleText: 'Months',
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
),
swapAnimationDuration: Duration.zero,
);
}
}
class ChartLegend extends StatelessWidget {
final Color color;
final bool isSelected;
final String title;
final VoidCallback onTap;
const ChartLegend({
Key? key,
required this.color,
required this.isSelected,
required this.title,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 18,
height: 18,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isSelected ? color : color.withOpacity(0.4),
),
),
SizedBox(width: 6),
Text(
title,
style: TextStyle(color: isSelected ? Colors.black : Colors.black.withOpacity(0.8), fontSize: 18),
)
],
),
);
}
}
@imaNNeo
Copy link
Author

imaNNeo commented Jul 2, 2021

Answer to this issue.
ezgif com-gif-maker (3)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment