This commit is contained in:
wyf
2025-05-22 08:56:27 +08:00
parent 489e907e00
commit 8a418c9c98
39 changed files with 5964 additions and 144 deletions

View File

@@ -0,0 +1,140 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/AdviceComponnetWidget.dart';
class AIAdviceWidget extends StatefulWidget {
AIAdviceWidget({super.key});
@override
State<AIAdviceWidget> createState() => _AIAdviceWidgetState();
}
class _AIAdviceWidgetState extends State<AIAdviceWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
List advices = [
{
"title": "调整作息时间",
"description": "确保每天在相同的时间上床并醒来。保持规律的作息可以帮助调整你的生物钟,改善睡眠质量。",
},
{
"title": "减少睡前刺激",
"description": "避免在睡前使用电子设备,如手机、电脑等,减少屏幕时间,以防影响你的睡眠质量。",
},
{
"title": "创造理想睡眠环境",
"description": "确保卧室安静、黑暗且舒适。调节室温,并避免过于嘈杂或明亮的环境,帮助你快速入睡。",
},
{
"title": "避免摄入咖啡因和酒精",
"description": "避免在睡前几小时内摄入咖啡、茶、酒精等饮品,因为这些物质可能会干扰你的睡眠。",
},
{
"title": "增加日间活动",
"description": "适量的日间运动可以帮助提高睡眠质量,但要避免睡前剧烈运动,以免影响入睡。",
},
{
"title": "放松身心",
"description": "睡前可以进行一些放松活动,如深呼吸、冥想或听轻音乐,这有助于减轻压力并促进良好的睡眠。",
},
];
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius), // 你可以按需调整圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"AI分析".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
showTipDialog(
context,
Container(
child: Text(
"AI分析介绍".tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
],
),
),
SizedBox(
height: 31.rpx,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Column(
children: advices.map<Widget>((advice) {
return AdviceComponnetWidget(
title: advice["title"],
description: advice["description"],
).paddingOnly(bottom: 0.rpx); // 在每个组件下方添加间隔
}).toList(),
),
)
],
),
),
);
}
}

View File

@@ -0,0 +1,315 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/TimeSeriesChart.dart';
class BreatheStandardWidget extends StatefulWidget {
BreatheStandardWidget({super.key});
@override
State<BreatheStandardWidget> createState() => _BreatheStandardWidgetState();
}
class _BreatheStandardWidgetState extends State<BreatheStandardWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final now = DateTime.now();
final startTime = now.subtract(Duration(hours: 5)).millisecondsSinceEpoch;
final endTime = now.millisecondsSinceEpoch;
final dataPoints = [
TimeSeriesPoint(startTime + Duration(minutes: 10).inMilliseconds, 50),
TimeSeriesPoint(startTime + Duration(hours: 1).inMilliseconds, 120),
TimeSeriesPoint(startTime + Duration(hours: 2).inMilliseconds, 80),
TimeSeriesPoint(startTime + Duration(hours: 3).inMilliseconds, 180),
TimeSeriesPoint(startTime + Duration(hours: 4).inMilliseconds, 30),
TimeSeriesPoint(endTime - Duration(minutes: 10).inMilliseconds, 150),
];
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius), // 你可以按需调整圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"呼吸基准".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
showTipDialog(
context,
Container(
child: Text(
"呼吸基准介绍".tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
],
),
),
SizedBox(
height: 31.rpx,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// 圆形小球容器
Container(
width: 14.rpx, // 圆球的直径
height: 14.rpx,
decoration: BoxDecoration(
color: themeController.currentColor.sc2, // 小球的颜色
shape: BoxShape.circle, // 设置为圆形
),
),
SizedBox(width: 15.rpx), // 圆球和文字之间的间隔
// 文字
Text(
'正常范围(8~20)',
style: TextStyle(
fontSize:
AppConstants().smaller_text_fontSize, // 文字的大小
color: themeController.currentColor.sc3, // 文字颜色
),
),
],
),
Container(
// color: Colors.red,
width: double.infinity,
// height: 300.rpx,
child: TimeSeriesChart(
startTime: startTime,
endTime: endTime,
yMin: 50,
yMax: 150,
dataPoints: dataPoints,
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
"平均呼吸",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"12",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"基准呼吸",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"15",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"最低呼吸",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"11",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"最高呼吸",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"18",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
],
),
),
].divide(SizedBox(
height: 18.rpx,
)),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,197 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/AdviceComponnetWidget.dart';
import 'package:vbvs_app/pages/sleep_report/chart/RadarChart.dart';
import 'package:vbvs_app/pages/sleep_report/chart/SleepRadarChart.dart';
class CompareSleepWidget extends StatefulWidget {
CompareSleepWidget({super.key});
@override
State<CompareSleepWidget> createState() => _CompareSleepWidgetState();
}
class _CompareSleepWidgetState extends State<CompareSleepWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
var today = {
"type1": 40.0,
"type2": 80.0,
"type3": 60.0,
"type4": 70.0,
"type5": 100.0
};
var yesterday = {
"type1": 40.0,
"type2": 90.0,
"type3": 50.0,
"type4": 70.0,
"type5": 30.0
};
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius), // 你可以按需调整圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"与昨日对比分析".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
showTipDialog(
context,
Container(
child: Text(
"与昨日对比分析介绍".tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
],
),
),
SizedBox(
height: 31.rpx,
),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
// child: SleepRadarChart(
// today: today,
// yesterday: yesterday,
// ),
// ),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Stack(
children: [
// 雷达图
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 0.rpx, 0.rpx),
child: SleepRadarChart(
today: today,
yesterday: yesterday,
),
),
// 在左侧添加一个 Text
Positioned(
left: 0, // 这里可以修改文本左边的距离
top: 0, // 这里可以修改文本顶部的距离
child: Container(
color: Colors.transparent, // 不需要背景色,可以去掉
child: Column(
children: [
Row(
children: [
// 长条容器
Container(
width:
34.rpx, // 你可以设置容器的宽度,或者使用 Expanded 填充剩余空间
height: 2.rpx, // 容器的高度
color: stringToColor("#00C1AA"), // 容器的颜色
),
SizedBox(width: 13.rpx), // 文字和容器之间的间距
// 文字
Text(
'今日数据', // 文字内容
style: TextStyle(
fontSize: 18.rpx, // 文字大小
color:
themeController.currentColor.sc4, // 文字颜色
),
),
],
),
Row(
children: [
// 长条容器
Container(
width:
34.rpx, // 你可以设置容器的宽度,或者使用 Expanded 填充剩余空间
height: 2.rpx, // 容器的高度
color: stringToColor("#FFD251"), // 容器的颜色
),
SizedBox(width: 13.rpx), // 文字和容器之间的间距
// 文字
Text(
'昨日数据', // 文字内容
style: TextStyle(
fontSize: 18.rpx, // 文字大小
color:
themeController.currentColor.sc4, // 文字颜色
),
),
],
),
].divide(SizedBox(height: 25.rpx)),
),
),
),
],
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,316 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/DataShowWidget.dart';
class HeartChangeWidget extends StatefulWidget {
HeartChangeWidget({super.key});
@override
State<HeartChangeWidget> createState() => _HeartChangeWidgetState();
}
class _HeartChangeWidgetState extends State<HeartChangeWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
//0上升 1下降 2持平
List data = [
{
"name": "心脏总能量",
"value": 5262,
"range": "2055-6000",
"change": 0,
"desc": "心脏总能量介绍"
},
{
"name": "心率减速力",
"value": 5262,
"range": "2055-6000",
"change": 1,
"desc": "心率减速力介绍"
},
{
"name": "迷走神经张力指数",
"value": 5262,
"range": "2055-6000",
"change": 2,
"desc": "迷走神经张力指数介绍"
},
{
"name": "交感神经张力指数",
"value": 5262,
"range": "2055-6000",
"change": 0,
"desc": "交感神经张力指数介绍"
},
{
"name": "自主神经张力指数",
"value": 5262,
"range": "2055-6000",
"change": 2,
"desc": "自主神经张力指数介绍"
},
{
"name": "血管舒张指数",
"value": 5262,
"range": "2055-6000",
"change": 1,
"desc": "血管舒张指数介绍"
},
{
"name": "SDNN",
"value": 5262,
"range": "2055-6000",
"change": 0,
"desc": "SDNN介绍"
},
{
"name": "PNN50",
"value": 5262,
"range": "2055-6000",
"change": 1,
"desc": "PNN50介绍"
},
{
"name": "RMSSD",
"value": 5262,
"range": "2055-6000",
"change": 2,
"desc": "RMSSD介绍"
},
];
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius), // 你可以按需调整圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"心率变异性HRV".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
showTipDialog(
context,
Container(
child: Text(
"心率变异性HRV介绍".tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
],
),
),
SizedBox(
height: 31.rpx,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Column(
children: [
DataShowWidget(
alignment: MainAxisAlignment.center,
widget1: Text(
"名称",
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
),
widget2: Text(
"测量值",
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
),
widget3: Text(
"参考范围",
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
),
widget4: Text(
"趋势",
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
),
),
Column(
children: data.map<Widget>((data) {
return DataShowWidget(
alignment: MainAxisAlignment.center,
widget1: Row(
children: [
Text(
'${data['name']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white,
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 14.rpx, 14.rpx, 14.rpx),
borderRadius: 0.rpx,
onTap: () {
// Get.toNamed("/deviceShareListPage", arguments: explain);
showTipDialog(
context,
Container(
child: Text(
'${data['desc']}',
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: SizedBox(
width: 17.rpx,
height: 17.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: Colors.white,
),
),
),
],
),
widget2: Text(
'${data['value']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
),
),
widget3: Text(
'${data['range']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
),
),
widget4: data['change'] == 0
? Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0, 0),
child: Container(
width: 22.rpx,
height: 22.rpx,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/score_up.svg',
// fit: BoxFit.cover,
),
),
)
: data['change'] == 1
? Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0, 0),
child: Container(
width: 22.rpx,
height: 22.rpx,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/score_down.svg',
// fit: BoxFit.cover,
),
),
)
: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0, 0),
child: Container(
width: 22.rpx,
height: 22.rpx,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/score_equal.svg',
// fit: BoxFit.fill,
),
),
),
).paddingOnly(bottom: 0.rpx); // 在每个组件下方添加间隔
}).toList(),
),
],
),
),
],
),
),
);
}
}

View File

@@ -1,4 +1,7 @@
import 'dart:math';
import 'package:ef/ef.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
@@ -6,7 +9,7 @@ import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/StatusBarWithIndicator.dart';
import 'package:vbvs_app/pages/sleep_report/chart/ScatterPlotChart.dart';
class HeartPointWidget extends StatefulWidget {
HeartPointWidget({super.key});
@@ -33,6 +36,18 @@ class _HeartPointWidgetState extends State<HeartPointWidget> {
@override
Widget build(BuildContext context) {
List<ScatterSpot> data = List.generate(200, (index) {
// 随机生成 x 和 y 值,范围都在 0-1400 之间
double x = Random().nextDouble() * 1400; // x 值在 0-1400 范围
double y = Random().nextDouble() * 1400; // y 值也在 0-1400 范围
// 返回 ScatterSpot使用圆点绘制器自定义大小和颜色
return ScatterSpot(
x,
y,
);
});
return Container(
width: double.infinity,
decoration: BoxDecoration(
@@ -91,24 +106,30 @@ class _HeartPointWidgetState extends State<HeartPointWidget> {
),
),
SizedBox(
height: 83.rpx,
height: 31.rpx,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
child: StatusBarWithIndicator(
selectKey: 2,
showLabel: [
{"key": 1, "name": "正常", "color": Color(0xFF4CAF50)},
{"key": 2, "name": "一般", "color": Color(0xFF8BC34A)},
{"key": 3, "name": "注意", "color": Color(0xFFFFC107)},
{"key": 4, "name": "警告", "color": Color(0xFFF44336)},
],
child: Container(
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.width * 0.7,
constraints: BoxConstraints(
minWidth: 430.rpx,
minHeight: 430.rpx,
),
child: ScatterPlotChart(
points: data,
xMax: 1400, // x轴最大值
yMax: 1400, // y轴最大值
pointColor: stringToColor("#00C1AA"), // 点的颜色
divisions: 7, // 刻度分割数量
),
),
),
SizedBox(
height: 56.rpx,
),
// SizedBox(
// height: 31.rpx,
// ),
],
),
),

View File

@@ -0,0 +1,316 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/sleep_report/chart/TimeSeriesChart.dart';
class HeartRateStandardWidget extends StatefulWidget {
HeartRateStandardWidget({super.key});
@override
State<HeartRateStandardWidget> createState() =>
_HeartRateStandardWidgetState();
}
class _HeartRateStandardWidgetState extends State<HeartRateStandardWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final now = DateTime.now();
final startTime = now.subtract(Duration(hours: 5)).millisecondsSinceEpoch;
final endTime = now.millisecondsSinceEpoch;
final dataPoints = [
TimeSeriesPoint(startTime + Duration(minutes: 10).inMilliseconds, 50),
TimeSeriesPoint(startTime + Duration(hours: 1).inMilliseconds, 120),
TimeSeriesPoint(startTime + Duration(hours: 2).inMilliseconds, 80),
TimeSeriesPoint(startTime + Duration(hours: 3).inMilliseconds, 180),
TimeSeriesPoint(startTime + Duration(hours: 4).inMilliseconds, 30),
TimeSeriesPoint(endTime - Duration(minutes: 10).inMilliseconds, 150),
];
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius), // 你可以按需调整圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"心率基准".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
showTipDialog(
context,
Container(
child: Text(
"心率基准介绍".tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,
),
),
),
);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/explain.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
],
),
),
SizedBox(
height: 31.rpx,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// 圆形小球容器
Container(
width: 14.rpx, // 圆球的直径
height: 14.rpx,
decoration: BoxDecoration(
color: themeController.currentColor.sc2, // 小球的颜色
shape: BoxShape.circle, // 设置为圆形
),
),
SizedBox(width: 15.rpx), // 圆球和文字之间的间隔
// 文字
Text(
'正常范围(50~80)',
style: TextStyle(
fontSize:
AppConstants().smaller_text_fontSize, // 文字的大小
color: themeController.currentColor.sc3, // 文字颜色
),
),
],
),
Container(
// color: Colors.red,
width: double.infinity,
// height: 300.rpx,
child: TimeSeriesChart(
startTime: startTime,
endTime: endTime,
yMin: 50,
yMax: 150,
dataPoints: dataPoints,
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
"平均心率",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"89",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"基准心率",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"80",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"最低心率",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"68",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
Column(
children: [
Text(
"最高心率",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"98",
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize:
AppConstants().normal_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"次/分钟",
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().small_text_fontSize),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
].divide(SizedBox(
width: 6.rpx,
)),
),
],
),
],
),
),
].divide(SizedBox(
height: 18.rpx,
)),
),
),
],
),
),
);
}
}

View File

@@ -61,7 +61,7 @@ class _SnoreViewWidgetWidgetState extends State<SnoreViewWidgetWidget> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"呼吸暂停监测".tr,
"打鼾监测".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().title_text_fontSize),
@@ -77,7 +77,7 @@ class _SnoreViewWidgetWidgetState extends State<SnoreViewWidgetWidget> {
context,
Container(
child: Text(
"呼吸暂停监测介绍。",
"打鼾监测介绍。",
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc3,