Skip to content

Instantly share code, notes, and snippets.

@imaNNeo
Created October 20, 2024 10:01
Show Gist options
  • Save imaNNeo/6a4fe59fd93cee646421c5959fc9a97d to your computer and use it in GitHub Desktop.
Save imaNNeo/6a4fe59fd93cee646421c5959fc9a97d to your computer and use it in GitHub Desktop.
FL Chart Responsive bottom titles
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:fl_chart_app/cubits/app/app_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AppCubit>(create: (BuildContext context) => AppCubit()),
],
child: MaterialApp(
home: Scaffold(
body: CustomChartMulti(
numbers1: const [5, 10, 15, 20, 25],
numbers2: const [10, 15, 20, 25, 30],
dataLabels: const [
'Long Title 1',
'Long Title 2',
'Long Title 3',
'Long Title 4',
'Long Title 5'
],
),
),
),
);
}
}
class CustomChartMulti extends StatefulWidget {
const CustomChartMulti({
super.key,
this.width,
this.height,
required this.numbers1,
required this.numbers2,
required this.dataLabels,
this.backgroundColor = Colors.white,
this.barBackgroundColor = Colors.grey,
this.barColor = Colors.blue,
this.touchedBarColor = Colors.red,
this.labelTextColor = Colors.white,
this.axisTextColor = Colors.black,
}) : assert(dataLabels.length == numbers1.length),
assert(dataLabels.length == numbers2.length);
final double? width;
final double? height;
final List<double> numbers1, numbers2;
final List<String> dataLabels;
final Color backgroundColor,
barBackgroundColor,
barColor,
touchedBarColor,
labelTextColor,
axisTextColor;
@override
State<CustomChartMulti> createState() => _CustomChartMultiState();
}
class _CustomChartMultiState extends State<CustomChartMulti> {
@override
Widget build(BuildContext context) {
return Container(
width: widget.width ?? double.infinity,
height: widget.height ?? 300,
decoration: BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(16),
),
child: LayoutBuilder(builder: (context, constraints) {
final smallSpace = constraints.maxWidth < 500;
return BarChart(
BarChartData(
barGroups: _getBarGroups(),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) => _bottomTitles(
value,
meta,
smallSpace,
),
reservedSize: 42,
),
),
leftTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
),
borderData: FlBorderData(show: false),
gridData: const FlGridData(show: false),
),
);
}),
);
}
List<BarChartGroupData> _getBarGroups() {
return List.generate(widget.dataLabels.length, (index) {
return BarChartGroupData(
x: index,
barRods: [
BarChartRodData(
toY: widget.numbers1[index],
color: widget.barColor,
width: 10,
),
BarChartRodData(
toY: widget.numbers2[index],
color: widget.touchedBarColor,
width: 10,
),
],
);
});
}
Widget _bottomTitles(double value, TitleMeta meta, bool smallSpace) {
final style = TextStyle(
color: widget.axisTextColor,
fontWeight: FontWeight.bold,
fontSize: 14,
);
return Transform.rotate(
angle: smallSpace ? -45 * pi / 180 : 0,
child: SideTitleWidget(
axisSide: meta.axisSide,
space: 16,
child: Text(widget.dataLabels[value.toInt()], style: style),
),
);
}
}
@imaNNeo
Copy link
Author

imaNNeo commented Oct 20, 2024

Answered to #1635

CleanShot.2024-10-20.at.12.02.44.mp4

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