main
1import 'package:blood_pressure_app/data_util/repository_builder.dart';
2import 'package:blood_pressure_app/features/data_picker/interval_picker.dart';
3import 'package:blood_pressure_app/features/statistics/blood_pressure_distribution.dart';
4import 'package:blood_pressure_app/features/statistics/clock_bp_graph.dart';
5import 'package:blood_pressure_app/l10n/app_localizations.dart';
6import 'package:blood_pressure_app/model/blood_pressure_analyzer.dart';
7import 'package:blood_pressure_app/model/storage/interval_store.dart';
8import 'package:flutter/material.dart';
9import 'package:health_data_store/health_data_store.dart';
10import 'package:provider/provider.dart';
11
12/// A page that shows statistics about stored blood pressure values.
13class StatisticsScreen extends StatefulWidget {
14 /// Create a screen to various display statistics.
15 const StatisticsScreen({super.key});
16
17 @override
18 State<StatisticsScreen> createState() => _StatisticsScreenState();
19}
20
21class _StatisticsScreenState extends State<StatisticsScreen> {
22 @override
23 Widget build(BuildContext context) {
24 final localizations = AppLocalizations.of(context)!;
25 return Scaffold(
26 appBar: AppBar(
27 title: Text(localizations.statistics),
28 ),
29 body: RepositoryBuilder<BloodPressureRecord, BloodPressureRepository>(
30 rangeType: IntervalStoreManagerLocation.statsPage,
31 onData: (context, records) {
32 final manager = context.watch<IntervalStoreManager>();
33 final timeLimitRange = manager.get(IntervalStoreManagerLocation.statsPage)
34 .timeLimitRange;
35 if (timeLimitRange != null) {
36 records = records.where((r) {
37 final time = TimeOfDay.fromDateTime(r.time);
38 return time.isAfter(timeLimitRange.start) && time.isBefore(timeLimitRange.end);
39 }).toList();
40 }
41 final analyzer = BloodPressureAnalyser(records.toList());
42 return ListView(
43 children: [
44 _buildSubTitle(localizations.statistics,),
45 ListTile(
46 title: Text(localizations.measurementCount),
47 trailing: Text(
48 records.length.toString(),
49 style: Theme.of(context).textTheme.headlineSmall,
50 ),
51 ),
52 ListTile(
53 title: Text(localizations.measurementsPerDay),
54 trailing: Text(
55 analyzer.measurementsPerDay?.toString() ?? '-',
56 style: Theme.of(context).textTheme.headlineSmall,
57 ),
58 ),
59 _buildSubTitle(localizations.valueDistribution,),
60 Container(
61 height: 260,
62 padding: const EdgeInsets.symmetric(horizontal: 16.0),
63 child: BloodPressureDistribution(
64 records: records,
65 ),
66 ),
67 _buildSubTitle(localizations.timeResolvedMetrics),
68 ClockBpGraph(measurements: records),
69 ],
70 );
71 },
72 ),
73 persistentFooterButtons: [Container(
74 height: 76.0,
75 margin: const EdgeInsets.only(top: 8.0, bottom: 6.0),
76 child: const IntervalPicker(type: IntervalStoreManagerLocation.statsPage,),
77 )],
78 );
79 }
80
81 Widget _buildSubTitle(String text) => ListTile(
82 contentPadding: EdgeInsets.zero,
83 title: Text(
84 text,
85 style: Theme.of(context).textTheme.titleLarge!,
86 ),
87 );
88}