psgeStability.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // stability.js - 稳定性测试相关功能
  2. // 稳定性测试时间数组
  3. let stabilityTimes = [];
  4. // 图表相关变量
  5. let stabilityCtx = null;
  6. let stabilityChartInstance = null;
  7. // 计时器相关变量
  8. let timerInterval = null;
  9. let timerTotalSeconds = 600; // 默认10分钟
  10. let timerCurrentSeconds = 600;
  11. let timerPaused = false;
  12. // 初始化稳定性图表
  13. function initStabilityChart() {
  14. stabilityCtx = document.getElementById('stabilityChart').getContext('2d');
  15. }
  16. // 在页面加载完成后初始化图表
  17. document.addEventListener('DOMContentLoaded', function() {
  18. initStabilityChart();
  19. });
  20. // 更新稳定性输入框的占位符
  21. function updateStabilityInputPlaceholders() {
  22. document.querySelectorAll('#stability-inputs input[type="number"]').forEach((input, index) => {
  23. input.placeholder = `测量值 ${index + 1}`;
  24. });
  25. }
  26. // 更新稳定性输入框的删除按钮
  27. function updateStabilityDeleteButtons() {
  28. const stabilityInputs = document.querySelectorAll('#stability-inputs .input-row');
  29. stabilityInputs.forEach((row, index) => {
  30. const deleteBtn = row.querySelector('.delete-btn');
  31. if (deleteBtn) {
  32. deleteBtn.style.display = index < 6 ? 'none' : 'inline';
  33. }
  34. });
  35. }
  36. // 稳定性测试函数
  37. function addStabilityInput() {
  38. const container = document.getElementById('stability-inputs');
  39. const newIndex = container.children.length + 1;
  40. const row = createInputRow(newIndex, 'stability', recordTimeAndCalculateStability, deleteStabilityInput);
  41. // 设置默认时间为上一个时间+10分钟
  42. const lastTimeSpan = container.querySelector(`.input-row:last-child span[id^="stability-time-text-"]`);
  43. let lastTime = 0;
  44. if (lastTimeSpan) {
  45. const lastTimeText = lastTimeSpan.textContent.trim();
  46. lastTime = parseInt(lastTimeText) || 0;
  47. }
  48. const newTime = lastTime + 10;
  49. row.querySelector(`span[id^="stability-time-text-"]`).textContent = `${newTime}: `;
  50. container.appendChild(row);
  51. updateStabilityInputs();
  52. }
  53. function deleteStabilityInput(btn) {
  54. const row = btn.parentNode;
  55. const container = row.parentNode;
  56. const index = Array.from(container.children).indexOf(row);
  57. // 移除对应的时间记录
  58. stabilityTimes.splice(index, 1);
  59. // 移除输入行
  60. container.removeChild(row);
  61. // 更新剩余输入行的索引
  62. const rows = container.querySelectorAll('.input-row');
  63. rows.forEach((row, i) => {
  64. const timeSpan = row.querySelector(`span[id^="stability-time-text-"]`);
  65. const input = row.querySelector(`input[id^="stability-value-"]`);
  66. // 更新ID
  67. const newIndex = i + 1;
  68. timeSpan.id = `stability-time-text-${newIndex}`;
  69. input.id = `stability-value-${newIndex}`;
  70. // 更新输入事件
  71. input.oninput = function() { recordTimeAndCalculateStability(newIndex); };
  72. });
  73. updateStabilityInputs();
  74. calculateStability();
  75. saveStabilityData();
  76. }
  77. function recordTimeAndCalculateStability(index) {
  78. recordTimeAndCalculate('stability', index, stabilityTimes, calculateStability);
  79. }
  80. function calculateStability() {
  81. const values = getNumericInputs('#stability-inputs input[type="number"]');
  82. if (values.length >= 2) {
  83. // 计算统计量
  84. const max = Math.max(...values);
  85. const min = Math.min(...values);
  86. const range = max - min;
  87. const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
  88. // 更新结果显示
  89. updateResultDisplay('stability-max', max);
  90. updateResultDisplay('stability-min', min);
  91. updateResultDisplay('stability-mean', mean);
  92. updateResultDisplay('stability-range', range);
  93. // 更新图表
  94. updateStabilityChart(values);
  95. } else {
  96. // 清空结果显示
  97. document.querySelectorAll('#stability .result-item span').forEach(span => {
  98. span.innerText = '-';
  99. });
  100. // 清空图表
  101. if (stabilityChartInstance) {
  102. stabilityChartInstance.data.labels = [];
  103. stabilityChartInstance.data.datasets[0].data = [];
  104. stabilityChartInstance.update();
  105. }
  106. }
  107. }
  108. function updateStabilityChart(values) {
  109. // 获取时间标签
  110. const timeLabels = [];
  111. document.querySelectorAll('#stability-inputs .input-row').forEach((row, index) => {
  112. const timeSpan = row.querySelector(`span[id^="stability-time-text-"]`);
  113. const timeText = timeSpan.textContent.trim();
  114. const time = timeText.replace(':', '');
  115. timeLabels.push(time);
  116. });
  117. // 使用通用图表创建函数
  118. stabilityChartInstance = createOrUpdateChart(stabilityChartInstance, stabilityCtx, timeLabels, values, '稳定性');
  119. }
  120. function saveStabilityData() {
  121. collectAndSaveData('#stability-inputs input[type="number"]', 'stability-time-text', {
  122. max: 'stability-max',
  123. min: 'stability-min',
  124. mean: 'stability-mean',
  125. range: 'stability-range'
  126. }, 'stabilityData');
  127. }
  128. // 加载计时器设置
  129. function loadTimerSettings() {
  130. const savedMinutes = getLocalStorage('timerMinutes');
  131. const savedSeconds = getLocalStorage('timerSeconds');
  132. const savedAutoCountdown = getLocalStorage('autoCountdownEnabled');
  133. if (savedMinutes !== null && savedSeconds !== null) {
  134. const minutes = parseInt(savedMinutes);
  135. const seconds = parseInt(savedSeconds);
  136. document.getElementById('timer-minutes').value = minutes;
  137. document.getElementById('timer-seconds').value = seconds;
  138. timerTotalSeconds = minutes * 60 + seconds;
  139. timerCurrentSeconds = timerTotalSeconds;
  140. updateTimerDisplay();
  141. }
  142. // 加载自动倒计时设置
  143. if (savedAutoCountdown !== null) {
  144. document.getElementById('auto-countdown-enabled').checked = (savedAutoCountdown === '1');
  145. }
  146. }
  147. // 保存计时器设置
  148. function saveTimerSettings(minutes, seconds) {
  149. setLocalStorage('timerMinutes', minutes, 30);
  150. setLocalStorage('timerSeconds', seconds, 30);
  151. // 保存自动倒计时设置
  152. const autoCountdownEnabled = document.getElementById('auto-countdown-enabled').checked;
  153. setLocalStorage('autoCountdownEnabled', autoCountdownEnabled ? '1' : '0', 30);
  154. }
  155. // 打开计时器对话框
  156. function openTimerDialog() {
  157. document.getElementById('timer-dialog').style.display = 'flex';
  158. }
  159. // 关闭计时器对话框
  160. function closeTimerDialog() {
  161. document.getElementById('timer-dialog').style.display = 'none';
  162. }
  163. // 开始计时器
  164. function startTimer() {
  165. // 如果已暂停,则继续计时
  166. if (timerPaused) {
  167. timerPaused = false;
  168. } else {
  169. // 获取设置的时间
  170. const minutes = parseInt(document.getElementById('timer-minutes').value) || 0;
  171. const seconds = parseInt(document.getElementById('timer-seconds').value) || 0;
  172. timerTotalSeconds = minutes * 60 + seconds;
  173. timerCurrentSeconds = timerTotalSeconds;
  174. // 保存设置到cookie
  175. saveTimerSettings(minutes, seconds);
  176. // 停止警报铃声
  177. document.getElementById('alertSound').pause();
  178. document.getElementById('alertSound').currentTime = 0;
  179. // 更新暂停按钮文本为暂停
  180. document.querySelector('#timer-dialog button:nth-child(1)').textContent = '暂停';
  181. }
  182. // 更新显示
  183. updateTimerDisplay();
  184. // 开始倒计时
  185. if (!timerInterval) {
  186. timerInterval = setInterval(updateTimer, 1000);
  187. }
  188. }
  189. // 暂停计时器
  190. function pauseTimer() {
  191. if (timerInterval) {
  192. clearInterval(timerInterval);
  193. timerInterval = null;
  194. timerPaused = true;
  195. // 停止警报铃声
  196. document.getElementById('alertSound').pause();
  197. document.getElementById('alertSound').currentTime = 0;
  198. // 更新暂停按钮文本为继续
  199. document.querySelector('#timer-dialog button:nth-child(1)').textContent = '继续';
  200. }
  201. }
  202. // 重置计时器
  203. function resetTimer() {
  204. if (timerInterval) {
  205. clearInterval(timerInterval);
  206. timerInterval = null;
  207. }
  208. timerPaused = false;
  209. // 获取设置的时间
  210. const minutes = parseInt(document.getElementById('timer-minutes').value) || 0;
  211. const seconds = parseInt(document.getElementById('timer-seconds').value) || 0;
  212. timerTotalSeconds = minutes * 60 + seconds;
  213. timerCurrentSeconds = timerTotalSeconds;
  214. // 更新显示
  215. updateTimerDisplay();
  216. // 停止警报铃声
  217. document.getElementById('alertSound').pause();
  218. document.getElementById('alertSound').currentTime = 0;
  219. // 更新暂停按钮文本为开始
  220. document.querySelector('#timer-dialog button:nth-child(1)').textContent = '开始';
  221. }
  222. // 更新计时器
  223. function updateTimer() {
  224. if (timerCurrentSeconds > 0) {
  225. timerCurrentSeconds--;
  226. updateTimerDisplay();
  227. // 当倒计时接近结束时播放警报
  228. if (timerCurrentSeconds <= 3 && timerCurrentSeconds > 0) {
  229. document.getElementById('alertSound').play();
  230. }
  231. } else {
  232. // 倒计时结束
  233. clearInterval(timerInterval);
  234. timerInterval = null;
  235. // 播放警报
  236. document.getElementById('alertSound').play();
  237. // 更新暂停按钮文本为开始
  238. document.querySelector('#timer-dialog button:nth-child(1)').textContent = '开始';
  239. }
  240. }
  241. // 更新计时器显示
  242. function updateTimerDisplay() {
  243. const minutes = Math.floor(timerCurrentSeconds / 60);
  244. const seconds = timerCurrentSeconds % 60;
  245. const displayText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
  246. document.getElementById('countdown').textContent = displayText;
  247. }