first commit
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// 一个扇区
|
||||
class DonutSlice {
|
||||
final double value;
|
||||
final Color color;
|
||||
final String label;
|
||||
|
||||
const DonutSlice({required this.value, required this.color, this.label = ''});
|
||||
}
|
||||
|
||||
/// 图表配色:以主题橙棕/金色为主,穿插少量对比色便于区分分类
|
||||
const List<Color> kChartPalette = [
|
||||
Color(0xFFC8956E), // 橙棕(主色)
|
||||
Color(0xFFFFB74D), // 亮橙
|
||||
Color(0xFFE57373), // 红
|
||||
Color(0xFF81C784), // 绿
|
||||
Color(0xFF64B5F6), // 蓝
|
||||
Color(0xFFBA68C8), // 紫
|
||||
Color(0xFF4DB6AC), // 青
|
||||
Color(0xFFF06292), // 粉
|
||||
Color(0xFFA1887F), // 棕灰
|
||||
Color(0xFF90A4AE), // 蓝灰
|
||||
];
|
||||
|
||||
Color chartColorAt(int index) => kChartPalette[index % kChartPalette.length];
|
||||
|
||||
/// 通用环形图(首页预算环 + 统计页分类饼图共用)
|
||||
///
|
||||
/// 内部处理了 fl_chart 的空数据问题:`PieChartSectionData.value` 必须 > 0,
|
||||
/// 全 0 / NaN 会算出 NaN 角度导致渲染异常甚至崩溃,所以这里统一过滤并兜底成灰环。
|
||||
/// fl_chart 类型只出现在本文件,升级图表库时只需改这一处。
|
||||
class DonutChart extends StatelessWidget {
|
||||
const DonutChart({
|
||||
super.key,
|
||||
required this.slices,
|
||||
this.size = 150,
|
||||
this.centerSpaceRadius = 46,
|
||||
this.sectionsSpace = 2,
|
||||
this.center,
|
||||
});
|
||||
|
||||
final List<DonutSlice> slices;
|
||||
final double size;
|
||||
final double centerSpaceRadius;
|
||||
final double sectionsSpace;
|
||||
|
||||
/// 圆心内容,例如 Text('68%')
|
||||
final Widget? center;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final valid = slices.where((s) => s.value.isFinite && s.value > 0).toList();
|
||||
// 无有效数据时退化为单段灰环,避免空数据渲染问题
|
||||
final effective = valid.isEmpty
|
||||
? const [DonutSlice(value: 1, color: Color(0xFFE0C9A6))]
|
||||
: valid;
|
||||
|
||||
final ringRadius = (size / 2 - centerSpaceRadius).clamp(8.0, double.infinity);
|
||||
|
||||
return SizedBox(
|
||||
width: size,
|
||||
height: size,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
PieChart(
|
||||
PieChartData(
|
||||
sections: effective
|
||||
.map((s) => PieChartSectionData(
|
||||
value: s.value,
|
||||
color: s.color,
|
||||
radius: ringRadius,
|
||||
showTitle: false,
|
||||
))
|
||||
.toList(),
|
||||
centerSpaceRadius: centerSpaceRadius,
|
||||
sectionsSpace: sectionsSpace,
|
||||
),
|
||||
),
|
||||
?center,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user