| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // error.js - 示值误差测试相关功能
- // 图表相关变量
- let errorCtx = null;
- let errorChartInstance = null;
- // 初始化示值误差图表
- function initErrorChart() {
- errorCtx = document.getElementById('errorChart').getContext('2d');
- }
- // 在页面加载完成后初始化图表
- document.addEventListener('DOMContentLoaded', function() {
- initErrorChart();
- });
- // 示值误差测试函数
- 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();
- }
- 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);
- // 保存示值误差数据到cookies
- saveErrorData();
- };
- const deleteBtn = document.createElement('span');
- deleteBtn.className = 'delete-btn';
- deleteBtn.innerHTML = '×';
- deleteBtn.onclick = function () {
- container.parentNode.removeChild(container);
- // 如果删除后没有测试点,添加一个新的空白测试点
- if (document.querySelectorAll('.error-point-container').length === 0) {
- addErrorPoint();
- }
- calculateError();
- // 保存误差数据到cookies
- 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 = `输入值 ${i + 1}`;
- input.setAttribute('data-point', pointValue);
- input.style.flex = '1';
- input.style.minWidth = '100px';
- input.oninput = function () {
- calculateError();
- // 保存误差数据到cookies
- saveErrorData();
- };
- inputsContainer.appendChild(input);
- }
- // 结果显示部分
- const resultsRow = document.createElement('div');
- resultsRow.style.display = 'flex';
- resultsRow.style.gap = '1rem';
- 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);
- updateErrorPoints();
- }
- 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 = '-';
- }
- });
- // 更新图表
- updateErrorChart(errorData);
- // 计算不确定度
- calculateUncertainty(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 errorData = 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,
- inputs: Array.from(inputs).map(input => input.value),
- avg: avgSpan.innerText,
- error: errorSpan.innerText
- };
- });
- setCookie('errorData', JSON.stringify(errorData), 365);
- }
|