223 lines
6.3 KiB
Dart
223 lines
6.3 KiB
Dart
import 'package:flisp_app/models/flisp.dart';
|
|
import 'package:flisp_app/models/todo.dart';
|
|
import 'package:flisp_app/service/flisp_service.dart';
|
|
import 'package:flisp_app/service/todo_service.dart';
|
|
import 'package:flisp_app/widgets/flisp_widget.dart';
|
|
import 'package:flisp_app/widgets/todo_widget.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_common/models/common_model.dart';
|
|
import 'package:flutter_common/widget/chart.dart';
|
|
import 'package:flutter_common/widget/common_widget.dart';
|
|
import 'package:flutter_common/widget/year_selector.dart';
|
|
|
|
class StatsPage extends StatefulWidget {
|
|
const StatsPage({super.key});
|
|
|
|
@override
|
|
StatsPageState createState() => StatsPageState();
|
|
}
|
|
|
|
class StatsPageState extends State<StatsPage> {
|
|
final double chartHeight = 400;
|
|
final double statsHeight = 120;
|
|
int currentYear = DateTime.now().year;
|
|
final FlispService flispService = FlispService();
|
|
final TodoService todoService = TodoService();
|
|
|
|
late List<Flisp> allFlisps;
|
|
late List<Todo> allTodos;
|
|
late List<ChartData> flispMonthlyStats;
|
|
late List<ChartData> flispCategoryStats;
|
|
late List<ChartData> todoMonthlyStats;
|
|
late List<ChartData> todoMonthlyCompleteStats;
|
|
late List<ChartData> todoPriorityStats;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
refreshStats();
|
|
}
|
|
|
|
void refreshStats() {
|
|
allFlisps = flispService.getAllFlispsByYear(currentYear);
|
|
getFlispMonthlyStats(allFlisps);
|
|
getFlispCategoryStats(allFlisps);
|
|
|
|
allTodos = todoService.getAllTodosByYear(currentYear);
|
|
getTodoMonthlyStats(allTodos);
|
|
getTodoMonthlyCompleteStats(allTodos);
|
|
getTodoCategoryStats(allTodos);
|
|
}
|
|
|
|
void getFlispMonthlyStats(List<Flisp> flisps) {
|
|
Map<String, double> countMap = {};
|
|
|
|
for (var flisp in flisps) {
|
|
String month = '${flisp.createTime.month}月';
|
|
countMap[month] = (countMap[month] ?? 0) + 1;
|
|
}
|
|
|
|
flispMonthlyStats = convert2ChartData(countMap);
|
|
}
|
|
|
|
void getFlispCategoryStats(List<Flisp> flisps) {
|
|
Map<String, double> countMap = {};
|
|
|
|
for (var flisp in flisps) {
|
|
String category = flisp.tag.label;
|
|
countMap[category] = (countMap[category] ?? 0) + 1;
|
|
}
|
|
|
|
flispCategoryStats = convert2ChartData(countMap);
|
|
}
|
|
|
|
void getTodoMonthlyStats(List<Todo> todos) {
|
|
Map<String, double> countMap = {};
|
|
|
|
for (var todo in todos) {
|
|
String month = '${todo.createTime.month}月';
|
|
countMap[month] = (countMap[month] ?? 0) + 1;
|
|
}
|
|
|
|
todoMonthlyStats = convert2ChartData(countMap);
|
|
}
|
|
|
|
void getTodoMonthlyCompleteStats(List<Todo> todos) {
|
|
Map<String, double> countMap = {};
|
|
|
|
for (var todo in todos) {
|
|
if (todo.isCompleted) {
|
|
String month = '${todo.createTime.month}月';
|
|
countMap[month] = (countMap[month] ?? 0) + 1;
|
|
}
|
|
}
|
|
|
|
todoMonthlyCompleteStats = convert2ChartData(countMap);
|
|
}
|
|
|
|
void getTodoCategoryStats(List<Todo> todos) {
|
|
Map<String, double> countMap = {};
|
|
|
|
for (var todo in todos) {
|
|
String priority = todo.priority.label;
|
|
countMap[priority] = (countMap[priority] ?? 0) + 1;
|
|
}
|
|
|
|
todoPriorityStats = convert2ChartData(countMap);
|
|
}
|
|
|
|
List<ChartData> convert2ChartData(Map<String, double> countMap) {
|
|
return countMap.entries
|
|
.map((e) => ChartData(name: e.key, value: e.value))
|
|
.toList();
|
|
}
|
|
|
|
Widget _buildFlispStats(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Icon(Icons.analytics, color: Theme.of(context).colorScheme.primary),
|
|
const SizedBox(width: 3),
|
|
const Text('闪灵统计'),
|
|
],
|
|
),
|
|
const SizedBox(height: 5),
|
|
buildFlispStatsCard(context, allFlisps),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildTodoStats(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Icon(Icons.analytics, color: Theme.of(context).colorScheme.primary),
|
|
const SizedBox(width: 3),
|
|
const Text('待办统计'),
|
|
],
|
|
),
|
|
const SizedBox(height: 5),
|
|
Expanded(child: buildTodoStatsCard(context, allTodos)),
|
|
],
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
children: [
|
|
YearSelector(
|
|
currentYear: DateTime.now().year,
|
|
onYearChanged:
|
|
(year) => {
|
|
setState(() {
|
|
currentYear = year;
|
|
refreshStats();
|
|
}),
|
|
},
|
|
),
|
|
SizedBox(height: statsHeight, child: _buildFlispStats(context)),
|
|
SizedBox(height: 10),
|
|
SizedBox(height: statsHeight, child: _buildTodoStats(context)),
|
|
SizedBox(height: 10),
|
|
SizedBox(
|
|
height: chartHeight,
|
|
child: CommonCard(
|
|
child: LineChart(
|
|
title: '每月闪灵数量统计',
|
|
xAxisName: '月份',
|
|
yAxisName: '数量',
|
|
unit: '篇',
|
|
data: flispMonthlyStats,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(
|
|
height: chartHeight,
|
|
child: CommonCard(
|
|
child: PieChart(
|
|
title: '闪灵分类统计',
|
|
unit: '篇',
|
|
data: flispCategoryStats,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(
|
|
height: chartHeight,
|
|
child: CommonCard(
|
|
child: DoubleBarChart(
|
|
title: '每月待办数量统计',
|
|
xAxisName: '月份',
|
|
yAxisName: '数量',
|
|
unit: '个',
|
|
data1: todoMonthlyStats,
|
|
data2: todoMonthlyCompleteStats,
|
|
series1Name: '总数',
|
|
series2Name: '完成数',
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(
|
|
height: chartHeight,
|
|
child: CommonCard(
|
|
child: PieChart(
|
|
title: '待办分类统计',
|
|
unit: '个',
|
|
data: todoPriorityStats,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|