diff --git a/lib/layout/main_screen.dart b/lib/layout/main_screen.dart index 026ba76..eaf1ba5 100644 --- a/lib/layout/main_screen.dart +++ b/lib/layout/main_screen.dart @@ -127,7 +127,7 @@ class _MainScreenState extends State { } String _getAppBarTitle(int index) { - final titles = {0: '闪灵', 1: '待办', 2: '日程'}; + final titles = {0: '闪灵', 1: '待办', 2: '日程', 3: '统计'}; return titles[index] ?? '闪灵'; } } diff --git a/lib/pages/stats_page.dart b/lib/pages/stats_page.dart index 79780b2..a129c5b 100644 --- a/lib/pages/stats_page.dart +++ b/lib/pages/stats_page.dart @@ -4,6 +4,9 @@ import 'package:flisp_app/service/flisp_service.dart'; import 'package:flisp_app/service/todo_service.dart'; import 'package:flisp_app/widgets/chart.dart'; import 'package:flisp_app/widgets/common.dart'; +import 'package:flisp_app/widgets/flisp_widget.dart'; +import 'package:flisp_app/widgets/stats.dart'; +import 'package:flisp_app/widgets/todo_widget.dart'; import 'package:flutter/material.dart'; class StatsPage extends StatefulWidget { @@ -15,9 +18,12 @@ class StatsPage extends StatefulWidget { class StatsPageState extends State { final double chartHeight = 400; + final double statsHeight = 160; final FlispService flispService = FlispService(); final TodoService todoService = TodoService(); + late List allFlisps; + late List allTodos; late List flispMonthlyStats; late List flispCategoryStats; late List todoMonthlyStats; @@ -27,11 +33,11 @@ class StatsPageState extends State { @override void initState() { super.initState(); - final allFlisps = flispService.getAllFlisps(); + allFlisps = flispService.getAllFlisps(); getFlispMonthlyStats(allFlisps); getFlispCategoryStats(allFlisps); - final allTodos = todoService.getAllTodos(); + allTodos = todoService.getAllTodos(); getTodoMonthlyStats(allTodos); getTodoMonthlyCompleteStats(allTodos); getTodoCategoryStats(allTodos); @@ -100,10 +106,22 @@ class StatsPageState extends State { .toList(); } + Widget _buildFlispStats(BuildContext context) { + return Column( + children: [ + buildChartTitle(context, '闪灵统计', Icons.analytics), + const SizedBox(height: 3), + buildChartDivider(context), + const SizedBox(height: 3), + Expanded(child: buildFlispStatsCard(allFlisps)), + ], + ); + } + Widget _buildFlispMonthlyStats(BuildContext context) { return Column( children: [ - buildChartTitle(context, '每月闪灵数量统计'), + buildChartTitle(context, '每月闪灵数量统计', Icons.show_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), @@ -123,7 +141,7 @@ class StatsPageState extends State { Widget _buildFlispCategoryStats(BuildContext context) { return Column( children: [ - buildChartTitle(context, '闪灵分类统计'), + buildChartTitle(context, '闪灵分类统计', Icons.pie_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), @@ -138,10 +156,22 @@ class StatsPageState extends State { ); } + Widget _buildTodoStats(BuildContext context) { + return Column( + children: [ + buildChartTitle(context, '待办统计', Icons.analytics), + const SizedBox(height: 3), + buildChartDivider(context), + const SizedBox(height: 3), + Expanded(child: buildTodoStatsCard(allTodos)), + ], + ); + } + Widget _buildTodoMonthlyStats(BuildContext context) { return Column( children: [ - buildChartTitle(context, '每月待办数量统计'), + buildChartTitle(context, '每月待办数量统计', Icons.bar_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), @@ -164,7 +194,7 @@ class StatsPageState extends State { Widget _buildTodoPriorityStats(BuildContext context) { return Column( children: [ - buildChartTitle(context, '待办分类统计'), + buildChartTitle(context, '待办分类统计', Icons.pie_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), @@ -182,6 +212,16 @@ class StatsPageState extends State { padding: EdgeInsets.all(10), child: Column( children: [ + SizedBox( + height: statsHeight, + child: BuildCard(child: _buildFlispStats(context)), + ), + SizedBox(height: 10), + SizedBox( + height: statsHeight, + child: BuildCard(child: _buildTodoStats(context)), + ), + SizedBox(height: 10), SizedBox( height: chartHeight, child: BuildCard(child: _buildFlispMonthlyStats(context)), diff --git a/lib/widgets/chart.dart b/lib/widgets/chart.dart index 550fd78..85eacf6 100644 --- a/lib/widgets/chart.dart +++ b/lib/widgets/chart.dart @@ -8,10 +8,10 @@ class ChartData { ChartData({required this.name, required this.value}); } -Widget buildChartTitle(BuildContext context, String title) { +Widget buildChartTitle(BuildContext context, String title, IconData icon) { return Row( children: [ - Icon(Icons.insert_chart, color: Theme.of(context).colorScheme.primary), + Icon(icon, color: Theme.of(context).colorScheme.primary), Text(title), ], ); @@ -101,10 +101,7 @@ Widget barChart({ }) { return SfCartesianChart( // X轴配置(类别轴) - primaryXAxis: CategoryAxis( - majorGridLines: MajorGridLines(width: 0), - title: AxisTitle(text: xAxisName), - ), + primaryXAxis: CategoryAxis(majorGridLines: MajorGridLines(width: 0)), // Y轴配置(数值轴) // primaryYAxis: NumericAxis(title: AxisTitle(text: '$yAxisName($unit)')), @@ -164,10 +161,7 @@ Widget doubleBarChart({ }) { return SfCartesianChart( // X轴配置(类别轴) - primaryXAxis: CategoryAxis( - majorGridLines: const MajorGridLines(width: 0), - title: AxisTitle(text: xAxisName), - ), + primaryXAxis: CategoryAxis(majorGridLines: const MajorGridLines(width: 0)), // Y轴配置(数值轴) // primaryYAxis: NumericAxis(title: AxisTitle(text: '$yAxisName($unit)')), diff --git a/lib/widgets/flisp_widget.dart b/lib/widgets/flisp_widget.dart index 086e4aa..1946a48 100644 --- a/lib/widgets/flisp_widget.dart +++ b/lib/widgets/flisp_widget.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:toggle_switch/toggle_switch.dart'; -Widget buildStatsCard(List flisps) { +Widget buildFlispStatsCard(List flisps) { int totalCount = flisps.length; int lifeCount = flisps.where((flisp) => flisp.tag == FlispTag.life).length; diff --git a/lib/widgets/stats.dart b/lib/widgets/stats.dart new file mode 100644 index 0000000..a0d9ed3 --- /dev/null +++ b/lib/widgets/stats.dart @@ -0,0 +1,54 @@ +import 'package:flisp_app/widgets/common.dart'; +import 'package:flutter/material.dart'; + +class StatisticCard extends StatelessWidget { + final IconData icon; + final Color color; + final String title; + final num value; + final String unit; + + const StatisticCard({ + super.key, + required this.icon, + required this.color, + required this.title, + required this.value, + required this.unit, + }); + + @override + Widget build(BuildContext context) { + return BuildCard( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 40, + height: 40, + child: Icon(icon, color: color, size: 40), + ), + const SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(title, style: TextStyle(fontSize: 20, color: color)), + const SizedBox(height: 4), + Row( + children: [ + Text( + value.toString(), + style: TextStyle(fontSize: 20, color: color), + ), + const SizedBox(width: 5), + Text(unit, style: TextStyle(fontSize: 20, color: color)), + ], + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/widgets/todo_widget.dart b/lib/widgets/todo_widget.dart index 46b323a..b6a61a4 100644 --- a/lib/widgets/todo_widget.dart +++ b/lib/widgets/todo_widget.dart @@ -3,10 +3,9 @@ import 'package:flisp_app/utils/todo_utils.dart'; import 'package:flisp_app/widgets/common.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:toggle_switch/toggle_switch.dart'; // 统计卡片 -Widget buildStatsCard(List todos) { +Widget buildTodoStatsCard(List todos) { int totalCount = todos.length; int activeCount = todos.where((todo) => !todo.isCompleted).length;