feat: add observable values for charts

feature/chart-progress-page
98spag 2023-05-30 21:03:46 +02:00
parent 1f5b6e18ff
commit cc1ea62d2d
8 changed files with 86 additions and 40 deletions

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.0.27\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.1.10\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.1.6\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2023-05-30 16:44:16.405074","version":"3.10.2"} {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.0.27\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.1.10\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\FUCHSLAU\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.1.6\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2023-05-30 20:39:45.634550","version":"3.10.2"}

View File

@ -1,21 +1,39 @@
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart'; import 'package:percent_indicator/circular_percent_indicator.dart';
class CircularLoadingComponent extends StatelessWidget { class CircularLoadingComponent extends StatelessWidget {
final int eatenCalories; const CircularLoadingComponent({Key? key}) : super(key: key);
const CircularLoadingComponent(this.eatenCalories, {Key? key}) : super(key: key);
final int targetCaolries = 3500; // TODO get from user data final int targetCaolries = 3500; // TODO get from user data
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {;
double progress = double.parse((eatenCalories/targetCaolries).toStringAsFixed(1));
return CircularPercentIndicator( return ValueListenableBuilder(
animation: true, valueListenable: StatisticsService.instance.eatenCalories,
radius: 60.0, builder: (context, value, child) {
lineWidth: 5.0, double progress = double.parse((value / targetCaolries).toStringAsFixed(1));
percent: progress, progress = progress > 1.0 ? 1.0 : progress;
center: Text("${progress*100} %"),
progressColor: Colors.lightGreen, return Column(
); mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularPercentIndicator(
animation: true,
radius: 60.0,
lineWidth: 5.0,
percent: progress,
center: Text(
"$value/$targetCaolries kcal",
textAlign: TextAlign.center,
),
progressColor: Colors.lightGreen,
),
],
);
},
);
} }
} }

View File

@ -16,6 +16,7 @@ class LineCircularWiTextComponent extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double progress = double.parse((value/total).toStringAsFixed(1)); double progress = double.parse((value/total).toStringAsFixed(1));
progress = progress > 1.0 ? 1.0 : progress;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: Column( child: Column(

View File

@ -11,8 +11,8 @@ class StaticsTextComponent extends StatelessWidget {
return Text(name, return Text(name,
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: TextStyle( style: TextStyle(
color: const Color.fromARGB(255, 211, 211, 211), color: const Color(0xff000000),
fontSize: titleOrSecondary ? 14 : 10, fontSize: titleOrSecondary ? 15 : 13,
fontWeight: titleOrSecondary ? FontWeight.w600 : FontWeight.w400 fontWeight: titleOrSecondary ? FontWeight.w600 : FontWeight.w400
)); ));
} }

View File

@ -11,9 +11,7 @@ class StatisticsPercentage extends StatelessWidget {
const StatisticsPercentage({Key? key}) : super(key: key); const StatisticsPercentage({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {;
StatisticsService statisticsService = StatisticsService();
List<double> ingredients = statisticsService.getAllEatenIngredientsForTodayStatistics();
return Container( return Container(
decoration: decoration:
BoxDecoration(border: Border.all(width: 2.0, color: Colors.black)), BoxDecoration(border: Border.all(width: 2.0, color: Colors.black)),
@ -22,28 +20,34 @@ class StatisticsPercentage extends StatelessWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( const Expanded(
child: SizedBox( child: SizedBox(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8), padding: EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: FittedBox( child: FittedBox(
child: CircularLoadingComponent(statisticsService.getAllEatenCaloriesForTodayStatistics()), child: CircularLoadingComponent(),
), ),
), ),
), ),
), ),
Expanded( Expanded(
child: Column( child: ValueListenableBuilder<List<double>>(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, valueListenable: StatisticsService.instance.ingredients,
children: [ builder: (context, value, child) {
// TODO adjust total values (200) to user inputs print(value);
LineCircularWiTextComponent( return Column(
Colors.green.shade400, ingredients[0], 200, "Fat (g)"), mainAxisAlignment: MainAxisAlignment.spaceEvenly,
LineCircularWiTextComponent( children: [
Colors.green.shade400, ingredients[1], 200, "Protein (g)"), // TODO adjust 200 to values from user box
LineCircularWiTextComponent( LineCircularWiTextComponent(
Colors.green.shade400, ingredients[2], 200, "Carbohydrate (g)"), Colors.lightGreen, value[0], 200, "Fat (g)"),
], LineCircularWiTextComponent(
Colors.lightGreen, value[1], 200, "Protein (g)"),
LineCircularWiTextComponent(
Colors.lightGreen, value[2], 200, "Carbohydrate (g)"),
],
);
},
), ),
) )
], ],

View File

@ -18,7 +18,7 @@ class StatisticsPercentComponent extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("$eaten gegessen"), Text("$eaten gegessen"),
CircularLoadingComponent(eaten), const CircularLoadingComponent(),
Text("$calorienBurned verbrannt"), Text("$calorienBurned verbrannt"),
], ],
); );

View File

@ -1,17 +1,28 @@
import 'dart:math'; import 'dart:math';
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart'; import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
import 'package:ernaehrung/android/config/cast_helper.dart'; import 'package:ernaehrung/android/config/cast_helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import '../models/food.dart'; import '../models/food.dart';
class StatisticsService { class StatisticsService {
final String reducedStatisticsBoxName = 'STATISTICS_REDUCED';
final String mainStatisticsBoxName = 'STATISTICS_MAIN';
StatisticsService() { static final StatisticsService _instance = StatisticsService._internal();
factory StatisticsService() => _instance;
static StatisticsService get instance => _instance;
StatisticsService._internal() {
initBoxes(); initBoxes();
} }
final String reducedStatisticsBoxName = 'STATISTICS_REDUCED';
final String mainStatisticsBoxName = 'STATISTICS_MAIN';
ValueNotifier<int> eatenCalories = ValueNotifier<int>(0);
ValueNotifier<List<double>> ingredients = ValueNotifier<List<double>>([0,0,0]);
initBoxes()async{ initBoxes()async{
Box reducedBox = Hive.box(reducedStatisticsBoxName); Box reducedBox = Hive.box(reducedStatisticsBoxName);
putIfKeyNotExists(reducedBox, 'FRÜHSTÜCK', []); putIfKeyNotExists(reducedBox, 'FRÜHSTÜCK', []);
@ -20,6 +31,7 @@ class StatisticsService {
updateReducedBoxByTimespan(TimeSpan.day); updateReducedBoxByTimespan(TimeSpan.day);
} }
void putIfKeyNotExists(Box box, String key, dynamic value) { void putIfKeyNotExists(Box box, String key, dynamic value) {
if (!box.containsKey(key)) { if (!box.containsKey(key)) {
box.put(key, value); box.put(key, value);
@ -47,8 +59,15 @@ class StatisticsService {
} }
break; break;
} }
updateCalculationsAndNotfiyListeners();
} }
void updateCalculationsAndNotfiyListeners(){
eatenCalories.value = getAllEatenCaloriesForTodayStatistics();
eatenCalories.notifyListeners();
ingredients.value = getAllEatenIngredientsForTodayStatistics();
ingredients.notifyListeners();
}
void getNewFoodAndUpdateReducedBoxByTimestamp(int timestamp){ void getNewFoodAndUpdateReducedBoxByTimestamp(int timestamp){
Map<String,List<Food>> newFood = getFoodMapForGivenTimestampFromMainBox(timestamp); Map<String,List<Food>> newFood = getFoodMapForGivenTimestampFromMainBox(timestamp);
if(newFood.keys.isNotEmpty){ if(newFood.keys.isNotEmpty){
@ -78,6 +97,7 @@ class StatisticsService {
box.put(box.keys.elementAt(i), []); box.put(box.keys.elementAt(i), []);
} }
} }
setElementsOfReducedBox(Map<String,List<Food>> newFood){ setElementsOfReducedBox(Map<String,List<Food>> newFood){
Box box = Hive.box(reducedStatisticsBoxName); Box box = Hive.box(reducedStatisticsBoxName);
Iterable<String> keys = newFood.keys; Iterable<String> keys = newFood.keys;
@ -186,8 +206,8 @@ class StatisticsService {
for(int i = 0; i < box.keys.length;i++){ for(int i = 0; i < box.keys.length;i++){
for(Food food in box.get(box.keys.elementAt(i))){ for(Food food in box.get(box.keys.elementAt(i))){
fat += food.fatg; fat += food.fatg;
protein = food.proteing; protein += food.proteing;
carbs = food.carbohydrateg; carbs += food.carbohydrateg;
} }
} }
return [fat as double,protein as double,carbs as double]; return [fat as double,protein as double,carbs as double];
@ -220,8 +240,6 @@ class StatisticsService {
return sum; return sum;
} }
showItems(){ showItems(){
print("Statistics.dart - showItems() - ITEMS"); print("Statistics.dart - showItems() - ITEMS");
//Hive.box(boxName).clear(); //Hive.box(boxName).clear();

View File

@ -1,3 +1,5 @@
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:ernaehrung/android/pages/nav_pages/progress_page.dart'; import 'package:ernaehrung/android/pages/nav_pages/progress_page.dart';
import 'package:ernaehrung/android/pages/nav_pages/today_page.dart'; import 'package:ernaehrung/android/pages/nav_pages/today_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -22,6 +24,9 @@ class MainPageState extends State<MainPage> {
void onTap(int index) { void onTap(int index) {
setState(() { setState(() {
currentIndex = index; currentIndex = index;
if(currentIndex == 1){
StatisticsService.instance.updateReducedBoxByTimespan(TimeSpan.day);
}
pages[currentIndex]; pages[currentIndex];
}); });
} }