import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; class SegmentData { final Color color; final double value; SegmentData({required this.color, required this.value}); } class SegmentedCirclePainter extends CustomPainter { final List segments; final double strokeWidth; final double gapAngle; // 每段之间的间隔角度(单位:度) SegmentedCirclePainter({ required this.segments, this.strokeWidth = 6.0, this.gapAngle = 4.0, }); @override void paint(Canvas canvas, Size size) { final double radius = size.width / 2; final Offset center = Offset(size.width / 2, size.height / 2); final Paint paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = strokeWidth ..strokeCap = StrokeCap.square; final double totalValue = segments.fold(0, (sum, item) => sum + item.value); final double totalGap = gapAngle * segments.length; final double totalDrawAngle = 360.0 - totalGap; double startAngle = -90.0; // 从顶部开始 for (var segment in segments) { final double sweepAngle = (segment.value / totalValue) * totalDrawAngle; paint.color = segment.color; canvas.drawArc( Rect.fromCircle(center: center, radius: radius - strokeWidth / 2), radians(startAngle), radians(sweepAngle), false, paint, ); startAngle += sweepAngle + gapAngle; } } double radians(double degrees) => degrees * 3.1415926 / 180; @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; } class SegmentedCircleWithCenterWidget extends StatelessWidget { final List segments; final double strokeWidth; final double gapAngle; final Widget centerWidget; final int trend; const SegmentedCircleWithCenterWidget({ Key? key, required this.segments, this.strokeWidth = 6.0, this.gapAngle = 4.0, required this.centerWidget, required this.trend, }) : super(key: key); @override Widget build(BuildContext context) { return Stack( alignment: Alignment.center, children: [ CustomPaint( size: Size(200, 200), // 设置圆的尺寸 painter: SegmentedCirclePainter( segments: segments, strokeWidth: strokeWidth, gapAngle: gapAngle, ), ), centerWidget, // 放置自定义的中心 Widget Positioned( bottom: 140.rpx, right: 50.rpx, // 放置在右侧 child: SvgPicture.asset( _getTrendIcon(trend), width: trend != 0 ? 14.rpx : 18.rpx, height: trend != 0 ? 22.rpx : 6.rpx, // color: themeController.currentColor.sc9, ), ), ], ); } String _getTrendIcon(int? trend) { switch (trend) { case 0: return 'assets/img/icon/score_equal.svg'; case 1: return 'assets/img/icon/score_up.svg'; default: return 'assets/img/icon/score_down.svg'; } } }