pageStability.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // stability.js - 稳定性测试相关功能
  2. // 稳定性测试时间数组
  3. let stabilityTimes = [];
  4. // 图表相关变量
  5. let stabilityCtx = null;
  6. let stabilityChartInstance = null;
  7. function initializeStabilityPage() {
  8. // 生成稳定性标签页内容
  9. generateStabilityTabContent();
  10. // 加载稳定性数据
  11. loadStabilityData();
  12. }
  13. // 生成稳定性标签页内容
  14. function generateStabilityTabContent() {
  15. console.log('generateStabilityTabContent');
  16. const stabilityTab = document.createElement('div');
  17. stabilityTab.id = 'stability';
  18. stabilityTab.className = 'tab-content';
  19. // 创建内容容器
  20. const contentContainer = document.createElement('div');
  21. contentContainer.className = 'content-container';
  22. // 创建输入部分
  23. const inputSection = document.createElement('div');
  24. inputSection.className = 'input-section';
  25. // 创建输入组
  26. const inputGroup = document.createElement('div');
  27. inputGroup.className = 'input-group';
  28. inputGroup.id = 'stability-inputs';
  29. // 添加默认的6个输入行,设置默认时间间隔为10分钟
  30. const defaultTimes = [0, 10, 20, 30, 40, 50];
  31. for (let i = 1; i <= 6; i++) {
  32. const row = createInputRow(i, 'stability', recordTimeAndCalculateStability, deleteStabilityInput);
  33. inputGroup.appendChild(row);
  34. }
  35. // 添加按钮
  36. const addInputBtn = document.createElement('div');
  37. addInputBtn.className = 'add-input-btn';
  38. addInputBtn.onclick = addStabilityInput;
  39. const addInputSpan = document.createElement('span');
  40. addInputSpan.textContent = '+ 添加输入';
  41. addInputBtn.appendChild(addInputSpan);
  42. // 组装输入部分
  43. inputSection.appendChild(inputGroup);
  44. inputSection.appendChild(addInputBtn);
  45. // 创建结果部分
  46. const resultsSection = document.createElement('div');
  47. resultsSection.className = 'results-section';
  48. // 创建结果显示
  49. const results = document.createElement('div');
  50. results.className = 'results';
  51. // 添加结果项
  52. const resultItems = [
  53. { label: '最大值:', id: 'stability-max' },
  54. { label: '最小值:', id: 'stability-min' },
  55. { label: '平均值:', id: 'stability-mean' },
  56. { label: '极值差:', id: 'stability-range' }
  57. ];
  58. resultItems.forEach(item => {
  59. const resultItem = document.createElement('div');
  60. resultItem.className = 'result-item';
  61. resultItem.innerHTML = `${item.label} <span id="${item.id}">-</span>`;
  62. results.appendChild(resultItem);
  63. });
  64. // 创建图表容器
  65. const chartContainer = document.createElement('div');
  66. chartContainer.className = 'chart-container';
  67. const canvas = document.createElement('canvas');
  68. canvas.id = 'stabilityChart';
  69. chartContainer.appendChild(canvas);
  70. stabilityCtx = canvas.getContext('2d');
  71. // 组装结果部分
  72. resultsSection.appendChild(results);
  73. resultsSection.appendChild(chartContainer);
  74. // 组装整个内容
  75. contentContainer.appendChild(inputSection);
  76. contentContainer.appendChild(resultsSection);
  77. stabilityTab.appendChild(contentContainer);
  78. if (document.getElementById('container')) {
  79. console.log('appendChild stabilityTab');
  80. document.getElementById('container').appendChild(stabilityTab);
  81. }
  82. }
  83. // 添加稳定性输入行
  84. function addStabilityInput() {
  85. const container = document.getElementById('stability-inputs');
  86. const newIndex = container.children.length + 1;
  87. const row = createInputRow(newIndex, 'stability', recordTimeAndCalculateStability, deleteStabilityInput);
  88. container.appendChild(row);
  89. }
  90. // 删除稳定性输入行
  91. function deleteStabilityInput(btn) {
  92. const row = btn.parentNode;
  93. const container = row.parentNode;
  94. const index = Array.from(container.children).indexOf(row);
  95. // 移除对应的时间记录
  96. stabilityTimes.splice(index, 1);
  97. // 移除输入行
  98. container.removeChild(row);
  99. // 更新剩余输入行的索引
  100. const rows = container.querySelectorAll('.input-row');
  101. rows.forEach((row, i) => {
  102. const timeSpan = row.querySelector(`span[id^="stability-time-text-"]`);
  103. const input = row.querySelector(`input[id^="stability-value-"]`);
  104. // 更新ID
  105. const newIndex = i + 1;
  106. timeSpan.id = `stability-time-text-${newIndex}`;
  107. input.id = `stability-value-${newIndex}`;
  108. // 如果有保存的时间,则显示时间,否则显示索引
  109. if (stabilityTimes[i]) {
  110. timeSpan.textContent = `${parseUnixTime(stabilityTimes[i])}: `;
  111. } else {
  112. timeSpan.textContent = `${newIndex}: `;
  113. }
  114. // 更新输入事件
  115. input.oninput = function() { recordTimeAndCalculateStability(newIndex); };
  116. });
  117. document.querySelectorAll('#stability-inputs input[type="number"]').forEach((input) => {
  118. input.placeholder = `输入值`;
  119. });
  120. calculateStability();
  121. saveStabilityData();
  122. }
  123. // 清除稳定性数据
  124. function clearStabilityData() {
  125. // 清除稳定性数据
  126. const stabilityInputs = document.querySelectorAll('#stability-inputs .input-row');
  127. for (let i = 6; i < stabilityInputs.length; i++) {
  128. stabilityInputs[i].remove();
  129. }
  130. document.querySelectorAll('#stability-inputs input[type="number"]').forEach(input => {
  131. input.value = '';
  132. });
  133. stabilityTimes = [];
  134. // 重置稳定性时间标签
  135. for (let i = 1; i <= 6; i++) {
  136. const timeSpan = document.getElementById(`stability-time-text-${i}`);
  137. if (timeSpan) {
  138. timeSpan.textContent = `${i}: `;
  139. }
  140. }
  141. // 重置图表
  142. if (stabilityChartInstance) {
  143. stabilityChartInstance.destroy();
  144. stabilityChartInstance = null;
  145. }
  146. }
  147. // 记录稳定性时间并计算
  148. function recordTimeAndCalculateStability(index) {
  149. recordTimeAndCalculate('stability', index, stabilityTimes, calculateStability);
  150. }
  151. // 稳定性计算
  152. function calculateStability() {
  153. const values = getNumericInputs('#stability-inputs input[type="number"]');
  154. if (values.length >= 2) {
  155. // 计算统计量
  156. const max = Math.max(...values);
  157. const min = Math.min(...values);
  158. const range = max - min;
  159. const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
  160. // 更新结果显示
  161. updateResultDisplay('stability-max', max);
  162. updateResultDisplay('stability-min', min);
  163. updateResultDisplay('stability-mean', mean);
  164. updateResultDisplay('stability-range', range);
  165. // 保存数据
  166. saveStabilityData();
  167. // 更新图表
  168. updateStabilityChart(values);
  169. } else {
  170. // 清空结果显示
  171. document.querySelectorAll('#stability .result-item span').forEach(span => {
  172. span.innerText = '-';
  173. });
  174. // 清空图表
  175. if (stabilityChartInstance) {
  176. stabilityChartInstance.data.labels = [];
  177. stabilityChartInstance.data.datasets[0].data = [];
  178. stabilityChartInstance.update();
  179. }
  180. }
  181. }
  182. // 稳定性图表更新
  183. function updateStabilityChart(values) {
  184. // 获取时间标签
  185. const timeLabels = [];
  186. stabilityTimes.forEach((time) => {
  187. // 使用已保存的时间戳生成标签
  188. if (time > 9999) {
  189. timeLabels.push(parseUnixTime(time));
  190. }
  191. });
  192. // 使用通用图表创建函数
  193. stabilityChartInstance = createOrUpdateChart(stabilityChartInstance, stabilityCtx, timeLabels, values, '稳定性');
  194. }
  195. // 稳定性数据保存
  196. function saveStabilityData() {
  197. collectAndSaveData('#stability-inputs input[type="number"]', stabilityTimes, {
  198. max: 'stability-max',
  199. min: 'stability-min',
  200. mean: 'stability-mean',
  201. range: 'stability-range'
  202. }, 'stabilityData');
  203. }
  204. // 稳定性数据加载
  205. function loadStabilityData() {
  206. const savedStabilityData = getLocalStorage('stabilityData');
  207. if (savedStabilityData) {
  208. try {
  209. const data = JSON.parse(savedStabilityData);
  210. // 清除现有的额外输入框(保留前6个)
  211. const stabilityInputs = document.querySelectorAll('#stability-inputs .input-row');
  212. for (let i = 6; i < stabilityInputs.length; i++) {
  213. stabilityInputs[i].remove();
  214. }
  215. // 清除现有输入值
  216. document.querySelectorAll('#stability-inputs input[type="number"]').forEach(input => {
  217. input.value = '';
  218. });
  219. // 填充保存的数据
  220. if (data.inputs && data.inputs.length > 0) {
  221. data.inputs.forEach((item, index) => {
  222. const time = typeof item === 'object' ? item.time : '';
  223. const value = typeof item === 'object' ? item.value : '';
  224. // 如果索引超出现有输入框数量,添加新的输入框
  225. if (index >= 6) {
  226. addStabilityInput();
  227. }
  228. // 设置时间
  229. if (time) {
  230. const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
  231. if (timeSpan) {
  232. timeSpan.textContent = parseUnixTime(time) + ': ';
  233. stabilityTimes[index] = time;
  234. }
  235. }
  236. // 设置值
  237. const input = document.querySelector(`#stability-inputs .input-row:nth-child(${index + 1}) input`);
  238. if (input) {
  239. input.value = value;
  240. }
  241. });
  242. // 计算结果
  243. calculateStability();
  244. }
  245. } catch (e) {
  246. console.error('加载稳定性数据失败:', e);
  247. }
  248. }
  249. }