rapid-spreadjs 1.0.101 → 1.0.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -8611,6 +8611,174 @@ const EChartsUtilsAll = {
8611
8611
  };
8612
8612
  return option;
8613
8613
  },
8614
+ /**
8615
+ * 最大剪应力与法向应力关系曲线
8616
+ * @param config 折线配置
8617
+ * @param xDataArr x轴原始数据(二维数组)
8618
+ * @param yDataArr y轴原始数据(二维数组)
8619
+ * @returns 返回ECharts配置项
8620
+ */
8621
+ chart450: (config, xDataArr, yDataArr) => {
8622
+ let lineData = JSON.parse(config.chartLinesJson);
8623
+ // const chartExtJson = config.chartExtJson == null || config.chartExtJson == undefined ? null : JSON.parse(config.chartExtJson);
8624
+ let title = config.chartTitle, xName = config.chartXName, yName = config.chartYName, color = lineData[0].lineColor;
8625
+ // 原始数据
8626
+ const xData = xDataArr[0];
8627
+ const yData = yDataArr[0];
8628
+ // 计算线性回归参数(斜率和截距)
8629
+ function linearRegression(x, y) {
8630
+ const n = x.length;
8631
+ let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
8632
+ for (let i = 0; i < n; i++) {
8633
+ sumX += x[i];
8634
+ sumY += y[i];
8635
+ sumXY += x[i] * y[i];
8636
+ sumXX += x[i] * x[i];
8637
+ }
8638
+ const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
8639
+ const intercept = (sumY - slope * sumX) / n;
8640
+ return { slope, intercept };
8641
+ }
8642
+ const regression = linearRegression(xData, yData);
8643
+ // console.log('斜率:', regression.slope, '截距:', regression.intercept);
8644
+ // 计算趋势线的数据点
8645
+ // 前推0.0,后推50.0
8646
+ Math.min(...xData);
8647
+ const maxX = Math.max(...xData) + 50; // 后推50
8648
+ // 生成趋势线数据点,确保与y轴相交(x=0)
8649
+ const trendData = [];
8650
+ for (let x = 0; x <= maxX; x += 10) {
8651
+ const y = regression.slope * x + regression.intercept;
8652
+ trendData.push([x, y]);
8653
+ }
8654
+ let yValIsAllNull = false;
8655
+ if (xData.length == 0 ||
8656
+ yData.length == 0 ||
8657
+ (!xData.some((x) => x != '' && x != '/' && x != null && x != undefined) &&
8658
+ !yData.some((x) => x != '' && x != '/' && x != null && x != undefined))) {
8659
+ yValIsAllNull = true;
8660
+ }
8661
+ if (xData.filter((x) => x == 0).length == xData.length || yData.filter((x) => x == 0).length == yData.length) {
8662
+ yValIsAllNull = true;
8663
+ }
8664
+ // 配置图表选项
8665
+ const option = {
8666
+ title: [
8667
+ {
8668
+ show: true,
8669
+ text: title,
8670
+ left: 'center',
8671
+ top: 2,
8672
+ textStyle: {
8673
+ fontSize: 14,
8674
+ fontWeight: 'normal',
8675
+ },
8676
+ },
8677
+ {
8678
+ show: true,
8679
+ text: xName,
8680
+ left: 'center',
8681
+ bottom: 0,
8682
+ textStyle: {
8683
+ fontSize: 12,
8684
+ fontWeight: 'normal',
8685
+ },
8686
+ },
8687
+ ],
8688
+ grid: {
8689
+ top: 25,
8690
+ left: 25,
8691
+ right: 15,
8692
+ bottom: 20,
8693
+ containLabel: true,
8694
+ },
8695
+ tooltip: {
8696
+ trigger: 'axis',
8697
+ formatter: function (params) {
8698
+ let result = '';
8699
+ params.forEach((param) => {
8700
+ if (param.seriesName === '实际数据') {
8701
+ result += `法向应力: ${param.value[0]} kPA<br/>剪应力: ${param.value[1]} kPA`;
8702
+ }
8703
+ else if (param.seriesName === '趋势线') {
8704
+ result += `趋势线<br/>法向应力: ${param.value[0]} kPA<br/>预测剪应力: ${param.value[1].toFixed(2)} kPA`;
8705
+ }
8706
+ });
8707
+ return result;
8708
+ },
8709
+ },
8710
+ xAxis: {
8711
+ name: xName,
8712
+ nameLocation: 'end',
8713
+ nameGap: 20,
8714
+ nameTextStyle: {
8715
+ fontSize: 12,
8716
+ fontWeight: 'bold',
8717
+ },
8718
+ type: 'value',
8719
+ min: 0,
8720
+ max: 450,
8721
+ interval: 50,
8722
+ axisLine: {
8723
+ lineStyle: {
8724
+ color: '#333',
8725
+ },
8726
+ },
8727
+ },
8728
+ yAxis: {
8729
+ name: yName,
8730
+ nameGap: !yValIsAllNull ? 35 : 5,
8731
+ nameRotate: 90,
8732
+ nameLocation: 'middle',
8733
+ type: 'value',
8734
+ min: 0,
8735
+ interval: 50,
8736
+ axisLine: {
8737
+ lineStyle: {
8738
+ color: '#333',
8739
+ },
8740
+ },
8741
+ },
8742
+ series: [
8743
+ {
8744
+ name: '实际数据',
8745
+ type: 'scatter',
8746
+ data: !yValIsAllNull ? xData.map((x, i) => [x, yData[i]]) : [],
8747
+ symbolSize: 5,
8748
+ itemStyle: {
8749
+ color: color,
8750
+ },
8751
+ },
8752
+ {
8753
+ name: '趋势线',
8754
+ type: 'line',
8755
+ data: !yValIsAllNull ? trendData : [],
8756
+ symbol: 'none',
8757
+ lineStyle: {
8758
+ color: color,
8759
+ width: 1,
8760
+ type: 'solid',
8761
+ },
8762
+ /*
8763
+ markPoint: {
8764
+ data: [
8765
+ {
8766
+ type: 'min',
8767
+ symbol: 'circle',
8768
+ symbolSize: 6,
8769
+ label: {
8770
+ formatter: '起点',
8771
+ position: 'right'
8772
+ }
8773
+ }
8774
+ ]
8775
+ }
8776
+ */
8777
+ },
8778
+ ],
8779
+ };
8780
+ return option;
8781
+ },
8614
8782
  };
8615
8783
 
8616
8784
  /**
@@ -8877,6 +9045,9 @@ const EChartsUtils = {
8877
9045
  else if (config.chartType == 430) {
8878
9046
  option = EChartsUtilsAll.chart430(config, xDataArr, yDataArr, sheet);
8879
9047
  }
9048
+ else if (config.chartType == 450) {
9049
+ option = EChartsUtilsAll.chart450(config, xDataArr, yDataArr);
9050
+ }
8880
9051
  if (option && typeof option === 'object') {
8881
9052
  //如果是隐藏的图表,则需要禁用ECharts的动画效果
8882
9053
  //原因是:如果ECharts使用了动画效果,图表渲染完成可能需要0.5秒,但是在导出ECharts统计图为图片的场景下时,可能在图表还没有渲染完成(动画效果还没结束)前就要获取图像了,此时可能就会造成获取到的图像内容丢失的情况
@@ -20274,6 +20445,83 @@ const FormulaUtils = {
20274
20445
  return sw;
20275
20446
  },
20276
20447
  },
20448
+ {
20449
+ funName: 'YJWDDLZ',
20450
+ funDesc: '马歇尔稳定度/流值',
20451
+ funDefaultVal: null,
20452
+ isAcceptArea: true,
20453
+ funParams: [
20454
+ {
20455
+ name: '数值1',
20456
+ repeatable: false,
20457
+ optional: false,
20458
+ },
20459
+ {
20460
+ name: '数值2',
20461
+ repeatable: false,
20462
+ optional: false,
20463
+ },
20464
+ {
20465
+ name: '数值3',
20466
+ repeatable: false,
20467
+ optional: false,
20468
+ },
20469
+ {
20470
+ name: '数值4',
20471
+ repeatable: false,
20472
+ optional: false,
20473
+ },
20474
+ {
20475
+ name: '数值5',
20476
+ repeatable: false,
20477
+ optional: false,
20478
+ },
20479
+ {
20480
+ name: '数值6',
20481
+ repeatable: false,
20482
+ optional: false,
20483
+ },
20484
+ {
20485
+ name: '超过比例,如:0.15、0.2',
20486
+ repeatable: false,
20487
+ optional: false,
20488
+ },
20489
+ ],
20490
+ funCallback: (spread, sheet, retData) => {
20491
+ //如果传递的参数小于7个,则返回空字符串
20492
+ if (retData.allCellVals.length < 7) {
20493
+ return '/';
20494
+ }
20495
+ const val1 = retData.allCellVals[0], val2 = retData.allCellVals[1], val3 = retData.allCellVals[2], val4 = retData.allCellVals[3], val5 = retData.allCellVals[4], val6 = retData.allCellVals[5], overVal = retData.allCellVals[6];
20496
+ // 参数类型检查 - 所有参数必须为数字类型
20497
+ const args = [val1, val2, val3, val4, val5, val6, overVal];
20498
+ for (let i = 0; i < args.length; i++) {
20499
+ if (typeof args[i] !== 'number' || isNaN(args[i])) {
20500
+ return '/';
20501
+ }
20502
+ }
20503
+ // 提取前6个值进行计算
20504
+ const values = [val1, val2, val3, val4, val5, val6];
20505
+ // 计算初始平均值avg
20506
+ const sum = values.reduce((acc, val) => preciseCalc(acc, val, 'add'), 0);
20507
+ const avg = preciseCalc(sum, values.length, 'div');
20508
+ // 检查是否有值与平均值a的差大于overVal(不取绝对值)
20509
+ const abnormalValues = values.filter((val) => preciseCalc(val, avg, 'sub') > preciseCalc(overVal, val, 'mul'));
20510
+ // 如果没有异常值,直接返回平均值a
20511
+ if (abnormalValues.length === 0) {
20512
+ return avg;
20513
+ }
20514
+ // 舍弃异常值后重新计算平均值
20515
+ const normalValues = values.filter((val) => preciseCalc(val, avg, 'sub') <= preciseCalc(overVal, val, 'mul'));
20516
+ // 确保至少有一个正常值
20517
+ if (normalValues.length === 0) {
20518
+ return '/';
20519
+ }
20520
+ // 计算剩余值的平均值
20521
+ const newSum = normalValues.reduce((acc, val) => preciseCalc(acc, val, 'add'), 0);
20522
+ return preciseCalc(newSum, normalValues.length, 'div');
20523
+ },
20524
+ },
20277
20525
  {
20278
20526
  funName: 'YJTREND',
20279
20527
  funDesc: '返回线性回归拟合线的一组纵坐标值(y值)',