|
|
@@ -1,38 +1,155 @@
|
|
|
// data.js - 数据管理、导入导出相关功能
|
|
|
|
|
|
-// 收集并保存数据到localStorage
|
|
|
-function collectAndSaveData(selector, timeSelector, resultIds, cookieName) {
|
|
|
- // 收集输入数据
|
|
|
- const inputs = Array.from(document.querySelectorAll(selector)).map((input, index) => {
|
|
|
- const timeSpan = document.getElementById(`${timeSelector}-${index + 1}`);
|
|
|
- return {
|
|
|
- value: input.value,
|
|
|
- time: timeSpan ? timeSpan.textContent.trim() : ''
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- // 收集结果数据
|
|
|
- const results = {};
|
|
|
- if (resultIds) {
|
|
|
- Object.keys(resultIds).forEach(key => {
|
|
|
- const element = document.getElementById(resultIds[key]);
|
|
|
- if (element) {
|
|
|
- results[key] = element.innerText;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+function initializeDataPage() {
|
|
|
+ // 生成数据标签页内容
|
|
|
+ generateDataTabContent();
|
|
|
|
|
|
- // 保存到localStorage
|
|
|
- const data = {
|
|
|
- inputs: inputs,
|
|
|
- results: results
|
|
|
+ // 加载项目标题和自定义参数数据
|
|
|
+ loadProjectTitle();
|
|
|
+ loadCustomParamsData();
|
|
|
+}
|
|
|
+
|
|
|
+// 生成数据标签页内容
|
|
|
+function generateDataTabContent() {
|
|
|
+ console.log('generateDataTabContent');
|
|
|
+
|
|
|
+ const dataTab = document.createElement('div');
|
|
|
+ dataTab.id = 'data';
|
|
|
+ dataTab.className = 'tab-content';
|
|
|
+
|
|
|
+ // 创建内容容器
|
|
|
+ const contentContainer = document.createElement('div');
|
|
|
+ contentContainer.className = 'content-container';
|
|
|
+ contentContainer.style.flexDirection = 'column';
|
|
|
+
|
|
|
+ // 创建项目标题和按钮部分
|
|
|
+ const titleSection = document.createElement('div');
|
|
|
+ titleSection.style.marginBottom = '1.5rem';
|
|
|
+
|
|
|
+ // 创建标题输入部分
|
|
|
+ const titleRow = document.createElement('div');
|
|
|
+ titleRow.style.display = 'flex';
|
|
|
+ titleRow.style.alignItems = 'center';
|
|
|
+ titleRow.style.marginBottom = '1rem';
|
|
|
+
|
|
|
+ const titleLabel = document.createElement('label');
|
|
|
+ titleLabel.htmlFor = 'project-title';
|
|
|
+ titleLabel.style.marginRight = '1rem';
|
|
|
+ titleLabel.style.fontWeight = 'bold';
|
|
|
+ titleLabel.textContent = '工程标题:';
|
|
|
+
|
|
|
+ const titleInput = document.createElement('input');
|
|
|
+ titleInput.type = 'text';
|
|
|
+ titleInput.id = 'project-title';
|
|
|
+ titleInput.placeholder = '请输入工程标题';
|
|
|
+ titleInput.style.flex = '1';
|
|
|
+ titleInput.style.padding = '0.5rem';
|
|
|
+ titleInput.style.border = '1px solid #ccc';
|
|
|
+ titleInput.style.borderRadius = '4px';
|
|
|
+ titleInput.oninput = updateProjectTitle;
|
|
|
+
|
|
|
+ titleRow.appendChild(titleLabel);
|
|
|
+ titleRow.appendChild(titleInput);
|
|
|
+
|
|
|
+ // 创建按钮容器
|
|
|
+ const buttonContainer = document.createElement('div');
|
|
|
+ buttonContainer.className = 'button-container';
|
|
|
+
|
|
|
+ // 创建导出按钮
|
|
|
+ const exportBtn = document.createElement('button');
|
|
|
+ exportBtn.className = 'export-btn';
|
|
|
+ exportBtn.textContent = '导出数据';
|
|
|
+ exportBtn.onclick = exportData;
|
|
|
+
|
|
|
+ // 创建导入按钮
|
|
|
+ const importBtn = document.createElement('button');
|
|
|
+ importBtn.className = 'import-btn';
|
|
|
+ importBtn.textContent = '导入数据';
|
|
|
+ importBtn.onclick = function () {
|
|
|
+ document.getElementById('importFile').click();
|
|
|
};
|
|
|
- console.log(data);
|
|
|
-
|
|
|
|
|
|
- setLocalStorage(cookieName, JSON.stringify(data));
|
|
|
+ // 创建新建工程按钮
|
|
|
+ const newProjectBtn = document.createElement('button');
|
|
|
+ newProjectBtn.className = 'export-btn';
|
|
|
+ newProjectBtn.style.backgroundColor = '#dc3545';
|
|
|
+ newProjectBtn.textContent = '新建工程';
|
|
|
+ newProjectBtn.onclick = newProject;
|
|
|
+
|
|
|
+ // 创建文件输入(隐藏)
|
|
|
+ const importFile = document.createElement('input');
|
|
|
+ importFile.type = 'file';
|
|
|
+ importFile.id = 'importFile';
|
|
|
+ importFile.accept = '.json,.txt';
|
|
|
+ importFile.style.display = 'none';
|
|
|
+ importFile.onchange = importData;
|
|
|
+
|
|
|
+ // 添加按钮到容器
|
|
|
+ buttonContainer.appendChild(exportBtn);
|
|
|
+ buttonContainer.appendChild(importBtn);
|
|
|
+ buttonContainer.appendChild(newProjectBtn);
|
|
|
+ buttonContainer.appendChild(importFile);
|
|
|
+
|
|
|
+ // 组装标题部分
|
|
|
+ titleSection.appendChild(titleRow);
|
|
|
+ titleSection.appendChild(buttonContainer);
|
|
|
+
|
|
|
+ // 创建自定义参数部分
|
|
|
+ const customParamsSection = document.createElement('div');
|
|
|
+ customParamsSection.style.marginTop = '1.5rem';
|
|
|
+ customParamsSection.style.border = '1px solid #eee';
|
|
|
+ customParamsSection.style.borderRadius = '4px';
|
|
|
+ customParamsSection.style.padding = '1rem';
|
|
|
+
|
|
|
+ // 添加标题
|
|
|
+ const customParamsTitle = document.createElement('h3');
|
|
|
+ customParamsTitle.style.marginTop = '0';
|
|
|
+ customParamsTitle.style.marginBottom = '1rem';
|
|
|
+ customParamsTitle.textContent = '自定义参数';
|
|
|
+
|
|
|
+ // 创建参数容器
|
|
|
+ const customParamsContainer = document.createElement('div');
|
|
|
+ customParamsContainer.id = 'custom-params-container';
|
|
|
+ customParamsContainer.style.display = 'flex';
|
|
|
+ customParamsContainer.style.flexDirection = 'column';
|
|
|
+ customParamsContainer.style.gap = '0.5rem';
|
|
|
+ customParamsContainer.style.maxHeight = '300px';
|
|
|
+ customParamsContainer.style.overflowY = 'auto';
|
|
|
+
|
|
|
+ // 添加按钮
|
|
|
+ const addParamBtn = document.createElement('div');
|
|
|
+ addParamBtn.className = 'add-input-btn';
|
|
|
+ addParamBtn.style.marginTop = '1rem';
|
|
|
+ addParamBtn.onclick = addCustomParam;
|
|
|
+ const addParamSpan = document.createElement('span');
|
|
|
+ addParamSpan.textContent = '+ 添加参数';
|
|
|
+ addParamBtn.appendChild(addParamSpan);
|
|
|
+
|
|
|
+ // 组装自定义参数部分
|
|
|
+ customParamsSection.appendChild(customParamsTitle);
|
|
|
+ customParamsSection.appendChild(customParamsContainer);
|
|
|
+ customParamsSection.appendChild(addParamBtn);
|
|
|
+
|
|
|
+ // 组装整个内容
|
|
|
+ contentContainer.appendChild(titleSection);
|
|
|
+ contentContainer.appendChild(customParamsSection);
|
|
|
+ dataTab.appendChild(contentContainer);
|
|
|
+ if (document.getElementById('container')) {
|
|
|
+ console.log('appendChild dataTab');
|
|
|
+ document.getElementById('container').appendChild(dataTab);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加版本信息
|
|
|
+ const versionInfo = document.createElement('div');
|
|
|
+ versionInfo.style.textAlign = 'center';
|
|
|
+ versionInfo.style.marginTop = '1rem';
|
|
|
+ versionInfo.style.color = '#666';
|
|
|
+ versionInfo.style.fontSize = '0.8rem';
|
|
|
+ versionInfo.textContent = 'Ver 1.1.02.250628';
|
|
|
+ dataTab.appendChild(versionInfo);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
// 添加自定义参数
|
|
|
function addCustomParam() {
|
|
|
const container = document.getElementById('custom-params-container');
|
|
|
@@ -77,6 +194,17 @@ function addCustomParam() {
|
|
|
container.appendChild(paramRow);
|
|
|
}
|
|
|
|
|
|
+// 清除自定义参数数据
|
|
|
+function clearCustomParamsData() {
|
|
|
+ // 清除自定义参数
|
|
|
+ const customParamsContainer = document.getElementById('custom-params-container');
|
|
|
+ while (customParamsContainer.firstChild) {
|
|
|
+ customParamsContainer.removeChild(customParamsContainer.firstChild);
|
|
|
+ }
|
|
|
+
|
|
|
+ saveCustomParamsData();
|
|
|
+}
|
|
|
+
|
|
|
// 保存自定义参数数据
|
|
|
function saveCustomParamsData() {
|
|
|
const customParams = Array.from(document.querySelectorAll('#custom-params-container .custom-param-row')).map(row => ({
|
|
|
@@ -84,12 +212,14 @@ function saveCustomParamsData() {
|
|
|
value: row.querySelector('.param-value').value
|
|
|
}));
|
|
|
|
|
|
- setLocalStorage('customParamsData', JSON.stringify(customParams), 365);
|
|
|
+ setLocalStorage('customParamsData', JSON.stringify(customParams));
|
|
|
}
|
|
|
|
|
|
-// 从localStorage加载自定义参数
|
|
|
-function loadCustomParamsFromLocalStorage() {
|
|
|
+// 从localStorage加载自定义参数数据
|
|
|
+function loadCustomParamsData() {
|
|
|
const savedParams = getLocalStorage('customParamsData');
|
|
|
+ console.log('customParamsData', savedParams);
|
|
|
+
|
|
|
if (savedParams) {
|
|
|
try {
|
|
|
const params = JSON.parse(savedParams);
|
|
|
@@ -149,442 +279,107 @@ function loadCustomParamsFromLocalStorage() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 从localStorage加载数据
|
|
|
-function loadDataFromLocalStorage() {
|
|
|
- // 加载重复性数据
|
|
|
- const savedRepeatabilityData = getLocalStorage('repeatabilityData');
|
|
|
- if (savedRepeatabilityData) {
|
|
|
+// 从localStorage加载项目标题
|
|
|
+function loadProjectTitle() {
|
|
|
+ const savedTitle = getLocalStorage('projectTitle');
|
|
|
+ if (savedTitle) {
|
|
|
try {
|
|
|
- const data = JSON.parse(savedRepeatabilityData);
|
|
|
+ const titleInput = document.getElementById('project-title');
|
|
|
+ console.log('projectTitle', savedTitle);
|
|
|
|
|
|
- // 清除现有的额外输入框(保留前6个)
|
|
|
- const repeatabilityInputs = document.querySelectorAll('#repeatability-inputs .input-row');
|
|
|
- for (let i = 6; i < repeatabilityInputs.length; i++) {
|
|
|
- repeatabilityInputs[i].remove();
|
|
|
- }
|
|
|
-
|
|
|
- // 清除现有输入值
|
|
|
- document.querySelectorAll('#repeatability-inputs input[type="number"]').forEach(input => {
|
|
|
- input.value = '';
|
|
|
- });
|
|
|
-
|
|
|
- // 填充保存的数据
|
|
|
- if (data.inputs && data.inputs.length > 0) {
|
|
|
- data.inputs.forEach((item, index) => {
|
|
|
- const value = typeof item === 'object' ? item.value : item;
|
|
|
- const time = typeof item === 'object' ? item.time : '';
|
|
|
-
|
|
|
- // 如果索引超出现有输入框数量,添加新的输入框
|
|
|
- if (index >= 6) {
|
|
|
- addRepeatabilityInput();
|
|
|
- }
|
|
|
-
|
|
|
- // 设置值
|
|
|
- const input = document.querySelector(`#repeatability-inputs .input-row:nth-child(${index + 1}) input`);
|
|
|
- if (input) {
|
|
|
- input.value = value;
|
|
|
- }
|
|
|
-
|
|
|
- // 设置时间
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`repeatability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = `${time}: `;
|
|
|
- repeatabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 计算结果
|
|
|
- calculateRepeatability();
|
|
|
+ if (titleInput) {
|
|
|
+ titleInput.value = savedTitle;
|
|
|
}
|
|
|
} catch (e) {
|
|
|
- console.error('加载重复性数据失败:', e);
|
|
|
+ console.error('加载项目标题失败:', e);
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- // 加载稳定性数据
|
|
|
- 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 value = typeof item === 'object' ? item.value : item;
|
|
|
- const time = typeof item === 'object' ? item.time : '';
|
|
|
-
|
|
|
- // 如果索引超出现有输入框数量,添加新的输入框
|
|
|
- if (index >= 6) {
|
|
|
- addStabilityInput();
|
|
|
- }
|
|
|
-
|
|
|
- // 设置值
|
|
|
- const input = document.querySelector(`#stability-inputs .input-row:nth-child(${index + 1}) input`);
|
|
|
- if (input) {
|
|
|
- input.value = value;
|
|
|
- }
|
|
|
+function newProject() {
|
|
|
+ if (confirm('确定要新建工程吗?这将清除所有当前数据!')) {
|
|
|
+ // 清除整个localStorage
|
|
|
+ localStorage.clear();
|
|
|
+ // 刷新页面
|
|
|
+ location.reload();
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // 设置时间
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = `${time}: `;
|
|
|
- stabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
|
|
|
- // 计算结果
|
|
|
- calculateStability();
|
|
|
- }
|
|
|
+// 导出数据
|
|
|
+function exportData() {
|
|
|
+ // 获取所有localStorage数据
|
|
|
+ const data = {};
|
|
|
+ for (let i = 0; i < localStorage.length; i++) {
|
|
|
+ const key = localStorage.key(i);
|
|
|
+ try {
|
|
|
+ // 尝试解析JSON数据
|
|
|
+ const value = localStorage.getItem(key);
|
|
|
+ data[key] = JSON.parse(value);
|
|
|
} catch (e) {
|
|
|
- console.error('加载稳定性数据失败:', e);
|
|
|
+ // 如果不是JSON格式则直接存储原始值
|
|
|
+ data[key] = localStorage.getItem(key);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 加载示值误差数据
|
|
|
- const savedErrorData = getLocalStorage('errorData');
|
|
|
- if (savedErrorData) {
|
|
|
- try {
|
|
|
- const errorData = JSON.parse(savedErrorData);
|
|
|
+ const projectTitle = document.getElementById('project-title').value;
|
|
|
+ const jsonString = JSON.stringify(data, null, 2);
|
|
|
+ const blob = new Blob([jsonString], { type: 'application/json' });
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
+
|
|
|
+ const a = document.createElement('a');
|
|
|
+ a.href = url;
|
|
|
+ const fileName = `_LabStatistics_${new Date().toISOString().split('.')[0]}.json`;
|
|
|
+ a.download = `${projectTitle}${fileName.replace(/-/g, '_')}`;
|
|
|
+ document.body.appendChild(a);
|
|
|
+ a.click();
|
|
|
+ document.body.removeChild(a);
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+}
|
|
|
|
|
|
- // 清除现有的测试点
|
|
|
- const errorContainer = document.getElementById('error-inputs');
|
|
|
- while (errorContainer.firstChild) {
|
|
|
- errorContainer.removeChild(errorContainer.firstChild);
|
|
|
- }
|
|
|
+// 导入数据
|
|
|
+function importData() {
|
|
|
+ const fileInput = document.getElementById('importFile');
|
|
|
+ const file = fileInput.files[0];
|
|
|
|
|
|
- // 添加保存的测试点
|
|
|
- errorData.forEach(item => {
|
|
|
- const pointContainer = createErrorPointContainer(item.point);
|
|
|
- errorContainer.appendChild(pointContainer);
|
|
|
+ if (!file) {
|
|
|
+ alert('请选择要导入的文件!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // 填充输入值
|
|
|
- const inputs = pointContainer.querySelectorAll('.error-input');
|
|
|
- item.inputs.forEach((value, index) => {
|
|
|
- if (index < inputs.length) {
|
|
|
- inputs[index].value = value;
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = function (e) {
|
|
|
+ try {
|
|
|
+ const data = JSON.parse(e.target.result);
|
|
|
+
|
|
|
+ // 清除现有数据
|
|
|
+ localStorage.clear();
|
|
|
+
|
|
|
+ // 导入所有数据到localStorage
|
|
|
+ // 遍历数据对象的所有键
|
|
|
+ for (const key in data) {
|
|
|
+ try {
|
|
|
+ // 检查数据类型并相应处理
|
|
|
+ if (typeof data[key] === 'object' && data[key] !== null) {
|
|
|
+ // 对象类型数据转换为JSON字符串存储
|
|
|
+ localStorage.setItem(key, JSON.stringify(data[key]));
|
|
|
+ } else {
|
|
|
+ // 其他类型直接存储
|
|
|
+ localStorage.setItem(key, data[key]);
|
|
|
}
|
|
|
- });
|
|
|
- });
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`导入键 ${key} 时出错:`, error);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 计算结果
|
|
|
- calculateError();
|
|
|
- updateErrorPoints();
|
|
|
- } catch (e) {
|
|
|
- console.error('加载示值误差数据失败:', e);
|
|
|
+ // 导入完成后重新加载页面以更新显示
|
|
|
+ location.reload();
|
|
|
+
|
|
|
+ alert('数据导入成功!');
|
|
|
+ } catch (error) {
|
|
|
+ alert('导入失败!请检查文件格式。');
|
|
|
+ console.error('导入错误:', error);
|
|
|
}
|
|
|
- }
|
|
|
+ };
|
|
|
+ reader.readAsText(file);
|
|
|
}
|
|
|
-
|
|
|
-// 导出数据
|
|
|
-function exportData() {
|
|
|
- const data = {
|
|
|
- repeatability: {
|
|
|
- inputs: Array.from(document.querySelectorAll('#repeatability-inputs input[type="number"]')).map((input, index) => {
|
|
|
- const timeSpan = document.getElementById(`repeatability-time-text-${index + 1}`);
|
|
|
- return {
|
|
|
- value: input.value,
|
|
|
- time: timeSpan ? timeSpan.textContent.trim() : ''
|
|
|
- };
|
|
|
- }),
|
|
|
- results: {
|
|
|
- range: document.getElementById('range').innerText,
|
|
|
- mean: document.getElementById('mean').innerText,
|
|
|
- variance: document.getElementById('variance').innerText,
|
|
|
- stdDev: document.getElementById('stdDev').innerText,
|
|
|
- rsd: document.getElementById('rsd').innerText
|
|
|
- }
|
|
|
- },
|
|
|
- stability: {
|
|
|
- inputs: Array.from(document.querySelectorAll('#stability-inputs input[type="number"]')).map((input, index) => {
|
|
|
- const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
|
|
|
- return {
|
|
|
- value: input.value,
|
|
|
- time: timeSpan ? timeSpan.textContent.trim() : ''
|
|
|
- };
|
|
|
- }),
|
|
|
- results: {
|
|
|
- max: document.getElementById('stability-max').innerText,
|
|
|
- min: document.getElementById('stability-min').innerText,
|
|
|
- mean: document.getElementById('stability-mean').innerText,
|
|
|
- range: document.getElementById('stability-range').innerText
|
|
|
- }
|
|
|
- },
|
|
|
- error: Array.from(document.querySelectorAll('.error-point-container')).map(container => ({
|
|
|
- point: container.querySelector('.error-point-input').value,
|
|
|
- inputs: Array.from(container.querySelectorAll('.error-input')).map(input => input.value),
|
|
|
- avg: container.querySelector('.error-avg').innerText,
|
|
|
- error: container.querySelector('.error-value').innerText
|
|
|
- })),
|
|
|
- customParams: Array.from(document.querySelectorAll('#custom-params-container .custom-param-row')).map(row => ({
|
|
|
- name: row.querySelector('.param-name').value,
|
|
|
- value: row.querySelector('.param-value').value
|
|
|
- })),
|
|
|
- projectTitle: document.getElementById('project-title').value,
|
|
|
- timestamp: new Date().toISOString()
|
|
|
- };
|
|
|
-
|
|
|
- const jsonString = JSON.stringify(data, null, 2);
|
|
|
- const blob = new Blob([jsonString], { type: 'application/json' });
|
|
|
- const url = URL.createObjectURL(blob);
|
|
|
-
|
|
|
- const a = document.createElement('a');
|
|
|
- a.href = url;
|
|
|
- a.download = `lab-statistics-${new Date().toISOString().slice(0, 10)}.json`;
|
|
|
- document.body.appendChild(a);
|
|
|
- a.click();
|
|
|
- document.body.removeChild(a);
|
|
|
- URL.revokeObjectURL(url);
|
|
|
-
|
|
|
- // 保存所有数据到localStorage
|
|
|
- saveDataToLocalStorage();
|
|
|
- }
|
|
|
-
|
|
|
-// 导入数据
|
|
|
-function importData() {
|
|
|
- const fileInput = document.getElementById('importFile');
|
|
|
- const file = fileInput.files[0];
|
|
|
-
|
|
|
- if (!file) {
|
|
|
- alert('请选择要导入的文件!');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const reader = new FileReader();
|
|
|
- reader.onload = function(e) {
|
|
|
- try {
|
|
|
- const data = JSON.parse(e.target.result);
|
|
|
-
|
|
|
- // 导入项目标题
|
|
|
- if (data.projectTitle) {
|
|
|
- document.getElementById('project-title').value = data.projectTitle;
|
|
|
- updateProjectTitle();
|
|
|
- }
|
|
|
-
|
|
|
- // 清除现有数据
|
|
|
- clearAllData();
|
|
|
-
|
|
|
- // 导入重复性数据
|
|
|
- if (data.repeatability && data.repeatability.inputs) {
|
|
|
- const inputsContainer = document.getElementById('repeatability-inputs');
|
|
|
- // 清除现有的额外输入框(保留前6个)
|
|
|
- while (inputsContainer.children.length > 6) {
|
|
|
- inputsContainer.removeChild(inputsContainer.lastChild);
|
|
|
- }
|
|
|
-
|
|
|
- // 获取现有的输入框
|
|
|
- const existingInputs = document.querySelectorAll('#repeatability-inputs input[type="number"]');
|
|
|
-
|
|
|
- // 填充现有输入框的值
|
|
|
- data.repeatability.inputs.forEach((item, index) => {
|
|
|
- const value = typeof item === 'object' ? item.value : item;
|
|
|
- const time = typeof item === 'object' ? item.time : '';
|
|
|
-
|
|
|
- if (index < existingInputs.length) {
|
|
|
- // 如果有对应的输入框,直接设置值
|
|
|
- existingInputs[index].value = value;
|
|
|
-
|
|
|
- // 更新时间显示
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`repeatability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = time + ' ';
|
|
|
- repeatabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果没有对应的输入框,创建新的
|
|
|
- addRepeatabilityInput();
|
|
|
- // 获取新创建的输入框并设置值
|
|
|
- const newInput = document.querySelector('#repeatability-inputs .input-row:last-child input');
|
|
|
- newInput.value = value;
|
|
|
-
|
|
|
- // 更新时间显示
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`repeatability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = time + ' ';
|
|
|
- repeatabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- calculateRepeatability();
|
|
|
- }
|
|
|
-
|
|
|
- // 导入稳定性数据
|
|
|
- if (data.stability && data.stability.inputs) {
|
|
|
- const inputsContainer = document.getElementById('stability-inputs');
|
|
|
- // 清除现有的额外输入框(保留前6个)
|
|
|
- while (inputsContainer.children.length > 6) {
|
|
|
- inputsContainer.removeChild(inputsContainer.lastChild);
|
|
|
- }
|
|
|
-
|
|
|
- // 获取现有的输入框
|
|
|
- const existingInputs = document.querySelectorAll('#stability-inputs input[type="number"]');
|
|
|
-
|
|
|
- // 填充现有输入框的值
|
|
|
- data.stability.inputs.forEach((item, index) => {
|
|
|
- const value = typeof item === 'object' ? item.value : item;
|
|
|
- const time = typeof item === 'object' ? item.time : '';
|
|
|
-
|
|
|
- if (index < existingInputs.length) {
|
|
|
- // 如果有对应的输入框,直接设置值
|
|
|
- existingInputs[index].value = value;
|
|
|
-
|
|
|
- // 更新时间显示
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = time + ' ';
|
|
|
- stabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果没有对应的输入框,创建新的
|
|
|
- addStabilityInput();
|
|
|
- // 获取新创建的输入框并设置值
|
|
|
- const newInput = document.querySelector('#stability-inputs .input-row:last-child input');
|
|
|
- newInput.value = value;
|
|
|
-
|
|
|
- // 更新时间显示
|
|
|
- if (time) {
|
|
|
- const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
|
|
|
- if (timeSpan) {
|
|
|
- timeSpan.textContent = time + ' ';
|
|
|
- stabilityTimes[index] = time;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- calculateStability();
|
|
|
- }
|
|
|
-
|
|
|
- // 导入示值误差数据
|
|
|
- if (data.error && data.error.length > 0) {
|
|
|
- const errorContainer = document.getElementById('error-inputs');
|
|
|
- while (errorContainer.firstChild) {
|
|
|
- errorContainer.removeChild(errorContainer.firstChild);
|
|
|
- }
|
|
|
-
|
|
|
- // 处理导入的测试点数据
|
|
|
- data.error.forEach(item => {
|
|
|
- addErrorPoint();
|
|
|
- const pointContainers = document.querySelectorAll('.error-point-container');
|
|
|
- const pointContainer = pointContainers[pointContainers.length - 1];
|
|
|
-
|
|
|
- // 更新测试点的输入框值
|
|
|
- const pointInput = pointContainer.querySelector('.error-point-input');
|
|
|
- pointInput.value = item.point;
|
|
|
- pointInput.setAttribute('data-original', item.point);
|
|
|
-
|
|
|
- // 更新输入框的data-point属性
|
|
|
- const inputs = pointContainer.querySelectorAll('.error-input');
|
|
|
- inputs.forEach(input => {
|
|
|
- input.setAttribute('data-point', item.point);
|
|
|
- });
|
|
|
-
|
|
|
- // 更新结果span的data-point属性
|
|
|
- const avgSpan = pointContainer.querySelector('.error-avg');
|
|
|
- const errorSpan = pointContainer.querySelector('.error-value');
|
|
|
- avgSpan.setAttribute('data-point', item.point);
|
|
|
- errorSpan.setAttribute('data-point', item.point);
|
|
|
-
|
|
|
- // 填充输入值
|
|
|
- item.inputs.forEach((value, index) => {
|
|
|
- if (index < inputs.length) {
|
|
|
- inputs[index].value = value;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- calculateError();
|
|
|
- }
|
|
|
-
|
|
|
- // 导入自定义参数数据
|
|
|
- if (data.customParams && data.customParams.length > 0) {
|
|
|
- const container = document.getElementById('custom-params-container');
|
|
|
- while (container.firstChild) {
|
|
|
- container.removeChild(container.firstChild);
|
|
|
- }
|
|
|
-
|
|
|
- // 添加保存的自定义参数
|
|
|
- data.customParams.forEach(param => {
|
|
|
- const paramRow = document.createElement('div');
|
|
|
- paramRow.className = 'custom-param-row';
|
|
|
- paramRow.style.display = 'flex';
|
|
|
- paramRow.style.alignItems = 'center';
|
|
|
- paramRow.style.gap = '0.5rem';
|
|
|
-
|
|
|
- const nameInput = document.createElement('input');
|
|
|
- nameInput.type = 'text';
|
|
|
- nameInput.className = 'param-name';
|
|
|
- nameInput.placeholder = '参数名称';
|
|
|
- nameInput.style.flex = '1';
|
|
|
- nameInput.style.padding = '0.5rem';
|
|
|
- nameInput.style.border = '1px solid #ccc';
|
|
|
- nameInput.style.borderRadius = '4px';
|
|
|
- nameInput.value = param.name;
|
|
|
- nameInput.oninput = saveCustomParamsData;
|
|
|
-
|
|
|
- const valueInput = document.createElement('input');
|
|
|
- valueInput.type = 'text';
|
|
|
- valueInput.className = 'param-value';
|
|
|
- valueInput.placeholder = '参数值';
|
|
|
- valueInput.style.flex = '1';
|
|
|
- valueInput.style.padding = '0.5rem';
|
|
|
- valueInput.style.border = '1px solid #ccc';
|
|
|
- valueInput.style.borderRadius = '4px';
|
|
|
- valueInput.value = param.value;
|
|
|
- valueInput.oninput = saveCustomParamsData;
|
|
|
-
|
|
|
- const deleteBtn = document.createElement('span');
|
|
|
- deleteBtn.className = 'delete-btn';
|
|
|
- deleteBtn.innerHTML = '×';
|
|
|
- deleteBtn.onclick = function () {
|
|
|
- container.removeChild(paramRow);
|
|
|
- saveCustomParamsData();
|
|
|
- };
|
|
|
-
|
|
|
- paramRow.appendChild(nameInput);
|
|
|
- paramRow.appendChild(valueInput);
|
|
|
- paramRow.appendChild(deleteBtn);
|
|
|
- container.appendChild(paramRow);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 保存所有数据到localStorage
|
|
|
- saveDataToLocalStorage();
|
|
|
-
|
|
|
- alert('数据导入成功!');
|
|
|
- } catch (error) {
|
|
|
- alert('导入失败!请检查文件格式。');
|
|
|
- console.error('导入错误:', error);
|
|
|
- }
|
|
|
- };
|
|
|
- reader.readAsText(file);
|
|
|
- }
|
|
|
-
|
|
|
-// 保存所有数据到localStorage(兼容性函数)
|
|
|
-function saveDataToLocalStorage() {
|
|
|
- saveRepeatabilityData();
|
|
|
- saveStabilityData();
|
|
|
- saveErrorData();
|
|
|
- saveCustomParamsData();
|
|
|
-}
|