rapid-spreadjs 1.0.185 → 1.0.187
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.cjs.js +128 -121
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.cjs.min.js +1 -1
- package/dist/index.cjs.min.js.map +1 -1
- package/dist/index.esm.js +128 -121
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/utils/echarts-all.d.ts +12 -10
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -5313,117 +5313,132 @@ const EChartsUtilsAll = {
|
|
|
5313
5313
|
return option;
|
|
5314
5314
|
},
|
|
5315
5315
|
/**
|
|
5316
|
-
*
|
|
5316
|
+
* 筛分(动态多折线版)
|
|
5317
|
+
* 与 chart50 主体逻辑一致(x轴 0.45 次方变换、按x排序、空值过滤、markLine 模拟x轴标签等),
|
|
5318
|
+
* 区别在于折线数量不再固定为 3 条,而是根据 chartLinesJson 中的折线配置数量动态生成 N 条线:
|
|
5319
|
+
* - 每条线的图例名取 lineData[i].legend
|
|
5320
|
+
* - 每条线的颜色取 lineData[i].lineColor
|
|
5321
|
+
* - 每条线的 Y 数据取 yDataArr[i]
|
|
5322
|
+
* - 符号与线型按索引循环取预设值(首线保持实心方块+实线,与 chart50 一致)
|
|
5317
5323
|
* @param config 折线配置
|
|
5318
|
-
* @param xDataArr x
|
|
5319
|
-
* @param yDataArr y
|
|
5324
|
+
* @param xDataArr x轴原始数据(二维数组,取 xDataArr[0] 作为共享x轴)
|
|
5325
|
+
* @param yDataArr y轴原始数据(二维数组,yDataArr[i] 对应第 i 条线)
|
|
5320
5326
|
* @returns 返回ECharts配置项
|
|
5321
5327
|
*/
|
|
5322
5328
|
chart50: (config, xDataArr, yDataArr) => {
|
|
5323
5329
|
let lineData = JSON.parse(config.chartLinesJson);
|
|
5324
|
-
let title = '',
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5330
|
+
let title = '', xName = config.chartXName, yName = config.chartYName;
|
|
5331
|
+
// 折线数量:以 chartLinesJson 中配置的折线条数为准
|
|
5332
|
+
const lineCount = Array.isArray(lineData) ? lineData.length : 0;
|
|
5333
|
+
// x轴原始数据(共享一份)
|
|
5334
|
+
const xDataSourceOld = xDataArr[0];
|
|
5328
5335
|
const allData = [];
|
|
5329
5336
|
xDataSourceOld.forEach((item, index) => {
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5337
|
+
const point = { x: item };
|
|
5338
|
+
// 将每条线的 y 值都收进同一个点对象,key 为 y0/y1/y2...
|
|
5339
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5340
|
+
point['y' + i] = (yDataArr[i] || [])[index];
|
|
5341
|
+
}
|
|
5342
|
+
allData.push(point);
|
|
5336
5343
|
});
|
|
5337
5344
|
allData.sort(function (a, b) {
|
|
5338
5345
|
return a.x - b.x;
|
|
5339
5346
|
});
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
let
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
yDataSource.push(item.y);
|
|
5353
|
-
yDataSourceSx.push(item.ySx);
|
|
5354
|
-
yDataSourceXx.push(item.yXx);
|
|
5355
|
-
});
|
|
5356
|
-
}
|
|
5357
|
-
else {
|
|
5358
|
-
// 只获取上限或下限中值不为null的点
|
|
5359
|
-
allData.forEach((item, index) => {
|
|
5360
|
-
if (item.ySx != null && item.ySx != '/' && item.yXx != null && item.yXx != '/') {
|
|
5361
|
-
xDataSource.push(item.x);
|
|
5362
|
-
yDataSource.push(item.y);
|
|
5363
|
-
yDataSourceSx.push(item.ySx);
|
|
5364
|
-
yDataSourceXx.push(item.yXx);
|
|
5347
|
+
// 每条线的数据数组
|
|
5348
|
+
const yDataSources = [];
|
|
5349
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5350
|
+
yDataSources.push([]);
|
|
5351
|
+
}
|
|
5352
|
+
// 统计各条线中值为 null 或 "/" 的个数(用于后续空值过滤逻辑,保持与 chart50 一致的行为)
|
|
5353
|
+
const nullCounts = [];
|
|
5354
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5355
|
+
let cnt = 0;
|
|
5356
|
+
(yDataArr[i] || []).forEach((item) => {
|
|
5357
|
+
if (item == null || item == '/') {
|
|
5358
|
+
cnt++;
|
|
5365
5359
|
}
|
|
5366
5360
|
});
|
|
5361
|
+
nullCounts.push(cnt);
|
|
5367
5362
|
}
|
|
5368
|
-
//
|
|
5369
|
-
|
|
5363
|
+
// 若任意一条线存在非空值,则按“所有线均非空”过滤出有效点;否则保留全部点(与 chart50 上限/下限过滤逻辑保持语义一致)
|
|
5364
|
+
const hasAnyValid = nullCounts.some((cnt, i) => cnt < (yDataArr[i] || []).length);
|
|
5365
|
+
allData.forEach((item) => {
|
|
5366
|
+
if (!hasAnyValid) {
|
|
5367
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5368
|
+
yDataSources[i].push(item['y' + i]);
|
|
5369
|
+
}
|
|
5370
|
+
return;
|
|
5371
|
+
}
|
|
5372
|
+
// 存在有效值时,仅当所有线该点均非空才保留
|
|
5373
|
+
let allValid = true;
|
|
5374
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5375
|
+
const v = item['y' + i];
|
|
5376
|
+
if (v == null || v == '/') {
|
|
5377
|
+
allValid = false;
|
|
5378
|
+
break;
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
if (allValid) {
|
|
5382
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5383
|
+
yDataSources[i].push(item['y' + i]);
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
});
|
|
5387
|
+
// x轴数据:x轴原始数据的0.45次方,并修约0.001
|
|
5388
|
+
let xData = [];
|
|
5389
|
+
let markLineData = [];
|
|
5370
5390
|
// x和y轴的字体大小
|
|
5371
5391
|
const xyFontSize = 10;
|
|
5372
|
-
//
|
|
5373
|
-
|
|
5374
|
-
// 得到x轴原始数据的0.45次方值,并修约0.001
|
|
5392
|
+
// 组装 x 轴与 markLine(所有线共用同一套 x 值)
|
|
5393
|
+
xDataSourceOld.forEach((item, index) => {
|
|
5375
5394
|
const val045 = Number(EChartsUtilsComm.getRound(item ** 0.45, 0.001));
|
|
5376
|
-
xData.push([val045, yDataSource[index]]);
|
|
5377
5395
|
markLineData.push({
|
|
5378
5396
|
name: item + '',
|
|
5379
5397
|
xAxis: val045,
|
|
5380
5398
|
label: {
|
|
5381
|
-
show:
|
|
5399
|
+
show: xDataSourceOld.length >= 6 && index % 2 != 0 && index < 6 ? false : true,
|
|
5382
5400
|
fontSize: xyFontSize,
|
|
5383
5401
|
},
|
|
5384
5402
|
});
|
|
5385
|
-
|
|
5386
|
-
xDataXx.push([val045, yDataSourceXx[index]]);
|
|
5403
|
+
xData.push(val045);
|
|
5387
5404
|
});
|
|
5405
|
+
// 符号与线型预设值(循环取用)
|
|
5406
|
+
const symbolPresets = ['rect', 'triangle', 'circle', 'diamond', 'roundRect', 'arrow'];
|
|
5407
|
+
const lineTypePresets = ['solid', 'dotted', [10, 5], 'dashed', [2, 2], [6, 3, 2, 3]];
|
|
5388
5408
|
/**
|
|
5389
|
-
* 获取series
|
|
5390
|
-
* @param
|
|
5391
|
-
* @param data
|
|
5409
|
+
* 获取 series 需要的单条线配置(动态版)
|
|
5410
|
+
* @param index 第几条线
|
|
5411
|
+
* @param data 对应的坐标点数据([x, y])
|
|
5392
5412
|
*/
|
|
5393
|
-
const getLineObj = (
|
|
5394
|
-
const
|
|
5395
|
-
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5413
|
+
const getLineObj = (index, data) => {
|
|
5414
|
+
const lineCfg = lineData[index] || {};
|
|
5415
|
+
// 图例名:优先取 lineData[index].legend,其次用序号兜底
|
|
5416
|
+
const name = lineCfg.legend != null && lineCfg.legend !== '' ? lineCfg.legend : '折线' + (index + 1);
|
|
5417
|
+
// 颜色:优先取 lineData[index].lineColor,其次循环取预设色
|
|
5418
|
+
const color = lineCfg.lineColor != null && lineCfg.lineColor !== '' ? lineCfg.lineColor : null;
|
|
5419
|
+
const symbol = symbolPresets[index % symbolPresets.length];
|
|
5420
|
+
const lineType = lineTypePresets[index % lineTypePresets.length];
|
|
5398
5421
|
let obj = {
|
|
5399
5422
|
name: name,
|
|
5400
5423
|
type: 'line',
|
|
5401
|
-
smooth: true,
|
|
5402
|
-
// 设置数据点形状(实心),参考文档:https://echarts.apache.org/zh/option.html#series-line.symbol
|
|
5424
|
+
smooth: true,
|
|
5403
5425
|
symbol: symbol,
|
|
5404
5426
|
symbolSize: 5,
|
|
5405
|
-
z: 10,
|
|
5406
|
-
// 线条的颜色
|
|
5427
|
+
z: 10,
|
|
5407
5428
|
lineStyle: {
|
|
5408
5429
|
color: color,
|
|
5409
|
-
// 线条类型(solid:实线、dashed:粗虚线、dotted:细虚线)
|
|
5410
5430
|
type: lineType,
|
|
5411
5431
|
},
|
|
5412
|
-
// 线条上数据点的颜色
|
|
5413
5432
|
itemStyle: {
|
|
5414
5433
|
color: color,
|
|
5415
5434
|
},
|
|
5416
5435
|
data: data,
|
|
5417
|
-
connectNulls: true,
|
|
5436
|
+
connectNulls: true,
|
|
5418
5437
|
markLine: {
|
|
5419
|
-
symbol: '',
|
|
5420
|
-
silent: true,
|
|
5438
|
+
symbol: '',
|
|
5439
|
+
silent: true,
|
|
5421
5440
|
label: {
|
|
5422
|
-
|
|
5423
|
-
position: 'start', // 改变label位置
|
|
5424
|
-
//rotate: 45, // 设置文字旋转度数(注意:ECharts官网文档居然没有rotate这个属性的说明)
|
|
5425
|
-
// backgroundColor:'#fff'
|
|
5426
|
-
// color:'#f00',// 文字颜色
|
|
5441
|
+
position: 'start',
|
|
5427
5442
|
formatter: (data) => {
|
|
5428
5443
|
return data.name;
|
|
5429
5444
|
},
|
|
@@ -5439,40 +5454,48 @@ const EChartsUtilsAll = {
|
|
|
5439
5454
|
if (xData.length == 0) {
|
|
5440
5455
|
yValIsAllNull = true;
|
|
5441
5456
|
}
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5457
|
+
// 组装每条线的 [x, y] 坐标点数据
|
|
5458
|
+
const seriesDataList = [];
|
|
5459
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5460
|
+
const linePoints = [];
|
|
5461
|
+
for (let j = 0; j < xData.length; j++) {
|
|
5462
|
+
linePoints.push([xData[j], yDataSources[i][j]]);
|
|
5446
5463
|
}
|
|
5447
|
-
|
|
5448
|
-
if (nullCount == xData.length) {
|
|
5449
|
-
yValIsAllNull = true;
|
|
5464
|
+
seriesDataList.push(linePoints);
|
|
5450
5465
|
}
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5466
|
+
let nullCount = 0;
|
|
5467
|
+
seriesDataList.forEach((linePoints) => {
|
|
5468
|
+
linePoints.forEach((item) => {
|
|
5469
|
+
if (item[1] == null || item[1] == undefined || item[1] == '/') {
|
|
5470
|
+
nullCount++;
|
|
5471
|
+
}
|
|
5472
|
+
});
|
|
5473
|
+
});
|
|
5474
|
+
if (nullCount == xData.length * lineCount) {
|
|
5458
5475
|
yValIsAllNull = true;
|
|
5459
5476
|
}
|
|
5460
|
-
if (
|
|
5461
|
-
!yDataArr[1].some((x) => x != '' && x != '/' && x != null && x != undefined) &&
|
|
5462
|
-
!yDataArr[2].some((x) => x != '' && x != '/' && x != null && x != undefined)) {
|
|
5477
|
+
if (yDataArr.every((arr) => !arr.some((x) => x != '' && x != '/' && x != null && x != undefined))) {
|
|
5463
5478
|
yValIsAllNull = true;
|
|
5464
5479
|
}
|
|
5480
|
+
// 图例名称与选中状态(动态)
|
|
5481
|
+
const legendNames = [];
|
|
5482
|
+
const legendSelected = {};
|
|
5483
|
+
for (let i = 0; i < lineCount; i++) {
|
|
5484
|
+
const lineCfg = lineData[i] || {};
|
|
5485
|
+
const name = lineCfg.legend != null && lineCfg.legend !== '' ? lineCfg.legend : '折线' + (i + 1);
|
|
5486
|
+
legendNames.push(name);
|
|
5487
|
+
legendSelected[name] = true;
|
|
5488
|
+
}
|
|
5489
|
+
// series 动态生成
|
|
5490
|
+
const series = seriesDataList.map((linePoints, i) => getLineObj(i, !yValIsAllNull ? linePoints : []));
|
|
5465
5491
|
let option = {
|
|
5466
5492
|
grid: {
|
|
5467
|
-
// show: true,// 是否显示外边框线
|
|
5468
|
-
// borderColor: '#f00',// 外边框线颜色
|
|
5469
5493
|
top: 20,
|
|
5470
5494
|
left: 30,
|
|
5471
5495
|
right: 10,
|
|
5472
5496
|
bottom: 35,
|
|
5473
5497
|
containLabel: true,
|
|
5474
5498
|
},
|
|
5475
|
-
// 提示框组件,参考文档:https://echarts.apache.org/zh/option.html#tooltip
|
|
5476
5499
|
tooltip: {
|
|
5477
5500
|
trigger: 'axis',
|
|
5478
5501
|
formatter: function (datas, ticket) {
|
|
@@ -5485,7 +5508,6 @@ const EChartsUtilsAll = {
|
|
|
5485
5508
|
}
|
|
5486
5509
|
},
|
|
5487
5510
|
},
|
|
5488
|
-
// 顶部的标题,参考文档:https://echarts.apache.org/zh/option.html#title
|
|
5489
5511
|
title: [
|
|
5490
5512
|
{
|
|
5491
5513
|
show: true,
|
|
@@ -5508,29 +5530,22 @@ const EChartsUtilsAll = {
|
|
|
5508
5530
|
},
|
|
5509
5531
|
},
|
|
5510
5532
|
],
|
|
5511
|
-
// 图例,参考文档:https://echarts.apache.org/zh/option.html#legend
|
|
5512
5533
|
legend: {
|
|
5513
|
-
// show: !yValIsAllNull,
|
|
5514
5534
|
top: '0px',
|
|
5515
5535
|
left: 'center',
|
|
5516
|
-
data:
|
|
5517
|
-
selected:
|
|
5518
|
-
|
|
5519
|
-
上限: true, // 显示
|
|
5520
|
-
下限: true, // 显示
|
|
5521
|
-
},
|
|
5522
|
-
selectedMode: 'multiple', // 用于控制图例的选择模式(single:单选、multiple:多选、false:禁止选择)
|
|
5536
|
+
data: legendNames,
|
|
5537
|
+
selected: legendSelected,
|
|
5538
|
+
selectedMode: 'multiple',
|
|
5523
5539
|
},
|
|
5524
5540
|
xAxis: {
|
|
5525
5541
|
type: 'value',
|
|
5526
|
-
axisTick: { show: false },
|
|
5527
|
-
axisLabel: { show: false },
|
|
5528
|
-
// 网格线,参考文档:https://echarts.apache.org/zh/option.html#xAxis.splitLine
|
|
5542
|
+
axisTick: { show: false },
|
|
5543
|
+
axisLabel: { show: false },
|
|
5529
5544
|
splitLine: {
|
|
5530
|
-
show: false,
|
|
5545
|
+
show: false,
|
|
5531
5546
|
},
|
|
5532
|
-
min: xData.length > 0 ? (xData[0]
|
|
5533
|
-
max: xData.length > 0 ? xData[xData.length - 1]
|
|
5547
|
+
min: xData.length > 0 ? (xData[0] > 0.2 ? xData[0] - 0.2 : 0) : null,
|
|
5548
|
+
max: xData.length > 0 ? xData[xData.length - 1] + 0.1 : null,
|
|
5534
5549
|
},
|
|
5535
5550
|
yAxis: [
|
|
5536
5551
|
{
|
|
@@ -5542,23 +5557,19 @@ const EChartsUtilsAll = {
|
|
|
5542
5557
|
splitLine: {
|
|
5543
5558
|
show: true,
|
|
5544
5559
|
lineStyle: {
|
|
5545
|
-
color: '#e0e6f1',
|
|
5560
|
+
color: '#e0e6f1',
|
|
5546
5561
|
type: 'solid',
|
|
5547
5562
|
},
|
|
5548
5563
|
},
|
|
5549
5564
|
min: 0,
|
|
5550
5565
|
max: 100,
|
|
5551
|
-
splitNumber: 10,
|
|
5566
|
+
splitNumber: 10,
|
|
5552
5567
|
axisLabel: {
|
|
5553
5568
|
fontSize: xyFontSize,
|
|
5554
5569
|
},
|
|
5555
5570
|
},
|
|
5556
5571
|
],
|
|
5557
|
-
series:
|
|
5558
|
-
getLineObj(1, !yValIsAllNull ? xData : []),
|
|
5559
|
-
getLineObj(2, !yValIsAllNull ? xDataSx : []),
|
|
5560
|
-
getLineObj(3, !yValIsAllNull ? xDataXx : []),
|
|
5561
|
-
],
|
|
5572
|
+
series: series,
|
|
5562
5573
|
};
|
|
5563
5574
|
return option;
|
|
5564
5575
|
},
|
|
@@ -23973,22 +23984,18 @@ const FormulaUtils = {
|
|
|
23973
23984
|
optional: false,
|
|
23974
23985
|
},
|
|
23975
23986
|
{
|
|
23976
|
-
name: '
|
|
23977
|
-
repeatable: false,
|
|
23978
|
-
optional: false,
|
|
23979
|
-
},
|
|
23980
|
-
{
|
|
23981
|
-
name: '目标点y坐标',
|
|
23987
|
+
name: '目标点坐标,格式如 (3.5,6.5)',
|
|
23982
23988
|
repeatable: false,
|
|
23983
23989
|
optional: false,
|
|
23984
23990
|
},
|
|
23985
23991
|
],
|
|
23986
23992
|
funCallback: (spread, sheet, retData) => {
|
|
23987
|
-
// 如果传递的参数小于
|
|
23988
|
-
if (retData.allCellVals.length <
|
|
23993
|
+
// 如果传递的参数小于2个,则返回/
|
|
23994
|
+
if (retData.allCellVals.length < 2) {
|
|
23989
23995
|
return '/';
|
|
23990
23996
|
}
|
|
23991
|
-
|
|
23997
|
+
const pointStrArr = retData.allCellVals[1].replace('(', '').replace(')', '').split(',');
|
|
23998
|
+
let points = retData.allCellVals[0], xPoint = pointStrArr[0], yPoint = pointStrArr[1];
|
|
23992
23999
|
// 1. 格式校验
|
|
23993
24000
|
if (typeof points !== 'string' || !points)
|
|
23994
24001
|
return '/';
|