import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; class DurationBarChart extends StatelessWidget { const DurationBarChart({ super.key, required this.values, required this.labels, }); /// Values in minutes (one per bar) final List values; /// X-axis labels (e.g. ['Mon', 'Tue', …]) final List labels; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final maxY = values.isEmpty ? 60.0 : (values.reduce((a, b) => a > b ? a : b) * 1.2).clamp(30.0, double.infinity); return BarChart( BarChartData( maxY: maxY, barGroups: List.generate(values.length, (i) { return BarChartGroupData( x: i, barRods: [ BarChartRodData( toY: values[i], color: colorScheme.primary, width: 16, borderRadius: const BorderRadius.vertical(top: Radius.circular(4)), ), ], ); }), titlesData: FlTitlesData( leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 36, getTitlesWidget: (value, meta) => Text( '${(value / 60).toStringAsFixed(0)}h', style: Theme.of(context).textTheme.labelSmall, ), ), ), bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, meta) { final idx = value.toInt(); if (idx < 0 || idx >= labels.length) return const SizedBox.shrink(); return Text( labels[idx], style: Theme.of(context).textTheme.labelSmall, ); }, ), ), rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), ), gridData: FlGridData( drawVerticalLine: false, getDrawingHorizontalLine: (value) => FlLine( color: colorScheme.outlineVariant, strokeWidth: 0.5, ), ), borderData: FlBorderData(show: false), ), ); } }