import 'package:easy_localization/easy_localization.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:scrobbles/config/app_colors.dart'; import 'package:scrobbles/utils/color_extensions.dart'; class CustomBarChart extends StatelessWidget { const CustomBarChart({super.key}); final double chartHeight = 150.0; final double verticalTicksInterval = 10; final String verticalAxisTitleSuffix = ''; final double titleFontSize = 10; @override Widget build(BuildContext context) { return Container( child: SizedBox( height: this.chartHeight, ), ); } BarChart getBarChart({barWidth, backgroundColor}) { return BarChart( BarChartData( barGroups: getDataCounts(barWidth), backgroundColor: backgroundColor, borderData: getBorderData(), gridData: getGridData(), titlesData: getTitlesData(), barTouchData: BarTouchData(enabled: false), maxY: getNextRoundNumber(getMaxCountsValue(), this.verticalTicksInterval), ), ); } double getBarWidth(double containerWidth, int barsCount) { return 0.65 * (containerWidth / barsCount); } List<BarChartGroupData> getDataCounts(double barWidth) { return []; } double getMaxCountsValue() { return 0.0; } double getNextRoundNumber(double number, double scale) { return scale * ((number ~/ scale).toInt() + 1); } BarChartGroupData getBarItem( {required int x, required List<double> values, required List<Color> barColors, required double barWidth}) { List<BarChartRodData> barRods = []; for (int i = 0; i < values.length; i++) { double value = values[i]; Color barColor = barColors[i]; final gradient = this.getGradient(barColor, value, this.getMaxCountsValue()); final borderColor = barColor.darken(20); barRods.add( BarChartRodData( toY: value, color: barColor, gradient: gradient, width: barWidth, borderRadius: BorderRadius.all(Radius.zero), borderSide: BorderSide( color: borderColor, ), ), ); } return BarChartGroupData( x: x, barRods: barRods, ); } LinearGradient getGradient(Color baseColor, double value, double maxValue) { double alignmentTopValue = value != 0.0 ? -2 * maxValue / value + 1 : 0; return LinearGradient( begin: Alignment(-1, alignmentTopValue), end: Alignment(1, 1), colors: <Color>[ baseColor.lighten(30), baseColor, baseColor.darken(30), ], tileMode: TileMode.mirror, ); } FlBorderData getBorderData() { return FlBorderData( show: true, border: Border.all( color: AppColors.borderColor, width: 2, ), ); } FlGridData getGridData() { return const FlGridData( show: true, drawHorizontalLine: true, drawVerticalLine: false, ); } FlTitlesData getTitlesData() { const AxisTitles none = const AxisTitles( sideTitles: SideTitles(showTitles: false), ); final AxisTitles verticalTitles = AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 35, getTitlesWidget: getVerticalTitlesWidget, interval: this.verticalTicksInterval, ), ); final AxisTitles verticalSpacer = AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 35, getTitlesWidget: getVerticalTitlesSpacerWidget, interval: this.verticalTicksInterval, ), ); final AxisTitles horizontalTitles = AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 20, getTitlesWidget: getHorizontalTitlesWidget, ), ); return FlTitlesData( show: true, bottomTitles: horizontalTitles, leftTitles: verticalTitles, topTitles: none, rightTitles: verticalSpacer, ); } Widget getVerticalTitlesWidget(double value, TitleMeta meta) { String suffix = this.verticalAxisTitleSuffix != '' ? ' ' + this.verticalAxisTitleSuffix : ''; return SideTitleWidget( axisSide: meta.axisSide, space: 4, child: Text( value.toInt().toString() + suffix, style: TextStyle( color: AppColors.mainTextColor1, fontSize: this.titleFontSize, ), ), ); } Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) { return SideTitleWidget( axisSide: meta.axisSide, space: 4, child: Text(''), ); } Widget getHorizontalTitlesWidget(double value, TitleMeta meta) { final DateFormat formatter = DateFormat('dd/MM'); final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt()); final String text = formatter.format(date); return SideTitleWidget( axisSide: meta.axisSide, space: 4, child: Padding( padding: EdgeInsets.only(right: 10), child: RotationTransition( turns: new AlwaysStoppedAnimation(-30 / 360), child: Text( text, style: TextStyle( color: AppColors.mainTextColor1, fontSize: this.titleFontSize, ), ), ), ), ); } }