// stability.js - 稳定性测试相关功能 // 稳定性测试时间数组 let stabilityTimes = []; // 图表相关变量 let stabilityCtx = null; let stabilityChartInstance = null; function initializeStabilityPage() { // 生成稳定性标签页内容 generateStabilityTabContent(); // 加载稳定性数据 loadStabilityData(); } // 生成稳定性标签页内容 function generateStabilityTabContent() { console.log('generateStabilityTabContent'); const stabilityTab = document.createElement('div'); stabilityTab.id = 'stability'; stabilityTab.className = 'tab-content'; // 创建内容容器 const contentContainer = document.createElement('div'); contentContainer.className = 'content-container'; // 创建输入部分 const inputSection = document.createElement('div'); inputSection.className = 'input-section'; // 创建输入组 const inputGroup = document.createElement('div'); inputGroup.className = 'input-group'; inputGroup.id = 'stability-inputs'; // 添加默认的6个输入行,设置默认时间间隔为10分钟 const defaultTimes = [0, 10, 20, 30, 40, 50]; for (let i = 1; i <= 6; i++) { const row = createInputRow(i, 'stability', recordTimeAndCalculateStability, deleteStabilityInput); inputGroup.appendChild(row); } // 添加按钮 const addInputBtn = document.createElement('div'); addInputBtn.className = 'add-input-btn'; addInputBtn.onclick = addStabilityInput; const addInputSpan = document.createElement('span'); addInputSpan.textContent = '+ 添加输入'; addInputBtn.appendChild(addInputSpan); // 组装输入部分 inputSection.appendChild(inputGroup); inputSection.appendChild(addInputBtn); // 创建结果部分 const resultsSection = document.createElement('div'); resultsSection.className = 'results-section'; // 创建结果显示 const results = document.createElement('div'); results.className = 'results'; // 添加结果项 const resultItems = [ { label: '最大值:', id: 'stability-max' }, { label: '最小值:', id: 'stability-min' }, { label: '平均值:', id: 'stability-mean' }, { label: '极值差:', id: 'stability-range' } ]; resultItems.forEach(item => { const resultItem = document.createElement('div'); resultItem.className = 'result-item'; resultItem.innerHTML = `${item.label} -`; results.appendChild(resultItem); }); // 创建图表容器 const chartContainer = document.createElement('div'); chartContainer.className = 'chart-container'; const canvas = document.createElement('canvas'); canvas.id = 'stabilityChart'; chartContainer.appendChild(canvas); stabilityCtx = canvas.getContext('2d'); // 组装结果部分 resultsSection.appendChild(results); resultsSection.appendChild(chartContainer); // 组装整个内容 contentContainer.appendChild(inputSection); contentContainer.appendChild(resultsSection); stabilityTab.appendChild(contentContainer); if (document.getElementById('container')) { console.log('appendChild stabilityTab'); document.getElementById('container').appendChild(stabilityTab); } } // 添加稳定性输入行 function addStabilityInput() { const container = document.getElementById('stability-inputs'); const newIndex = container.children.length + 1; const row = createInputRow(newIndex, 'stability', recordTimeAndCalculateStability, deleteStabilityInput); container.appendChild(row); } // 删除稳定性输入行 function deleteStabilityInput(btn) { const row = btn.parentNode; const container = row.parentNode; const index = Array.from(container.children).indexOf(row); // 移除对应的时间记录 stabilityTimes.splice(index, 1); // 移除输入行 container.removeChild(row); // 更新剩余输入行的索引 const rows = container.querySelectorAll('.input-row'); rows.forEach((row, i) => { const timeSpan = row.querySelector(`span[id^="stability-time-text-"]`); const input = row.querySelector(`input[id^="stability-value-"]`); // 更新ID const newIndex = i + 1; timeSpan.id = `stability-time-text-${newIndex}`; input.id = `stability-value-${newIndex}`; // 如果有保存的时间,则显示时间,否则显示索引 if (stabilityTimes[i]) { timeSpan.textContent = `${parseUnixTime(stabilityTimes[i])}: `; } else { timeSpan.textContent = `${newIndex}: `; } // 更新输入事件 input.oninput = function() { recordTimeAndCalculateStability(newIndex); }; }); document.querySelectorAll('#stability-inputs input[type="number"]').forEach((input) => { input.placeholder = `输入值`; }); calculateStability(); saveStabilityData(); } // 清除稳定性数据 function clearStabilityData() { // 清除稳定性数据 const stabilityInputs = document.querySelectorAll('#stability-inputs .input-row'); for (let i = 6; i < stabilityInputs.length; i++) { stabilityInputs[i].remove(); } document.querySelectorAll('#stability-inputs input[type="number"]').forEach(input => { input.value = ''; }); stabilityTimes = []; // 重置稳定性时间标签 for (let i = 1; i <= 6; i++) { const timeSpan = document.getElementById(`stability-time-text-${i}`); if (timeSpan) { timeSpan.textContent = `${i}: `; } } // 重置图表 if (stabilityChartInstance) { stabilityChartInstance.destroy(); stabilityChartInstance = null; } } // 记录稳定性时间并计算 function recordTimeAndCalculateStability(index) { recordTimeAndCalculate('stability', index, stabilityTimes, calculateStability); } // 稳定性计算 function calculateStability() { const values = getNumericInputs('#stability-inputs input[type="number"]'); if (values.length >= 2) { // 计算统计量 const max = Math.max(...values); const min = Math.min(...values); const range = max - min; const mean = values.reduce((sum, val) => sum + val, 0) / values.length; // 更新结果显示 updateResultDisplay('stability-max', max); updateResultDisplay('stability-min', min); updateResultDisplay('stability-mean', mean); updateResultDisplay('stability-range', range); // 保存数据 saveStabilityData(); // 更新图表 updateStabilityChart(values); } else { // 清空结果显示 document.querySelectorAll('#stability .result-item span').forEach(span => { span.innerText = '-'; }); // 清空图表 if (stabilityChartInstance) { stabilityChartInstance.data.labels = []; stabilityChartInstance.data.datasets[0].data = []; stabilityChartInstance.update(); } } } // 稳定性图表更新 function updateStabilityChart(values) { // 获取时间标签 const timeLabels = []; stabilityTimes.forEach((time) => { // 使用已保存的时间戳生成标签 if (time > 9999) { timeLabels.push(parseUnixTime(time)); } }); // 使用通用图表创建函数 stabilityChartInstance = createOrUpdateChart(stabilityChartInstance, stabilityCtx, timeLabels, values, '稳定性'); } // 稳定性数据保存 function saveStabilityData() { collectAndSaveData('#stability-inputs input[type="number"]', stabilityTimes, { max: 'stability-max', min: 'stability-min', mean: 'stability-mean', range: 'stability-range' }, 'stabilityData'); } // 稳定性数据加载 function loadStabilityData() { const savedStabilityData = getLocalStorage('stabilityData'); if (savedStabilityData) { try { const data = JSON.parse(savedStabilityData); // 清除现有的额外输入框(保留前6个) const stabilityInputs = document.querySelectorAll('#stability-inputs .input-row'); for (let i = 6; i < stabilityInputs.length; i++) { stabilityInputs[i].remove(); } // 清除现有输入值 document.querySelectorAll('#stability-inputs input[type="number"]').forEach(input => { input.value = ''; }); // 填充保存的数据 if (data.inputs && data.inputs.length > 0) { data.inputs.forEach((item, index) => { const time = typeof item === 'object' ? item.time : ''; const value = typeof item === 'object' ? item.value : ''; // 如果索引超出现有输入框数量,添加新的输入框 if (index >= 6) { addStabilityInput(); } // 设置时间 if (time) { const timeSpan = document.getElementById(`stability-time-text-${index + 1}`); if (timeSpan) { timeSpan.textContent = parseUnixTime(time) + ': '; stabilityTimes[index] = time; } } // 设置值 const input = document.querySelector(`#stability-inputs .input-row:nth-child(${index + 1}) input`); if (input) { input.value = value; } }); // 计算结果 calculateStability(); } } catch (e) { console.error('加载稳定性数据失败:', e); } } }