import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:ef/base/chart/drawer.dart'; import 'package:ef/base/chart/easychart.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; enum ChartDisplayMode { line, bar, both, dualBar } class LineView extends StatelessWidget { final List xLabels; final List yLabels; final double barWidth; final int xCount; final int yCount; final List points; final ChartDisplayMode displayMode; final List? barColors; final List>? dualBarPoints; final String? xUnit; final List tips; final double bottomPadding; const LineView({ super.key, required this.xLabels, required this.yLabels, required this.xCount, required this.yCount, required this.points, required this.barWidth, required this.tips, this.xUnit = '', this.bottomPadding = 100, this.displayMode = ChartDisplayMode.bar, this.barColors, // 添加进构造函数 this.dualBarPoints, }); @override Widget build(BuildContext context) { return LayoutBuilder(builder: (a, b) { return Container( alignment: Alignment.topCenter, margin: EdgeInsets.only( left: 43.rpx, bottom: bottomPadding.rpx, ), child: EasyChartView( size: Size(b.maxWidth, 220.rpx), drawer: ChartDrawer( xAxis: ChartAxis( intent: 44, entintent: 15, labels: xLabels, count: xCount, ), yAxis: ChartAxis( color: Colors.transparent, isX: false, intent: 0, entintent: 45.rpx.toInt(), labels: yLabels, count: yCount, ), ondrawer: (canvas, size, drawer) { canvas.scale(1, -1); ChartLables.drawText( canvas, xUnit!, Offset(drawer.yAxis.labels.first.offset.dx, -drawer.drawsize.height + 0), style: TextStyle( color: Color(0xFFFFFFFF).withOpacity(0.6), fontSize: 18.rpx, ), ); canvas.scale(1, -1); // 虚线 for (var i = 1; i < drawer.yAxis.labels.first.labels.length; i++) { drawer.drawHorizontalDashedLine( canvas, drawer.yAxis.labels.first.steps[i].dy, drawer.drawsize.width, dashWidth: 3, dashSpace: 3, paint: Paint()..color = Colors.grey, ); } if (displayMode == ChartDisplayMode.line || displayMode == ChartDisplayMode.both) { drawer.drawcurveline( canvas, points, Paint() ..color = Color(0xFF00C1AA) ..strokeWidth = 1.5, ); drawer.drawpoints( canvas, points, 5, Paint()..color = Color(0Xff00C1AA), values: tips, ); } if (displayMode == ChartDisplayMode.bar || displayMode == ChartDisplayMode.both) { for (var i = 0; i < points.length; i++) { final offset = points[i]; // final color = (barColors != null && barColors!.length > i) // ? barColors![i] // : Colors.yellow.withAlpha(100 + i * 10); // 默认回退 drawer.drawBar( canvas, Offset(offset.dx, 0), barWidth, offset.dy, Paint() ..color = barColors!.length == 0 ? Colors.white : stringToColor(barColors![i]), value: tips[i], ); } } if ((displayMode == ChartDisplayMode.dualBar || displayMode == ChartDisplayMode.both) && dualBarPoints != null) { for (int i = 0; i < dualBarPoints!.length; i++) { final List bar = dualBarPoints![i]; if (bar.length < 3) continue; final Offset deep = bar[0]; // 深睡:起点 -> deep.dy final Offset light = bar[1]; // 浅睡:起点 -> light.dy final Offset total = bar[2]; // 总睡眠:起点 -> total.dy const String deepColor = "#21AD5D"; // 深睡 const String lightColor = "#45D989"; // 浅睡 const String remainColor = "#D3D3D3"; // 剩余 // 画深睡 if (deep.dy > 0) { drawer.drawBar( canvas, Offset(deep.dx, 0), barWidth, deep.dy, value: tips[i], Paint()..color = stringToColor(deepColor), ); } // 画浅睡(从 deep.dy 开始) final double lightHeight = light.dy - deep.dy; if (lightHeight > 0) { drawer.drawBar( canvas, Offset(light.dx, deep.dy), barWidth, lightHeight, Paint()..color = stringToColor(lightColor), ); } // 判断是否需要画灰色剩余段和文字 final double remainHeight = total.dy - light.dy; if (remainHeight > 0.01) { // 灰色部分 drawer.drawBar( canvas, Offset(total.dx, light.dy), barWidth, remainHeight, Paint() ..color = stringToColor(remainColor).withOpacity(0.8), ); } // 若已满,不绘制灰色段、也不显示文字(不做任何处理) } } }, ), onTips: (view, tips) => Container( padding: EdgeInsets.all(16.rpx), // ✅ 容器内部边距,给文字留空间 decoration: BoxDecoration( color: themeController.currentColor.sc5, borderRadius: BorderRadius.circular(20.rpx), ), alignment: Alignment.center, child: Text( tips, style: TextStyle( color: Color(0XFFFFFFFF), // 多了一个 F,建议改成正确格式 fontSize: 26.rpx, ), ), ))); }); } }