import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/analytics/models/occupacy.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; class OccupancyChart extends StatelessWidget { const OccupancyChart({required this.chartData, super.key}); final List chartData; static const _chartWidth = 16.0; @override Widget build(BuildContext context) { return BarChart( BarChartData( maxY: 100.001, gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, horizontalInterval: 20, ), borderData: EnergyManagementChartsHelper.borderData(), barTouchData: _barTouchData(context), titlesData: _titlesData(context).copyWith( leftTitles: _titlesData(context).leftTitles.copyWith( sideTitles: _titlesData(context).leftTitles.sideTitles.copyWith( maxIncluded: true, minIncluded: true, ), ), ), barGroups: List.generate(chartData.length, (index) { final actual = chartData[index]; final occupancyValue = double.parse(actual.occupancy); return BarChartGroupData( x: index, barsSpace: 0, groupVertically: true, barRods: [ BarChartRodData( toY: 100.0, fromY: occupancyValue == 0 ? occupancyValue : occupancyValue + 2.5, color: ColorsManager.graysColor, width: _chartWidth, borderRadius: BorderRadius.circular(10), ), BarChartRodData( toY: occupancyValue, color: ColorsManager.vividBlue.withValues(alpha: 0.8), width: _chartWidth, borderRadius: BorderRadius.circular(10), ), ], ); }), ), ); } BarTouchData _barTouchData(BuildContext context) { return BarTouchData( touchTooltipData: BarTouchTooltipData( getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors, tooltipBorder: const BorderSide( color: ColorsManager.semiTransparentBlack, ), tooltipRoundedRadius: 16, tooltipPadding: const EdgeInsets.all(8), getTooltipItem: (group, groupIndex, rod, rodIndex) => getTooltipItem( context: context, group: group, groupIndex: groupIndex, rod: rod, rodIndex: rodIndex, ), ), ); } BarTooltipItem? getTooltipItem({ required BuildContext context, required BarChartGroupData group, required int groupIndex, required BarChartRodData rod, required int rodIndex, }) { final data = chartData; final occupancyValue = double.parse(data[group.x.toInt()].occupancy); final percentage = '${(occupancyValue).toStringAsFixed(0)}%'; return BarTooltipItem( percentage, context.textTheme.bodyMedium!.copyWith( color: ColorsManager.blackColor, fontSize: 14, ), ); } FlTitlesData _titlesData(BuildContext context) { final titlesData = EnergyManagementChartsHelper.titlesData( context, leftTitlesInterval: 250, ); final leftTitles = titlesData.leftTitles.copyWith( sideTitles: titlesData.leftTitles.sideTitles.copyWith( reservedSize: 70, interval: 20, getTitlesWidget: (value, meta) => Padding( padding: const EdgeInsetsDirectional.only(end: 12), child: FittedBox( alignment: AlignmentDirectional.centerStart, fit: BoxFit.scaleDown, child: Text( '${(value).toStringAsFixed(0)}%', style: context.textTheme.bodySmall?.copyWith( fontSize: 12, color: ColorsManager.greyColor, ), ), ), ), ), ); final bottomTitles = AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, _) => FittedBox( alignment: AlignmentDirectional.bottomCenter, fit: BoxFit.scaleDown, child: Text( chartData[value.toInt()].date.day.toString(), style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.greyColor, fontSize: 8, ), ), ), reservedSize: 36, ), ); return titlesData.copyWith( leftTitles: leftTitles, bottomTitles: bottomTitles, ); } }