@visactor/vseed 0.4.1 → 0.4.3
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/cjs/index.cjs +646 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/builder/builder/buildSpec.d.ts +1 -2
- package/dist/esm/builder/builder/buildSpec.js.map +1 -1
- package/dist/esm/builder/builder/builder.d.ts +1116 -106
- package/dist/esm/builder/builder/builder.js +10 -0
- package/dist/esm/builder/builder/builder.js.map +1 -1
- package/dist/esm/builder/builder/prepare.d.ts +12 -0
- package/dist/esm/builder/builder/prepare.js +269 -0
- package/dist/esm/builder/builder/prepare.js.map +1 -0
- package/dist/esm/dataReshape/constant.d.ts +1 -0
- package/dist/esm/dataReshape/constant.js +2 -1
- package/dist/esm/dataReshape/constant.js.map +1 -1
- package/dist/esm/dataSelector/selector.d.ts +71 -2
- package/dist/esm/dataSelector/selector.js +96 -32
- package/dist/esm/dataSelector/selector.js.map +1 -1
- package/dist/esm/pipeline/advanced/chart/pipes/default/defaultMeasures.js +2 -1
- package/dist/esm/pipeline/advanced/chart/pipes/default/defaultMeasures.js.map +1 -1
- package/dist/esm/pipeline/advanced/table/pipes/default/defaultMeasures.js +2 -1
- package/dist/esm/pipeline/advanced/table/pipes/default/defaultMeasures.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationHorizontalLine.js +10 -4
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationHorizontalLine.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointCommon.d.ts +8 -2
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointCommon.js +27 -5
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointCommon.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointOfDualAxis.js +8 -4
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointOfDualAxis.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationVerticalLine.js +10 -4
- package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationVerticalLine.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.d.ts +9 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.js +7 -1
- package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/barStyle.js +3 -2
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/barStyle.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/lineStyle.js +5 -2
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/lineStyle.js.map +1 -1
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/pointStyle.js +3 -2
- package/dist/esm/pipeline/spec/chart/pipes/markStyle/pointStyle.js.map +1 -1
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/common.d.ts +4 -1
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/common.js +12 -1
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/common.js.map +1 -1
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/pivot.js +6 -3
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/pivot.js.map +1 -1
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/table.js +7 -3
- package/dist/esm/pipeline/spec/table/pipes/cellStyle/table.js.map +1 -1
- package/dist/esm/pipeline/utils/index.d.ts +1 -0
- package/dist/esm/pipeline/utils/index.js +1 -0
- package/dist/esm/pipeline/utils/sandbox/builtin-utils.d.ts +6 -0
- package/dist/esm/pipeline/utils/sandbox/builtin-utils.js +337 -0
- package/dist/esm/pipeline/utils/sandbox/builtin-utils.js.map +1 -0
- package/dist/esm/pipeline/utils/sandbox/execute.d.ts +73 -0
- package/dist/esm/pipeline/utils/sandbox/execute.js +716 -0
- package/dist/esm/pipeline/utils/sandbox/execute.js.map +1 -0
- package/dist/esm/pipeline/utils/sandbox/index.d.ts +7 -0
- package/dist/esm/pipeline/utils/sandbox/index.js +3 -0
- package/dist/esm/types/builder/builder.d.ts +1 -0
- package/dist/esm/types/builder/builder.js.map +1 -1
- package/dist/esm/types/chartType/area/zArea.d.ts +682 -18
- package/dist/esm/types/chartType/areaPercent/zAreaPercent.d.ts +682 -18
- package/dist/esm/types/chartType/bar/zBar.d.ts +362 -10
- package/dist/esm/types/chartType/barParallel/zBarParallel.d.ts +362 -10
- package/dist/esm/types/chartType/barPercent/zBarPercent.d.ts +362 -10
- package/dist/esm/types/chartType/boxPlot/zBoxPlot.d.ts +210 -14
- package/dist/esm/types/chartType/circlePacking/zCirclePacking.d.ts +2 -2
- package/dist/esm/types/chartType/column/zColumn.d.ts +362 -10
- package/dist/esm/types/chartType/columnParallel/zColumnParallel.d.ts +362 -10
- package/dist/esm/types/chartType/columnPercent/zColumnPercent.d.ts +362 -10
- package/dist/esm/types/chartType/donut/zDonut.d.ts +2 -2
- package/dist/esm/types/chartType/dualAxis/zDualAxis.d.ts +842 -22
- package/dist/esm/types/chartType/funnel/zFunnel.d.ts +2 -2
- package/dist/esm/types/chartType/heatmap/zHeatmap.d.ts +2 -2
- package/dist/esm/types/chartType/histogram/zHistogram.d.ts +362 -10
- package/dist/esm/types/chartType/line/zLine.d.ts +522 -14
- package/dist/esm/types/chartType/pie/zPie.d.ts +2 -2
- package/dist/esm/types/chartType/pivotTable/zPivotTable.d.ts +241 -4
- package/dist/esm/types/chartType/pivotTable/zPivotTable.js +1 -1
- package/dist/esm/types/chartType/pivotTable/zPivotTable.js.map +1 -1
- package/dist/esm/types/chartType/raceBar/zRaceBar.d.ts +362 -10
- package/dist/esm/types/chartType/raceColumn/zRaceColumn.d.ts +362 -10
- package/dist/esm/types/chartType/raceScatter/zRaceScatter.d.ts +362 -10
- package/dist/esm/types/chartType/radar/zRadar.d.ts +2 -2
- package/dist/esm/types/chartType/rose/zRose.d.ts +2 -2
- package/dist/esm/types/chartType/roseParallel/zRoseParallel.d.ts +2 -2
- package/dist/esm/types/chartType/scatter/zScatter.d.ts +362 -10
- package/dist/esm/types/chartType/sunburst/zSunburst.d.ts +2 -2
- package/dist/esm/types/chartType/table/zTable.d.ts +241 -4
- package/dist/esm/types/chartType/table/zTable.js +1 -1
- package/dist/esm/types/chartType/table/zTable.js.map +1 -1
- package/dist/esm/types/chartType/treeMap/zTreeMap.d.ts +2 -2
- package/dist/esm/types/dataSelector/selector.d.ts +594 -3
- package/dist/esm/types/dataSelector/selector.js +58 -2
- package/dist/esm/types/dataSelector/selector.js.map +1 -1
- package/dist/esm/types/properties/annotation/annotation.d.ts +200 -4
- package/dist/esm/types/properties/annotation/annotationHorizontalLine.d.ts +12 -0
- package/dist/esm/types/properties/annotation/annotationPoint.d.ts +19 -0
- package/dist/esm/types/properties/annotation/annotationVerticalLine.d.ts +12 -0
- package/dist/esm/types/properties/annotation/zAnnotationHorizontalLine.d.ts +10 -0
- package/dist/esm/types/properties/annotation/zAnnotationHorizontalLine.js +2 -0
- package/dist/esm/types/properties/annotation/zAnnotationHorizontalLine.js.map +1 -1
- package/dist/esm/types/properties/annotation/zAnnotationPoint.d.ts +80 -2
- package/dist/esm/types/properties/annotation/zAnnotationPoint.js +2 -1
- package/dist/esm/types/properties/annotation/zAnnotationPoint.js.map +1 -1
- package/dist/esm/types/properties/annotation/zAnnotationVerticalLine.d.ts +10 -0
- package/dist/esm/types/properties/annotation/zAnnotationVerticalLine.js +2 -0
- package/dist/esm/types/properties/annotation/zAnnotationVerticalLine.js.map +1 -1
- package/dist/esm/types/properties/cellStyle/bodyCellStyle.d.ts +105 -2
- package/dist/esm/types/properties/cellStyle/bodyCellStyle.js +2 -1
- package/dist/esm/types/properties/cellStyle/bodyCellStyle.js.map +1 -1
- package/dist/esm/types/properties/cellStyle/cellStyle.d.ts +83 -2
- package/dist/esm/types/properties/config/annotation/zAnnotation.d.ts +156 -0
- package/dist/esm/types/properties/config/area.d.ts +160 -4
- package/dist/esm/types/properties/config/bar.d.ts +240 -6
- package/dist/esm/types/properties/config/boxplot.d.ts +80 -2
- package/dist/esm/types/properties/config/circlePacking.d.ts +2 -2
- package/dist/esm/types/properties/config/column.d.ts +240 -6
- package/dist/esm/types/properties/config/config.d.ts +1300 -52
- package/dist/esm/types/properties/config/dualAxis.d.ts +80 -2
- package/dist/esm/types/properties/config/funnel.d.ts +2 -2
- package/dist/esm/types/properties/config/heatmap.d.ts +2 -2
- package/dist/esm/types/properties/config/histogram.d.ts +80 -2
- package/dist/esm/types/properties/config/label/zLabel.d.ts +2 -2
- package/dist/esm/types/properties/config/label/zPieLabel.d.ts +2 -2
- package/dist/esm/types/properties/config/line.d.ts +80 -2
- package/dist/esm/types/properties/config/pie.d.ts +6 -6
- package/dist/esm/types/properties/config/race.d.ts +240 -6
- package/dist/esm/types/properties/config/rose.d.ts +4 -4
- package/dist/esm/types/properties/config/scatter.d.ts +80 -2
- package/dist/esm/types/properties/config/sunburst.d.ts +2 -2
- package/dist/esm/types/properties/config/treeMap.d.ts +2 -2
- package/dist/esm/types/properties/markStyle/areaStyle.d.ts +19 -0
- package/dist/esm/types/properties/markStyle/barStyle.d.ts +99 -2
- package/dist/esm/types/properties/markStyle/barStyle.js +2 -1
- package/dist/esm/types/properties/markStyle/barStyle.js.map +1 -1
- package/dist/esm/types/properties/markStyle/boxPlotStyle.d.ts +2 -2
- package/dist/esm/types/properties/markStyle/lineStyle.d.ts +99 -2
- package/dist/esm/types/properties/markStyle/lineStyle.js +2 -1
- package/dist/esm/types/properties/markStyle/lineStyle.js.map +1 -1
- package/dist/esm/types/properties/markStyle/markStyle.d.ts +648 -24
- package/dist/esm/types/properties/markStyle/outlierStyle.d.ts +2 -2
- package/dist/esm/types/properties/markStyle/pointStyle.d.ts +99 -2
- package/dist/esm/types/properties/markStyle/pointStyle.js +2 -1
- package/dist/esm/types/properties/markStyle/pointStyle.js.map +1 -1
- package/dist/esm/types/properties/markStyle/zAreaStyle.d.ts +80 -2
- package/dist/esm/types/properties/markStyle/zAreaStyle.js +2 -1
- package/dist/esm/types/properties/markStyle/zAreaStyle.js.map +1 -1
- package/dist/esm/types/properties/theme/customTheme.d.ts +2600 -104
- package/dist/esm/types/sandbox.d.ts +19 -0
- package/dist/esm/types/sandbox.js +0 -0
- package/dist/esm/types/zVseed.d.ts +7 -25058
- package/dist/esm/types/zVseed.js.map +1 -1
- package/dist/umd/index.js +1786 -260
- package/dist/umd/index.js.map +1 -1
- package/package.json +1 -1
package/dist/umd/index.js
CHANGED
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
zDataset: ()=>zDataset,
|
|
74
74
|
DimensionEncodingEnum: ()=>DimensionEncodingEnum,
|
|
75
75
|
barPercentAdvancedPipeline: ()=>barPercentAdvancedPipeline,
|
|
76
|
+
zPartialSelector: ()=>zPartialSelector,
|
|
76
77
|
zColumnParallel: ()=>zColumnParallel,
|
|
77
78
|
zDimensions: ()=>zDimensions,
|
|
78
79
|
zLegend: ()=>zLegend,
|
|
@@ -103,31 +104,35 @@
|
|
|
103
104
|
registerRose: ()=>registerRose,
|
|
104
105
|
zPivotChartGridConfig: ()=>zPivotChartGridConfig,
|
|
105
106
|
zRose: ()=>zRose,
|
|
106
|
-
|
|
107
|
+
zCellSelector: ()=>zCellSelector,
|
|
107
108
|
registerTable: ()=>registerTable,
|
|
108
|
-
isMeasureGroup: ()=>isMeasureGroup,
|
|
109
109
|
autoFormatter: ()=>autoFormatter,
|
|
110
|
+
isMeasureGroup: ()=>isMeasureGroup,
|
|
110
111
|
YEncoding: ()=>YEncoding,
|
|
111
112
|
isColumnPercent: ()=>isColumnPercent,
|
|
112
113
|
registerAll: ()=>registerAll,
|
|
113
114
|
isVChart: ()=>isVChart,
|
|
114
115
|
registerBar: ()=>registerBar,
|
|
115
116
|
zPolynomialRegressionLine: ()=>zPolynomialRegressionLine,
|
|
117
|
+
zSunburstConfig: ()=>zSunburstConfig,
|
|
116
118
|
zDimensionSelector: ()=>zDimensionSelector,
|
|
117
119
|
zColor: ()=>zColor,
|
|
118
120
|
registerDonut: ()=>registerDonut,
|
|
119
121
|
BinStartMeasureId: ()=>BinStartMeasureId,
|
|
122
|
+
InnerRowIndex: ()=>InnerRowIndex,
|
|
120
123
|
heatmapAdvancedPipeline: ()=>heatmapAdvancedPipeline,
|
|
121
124
|
heatmapSpecPipeline: ()=>heatmapSpecPipeline,
|
|
122
125
|
zFunnelConfig: ()=>zFunnelConfig,
|
|
123
|
-
zMeasures: ()=>zMeasures,
|
|
124
126
|
zDualAxis: ()=>zDualAxis,
|
|
125
127
|
FoldMeasureName: ()=>FoldMeasureName,
|
|
128
|
+
zMeasures: ()=>zMeasures,
|
|
126
129
|
darkTheme: ()=>darkTheme,
|
|
127
130
|
isVTable: ()=>isVTable,
|
|
131
|
+
terminateWorkerPool: ()=>terminateWorkerPool,
|
|
128
132
|
zBrush: ()=>zBrush,
|
|
129
133
|
BoxPlotPivotIndicator: ()=>BoxPlotPivotIndicator,
|
|
130
134
|
ORIGINAL_DATA: ()=>ORIGINAL_DATA,
|
|
135
|
+
BUILTIN_UTILS_SOURCE: ()=>BUILTIN_UTILS_SOURCE,
|
|
131
136
|
zMeasureSelector: ()=>zMeasureSelector,
|
|
132
137
|
zAnnotationHorizontalLineConfig: ()=>zAnnotationHorizontalLineConfig,
|
|
133
138
|
columnParallelSpecPipeline: ()=>columnParallelSpecPipeline,
|
|
@@ -145,6 +150,7 @@
|
|
|
145
150
|
zLineConfig: ()=>zLineConfig,
|
|
146
151
|
FoldPrimaryMeasureValue: ()=>FoldPrimaryMeasureValue,
|
|
147
152
|
zXBandAxis: ()=>zXBandAxis,
|
|
153
|
+
zDynamicFilter: ()=>zDynamicFilter,
|
|
148
154
|
zSelectors: ()=>zSelectors,
|
|
149
155
|
FoldYMeasureId: ()=>FoldYMeasureId,
|
|
150
156
|
findMeasureById: ()=>findMeasureById,
|
|
@@ -187,18 +193,19 @@
|
|
|
187
193
|
ANNOTATION_Z_INDEX: ()=>1000,
|
|
188
194
|
Q3MeasureValue: ()=>"__Q3__",
|
|
189
195
|
createFormatter: ()=>createFormatter,
|
|
196
|
+
isMeasureSelector: ()=>isMeasureSelector,
|
|
190
197
|
registerBoxPlot: ()=>registerBoxPlot,
|
|
191
|
-
BAND_AXIS_INNER_OFFSET_IN_PIVOT: ()=>2,
|
|
192
198
|
selectByPartial: ()=>selectByPartial,
|
|
193
199
|
columnPercentSpecPipeline: ()=>columnPercentSpecPipeline,
|
|
194
200
|
zBarConfig: ()=>zBarConfig,
|
|
195
|
-
isMeasureSelector: ()=>isMeasureSelector,
|
|
196
|
-
barParallelSpecPipeline: ()=>barParallelSpecPipeline,
|
|
197
201
|
areaAdvancedPipeline: ()=>areaAdvancedPipeline,
|
|
202
|
+
isRowWithFieldDynamicFilter: ()=>isRowWithFieldDynamicFilter,
|
|
203
|
+
executeFilterCode: ()=>executeFilterCode,
|
|
198
204
|
areaPercentSpecPipeline: ()=>areaPercentSpecPipeline,
|
|
199
|
-
|
|
205
|
+
barParallelSpecPipeline: ()=>barParallelSpecPipeline,
|
|
200
206
|
zBar: ()=>zBar,
|
|
201
207
|
pieAdvancedPipeline: ()=>pieAdvancedPipeline,
|
|
208
|
+
BAND_AXIS_INNER_OFFSET_IN_PIVOT: ()=>2,
|
|
202
209
|
zDualMeasures: ()=>zDualMeasures,
|
|
203
210
|
isTable: ()=>isTable,
|
|
204
211
|
zBarMaxWidth: ()=>zBarMaxWidth,
|
|
@@ -208,6 +215,7 @@
|
|
|
208
215
|
scatterAdvancedPipeline: ()=>scatterAdvancedPipeline,
|
|
209
216
|
zFunnelTransform: ()=>zFunnelTransform,
|
|
210
217
|
zLinearRegressionLine: ()=>zLinearRegressionLine,
|
|
218
|
+
zPie: ()=>zPie,
|
|
211
219
|
zRoseConfig: ()=>zRoseConfig,
|
|
212
220
|
zBodyCellStyle: ()=>zBodyCellStyle,
|
|
213
221
|
zAnnotation: ()=>zAnnotation,
|
|
@@ -231,14 +239,16 @@
|
|
|
231
239
|
MeasureName: ()=>MeasureName,
|
|
232
240
|
hasMultipleMeasureInSingleView: ()=>hasMultipleMeasureInSingleView,
|
|
233
241
|
raceScatterSpecPipeline: ()=>raceScatterSpecPipeline,
|
|
234
|
-
|
|
242
|
+
zChartDynamicFilter: ()=>zChartDynamicFilter,
|
|
235
243
|
zNumFormat: ()=>zNumFormat,
|
|
236
244
|
zRaceBar: ()=>zRaceBar,
|
|
237
245
|
zRegressionLine: ()=>zRegressionLine,
|
|
246
|
+
zTableDynamicFilter: ()=>zTableDynamicFilter,
|
|
238
247
|
FoldYMeasureValue: ()=>FoldYMeasureValue,
|
|
239
248
|
zCirclePackingConfig: ()=>zCirclePackingConfig,
|
|
240
|
-
|
|
249
|
+
validateCodeSafety: ()=>validateCodeSafety,
|
|
241
250
|
zArea: ()=>zArea,
|
|
251
|
+
zPivotTableConfig: ()=>zPivotTableConfig,
|
|
242
252
|
FoldMeasureId: ()=>FoldMeasureId,
|
|
243
253
|
zColumnParallelConfig: ()=>zColumnParallelConfig,
|
|
244
254
|
donutSpecPipeline: ()=>donutSpecPipeline,
|
|
@@ -265,11 +275,13 @@
|
|
|
265
275
|
dualAxisSpecPipeline: ()=>dualAxisSpecPipeline,
|
|
266
276
|
zAnnotationVerticalLine: ()=>zAnnotationVerticalLine,
|
|
267
277
|
barSpecPipeline: ()=>barSpecPipeline,
|
|
278
|
+
isDynamicFilter: ()=>isDynamicFilter,
|
|
268
279
|
unfoldDimensions: ()=>unfoldDimensions,
|
|
269
280
|
roseParallelAdvancedPipeline: ()=>roseParallelAdvancedPipeline,
|
|
270
281
|
zPieConfig: ()=>zPieConfig,
|
|
271
282
|
Builder: ()=>Builder,
|
|
272
283
|
zWhiskersConfig: ()=>zWhiskersConfig,
|
|
284
|
+
matchDynamicFilterResult: ()=>matchDynamicFilterResult,
|
|
273
285
|
revisedBoxPlotFieldKey: ()=>revisedBoxPlotFieldKey,
|
|
274
286
|
sunburstSpecPipeline: ()=>sunburstSpecPipeline,
|
|
275
287
|
radarSpecPipeline: ()=>radarSpecPipeline,
|
|
@@ -277,10 +289,11 @@
|
|
|
277
289
|
zRadar: ()=>zRadar,
|
|
278
290
|
zTable: ()=>zTable,
|
|
279
291
|
histogramSpecPipeline: ()=>histogramSpecPipeline,
|
|
280
|
-
|
|
292
|
+
isValueDynamicFilter: ()=>isValueDynamicFilter,
|
|
281
293
|
registerCustomTheme: ()=>registerCustomTheme,
|
|
282
|
-
|
|
294
|
+
registerLine: ()=>registerLine,
|
|
283
295
|
registerRoseParallel: ()=>registerRoseParallel,
|
|
296
|
+
zAreaSelector: ()=>zAreaSelector,
|
|
284
297
|
zDonutConfig: ()=>zDonutConfig,
|
|
285
298
|
zMeasureGroup: ()=>zMeasureGroup,
|
|
286
299
|
zPieLabel: ()=>zPieLabel,
|
|
@@ -288,6 +301,7 @@
|
|
|
288
301
|
zRadarConfig: ()=>zRadarConfig,
|
|
289
302
|
a: ()=>i18n_a,
|
|
290
303
|
createNumFormatter: ()=>createNumFormatter,
|
|
304
|
+
HAS_BUILTIN_UTILS: ()=>HAS_BUILTIN_UTILS,
|
|
291
305
|
zAreaConfig: ()=>zAreaConfig,
|
|
292
306
|
zPage: ()=>zPage,
|
|
293
307
|
zLine: ()=>zLine,
|
|
@@ -309,13 +323,16 @@
|
|
|
309
323
|
lightTheme: ()=>lightTheme,
|
|
310
324
|
registerColumnParallel: ()=>registerColumnParallel,
|
|
311
325
|
updateAdvanced: ()=>updateAdvanced,
|
|
326
|
+
initializeWorkerPool: ()=>initializeWorkerPool,
|
|
312
327
|
treeMapAdvancedPipeline: ()=>treeMapAdvancedPipeline,
|
|
313
328
|
histogramAdvancedPipeline: ()=>histogramAdvancedPipeline,
|
|
314
329
|
condition: ()=>condition_condition,
|
|
330
|
+
selectorWithDynamicFilter: ()=>selectorWithDynamicFilter,
|
|
315
331
|
isAreaPercent: ()=>isAreaPercent,
|
|
316
332
|
zColumn: ()=>zColumn,
|
|
317
333
|
zCustomTheme: ()=>zCustomTheme,
|
|
318
334
|
zTableConfig: ()=>zTableConfig,
|
|
335
|
+
executeDynamicFilter: ()=>executeDynamicFilter,
|
|
319
336
|
zColumnPercentConfig: ()=>zColumnPercentConfig,
|
|
320
337
|
zBarGapInGroup: ()=>zBarGapInGroup,
|
|
321
338
|
ChartTypeEnum: ()=>ChartTypeEnum,
|
|
@@ -339,6 +356,7 @@
|
|
|
339
356
|
zAdvancedVSeed: ()=>zAdvancedVSeed,
|
|
340
357
|
isRectungularCoordinate: ()=>isRectungularCoordinate,
|
|
341
358
|
zEncoding: ()=>zEncoding,
|
|
359
|
+
zValueDynamicFilter: ()=>zValueDynamicFilter,
|
|
342
360
|
zAreaPercent: ()=>zAreaPercent,
|
|
343
361
|
isValueSelector: ()=>isValueSelector,
|
|
344
362
|
donutAdvancedPipeline: ()=>donutAdvancedPipeline,
|
|
@@ -346,15 +364,15 @@
|
|
|
346
364
|
zScatterConfig: ()=>zScatterConfig,
|
|
347
365
|
zTooltip: ()=>zTooltip,
|
|
348
366
|
isBarLikeChart: ()=>isBarLikeChart,
|
|
349
|
-
isDualAxisChartType: ()=>isDualAxisChartType,
|
|
350
|
-
deleteMeasureTreeByCallback: ()=>deleteMeasureTreeByCallback,
|
|
351
|
-
zBarPercentConfig: ()=>zBarPercentConfig,
|
|
352
367
|
barParallelAdvancedPipeline: ()=>barParallelAdvancedPipeline,
|
|
368
|
+
deleteMeasureTreeByCallback: ()=>deleteMeasureTreeByCallback,
|
|
353
369
|
barPercentSpecPipeline: ()=>barPercentSpecPipeline,
|
|
354
|
-
lineSpecPipeline: ()=>lineSpecPipeline,
|
|
355
370
|
circlePackingAdvancedPipeline: ()=>circlePackingAdvancedPipeline,
|
|
356
|
-
raceBarAdvancedPipeline: ()=>raceBarAdvancedPipeline,
|
|
357
371
|
dataReshapeByEncoding: ()=>dataReshapeByEncoding,
|
|
372
|
+
lineSpecPipeline: ()=>lineSpecPipeline,
|
|
373
|
+
isDualAxisChartType: ()=>isDualAxisChartType,
|
|
374
|
+
raceBarAdvancedPipeline: ()=>raceBarAdvancedPipeline,
|
|
375
|
+
zBarPercentConfig: ()=>zBarPercentConfig,
|
|
358
376
|
raceColumnAdvancedPipeline: ()=>raceColumnAdvancedPipeline,
|
|
359
377
|
isPositionMeasure: ()=>isPositionMeasure,
|
|
360
378
|
zDimensionGroup: ()=>zDimensionGroup
|
|
@@ -447,33 +465,1600 @@
|
|
|
447
465
|
builder.performance['buildAdvanced'] = `${(end - start).toFixed(4)}ms`;
|
|
448
466
|
}
|
|
449
467
|
};
|
|
450
|
-
const buildSpec = (builder, advancedVSeed)=>{
|
|
451
|
-
const start = 'undefined' != typeof performance ? performance.now() : Date.now();
|
|
452
|
-
const { chartType } = builder.vseed;
|
|
453
|
-
const pipeline = Builder.getSpecPipeline(chartType);
|
|
454
|
-
if (!pipeline) throw new Error(`please invoke registerAll or register ${chartType} before build, no spec pipeline for chartType ${chartType}`);
|
|
455
|
-
const context = {
|
|
456
|
-
vseed: builder.vseed,
|
|
457
|
-
advancedVSeed
|
|
468
|
+
const buildSpec = (builder, advancedVSeed)=>{
|
|
469
|
+
const start = 'undefined' != typeof performance ? performance.now() : Date.now();
|
|
470
|
+
const { chartType } = builder.vseed;
|
|
471
|
+
const pipeline = Builder.getSpecPipeline(chartType);
|
|
472
|
+
if (!pipeline) throw new Error(`please invoke registerAll or register ${chartType} before build, no spec pipeline for chartType ${chartType}`);
|
|
473
|
+
const context = {
|
|
474
|
+
vseed: builder.vseed,
|
|
475
|
+
advancedVSeed
|
|
476
|
+
};
|
|
477
|
+
if (builder.locale) intl.setLocale(builder.locale);
|
|
478
|
+
try {
|
|
479
|
+
const spec = execPipeline(pipeline, context);
|
|
480
|
+
builder.spec = spec;
|
|
481
|
+
return spec;
|
|
482
|
+
} catch (e) {
|
|
483
|
+
console.error(e);
|
|
484
|
+
throw new Error(`buildSpec error: ${e.message}`);
|
|
485
|
+
} finally{
|
|
486
|
+
const end = 'undefined' != typeof performance ? performance.now() : Date.now();
|
|
487
|
+
builder.performance['buildSpec'] = `${(end - start).toFixed(4)}ms`;
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
const build = (builder)=>{
|
|
491
|
+
const advancedVSeed = builder.buildAdvanced();
|
|
492
|
+
if (!advancedVSeed) throw new Error('advancedVSeed is null');
|
|
493
|
+
const spec = builder.buildSpec(advancedVSeed);
|
|
494
|
+
return spec;
|
|
495
|
+
};
|
|
496
|
+
const ORIGINAL_DATA = '__OriginalData__';
|
|
497
|
+
const FoldMeasureName = '__MeaName__';
|
|
498
|
+
const FoldMeasureId = '__MeaId__';
|
|
499
|
+
const FoldMeasureValue = '__MeaValue__';
|
|
500
|
+
const MeasureId = FoldMeasureId;
|
|
501
|
+
const MeasureName = FoldMeasureName;
|
|
502
|
+
const FoldPrimaryMeasureValue = '__MeaPrimaryValue__';
|
|
503
|
+
const FoldSecondaryMeasureValue = '__MeaSecondaryValue__';
|
|
504
|
+
const DimAxisType = '__Dim_AxisType__';
|
|
505
|
+
const FoldXMeasureValue = '__MeaXValue__';
|
|
506
|
+
const FoldYMeasureValue = '__MeaYValue__';
|
|
507
|
+
const FoldXMeasureId = '__MeaXId__';
|
|
508
|
+
const FoldYMeasureId = '__MeaYId__';
|
|
509
|
+
const XEncoding = '__Dim_X__';
|
|
510
|
+
const YEncoding = '__Dim_Y__';
|
|
511
|
+
const AngleEncoding = '__Dim_Angle__';
|
|
512
|
+
const DetailEncoding = '__Dim_Detail__';
|
|
513
|
+
const PlayerEncoding = '__Dim_Player__';
|
|
514
|
+
const ColorEncoding = '__Dim_Color__';
|
|
515
|
+
const ColorIdEncoding = '__Dim_ColorId__';
|
|
516
|
+
const HierarchyEncoding = '__Dim_Hierarchy__';
|
|
517
|
+
const BoxPlotPivotIndicator = '__BoxPlot_Pivot_Indicator__';
|
|
518
|
+
const LowerWhisker = '__Lower_Whisker__';
|
|
519
|
+
const UpperWhisker = '__Upper_Whisker__';
|
|
520
|
+
const OutliersMeasureId = '__Outliers__';
|
|
521
|
+
const MedianMeasureId = '__Meadian__';
|
|
522
|
+
const BinStartMeasureId = '__BinStart__';
|
|
523
|
+
const BinEndMeasureId = '__BinEnd__';
|
|
524
|
+
const BinCountMeasureId = '__BinCount__';
|
|
525
|
+
const BinPercentageMeasureId = '__BinPercentage__';
|
|
526
|
+
const InnerRowIndex = '__row_index';
|
|
527
|
+
function chunk_D6FCK2GA_u(o, n, a) {
|
|
528
|
+
let t = (r)=>o(r, ...n);
|
|
529
|
+
return void 0 === a ? t : Object.assign(t, {
|
|
530
|
+
lazy: a,
|
|
531
|
+
lazyArgs: n
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
function chunk_WIMGWYZL_u(r, n, o) {
|
|
535
|
+
let a = r.length - n.length;
|
|
536
|
+
if (0 === a) return r(...n);
|
|
537
|
+
if (1 === a) return chunk_D6FCK2GA_u(r, n, o);
|
|
538
|
+
throw new Error("Wrong number of arguments");
|
|
539
|
+
}
|
|
540
|
+
function chunk_AIG3BDKO_i(...e) {
|
|
541
|
+
return chunk_WIMGWYZL_u(chunk_AIG3BDKO_n, e);
|
|
542
|
+
}
|
|
543
|
+
var chunk_AIG3BDKO_n = (e, r)=>e.length >= r;
|
|
544
|
+
function chunk_KI5X74E2_y(...t) {
|
|
545
|
+
return chunk_WIMGWYZL_u(chunk_KI5X74E2_f, t);
|
|
546
|
+
}
|
|
547
|
+
function chunk_KI5X74E2_f(t, e) {
|
|
548
|
+
if (!chunk_AIG3BDKO_i(e, 1)) return {
|
|
549
|
+
...t
|
|
550
|
+
};
|
|
551
|
+
if (!chunk_AIG3BDKO_i(e, 2)) {
|
|
552
|
+
let { [e[0]]: r, ...m } = t;
|
|
553
|
+
return m;
|
|
554
|
+
}
|
|
555
|
+
let o = {
|
|
556
|
+
...t
|
|
557
|
+
};
|
|
558
|
+
for (let r of e)delete o[r];
|
|
559
|
+
return o;
|
|
560
|
+
}
|
|
561
|
+
const BUILTIN_UTILS_SOURCE = `
|
|
562
|
+
// ============================================
|
|
563
|
+
// 内置工具库 - 与 lodash/Ramda 兼容
|
|
564
|
+
// ============================================
|
|
565
|
+
|
|
566
|
+
const _ = {
|
|
567
|
+
// ========== 数组操作 ==========
|
|
568
|
+
|
|
569
|
+
map: (array, iteratee) => {
|
|
570
|
+
if (!Array.isArray(array)) return [];
|
|
571
|
+
return array.map(typeof iteratee === 'function'
|
|
572
|
+
? iteratee
|
|
573
|
+
: item => item?.[iteratee]);
|
|
574
|
+
},
|
|
575
|
+
|
|
576
|
+
filter: (array, predicate) => {
|
|
577
|
+
if (!Array.isArray(array)) return [];
|
|
578
|
+
if (typeof predicate === 'function') return array.filter(predicate);
|
|
579
|
+
if (typeof predicate === 'object') {
|
|
580
|
+
return array.filter(item =>
|
|
581
|
+
Object.entries(predicate).every(([key, val]) => item?.[key] === val)
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
return array.filter(item => item?.[predicate]);
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
find: (array, predicate) => {
|
|
588
|
+
if (!Array.isArray(array)) return undefined;
|
|
589
|
+
if (typeof predicate === 'function') return array.find(predicate);
|
|
590
|
+
if (typeof predicate === 'object') {
|
|
591
|
+
return array.find(item =>
|
|
592
|
+
Object.entries(predicate).every(([key, val]) => item?.[key] === val)
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
return array.find(item => item?.[predicate]);
|
|
596
|
+
},
|
|
597
|
+
|
|
598
|
+
some: (array, predicate) => {
|
|
599
|
+
if (!Array.isArray(array)) return false;
|
|
600
|
+
if (typeof predicate === 'function') return array.some(predicate);
|
|
601
|
+
return array.some(item => item?.[predicate]);
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
every: (array, predicate) => {
|
|
605
|
+
if (!Array.isArray(array)) return true;
|
|
606
|
+
if (typeof predicate === 'function') return array.every(predicate);
|
|
607
|
+
return array.every(item => item?.[predicate]);
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
reduce: (array, iteratee, accumulator) => {
|
|
611
|
+
if (!Array.isArray(array)) return accumulator;
|
|
612
|
+
return accumulator !== undefined
|
|
613
|
+
? array.reduce(iteratee, accumulator)
|
|
614
|
+
: array.reduce(iteratee);
|
|
615
|
+
},
|
|
616
|
+
|
|
617
|
+
groupBy: (array, iteratee) => {
|
|
618
|
+
if (!Array.isArray(array)) return {};
|
|
619
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
620
|
+
return array.reduce((result, item) => {
|
|
621
|
+
const key = fn(item);
|
|
622
|
+
(result[key] = result[key] || []).push(item);
|
|
623
|
+
return result;
|
|
624
|
+
}, {});
|
|
625
|
+
},
|
|
626
|
+
|
|
627
|
+
sortBy: (array, iteratees) => {
|
|
628
|
+
if (!Array.isArray(array)) return [];
|
|
629
|
+
const arr = [...array];
|
|
630
|
+
const fns = Array.isArray(iteratees) ? iteratees : [iteratees];
|
|
631
|
+
return arr.sort((a, b) => {
|
|
632
|
+
for (const fn of fns) {
|
|
633
|
+
const getVal = typeof fn === 'function' ? fn : item => item?.[fn];
|
|
634
|
+
const valA = getVal(a);
|
|
635
|
+
const valB = getVal(b);
|
|
636
|
+
if (valA < valB) return -1;
|
|
637
|
+
if (valA > valB) return 1;
|
|
638
|
+
}
|
|
639
|
+
return 0;
|
|
640
|
+
});
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
uniq: (array) => {
|
|
644
|
+
if (!Array.isArray(array)) return [];
|
|
645
|
+
return [...new Set(array)];
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
uniqBy: (array, iteratee) => {
|
|
649
|
+
if (!Array.isArray(array)) return [];
|
|
650
|
+
const seen = new Set();
|
|
651
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
652
|
+
return array.filter(item => {
|
|
653
|
+
const key = fn(item);
|
|
654
|
+
if (seen.has(key)) return false;
|
|
655
|
+
seen.add(key);
|
|
656
|
+
return true;
|
|
657
|
+
});
|
|
658
|
+
},
|
|
659
|
+
|
|
660
|
+
flatten: (array) => {
|
|
661
|
+
if (!Array.isArray(array)) return [];
|
|
662
|
+
return array.flat();
|
|
663
|
+
},
|
|
664
|
+
|
|
665
|
+
flattenDeep: (array) => {
|
|
666
|
+
if (!Array.isArray(array)) return [];
|
|
667
|
+
return array.flat(Infinity);
|
|
668
|
+
},
|
|
669
|
+
|
|
670
|
+
chunk: (array, size = 1) => {
|
|
671
|
+
if (!Array.isArray(array) || size < 1) return [];
|
|
672
|
+
const result = [];
|
|
673
|
+
for (let i = 0; i < array.length; i += size) {
|
|
674
|
+
result.push(array.slice(i, i + size));
|
|
675
|
+
}
|
|
676
|
+
return result;
|
|
677
|
+
},
|
|
678
|
+
|
|
679
|
+
take: (array, n = 1) => {
|
|
680
|
+
if (!Array.isArray(array)) return [];
|
|
681
|
+
return array.slice(0, n);
|
|
682
|
+
},
|
|
683
|
+
|
|
684
|
+
drop: (array, n = 1) => {
|
|
685
|
+
if (!Array.isArray(array)) return [];
|
|
686
|
+
return array.slice(n);
|
|
687
|
+
},
|
|
688
|
+
|
|
689
|
+
compact: (array) => {
|
|
690
|
+
if (!Array.isArray(array)) return [];
|
|
691
|
+
return array.filter(Boolean);
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
// ========== 对象操作 ==========
|
|
695
|
+
|
|
696
|
+
keys: (obj) => {
|
|
697
|
+
if (!obj || typeof obj !== 'object') return [];
|
|
698
|
+
return Object.keys(obj);
|
|
699
|
+
},
|
|
700
|
+
|
|
701
|
+
values: (obj) => {
|
|
702
|
+
if (!obj || typeof obj !== 'object') return [];
|
|
703
|
+
return Object.values(obj);
|
|
704
|
+
},
|
|
705
|
+
|
|
706
|
+
entries: (obj) => {
|
|
707
|
+
if (!obj || typeof obj !== 'object') return [];
|
|
708
|
+
return Object.entries(obj);
|
|
709
|
+
},
|
|
710
|
+
|
|
711
|
+
pick: (obj, keys) => {
|
|
712
|
+
if (!obj || typeof obj !== 'object') return {};
|
|
713
|
+
const picked = {};
|
|
714
|
+
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
715
|
+
keyArray.forEach(key => {
|
|
716
|
+
if (key in obj) picked[key] = obj[key];
|
|
717
|
+
});
|
|
718
|
+
return picked;
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
omit: (obj, keys) => {
|
|
722
|
+
if (!obj || typeof obj !== 'object') return {};
|
|
723
|
+
const result = { ...obj };
|
|
724
|
+
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
725
|
+
keyArray.forEach(key => delete result[key]);
|
|
726
|
+
return result;
|
|
727
|
+
},
|
|
728
|
+
|
|
729
|
+
mapValues: (obj, iteratee) => {
|
|
730
|
+
if (!obj || typeof obj !== 'object') return {};
|
|
731
|
+
const result = {};
|
|
732
|
+
const fn = typeof iteratee === 'function' ? iteratee : () => iteratee;
|
|
733
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
734
|
+
result[key] = fn(value, key, obj);
|
|
735
|
+
});
|
|
736
|
+
return result;
|
|
737
|
+
},
|
|
738
|
+
|
|
739
|
+
get: (obj, path, defaultValue) => {
|
|
740
|
+
if (!obj) return defaultValue;
|
|
741
|
+
const keys = Array.isArray(path) ? path : path.split('.');
|
|
742
|
+
let result = obj;
|
|
743
|
+
for (const key of keys) {
|
|
744
|
+
result = result?.[key];
|
|
745
|
+
if (result === undefined) return defaultValue;
|
|
746
|
+
}
|
|
747
|
+
return result;
|
|
748
|
+
},
|
|
749
|
+
|
|
750
|
+
// ========== 数据判断 ==========
|
|
751
|
+
|
|
752
|
+
isArray: (value) => Array.isArray(value),
|
|
753
|
+
|
|
754
|
+
isObject: (value) => {
|
|
755
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
isString: (value) => typeof value === 'string',
|
|
759
|
+
|
|
760
|
+
isNumber: (value) => typeof value === 'number' && !isNaN(value),
|
|
761
|
+
|
|
762
|
+
isBoolean: (value) => typeof value === 'boolean',
|
|
763
|
+
|
|
764
|
+
isFunction: (value) => typeof value === 'function',
|
|
765
|
+
|
|
766
|
+
isNil: (value) => value === null || value === undefined,
|
|
767
|
+
|
|
768
|
+
isEmpty: (value) => {
|
|
769
|
+
if (value == null) return true;
|
|
770
|
+
if (Array.isArray(value) || typeof value === 'string') return value.length === 0;
|
|
771
|
+
if (typeof value === 'object') return Object.keys(value).length === 0;
|
|
772
|
+
return false;
|
|
773
|
+
},
|
|
774
|
+
|
|
775
|
+
// ========== 数学统计 ==========
|
|
776
|
+
|
|
777
|
+
sum: (array) => {
|
|
778
|
+
if (!Array.isArray(array)) return 0;
|
|
779
|
+
return array.reduce((sum, n) => sum + (Number(n) || 0), 0);
|
|
780
|
+
},
|
|
781
|
+
|
|
782
|
+
sumBy: (array, iteratee) => {
|
|
783
|
+
if (!Array.isArray(array)) return 0;
|
|
784
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
785
|
+
return array.reduce((sum, item) => sum + (Number(fn(item)) || 0), 0);
|
|
786
|
+
},
|
|
787
|
+
|
|
788
|
+
mean: (array) => {
|
|
789
|
+
if (!Array.isArray(array) || array.length === 0) return 0;
|
|
790
|
+
return _.sum(array) / array.length;
|
|
791
|
+
},
|
|
792
|
+
|
|
793
|
+
meanBy: (array, iteratee) => {
|
|
794
|
+
if (!Array.isArray(array) || array.length === 0) return 0;
|
|
795
|
+
return _.sumBy(array, iteratee) / array.length;
|
|
796
|
+
},
|
|
797
|
+
|
|
798
|
+
max: (array) => {
|
|
799
|
+
if (!Array.isArray(array) || array.length === 0) return undefined;
|
|
800
|
+
return Math.max(...array.map(Number).filter(n => !isNaN(n)));
|
|
801
|
+
},
|
|
802
|
+
|
|
803
|
+
maxBy: (array, iteratee) => {
|
|
804
|
+
if (!Array.isArray(array) || array.length === 0) return undefined;
|
|
805
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
806
|
+
return array.reduce((max, item) => {
|
|
807
|
+
const val = fn(item);
|
|
808
|
+
return max === undefined || val > fn(max) ? item : max;
|
|
809
|
+
}, undefined);
|
|
810
|
+
},
|
|
811
|
+
|
|
812
|
+
min: (array) => {
|
|
813
|
+
if (!Array.isArray(array) || array.length === 0) return undefined;
|
|
814
|
+
return Math.min(...array.map(Number).filter(n => !isNaN(n)));
|
|
815
|
+
},
|
|
816
|
+
|
|
817
|
+
minBy: (array, iteratee) => {
|
|
818
|
+
if (!Array.isArray(array) || array.length === 0) return undefined;
|
|
819
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
820
|
+
return array.reduce((min, item) => {
|
|
821
|
+
const val = fn(item);
|
|
822
|
+
return min === undefined || val < fn(min) ? item : min;
|
|
823
|
+
}, undefined);
|
|
824
|
+
},
|
|
825
|
+
|
|
826
|
+
count: (array) => {
|
|
827
|
+
if (!Array.isArray(array)) return 0;
|
|
828
|
+
return array.length;
|
|
829
|
+
},
|
|
830
|
+
|
|
831
|
+
countBy: (array, iteratee) => {
|
|
832
|
+
if (!Array.isArray(array)) return {};
|
|
833
|
+
const fn = typeof iteratee === 'function' ? iteratee : item => item?.[iteratee];
|
|
834
|
+
return array.reduce((result, item) => {
|
|
835
|
+
const key = fn(item);
|
|
836
|
+
result[key] = (result[key] || 0) + 1;
|
|
837
|
+
return result;
|
|
838
|
+
}, {});
|
|
839
|
+
},
|
|
840
|
+
|
|
841
|
+
// ========== 其他工具 ==========
|
|
842
|
+
|
|
843
|
+
cloneDeep: (value) => {
|
|
844
|
+
if (value === null || typeof value !== 'object') return value;
|
|
845
|
+
if (Array.isArray(value)) return value.map(_.cloneDeep);
|
|
846
|
+
return Object.fromEntries(
|
|
847
|
+
Object.entries(value).map(([k, v]) => [k, _.cloneDeep(v)])
|
|
848
|
+
);
|
|
849
|
+
},
|
|
850
|
+
|
|
851
|
+
merge: (...objects) => {
|
|
852
|
+
return Object.assign({}, ...objects);
|
|
853
|
+
},
|
|
854
|
+
|
|
855
|
+
debounce: (func, wait = 0) => {
|
|
856
|
+
let timeout;
|
|
857
|
+
return function(...args) {
|
|
858
|
+
clearTimeout(timeout);
|
|
859
|
+
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
860
|
+
};
|
|
861
|
+
},
|
|
862
|
+
|
|
863
|
+
throttle: (func, wait = 0) => {
|
|
864
|
+
let lastTime = 0;
|
|
865
|
+
return function(...args) {
|
|
866
|
+
const now = Date.now();
|
|
867
|
+
if (now - lastTime >= wait) {
|
|
868
|
+
lastTime = now;
|
|
869
|
+
return func.apply(this, args);
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
},
|
|
873
|
+
|
|
874
|
+
range: (start, end, step = 1) => {
|
|
875
|
+
if (end === undefined) {
|
|
876
|
+
end = start;
|
|
877
|
+
start = 0;
|
|
878
|
+
}
|
|
879
|
+
const result = [];
|
|
880
|
+
for (let i = start; i < end; i += step) {
|
|
881
|
+
result.push(i);
|
|
882
|
+
}
|
|
883
|
+
return result;
|
|
884
|
+
},
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
// 同时暴露为 R (Ramda 风格)
|
|
888
|
+
const R = _;
|
|
889
|
+
|
|
890
|
+
// 暴露到全局
|
|
891
|
+
self._ = _;
|
|
892
|
+
self.R = R;
|
|
893
|
+
`.trim();
|
|
894
|
+
const HAS_BUILTIN_UTILS = BUILTIN_UTILS_SOURCE.length > 100;
|
|
895
|
+
class WorkerPool {
|
|
896
|
+
workers = [];
|
|
897
|
+
availableWorkers = [];
|
|
898
|
+
maxSize;
|
|
899
|
+
isInitialized = false;
|
|
900
|
+
constructor(maxSize = 2){
|
|
901
|
+
this.maxSize = maxSize;
|
|
902
|
+
}
|
|
903
|
+
async initialize() {
|
|
904
|
+
if (this.isInitialized) return;
|
|
905
|
+
for(let i = 0; i < this.maxSize; i++)try {
|
|
906
|
+
const worker = await this.createSecureWorker();
|
|
907
|
+
this.workers.push(worker);
|
|
908
|
+
this.availableWorkers.push(worker);
|
|
909
|
+
} catch (error) {
|
|
910
|
+
this.workers.forEach((w)=>w.terminate());
|
|
911
|
+
this.workers = [];
|
|
912
|
+
this.availableWorkers = [];
|
|
913
|
+
throw new Error(`Failed to initialize Worker pool: ${error instanceof Error ? error.message : String(error)}`);
|
|
914
|
+
}
|
|
915
|
+
this.isInitialized = true;
|
|
916
|
+
}
|
|
917
|
+
createSecureWorker() {
|
|
918
|
+
const libraryLoadCode = `// 内置工具库(lodash/Ramda 兼容 API)\n${BUILTIN_UTILS_SOURCE}`;
|
|
919
|
+
const workerCode = `
|
|
920
|
+
// ============================================
|
|
921
|
+
// 阶段 1: 立即执行安全加固 (IIFE)
|
|
922
|
+
// ============================================
|
|
923
|
+
(function initSecureSandbox() {
|
|
924
|
+
'use strict';
|
|
925
|
+
|
|
926
|
+
// 1.1 保存必要的原生引用(在被删除前)
|
|
927
|
+
const nativeImportScripts = self.importScripts;
|
|
928
|
+
const nativePostMessage = self.postMessage.bind(self);
|
|
929
|
+
|
|
930
|
+
// 1.2 立即删除危险 API
|
|
931
|
+
delete self.importScripts;
|
|
932
|
+
delete self.fetch;
|
|
933
|
+
delete self.XMLHttpRequest;
|
|
934
|
+
delete self.WebSocket;
|
|
935
|
+
|
|
936
|
+
// 1.3 冻结关键原型链(防止污染和篡改)
|
|
937
|
+
Object.freeze(Object.prototype);
|
|
938
|
+
Object.freeze(Array.prototype);
|
|
939
|
+
Object.freeze(Function.prototype);
|
|
940
|
+
Object.freeze(String.prototype);
|
|
941
|
+
Object.freeze(Number.prototype);
|
|
942
|
+
Object.freeze(Boolean.prototype);
|
|
943
|
+
|
|
944
|
+
// ============================================
|
|
945
|
+
// 阶段 2: 加载工具库
|
|
946
|
+
// ============================================
|
|
947
|
+
try {
|
|
948
|
+
${libraryLoadCode}
|
|
949
|
+
} catch (error) {
|
|
950
|
+
nativePostMessage({
|
|
951
|
+
initError: 'Failed to load utility library: ' + error.message
|
|
952
|
+
});
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// 验证库是否加载成功
|
|
957
|
+
const utilityLib = self._;
|
|
958
|
+
if (!utilityLib) {
|
|
959
|
+
nativePostMessage({
|
|
960
|
+
initError: 'Builtin utility library (_ or R) not found after loading'
|
|
961
|
+
});
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// ============================================
|
|
966
|
+
// 阶段 3: 创建安全上下文
|
|
967
|
+
// ============================================
|
|
968
|
+
const createSafeContext = (lib) => {
|
|
969
|
+
const allowedGlobals = {
|
|
970
|
+
// 工具库
|
|
971
|
+
_: lib,
|
|
972
|
+
R: lib,
|
|
973
|
+
|
|
974
|
+
// 基础类型构造函数(只读)
|
|
975
|
+
Array: Array,
|
|
976
|
+
Object: Object,
|
|
977
|
+
String: String,
|
|
978
|
+
Number: Number,
|
|
979
|
+
Boolean: Boolean,
|
|
980
|
+
Date: Date,
|
|
981
|
+
|
|
982
|
+
// 数学和工具
|
|
983
|
+
Math: Math,
|
|
984
|
+
JSON: JSON,
|
|
985
|
+
|
|
986
|
+
// 类型检查
|
|
987
|
+
parseInt: parseInt,
|
|
988
|
+
parseFloat: parseFloat,
|
|
989
|
+
isNaN: isNaN,
|
|
990
|
+
isFinite: isFinite,
|
|
991
|
+
|
|
992
|
+
// 错误类型(用于调试)
|
|
993
|
+
Error: Error,
|
|
994
|
+
TypeError: TypeError,
|
|
995
|
+
RangeError: RangeError,
|
|
996
|
+
|
|
997
|
+
// 只读的数据引用
|
|
998
|
+
data: null,
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
// 使用 Proxy 严格控制访问
|
|
1002
|
+
return new Proxy(allowedGlobals, {
|
|
1003
|
+
get(target, prop) {
|
|
1004
|
+
if (prop === Symbol.unscopables) {
|
|
1005
|
+
return undefined;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
if (prop in target) {
|
|
1009
|
+
return target[prop];
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// 拒绝访问任何未定义的属性
|
|
1013
|
+
throw new ReferenceError(
|
|
1014
|
+
\`'\${String(prop)}' is not defined. \\n\` +
|
|
1015
|
+
\`Only these globals are available: \${Object.keys(allowedGlobals).join(', ')}\`
|
|
1016
|
+
);
|
|
1017
|
+
},
|
|
1018
|
+
|
|
1019
|
+
set(target, prop, value) {
|
|
1020
|
+
// 只允许设置 data 属性(用于传递执行数据)
|
|
1021
|
+
if (prop === 'data') {
|
|
1022
|
+
target[prop] = value;
|
|
1023
|
+
return true;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// 拒绝设置其他属性
|
|
1027
|
+
throw new TypeError(
|
|
1028
|
+
\`Cannot set property '\${String(prop)}' on global context\`
|
|
1029
|
+
);
|
|
1030
|
+
},
|
|
1031
|
+
|
|
1032
|
+
has(target, prop) {
|
|
1033
|
+
return prop in target;
|
|
1034
|
+
},
|
|
1035
|
+
|
|
1036
|
+
// 防止 getOwnPropertyDescriptor 等元编程操作
|
|
1037
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
1038
|
+
if (prop in target) {
|
|
1039
|
+
return Object.getOwnPropertyDescriptor(target, prop);
|
|
1040
|
+
}
|
|
1041
|
+
return undefined;
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
const safeContext = createSafeContext(utilityLib);
|
|
1047
|
+
|
|
1048
|
+
// ============================================
|
|
1049
|
+
// 阶段 4: 代码执行引擎
|
|
1050
|
+
// ============================================
|
|
1051
|
+
const executeUserCodeSafely = (code, data, timeout) => {
|
|
1052
|
+
// 设置超时保护(内层防御)
|
|
1053
|
+
let timeoutId = null;
|
|
1054
|
+
let isTimedOut = false;
|
|
1055
|
+
|
|
1056
|
+
if (timeout > 0) {
|
|
1057
|
+
timeoutId = setTimeout(() => {
|
|
1058
|
+
isTimedOut = true;
|
|
1059
|
+
}, timeout);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
try {
|
|
1063
|
+
// 超时检查函数
|
|
1064
|
+
// ⚠️ 注意:这只能防御"合作式"的代码(包含 I/O、迭代、递归)
|
|
1065
|
+
// 对于纯计算死循环(while(true){}),只有外层 worker.terminate() 能终止
|
|
1066
|
+
const checkTimeout = () => {
|
|
1067
|
+
if (isTimedOut) {
|
|
1068
|
+
throw new Error(\`Execution timeout (exceeded \${timeout}ms)\`);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
// 更新安全上下文中的数据
|
|
1073
|
+
safeContext.data = data;
|
|
1074
|
+
|
|
1075
|
+
// 提取安全上下文的所有变量名和值
|
|
1076
|
+
const contextKeys = Object.keys(safeContext);
|
|
1077
|
+
const contextValues = contextKeys.map(key => safeContext[key]);
|
|
1078
|
+
|
|
1079
|
+
// 显式遮蔽 Worker 全局对象中的危险变量(设为 undefined)
|
|
1080
|
+
const shadowedGlobals = [
|
|
1081
|
+
'self', // Worker 全局对象本身
|
|
1082
|
+
'postMessage', // 通信通道(防止滥用)
|
|
1083
|
+
'close', // Worker 终止方法
|
|
1084
|
+
'importScripts', // 动态加载脚本(已删除,但显式遮蔽更安全)
|
|
1085
|
+
'addEventListener', // 事件监听器
|
|
1086
|
+
'removeEventListener',
|
|
1087
|
+
'dispatchEvent',
|
|
1088
|
+
'onmessage', // 消息处理器
|
|
1089
|
+
'onerror', // 错误处理器
|
|
1090
|
+
'onmessageerror',
|
|
1091
|
+
'setTimeout', // ⚠️ 遮蔽定时器,防止资源泄漏
|
|
1092
|
+
'clearTimeout',
|
|
1093
|
+
'setInterval', // ⚠️ 防止用户创建大量定时器
|
|
1094
|
+
'clearInterval',
|
|
1095
|
+
];
|
|
1096
|
+
|
|
1097
|
+
// 包装用户代码:在严格模式下执行,通过参数注入变量
|
|
1098
|
+
const wrappedCode = \`
|
|
1099
|
+
"use strict";
|
|
1100
|
+
// 用户代码在这里执行,可以直接访问注入的变量(_, R, data, Math, etc.)
|
|
1101
|
+
\${code}
|
|
1102
|
+
\`;
|
|
1103
|
+
|
|
1104
|
+
// 创建函数:参数是上下文变量名 + checkTimeout + 遮蔽的全局变量名
|
|
1105
|
+
const userFunction = new Function(
|
|
1106
|
+
...contextKeys, // 安全上下文变量
|
|
1107
|
+
'checkTimeout', // 超时检查函数(用户可选调用)
|
|
1108
|
+
...shadowedGlobals, // 显式遮蔽的危险全局变量
|
|
1109
|
+
wrappedCode
|
|
1110
|
+
);
|
|
1111
|
+
|
|
1112
|
+
// 执行并获取结果
|
|
1113
|
+
const result = userFunction(
|
|
1114
|
+
...contextValues, // 安全上下文的值
|
|
1115
|
+
checkTimeout, // 超时检查函数
|
|
1116
|
+
...shadowedGlobals.map(() => undefined) // 所有危险全局变量设为 undefined
|
|
1117
|
+
);
|
|
1118
|
+
|
|
1119
|
+
// 清除超时
|
|
1120
|
+
if (timeoutId) {
|
|
1121
|
+
clearTimeout(timeoutId);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// 验证返回值(只检查危险类型,不限制结构)
|
|
1125
|
+
const validateResultType = (result) => {
|
|
1126
|
+
const type = typeof result
|
|
1127
|
+
|
|
1128
|
+
// 禁止返回函数、Symbol
|
|
1129
|
+
if (type === 'function' || type === 'symbol') {
|
|
1130
|
+
throw new TypeError(
|
|
1131
|
+
\`Code must not return \${type}. Returned types must be serializable.\`
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// 禁止返回 Promise
|
|
1136
|
+
if (result && typeof result.then === 'function') {
|
|
1137
|
+
throw new TypeError(
|
|
1138
|
+
\`Code must not return a Promise. Async operations are not allowed.\`
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// 如果是数组,检查元素的危险类型
|
|
1143
|
+
if (Array.isArray(result)) {
|
|
1144
|
+
for (let i = 0; i < result.length; i++) {
|
|
1145
|
+
const item = result[i];
|
|
1146
|
+
const itemType = typeof item;
|
|
1147
|
+
|
|
1148
|
+
if (itemType === 'function' || itemType === 'symbol') {
|
|
1149
|
+
throw new TypeError(
|
|
1150
|
+
\`Array element at index \${i} has forbidden type: \${itemType}\`
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
if (item && typeof item.then === 'function') {
|
|
1155
|
+
throw new TypeError(
|
|
1156
|
+
\`Array element at index \${i} is a Promise. Async operations are not allowed.\`
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
validateResultType(result);
|
|
1164
|
+
|
|
1165
|
+
return result;
|
|
1166
|
+
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
throw error;
|
|
1169
|
+
} finally {
|
|
1170
|
+
// 清理数据引用(防止内存泄漏)
|
|
1171
|
+
safeContext.data = null;
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
// ============================================
|
|
1176
|
+
// 阶段 5: 消息处理
|
|
1177
|
+
// ============================================
|
|
1178
|
+
self.onmessage = function(event) {
|
|
1179
|
+
// ⚠️ 防御性检查:确保消息格式正确
|
|
1180
|
+
if (!event || !event.data) {
|
|
1181
|
+
nativePostMessage({
|
|
1182
|
+
taskId: 'unknown',
|
|
1183
|
+
success: false,
|
|
1184
|
+
error: 'Invalid message format: event.data is null or undefined'
|
|
1185
|
+
});
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
const { code, data, timeout, taskId } = event.data;
|
|
1190
|
+
|
|
1191
|
+
// 验证必需字段
|
|
1192
|
+
if (!taskId) {
|
|
1193
|
+
nativePostMessage({
|
|
1194
|
+
taskId: 'unknown',
|
|
1195
|
+
success: false,
|
|
1196
|
+
error: 'Invalid message: taskId is required'
|
|
1197
|
+
});
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
try {
|
|
1202
|
+
const result = executeUserCodeSafely(code, data, timeout);
|
|
1203
|
+
|
|
1204
|
+
nativePostMessage({
|
|
1205
|
+
taskId,
|
|
1206
|
+
success: true,
|
|
1207
|
+
result: result
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
nativePostMessage({
|
|
1212
|
+
taskId,
|
|
1213
|
+
success: false,
|
|
1214
|
+
error: error.message || String(error),
|
|
1215
|
+
errorType: error.constructor.name
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
// 错误捕获
|
|
1221
|
+
self.onerror = function(event) {
|
|
1222
|
+
nativePostMessage({
|
|
1223
|
+
globalError: event.message || 'Unknown worker error'
|
|
1224
|
+
});
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
// 发送初始化成功消息
|
|
1228
|
+
nativePostMessage({ initialized: true });
|
|
1229
|
+
|
|
1230
|
+
})(); // 立即执行
|
|
1231
|
+
`;
|
|
1232
|
+
const blob = new Blob([
|
|
1233
|
+
workerCode
|
|
1234
|
+
], {
|
|
1235
|
+
type: "application/javascript"
|
|
1236
|
+
});
|
|
1237
|
+
const blobURL = URL.createObjectURL(blob);
|
|
1238
|
+
const worker = new Worker(blobURL);
|
|
1239
|
+
URL.revokeObjectURL(blobURL);
|
|
1240
|
+
return new Promise((resolve, reject)=>{
|
|
1241
|
+
let isSettled = false;
|
|
1242
|
+
const cleanup = ()=>{
|
|
1243
|
+
if (!isSettled) {
|
|
1244
|
+
isSettled = true;
|
|
1245
|
+
worker.onmessage = null;
|
|
1246
|
+
worker.onerror = null;
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
const timeout = setTimeout(()=>{
|
|
1250
|
+
cleanup();
|
|
1251
|
+
worker.terminate();
|
|
1252
|
+
reject(new Error('Worker initialization timeout'));
|
|
1253
|
+
}, 10000);
|
|
1254
|
+
worker.onmessage = (e)=>{
|
|
1255
|
+
if (e.data.initialized) {
|
|
1256
|
+
clearTimeout(timeout);
|
|
1257
|
+
cleanup();
|
|
1258
|
+
resolve(worker);
|
|
1259
|
+
} else if (e.data.initError) {
|
|
1260
|
+
clearTimeout(timeout);
|
|
1261
|
+
cleanup();
|
|
1262
|
+
worker.terminate();
|
|
1263
|
+
reject(new Error(e.data.initError));
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
worker.onerror = (errorEvent)=>{
|
|
1267
|
+
clearTimeout(timeout);
|
|
1268
|
+
cleanup();
|
|
1269
|
+
worker.terminate();
|
|
1270
|
+
const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker initialization error';
|
|
1271
|
+
reject(new Error(`Worker initialization failed: ${errorMessage}`));
|
|
1272
|
+
};
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
async acquire() {
|
|
1276
|
+
if (!this.isInitialized) await this.initialize();
|
|
1277
|
+
if (0 === this.availableWorkers.length) try {
|
|
1278
|
+
const tempWorker = await this.createSecureWorker();
|
|
1279
|
+
return tempWorker;
|
|
1280
|
+
} catch (error) {
|
|
1281
|
+
throw new Error(`Failed to create temporary Worker: ${error instanceof Error ? error.message : String(error)}`);
|
|
1282
|
+
}
|
|
1283
|
+
return this.availableWorkers.pop();
|
|
1284
|
+
}
|
|
1285
|
+
release(worker) {
|
|
1286
|
+
if (this.workers.includes(worker)) this.availableWorkers.push(worker);
|
|
1287
|
+
else worker.terminate();
|
|
1288
|
+
}
|
|
1289
|
+
terminate() {
|
|
1290
|
+
this.workers.forEach((worker)=>worker.terminate());
|
|
1291
|
+
this.workers = [];
|
|
1292
|
+
this.availableWorkers = [];
|
|
1293
|
+
this.isInitialized = false;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
let globalWorkerPool = null;
|
|
1297
|
+
let poolInitPromise = null;
|
|
1298
|
+
let poolConfig = {
|
|
1299
|
+
poolSize: 2
|
|
1300
|
+
};
|
|
1301
|
+
function getOrCreateWorkerPool() {
|
|
1302
|
+
if (globalWorkerPool) return Promise.resolve(globalWorkerPool);
|
|
1303
|
+
if (poolInitPromise) return poolInitPromise;
|
|
1304
|
+
poolInitPromise = (async ()=>{
|
|
1305
|
+
try {
|
|
1306
|
+
const pool = new WorkerPool(poolConfig.poolSize);
|
|
1307
|
+
await pool.initialize();
|
|
1308
|
+
globalWorkerPool = pool;
|
|
1309
|
+
return pool;
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
poolInitPromise = null;
|
|
1312
|
+
throw error;
|
|
1313
|
+
}
|
|
1314
|
+
})();
|
|
1315
|
+
return poolInitPromise;
|
|
1316
|
+
}
|
|
1317
|
+
async function initializeWorkerPool(options = {}) {
|
|
1318
|
+
poolConfig = {
|
|
1319
|
+
poolSize: options.poolSize ?? 2
|
|
1320
|
+
};
|
|
1321
|
+
await getOrCreateWorkerPool();
|
|
1322
|
+
}
|
|
1323
|
+
function terminateWorkerPool() {
|
|
1324
|
+
if (globalWorkerPool) {
|
|
1325
|
+
globalWorkerPool.terminate();
|
|
1326
|
+
globalWorkerPool = null;
|
|
1327
|
+
}
|
|
1328
|
+
poolInitPromise = null;
|
|
1329
|
+
}
|
|
1330
|
+
function validateCodeSafety(code) {
|
|
1331
|
+
if (!code || 0 === code.trim().length) throw new Error('Code cannot be empty');
|
|
1332
|
+
if (code.length > 50000) throw new Error('Code is too long (max 50KB)');
|
|
1333
|
+
if (!/\breturn\b/.test(code)) throw new Error('Code must contain a return statement');
|
|
1334
|
+
const forbiddenPatterns = [
|
|
1335
|
+
{
|
|
1336
|
+
pattern: /\beval\b/gi,
|
|
1337
|
+
description: 'eval()'
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
pattern: /\bFunction\s*\(/gi,
|
|
1341
|
+
description: 'Function constructor'
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
pattern: /\bnew\s+Function\b/gi,
|
|
1345
|
+
description: 'new Function()'
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
pattern: /\bimportScripts\b/gi,
|
|
1349
|
+
description: 'importScripts()'
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
pattern: /\bfetch\b/gi,
|
|
1353
|
+
description: 'fetch()'
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
pattern: /\bXMLHttpRequest\b/gi,
|
|
1357
|
+
description: 'XMLHttpRequest'
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
pattern: /\bWebSocket\b/gi,
|
|
1361
|
+
description: 'WebSocket'
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
pattern: /\blocalStorage\b/gi,
|
|
1365
|
+
description: 'localStorage'
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
pattern: /\bsessionStorage\b/gi,
|
|
1369
|
+
description: 'sessionStorage'
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
pattern: /\bindexedDB\b/gi,
|
|
1373
|
+
description: 'indexedDB'
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
pattern: /\bwindow\b/gi,
|
|
1377
|
+
description: 'window'
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
pattern: /\bdocument\b/gi,
|
|
1381
|
+
description: 'document'
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
pattern: /\bnavigator\b/gi,
|
|
1385
|
+
description: 'navigator'
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
pattern: /\blocation\b/gi,
|
|
1389
|
+
description: 'location'
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
pattern: /\brequire\b/gi,
|
|
1393
|
+
description: 'require()'
|
|
1394
|
+
},
|
|
1395
|
+
{
|
|
1396
|
+
pattern: /\bimport\s+/gi,
|
|
1397
|
+
description: 'import statement'
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
pattern: /\bexport\s+/gi,
|
|
1401
|
+
description: 'export statement'
|
|
1402
|
+
},
|
|
1403
|
+
{
|
|
1404
|
+
pattern: /\bconstructor\b/gi,
|
|
1405
|
+
description: 'constructor access'
|
|
1406
|
+
},
|
|
1407
|
+
{
|
|
1408
|
+
pattern: /\[['"]constructor['"]\]/gi,
|
|
1409
|
+
description: 'constructor via bracket notation'
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
pattern: /\['constructor'\]/gi,
|
|
1413
|
+
description: 'constructor string access'
|
|
1414
|
+
},
|
|
1415
|
+
{
|
|
1416
|
+
pattern: /\b__proto__\b/gi,
|
|
1417
|
+
description: '__proto__'
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
pattern: /\bprototype\b/gi,
|
|
1421
|
+
description: 'prototype manipulation'
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
pattern: /Object\.setPrototypeOf/gi,
|
|
1425
|
+
description: 'Object.setPrototypeOf()'
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
pattern: /Object\.getPrototypeOf/gi,
|
|
1429
|
+
description: 'Object.getPrototypeOf()'
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
pattern: /Object\.create\s*\(\s*null\s*\)/gi,
|
|
1433
|
+
description: 'Object.create(null)'
|
|
1434
|
+
},
|
|
1435
|
+
{
|
|
1436
|
+
pattern: /\bReflect\./gi,
|
|
1437
|
+
description: 'Reflect API'
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
pattern: /\bProxy\b/gi,
|
|
1441
|
+
description: 'Proxy constructor'
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
pattern: /\bglobal\b/gi,
|
|
1445
|
+
description: 'global object'
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
pattern: /\bglobalThis\b/gi,
|
|
1449
|
+
description: 'globalThis'
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
pattern: /\bself\s*\[/gi,
|
|
1453
|
+
description: 'self[] access'
|
|
1454
|
+
},
|
|
1455
|
+
{
|
|
1456
|
+
pattern: /\bthis\s*\.\s*constructor/gi,
|
|
1457
|
+
description: 'this.constructor'
|
|
1458
|
+
},
|
|
1459
|
+
{
|
|
1460
|
+
pattern: /\basync\s+function/gi,
|
|
1461
|
+
description: 'async function'
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
pattern: /\bawait\b/gi,
|
|
1465
|
+
description: 'await keyword'
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
pattern: /\bnew\s+Promise\b/gi,
|
|
1469
|
+
description: 'new Promise()'
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
pattern: /\.then\s*\(/gi,
|
|
1473
|
+
description: 'Promise.then()'
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
pattern: /\bfunction\s*\*/gi,
|
|
1477
|
+
description: 'generator function'
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
pattern: /\byield\b/gi,
|
|
1481
|
+
description: 'yield keyword'
|
|
1482
|
+
},
|
|
1483
|
+
{
|
|
1484
|
+
pattern: /\.apply\s*\(/gi,
|
|
1485
|
+
description: 'Function.apply()'
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
pattern: /\.call\s*\(/gi,
|
|
1489
|
+
description: 'Function.call()'
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
pattern: /\.bind\s*\(/gi,
|
|
1493
|
+
description: 'Function.bind()'
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
pattern: /\bWorker\b/gi,
|
|
1497
|
+
description: 'Worker constructor'
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
pattern: /\bSharedWorker\b/gi,
|
|
1501
|
+
description: 'SharedWorker'
|
|
1502
|
+
},
|
|
1503
|
+
{
|
|
1504
|
+
pattern: /\bServiceWorker\b/gi,
|
|
1505
|
+
description: 'ServiceWorker'
|
|
1506
|
+
}
|
|
1507
|
+
];
|
|
1508
|
+
for (const { pattern, description } of forbiddenPatterns)if (pattern.test(code)) throw new Error(`Security violation: Code contains forbidden pattern "${description}". For AI-generated code, please regenerate without this pattern.`);
|
|
1509
|
+
const suspiciousPatterns = [
|
|
1510
|
+
/['"]con['"] *\+ *['"]structor['"]/gi,
|
|
1511
|
+
/['"]ev['"] *\+ *['"]al['"]/gi,
|
|
1512
|
+
/['"]__pro['"] *\+ *['"]to__['"]/gi,
|
|
1513
|
+
/\b(self|window|global)\s*\[\s*['"][a-z]+['"]\s*\+\s*['"][a-z]+['"]\s*\]/gi
|
|
1514
|
+
];
|
|
1515
|
+
for (const pattern of suspiciousPatterns)if (pattern.test(code)) throw new Error('Security violation: Code contains suspicious string concatenation that may bypass security checks.');
|
|
1516
|
+
const aiCodeWarnings = [
|
|
1517
|
+
{
|
|
1518
|
+
pattern: /\[['"][a-z_$]+['"]\]/gi,
|
|
1519
|
+
count: 0,
|
|
1520
|
+
threshold: 10,
|
|
1521
|
+
description: 'excessive bracket notation'
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
pattern: /\s*\+\s*['"]/gi,
|
|
1525
|
+
count: 0,
|
|
1526
|
+
threshold: 5,
|
|
1527
|
+
description: 'excessive string concatenation'
|
|
1528
|
+
}
|
|
1529
|
+
];
|
|
1530
|
+
for (const warning of aiCodeWarnings){
|
|
1531
|
+
const matches = code.match(warning.pattern);
|
|
1532
|
+
if (matches && matches.length > warning.threshold) throw new Error(`Security warning: Code contains ${matches.length} instances of ${warning.description}, which is unusual for AI-generated code. Please regenerate.`);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
async function executeFilterCode(options) {
|
|
1536
|
+
const { code, data, timeout = 2000 } = options;
|
|
1537
|
+
if ('undefined' == typeof Worker) return {
|
|
1538
|
+
success: false,
|
|
1539
|
+
data: [],
|
|
1540
|
+
error: 'Web Worker is not supported in this environment'
|
|
1541
|
+
};
|
|
1542
|
+
try {
|
|
1543
|
+
validateCodeSafety(code);
|
|
1544
|
+
if (!Array.isArray(data)) throw new Error('Input data must be an array');
|
|
1545
|
+
if (data.length > 100000) console.warn(`[vseed] Large dataset detected: ${data.length} items. Consider pagination for better performance.`);
|
|
1546
|
+
const dataSize = JSON.stringify(data).length;
|
|
1547
|
+
if (dataSize > 10485760) throw new Error(`Input data is too large (${(dataSize / 1024 / 1024).toFixed(1)}MB). Maximum allowed is 10MB.`);
|
|
1548
|
+
const pool = await getOrCreateWorkerPool();
|
|
1549
|
+
const worker = await pool.acquire();
|
|
1550
|
+
const taskId = `task_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
1551
|
+
let shouldReleaseWorker = true;
|
|
1552
|
+
try {
|
|
1553
|
+
const result = await new Promise((resolve, reject)=>{
|
|
1554
|
+
let isSettled = false;
|
|
1555
|
+
const cleanup = ()=>{
|
|
1556
|
+
if (!isSettled) {
|
|
1557
|
+
isSettled = true;
|
|
1558
|
+
worker.removeEventListener('message', messageHandler);
|
|
1559
|
+
worker.removeEventListener('error', errorHandler);
|
|
1560
|
+
}
|
|
1561
|
+
};
|
|
1562
|
+
const outerTimeoutId = setTimeout(()=>{
|
|
1563
|
+
cleanup();
|
|
1564
|
+
shouldReleaseWorker = false;
|
|
1565
|
+
worker.terminate();
|
|
1566
|
+
reject(new Error(`Execution timeout (exceeded ${timeout}ms) - outer guard`));
|
|
1567
|
+
}, timeout + 1000);
|
|
1568
|
+
const messageHandler = (e)=>{
|
|
1569
|
+
if (e.data.taskId !== taskId) return;
|
|
1570
|
+
clearTimeout(outerTimeoutId);
|
|
1571
|
+
cleanup();
|
|
1572
|
+
if (e.data.success) resolve(e.data.result);
|
|
1573
|
+
else reject(new Error(`Execution failed: ${e.data.error}${e.data.errorType ? ` (${e.data.errorType})` : ''}`));
|
|
1574
|
+
};
|
|
1575
|
+
const errorHandler = (errorEvent)=>{
|
|
1576
|
+
clearTimeout(outerTimeoutId);
|
|
1577
|
+
cleanup();
|
|
1578
|
+
shouldReleaseWorker = false;
|
|
1579
|
+
worker.terminate();
|
|
1580
|
+
const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker error';
|
|
1581
|
+
reject(new Error(`Worker error: ${errorMessage}`));
|
|
1582
|
+
};
|
|
1583
|
+
worker.addEventListener('message', messageHandler);
|
|
1584
|
+
worker.addEventListener('error', errorHandler);
|
|
1585
|
+
worker.postMessage({
|
|
1586
|
+
taskId,
|
|
1587
|
+
code,
|
|
1588
|
+
data,
|
|
1589
|
+
timeout
|
|
1590
|
+
});
|
|
1591
|
+
});
|
|
1592
|
+
return {
|
|
1593
|
+
success: true,
|
|
1594
|
+
data: result
|
|
1595
|
+
};
|
|
1596
|
+
} finally{
|
|
1597
|
+
if (shouldReleaseWorker && globalWorkerPool) globalWorkerPool.release(worker);
|
|
1598
|
+
}
|
|
1599
|
+
} catch (error) {
|
|
1600
|
+
return {
|
|
1601
|
+
success: false,
|
|
1602
|
+
data: [],
|
|
1603
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
function nearlyEqual(a, b, epsilon = 1e-8) {
|
|
1608
|
+
if (Number.isNaN(a) || Number.isNaN(b)) return false;
|
|
1609
|
+
if (a === b) return true;
|
|
1610
|
+
const diff = Math.abs(a - b);
|
|
1611
|
+
return diff <= epsilon;
|
|
1612
|
+
}
|
|
1613
|
+
const selector_selector = (vchartDatum, selector, selectorMode = 'And')=>{
|
|
1614
|
+
if (!selector) return true;
|
|
1615
|
+
const vchartKeys = Object.keys(vchartDatum).filter((k)=>k.toLocaleLowerCase().startsWith('__vchart'));
|
|
1616
|
+
const datum = chunk_KI5X74E2_y(vchartDatum, vchartKeys);
|
|
1617
|
+
const selectors = Array.isArray(selector) ? selector : [
|
|
1618
|
+
selector
|
|
1619
|
+
];
|
|
1620
|
+
return selectors['And' === selectorMode ? 'every' : 'some']((selector)=>{
|
|
1621
|
+
if (isValueSelector(selector)) return selectByValue(selector, datum);
|
|
1622
|
+
if (isMeasureSelector(selector)) return selectByMeasure(selector, datum);
|
|
1623
|
+
if (isDimensionSelector(selector)) return selectByDmension(selector, datum);
|
|
1624
|
+
if (isPartialDatumSelector(selector)) return selectByPartial(selector, datum);
|
|
1625
|
+
return false;
|
|
1626
|
+
});
|
|
1627
|
+
};
|
|
1628
|
+
const isValueSelector = (selector)=>'string' == typeof selector || 'number' == typeof selector;
|
|
1629
|
+
const isPartialDatumSelector = (selector)=>'object' == typeof selector && null !== selector;
|
|
1630
|
+
const isMeasureSelector = (selector)=>'object' == typeof selector && null !== selector && 'field' in selector && ('operator' in selector || 'op' in selector) && 'value' in selector && ([
|
|
1631
|
+
'=',
|
|
1632
|
+
'==',
|
|
1633
|
+
'!=',
|
|
1634
|
+
'>',
|
|
1635
|
+
'<',
|
|
1636
|
+
'>=',
|
|
1637
|
+
'<=',
|
|
1638
|
+
'between'
|
|
1639
|
+
].includes(selector.operator) || [
|
|
1640
|
+
'=',
|
|
1641
|
+
'==',
|
|
1642
|
+
'!=',
|
|
1643
|
+
'>',
|
|
1644
|
+
'<',
|
|
1645
|
+
'>=',
|
|
1646
|
+
'<=',
|
|
1647
|
+
'between'
|
|
1648
|
+
].includes(selector.op));
|
|
1649
|
+
const isDimensionSelector = (selector)=>'object' == typeof selector && null !== selector && 'field' in selector && ('operator' in selector || 'op' in selector) && 'value' in selector && ([
|
|
1650
|
+
'in',
|
|
1651
|
+
'not in'
|
|
1652
|
+
].includes(selector.operator) || [
|
|
1653
|
+
'in',
|
|
1654
|
+
'not in'
|
|
1655
|
+
].includes(selector.op));
|
|
1656
|
+
const selectByMeasure = (selector, datum)=>{
|
|
1657
|
+
const op = selector.operator || selector.op;
|
|
1658
|
+
const selectorValueArr = Array.isArray(selector.value) ? selector.value : [
|
|
1659
|
+
selector.value
|
|
1660
|
+
];
|
|
1661
|
+
switch(op){
|
|
1662
|
+
case '=':
|
|
1663
|
+
if (String(datum[selector.field]) === String(selectorValueArr[0]) || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1664
|
+
break;
|
|
1665
|
+
case '==':
|
|
1666
|
+
if (datum[selector.field] === selectorValueArr[0]) return true;
|
|
1667
|
+
break;
|
|
1668
|
+
case '!=':
|
|
1669
|
+
if (datum[selector.field] !== selectorValueArr[0]) return true;
|
|
1670
|
+
break;
|
|
1671
|
+
case '>':
|
|
1672
|
+
if (datum[selector.field] > selectorValueArr[0] && !nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1673
|
+
break;
|
|
1674
|
+
case '<':
|
|
1675
|
+
if (datum[selector.field] < selectorValueArr[0] && !nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1676
|
+
break;
|
|
1677
|
+
case '>=':
|
|
1678
|
+
if (datum[selector.field] >= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1679
|
+
break;
|
|
1680
|
+
case '<=':
|
|
1681
|
+
if (datum[selector.field] <= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1682
|
+
break;
|
|
1683
|
+
case 'between':
|
|
1684
|
+
if (Array.isArray(selector.value) && (datum[selector.field] >= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) && (datum[selector.field] <= selectorValueArr[1] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[1])))) return true;
|
|
1685
|
+
break;
|
|
1686
|
+
}
|
|
1687
|
+
return false;
|
|
1688
|
+
};
|
|
1689
|
+
const selectByDmension = (selector, datum)=>{
|
|
1690
|
+
const op = selector.operator || selector.op;
|
|
1691
|
+
const selectorValueArr = Array.isArray(selector.value) ? selector.value : [
|
|
1692
|
+
selector.value
|
|
1693
|
+
];
|
|
1694
|
+
switch(op){
|
|
1695
|
+
case 'in':
|
|
1696
|
+
if (selectorValueArr.includes(datum[selector.field])) return true;
|
|
1697
|
+
break;
|
|
1698
|
+
case 'not in':
|
|
1699
|
+
if (!selectorValueArr.includes(datum[selector.field])) return true;
|
|
1700
|
+
break;
|
|
1701
|
+
}
|
|
1702
|
+
return false;
|
|
1703
|
+
};
|
|
1704
|
+
const selectByPartial = (selector, datum)=>Object.keys(selector).every((key)=>datum[key] === selector[key]);
|
|
1705
|
+
const selectByValue = (selector, datum)=>Object.values(datum).some((v)=>v === selector);
|
|
1706
|
+
const matchesCellSelector = (cell, filterRes)=>{
|
|
1707
|
+
if (filterRes[InnerRowIndex] !== cell[InnerRowIndex]) return false;
|
|
1708
|
+
return '*' === filterRes.field || Object.keys(cell).includes(filterRes.field);
|
|
1709
|
+
};
|
|
1710
|
+
const matchesDatum = (target, candidate)=>Object.keys(candidate).every((key)=>target[key] === candidate[key]);
|
|
1711
|
+
const isDynamicFilterLike = (selector, expectedTypes)=>'object' == typeof selector && null !== selector && 'type' in selector && expectedTypes.includes(selector.type) && 'code' in selector && 'string' == typeof selector.code;
|
|
1712
|
+
const isRowWithFieldDynamicFilter = (selector)=>isDynamicFilterLike(selector, [
|
|
1713
|
+
'row-with-field'
|
|
1714
|
+
]);
|
|
1715
|
+
const isValueDynamicFilter = (selector)=>isDynamicFilterLike(selector, [
|
|
1716
|
+
'value'
|
|
1717
|
+
]);
|
|
1718
|
+
const isDynamicFilter = (selector)=>isDynamicFilterLike(selector, [
|
|
1719
|
+
'row-with-field',
|
|
1720
|
+
'value'
|
|
1721
|
+
]);
|
|
1722
|
+
const validateFilterResult = (result, filter)=>{
|
|
1723
|
+
if (isValueDynamicFilter(filter)) {
|
|
1724
|
+
if ('number' != typeof result && 'string' != typeof result) throw new TypeError(`ValueDynamicFilter must return a number or string, but got: ${typeof result}. Code: "${filter.code}"`);
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
if (!Array.isArray(result)) throw new TypeError(`${isRowWithFieldDynamicFilter(filter) ? 'TableDynamicFilter' : 'ChartDynamicFilter'} must return an array, but got: ${typeof result}. Code: "${filter.code}"`);
|
|
1728
|
+
if (isRowWithFieldDynamicFilter(filter)) for(let i = 0; i < result.length; i++){
|
|
1729
|
+
const item = result[i];
|
|
1730
|
+
if ('object' != typeof item || null === item) throw new TypeError(`TableDynamicFilter array element at index ${i} must be an object, got: ${typeof item}`);
|
|
1731
|
+
if (!(InnerRowIndex in item) && '__row_index' in item === false) throw new TypeError(`TableDynamicFilter array element at index ${i} must contain __row_index or InnerRowIndex field`);
|
|
1732
|
+
if (!('field' in item)) throw new TypeError(`TableDynamicFilter array element at index ${i} must contain 'field' field`);
|
|
1733
|
+
}
|
|
1734
|
+
};
|
|
1735
|
+
const executeDynamicFilter = async (filter, allData)=>{
|
|
1736
|
+
try {
|
|
1737
|
+
const { success, data, error } = await executeFilterCode({
|
|
1738
|
+
code: filter.code,
|
|
1739
|
+
data: allData
|
|
1740
|
+
});
|
|
1741
|
+
if (!success) {
|
|
1742
|
+
console.warn('[vseed] Dynamic filter execution failed:', error);
|
|
1743
|
+
return {
|
|
1744
|
+
success: false,
|
|
1745
|
+
data: isRowWithFieldDynamicFilter(filter) ? [] : '',
|
|
1746
|
+
error
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
try {
|
|
1750
|
+
validateFilterResult(data, filter);
|
|
1751
|
+
} catch (validationError) {
|
|
1752
|
+
console.error('[vseed] Dynamic filter result validation failed:', validationError);
|
|
1753
|
+
return {
|
|
1754
|
+
success: false,
|
|
1755
|
+
data: isRowWithFieldDynamicFilter(filter) ? [] : '',
|
|
1756
|
+
error: validationError instanceof Error ? validationError.message : String(validationError)
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
return {
|
|
1760
|
+
success,
|
|
1761
|
+
data: data
|
|
1762
|
+
};
|
|
1763
|
+
} catch (error) {
|
|
1764
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1765
|
+
console.error('[vseed] Dynamic filter execution threw exception:', errorMessage);
|
|
1766
|
+
return {
|
|
1767
|
+
success: false,
|
|
1768
|
+
data: isRowWithFieldDynamicFilter(filter) ? [] : '',
|
|
1769
|
+
error: errorMessage
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
const matchDynamicFilterResult = (result, datum, selectorType = 'table')=>{
|
|
1774
|
+
if ('number' == typeof result || 'string' == typeof result) throw new Error('matchDynamicFilterResult does not support ValueDynamicFilter results');
|
|
1775
|
+
if ('table' === selectorType) return result.some((item)=>matchesCellSelector(datum, item));
|
|
1776
|
+
return result.some((item)=>matchesDatum(datum, item));
|
|
1777
|
+
};
|
|
1778
|
+
const selectorWithDynamicFilter = (vchartDatum, selectorConfig, defaultSelector)=>{
|
|
1779
|
+
if (!selectorConfig) return true;
|
|
1780
|
+
if (isValueDynamicFilter(selectorConfig)) {
|
|
1781
|
+
if (selectorConfig.fallback) {
|
|
1782
|
+
const fallbackSelector = Array.isArray(selectorConfig.fallback) ? selectorConfig.fallback : [
|
|
1783
|
+
selectorConfig.fallback
|
|
1784
|
+
];
|
|
1785
|
+
return selector_selector(vchartDatum, fallbackSelector);
|
|
1786
|
+
}
|
|
1787
|
+
return defaultSelector ? selector_selector(vchartDatum, defaultSelector) : false;
|
|
1788
|
+
}
|
|
1789
|
+
const selectorType = isRowWithFieldDynamicFilter(selectorConfig) ? 'table' : 'chart';
|
|
1790
|
+
if (selectorConfig.result?.success && selectorConfig.result.data) return matchDynamicFilterResult(selectorConfig.result.data, vchartDatum, selectorType);
|
|
1791
|
+
if (selectorConfig.fallback) {
|
|
1792
|
+
const fallbackSelector = Array.isArray(selectorConfig.fallback) ? selectorConfig.fallback : [
|
|
1793
|
+
selectorConfig.fallback
|
|
1794
|
+
];
|
|
1795
|
+
return selector_selector(vchartDatum, fallbackSelector);
|
|
1796
|
+
}
|
|
1797
|
+
return defaultSelector ? selector_selector(vchartDatum, defaultSelector) : false;
|
|
1798
|
+
};
|
|
1799
|
+
const generateDynamicFilterKeyPaths = ()=>{
|
|
1800
|
+
const dynamicFilterConfig = {
|
|
1801
|
+
table: [
|
|
1802
|
+
'bodyCellStyle'
|
|
1803
|
+
],
|
|
1804
|
+
pivotTable: [
|
|
1805
|
+
'bodyCellStyle'
|
|
1806
|
+
],
|
|
1807
|
+
bar: [
|
|
1808
|
+
'barStyle',
|
|
1809
|
+
'annotationPoint',
|
|
1810
|
+
'annotationVerticalLine'
|
|
1811
|
+
],
|
|
1812
|
+
barParallel: [
|
|
1813
|
+
'barStyle',
|
|
1814
|
+
'annotationPoint',
|
|
1815
|
+
'annotationVerticalLine'
|
|
1816
|
+
],
|
|
1817
|
+
barPercent: [
|
|
1818
|
+
'barStyle',
|
|
1819
|
+
'annotationPoint',
|
|
1820
|
+
'annotationVerticalLine'
|
|
1821
|
+
],
|
|
1822
|
+
column: [
|
|
1823
|
+
'barStyle',
|
|
1824
|
+
'annotationPoint',
|
|
1825
|
+
'annotationHorizontalLine'
|
|
1826
|
+
],
|
|
1827
|
+
columnParallel: [
|
|
1828
|
+
'barStyle',
|
|
1829
|
+
'annotationPoint',
|
|
1830
|
+
'annotationHorizontalLine'
|
|
1831
|
+
],
|
|
1832
|
+
columnPercent: [
|
|
1833
|
+
'barStyle',
|
|
1834
|
+
'annotationPoint',
|
|
1835
|
+
'annotationHorizontalLine'
|
|
1836
|
+
],
|
|
1837
|
+
line: [
|
|
1838
|
+
'lineStyle',
|
|
1839
|
+
'pointStyle',
|
|
1840
|
+
'annotationPoint',
|
|
1841
|
+
'annotationHorizontalLine'
|
|
1842
|
+
],
|
|
1843
|
+
area: [
|
|
1844
|
+
'lineStyle',
|
|
1845
|
+
'pointStyle',
|
|
1846
|
+
'annotationPoint',
|
|
1847
|
+
'annotationHorizontalLine'
|
|
1848
|
+
],
|
|
1849
|
+
areaPercent: [
|
|
1850
|
+
'lineStyle',
|
|
1851
|
+
'pointStyle',
|
|
1852
|
+
'annotationPoint',
|
|
1853
|
+
'annotationHorizontalLine'
|
|
1854
|
+
],
|
|
1855
|
+
dualAxis: [
|
|
1856
|
+
'barStyle',
|
|
1857
|
+
'lineStyle',
|
|
1858
|
+
'pointStyle',
|
|
1859
|
+
'annotationPoint',
|
|
1860
|
+
'annotationHorizontalLine'
|
|
1861
|
+
],
|
|
1862
|
+
scatter: [
|
|
1863
|
+
'pointStyle',
|
|
1864
|
+
'annotationPoint',
|
|
1865
|
+
'annotationHorizontalLine',
|
|
1866
|
+
'annotationVerticalLine'
|
|
1867
|
+
],
|
|
1868
|
+
histogram: [
|
|
1869
|
+
'annotationHorizontalLine'
|
|
1870
|
+
],
|
|
1871
|
+
boxPlot: [
|
|
1872
|
+
'annotationHorizontalLine'
|
|
1873
|
+
]
|
|
1874
|
+
};
|
|
1875
|
+
const result = {};
|
|
1876
|
+
for (const [chartType, baseKeyPaths] of Object.entries(dynamicFilterConfig))result[chartType] = baseKeyPaths.flatMap((basePath)=>[
|
|
1877
|
+
`${basePath}[].dynamicFilter`,
|
|
1878
|
+
`${basePath}.dynamicFilter`
|
|
1879
|
+
]);
|
|
1880
|
+
return result;
|
|
1881
|
+
};
|
|
1882
|
+
const dynamicFilterKeyPathsByChartType = generateDynamicFilterKeyPaths();
|
|
1883
|
+
const getBasePathsForDeepClone = (chartType)=>{
|
|
1884
|
+
const config = {
|
|
1885
|
+
table: [
|
|
1886
|
+
'bodyCellStyle'
|
|
1887
|
+
],
|
|
1888
|
+
pivotTable: [
|
|
1889
|
+
'bodyCellStyle'
|
|
1890
|
+
],
|
|
1891
|
+
bar: [
|
|
1892
|
+
'barStyle',
|
|
1893
|
+
'annotationPoint',
|
|
1894
|
+
'annotationVerticalLine'
|
|
1895
|
+
],
|
|
1896
|
+
barParallel: [
|
|
1897
|
+
'barStyle',
|
|
1898
|
+
'annotationPoint',
|
|
1899
|
+
'annotationVerticalLine'
|
|
1900
|
+
],
|
|
1901
|
+
barPercent: [
|
|
1902
|
+
'barStyle',
|
|
1903
|
+
'annotationPoint',
|
|
1904
|
+
'annotationVerticalLine'
|
|
1905
|
+
],
|
|
1906
|
+
column: [
|
|
1907
|
+
'barStyle',
|
|
1908
|
+
'annotationPoint',
|
|
1909
|
+
'annotationHorizontalLine'
|
|
1910
|
+
],
|
|
1911
|
+
columnParallel: [
|
|
1912
|
+
'barStyle',
|
|
1913
|
+
'annotationPoint',
|
|
1914
|
+
'annotationHorizontalLine'
|
|
1915
|
+
],
|
|
1916
|
+
columnPercent: [
|
|
1917
|
+
'barStyle',
|
|
1918
|
+
'annotationPoint',
|
|
1919
|
+
'annotationHorizontalLine'
|
|
1920
|
+
],
|
|
1921
|
+
line: [
|
|
1922
|
+
'lineStyle',
|
|
1923
|
+
'pointStyle',
|
|
1924
|
+
'annotationPoint',
|
|
1925
|
+
'annotationHorizontalLine'
|
|
1926
|
+
],
|
|
1927
|
+
area: [
|
|
1928
|
+
'lineStyle',
|
|
1929
|
+
'pointStyle',
|
|
1930
|
+
'annotationPoint',
|
|
1931
|
+
'annotationHorizontalLine'
|
|
1932
|
+
],
|
|
1933
|
+
areaPercent: [
|
|
1934
|
+
'lineStyle',
|
|
1935
|
+
'pointStyle',
|
|
1936
|
+
'annotationPoint',
|
|
1937
|
+
'annotationHorizontalLine'
|
|
1938
|
+
],
|
|
1939
|
+
dualAxis: [
|
|
1940
|
+
'barStyle',
|
|
1941
|
+
'lineStyle',
|
|
1942
|
+
'pointStyle',
|
|
1943
|
+
'annotationPoint',
|
|
1944
|
+
'annotationHorizontalLine'
|
|
1945
|
+
],
|
|
1946
|
+
scatter: [
|
|
1947
|
+
'pointStyle',
|
|
1948
|
+
'annotationPoint',
|
|
1949
|
+
'annotationHorizontalLine',
|
|
1950
|
+
'annotationVerticalLine'
|
|
1951
|
+
],
|
|
1952
|
+
histogram: [
|
|
1953
|
+
'annotationHorizontalLine'
|
|
1954
|
+
],
|
|
1955
|
+
boxPlot: [
|
|
1956
|
+
'annotationHorizontalLine'
|
|
1957
|
+
]
|
|
1958
|
+
};
|
|
1959
|
+
return config[chartType] ?? [];
|
|
1960
|
+
};
|
|
1961
|
+
const parseKeyPath = (path)=>path.split('.').map((segment)=>{
|
|
1962
|
+
if (segment.endsWith('[]')) return {
|
|
1963
|
+
key: segment.slice(0, -2),
|
|
1964
|
+
isArray: true
|
|
1965
|
+
};
|
|
1966
|
+
return {
|
|
1967
|
+
key: segment,
|
|
1968
|
+
isArray: false
|
|
1969
|
+
};
|
|
1970
|
+
});
|
|
1971
|
+
const getValuesByKeyPath = (target, path)=>{
|
|
1972
|
+
const segments = parseKeyPath(path);
|
|
1973
|
+
let current = [
|
|
1974
|
+
target
|
|
1975
|
+
];
|
|
1976
|
+
for (const segment of segments){
|
|
1977
|
+
const next = [];
|
|
1978
|
+
for (const node of current){
|
|
1979
|
+
if (!node || 'object' != typeof node) continue;
|
|
1980
|
+
const value = node[segment.key];
|
|
1981
|
+
if (segment.isArray) {
|
|
1982
|
+
if (Array.isArray(value)) next.push(...value);
|
|
1983
|
+
} else if (void 0 !== value) next.push(value);
|
|
1984
|
+
}
|
|
1985
|
+
current = next;
|
|
1986
|
+
}
|
|
1987
|
+
return current;
|
|
1988
|
+
};
|
|
1989
|
+
const collectDynamicFiltersByKeyPaths = (target, chartType)=>{
|
|
1990
|
+
const paths = dynamicFilterKeyPathsByChartType[chartType] ?? [];
|
|
1991
|
+
if (!paths.length) return [];
|
|
1992
|
+
return paths.flatMap((path)=>getValuesByKeyPath(target, path)).filter((value)=>isDynamicFilter(value) && !!value?.code);
|
|
1993
|
+
};
|
|
1994
|
+
const executeDynamicFiltersAndInject = async (filters, dataset)=>{
|
|
1995
|
+
if (!filters.length || !dataset.length) return;
|
|
1996
|
+
await Promise.all(filters.map(async (filter)=>{
|
|
1997
|
+
const { success, data, error } = await executeDynamicFilter(filter, dataset);
|
|
1998
|
+
filter.result = {
|
|
1999
|
+
success,
|
|
2000
|
+
error,
|
|
2001
|
+
data: data
|
|
2002
|
+
};
|
|
2003
|
+
}));
|
|
2004
|
+
};
|
|
2005
|
+
const deepCloneDynamicFilterPaths = (vseed, chartType)=>{
|
|
2006
|
+
const basePaths = getBasePathsForDeepClone(chartType);
|
|
2007
|
+
if (!basePaths.length) return {
|
|
2008
|
+
...vseed
|
|
2009
|
+
};
|
|
2010
|
+
const clonedVseed = {
|
|
2011
|
+
...vseed
|
|
2012
|
+
};
|
|
2013
|
+
for (const basePath of basePaths){
|
|
2014
|
+
if (!(basePath in clonedVseed)) continue;
|
|
2015
|
+
const value = clonedVseed[basePath];
|
|
2016
|
+
if (Array.isArray(value)) clonedVseed[basePath] = value.map((item)=>{
|
|
2017
|
+
if (!item || 'object' != typeof item) return item;
|
|
2018
|
+
const clonedItem = {
|
|
2019
|
+
...item
|
|
2020
|
+
};
|
|
2021
|
+
if (clonedItem.dynamicFilter && 'object' == typeof clonedItem.dynamicFilter) clonedItem.dynamicFilter = {
|
|
2022
|
+
...clonedItem.dynamicFilter
|
|
2023
|
+
};
|
|
2024
|
+
return clonedItem;
|
|
2025
|
+
});
|
|
2026
|
+
else if (value && 'object' == typeof value) {
|
|
2027
|
+
clonedVseed[basePath] = {
|
|
2028
|
+
...value
|
|
2029
|
+
};
|
|
2030
|
+
if (clonedVseed[basePath].dynamicFilter && 'object' == typeof clonedVseed[basePath].dynamicFilter) clonedVseed[basePath].dynamicFilter = {
|
|
2031
|
+
...clonedVseed[basePath].dynamicFilter
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
return clonedVseed;
|
|
2036
|
+
};
|
|
2037
|
+
const prepare = async (builder)=>{
|
|
2038
|
+
if (builder.isPrepared || !builder.vseed || !builder.vseed?.chartType || !builder.vseed.dataset) return;
|
|
2039
|
+
const filters = collectDynamicFiltersByKeyPaths(builder.vseed, builder.vseed.chartType);
|
|
2040
|
+
if (!filters.length) {
|
|
2041
|
+
builder.isPrepared = true;
|
|
2042
|
+
return;
|
|
2043
|
+
}
|
|
2044
|
+
const clonedVseed = deepCloneDynamicFilterPaths(builder.vseed, builder.vseed.chartType);
|
|
2045
|
+
const originalDataset = clonedVseed.dataset;
|
|
2046
|
+
let datasetWithIndex = originalDataset;
|
|
2047
|
+
if (!originalDataset[0] || !(InnerRowIndex in originalDataset[0])) datasetWithIndex = originalDataset.map((item, index)=>({
|
|
2048
|
+
...item,
|
|
2049
|
+
[InnerRowIndex]: index
|
|
2050
|
+
}));
|
|
2051
|
+
builder.vseed = {
|
|
2052
|
+
...clonedVseed,
|
|
2053
|
+
dataset: datasetWithIndex
|
|
458
2054
|
};
|
|
459
|
-
|
|
2055
|
+
const clonedFilters = collectDynamicFiltersByKeyPaths(builder.vseed, builder.vseed.chartType);
|
|
460
2056
|
try {
|
|
461
|
-
|
|
462
|
-
builder.spec = spec;
|
|
463
|
-
return spec;
|
|
2057
|
+
await executeDynamicFiltersAndInject(clonedFilters, datasetWithIndex);
|
|
464
2058
|
} catch (e) {
|
|
465
|
-
|
|
466
|
-
throw new Error(`buildSpec error: ${e.message}`);
|
|
467
|
-
} finally{
|
|
468
|
-
const end = 'undefined' != typeof performance ? performance.now() : Date.now();
|
|
469
|
-
builder.performance['buildSpec'] = `${(end - start).toFixed(4)}ms`;
|
|
2059
|
+
throw new Error(`Failed to execute dynamic filters: ${e.message}`);
|
|
470
2060
|
}
|
|
471
|
-
|
|
472
|
-
const build = (builder)=>{
|
|
473
|
-
const advancedVSeed = builder.buildAdvanced();
|
|
474
|
-
if (!advancedVSeed) throw new Error('advancedVSeed is null');
|
|
475
|
-
const spec = builder.buildSpec(advancedVSeed);
|
|
476
|
-
return spec;
|
|
2061
|
+
builder.isPrepared = true;
|
|
477
2062
|
};
|
|
478
2063
|
var chunk_ANXBDSUI_s = {
|
|
479
2064
|
done: !1,
|
|
@@ -749,6 +2334,7 @@
|
|
|
749
2334
|
_spec = null;
|
|
750
2335
|
_performance = {};
|
|
751
2336
|
_locale;
|
|
2337
|
+
_isPrepared = false;
|
|
752
2338
|
constructor(vseed){
|
|
753
2339
|
this._vseed = vseed;
|
|
754
2340
|
this._locale = vseed.locale || intl.getLocale();
|
|
@@ -756,6 +2342,7 @@
|
|
|
756
2342
|
get locale() {
|
|
757
2343
|
return this._locale;
|
|
758
2344
|
}
|
|
2345
|
+
prepare = async ()=>prepare(this);
|
|
759
2346
|
build = ()=>build(this);
|
|
760
2347
|
buildSpec = (advanced)=>buildSpec(this, advanced);
|
|
761
2348
|
buildAdvanced = ()=>buildAdvanced(this);
|
|
@@ -766,6 +2353,13 @@
|
|
|
766
2353
|
}
|
|
767
2354
|
set vseed(value) {
|
|
768
2355
|
this._vseed = value;
|
|
2356
|
+
this._isPrepared = false;
|
|
2357
|
+
}
|
|
2358
|
+
get isPrepared() {
|
|
2359
|
+
return this._isPrepared;
|
|
2360
|
+
}
|
|
2361
|
+
set isPrepared(value) {
|
|
2362
|
+
this._isPrepared = value;
|
|
769
2363
|
}
|
|
770
2364
|
get advancedVSeed() {
|
|
771
2365
|
return this._advancedVSeed;
|
|
@@ -854,19 +2448,6 @@
|
|
|
854
2448
|
locale: locale || 'zh-CN'
|
|
855
2449
|
};
|
|
856
2450
|
};
|
|
857
|
-
function chunk_D6FCK2GA_u(o, n, a) {
|
|
858
|
-
let t = (r)=>o(r, ...n);
|
|
859
|
-
return void 0 === a ? t : Object.assign(t, {
|
|
860
|
-
lazy: a,
|
|
861
|
-
lazyArgs: n
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
function chunk_WIMGWYZL_u(r, n, o) {
|
|
865
|
-
let a = r.length - n.length;
|
|
866
|
-
if (0 === a) return r(...n);
|
|
867
|
-
if (1 === a) return chunk_D6FCK2GA_u(r, n, o);
|
|
868
|
-
throw new Error("Wrong number of arguments");
|
|
869
|
-
}
|
|
870
2451
|
function chunk_BCBB46UE_d(...n) {
|
|
871
2452
|
return chunk_WIMGWYZL_u(chunk_BCBB46UE_u, n);
|
|
872
2453
|
}
|
|
@@ -936,7 +2517,7 @@
|
|
|
936
2517
|
...prev,
|
|
937
2518
|
...cur
|
|
938
2519
|
}), {});
|
|
939
|
-
const defaultMeasures = Object.keys(sample).filter((key)=>top100dataset.some((item)=>'number' == typeof item[key]) && ![
|
|
2520
|
+
const defaultMeasures = Object.keys(sample).filter((key)=>key !== InnerRowIndex && top100dataset.some((item)=>'number' == typeof item[key]) && ![
|
|
940
2521
|
'',
|
|
941
2522
|
null,
|
|
942
2523
|
void 0
|
|
@@ -1524,157 +3105,9 @@
|
|
|
1524
3105
|
arr
|
|
1525
3106
|
] : [];
|
|
1526
3107
|
}
|
|
1527
|
-
function
|
|
1528
|
-
return
|
|
1529
|
-
}
|
|
1530
|
-
var chunk_AIG3BDKO_n = (e, r)=>e.length >= r;
|
|
1531
|
-
function chunk_KI5X74E2_y(...t) {
|
|
1532
|
-
return chunk_WIMGWYZL_u(chunk_KI5X74E2_f, t);
|
|
1533
|
-
}
|
|
1534
|
-
function chunk_KI5X74E2_f(t, e) {
|
|
1535
|
-
if (!chunk_AIG3BDKO_i(e, 1)) return {
|
|
1536
|
-
...t
|
|
1537
|
-
};
|
|
1538
|
-
if (!chunk_AIG3BDKO_i(e, 2)) {
|
|
1539
|
-
let { [e[0]]: r, ...m } = t;
|
|
1540
|
-
return m;
|
|
1541
|
-
}
|
|
1542
|
-
let o = {
|
|
1543
|
-
...t
|
|
1544
|
-
};
|
|
1545
|
-
for (let r of e)delete o[r];
|
|
1546
|
-
return o;
|
|
1547
|
-
}
|
|
1548
|
-
function nearlyEqual(a, b, epsilon = 1e-8) {
|
|
1549
|
-
if (Number.isNaN(a) || Number.isNaN(b)) return false;
|
|
1550
|
-
if (a === b) return true;
|
|
1551
|
-
const diff = Math.abs(a - b);
|
|
1552
|
-
return diff <= epsilon;
|
|
3108
|
+
function chunk_BO3LQZNF_o(r) {
|
|
3109
|
+
return Array.isArray(r);
|
|
1553
3110
|
}
|
|
1554
|
-
const selector_selector = (vchartDatum, selector, selectorMode = 'And')=>{
|
|
1555
|
-
if (!selector) return true;
|
|
1556
|
-
const vchartKeys = Object.keys(vchartDatum).filter((k)=>k.toLocaleLowerCase().startsWith('__vchart'));
|
|
1557
|
-
const datum = chunk_KI5X74E2_y(vchartDatum, vchartKeys);
|
|
1558
|
-
const selectors = Array.isArray(selector) ? selector : [
|
|
1559
|
-
selector
|
|
1560
|
-
];
|
|
1561
|
-
return selectors['And' === selectorMode ? 'every' : 'some']((selector)=>{
|
|
1562
|
-
if (isValueSelector(selector)) return selectByValue(selector, datum);
|
|
1563
|
-
if (isMeasureSelector(selector)) return selectByMeasure(selector, datum);
|
|
1564
|
-
if (isDimensionSelector(selector)) return selectByDmension(selector, datum);
|
|
1565
|
-
if (isPartialDatumSelector(selector)) return selectByPartial(selector, datum);
|
|
1566
|
-
return false;
|
|
1567
|
-
});
|
|
1568
|
-
};
|
|
1569
|
-
const selectorDatum = (datum, selector)=>{
|
|
1570
|
-
if (!selector) return [];
|
|
1571
|
-
const selectors = Array.isArray(selector) ? selector : [
|
|
1572
|
-
selector
|
|
1573
|
-
];
|
|
1574
|
-
let finalResult = [];
|
|
1575
|
-
for (const selector of selectors){
|
|
1576
|
-
const results = [];
|
|
1577
|
-
if (isValueSelector(selector)) Object.entries(datum).forEach(([key, value])=>{
|
|
1578
|
-
if (value === selector) results.push({
|
|
1579
|
-
[key]: value
|
|
1580
|
-
});
|
|
1581
|
-
});
|
|
1582
|
-
else if (isMeasureSelector(selector) && selectByMeasure(selector, datum)) results.push({
|
|
1583
|
-
[selector.field]: datum[selector.field]
|
|
1584
|
-
});
|
|
1585
|
-
else if (isDimensionSelector(selector) && selectByDmension(selector, datum)) results.push({
|
|
1586
|
-
[selector.field]: datum[selector.field]
|
|
1587
|
-
});
|
|
1588
|
-
else if (isPartialDatumSelector(selector) && selectByPartial(selector, datum)) results.push(selector);
|
|
1589
|
-
if (results.length) finalResult = finalResult.length ? finalResult.flatMap((prev)=>results.map((r)=>({
|
|
1590
|
-
...prev,
|
|
1591
|
-
...r
|
|
1592
|
-
}))) : results;
|
|
1593
|
-
else {
|
|
1594
|
-
finalResult = [];
|
|
1595
|
-
break;
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
return finalResult;
|
|
1599
|
-
};
|
|
1600
|
-
const isValueSelector = (selector)=>'string' == typeof selector || 'number' == typeof selector;
|
|
1601
|
-
const isPartialDatumSelector = (selector)=>'object' == typeof selector && null !== selector;
|
|
1602
|
-
const isMeasureSelector = (selector)=>'object' == typeof selector && null !== selector && 'field' in selector && ('operator' in selector || 'op' in selector) && 'value' in selector && ([
|
|
1603
|
-
'=',
|
|
1604
|
-
'==',
|
|
1605
|
-
'!=',
|
|
1606
|
-
'>',
|
|
1607
|
-
'<',
|
|
1608
|
-
'>=',
|
|
1609
|
-
'<=',
|
|
1610
|
-
'between'
|
|
1611
|
-
].includes(selector.operator) || [
|
|
1612
|
-
'=',
|
|
1613
|
-
'==',
|
|
1614
|
-
'!=',
|
|
1615
|
-
'>',
|
|
1616
|
-
'<',
|
|
1617
|
-
'>=',
|
|
1618
|
-
'<=',
|
|
1619
|
-
'between'
|
|
1620
|
-
].includes(selector.op));
|
|
1621
|
-
const isDimensionSelector = (selector)=>'object' == typeof selector && null !== selector && 'field' in selector && ('operator' in selector || 'op' in selector) && 'value' in selector && ([
|
|
1622
|
-
'in',
|
|
1623
|
-
'not in'
|
|
1624
|
-
].includes(selector.operator) || [
|
|
1625
|
-
'in',
|
|
1626
|
-
'not in'
|
|
1627
|
-
].includes(selector.op));
|
|
1628
|
-
const selectByMeasure = (selector, datum)=>{
|
|
1629
|
-
const op = selector.operator || selector.op;
|
|
1630
|
-
const selectorValueArr = Array.isArray(selector.value) ? selector.value : [
|
|
1631
|
-
selector.value
|
|
1632
|
-
];
|
|
1633
|
-
switch(op){
|
|
1634
|
-
case '=':
|
|
1635
|
-
if (String(datum[selector.field]) === String(selectorValueArr[0]) || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1636
|
-
break;
|
|
1637
|
-
case '==':
|
|
1638
|
-
if (datum[selector.field] === selectorValueArr[0]) return true;
|
|
1639
|
-
break;
|
|
1640
|
-
case '!=':
|
|
1641
|
-
if (datum[selector.field] !== selectorValueArr[0]) return true;
|
|
1642
|
-
break;
|
|
1643
|
-
case '>':
|
|
1644
|
-
if (datum[selector.field] > selectorValueArr[0] && !nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1645
|
-
break;
|
|
1646
|
-
case '<':
|
|
1647
|
-
if (datum[selector.field] < selectorValueArr[0] && !nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1648
|
-
break;
|
|
1649
|
-
case '>=':
|
|
1650
|
-
if (datum[selector.field] >= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1651
|
-
break;
|
|
1652
|
-
case '<=':
|
|
1653
|
-
if (datum[selector.field] <= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) return true;
|
|
1654
|
-
break;
|
|
1655
|
-
case 'between':
|
|
1656
|
-
if (Array.isArray(selector.value) && (datum[selector.field] >= selectorValueArr[0] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[0]))) && (datum[selector.field] <= selectorValueArr[1] || nearlyEqual(Number(datum[selector.field]), Number(selectorValueArr[1])))) return true;
|
|
1657
|
-
break;
|
|
1658
|
-
}
|
|
1659
|
-
return false;
|
|
1660
|
-
};
|
|
1661
|
-
const selectByDmension = (selector, datum)=>{
|
|
1662
|
-
const op = selector.operator || selector.op;
|
|
1663
|
-
const selectorValueArr = Array.isArray(selector.value) ? selector.value : [
|
|
1664
|
-
selector.value
|
|
1665
|
-
];
|
|
1666
|
-
switch(op){
|
|
1667
|
-
case 'in':
|
|
1668
|
-
if (selectorValueArr.includes(datum[selector.field])) return true;
|
|
1669
|
-
break;
|
|
1670
|
-
case 'not in':
|
|
1671
|
-
if (!selectorValueArr.includes(datum[selector.field])) return true;
|
|
1672
|
-
break;
|
|
1673
|
-
}
|
|
1674
|
-
return false;
|
|
1675
|
-
};
|
|
1676
|
-
const selectByPartial = (selector, datum)=>Object.keys(selector).every((key)=>datum[key] === selector[key]);
|
|
1677
|
-
const selectByValue = (selector, datum)=>Object.values(datum).some((v)=>v === selector);
|
|
1678
3111
|
const tableStyleMap = {
|
|
1679
3112
|
backgroundColor: 'bgColor',
|
|
1680
3113
|
textColor: 'color',
|
|
@@ -1686,6 +3119,15 @@
|
|
|
1686
3119
|
if (key in bodyCellStyle) acc[tableStyleMap[key]] = bodyCellStyle[key];
|
|
1687
3120
|
return acc;
|
|
1688
3121
|
}, {});
|
|
3122
|
+
const getCellOriginalDataByDatum = (datum, hasDynamicFilter, originalDatum)=>{
|
|
3123
|
+
const tableInstance = datum?.table;
|
|
3124
|
+
let originRowData = tableInstance && hasDynamicFilter ? tableInstance?.getCellOriginRecord(datum?.col, datum?.row) : null;
|
|
3125
|
+
if (originRowData && chunk_BO3LQZNF_o(originRowData)) originRowData = originRowData[0];
|
|
3126
|
+
return originRowData ? {
|
|
3127
|
+
...originalDatum,
|
|
3128
|
+
[InnerRowIndex]: originRowData?.[InnerRowIndex]
|
|
3129
|
+
} : null;
|
|
3130
|
+
};
|
|
1689
3131
|
const tableBodyCell = (spec, context)=>{
|
|
1690
3132
|
const { advancedVSeed } = context;
|
|
1691
3133
|
const { cellStyle } = advancedVSeed;
|
|
@@ -1697,17 +3139,21 @@
|
|
|
1697
3139
|
const setStyleOfColumn = (col)=>{
|
|
1698
3140
|
const field = col.field;
|
|
1699
3141
|
const matchedStyles = bodyCellStyleList.filter((style)=>{
|
|
3142
|
+
if (style?.dynamicFilter) return style.dynamicFilter?.result?.success === true || !!style.dynamicFilter?.fallback;
|
|
1700
3143
|
if (chunk_JK3VNB42_n(style.selector)) return true;
|
|
1701
3144
|
const selectors = array_array(style.selector);
|
|
1702
3145
|
return selectors.some((selector)=>chunk_BZNENX2T_r(selector) ? chunk_JK3VNB42_n(selector.field) || selector.field === field : chunk_6GTAPB47_e(selector) || chunk_SFZGYJFI_t(selector));
|
|
1703
3146
|
});
|
|
1704
3147
|
if (!matchedStyles.length) return false;
|
|
3148
|
+
const hasDynamicFilter = matchedStyles.some((style)=>!!style.dynamicFilter);
|
|
1705
3149
|
col.style = (datum)=>{
|
|
1706
3150
|
const originalDatum = {
|
|
1707
3151
|
[field]: datum.dataValue
|
|
1708
3152
|
};
|
|
3153
|
+
const currentCellData = getCellOriginalDataByDatum(datum, hasDynamicFilter, originalDatum);
|
|
1709
3154
|
const mergedStyle = matchedStyles.reduce((result, style)=>{
|
|
1710
|
-
|
|
3155
|
+
const shouldApply = style.dynamicFilter ? selectorWithDynamicFilter(currentCellData || originalDatum, style.dynamicFilter, style.selector) : selector_selector(originalDatum, style.selector);
|
|
3156
|
+
if (shouldApply) {
|
|
1711
3157
|
if (selectedPos.length && selectedPos[0].col === datum?.col && selectedPos[0].row === datum?.row) selectedPos.length = 0;
|
|
1712
3158
|
selectedPos.push({
|
|
1713
3159
|
col: datum?.col,
|
|
@@ -1745,36 +3191,6 @@
|
|
|
1745
3191
|
Builder.registerAdvancedPipeline('table', tableAdvancedPipeline);
|
|
1746
3192
|
Builder.registerSpecPipeline('table', tableSpecPipeline);
|
|
1747
3193
|
};
|
|
1748
|
-
const ORIGINAL_DATA = '__OriginalData__';
|
|
1749
|
-
const FoldMeasureName = '__MeaName__';
|
|
1750
|
-
const FoldMeasureId = '__MeaId__';
|
|
1751
|
-
const FoldMeasureValue = '__MeaValue__';
|
|
1752
|
-
const MeasureId = FoldMeasureId;
|
|
1753
|
-
const MeasureName = FoldMeasureName;
|
|
1754
|
-
const FoldPrimaryMeasureValue = '__MeaPrimaryValue__';
|
|
1755
|
-
const FoldSecondaryMeasureValue = '__MeaSecondaryValue__';
|
|
1756
|
-
const DimAxisType = '__Dim_AxisType__';
|
|
1757
|
-
const FoldXMeasureValue = '__MeaXValue__';
|
|
1758
|
-
const FoldYMeasureValue = '__MeaYValue__';
|
|
1759
|
-
const FoldXMeasureId = '__MeaXId__';
|
|
1760
|
-
const FoldYMeasureId = '__MeaYId__';
|
|
1761
|
-
const XEncoding = '__Dim_X__';
|
|
1762
|
-
const YEncoding = '__Dim_Y__';
|
|
1763
|
-
const AngleEncoding = '__Dim_Angle__';
|
|
1764
|
-
const DetailEncoding = '__Dim_Detail__';
|
|
1765
|
-
const PlayerEncoding = '__Dim_Player__';
|
|
1766
|
-
const ColorEncoding = '__Dim_Color__';
|
|
1767
|
-
const ColorIdEncoding = '__Dim_ColorId__';
|
|
1768
|
-
const HierarchyEncoding = '__Dim_Hierarchy__';
|
|
1769
|
-
const BoxPlotPivotIndicator = '__BoxPlot_Pivot_Indicator__';
|
|
1770
|
-
const LowerWhisker = '__Lower_Whisker__';
|
|
1771
|
-
const UpperWhisker = '__Upper_Whisker__';
|
|
1772
|
-
const OutliersMeasureId = '__Outliers__';
|
|
1773
|
-
const MedianMeasureId = '__Meadian__';
|
|
1774
|
-
const BinStartMeasureId = '__BinStart__';
|
|
1775
|
-
const BinEndMeasureId = '__BinEnd__';
|
|
1776
|
-
const BinCountMeasureId = '__BinCount__';
|
|
1777
|
-
const BinPercentageMeasureId = '__BinPercentage__';
|
|
1778
3194
|
const defaultMeasureId = (advancedVSeed)=>{
|
|
1779
3195
|
const result = {
|
|
1780
3196
|
...advancedVSeed
|
|
@@ -2186,6 +3602,7 @@
|
|
|
2186
3602
|
const bodyCellStyleList = array_array(bodyCellStyle);
|
|
2187
3603
|
const indicators = spec.indicators || [];
|
|
2188
3604
|
const selectedPos = [];
|
|
3605
|
+
const hasDynamicFilter = bodyCellStyleList.some((style)=>!!style.dynamicFilter);
|
|
2189
3606
|
const newIndicators = indicators.map((ind)=>{
|
|
2190
3607
|
const newInd = chunk_SFZGYJFI_t(ind) ? {
|
|
2191
3608
|
indicatorKey: ind
|
|
@@ -2204,8 +3621,10 @@
|
|
|
2204
3621
|
if (path.dimensionKey) originalDatum[path.dimensionKey] = path.value;
|
|
2205
3622
|
});
|
|
2206
3623
|
if (!chunk_JK3VNB42_n(originalDatum[MeasureId]) && !chunk_JK3VNB42_n(originalDatum[FoldMeasureValue])) originalDatum[originalDatum[MeasureId]] = originalDatum[FoldMeasureValue];
|
|
3624
|
+
const currentCellData = getCellOriginalDataByDatum(datum, hasDynamicFilter, originalDatum);
|
|
2207
3625
|
const mergedStyle = bodyCellStyleList.reduce((result, style)=>{
|
|
2208
|
-
|
|
3626
|
+
const shouldApply = style.dynamicFilter ? selectorWithDynamicFilter(currentCellData || originalDatum, style.dynamicFilter, style.selector) : selector_selector(originalDatum, style.selector);
|
|
3627
|
+
if (shouldApply) {
|
|
2209
3628
|
if (selectedPos.length && selectedPos[0].col === datum?.col && selectedPos[0].row === datum?.row) selectedPos.length = 0;
|
|
2210
3629
|
selectedPos.push({
|
|
2211
3630
|
col: datum?.col,
|
|
@@ -2306,7 +3725,7 @@
|
|
|
2306
3725
|
...prev,
|
|
2307
3726
|
...cur
|
|
2308
3727
|
}), {});
|
|
2309
|
-
const defaultMeasures = Object.keys(sample).filter((key)=>top100dataset.some((item)=>'number' == typeof item[key]) && ![
|
|
3728
|
+
const defaultMeasures = Object.keys(sample).filter((key)=>key !== InnerRowIndex && top100dataset.some((item)=>'number' == typeof item[key]) && ![
|
|
2310
3729
|
'',
|
|
2311
3730
|
null,
|
|
2312
3731
|
void 0
|
|
@@ -3565,7 +4984,8 @@
|
|
|
3565
4984
|
[`custom${index + 1}`]: {
|
|
3566
4985
|
level: index + 1,
|
|
3567
4986
|
filter: (datum)=>{
|
|
3568
|
-
|
|
4987
|
+
const shouldApply = style.dynamicFilter ? selectorWithDynamicFilter(datum, style.dynamicFilter, style.selector) : selector_selector(datum, style.selector);
|
|
4988
|
+
if (shouldApply) return true;
|
|
3569
4989
|
return false;
|
|
3570
4990
|
},
|
|
3571
4991
|
style: {
|
|
@@ -3699,7 +5119,10 @@
|
|
|
3699
5119
|
level: index + 1,
|
|
3700
5120
|
filter: (_, node)=>{
|
|
3701
5121
|
const lineData = node.renderNode.context.data;
|
|
3702
|
-
for (const d of lineData)
|
|
5122
|
+
for (const d of lineData){
|
|
5123
|
+
const shouldApply = style.dynamicFilter ? selectorWithDynamicFilter(d, style.dynamicFilter, style.selector) : selector_selector(d, style.selector);
|
|
5124
|
+
if (shouldApply) return true;
|
|
5125
|
+
}
|
|
3703
5126
|
return false;
|
|
3704
5127
|
},
|
|
3705
5128
|
style: {
|
|
@@ -4066,11 +5489,33 @@
|
|
|
4066
5489
|
textBaseline: 'middle'
|
|
4067
5490
|
}
|
|
4068
5491
|
};
|
|
5492
|
+
const resolveAnnotationValue = (options)=>{
|
|
5493
|
+
const { dynamicFilter, fallback, defaultValue } = options;
|
|
5494
|
+
if (dynamicFilter?.result?.success && void 0 !== dynamicFilter.result.data) return dynamicFilter.result.data;
|
|
5495
|
+
if (void 0 !== fallback) return fallback;
|
|
5496
|
+
return defaultValue;
|
|
5497
|
+
};
|
|
4069
5498
|
const generateAnnotationPointPipe = (options)=>{
|
|
4070
|
-
const findSelectedDatas = options.findSelectedDatas ?? ((
|
|
5499
|
+
const findSelectedDatas = options.findSelectedDatas ?? ((opts)=>{
|
|
5500
|
+
const { dataset, selector: s, dynamicFilter } = opts;
|
|
5501
|
+
return dataset.filter((datum)=>dynamicFilter ? selectorWithDynamicFilter(datum, dynamicFilter, s) : selector_selector(datum, s));
|
|
5502
|
+
});
|
|
4071
5503
|
const generateMarkPoint = options.generateMarkPoint ?? ((datum)=>[
|
|
4072
5504
|
{
|
|
4073
|
-
coordinate: (data
|
|
5505
|
+
coordinate: (data, context)=>{
|
|
5506
|
+
const targetDatum = data.find((item)=>isSubset(datum, item));
|
|
5507
|
+
if (true === context.getStack()) {
|
|
5508
|
+
const stackedDatum = {
|
|
5509
|
+
...datum,
|
|
5510
|
+
...targetDatum
|
|
5511
|
+
};
|
|
5512
|
+
return {
|
|
5513
|
+
...stackedDatum,
|
|
5514
|
+
[context.getStackValueField()]: stackedDatum['__VCHART_STACK_END']
|
|
5515
|
+
};
|
|
5516
|
+
}
|
|
5517
|
+
return targetDatum;
|
|
5518
|
+
}
|
|
4074
5519
|
}
|
|
4075
5520
|
]);
|
|
4076
5521
|
return (spec, context)=>{
|
|
@@ -4091,9 +5536,15 @@
|
|
|
4091
5536
|
textBaseline: 'top'
|
|
4092
5537
|
};
|
|
4093
5538
|
const markPoint = annotationPointList.flatMap((annotationPoint)=>{
|
|
4094
|
-
const { selector: selectorPoint, text = '', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = defaultStyle.textAlign, textBaseline = defaultStyle.textBaseline, textBackgroundBorderColor = theme?.textBackgroundBorderColor, textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundPadding = theme?.textBackgroundPadding ?? 2, textBackgroundVisible = theme?.textBackgroundVisible ?? true, offsetX = theme?.offsetX ?? 0, offsetY = theme?.offsetY ?? 0 } = annotationPoint;
|
|
5539
|
+
const { selector: selectorPoint, dynamicFilter, text = '', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = defaultStyle.textAlign, textBaseline = defaultStyle.textBaseline, textBackgroundBorderColor = theme?.textBackgroundBorderColor, textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundPadding = theme?.textBackgroundPadding ?? 2, textBackgroundVisible = theme?.textBackgroundVisible ?? true, offsetX = theme?.offsetX ?? 0, offsetY = theme?.offsetY ?? 0 } = annotationPoint;
|
|
4095
5540
|
const dataset = advancedVSeed.dataset.flat();
|
|
4096
|
-
const selectedData = selectorPoint ? findSelectedDatas(
|
|
5541
|
+
const selectedData = selectorPoint || dynamicFilter ? findSelectedDatas({
|
|
5542
|
+
dataset,
|
|
5543
|
+
selector: selectorPoint,
|
|
5544
|
+
dynamicFilter,
|
|
5545
|
+
spec,
|
|
5546
|
+
context
|
|
5547
|
+
}) : [];
|
|
4097
5548
|
const dx = -10 - (isHorizontalBar ? textFontSize : 0);
|
|
4098
5549
|
const dy = isHorizontalBar ? 0 : textFontSize;
|
|
4099
5550
|
const markPointStyle = {
|
|
@@ -4155,9 +5606,6 @@
|
|
|
4155
5606
|
};
|
|
4156
5607
|
};
|
|
4157
5608
|
const annotationPoint_annotationPoint = generateAnnotationPointPipe({});
|
|
4158
|
-
function chunk_BO3LQZNF_o(r) {
|
|
4159
|
-
return Array.isArray(r);
|
|
4160
|
-
}
|
|
4161
5609
|
const annotationVerticalLine_annotationVerticalLine = (spec, context)=>{
|
|
4162
5610
|
const { advancedVSeed, vseed } = context;
|
|
4163
5611
|
const { annotation, config } = advancedVSeed;
|
|
@@ -4176,7 +5624,7 @@
|
|
|
4176
5624
|
insideEnd: 'insideEndTop'
|
|
4177
5625
|
};
|
|
4178
5626
|
const markLine = annotationVerticalLineList.flatMap((annotationVerticalLine)=>{
|
|
4179
|
-
const { xValue, text = '', textPosition = 'insideEnd', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = 'center', textBaseline = 'top', lineColor = theme?.lineColor ?? '#212121', lineStyle = theme?.lineStyle ?? 'dashed', lineVisible = theme?.lineStyle ?? true, lineWidth = theme?.lineWidth ?? 1, textBackgroundVisible = theme?.textBackgroundVisible ?? true, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundBorderColor = theme?.textBackgroundBorderColor ?? '#212121', textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundPadding = theme?.textBackgroundPadding ?? 2 } = annotationVerticalLine;
|
|
5627
|
+
const { xValue, dynamicFilter, text = '', textPosition = 'insideEnd', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = 'center', textBaseline = 'top', lineColor = theme?.lineColor ?? '#212121', lineStyle = theme?.lineStyle ?? 'dashed', lineVisible = theme?.lineStyle ?? true, lineWidth = theme?.lineWidth ?? 1, textBackgroundVisible = theme?.textBackgroundVisible ?? true, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundBorderColor = theme?.textBackgroundBorderColor ?? '#212121', textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundPadding = theme?.textBackgroundPadding ?? 2 } = annotationVerticalLine;
|
|
4180
5628
|
const generateOneMarkLine = (x)=>({
|
|
4181
5629
|
x,
|
|
4182
5630
|
autoRange: true,
|
|
@@ -4247,9 +5695,14 @@
|
|
|
4247
5695
|
}
|
|
4248
5696
|
}
|
|
4249
5697
|
});
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
5698
|
+
const finalXValue = resolveAnnotationValue({
|
|
5699
|
+
dynamicFilter,
|
|
5700
|
+
fallback: dynamicFilter?.fallback,
|
|
5701
|
+
defaultValue: xValue
|
|
5702
|
+
});
|
|
5703
|
+
if (chunk_BO3LQZNF_o(finalXValue) || chunk_SFZGYJFI_t(finalXValue) || chunk_6GTAPB47_e(finalXValue)) {
|
|
5704
|
+
const xValueArr = Array.isArray(finalXValue) ? finalXValue : [
|
|
5705
|
+
finalXValue
|
|
4253
5706
|
];
|
|
4254
5707
|
return xValueArr.map(generateOneMarkLine);
|
|
4255
5708
|
}
|
|
@@ -4283,7 +5736,7 @@
|
|
|
4283
5736
|
insideEnd: 'insideEndTop'
|
|
4284
5737
|
};
|
|
4285
5738
|
const markLine = annotationHorizontalLineList.flatMap((annotationHorizontalLine)=>{
|
|
4286
|
-
const { yValue, text = '', textPosition = 'insideEnd', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = 'right', textBaseline = 'bottom', lineColor = theme?.lineColor ?? '#212121', lineStyle = theme?.lineStyle ?? 'dashed', lineVisible = theme?.lineStyle ?? true, lineWidth = theme?.lineWidth ?? 1, textBackgroundVisible = theme?.textBackgroundVisible ?? true, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundBorderColor = theme?.textBackgroundBorderColor ?? '#212121', textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundPadding = theme?.textBackgroundPadding ?? 2 } = annotationHorizontalLine;
|
|
5739
|
+
const { yValue, dynamicFilter, text = '', textPosition = 'insideEnd', textColor = theme?.textColor ?? '#ffffff', textFontSize = theme?.textFontSize ?? 12, textFontWeight = theme?.textFontWeight ?? 400, textAlign = 'right', textBaseline = 'bottom', lineColor = theme?.lineColor ?? '#212121', lineStyle = theme?.lineStyle ?? 'dashed', lineVisible = theme?.lineStyle ?? true, lineWidth = theme?.lineWidth ?? 1, textBackgroundVisible = theme?.textBackgroundVisible ?? true, textBackgroundColor = theme?.textBackgroundColor ?? '#212121', textBackgroundBorderColor = theme?.textBackgroundBorderColor ?? '#212121', textBackgroundBorderRadius = theme?.textBackgroundBorderRadius ?? 4, textBackgroundBorderWidth = theme?.textBackgroundBorderWidth ?? 1, textBackgroundPadding = theme?.textBackgroundPadding ?? 2 } = annotationHorizontalLine;
|
|
4287
5740
|
const generateOneMarkLine = (y)=>({
|
|
4288
5741
|
y,
|
|
4289
5742
|
autoRange: true,
|
|
@@ -4353,9 +5806,14 @@
|
|
|
4353
5806
|
}
|
|
4354
5807
|
}
|
|
4355
5808
|
});
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
5809
|
+
const finalYValue = resolveAnnotationValue({
|
|
5810
|
+
dynamicFilter,
|
|
5811
|
+
fallback: dynamicFilter?.fallback,
|
|
5812
|
+
defaultValue: yValue
|
|
5813
|
+
});
|
|
5814
|
+
if (chunk_BO3LQZNF_o(finalYValue) || chunk_SFZGYJFI_t(finalYValue) || chunk_6GTAPB47_e(finalYValue)) {
|
|
5815
|
+
const yValueArr = Array.isArray(finalYValue) ? finalYValue : [
|
|
5816
|
+
finalYValue
|
|
4359
5817
|
];
|
|
4360
5818
|
return yValueArr.map(generateOneMarkLine);
|
|
4361
5819
|
}
|
|
@@ -6140,7 +7598,8 @@
|
|
|
6140
7598
|
[`custom${index + 1}`]: {
|
|
6141
7599
|
level: index + 1,
|
|
6142
7600
|
filter: (datum)=>{
|
|
6143
|
-
|
|
7601
|
+
const shouldApply = style.dynamicFilter ? selectorWithDynamicFilter(datum, style.dynamicFilter, style.selector) : selector_selector(datum, style.selector);
|
|
7602
|
+
if (shouldApply) return true;
|
|
6144
7603
|
return false;
|
|
6145
7604
|
},
|
|
6146
7605
|
style: {
|
|
@@ -10679,13 +12138,17 @@
|
|
|
10679
12138
|
}), result;
|
|
10680
12139
|
}
|
|
10681
12140
|
const annotationPointOfDualAxis = generateAnnotationPointPipe({
|
|
10682
|
-
findSelectedDatas: (
|
|
12141
|
+
findSelectedDatas: (options)=>{
|
|
12142
|
+
const { dataset, selector: s, dynamicFilter, context } = options;
|
|
12143
|
+
return dataset.reduce((res, d)=>{
|
|
10683
12144
|
const { advancedVSeed } = context;
|
|
10684
12145
|
const allMeasureIds = flatReshapeMeasures(advancedVSeed.reshapeMeasures ?? []).map((m)=>m.id);
|
|
10685
12146
|
const pickedDatum = pickWithout(d, allMeasureIds.filter((id)=>id !== d[MeasureId]));
|
|
10686
|
-
|
|
12147
|
+
const shouldSelect = dynamicFilter ? selectorWithDynamicFilter(pickedDatum, dynamicFilter, s) : selector_selector(pickedDatum, s);
|
|
12148
|
+
if (shouldSelect) res.push(pickedDatum);
|
|
10687
12149
|
return res;
|
|
10688
|
-
}, [])
|
|
12150
|
+
}, []);
|
|
12151
|
+
},
|
|
10689
12152
|
generateMarkPoint: (datum, spec, context)=>{
|
|
10690
12153
|
const { advancedVSeed } = context;
|
|
10691
12154
|
const allMeasureIds = flatReshapeMeasures(advancedVSeed.reshapeMeasures ?? []).map((m)=>m.id);
|
|
@@ -20732,6 +22195,7 @@
|
|
|
20732
22195
|
const zLinearColor = schemas_object({
|
|
20733
22196
|
linearColorScheme: schemas_array(schemas_string()).nullish()
|
|
20734
22197
|
});
|
|
22198
|
+
const zPartialSelector = zDatum;
|
|
20735
22199
|
const zMeasureSelector = schemas_object({
|
|
20736
22200
|
field: schemas_string(),
|
|
20737
22201
|
operator: schemas_enum([
|
|
@@ -20786,7 +22250,8 @@
|
|
|
20786
22250
|
schemas_string(),
|
|
20787
22251
|
schemas_number(),
|
|
20788
22252
|
zMeasureSelector,
|
|
20789
|
-
zDimensionSelector
|
|
22253
|
+
zDimensionSelector,
|
|
22254
|
+
zPartialSelector
|
|
20790
22255
|
]);
|
|
20791
22256
|
const zSelectors = schemas_array(zSelector);
|
|
20792
22257
|
const zAreaSelector = union([
|
|
@@ -20794,6 +22259,59 @@
|
|
|
20794
22259
|
zDimensionSelector
|
|
20795
22260
|
]);
|
|
20796
22261
|
const zAreaSelectors = schemas_array(zAreaSelector);
|
|
22262
|
+
const zCellSelector = schemas_object({
|
|
22263
|
+
__row_index: schemas_number(),
|
|
22264
|
+
field: union([
|
|
22265
|
+
schemas_string(),
|
|
22266
|
+
literal('*')
|
|
22267
|
+
])
|
|
22268
|
+
});
|
|
22269
|
+
const zTableDynamicFilter = schemas_object({
|
|
22270
|
+
type: literal('row-with-field'),
|
|
22271
|
+
description: schemas_string().optional(),
|
|
22272
|
+
code: schemas_string(),
|
|
22273
|
+
fallback: union([
|
|
22274
|
+
zSelector,
|
|
22275
|
+
zSelectors
|
|
22276
|
+
]).optional(),
|
|
22277
|
+
result: schemas_object({
|
|
22278
|
+
success: schemas_boolean(),
|
|
22279
|
+
data: schemas_array(zCellSelector).optional()
|
|
22280
|
+
}).optional()
|
|
22281
|
+
});
|
|
22282
|
+
const zChartDynamicFilter = schemas_object({
|
|
22283
|
+
type: literal('row-with-field'),
|
|
22284
|
+
description: schemas_string().optional(),
|
|
22285
|
+
code: schemas_string(),
|
|
22286
|
+
fallback: union([
|
|
22287
|
+
zSelector,
|
|
22288
|
+
zSelectors
|
|
22289
|
+
]).optional(),
|
|
22290
|
+
result: schemas_object({
|
|
22291
|
+
success: schemas_boolean(),
|
|
22292
|
+
data: schemas_array(record(schemas_string(), any())).optional()
|
|
22293
|
+
}).optional()
|
|
22294
|
+
});
|
|
22295
|
+
const zValueDynamicFilter = schemas_object({
|
|
22296
|
+
type: literal('value'),
|
|
22297
|
+
description: schemas_string().optional(),
|
|
22298
|
+
code: schemas_string(),
|
|
22299
|
+
fallback: union([
|
|
22300
|
+
schemas_string(),
|
|
22301
|
+
schemas_number()
|
|
22302
|
+
]).optional(),
|
|
22303
|
+
result: schemas_object({
|
|
22304
|
+
success: schemas_boolean(),
|
|
22305
|
+
data: union([
|
|
22306
|
+
schemas_number(),
|
|
22307
|
+
schemas_string()
|
|
22308
|
+
]).optional()
|
|
22309
|
+
}).optional()
|
|
22310
|
+
});
|
|
22311
|
+
const zDynamicFilter = union([
|
|
22312
|
+
zTableDynamicFilter,
|
|
22313
|
+
zChartDynamicFilter
|
|
22314
|
+
]);
|
|
20797
22315
|
const zLabel = schemas_object({
|
|
20798
22316
|
enable: schemas_boolean().nullish(),
|
|
20799
22317
|
wrap: schemas_boolean().nullish(),
|
|
@@ -20919,6 +22437,7 @@
|
|
|
20919
22437
|
zSelector,
|
|
20920
22438
|
zSelectors
|
|
20921
22439
|
]).nullish(),
|
|
22440
|
+
dynamicFilter: zChartDynamicFilter.optional(),
|
|
20922
22441
|
text: schemas_string().or(schemas_array(schemas_string())).nullish(),
|
|
20923
22442
|
textColor: schemas_string().default('#ffffff').nullish(),
|
|
20924
22443
|
textFontSize: schemas_number().default(12).nullish(),
|
|
@@ -20951,6 +22470,7 @@
|
|
|
20951
22470
|
schemas_string()
|
|
20952
22471
|
]))
|
|
20953
22472
|
]).nullish(),
|
|
22473
|
+
dynamicFilter: zValueDynamicFilter.optional(),
|
|
20954
22474
|
text: schemas_string().or(schemas_array(schemas_string())).nullish(),
|
|
20955
22475
|
textPosition: schemas_enum([
|
|
20956
22476
|
'outsideStart',
|
|
@@ -21495,6 +23015,7 @@
|
|
|
21495
23015
|
zSelector,
|
|
21496
23016
|
zSelectors
|
|
21497
23017
|
]).nullish(),
|
|
23018
|
+
dynamicFilter: zChartDynamicFilter.optional(),
|
|
21498
23019
|
barVisible: schemas_boolean().nullish(),
|
|
21499
23020
|
barColor: schemas_string().nullish(),
|
|
21500
23021
|
barColorOpacity: schemas_number().nullish(),
|
|
@@ -21515,6 +23036,7 @@
|
|
|
21515
23036
|
zSelector,
|
|
21516
23037
|
zSelectors
|
|
21517
23038
|
]).nullish(),
|
|
23039
|
+
dynamicFilter: zChartDynamicFilter.optional(),
|
|
21518
23040
|
pointVisible: schemas_boolean().nullish(),
|
|
21519
23041
|
pointSize: schemas_number().nullish(),
|
|
21520
23042
|
pointColor: schemas_string().nullish(),
|
|
@@ -21534,6 +23056,7 @@
|
|
|
21534
23056
|
zSelector,
|
|
21535
23057
|
zSelectors
|
|
21536
23058
|
]).nullish(),
|
|
23059
|
+
dynamicFilter: zChartDynamicFilter.optional(),
|
|
21537
23060
|
lineVisible: schemas_boolean().nullish(),
|
|
21538
23061
|
lineSmooth: schemas_boolean().nullish(),
|
|
21539
23062
|
lineColor: schemas_string().nullish(),
|
|
@@ -21552,6 +23075,7 @@
|
|
|
21552
23075
|
zSelector,
|
|
21553
23076
|
zSelectors
|
|
21554
23077
|
]).nullish(),
|
|
23078
|
+
dynamicFilter: zChartDynamicFilter.optional(),
|
|
21555
23079
|
areaVisible: schemas_boolean().nullish(),
|
|
21556
23080
|
areaColor: schemas_string().nullish(),
|
|
21557
23081
|
areaColorOpacity: schemas_number().nullish()
|
|
@@ -21573,6 +23097,7 @@
|
|
|
21573
23097
|
schemas_string()
|
|
21574
23098
|
]))
|
|
21575
23099
|
]).nullish(),
|
|
23100
|
+
dynamicFilter: zValueDynamicFilter.optional(),
|
|
21576
23101
|
text: schemas_string().or(schemas_array(schemas_string())).nullish(),
|
|
21577
23102
|
textPosition: schemas_enum([
|
|
21578
23103
|
'outsideStart',
|
|
@@ -21640,6 +23165,7 @@
|
|
|
21640
23165
|
zSelector,
|
|
21641
23166
|
zSelectors
|
|
21642
23167
|
]).nullish(),
|
|
23168
|
+
dynamicFilter: zTableDynamicFilter.nullish(),
|
|
21643
23169
|
backgroundColor: schemas_string().nullish(),
|
|
21644
23170
|
textColor: schemas_string().nullish(),
|
|
21645
23171
|
textFontSize: schemas_number().nullish(),
|
|
@@ -21674,7 +23200,7 @@
|
|
|
21674
23200
|
hoverHeaderInlineBackgroundColor: schemas_string().nullish(),
|
|
21675
23201
|
selectedBorderColor: schemas_string().nullish(),
|
|
21676
23202
|
selectedBackgroundColor: schemas_string().nullish(),
|
|
21677
|
-
bodyCellStyle: zBodyCellStyle.nullish(),
|
|
23203
|
+
bodyCellStyle: schemas_array(zBodyCellStyle).or(zBodyCellStyle).nullish(),
|
|
21678
23204
|
theme: zTheme.nullish(),
|
|
21679
23205
|
locale: zLocale.nullish()
|
|
21680
23206
|
});
|
|
@@ -21698,7 +23224,7 @@
|
|
|
21698
23224
|
hoverHeaderInlineBackgroundColor: schemas_string().nullish(),
|
|
21699
23225
|
selectedBorderColor: schemas_string().nullish(),
|
|
21700
23226
|
selectedBackgroundColor: schemas_string().nullish(),
|
|
21701
|
-
bodyCellStyle: zBodyCellStyle.nullish(),
|
|
23227
|
+
bodyCellStyle: schemas_array(zBodyCellStyle).or(zBodyCellStyle).nullish(),
|
|
21702
23228
|
theme: zTheme.nullish(),
|
|
21703
23229
|
locale: zLocale.nullish()
|
|
21704
23230
|
});
|