pageRepeatability.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // repeatability.js - 重复性测试相关功能
  2. // 重复性测试时间数组
  3. let repeatabilityTimes = [];
  4. // 图表相关变量
  5. let ctx = null;
  6. let chartInstance = null;
  7. // 初始化重复性图表
  8. function initRepeatabilityChart() {
  9. ctx = document.getElementById('lineChart').getContext('2d');
  10. }
  11. // 在页面加载完成后初始化图表
  12. document.addEventListener('DOMContentLoaded', function() {
  13. initRepeatabilityChart();
  14. });
  15. // 更新重复性输入框的占位符
  16. function updateRepeatabilityInputPlaceholders() {
  17. document.querySelectorAll('#repeatability-inputs input[type="number"]').forEach((input, index) => {
  18. input.placeholder = `测量值 ${index + 1}`;
  19. });
  20. }
  21. // 更新重复性输入框的删除按钮
  22. function updateRepeatabilityDeleteButtons() {
  23. const repeatabilityInputs = document.querySelectorAll('#repeatability-inputs .input-row');
  24. repeatabilityInputs.forEach((row, index) => {
  25. const deleteBtn = row.querySelector('.delete-btn');
  26. if (deleteBtn) {
  27. deleteBtn.style.display = index < 6 ? 'none' : 'inline';
  28. }
  29. });
  30. }
  31. // 重复性测试函数
  32. function addRepeatabilityInput() {
  33. const container = document.getElementById('repeatability-inputs');
  34. const newIndex = container.children.length + 1;
  35. const row = createInputRow(newIndex, 'repeatability', recordTimeAndCalculateRepeatability, deleteRepeatabilityInput);
  36. container.appendChild(row);
  37. updateRepeatabilityInputPlaceholders();
  38. }
  39. function deleteRepeatabilityInput(btn) {
  40. const row = btn.parentNode;
  41. const container = row.parentNode;
  42. const index = Array.from(container.children).indexOf(row);
  43. // 移除对应的时间记录
  44. repeatabilityTimes.splice(index, 1);
  45. // 移除输入行
  46. container.removeChild(row);
  47. // 更新剩余输入行的索引
  48. const rows = container.querySelectorAll('.input-row');
  49. rows.forEach((row, i) => {
  50. const timeSpan = row.querySelector(`span[id^="repeatability-time-text-"]`);
  51. const input = row.querySelector(`input[id^="repeatability-value-"]`);
  52. // 更新ID和文本
  53. const newIndex = i + 1;
  54. timeSpan.id = `repeatability-time-text-${newIndex}`;
  55. input.id = `repeatability-value-${newIndex}`;
  56. // 如果有保存的时间,则显示时间,否则显示索引
  57. if (repeatabilityTimes[i]) {
  58. timeSpan.textContent = `${repeatabilityTimes[i]}: `;
  59. } else {
  60. timeSpan.textContent = `${newIndex}: `;
  61. }
  62. // 更新输入事件
  63. input.oninput = function() { recordTimeAndCalculateRepeatability(newIndex); };
  64. });
  65. updateRepeatabilityInputPlaceholders();
  66. calculateRepeatability();
  67. saveRepeatabilityData();
  68. }
  69. function recordTimeAndCalculateRepeatability(index) {
  70. recordTimeAndCalculate('repeatability', index, repeatabilityTimes, calculateRepeatability);
  71. }
  72. function calculateRepeatability() {
  73. const values = getNumericInputs('#repeatability-inputs input[type="number"]');
  74. if (values.length >= 2) {
  75. // 计算统计量
  76. const max = Math.max(...values);
  77. const min = Math.min(...values);
  78. const range = max - min;
  79. const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
  80. // 计算方差和标准差
  81. const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;
  82. const stdDev = Math.sqrt(variance);
  83. const rsd = (stdDev / mean) * 100; // 相对标准偏差,以百分比表示
  84. // 更新结果显示
  85. updateResultDisplay('range', range);
  86. updateResultDisplay('mean', mean);
  87. updateResultDisplay('variance', variance);
  88. updateResultDisplay('stdDev', stdDev);
  89. updateResultDisplay('rsd', rsd);
  90. // 更新图表
  91. updateRepeatabilityChart(values);
  92. } else {
  93. // 清空结果显示
  94. document.querySelectorAll('#repeatability .result-item span').forEach(span => {
  95. span.innerText = '-';
  96. });
  97. // 清空图表
  98. if (chartInstance) {
  99. chartInstance.data.labels = [];
  100. chartInstance.data.datasets[0].data = [];
  101. chartInstance.update();
  102. }
  103. }
  104. }
  105. function updateRepeatabilityChart(values) {
  106. // 创建标签(1, 2, 3, ...)
  107. const labels = Array.from({length: values.length}, (_, i) => i + 1);
  108. // 使用通用图表创建函数
  109. chartInstance = createOrUpdateChart(chartInstance, ctx, labels, values, '重复性');
  110. }
  111. function saveRepeatabilityData() {
  112. collectAndSaveData('#repeatability-inputs input[type="number"]', 'repeatability-time-text', {
  113. range: 'range',
  114. mean: 'mean',
  115. variance: 'variance',
  116. stdDev: 'stdDev',
  117. rsd: 'rsd'
  118. }, 'repeatabilityData');
  119. }