更新
This commit is contained in:
102
lib/pages/sleep_report/component/SegmentedCirclePainter.dart
Normal file
102
lib/pages/sleep_report/component/SegmentedCirclePainter.dart
Normal file
@@ -0,0 +1,102 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
|
||||
class SegmentData {
|
||||
final Color color;
|
||||
final double value;
|
||||
|
||||
SegmentData({required this.color, required this.value});
|
||||
}
|
||||
|
||||
class SegmentedCirclePainter extends CustomPainter {
|
||||
final List<SegmentData> 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<SegmentData> segments;
|
||||
final double strokeWidth;
|
||||
final double gapAngle;
|
||||
final Widget centerWidget;
|
||||
|
||||
const SegmentedCircleWithCenterWidget({
|
||||
Key? key,
|
||||
required this.segments,
|
||||
this.strokeWidth = 6.0,
|
||||
this.gapAngle = 4.0,
|
||||
required this.centerWidget,
|
||||
}) : 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(
|
||||
right: 60.rpx, // 放置在右侧
|
||||
child: SvgPicture.asset(
|
||||
'assets/img/icon/add.svg',
|
||||
width: 14.rpx,
|
||||
height: 22.rpx,
|
||||
color: themeController.currentColor.sc9,
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user