import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'dart:math'; import '../model/reading.dart'; import '../services/date_utility.dart'; class ReadingGraph extends StatelessWidget { const ReadingGraph({super.key, required List readings}) : _readings = readings; final List _readings; @override Widget build(BuildContext context) { final spots = _readings .map( (e) => FlSpot( e.dateTime.millisecondsSinceEpoch.toDouble() / 1000 / 60, e.value), ) .toList(); return LineChart( LineChartData( maxY: _readings.map((e) => e.value).reduce(max) + 0.05, minY: _readings.map((e) => e.value).reduce(min) - 0.05, lineBarsData: [ LineChartBarData( isCurved: true, color: Theme.of(context).colorScheme.primary, barWidth: 2, isStrokeCapRound: true, dotData: const FlDotData(show: false), spots: _readings .map( (e) => FlSpot( e.dateTime.millisecondsSinceEpoch.toDouble() / 1000 / 60, e.value), ) .toList(), ) ], titlesData: FlTitlesData( bottomTitles: _getBottomTitles(spots), leftTitles: _getLeftTitles(spots), topTitles: const AxisTitles(sideTitles: SideTitles()), rightTitles: const AxisTitles(sideTitles: SideTitles()), ), lineTouchData: LineTouchData( touchTooltipData: LineTouchTooltipData( getTooltipColor: (touchedSpot) => Theme.of(context).colorScheme.primaryContainer, getTooltipItems: (touchedSpots) { return touchedSpots.map((touchedSpot) { return LineTooltipItem( '${touchedSpot.y.toString()}\n${_getLongDate(touchedSpot.x)}', TextStyle( color: Theme.of(context).colorScheme.onPrimaryContainer, fontWeight: FontWeight.bold)); }).toList(); }, ), ), ), ); } AxisTitles _getBottomTitles(List spots) { return AxisTitles( sideTitles: SideTitles( interval: 90, reservedSize: 40, showTitles: true, maxIncluded: false, minIncluded: false, getTitlesWidget: (value, meta) => SideTitleWidget( meta: meta, child: Text(DateUtility.formatMinutesToHm(value)), ), ), ); } AxisTitles _getLeftTitles(List spots) { return AxisTitles( sideTitles: SideTitles( reservedSize: 50, showTitles: true, maxIncluded: false, minIncluded: false, getTitlesWidget: (value, meta) => SideTitleWidget( meta: meta, child: Text(value.toStringAsFixed(2)), ), ), ); } String _getLongDate(double value) { DateTime date = DateTime.fromMillisecondsSinceEpoch((value * 1000 * 60).toInt()); int daysDifference = (DateTime.now().weekday - date.weekday + 7) % 7; if (daysDifference == 0) { return 'Today ${DateUtility.formatDateToHm(date)}'; } else if (daysDifference == 1) { return 'Yesterday ${DateUtility.formatDateToHm(date)}'; } return DateUtility.formatDateToYmdhm(date); } }