diff --git a/android/app/build.gradle b/android/app/build.gradle index 1a3e4b3..f3dd888 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -37,7 +37,7 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.corona_app" minSdkVersion 16 targetSdkVersion 28 @@ -47,7 +47,6 @@ android { buildTypes { release { - // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } diff --git a/lib/src/data/corona_api.dart b/lib/src/data/corona_api.dart index 4e1af82..76cbe92 100644 --- a/lib/src/data/corona_api.dart +++ b/lib/src/data/corona_api.dart @@ -10,12 +10,12 @@ Future fetchData(String country) async { Map last8Days; if (country == "Worldwide") { response = await http.get(apiUrl + "/all?allowNull=true"); - last8DaysResponse = await http.get(apiUrl + "/historical/all?lastdays=8"); + last8DaysResponse = await http.get(apiUrl + "/historical/all?lastdays=4"); last8Days = json.decode(last8DaysResponse.body); } else { response = await http.get(apiUrl + "/countries/$country"); last8DaysResponse = - await http.get(apiUrl + "/historical/$country?lastdays=8"); + await http.get(apiUrl + "/historical/$country?lastdays=4"); last8Days = json.decode(last8DaysResponse.body)["timeline"]; } return CoronaData.fromMap(json.decode(response.body), last8Days); diff --git a/lib/src/models/chart_model.dart b/lib/src/models/chart_model.dart new file mode 100644 index 0000000..61a5357 --- /dev/null +++ b/lib/src/models/chart_model.dart @@ -0,0 +1,5 @@ +class ChartsModel { + DateTime date; + int value; + ChartsModel(this.date, this.value); +} diff --git a/lib/src/models/corona_data.dart b/lib/src/models/corona_data.dart index 60e50ec..5245727 100644 --- a/lib/src/models/corona_data.dart +++ b/lib/src/models/corona_data.dart @@ -1,3 +1,7 @@ +import 'package:corona_app/src/models/chart_model.dart'; +import 'package:intl/intl.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + class CoronaData { String name; String flag; @@ -9,9 +13,9 @@ class CoronaData { int todayRecovered; int active; int critical; - List last8DaysCases = []; - List last8DaysDeaths = []; - List last8DaysRecovered = []; + List last8DaysCases = []; + List last8DaysDeaths = []; + List last8DaysRecovered = []; CoronaData.fromMap( Map rawjson, Map last8Days) { @@ -31,13 +35,76 @@ class CoronaData { Map lastDeaths = last8Days["deaths"]; Map lastRecovered = last8Days["recovered"]; lastCases.forEach((key, value) { - last8DaysCases.add(lastCases[key]); + last8DaysCases + .add(ChartsModel(DateFormat("M/d/yy").parse(key), lastCases[key])); }); lastDeaths.forEach((key, value) { - last8DaysDeaths.add(lastDeaths[key]); + last8DaysDeaths + .add(ChartsModel(DateFormat("M/d/yy").parse(key), lastDeaths[key])); }); lastRecovered.forEach((key, value) { - last8DaysRecovered.add(lastRecovered[key]); + last8DaysRecovered.add( + ChartsModel(DateFormat("M/d/yy").parse(key), lastRecovered[key])); }); } + + List> createCasesChartSeries() { + return [ + charts.Series( + id: "Cases", + colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, + domainFn: (chart, _) => chart.date, + measureFn: (chart, _) => chart.value, + data: last8DaysCases, + ) + ]; + } + + List> createDeathsChartSeries() { + return [ + charts.Series( + id: "Deaths", + colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, + domainFn: (chart, _) => chart.date, + measureFn: (chart, _) => chart.value, + data: last8DaysDeaths, + ) + ]; + } + + List> createRecoveredChartSeries() { + return [ + charts.Series( + id: "Recovered", + colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, + domainFn: (chart, _) => chart.date, + measureFn: (chart, _) => chart.value, + data: last8DaysRecovered, + ) + ]; + } + + String get recoveredPercentage { + return (last8DaysRecovered[last8DaysRecovered.length - 1].value / + last8DaysRecovered[last8DaysRecovered.length - 2].value * + 100 - + 100) + .toStringAsFixed(2); + } + + String get deathPercentage { + return (last8DaysDeaths[last8DaysDeaths.length - 1].value / + last8DaysDeaths[last8DaysDeaths.length - 2].value * + 100 - + 100) + .toStringAsFixed(2); + } + + String get casesPercentage { + return (last8DaysCases[last8DaysCases.length - 1].value / + last8DaysCases[last8DaysCases.length - 2].value * + 100 - + 100) + .toStringAsFixed(2); + } } diff --git a/lib/src/screens/main_screen.dart b/lib/src/screens/main_screen.dart index ed86eda..168f142 100644 --- a/lib/src/screens/main_screen.dart +++ b/lib/src/screens/main_screen.dart @@ -12,8 +12,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; -//TODO: Instructions -//TODO: Graphs and percentages +//TODO: percentages class MainScreen extends StatefulWidget { static final String routeName = "/main-screen"; diff --git a/lib/src/widgets/bottomNavBarPages/home_body.dart b/lib/src/widgets/bottomNavBarPages/home_body.dart index 8a0b7a9..b25dc5f 100644 --- a/lib/src/widgets/bottomNavBarPages/home_body.dart +++ b/lib/src/widgets/bottomNavBarPages/home_body.dart @@ -4,6 +4,7 @@ import 'package:corona_app/src/data/corona_api.dart'; import 'package:corona_app/src/models/corona_data.dart'; import 'package:corona_app/src/models/profile.dart'; import 'package:corona_app/src/providers/user_provider.dart'; +import 'package:corona_app/src/widgets/chart.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; @@ -212,13 +213,19 @@ class _HomeBodyState extends State { ), ), ), - Padding( - padding: EdgeInsets.only(top: 5.0), - child: Image( - width: 125, - height: 37.5, - image: - AssetImage("assets/images/closed_graph.png"), + Transform.scale( + scale: 1.2, + child: Transform.translate( + offset: const Offset(-10, -10), + child: Padding( + padding: EdgeInsets.only(bottom: 2.0), + child: SizedBox( + width: 130, + height: 37.5, + child: + Chart(data.createRecoveredChartSeries()), + ), + ), ), ), ], @@ -284,7 +291,7 @@ class _HomeBodyState extends State { Column( children: [ Text( - "+12%", + data.recoveredPercentage + "%", style: TextStyle( fontFamily: "WorkSansMedium", fontSize: 20.0, @@ -343,13 +350,18 @@ class _HomeBodyState extends State { ), ), ), - Padding( - padding: EdgeInsets.only(top: 5.0), - child: Image( - width: 125, - height: 37.5, - image: - AssetImage("assets/images/death_graph.png"), + Transform.scale( + scale: 1.2, + child: Transform.translate( + offset: const Offset(-10, -10), + child: Padding( + padding: EdgeInsets.only(bottom: 2.0), + child: SizedBox( + width: 130, + height: 37.5, + child: Chart(data.createDeathsChartSeries()), + ), + ), ), ), ], @@ -374,7 +386,7 @@ class _HomeBodyState extends State { Column( children: [ Text( - "+12.6%", + data.deathPercentage + "%", style: TextStyle( fontFamily: "WorkSansMedium", fontSize: 20.0, @@ -474,13 +486,18 @@ class _HomeBodyState extends State { ), ), ), - Padding( - padding: EdgeInsets.only(top: 5.0), - child: Image( - width: 125, - height: 37.5, - image: - AssetImage("assets/images/active_graph.png"), + Transform.scale( + scale: 1.2, + child: Transform.translate( + offset: const Offset(-10, -10), + child: Padding( + padding: EdgeInsets.only(bottom: 2.0), + child: SizedBox( + width: 130, + height: 37.5, + child: Chart(data.createCasesChartSeries()), + ), + ), ), ), ], @@ -505,7 +522,7 @@ class _HomeBodyState extends State { Column( children: [ Text( - "+25.7%", + data.casesPercentage + "%", style: TextStyle( fontFamily: "WorkSansMedium", fontSize: 20.0, diff --git a/lib/src/widgets/bottomNavBarPages/tasks_body.dart b/lib/src/widgets/bottomNavBarPages/tasks_body.dart index db44e8a..f0c4575 100644 --- a/lib/src/widgets/bottomNavBarPages/tasks_body.dart +++ b/lib/src/widgets/bottomNavBarPages/tasks_body.dart @@ -3,7 +3,6 @@ import 'package:corona_app/src/providers/user_provider.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -//TODO: REFRESH EVERY 24 HOURS class TasksBody extends StatelessWidget { @override Widget build(BuildContext context) { diff --git a/lib/src/widgets/chart.dart b/lib/src/widgets/chart.dart new file mode 100644 index 0000000..c66bf2e --- /dev/null +++ b/lib/src/widgets/chart.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + +class Chart extends StatelessWidget { + final List seriesList; + final bool animate; + Chart(this.seriesList, {this.animate: false}); + @override + Widget build(BuildContext context) { + return charts.TimeSeriesChart( + seriesList, + animate: animate, + dateTimeFactory: const charts.LocalDateTimeFactory(), + primaryMeasureAxis: charts.NumericAxisSpec( + tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false), + renderSpec: charts.NoneRenderSpec(), + ), + domainAxis: charts.DateTimeAxisSpec(renderSpec: charts.NoneRenderSpec()), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 4f6ce6d..56179cf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -29,6 +29,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.3" + charts_common: + dependency: transitive + description: + name: charts_common + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0" + charts_flutter: + dependency: "direct main" + description: + name: charts_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0" clock: dependency: transitive description: @@ -114,6 +128,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7e14af2..6ffe365 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: intl: ^0.16.1 webview_flutter: ^0.3.22+1 url_launcher: ^5.5.0 + charts_flutter: ^0.9.0 dev_dependencies: flutter_test: diff --git a/test/last_8_days_test.dart b/test/last_8_days_test.dart index 29dcf45..2ae2c78 100644 --- a/test/last_8_days_test.dart +++ b/test/last_8_days_test.dart @@ -1,16 +1,17 @@ import 'package:corona_app/src/data/corona_api.dart'; +import 'package:corona_app/src/models/chart_model.dart'; import 'package:corona_app/src/models/corona_data.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { test("Testing Last 8 days data for Worldwide", () async { CoronaData data = await fetchData("Worldwide"); - print(data.last8DaysCases); - expect(data.last8DaysCases is List, true); + print(data.last8DaysCases[0].date); + expect(data.last8DaysCases is List, true); }); test("Testing Last 8 days data for a Country", () async { CoronaData data = await fetchData("USA"); - print(data.last8DaysCases); - expect(data.last8DaysCases is List, true); + print(data.last8DaysCases[0].date); + expect(data.last8DaysCases is List, true); }); }