From c397036058f11bdee190f30e55a082ce851467e1 Mon Sep 17 00:00:00 2001 From: Qizot Date: Tue, 14 Apr 2020 17:12:14 +0200 Subject: [PATCH] Added new chart --- .../ui/charts/daily_cases_timeline_chart.dart | 61 +++++++++++++++++++ .../src/ui/charts/total_timeline_chart.dart | 9 --- .../country_timeline_screen.dart | 7 +-- .../global_timeline_sceen.dart | 3 + .../daily_cases_chart_card.dart | 32 ++++++++++ .../total_timeline_chart_card.dart | 26 +------- .../total_timeline/total_timeline_stats.dart | 17 +++--- .../lib/src/ui/total_timeline/utils.dart | 26 ++++++++ 8 files changed, 135 insertions(+), 46 deletions(-) create mode 100644 frontend/coronavirus_visualizer/lib/src/ui/charts/daily_cases_timeline_chart.dart create mode 100644 frontend/coronavirus_visualizer/lib/src/ui/total_timeline/daily_cases_chart_card.dart create mode 100644 frontend/coronavirus_visualizer/lib/src/ui/total_timeline/utils.dart diff --git a/frontend/coronavirus_visualizer/lib/src/ui/charts/daily_cases_timeline_chart.dart b/frontend/coronavirus_visualizer/lib/src/ui/charts/daily_cases_timeline_chart.dart new file mode 100644 index 0000000..f219f53 --- /dev/null +++ b/frontend/coronavirus_visualizer/lib/src/ui/charts/daily_cases_timeline_chart.dart @@ -0,0 +1,61 @@ +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:coronavirus_visualizer/src/models/timeline_item.dart'; +import 'package:coronavirus_visualizer/src/ui/charts/total_timeline_details_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +class DailyCasesTimeline extends StatelessWidget { + + + final List seriesList; + final bool animate; + + DailyCasesTimeline(List timelineItems, {this.animate}): seriesList = generateTimeSeries(timelineItems); + + static List> generateTimeSeries(List timelineItems) { + return [ + charts.Series( + id: 'Daily Cases', + colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, + domainFn: (TimelineItem item, _) => item.date, + measureFn: (TimelineItem item, _) => item.newCases, + data: timelineItems, + ), + ]; + } + + _onSelectionChanged(BuildContext context) { + return (charts.SelectionModel model) { + final selectedDatum = model.selectedDatum; + + if (selectedDatum.isNotEmpty) { + final item = model.selectedDatum.first.datum as TimelineItem; + showDialog(context: context, builder: (context) { + return TotalTimelineDetailsDialog(timelineItem: item); + }); + + } + }; + } + + + @override + Widget build(BuildContext context) { + return charts.TimeSeriesChart( + seriesList, + animate: animate, + defaultRenderer: charts.LineRendererConfig(), + customSeriesRenderers: [ + charts.PointRendererConfig( + customRendererId: 'customPoint') + ], + selectionModels: [ + charts.SelectionModelConfig( + type: charts.SelectionModelType.info, + changedListener: _onSelectionChanged(context), + ) + ], + dateTimeFactory: const charts.LocalDateTimeFactory(), + ); + } +} \ No newline at end of file diff --git a/frontend/coronavirus_visualizer/lib/src/ui/charts/total_timeline_chart.dart b/frontend/coronavirus_visualizer/lib/src/ui/charts/total_timeline_chart.dart index a901896..9bb42b0 100644 --- a/frontend/coronavirus_visualizer/lib/src/ui/charts/total_timeline_chart.dart +++ b/frontend/coronavirus_visualizer/lib/src/ui/charts/total_timeline_chart.dart @@ -58,15 +58,9 @@ class TotalTimelineChart extends StatelessWidget { return charts.TimeSeriesChart( seriesList, animate: animate, - // Configure the default renderer as a line renderer. This will be used - // for any series that does not define a rendererIdKey. - // - // This is the default configuration, but is shown here for illustration. defaultRenderer: charts.LineRendererConfig(), - // Custom renderer configuration for the point series. customSeriesRenderers: [ charts.PointRendererConfig( - // ID used to link series to this renderer. customRendererId: 'customPoint') ], selectionModels: [ @@ -75,9 +69,6 @@ class TotalTimelineChart extends StatelessWidget { changedListener: _onSelectionChanged(context), ) ], - // Optionally pass in a [DateTimeFactory] used by the chart. The factory - // should create the same type of [DateTime] as the data provided. If none - // specified, the default creates local date time. dateTimeFactory: const charts.LocalDateTimeFactory(), ); } diff --git a/frontend/coronavirus_visualizer/lib/src/ui/country_timeline/country_timeline_screen.dart b/frontend/coronavirus_visualizer/lib/src/ui/country_timeline/country_timeline_screen.dart index dbac29b..8f13e41 100644 --- a/frontend/coronavirus_visualizer/lib/src/ui/country_timeline/country_timeline_screen.dart +++ b/frontend/coronavirus_visualizer/lib/src/ui/country_timeline/country_timeline_screen.dart @@ -1,10 +1,7 @@ - - - - import 'package:coronavirus_visualizer/src/bloc/timeline_bloc/bloc.dart'; import 'package:coronavirus_visualizer/src/ui/splash/error_screen.dart'; import 'package:coronavirus_visualizer/src/ui/splash/loading_screen.dart'; +import 'package:coronavirus_visualizer/src/ui/total_timeline/daily_cases_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_circle_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_stats.dart'; @@ -52,6 +49,8 @@ class _CountryTimelineScreenState extends State { children: [ TotalTimelineChartCard(timeline: state.countryTimeline.timeline), SizedBox(height: 15), + DailyCasesChartCard(timeline: state.countryTimeline.timeline), + SizedBox(height: 15), TotalTimelineCircleChartCard(timeline: state.countryTimeline.timeline), SizedBox(height: 15), TotalTimelineStats(timeline: state.countryTimeline.timeline) diff --git a/frontend/coronavirus_visualizer/lib/src/ui/gloabl_timeline/global_timeline_sceen.dart b/frontend/coronavirus_visualizer/lib/src/ui/gloabl_timeline/global_timeline_sceen.dart index 7646660..39ae4e2 100644 --- a/frontend/coronavirus_visualizer/lib/src/ui/gloabl_timeline/global_timeline_sceen.dart +++ b/frontend/coronavirus_visualizer/lib/src/ui/gloabl_timeline/global_timeline_sceen.dart @@ -5,6 +5,7 @@ import 'package:coronavirus_visualizer/src/bloc/timeline_bloc/bloc.dart'; import 'package:coronavirus_visualizer/src/models/global_timeline.dart'; import 'package:coronavirus_visualizer/src/ui/splash/error_screen.dart'; import 'package:coronavirus_visualizer/src/ui/splash/loading_screen.dart'; +import 'package:coronavirus_visualizer/src/ui/total_timeline/daily_cases_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_circle_chart_card.dart'; import 'package:coronavirus_visualizer/src/ui/total_timeline/total_timeline_stats.dart'; @@ -58,6 +59,8 @@ class _GlobalTimelineScreenState extends State { children: [ TotalTimelineChartCard(timeline: globalTimeline.timeline), SizedBox(height: 15), + DailyCasesChartCard(timeline: globalTimeline.timeline), + SizedBox(height: 15), TotalTimelineCircleChartCard(timeline: globalTimeline.timeline), SizedBox(height: 15), TotalTimelineStats(timeline: globalTimeline.timeline) diff --git a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/daily_cases_chart_card.dart b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/daily_cases_chart_card.dart new file mode 100644 index 0000000..6737123 --- /dev/null +++ b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/daily_cases_chart_card.dart @@ -0,0 +1,32 @@ + +import 'package:coronavirus_visualizer/src/models/timeline_item.dart'; +import 'package:coronavirus_visualizer/src/ui/charts/daily_cases_timeline_chart.dart'; +import 'package:coronavirus_visualizer/src/ui/total_timeline/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +class DailyCasesChartCard extends StatelessWidget { + final List timeline; + + DailyCasesChartCard({this.timeline}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(8), + margin: EdgeInsets.all(8), + decoration: defaultGradientDecoration, + child: Column( + children: [ + SizedBox(height: 10), + Text("New cases daily", style: TextStyle(fontFamily: "Baloo", fontSize: 30, color: Colors.white, fontWeight: FontWeight.w600)), + SizedBox(height: 20), + Container( + height: 300, + child: DailyCasesTimeline(timeline, animate: true) + ) + ], + ) + ); + } +} \ No newline at end of file diff --git a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_chart_card.dart b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_chart_card.dart index 993973d..5a7b0e9 100644 --- a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_chart_card.dart +++ b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_chart_card.dart @@ -1,7 +1,6 @@ - - import 'package:coronavirus_visualizer/src/models/timeline_item.dart'; import 'package:coronavirus_visualizer/src/ui/charts/total_timeline_chart.dart'; +import 'package:coronavirus_visualizer/src/ui/total_timeline/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; @@ -15,28 +14,7 @@ class TotalTimelineChartCard extends StatelessWidget { return Container( padding: EdgeInsets.all(8), margin: EdgeInsets.all(8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - gradient: LinearGradient( - colors: [ - const Color(0xFF353535), // yellow sun - const Color(0xFF111111), - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight - ), - boxShadow: [ - BoxShadow( - color: Colors.black, - blurRadius: 20.0, - spreadRadius: 5.0, - offset: Offset( - 10, - 10 - ) - ) - ] - ), + decoration: defaultGradientDecoration, child: Column( children: [ SizedBox(height: 20), diff --git a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_stats.dart b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_stats.dart index e1f1395..e120943 100644 --- a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_stats.dart +++ b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/total_timeline_stats.dart @@ -48,6 +48,7 @@ class TotalTimelineStats extends StatelessWidget { physics: ScrollPhysics(), shrinkWrap: true, crossAxisCount: 2, + childAspectRatio: 1.8, children: [ // new cases and new deaths are only submitted a day before _info("Total cases", timeline.first.totalCases ?? 0), @@ -64,15 +65,13 @@ class TotalTimelineStats extends StatelessWidget { } Widget _info(String text, int amount) { - return Container( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(text, style: TextStyle(fontFamily: "Baloo", fontSize: 20, color: Colors.white, fontWeight: FontWeight.w500)), - SizedBox(height: 10), - Text(amount.toString(), style: TextStyle(fontFamily: "Baloo", fontSize: 25, color: Colors.white, fontWeight: FontWeight.w700)) - ], - ), + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(text, style: TextStyle(fontFamily: "Baloo", fontSize: 20, color: Colors.white, fontWeight: FontWeight.w500)), + SizedBox(height: 10), + Text(amount.toString(), style: TextStyle(fontFamily: "Baloo", fontSize: 25, color: Colors.white, fontWeight: FontWeight.w700)) + ], ); } diff --git a/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/utils.dart b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/utils.dart new file mode 100644 index 0000000..a4d4b24 --- /dev/null +++ b/frontend/coronavirus_visualizer/lib/src/ui/total_timeline/utils.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +final defaultGradientDecoration = BoxDecoration( + borderRadius: BorderRadius.circular(8), + gradient: LinearGradient( + colors: [ + const Color(0xFF353535), // yellow sun + const Color(0xFF111111), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight + ), + boxShadow: [ + BoxShadow( + color: Colors.black, + blurRadius: 20.0, + spreadRadius: 5.0, + offset: Offset( + 10, + 10 + ) + ) + ] +); + \ No newline at end of file