@orbcharts/core 3.0.7 → 4.0.0-beta.0
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/LICENSE +200 -200
- package/dist/orbcharts-core.es.js +2849 -6594
- package/dist/orbcharts-core.umd.js +6 -6
- package/dist/src/OrbCharts.d.ts +18 -0
- package/dist/src/chart/createChart.d.ts +3 -0
- package/dist/src/chart/createGraphData.d.ts +3 -0
- package/dist/src/chart/createGridData.d.ts +3 -0
- package/dist/src/chart/createMultivariateData.d.ts +3 -0
- package/dist/src/chart/createSeriesData.d.ts +3 -0
- package/dist/src/chart/createTreeData.d.ts +3 -0
- package/dist/src/chart/defaults.d.ts +5 -0
- package/dist/src/defineCanvasLayer.d.ts +16 -0
- package/dist/src/defineCanvasPlugin.d.ts +22 -0
- package/dist/src/defineSVGLayer.d.ts +16 -0
- package/dist/src/defineSVGPlugin.d.ts +22 -0
- package/dist/src/index.d.ts +6 -14
- package/dist/src/layer/createLayer.d.ts +3 -0
- package/dist/src/plugin/createPlugin.d.ts +3 -0
- package/dist/src/test/createGraphData.test.d.ts +1 -0
- package/dist/src/test/createTreeData.test.d.ts +1 -0
- package/dist/src/test/simple-graph-test.d.ts +74 -0
- package/dist/src/test/simple-tree-test.d.ts +13 -0
- package/dist/src/types/Chart.d.ts +39 -0
- package/dist/src/types/ChartContext.d.ts +27 -0
- package/dist/src/types/Common.d.ts +3 -0
- package/dist/src/types/Encoding.d.ts +33 -0
- package/dist/src/types/Event.d.ts +12 -0
- package/dist/src/types/Layers.d.ts +55 -0
- package/dist/src/types/ModelData.d.ts +70 -0
- package/dist/src/types/Plugin.d.ts +39 -0
- package/dist/src/types/RawData.d.ts +18 -0
- package/dist/src/types/RenderData.d.ts +4 -0
- package/dist/src/types/Theme.d.ts +17 -0
- package/dist/src/types/Validator.d.ts +20 -0
- package/dist/src/types/index.d.ts +12 -0
- package/dist/src/utils/aggregateUtils.d.ts +37 -0
- package/dist/src/utils/colorUtils.d.ts +22 -0
- package/dist/src/utils/commonUtils.d.ts +3 -5
- package/dist/src/utils/dom-lifecycle.d.ts +37 -0
- package/dist/src/utils/dom.d.ts +6 -0
- package/dist/src/utils/index.d.ts +5 -1
- package/dist/src/utils/observables.d.ts +1 -25
- package/dist/src/utils/orbchartsUtils.d.ts +2 -53
- package/dist/src/utils/validator.d.ts +2 -2
- package/dist/test/aggregateTest.d.ts +1 -0
- package/package.json +24 -13
- package/src/OrbCharts.ts +35 -0
- package/src/chart/createChart.ts +1014 -0
- package/src/chart/createGraphData.ts +391 -0
- package/src/chart/createGridData.ts +247 -0
- package/src/chart/createMultivariateData.ts +181 -0
- package/src/chart/createSeriesData.ts +297 -0
- package/src/chart/createTreeData.ts +344 -0
- package/src/chart/defaults.ts +120 -0
- package/src/defineCanvasLayer.ts +24 -0
- package/src/defineCanvasPlugin.ts +39 -0
- package/src/defineSVGLayer.ts +24 -0
- package/src/defineSVGPlugin.ts +39 -0
- package/src/index.ts +8 -20
- package/src/layer/createLayer.ts +138 -0
- package/src/plugin/createPlugin.ts +488 -0
- package/src/test/createGraphData.test.ts +103 -0
- package/src/test/createTreeData.test.ts +97 -0
- package/src/test/simple-graph-test.js +51 -0
- package/src/test/simple-tree-test.js +58 -0
- package/src/types/Chart.ts +62 -0
- package/src/types/ChartContext.ts +42 -0
- package/src/types/Common.ts +5 -0
- package/src/types/Encoding.ts +43 -0
- package/src/types/Event.ts +26 -0
- package/src/types/Layers.ts +93 -0
- package/src/types/ModelData.ts +95 -0
- package/src/types/Plugin.ts +101 -0
- package/src/types/RawData.ts +67 -0
- package/src/types/RenderData.ts +16 -0
- package/src/types/Theme.ts +21 -0
- package/src/types/Validator.ts +36 -0
- package/src/types/index.ts +12 -0
- package/src/utils/aggregateUtils.ts +99 -0
- package/src/utils/colorUtils.ts +63 -0
- package/src/utils/commonUtils.ts +56 -55
- package/src/utils/dom-lifecycle.ts +164 -0
- package/src/utils/dom.ts +55 -0
- package/src/utils/errorMessage.ts +40 -40
- package/src/utils/index.ts +8 -4
- package/src/utils/observables.ts +16 -307
- package/src/utils/orbchartsUtils.ts +9 -396
- package/src/utils/validator.ts +127 -126
- package/dist/lib/core-types.d.ts +0 -1
- package/dist/src/AbstractChart.d.ts +0 -19
- package/dist/src/GridChart.d.ts +0 -6
- package/dist/src/MultiGridChart.d.ts +0 -6
- package/dist/src/MultiValueChart.d.ts +0 -6
- package/dist/src/RelationshipChart.d.ts +0 -6
- package/dist/src/SeriesChart.d.ts +0 -6
- package/dist/src/TreeChart.d.ts +0 -6
- package/dist/src/base/createBaseChart.d.ts +0 -3
- package/dist/src/base/createBasePlugin.d.ts +0 -3
- package/dist/src/base/validators/chartOptionsValidator.d.ts +0 -3
- package/dist/src/base/validators/chartParamsValidator.d.ts +0 -3
- package/dist/src/base/validators/elementValidator.d.ts +0 -3
- package/dist/src/base/validators/pluginsValidator.d.ts +0 -3
- package/dist/src/defaults.d.ts +0 -25
- package/dist/src/defineGridPlugin.d.ts +0 -1
- package/dist/src/defineMultiGridPlugin.d.ts +0 -1
- package/dist/src/defineMultiValuePlugin.d.ts +0 -1
- package/dist/src/defineNoneDataPlugin.d.ts +0 -1
- package/dist/src/defineRelationshipPlugin.d.ts +0 -1
- package/dist/src/defineSeriesPlugin.d.ts +0 -1
- package/dist/src/defineTreePlugin.d.ts +0 -1
- package/dist/src/grid/computedDataFn.d.ts +0 -4
- package/dist/src/grid/contextObserverCallback.d.ts +0 -3
- package/dist/src/grid/dataFormatterValidator.d.ts +0 -3
- package/dist/src/grid/dataValidator.d.ts +0 -3
- package/dist/src/grid/gridObservables.d.ts +0 -64
- package/dist/src/multiGrid/computedDataFn.d.ts +0 -3
- package/dist/src/multiGrid/contextObserverCallback.d.ts +0 -3
- package/dist/src/multiGrid/dataFormatterValidator.d.ts +0 -3
- package/dist/src/multiGrid/dataValidator.d.ts +0 -3
- package/dist/src/multiGrid/multiGridObservables.d.ts +0 -16
- package/dist/src/multiValue/computedDataFn.d.ts +0 -3
- package/dist/src/multiValue/contextObserverCallback.d.ts +0 -3
- package/dist/src/multiValue/dataFormatterValidator.d.ts +0 -3
- package/dist/src/multiValue/dataValidator.d.ts +0 -3
- package/dist/src/multiValue/multiValueObservables.d.ts +0 -130
- package/dist/src/relationship/computedDataFn.d.ts +0 -3
- package/dist/src/relationship/contextObserverCallback.d.ts +0 -3
- package/dist/src/relationship/dataFormatterValidator.d.ts +0 -3
- package/dist/src/relationship/dataValidator.d.ts +0 -3
- package/dist/src/relationship/relationshipObservables.d.ts +0 -13
- package/dist/src/series/computedDataFn.d.ts +0 -3
- package/dist/src/series/contextObserverCallback.d.ts +0 -3
- package/dist/src/series/dataFormatterValidator.d.ts +0 -3
- package/dist/src/series/dataValidator.d.ts +0 -3
- package/dist/src/series/seriesObservables.d.ts +0 -37
- package/dist/src/tree/computedDataFn.d.ts +0 -3
- package/dist/src/tree/contextObserverCallback.d.ts +0 -3
- package/dist/src/tree/dataFormatterValidator.d.ts +0 -3
- package/dist/src/tree/dataValidator.d.ts +0 -3
- package/dist/src/tree/treeObservables.d.ts +0 -10
- package/dist/src/utils/d3Scale.d.ts +0 -28
- package/lib/core-types.ts +0 -7
- package/src/AbstractChart.ts +0 -57
- package/src/GridChart.ts +0 -25
- package/src/MultiGridChart.ts +0 -25
- package/src/MultiValueChart.ts +0 -25
- package/src/RelationshipChart.ts +0 -25
- package/src/SeriesChart.ts +0 -25
- package/src/TreeChart.ts +0 -25
- package/src/base/createBaseChart.ts +0 -524
- package/src/base/createBasePlugin.ts +0 -154
- package/src/base/validators/chartOptionsValidator.ts +0 -24
- package/src/base/validators/chartParamsValidator.ts +0 -134
- package/src/base/validators/elementValidator.ts +0 -14
- package/src/base/validators/pluginsValidator.ts +0 -15
- package/src/defaults.ts +0 -284
- package/src/defineGridPlugin.ts +0 -3
- package/src/defineMultiGridPlugin.ts +0 -3
- package/src/defineMultiValuePlugin.ts +0 -3
- package/src/defineNoneDataPlugin.ts +0 -4
- package/src/defineRelationshipPlugin.ts +0 -3
- package/src/defineSeriesPlugin.ts +0 -3
- package/src/defineTreePlugin.ts +0 -3
- package/src/grid/computedDataFn.ts +0 -129
- package/src/grid/contextObserverCallback.ts +0 -209
- package/src/grid/dataFormatterValidator.ts +0 -126
- package/src/grid/dataValidator.ts +0 -13
- package/src/grid/gridObservables.ts +0 -699
- package/src/multiGrid/computedDataFn.ts +0 -123
- package/src/multiGrid/contextObserverCallback.ts +0 -109
- package/src/multiGrid/dataFormatterValidator.ts +0 -121
- package/src/multiGrid/dataValidator.ts +0 -13
- package/src/multiGrid/multiGridObservables.ts +0 -367
- package/src/multiValue/computedDataFn.ts +0 -113
- package/src/multiValue/contextObserverCallback.ts +0 -328
- package/src/multiValue/dataFormatterValidator.ts +0 -95
- package/src/multiValue/dataValidator.ts +0 -13
- package/src/multiValue/multiValueObservables.ts +0 -865
- package/src/relationship/computedDataFn.ts +0 -159
- package/src/relationship/contextObserverCallback.ts +0 -80
- package/src/relationship/dataFormatterValidator.ts +0 -14
- package/src/relationship/dataValidator.ts +0 -14
- package/src/relationship/relationshipObservables.ts +0 -85
- package/src/series/computedDataFn.ts +0 -88
- package/src/series/contextObserverCallback.ts +0 -132
- package/src/series/dataFormatterValidator.ts +0 -47
- package/src/series/dataValidator.ts +0 -13
- package/src/series/seriesObservables.ts +0 -210
- package/src/tree/computedDataFn.ts +0 -129
- package/src/tree/contextObserverCallback.ts +0 -58
- package/src/tree/dataFormatterValidator.ts +0 -14
- package/src/tree/dataValidator.ts +0 -14
- package/src/tree/treeObservables.ts +0 -106
- package/src/utils/d3Scale.ts +0 -198
- package/tsconfig.base.json +0 -14
- package/tsconfig.json +0 -3
- package/vite-env.d.ts +0 -7
- package/vite.config.js +0 -23
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Subject,
|
|
3
|
+
BehaviorSubject,
|
|
4
|
+
filter,
|
|
5
|
+
takeUntil,
|
|
6
|
+
switchMap,
|
|
7
|
+
combineLatest,
|
|
8
|
+
of,
|
|
9
|
+
map,
|
|
10
|
+
shareReplay,
|
|
11
|
+
debounceTime,
|
|
12
|
+
} from "rxjs"
|
|
13
|
+
import type {
|
|
14
|
+
DefineLayerConfig,
|
|
15
|
+
LayerEntity,
|
|
16
|
+
ExtendableContext,
|
|
17
|
+
LayerEnableProps
|
|
18
|
+
} from "../types"
|
|
19
|
+
import { deepOverwrite } from "../utils/commonUtils"
|
|
20
|
+
import { createOrbChartsErrorMessage, createValidatorErrorMessage, createValidatorWarningMessage } from "../utils"
|
|
21
|
+
|
|
22
|
+
export const createLayer = <
|
|
23
|
+
ExtendContext extends ExtendableContext,
|
|
24
|
+
PluginParams extends Record<string, any>,
|
|
25
|
+
LayerParams extends Record<string, any>
|
|
26
|
+
>(elementType: 'canvas' | 'svg', config: DefineLayerConfig<'svg' | 'canvas', ExtendContext, PluginParams, LayerParams>): LayerEntity<ExtendContext, PluginParams, LayerParams> => {
|
|
27
|
+
|
|
28
|
+
// let svgElement: SVGSVGElement | null = null
|
|
29
|
+
// let canvasElement: HTMLCanvasElement | null = null
|
|
30
|
+
|
|
31
|
+
const layerParams$ = new BehaviorSubject<LayerParams>(Object.assign({}, config.defaultParams))
|
|
32
|
+
|
|
33
|
+
// let _context: ChartContext<ExtendContext> = {} as ChartContext<ExtendContext>
|
|
34
|
+
let destroySetup = () => {}
|
|
35
|
+
|
|
36
|
+
const enableProps$ = new BehaviorSubject<LayerEnableProps<'svg' | 'canvas', ExtendContext, PluginParams, LayerParams> | null>(null)
|
|
37
|
+
|
|
38
|
+
const enabledProps$ = enableProps$.pipe(
|
|
39
|
+
filter(enableProps => enableProps !== null)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
// show
|
|
43
|
+
combineLatest({
|
|
44
|
+
layerParams: layerParams$,
|
|
45
|
+
enabledProps: enabledProps$
|
|
46
|
+
}).pipe(
|
|
47
|
+
debounceTime(0)
|
|
48
|
+
).subscribe(({ layerParams, enabledProps }) => {
|
|
49
|
+
destroySetup()
|
|
50
|
+
destroySetup = elementType === 'svg' ?
|
|
51
|
+
config.setup({
|
|
52
|
+
svgG: (enabledProps as LayerEnableProps<'svg', ExtendContext, PluginParams, LayerParams>).svgG,
|
|
53
|
+
// canvas: enabledProps.canvas,
|
|
54
|
+
// context: Object.assign({}, enabledProps.context),
|
|
55
|
+
context: enabledProps.context,
|
|
56
|
+
pluginParams$: enabledProps.pluginParams$,
|
|
57
|
+
layerParams$: layerParams$.pipe(
|
|
58
|
+
map(params => {
|
|
59
|
+
return deepOverwrite(params, enabledProps.initLayerParams ?? {})
|
|
60
|
+
}),
|
|
61
|
+
)
|
|
62
|
+
})
|
|
63
|
+
: config.setup({
|
|
64
|
+
// svgG: enabledProps.svgG,
|
|
65
|
+
canvas: (enabledProps as LayerEnableProps<'canvas', ExtendContext, PluginParams, LayerParams>).canvas,
|
|
66
|
+
// context: Object.assign({}, enabledProps.context),
|
|
67
|
+
context: enabledProps.context,
|
|
68
|
+
pluginParams$: enabledProps.pluginParams$,
|
|
69
|
+
layerParams$: layerParams$.pipe(
|
|
70
|
+
map(params => {
|
|
71
|
+
return deepOverwrite(params, enabledProps.initLayerParams ?? {})
|
|
72
|
+
}),
|
|
73
|
+
)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// hide
|
|
78
|
+
enableProps$.pipe(filter(enableProps => enableProps === null)).subscribe(() => {
|
|
79
|
+
destroySetup()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
_name: config.name,
|
|
84
|
+
_defaultParams: config.defaultParams,
|
|
85
|
+
_layerIndex: config.layerIndex,
|
|
86
|
+
_initShow: config.initShow,
|
|
87
|
+
_enable: (enableProps) => {
|
|
88
|
+
enableProps$.next(enableProps)
|
|
89
|
+
},
|
|
90
|
+
_disable: () => {
|
|
91
|
+
enableProps$.next(null)
|
|
92
|
+
},
|
|
93
|
+
// setParams: (partial) => {
|
|
94
|
+
// previousParams$.next(deepOverwrite(defaultParams$.getValue(), partial))
|
|
95
|
+
// },
|
|
96
|
+
_updateParams: (patch) => {
|
|
97
|
+
try {
|
|
98
|
+
// 檢查 data$ 資料格式是否正確
|
|
99
|
+
const { status, columnName, expectToBe } = config.validator(patch)
|
|
100
|
+
if (status === 'error') {
|
|
101
|
+
throw new Error(createValidatorErrorMessage({
|
|
102
|
+
columnName,
|
|
103
|
+
expectToBe,
|
|
104
|
+
from: `${config.name}.params$`
|
|
105
|
+
}))
|
|
106
|
+
} else if (status === 'warning') {
|
|
107
|
+
console.warn(createValidatorWarningMessage({
|
|
108
|
+
columnName,
|
|
109
|
+
expectToBe,
|
|
110
|
+
from: `${config.name}.params$`
|
|
111
|
+
}))
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
// throw new Error(e.message)
|
|
115
|
+
// 驗證失敗仍繼續執行,才不會把 Observable 資料流給中斷掉
|
|
116
|
+
console.error(createOrbChartsErrorMessage(e))
|
|
117
|
+
}
|
|
118
|
+
const layerParams = deepOverwrite(layerParams$.getValue(), patch)
|
|
119
|
+
layerParams$.next(layerParams)
|
|
120
|
+
},
|
|
121
|
+
_forceReplaceParams: (full) => {
|
|
122
|
+
layerParams$.next(full)
|
|
123
|
+
},
|
|
124
|
+
_getParams: () => {
|
|
125
|
+
return layerParams$.getValue()
|
|
126
|
+
},
|
|
127
|
+
// injectContext: (context) => {
|
|
128
|
+
// _context = Object.assign({}, context)
|
|
129
|
+
// // re-setup layer with new context
|
|
130
|
+
// enableProps$.next(true)
|
|
131
|
+
// },
|
|
132
|
+
_destroy: () => {
|
|
133
|
+
enableProps$.next(null)
|
|
134
|
+
enableProps$.complete()
|
|
135
|
+
layerParams$.complete()
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import type { ChartContext, DeepPartial, DefinePluginConfig, ExtendableContext, PluginEntity } from '../types'
|
|
2
|
+
import {
|
|
3
|
+
BehaviorSubject,
|
|
4
|
+
combineLatest,
|
|
5
|
+
switchMap,
|
|
6
|
+
map,
|
|
7
|
+
filter,
|
|
8
|
+
of,
|
|
9
|
+
shareReplay,
|
|
10
|
+
debounceTime,
|
|
11
|
+
first,
|
|
12
|
+
Observable,
|
|
13
|
+
Subject,
|
|
14
|
+
} from 'rxjs'
|
|
15
|
+
import type { PluginSetupProps, LayerEnableProps } from '../types'
|
|
16
|
+
// import { handleElementLifecycle } from '../utils/dom-lifecycle'
|
|
17
|
+
// import { createSVG, createCanvasElement, createSVGGroup, createCanvas } from '../utils/dom'
|
|
18
|
+
// import { createPluginClassName, createLayerClassName } from '../utils/orbchartsUtils'
|
|
19
|
+
import { deepOverwrite } from '../utils/commonUtils'
|
|
20
|
+
import { createOrbChartsErrorMessage, createValidatorErrorMessage, createValidatorWarningMessage } from '../utils/errorMessage'
|
|
21
|
+
|
|
22
|
+
export const createPlugin = <
|
|
23
|
+
ElementType extends 'svg' | 'canvas',
|
|
24
|
+
ExtendContext extends ExtendableContext,
|
|
25
|
+
PluginParams,
|
|
26
|
+
AllLayerParams
|
|
27
|
+
>(elementType: ElementType, config: DefinePluginConfig<ExtendContext, PluginParams, AllLayerParams>, initPluginParams?: DeepPartial<PluginParams | AllLayerParams>): PluginEntity<ElementType, PluginParams, AllLayerParams> => {
|
|
28
|
+
// const svgClassName = `${createPluginClassName(config.name)}__svg`
|
|
29
|
+
// const svgGClassName = `${createPluginClassName(config.name)}__g`
|
|
30
|
+
// const canvasClassName = `${createPluginClassName(config.name)}__canvas`
|
|
31
|
+
|
|
32
|
+
// 內部保存起來的 id
|
|
33
|
+
let _id = config.name
|
|
34
|
+
|
|
35
|
+
let destroySetup = () => {}
|
|
36
|
+
|
|
37
|
+
const context$ = new BehaviorSubject<ChartContext<ExtendContext> | null>(null)
|
|
38
|
+
const injectedContext$ = context$.pipe(
|
|
39
|
+
filter((context): context is ChartContext<ExtendContext> => context !== null)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
// element 全部保存起來避免重複創建
|
|
43
|
+
// const layerSVGElementsRef: Record<string, SVGElement> = {}
|
|
44
|
+
// const layerCanvasElementsRef: Record<string, HTMLCanvasElement> = {}
|
|
45
|
+
|
|
46
|
+
// 每個 plugin 實例建立「自己的」layer 實體。
|
|
47
|
+
// Layer 內部狀態(enableProps$、setup 訂閱等)一次只能服務一個 plugin 實例,
|
|
48
|
+
// 若跨實例共用(例如 module 層級的單例),同頁多個 plugin 會互搶 layer,
|
|
49
|
+
// 造成部分圖表的 layer 不繪製或被銷毀。
|
|
50
|
+
const layers = config.layers.map((Layer) => new Layer())
|
|
51
|
+
|
|
52
|
+
// 全部的layers
|
|
53
|
+
const allLayerInstances = {
|
|
54
|
+
// 將陣列轉成字典
|
|
55
|
+
...layers.reduce((acc, layer) => {
|
|
56
|
+
acc[layer._name as keyof AllLayerParams] = layer
|
|
57
|
+
return acc
|
|
58
|
+
}, {} as Record<keyof AllLayerParams, typeof layers[number]>)
|
|
59
|
+
}
|
|
60
|
+
const getAllLayerNamesSet = () => new Set(layers.map(l => l._name as keyof AllLayerParams))
|
|
61
|
+
// const getParamsKeySet = (params: DeepPartial<PluginParams | AllLayerParams>): Set<keyof AllLayerParams> => {
|
|
62
|
+
// // 取得有設定 params 的 layer name
|
|
63
|
+
// if (params) {
|
|
64
|
+
// const AllLayerNamesSet = getAllLayerNamesSet()
|
|
65
|
+
// const keysOfParams = Object.keys(params) as (keyof AllLayerParams)[]
|
|
66
|
+
// return new Set(keysOfParams.filter(key => AllLayerNamesSet.has(key)))
|
|
67
|
+
// }
|
|
68
|
+
// return new Set()
|
|
69
|
+
// }
|
|
70
|
+
const getParamsKeys = (params: DeepPartial<PluginParams | AllLayerParams>): (keyof AllLayerParams)[] => {
|
|
71
|
+
// 取得有設定 params 的 layer name
|
|
72
|
+
if (params) {
|
|
73
|
+
const AllLayerNamesSet = getAllLayerNamesSet()
|
|
74
|
+
const keysOfParams = Object.keys(params) as (keyof AllLayerParams)[]
|
|
75
|
+
return keysOfParams.filter(key => AllLayerNamesSet.has(key))
|
|
76
|
+
}
|
|
77
|
+
return []
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// config 設定顯示的 layers
|
|
81
|
+
const systemInitLayerNames = layers.reduce((prev, current) => {
|
|
82
|
+
if (current._initShow) {
|
|
83
|
+
prev.push(current._name as keyof AllLayerParams)
|
|
84
|
+
}
|
|
85
|
+
return prev
|
|
86
|
+
}, [] as (keyof AllLayerParams)[])
|
|
87
|
+
// 有設定 params 對應的 layers 名稱
|
|
88
|
+
const initLayerNames = getParamsKeys(initPluginParams)
|
|
89
|
+
// const InitLayerNameSet$ = new BehaviorSubject<Set<keyof AllLayerParams>>(getParamsKeySet(initPluginParams))
|
|
90
|
+
// 有設定 show/showOnly 等的 layers 名稱
|
|
91
|
+
const ShownLayerNameSet$ = new BehaviorSubject<Set<keyof AllLayerParams>>(
|
|
92
|
+
new Set(initLayerNames.length > 0 ? initLayerNames : systemInitLayerNames)
|
|
93
|
+
)
|
|
94
|
+
// 顯示的 layers 名稱
|
|
95
|
+
// const getShownLayerNames = ({ InitLayerNameSet, IsShowLayerNameSet }: { InitLayerNameSet: Set<keyof AllLayerParams>, IsShowLayerNameSet: Set<keyof AllLayerParams> | null }) => {
|
|
96
|
+
// const ShownLayerNameSet = IsShowLayerNameSet == null ? InitLayerNameSet : IsShowLayerNameSet // IsShowLayerNameSet 預設為 null
|
|
97
|
+
// return ShownLayerNameSet
|
|
98
|
+
// }
|
|
99
|
+
// const ShownLayerNameSet$ = combineLatest({
|
|
100
|
+
// InitLayerNameSet: InitLayerNameSet$,
|
|
101
|
+
// IsShowLayerNameSet: IsShowLayerNameSet$
|
|
102
|
+
// }).pipe(
|
|
103
|
+
// debounceTime(0),
|
|
104
|
+
// // filter(({ context }) => context !== null),
|
|
105
|
+
// map(({ InitLayerNameSet, IsShowLayerNameSet }) => {
|
|
106
|
+
// return getShownLayerNames({ InitLayerNameSet, IsShowLayerNameSet })
|
|
107
|
+
// })
|
|
108
|
+
// )
|
|
109
|
+
// 顯示的 layers 名稱依照 layerIndex 排序
|
|
110
|
+
const shownLayerNamesSeq$ = ShownLayerNameSet$.pipe(
|
|
111
|
+
map(ShownLayerNameSet => {
|
|
112
|
+
// 依照 layerIndex 排序
|
|
113
|
+
const shownLayerNamesSeq: string[] = Array.from(ShownLayerNameSet)
|
|
114
|
+
.map(name => [
|
|
115
|
+
name,
|
|
116
|
+
layers.find(l => l._name === name)?._layerIndex ?? -1
|
|
117
|
+
])
|
|
118
|
+
.filter(([, index]) => index !== -1)
|
|
119
|
+
.sort((a, b) => (a[1] as number) - (b[1] as number))
|
|
120
|
+
.map(([name]) => name as string)
|
|
121
|
+
return shownLayerNamesSeq
|
|
122
|
+
})
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
// plugin 的根元素
|
|
126
|
+
// const pluginElement$: Observable<SVGGElement | HTMLCanvasElement> = injectedContext$.pipe(
|
|
127
|
+
// map(context => {
|
|
128
|
+
// // -- 在 svg 或 canvas 元素底下建立 plugin 的元素 --
|
|
129
|
+
// if (elementType === 'svg') {
|
|
130
|
+
// let svgGElement: SVGGElement | null = context.svg.querySelector(`.${svgGClassName}`)
|
|
131
|
+
// if (!svgGElement) {
|
|
132
|
+
// svgGElement = createSVGGroup(svgGClassName)
|
|
133
|
+
// context.svg.appendChild(svgGElement)
|
|
134
|
+
// }
|
|
135
|
+
// return svgGElement
|
|
136
|
+
// } else if (elementType === 'canvas') {
|
|
137
|
+
// let canvasElement: HTMLCanvasElement | null = context.canvas.querySelector(`.${canvasClassName}`)
|
|
138
|
+
// if (!canvasElement) {
|
|
139
|
+
// canvasElement = createCanvasElement(canvasClassName)
|
|
140
|
+
// context.canvas.appendChild(canvasElement)
|
|
141
|
+
// }
|
|
142
|
+
// return canvasElement
|
|
143
|
+
// }
|
|
144
|
+
// })
|
|
145
|
+
// )
|
|
146
|
+
|
|
147
|
+
// 目前生效的 plugin 本身 params(預設值 + 歷次 patch 累積合併)。
|
|
148
|
+
// deepOverwrite 會忽略 defaults 中不存在的 key,因此建構子參數內的
|
|
149
|
+
// layer keys(如 { Bar: {} })會被自然濾除,不會混入 plugin-level params。
|
|
150
|
+
let currentPluginParams: PluginParams = deepOverwrite(
|
|
151
|
+
(config.defaultParams ?? {}) as PluginParams,
|
|
152
|
+
(initPluginParams ?? {}) as DeepPartial<PluginParams>
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
// update plugin params
|
|
156
|
+
const patchPluginParams$ = new BehaviorSubject<DeepPartial<AllLayerParams | PluginParams> | undefined>(
|
|
157
|
+
initPluginParams ?? {}
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
// force replace plugin params
|
|
161
|
+
const forceReplacePluginParams$ = new Subject<DeepPartial<AllLayerParams | PluginParams> | undefined>()
|
|
162
|
+
|
|
163
|
+
const pluginParams$ = new Observable<PluginParams>(subscriber => {
|
|
164
|
+
// -- update --
|
|
165
|
+
patchPluginParams$.subscribe(patch => {
|
|
166
|
+
try {
|
|
167
|
+
// 檢查 data$ 資料格式是否正確
|
|
168
|
+
const { status, columnName, expectToBe } = config.validator(patch)
|
|
169
|
+
if (status === 'error') {
|
|
170
|
+
throw new Error(createValidatorErrorMessage({
|
|
171
|
+
columnName,
|
|
172
|
+
expectToBe,
|
|
173
|
+
from: `${config.name}.params$`
|
|
174
|
+
}))
|
|
175
|
+
} else if (status === 'warning') {
|
|
176
|
+
console.warn(createValidatorWarningMessage({
|
|
177
|
+
columnName,
|
|
178
|
+
expectToBe,
|
|
179
|
+
from: `${config.name}.params$`
|
|
180
|
+
}))
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
// throw new Error(e.message)
|
|
184
|
+
// 驗證失敗仍繼續執行,才不會把 Observable 資料流給中斷掉
|
|
185
|
+
console.error(createOrbChartsErrorMessage(e))
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// currentPluginParams 已於 updateParams 中累積合併(歷次 patch 不互相覆蓋)
|
|
189
|
+
subscriber.next(currentPluginParams)
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
// -- force replace --
|
|
193
|
+
forceReplacePluginParams$.subscribe(full => {
|
|
194
|
+
subscriber.next(full as PluginParams)
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
// patchPluginParams$.pipe(
|
|
199
|
+
// map(patch => {
|
|
200
|
+
// try {
|
|
201
|
+
// // 檢查 data$ 資料格式是否正確
|
|
202
|
+
// const { status, columnName, expectToBe } = config.validator(patch)
|
|
203
|
+
// if (status === 'error') {
|
|
204
|
+
// throw new Error(createValidatorErrorMessage({
|
|
205
|
+
// columnName,
|
|
206
|
+
// expectToBe,
|
|
207
|
+
// from: `${config.name}.params$`
|
|
208
|
+
// }))
|
|
209
|
+
// } else if (status === 'warning') {
|
|
210
|
+
// console.warn(createValidatorWarningMessage({
|
|
211
|
+
// columnName,
|
|
212
|
+
// expectToBe,
|
|
213
|
+
// from: `${config.name}.params$`
|
|
214
|
+
// }))
|
|
215
|
+
// }
|
|
216
|
+
// } catch (e) {
|
|
217
|
+
// // throw new Error(e.message)
|
|
218
|
+
// // 驗證失敗仍繼續執行,才不會把 Observable 資料流給中斷掉
|
|
219
|
+
// console.error(createOrbChartsErrorMessage(e))
|
|
220
|
+
// }
|
|
221
|
+
|
|
222
|
+
// return deepOverwrite(config.defaultParams, patch as DeepPartial<PluginParams> ?? {})
|
|
223
|
+
// }),
|
|
224
|
+
// shareReplay(1)
|
|
225
|
+
// )
|
|
226
|
+
|
|
227
|
+
const pluginSetupProps$: Observable<PluginSetupProps<ExtendContext, PluginParams>> = injectedContext$.pipe(
|
|
228
|
+
map((context) => {
|
|
229
|
+
// const pluginSetupProps: PluginSetupProps<ExtendContext, PluginParams> =
|
|
230
|
+
// elementType === 'svg' ? {
|
|
231
|
+
// context: context as ChartContext<ExtendContext>, // 初始化時 context 有可能被 in place 擴展
|
|
232
|
+
// svgG: pluginElement as SVGSVGElement,
|
|
233
|
+
// pluginParams$
|
|
234
|
+
// } : {
|
|
235
|
+
// context: context as ChartContext<ExtendContext>,
|
|
236
|
+
// canvas: pluginElement as HTMLCanvasElement,
|
|
237
|
+
// pluginParams$
|
|
238
|
+
// }
|
|
239
|
+
return {
|
|
240
|
+
context, // 初始化時 context 有可能被 in place 擴展
|
|
241
|
+
pluginParams$
|
|
242
|
+
}
|
|
243
|
+
}),
|
|
244
|
+
first() // 只做初始化
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
combineLatest({
|
|
248
|
+
pluginSetupProps: pluginSetupProps$,
|
|
249
|
+
ShownLayerNameSet: ShownLayerNameSet$,
|
|
250
|
+
shownLayerNamesSeq: shownLayerNamesSeq$
|
|
251
|
+
}).pipe(
|
|
252
|
+
debounceTime(0)
|
|
253
|
+
).subscribe(({ pluginSetupProps, ShownLayerNameSet, shownLayerNamesSeq }) => {
|
|
254
|
+
|
|
255
|
+
// 更新 layer elements
|
|
256
|
+
const layerElements = pluginSetupProps.context._updateLayerElements(
|
|
257
|
+
elementType,
|
|
258
|
+
_id,
|
|
259
|
+
shownLayerNamesSeq.map(layer => ({
|
|
260
|
+
pluginId: _id,
|
|
261
|
+
pluginName: config.name,
|
|
262
|
+
layerName: layer,
|
|
263
|
+
layerIndex: allLayerInstances[layer as keyof AllLayerParams]._layerIndex
|
|
264
|
+
}))
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
// init plugin
|
|
268
|
+
if (config.setup) {
|
|
269
|
+
destroySetup = config.setup(pluginSetupProps)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// // layer element - 處理 SVG 元素的 enter/update/exit
|
|
273
|
+
// if (elementType === 'svg') {
|
|
274
|
+
// handleElementLifecycle(
|
|
275
|
+
// // (pluginSetupProps as PluginSetupProps<ExtendContext, PluginParams>).svgG,
|
|
276
|
+
// pluginSetupProps.context.svg,
|
|
277
|
+
// shownLayerNamesSeq, // 依照 shownLayerNamesSeq
|
|
278
|
+
// layerSVGElementsRef,
|
|
279
|
+
// (layerName) => createSVGGroup(createLayerClassName(config.name, layerName))
|
|
280
|
+
// )
|
|
281
|
+
// }
|
|
282
|
+
|
|
283
|
+
// // layer element - 處理 Canvas 元素的 enter/update/exit
|
|
284
|
+
// if (elementType === 'canvas') {
|
|
285
|
+
// handleElementLifecycle(
|
|
286
|
+
// // (pluginSetupProps as PluginSetupProps<ExtendContext, PluginParams>).canvas,
|
|
287
|
+
// pluginSetupProps.context.canvas,
|
|
288
|
+
// shownLayerNamesSeq, // 依照 shownLayerNamesSeq
|
|
289
|
+
// layerCanvasElementsRef,
|
|
290
|
+
// (layerName) => createCanvas(createLayerClassName(config.name, layerName))
|
|
291
|
+
// )
|
|
292
|
+
// }
|
|
293
|
+
|
|
294
|
+
// init layers
|
|
295
|
+
layers.forEach((layer) => {
|
|
296
|
+
if (ShownLayerNameSet.has(layer._name as keyof AllLayerParams)) {
|
|
297
|
+
const layerEnableProps: LayerEnableProps<'svg' | 'canvas', ExtendContext, PluginParams, unknown> =
|
|
298
|
+
elementType === 'svg' ?
|
|
299
|
+
{
|
|
300
|
+
// svgG: (pluginSetupProps as PluginSetupProps<'svg', ExtendContext, PluginParams>).svgG.querySelector(`.${createLayerClassName(config.name, layer.name)}`),
|
|
301
|
+
svgG: layerElements[layer._name as keyof AllLayerParams] as SVGGElement,
|
|
302
|
+
// canvas: context.root.querySelector(`.${createLayerClassName(config.name, layer.name)}`),
|
|
303
|
+
// context: Object.assign({}, context) as ChartContext<ExtendContext>,
|
|
304
|
+
context: pluginSetupProps.context,
|
|
305
|
+
pluginParams$,
|
|
306
|
+
initLayerParams: patchPluginParams$.getValue()?.[layer._name as keyof AllLayerParams] as unknown || {}
|
|
307
|
+
}
|
|
308
|
+
: {
|
|
309
|
+
// svgG: context.root.querySelector(`.${createLayerClassName(config.name, layer.name)}`),
|
|
310
|
+
// canvas: (pluginSetupProps as PluginSetupProps<'canvas', ExtendContext, PluginParams>).canvas.querySelector(`.${createLayerClassName(config.name, layer.name)}`),
|
|
311
|
+
canvas: layerElements[layer._name as keyof AllLayerParams] as HTMLCanvasElement,
|
|
312
|
+
// context: Object.assign({}, context) as ChartContext<ExtendContext>,
|
|
313
|
+
context: pluginSetupProps.context,
|
|
314
|
+
pluginParams$,
|
|
315
|
+
initLayerParams: patchPluginParams$.getValue()?.[layer._name as keyof AllLayerParams] as unknown || {}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
layer._enable(layerEnableProps)
|
|
319
|
+
} else {
|
|
320
|
+
layer._disable()
|
|
321
|
+
}
|
|
322
|
+
})
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
// name: `${config.name}-${Math.random().toString(36).substr(2, 9)}`,
|
|
327
|
+
_name: config.name,
|
|
328
|
+
_elementType: elementType,
|
|
329
|
+
// info: {
|
|
330
|
+
// name: config.name,
|
|
331
|
+
// layers: [config.name]
|
|
332
|
+
// } as PluginInfo,
|
|
333
|
+
// layerIndex: config.layerIndex,
|
|
334
|
+
// contextExtension,
|
|
335
|
+
// layer visibility controls
|
|
336
|
+
_getId: () => _id,
|
|
337
|
+
_setId: (id: string) => {
|
|
338
|
+
_id = id
|
|
339
|
+
},
|
|
340
|
+
// 由 chart 注入 context
|
|
341
|
+
_injectContext: (context) => {
|
|
342
|
+
|
|
343
|
+
context$.next(Object.assign({}, context) as ChartContext<ExtendContext>)
|
|
344
|
+
|
|
345
|
+
// context.size$.subscribe(size => {
|
|
346
|
+
// const svgGElement: SVGGElement | null = context.root.querySelector(`.${svgGClassName}`)
|
|
347
|
+
// const canvasElement: HTMLCanvasElement | null = context.root.querySelector(`.${canvasClassName}`)
|
|
348
|
+
// if (svgGElement) {
|
|
349
|
+
// svgGElement.setAttribute('width', size.width.toString())
|
|
350
|
+
// svgGElement.setAttribute('height', size.height.toString())
|
|
351
|
+
// }
|
|
352
|
+
// if (canvasElement) {
|
|
353
|
+
// canvasElement.width = size.width
|
|
354
|
+
// canvasElement.height = size.height
|
|
355
|
+
// }
|
|
356
|
+
// })
|
|
357
|
+
|
|
358
|
+
// if (config.setup) {
|
|
359
|
+
// // const extension: ExtendContext = config.setup(context)
|
|
360
|
+
// // Object.assign(context, extension)
|
|
361
|
+
// config.setup({
|
|
362
|
+
// context: context as ChartContext<ExtendContext>,
|
|
363
|
+
// svg: mainSvgElement!,
|
|
364
|
+
// canvas: mainCanvasElement!,
|
|
365
|
+
// pluginParams$
|
|
366
|
+
// })
|
|
367
|
+
// }
|
|
368
|
+
|
|
369
|
+
// 顯示全部 layers
|
|
370
|
+
// IsShowLayerNameSet$.next(getAllLayerNamesSet())
|
|
371
|
+
},
|
|
372
|
+
show: (names: (keyof AllLayerParams) | (keyof AllLayerParams)[]) => {
|
|
373
|
+
names = Array.isArray(names) ? names : [names]
|
|
374
|
+
ShownLayerNameSet$.next(new Set([...Array.from(ShownLayerNameSet$.getValue()), ...names]))
|
|
375
|
+
},
|
|
376
|
+
showOnly: (names: (keyof AllLayerParams) | (keyof AllLayerParams)[]) => {
|
|
377
|
+
names = Array.isArray(names) ? names : [names]
|
|
378
|
+
ShownLayerNameSet$.next(new Set([...names]))
|
|
379
|
+
},
|
|
380
|
+
showAll: () => {
|
|
381
|
+
ShownLayerNameSet$.next(getAllLayerNamesSet())
|
|
382
|
+
},
|
|
383
|
+
hide: (names: (keyof AllLayerParams) | (keyof AllLayerParams)[]) => {
|
|
384
|
+
names = Array.isArray(names) ? names : [names]
|
|
385
|
+
ShownLayerNameSet$.next(new Set([...Array.from(ShownLayerNameSet$.getValue()).filter(name => !names.includes(name))]))
|
|
386
|
+
},
|
|
387
|
+
hideAll: () => {
|
|
388
|
+
ShownLayerNameSet$.next(new Set())
|
|
389
|
+
},
|
|
390
|
+
toggle: (names: (keyof AllLayerParams) | (keyof AllLayerParams)[]) => {
|
|
391
|
+
names = Array.isArray(names) ? names : [names]
|
|
392
|
+
Array.from(ShownLayerNameSet$.getValue()).forEach(shown => {
|
|
393
|
+
if (names.includes(shown)) {
|
|
394
|
+
names.splice(names.indexOf(shown), 1)
|
|
395
|
+
} else {
|
|
396
|
+
names.push(shown)
|
|
397
|
+
}
|
|
398
|
+
})
|
|
399
|
+
ShownLayerNameSet$.next(new Set(names))
|
|
400
|
+
},
|
|
401
|
+
getShownLayerNames: () => {
|
|
402
|
+
// const ShownLayerNameSet = getShownLayerNames({
|
|
403
|
+
// InitLayerNameSet: InitLayerNameSet$.getValue(),
|
|
404
|
+
// IsShowLayerNameSet: IsShowLayerNameSet$.getValue()
|
|
405
|
+
// })
|
|
406
|
+
return Array.from(ShownLayerNameSet$.getValue())
|
|
407
|
+
},
|
|
408
|
+
// layer params
|
|
409
|
+
// setLayers: (partial: DeepPartial<PluginParams>) => {
|
|
410
|
+
// params = { ...params, ...partial }
|
|
411
|
+
// },
|
|
412
|
+
updateParams: (patch: DeepPartial<PluginParams | AllLayerParams>) => {
|
|
413
|
+
// plugin params(累積合併至目前值,使連續多次 updateParams 不互相覆蓋)
|
|
414
|
+
currentPluginParams = deepOverwrite(currentPluginParams, patch as DeepPartial<PluginParams>)
|
|
415
|
+
patchPluginParams$.next(patch)
|
|
416
|
+
// layer params
|
|
417
|
+
Object.keys(patch).forEach((key) => {
|
|
418
|
+
const layer = allLayerInstances[key as keyof AllLayerParams]
|
|
419
|
+
if (layer) {
|
|
420
|
+
layer._updateParams((patch as Record<string, any>)[key])
|
|
421
|
+
}
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
// InitLayerNameSet$.next(getParamsKeySet(patch))
|
|
425
|
+
},
|
|
426
|
+
forceReplaceParams: (full: PluginParams | AllLayerParams) => {
|
|
427
|
+
// plugin params
|
|
428
|
+
currentPluginParams = full as PluginParams
|
|
429
|
+
forceReplacePluginParams$.next(full)
|
|
430
|
+
// layer params
|
|
431
|
+
Object.keys(full).forEach((key) => {
|
|
432
|
+
const layer = allLayerInstances[key as keyof AllLayerParams]
|
|
433
|
+
if (layer) {
|
|
434
|
+
layer._forceReplaceParams((full as Record<string, any>)[key])
|
|
435
|
+
}
|
|
436
|
+
})
|
|
437
|
+
// InitLayerNameSet$.next(getParamsKeySet(full))
|
|
438
|
+
},
|
|
439
|
+
getParams: () => {
|
|
440
|
+
// plugin 本身的 params 在前、各 layer params 在後
|
|
441
|
+
const result: Record<string, any> = Object.assign({}, currentPluginParams)
|
|
442
|
+
layers.forEach((layer) => {
|
|
443
|
+
result[layer._name] = layer._getParams()
|
|
444
|
+
})
|
|
445
|
+
return result as PluginParams | AllLayerParams
|
|
446
|
+
},
|
|
447
|
+
// layer: <LayerName extends keyof PluginParams>(name: LayerName) => ({
|
|
448
|
+
// // set: (partial: DeepPartial<PluginParams[LayerName]>) => {
|
|
449
|
+
// // if (params[name]) {
|
|
450
|
+
// // params[name] = { ...params[name], ...partial }
|
|
451
|
+
// // }
|
|
452
|
+
// // },
|
|
453
|
+
// update: (patch: DeepPartial<PluginParams[LayerName]>) => {
|
|
454
|
+
// if (params[name]) {
|
|
455
|
+
// params[name] = { ...params[name], ...patch }
|
|
456
|
+
// }
|
|
457
|
+
// },
|
|
458
|
+
// replace: (full: PluginParams[LayerName]) => {
|
|
459
|
+
// params[name] = full
|
|
460
|
+
// },
|
|
461
|
+
// show: () => {
|
|
462
|
+
// // implementation for showing this layer
|
|
463
|
+
// },
|
|
464
|
+
// hide: () => {
|
|
465
|
+
// // implementation for hiding this layer
|
|
466
|
+
// },
|
|
467
|
+
// toggle: () => {
|
|
468
|
+
// // implementation for toggling this layer
|
|
469
|
+
// }
|
|
470
|
+
// }),
|
|
471
|
+
destroy: () => {
|
|
472
|
+
destroySetup()
|
|
473
|
+
// subscription.unsubscribe()
|
|
474
|
+
context$.complete()
|
|
475
|
+
// IsShowLayerNameSet$.complete()
|
|
476
|
+
ShownLayerNameSet$.complete()
|
|
477
|
+
|
|
478
|
+
// layers 為本實例專屬,destroy 不影響其他 plugin 實例
|
|
479
|
+
layers.forEach((layer) => {
|
|
480
|
+
layer._destroy()
|
|
481
|
+
})
|
|
482
|
+
},
|
|
483
|
+
// // outputs
|
|
484
|
+
// layers$: new Observable<Record<string, PluginParams>>(subscriber => {
|
|
485
|
+
// subscriber.next(params)
|
|
486
|
+
// })
|
|
487
|
+
}
|
|
488
|
+
}
|