import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../../config/statistics.dart'; import '../meal_page_text/secondary_big_text_component.dart'; import '../meal_page_text/secondary_text_component.dart'; import '../meal_page_text/title_component.dart'; class ChartComponent extends StatelessWidget { const ChartComponent({Key? key}) : super(key: key); BarTouchData get barTouchData => BarTouchData( enabled: false, touchTooltipData: BarTouchTooltipData( tooltipBgColor: Colors.transparent, tooltipPadding: EdgeInsets.zero, tooltipMargin: 4, getTooltipItem: ( BarChartGroupData group, int groupIndex, BarChartRodData rod, int rodIndex, ) { return BarTooltipItem( rod.toY.round().toString(), const TextStyle( color: Colors.transparent, fontWeight: FontWeight.bold, ), ); }, ), ); Widget getTitles(double value, TitleMeta meta) { const style = TextStyle( color: Colors.orange, fontWeight: FontWeight.bold, fontSize: 14, ); String text; switch (value.toInt()) { case 0: text = 'M'; break; case 1: text = 'T'; break; case 2: text = 'W'; break; case 3: text = 'T'; break; case 4: text = 'F'; break; case 5: text = 'S'; break; case 6: text = 'S'; break; default: text = ''; break; } return SideTitleWidget( axisSide: meta.axisSide, space: 4, child: Text(text, style: style), ); } FlTitlesData get titlesData => FlTitlesData( show: true, bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 30, getTitlesWidget: getTitles, ), ), topTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), rightTitles: AxisTitles( sideTitles: SideTitles( showTitles: false, ), ), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, _) { // Return a custom widget for each axis value return Container( constraints: const BoxConstraints.tightFor(width: double.infinity), child: Padding( padding: const EdgeInsets.only(right: 3.0), // Adjust the margin value as needed child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( value.toInt().toString(), style: const TextStyle( color: Colors.orange, fontWeight: FontWeight.bold, ), ), ), ), ); }, ), )); FlBorderData get borderData => FlBorderData( show: true, // Set to true to display the chart border border: const Border( bottom: BorderSide(color: Colors.black, width: 1), left: BorderSide(color: Colors.black, width: 1), // Hide the left border ), ); @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(8))), child: Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Column( children: [ ValueListenableBuilder( valueListenable: StatisticsService .instance.dailyAverageForCurrentWeek, builder: (context, value, child) { return SizedBox( height: 100, width: 400, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const TitleComponent("Kalorien"), const SizedBox( height: 10, ), const SecondaryTextComponent( "Durchschnittlich", null ), SecondaryBigTextComponent( "${value.toString()} kcal/Tag"), ], ), ); }, ), ValueListenableBuilder( valueListenable: StatisticsService.instance.barChartData, builder: (context, value, child) { return SizedBox( height: 300, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 15, // Adjust the height of the legend as needed child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( margin: const EdgeInsets.symmetric( horizontal: 8.0), // Adjust the spacing between legend items child: Row( children: [ Container( width: 12, height: 12, decoration: const BoxDecoration( color: Colors.red, // Use the color of the first bar rod for the legend item shape: BoxShape.circle, ), ), const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label const Text( 'Frühstück', // Replace with your desired legend label style: TextStyle( fontSize: 12), // Adjust the font size of the legend labels ), ], ), ), Container( margin: const EdgeInsets.symmetric( horizontal: 8.0), // Adjust the spacing between legend items child: Row( children: [ Container( width: 12, height: 12, decoration: const BoxDecoration( color: Colors.green, // Use the color of the first bar rod for the legend item shape: BoxShape.circle, ), ), const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label const Text( 'Mittagessen', // Replace with your desired legend label style: TextStyle( fontSize: 12), // Adjust the font size of the legend labels ), ], ), ), Container( margin: const EdgeInsets.symmetric( horizontal: 8.0), // Adjust the spacing between legend items child: Row( children: [ Container( width: 12, height: 12, decoration: const BoxDecoration( color: Colors.yellow, // Use the color of the first bar rod for the legend item shape: BoxShape.circle, ), ), const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label const Text( 'Abendessen', // Replace with your desired legend label style: TextStyle( fontSize: 12), // Adjust the font size of the legend labels ), ], ), ), ], ), ), Container( margin: const EdgeInsets.fromLTRB(0, 24, 0, 0), height: 250, child: BarChart( BarChartData( barTouchData: barTouchData, titlesData: titlesData, borderData: borderData, barGroups: value, gridData: FlGridData(show: false), alignment: BarChartAlignment.spaceAround, extraLinesData: ExtraLinesData( horizontalLines: [ HorizontalLine( y: StatisticsService.instance.getCaloryTargetForOneDay(), // Specify the y-value where you want the line to be positioned color: Colors.black, // Change the color as per your requirement strokeWidth: 2, // Adjust the width as needed dashArray: [3, 2], label: HorizontalLineLabel( show: true, labelResolver: (x) => "Zielwert" ) ), ], ), ), ), ), ], ), ); }, ), ], ), )); } }