controller.dart 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import 'dart:async';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  4. import 'index.dart';
  5. class EcgViewController extends GetxController {
  6. EcgViewController();
  7. /// 每秒的数据量
  8. static int get dataPerSecond => 125;
  9. /// 更新帧率
  10. static int updateFrameRate = 25;
  11. /// 更新周期
  12. static int updatePeriod = 1000 ~/ updateFrameRate;
  13. /// 画布时间跨度(秒)
  14. int get timeSpan => 3;
  15. /// 横坐标数据量
  16. int get xDataCount => dataPerSecond * timeSpan;
  17. /// 所有心电数据
  18. List<int> allPoints = [];
  19. /// 需绘制的新数据
  20. List<int> newPointsToDraw = [];
  21. /// 需绘制的历史数据
  22. List<int> oldPointsToDraw = [];
  23. /// 启动时时间戳
  24. int startTime = DateTime.now().millisecondsSinceEpoch;
  25. /// 当前数据位(根据时间戳计算)
  26. int currentDataIndex = 0;
  27. /// 数据刷新定时器
  28. Timer timer = Timer(Duration.zero, () {});
  29. /// 发生错误时暂停了
  30. bool isPaused = false;
  31. /// 读取到数据的回调
  32. void addData(List<int> data) {
  33. if (allPoints.isEmpty) {
  34. startTime = DateTime.now().millisecondsSinceEpoch;
  35. _startTimer();
  36. }
  37. allPoints.addAll(data);
  38. if (isPaused) {
  39. isPaused = false;
  40. _startTimer();
  41. }
  42. }
  43. /// 开启定时器,每隔一定时间添加一次数据,并且更新UI
  44. void _startTimer() {
  45. timer = Timer.periodic(
  46. Duration(milliseconds: updatePeriod),
  47. (timer) {
  48. // print("timer: ${timer.tick}");
  49. _updateData();
  50. },
  51. );
  52. }
  53. /// 每帧更新数据
  54. void _updateData() {
  55. // 计算当前数据位
  56. currentDataIndex = (DateTime.now().millisecondsSinceEpoch - startTime) ~/
  57. (1000 ~/ dataPerSecond);
  58. /// 需显示的数据量
  59. int needDataCount = currentDataIndex % xDataCount;
  60. /// 当前周期数
  61. int currentPeriod = currentDataIndex ~/ xDataCount;
  62. // 计算新数据
  63. try {
  64. newPointsToDraw = allPoints.sublist(
  65. currentDataIndex - needDataCount,
  66. currentDataIndex,
  67. );
  68. if (currentPeriod > 0) {
  69. oldPointsToDraw = allPoints.sublist(
  70. (currentPeriod - 1) * xDataCount,
  71. currentPeriod * xDataCount,
  72. );
  73. }
  74. // print(
  75. // "update newPointsToDraw: ${currentDataIndex} ${needDataCount} ${newPointsToDraw.length} --currentPeriod ${currentPeriod}");
  76. } catch (e) {
  77. print(e);
  78. timer.cancel();
  79. isPaused = true;
  80. }
  81. update(['ecg_view']);
  82. }
  83. void openFullScreenDialog() {
  84. print("当前点总数为:${allPoints.length}");
  85. if (allPoints.length < dataPerSecond * 30) {
  86. PromptBox.toast("未完成检测,数据量不足");
  87. return;
  88. }
  89. Get.dialog(
  90. const FullScreenEcgDataDialog(),
  91. );
  92. }
  93. void reset() {
  94. allPoints.clear();
  95. newPointsToDraw.clear();
  96. oldPointsToDraw.clear();
  97. startTime = DateTime.now().millisecondsSinceEpoch;
  98. currentDataIndex = 0;
  99. timer.cancel();
  100. isPaused = false;
  101. update(['ecg_view']);
  102. }
  103. // @override
  104. // void onInit() {
  105. // super.onInit();
  106. // }
  107. @override
  108. void onReady() {
  109. super.onReady();
  110. print("onReady");
  111. }
  112. @override
  113. void onClose() {
  114. super.onClose();
  115. timer.cancel();
  116. }
  117. }