| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- // error.js - 示值误差测试相关功能
- // 图表相关变量
- let errorCtx = null;
- let errorChartInstance = null;
- function initializeErrorPage() {
- // 生成示值误差标签页内容
- generateErrorTabContent();
- // 加载示值误差数据
- loadErrorData();
- }
- // 生成示值误差标签页内容
- function generateErrorTabContent() {
- console.log('generateErrorTabContent');
- const errorTab = document.createElement('div');
- errorTab.id = 'error';
- errorTab.className = 'tab-content';
- // 创建内容容器
- const contentContainer = document.createElement('div');
- contentContainer.className = 'content-container';
- // 创建输入部分
- const inputSection = document.createElement('div');
- inputSection.className = 'input-section';
- inputSection.style.width = '100%';
- // 创建误差容器
- const errorContainer = document.createElement('div');
- errorContainer.className = 'error-container';
- errorContainer.id = 'error-inputs';
- // 添加按钮
- const addInputBtn = document.createElement('div');
- addInputBtn.className = 'add-input-btn';
- addInputBtn.onclick = addErrorPoint;
- const addInputSpan = document.createElement('span');
- addInputSpan.textContent = '+ 添加测试点';
- addInputBtn.appendChild(addInputSpan);
- // 创建不确定度结果部分
- const uncertaintyResults = document.createElement('div');
- uncertaintyResults.className = 'uncertainty-results';
- uncertaintyResults.style.marginTop = '1rem';
- uncertaintyResults.style.padding = '1rem';
- uncertaintyResults.style.border = '1px solid #eee';
- uncertaintyResults.style.borderRadius = '4px';
- // 添加标题
- const uncertaintyTitle = document.createElement('h3');
- uncertaintyTitle.style.marginTop = '0';
- uncertaintyTitle.textContent = '示值误差校准结果不确定度';
- uncertaintyResults.appendChild(uncertaintyTitle);
- // 创建结果显示
- const results = document.createElement('div');
- results.className = 'results';
- // 添加结果项
- const resultItems = [
- { label: 'A类不确定度(uA):', id: 'uncertainty-a' },
- { label: 'B类不确定度(uB):', id: 'uncertainty-b' },
- { label: 'C类不确定度(uc):', id: 'uncertainty-c' },
- { label: '扩展不确定度(U):', id: 'uncertainty-u' }
- ];
- resultItems.forEach(item => {
- const resultItem = document.createElement('div');
- resultItem.className = 'result-item';
- resultItem.innerHTML = `${item.label} <span id="${item.id}">-</span>`;
- results.appendChild(resultItem);
- });
- uncertaintyResults.appendChild(results);
- // 创建图表容器
- const chartContainer = document.createElement('div');
- chartContainer.className = 'chart-container';
- const canvas = document.createElement('canvas');
- canvas.id = 'errorChart';
- chartContainer.appendChild(canvas);
- errorCtx = canvas.getContext('2d');
- // 组装输入部分
- inputSection.appendChild(errorContainer);
- inputSection.appendChild(addInputBtn);
- inputSection.appendChild(uncertaintyResults);
- inputSection.appendChild(chartContainer);
- // 组装整个内容
- contentContainer.appendChild(inputSection);
- errorTab.appendChild(contentContainer);
- if (document.getElementById('container')) {
- console.log('appendChild errorTab');
- document.getElementById('container').appendChild(errorTab);
- }
- // 添加初始示值误差测试点(因为已移除所有默认测试点)
- if (document.querySelectorAll('#error-inputs .error-point-container').length === 0) {
- addErrorPoint();
- }
- }
- // 示值误差测试点容器创建
- function createErrorPointContainer(pointValue = '') {
- const container = document.createElement('div');
- container.className = 'error-point-container';
- container.style.marginBottom = '1rem';
- container.style.padding = '1rem';
- container.style.border = '1px solid #eee';
- container.style.borderRadius = '4px';
- // 测试点输入
- const pointRow = document.createElement('div');
- pointRow.style.display = 'flex';
- pointRow.style.alignItems = 'center';
- pointRow.style.marginBottom = '0.5rem';
- const pointLabel = document.createElement('label');
- pointLabel.textContent = '测试点:';
- pointLabel.style.marginRight = '0.5rem';
- pointLabel.style.fontWeight = 'bold';
- const pointInput = document.createElement('input');
- pointInput.type = 'number';
- pointInput.className = 'error-point-input';
- pointInput.placeholder = '测试点';
- pointInput.value = pointValue;
- pointInput.setAttribute('data-original', pointValue);
- pointInput.style.flex = '1';
- pointInput.style.marginRight = '0.5rem';
- pointInput.oninput = function () {
- updateErrorPoint(this);
- // 保存示值误差数据
- saveErrorData();
- };
- const deleteBtn = document.createElement('span');
- deleteBtn.className = 'delete-btn';
- deleteBtn.innerHTML = '×';
- deleteBtn.onclick = function () {
- container.parentNode.removeChild(container);
- calculateError();
- // 保存误差数据
- saveErrorData();
- };
- pointRow.appendChild(pointLabel);
- pointRow.appendChild(pointInput);
- pointRow.appendChild(deleteBtn);
- // 输入值部分
- const inputsContainer = document.createElement('div');
- inputsContainer.className = 'error-inputs';
- inputsContainer.style.display = 'flex';
- inputsContainer.style.flexWrap = 'wrap';
- inputsContainer.style.gap = '0.5rem';
- inputsContainer.style.marginBottom = '0.5rem';
- // 添加3个默认输入框
- for (let i = 0; i < 3; i++) {
- const input = document.createElement('input');
- input.type = 'number';
- input.className = 'error-input';
- input.placeholder = `输入值`;
- input.setAttribute('data-point', pointValue);
- input.style.flex = '1';
- input.style.minWidth = '100px';
- input.oninput = function () {
- calculateError();
- // 保存误差数据到localStorage
- saveErrorData();
- };
- inputsContainer.appendChild(input);
- }
- // 结果显示部分
- const resultsRow = document.createElement('div');
- resultsRow.style.display = 'flex';
- resultsRow.style.flexDirection = 'column';
- const avgContainer = document.createElement('div');
- avgContainer.style.flex = '1';
- const avgLabel = document.createElement('span');
- avgLabel.textContent = '平均值:';
- avgLabel.style.fontWeight = 'bold';
- const avgSpan = document.createElement('span');
- avgSpan.className = 'error-avg';
- avgSpan.setAttribute('data-point', pointValue);
- avgSpan.textContent = '-';
- avgContainer.appendChild(avgLabel);
- avgContainer.appendChild(avgSpan);
- const errorContainer = document.createElement('div');
- errorContainer.style.flex = '1';
- const errorLabel = document.createElement('span');
- errorLabel.textContent = '示值误差:';
- errorLabel.style.fontWeight = 'bold';
- const errorSpan = document.createElement('span');
- errorSpan.className = 'error-value';
- errorSpan.setAttribute('data-point', pointValue);
- errorSpan.textContent = '-';
- errorContainer.appendChild(errorLabel);
- errorContainer.appendChild(errorSpan);
- resultsRow.appendChild(avgContainer);
- resultsRow.appendChild(errorContainer);
- container.appendChild(pointRow);
- container.appendChild(inputsContainer);
- container.appendChild(resultsRow);
- return container;
- }
- // 示值误差测试点添加
- function addErrorPoint() {
- const container = document.getElementById('error-inputs');
- const pointContainer = createErrorPointContainer();
- container.appendChild(pointContainer);
- }
- // 示值误差测试点更新
- function updateErrorPoint(input) {
- const pointContainer = input.closest('.error-point-container');
- const originalValue = input.getAttribute('data-original');
- const newValue = input.value;
- // 如果测试点值发生变化,更新所有相关元素的data-point属性
- if (originalValue !== newValue) {
- input.setAttribute('data-original', newValue);
- pointContainer.querySelectorAll('.error-input').forEach(input => {
- input.setAttribute('data-point', newValue);
- });
- pointContainer.querySelector('.error-avg').setAttribute('data-point', newValue);
- pointContainer.querySelector('.error-value').setAttribute('data-point', newValue);
- }
- calculateError();
- saveErrorData();
- }
- // 清除示值误差数据
- function clearErrorData() {
- // 清除示值误差数据
- const errorContainer = document.getElementById('error-inputs');
- while (errorContainer.firstChild) {
- errorContainer.removeChild(errorContainer.firstChild);
- }
- addErrorPoint();
- // 重置图表
- if (errorChartInstance) {
- errorChartInstance.destroy();
- errorChartInstance = null;
- }
- }
- // 示值误差数据计算
- function calculateError() {
- const pointContainers = document.querySelectorAll('.error-point-container');
- const errorData = [];
- pointContainers.forEach(container => {
- const pointInput = container.querySelector('.error-point-input');
- const inputs = container.querySelectorAll('.error-input');
- const avgSpan = container.querySelector('.error-avg');
- const errorSpan = container.querySelector('.error-value');
- const pointValue = parseFloat(pointInput.value);
- const values = Array.from(inputs)
- .map(input => parseFloat(input.value))
- .filter(value => !isNaN(value));
- if (!isNaN(pointValue) && values.length > 0) {
- // 计算平均值
- const avg = values.reduce((sum, val) => sum + val, 0) / values.length;
- // 计算示值误差
- const error = avg - pointValue;
- // 更新显示
- avgSpan.textContent = avg.toFixed(6);
- errorSpan.textContent = error.toFixed(6);
- // 收集数据用于图表和不确定度计算
- errorData.push({
- point: pointValue,
- avg: avg,
- error: error
- });
- } else {
- avgSpan.textContent = '-';
- errorSpan.textContent = '-';
- }
- });
- // 计算不确定度
- calculateUncertainty(errorData);
- // 保存误差数据
- saveErrorData();
- // 更新图表
- updateErrorChart(errorData);
- return errorData;
- }
- // 示值误差不确定度计算
- function calculateUncertainty(errorData) {
- if (errorData.length === 0) {
- // 清空不确定度显示
- document.getElementById('uncertainty-a').textContent = '-';
- document.getElementById('uncertainty-b').textContent = '-';
- document.getElementById('uncertainty-c').textContent = '-';
- document.getElementById('uncertainty-u').textContent = '-';
- return;
- }
- // 计算A类不确定度(重复测量的标准偏差)
- let sumSquaredDeviations = 0;
- let totalMeasurements = 0;
- document.querySelectorAll('.error-point-container').forEach(container => {
- const inputs = container.querySelectorAll('.error-input');
- const values = Array.from(inputs)
- .map(input => parseFloat(input.value))
- .filter(value => !isNaN(value));
- if (values.length > 0) {
- const avg = values.reduce((sum, val) => sum + val, 0) / values.length;
- values.forEach(value => {
- sumSquaredDeviations += Math.pow(value - avg, 2);
- });
- totalMeasurements += values.length;
- }
- });
- // 计算A类不确定度
- const uA = totalMeasurements > 1 ? Math.sqrt(sumSquaredDeviations / (totalMeasurements * (totalMeasurements - 1))) : 0;
- // 假设B类不确定度(仪器分辨率引起的不确定度)
- // 这里假设分辨率为0.001,则B类不确定度为0.001/√3
- const resolution = 0.001;
- const uB = resolution / Math.sqrt(3);
- // 合成不确定度
- const uC = Math.sqrt(Math.pow(uA, 2) + Math.pow(uB, 2));
- // 扩展不确定度(k=2,约95%置信水平)
- const U = 2 * uC;
- // 更新显示
- document.getElementById('uncertainty-a').textContent = uA.toExponential(3);
- document.getElementById('uncertainty-b').textContent = uB.toExponential(3);
- document.getElementById('uncertainty-c').textContent = uC.toExponential(3);
- document.getElementById('uncertainty-u').textContent = U.toExponential(3);
- }
- // 示值误差图表更新
- function updateErrorChart(data) {
- if (data.length === 0) {
- if (errorChartInstance) {
- errorChartInstance.data.labels = [];
- errorChartInstance.data.datasets[0].data = [];
- errorChartInstance.update();
- }
- return;
- }
- // 按测试点值排序
- data.sort((a, b) => a.point - b.point);
- // 提取标签和误差值
- const labels = data.map(item => item.point);
- const errorValues = data.map(item => item.error);
- // 使用通用图表创建函数
- errorChartInstance = createOrUpdateChart(errorChartInstance, errorCtx, labels, errorValues, '示值误差');
- }
- // 示值误差数据保存
- function saveErrorData() {
- // 收集输入数据
- const inputs = Array.from(document.querySelectorAll('.error-point-container')).map(container => {
- const pointInput = container.querySelector('.error-point-input');
- const inputs = container.querySelectorAll('.error-input');
- const avgSpan = container.querySelector('.error-avg');
- const errorSpan = container.querySelector('.error-value');
- return {
- point: pointInput.value,
- value: Array.from(inputs).map(input => input.value),
- avg: avgSpan.innerText,
- error: errorSpan.innerText
- };
- });
- // 收集结果数据
- const results = {
- uncertainty_a: document.getElementById('uncertainty-a').textContent,
- uncertainty_b: document.getElementById('uncertainty-b').textContent,
- uncertainty_c: document.getElementById('uncertainty-c').textContent,
- uncertainty_u: document.getElementById('uncertainty-u').textContent
- };
- const data = {
- inputs: inputs,
- results: results
- };
- const dataName = 'errorData';
- console.log(dataName, data);
- setLocalStorage(dataName, JSON.stringify(data));
- }
- // 示值误差数据加载
- function loadErrorData() {
- const savedErrorData = getLocalStorage('errorData');
- if (savedErrorData) {
- try {
- const data = JSON.parse(savedErrorData);
- // 清除现有的测试点
- const errorContainer = document.getElementById('error-inputs');
- while (errorContainer.firstChild) {
- errorContainer.removeChild(errorContainer.firstChild);
- }
- // 添加保存的测试点
- if (data.inputs && data.inputs.length > 0) {
- data.inputs.forEach((item, index) => {
- const point = typeof item === 'object' ? item.point : '';
- const value = typeof item === 'object' ? item.value : '';
- const pointContainer = createErrorPointContainer(item.point);
- errorContainer.appendChild(pointContainer);
- // 填充测试点
- pointContainer.querySelector('.error-point-input').value = point;
- // 填充输入值
- const inputs = pointContainer.querySelectorAll('.error-input');
- value.forEach((value, index) => {
- if (index < inputs.length) {
- inputs[index].value = value;
- }
- });
- });
- }
- // 计算结果
- calculateError();
- } catch (e) {
- console.error('加载示值误差数据失败:', e);
- }
- }
- }
|