utils.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * 函数拟合工具 - 工具函数
  3. */
  4. /**
  5. * 从表格中获取数据点
  6. * @returns {Array} 数据点数组,每个元素包含x和y属性
  7. */
  8. function getDataPointsFromTable() {
  9. // 检查是否使用Excel风格表格
  10. const fitExcelTable = document.getElementById('fit-excel-table');
  11. if (fitExcelTable) {
  12. // 使用Excel表格数据提取函数
  13. return window.dataTable.getDataPointsFromExcelTable(fitExcelTable);
  14. }
  15. // 兼容旧版表格
  16. const dataTable = document.getElementById('data-table');
  17. if (!dataTable) return [];
  18. const rows = dataTable.querySelectorAll('tbody tr');
  19. const dataPoints = [];
  20. rows.forEach(row => {
  21. const xInput = row.querySelector('.x-value');
  22. const yInput = row.querySelector('.y-value');
  23. if (xInput && yInput) {
  24. const x = parseFloat(xInput.value);
  25. const y = parseFloat(yInput.value);
  26. if (!isNaN(x) && !isNaN(y)) {
  27. dataPoints.push({ x, y });
  28. }
  29. }
  30. });
  31. return dataPoints;
  32. }
  33. /**
  34. * 格式化数字,保留指定小数位
  35. * @param {number} value - 要格式化的数值
  36. * @param {number} decimals - 小数位数
  37. * @returns {string} 格式化后的数字字符串
  38. */
  39. function formatNumber(value, decimals = 4) {
  40. return Number(value).toFixed(decimals);
  41. }
  42. /**
  43. * 计算相关系数 (R²)
  44. * @param {Array} xValues - X值数组
  45. * @param {Array} yValues - Y值数组
  46. * @param {Function} predictFn - 预测函数,接收x返回预测的y
  47. * @returns {number} 相关系数
  48. */
  49. function calculateRSquared(xValues, yValues, predictFn) {
  50. if (xValues.length !== yValues.length || xValues.length === 0) {
  51. return 0;
  52. }
  53. // 计算y的平均值
  54. const yMean = yValues.reduce((sum, y) => sum + y, 0) / yValues.length;
  55. // 计算总平方和(SST)
  56. const sst = yValues.reduce((sum, y) => sum + Math.pow(y - yMean, 2), 0);
  57. // 计算残差平方和(SSE)
  58. let sse = 0;
  59. for (let i = 0; i < xValues.length; i++) {
  60. const yPred = predictFn(xValues[i]);
  61. sse += Math.pow(yValues[i] - yPred, 2);
  62. }
  63. // 计算R²
  64. return 1 - (sse / sst);
  65. }
  66. /**
  67. * 计算均方根误差(RMSE)
  68. * @param {Array} xValues - X值数组
  69. * @param {Array} yValues - Y值数组
  70. * @param {Function} predictFn - 预测函数,接收x返回预测的y
  71. * @returns {number} RMSE值
  72. */
  73. function calculateRMSE(xValues, yValues, predictFn) {
  74. if (xValues.length !== yValues.length || xValues.length === 0) {
  75. return 0;
  76. }
  77. let sumSquaredError = 0;
  78. for (let i = 0; i < xValues.length; i++) {
  79. const yPred = predictFn(xValues[i]);
  80. sumSquaredError += Math.pow(yValues[i] - yPred, 2);
  81. }
  82. return Math.sqrt(sumSquaredError / xValues.length);
  83. }
  84. /**
  85. * 生成统计结果HTML
  86. * @param {Object} params - 统计参数
  87. * @returns {string} HTML字符串
  88. */
  89. function generateStatsHTML(params) {
  90. const { coefficients, rSquared, rmse, formula, dataPoints } = params;
  91. let html = '<h4>拟合统计</h4>';
  92. html += '<table>';
  93. html += '<tr><th>参数</th><th>值</th></tr>';
  94. html += `<tr><td>数据点数量</td><td>${dataPoints}</td></tr>`;
  95. html += `<tr><td>决定系数 (R²)</td><td>${formatNumber(rSquared)}</td></tr>`;
  96. html += `<tr><td>均方根误差 (RMSE)</td><td>${formatNumber(rmse)}</td></tr>`;
  97. html += '<tr><th colspan="2">系数</th></tr>';
  98. if (Array.isArray(coefficients)) {
  99. coefficients.forEach((coef, index) => {
  100. let coefName = '';
  101. switch (index) {
  102. case 0: coefName = formula === 'linear' ? 'a (斜率)' : 'a'; break;
  103. case 1: coefName = formula === 'linear' ? 'b (截距)' : 'b'; break;
  104. default: coefName = String.fromCharCode(97 + index); // a, b, c, d...
  105. }
  106. html += `<tr><td>${coefName}</td><td>${formatNumber(coef)}</td></tr>`;
  107. });
  108. } else if (typeof coefficients === 'object') {
  109. for (const key in coefficients) {
  110. html += `<tr><td>${key}</td><td>${formatNumber(coefficients[key])}</td></tr>`;
  111. }
  112. }
  113. html += '</table>';
  114. return html;
  115. }