From 805b78bbaa7f3052454baa68f2e08e13d8b086bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Wed, 25 Oct 2023 21:28:38 +0200 Subject: [PATCH] Add "eclecticism" chart --- .../timeline_chart_eclecticism.dart | 164 ++++++++++++++++++ .../widgets/main_screen/timeline_content.dart | 5 + 2 files changed, 169 insertions(+) create mode 100644 lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart diff --git a/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart b/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart new file mode 100644 index 0000000..64598bb --- /dev/null +++ b/lib/ui/widgets/main_screen/timeline_chart_eclecticism.dart @@ -0,0 +1,164 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:fl_chart/fl_chart.dart'; + +import '../../../config/app_colors.dart'; +import '../../../models/timeline.dart'; + +class ChartTimelineEclecticism extends StatelessWidget { + final TimelineData chartData; + + const ChartTimelineEclecticism({super.key, required this.chartData}); + + @override + Widget build(BuildContext context) { + return Container( + height: 100.0, + child: LineChart( + LineChartData( + lineBarsData: getDataEclecticism(), + backgroundColor: Theme.of(context).colorScheme.onBackground, + borderData: getBorderData(), + gridData: getGridData(), + titlesData: getTitlesData(), + lineTouchData: getLineTouchDataEclecticism(), + maxY: 100, + minY: 0, + ), + duration: const Duration(milliseconds: 250), + ), + ); + } + + List<LineChartBarData> getDataEclecticism() { + List<FlSpot> spots = []; + + this.chartData.data.keys.forEach((element) { + TimelineDataValue? value = this.chartData.data[element]; + if (value != null) { + final double date = DateTime.parse(element).millisecondsSinceEpoch.toDouble(); + final double eclecticism = value.eclecticism.toDouble(); + + spots.add(FlSpot(date, eclecticism)); + } + }); + + return [ + LineChartBarData( + isCurved: true, + color: AppColors.contentColorCyan, + barWidth: 3, + isStrokeCapRound: false, + dotData: const FlDotData(show: false), + belowBarData: BarAreaData(show: true), + spots: spots, + ), + ]; + } + + FlBorderData getBorderData() { + return FlBorderData( + show: true, + border: Border.all( + color: AppColors.borderColor, + width: 2, + ), + ); + } + + FlGridData getGridData() { + return const FlGridData( + show: true, + ); + } + + FlTitlesData getTitlesData() { + const AxisTitles none = const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ); + + final AxisTitles verticalTitles = AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 30, + getTitlesWidget: getVerticalTitlesWidget, + interval: 25, + ), + ); + final AxisTitles horizontalTitles = AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 20, + getTitlesWidget: getHorizontalTitlesWidget, + ), + ); + + return FlTitlesData( + show: true, + bottomTitles: horizontalTitles, + leftTitles: none, + topTitles: none, + rightTitles: verticalTitles, + ); + } + + Widget getVerticalTitlesWidget(double value, TitleMeta meta) { + return SideTitleWidget( + axisSide: meta.axisSide, + space: 4, + child: Text( + value.toInt().toString(), + style: const TextStyle( + color: AppColors.mainTextColor1, + fontSize: 12, + ), + ), + ); + } + + 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: RotationTransition( + turns: new AlwaysStoppedAnimation(-30 / 360), + child: Text( + text, + style: const TextStyle( + color: AppColors.mainTextColor1, + fontSize: 11, + ), + ), + ), + ); + } + + LineTouchData getLineTouchDataEclecticism() { + return LineTouchData( + handleBuiltInTouches: true, + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.transparent, + tooltipPadding: EdgeInsets.all(8), + tooltipMargin: 2, + getTooltipItems: (List<LineBarSpot> touchedSpots) { + return touchedSpots.map((LineBarSpot touchedSpot) { + final textStyle = TextStyle( + color: AppColors.mainTextColor2, + fontWeight: FontWeight.bold, + fontSize: 10, + ); + return LineTooltipItem( + touchedSpot.y.toString(), + textStyle, + ); + }).toList(); + }, + ), + ); + } +} diff --git a/lib/ui/widgets/main_screen/timeline_content.dart b/lib/ui/widgets/main_screen/timeline_content.dart index 747a752..f460cdf 100644 --- a/lib/ui/widgets/main_screen/timeline_content.dart +++ b/lib/ui/widgets/main_screen/timeline_content.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import '../../../models/timeline.dart'; import 'timeline_chart_counts.dart'; +import 'timeline_chart_eclecticism.dart'; class ChartTimelineCardContent extends StatelessWidget { final int daysCount; @@ -41,6 +42,10 @@ class ChartTimelineCardContent extends StatelessWidget { ChartTimelineCounts( chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())), ), + const SizedBox(height: 8), + ChartTimelineEclecticism( + chartData: TimelineData.fromJson(jsonDecode(this.chartData.toString())), + ), ], ), ], -- GitLab