I am using fl_chart package in my Flutter application to add a Bar chart that is supposed to display dates (format - dd/mm/yy) in a titled fashion in the X - axis as shown in the below image
The code which generates this UI is as follows
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:vendors/gen/colors.gen.dart';
import 'package:vendors/src/shared/widgets/dividers/custom_divider.dart';
import 'package:vendors/src/shared/widgets/input/input_date_field.dart';
class ClaimsChart extends StatefulWidget {
const ClaimsChart({super.key});
@override
State<ClaimsChart> createState() => _ClaimsChartState();
}
class _ClaimsChartState extends State<ClaimsChart> {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AspectRatio(
aspectRatio: 1.75,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: BarChart(
BarChartData(
barGroups: _chartGroups(),
borderData: FlBorderData(
border: const Border(
bottom: BorderSide(color: Colors.black26),
left: BorderSide(color: Colors.black26))),
gridData: const FlGridData(show: false),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(sideTitles: _bottomTitles),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 5,
reservedSize: 20,
getTitlesWidget: (value, meta) => Text(
value.toInt().toString(),
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12),
))),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false)),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false)),
),
),
),
),
)
],
),
);
}
List<BarChartGroupData> _chartGroups() {
return List.generate(
10,
(index) =>
ChartData(date: DateTime.now(), value: Random().nextInt(20)))
.map((point) =>
BarChartGroupData(x: point.date.microsecondsSinceEpoch, barRods: [
BarChartRodData(
toY: point.value.toDouble(),
color: ColorName.barChart,
width: 12,
borderRadius: BorderRadius.circular(0)),
]))
.toList();
}
SideTitles get _bottomTitles => SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
String formattedDate = DateFormat("dd/mm/yy")
.format(DateTime.fromMicrosecondsSinceEpoch(value.toInt()));
return SideTitleWidget(
axisSide: meta.axisSide,
// You can adjust the space as needed
child: Transform.rotate(
angle: -45 * (pi / 180),
// Rotate by 45 degrees (convert to radians)
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Text(
formattedDate,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12,
),
),
),
));
},
);
}
class ChartData {
final DateTime date;
final int value;
ChartData({required this.date, this.value = 9});
}
Note - The ClaimsChart widget is part of a SingleChildScrollView
The expected UI should be like this
I have tried to add Top padding to move the Text title widget down by 10 points, but it just made the Text disappear
There is no need of Transform.rotate
if you only want to rotate the formatted date text. There is an angle property in SideTitleWidget
that can help you out.
Code snippet for your reference :-
SideTitleWidget(
axisSide: meta.axisSide,
angle: 125,
child: Text(
formattedDate,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12,
),
),
)
Let me know if it helps.