| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- // 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;
- }
- });
- }
- // 保存到localStorage
- const data = {
- inputs: inputs,
- results: results
- };
- console.log(data);
-
- setLocalStorage(cookieName, JSON.stringify(data));
- }
- // 添加自定义参数
- function addCustomParam() {
- const container = document.getElementById('custom-params-container');
- 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.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.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);
- }
- // 保存自定义参数数据
- function saveCustomParamsData() {
- const 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
- }));
- setLocalStorage('customParamsData', JSON.stringify(customParams), 365);
- }
- // 从localStorage加载自定义参数
- function loadCustomParamsFromLocalStorage() {
- const savedParams = getLocalStorage('customParamsData');
- if (savedParams) {
- try {
- const params = JSON.parse(savedParams);
- const container = document.getElementById('custom-params-container');
- // 清除现有参数
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
- // 添加保存的自定义参数
- params.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);
- });
- } catch (e) {
- console.error('加载自定义参数失败:', e);
- }
- }
- }
- // 从localStorage加载数据
- function loadDataFromLocalStorage() {
- // 加载重复性数据
- const savedRepeatabilityData = getLocalStorage('repeatabilityData');
- if (savedRepeatabilityData) {
- try {
- const data = JSON.parse(savedRepeatabilityData);
- // 清除现有的额外输入框(保留前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();
- }
- } catch (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;
- }
- // 设置时间
- if (time) {
- const timeSpan = document.getElementById(`stability-time-text-${index + 1}`);
- if (timeSpan) {
- timeSpan.textContent = `${time}: `;
- stabilityTimes[index] = time;
- }
- }
- });
- // 计算结果
- calculateStability();
- }
- } catch (e) {
- console.error('加载稳定性数据失败:', e);
- }
- }
- // 加载示值误差数据
- const savedErrorData = getLocalStorage('errorData');
- if (savedErrorData) {
- try {
- const errorData = JSON.parse(savedErrorData);
- // 清除现有的测试点
- const errorContainer = document.getElementById('error-inputs');
- while (errorContainer.firstChild) {
- errorContainer.removeChild(errorContainer.firstChild);
- }
- // 添加保存的测试点
- errorData.forEach(item => {
- const pointContainer = createErrorPointContainer(item.point);
- errorContainer.appendChild(pointContainer);
- // 填充输入值
- const inputs = pointContainer.querySelectorAll('.error-input');
- item.inputs.forEach((value, index) => {
- if (index < inputs.length) {
- inputs[index].value = value;
- }
- });
- });
- // 计算结果
- calculateError();
- updateErrorPoints();
- } catch (e) {
- console.error('加载示值误差数据失败:', e);
- }
- }
- }
- // 导出数据
- 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();
- }
|