@orbcharts/plugins-basic 3.0.9 → 3.0.11
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/orbcharts-plugins-basic.es.js +5504 -5405
- package/dist/orbcharts-plugins-basic.umd.js +50 -50
- package/package.json +4 -4
- package/src/series/defaults.ts +4 -2
- package/src/series/plugins/Indicator.ts +302 -58
- package/src/series/plugins/Pie.ts +107 -3
- package/src/series/plugins/PieEventTexts.ts +35 -14
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orbcharts/plugins-basic",
|
3
|
-
"version": "3.0.
|
3
|
+
"version": "3.0.11",
|
4
4
|
"description": "Plugins for OrbCharts",
|
5
5
|
"author": "Blue Planet Inc.",
|
6
6
|
"license": "Apache-2.0",
|
@@ -39,9 +39,9 @@
|
|
39
39
|
"vite-plugin-dts": "^3.7.3"
|
40
40
|
},
|
41
41
|
"dependencies": {
|
42
|
-
"@orbcharts/core": "^3.0.
|
43
|
-
"@orbcharts/core-types": "^3.0.
|
44
|
-
"@orbcharts/plugins-basic-types": "^3.0.
|
42
|
+
"@orbcharts/core": "^3.0.7",
|
43
|
+
"@orbcharts/core-types": "^3.0.5",
|
44
|
+
"@orbcharts/plugins-basic-types": "^3.0.5",
|
45
45
|
"d3": "^7.8.5",
|
46
46
|
"rxjs": "^7.8.1"
|
47
47
|
}
|
package/src/series/defaults.ts
CHANGED
@@ -230,7 +230,9 @@ export const DEFAULT_INDICATOR_PARAMS: IndicatorParams = {
|
|
230
230
|
startAngle: - Math.PI / 2,
|
231
231
|
endAngle: Math.PI / 2,
|
232
232
|
radius: 0.6,
|
233
|
-
|
233
|
+
indicatorType: 'needle',
|
234
|
+
size: 10,
|
234
235
|
colorType: 'label',
|
235
|
-
|
236
|
+
// autoHighlight: false,
|
237
|
+
value: 0,
|
236
238
|
}
|
@@ -2,17 +2,22 @@ import * as d3 from 'd3'
|
|
2
2
|
import {
|
3
3
|
combineLatest,
|
4
4
|
switchMap,
|
5
|
+
mergeMap,
|
6
|
+
mergeWith,
|
7
|
+
concatMap,
|
5
8
|
first,
|
9
|
+
filter,
|
6
10
|
map,
|
7
11
|
takeUntil,
|
8
12
|
Observable,
|
9
13
|
distinctUntilChanged,
|
10
14
|
Subject,
|
11
15
|
BehaviorSubject } from 'rxjs'
|
12
|
-
import type { DefinePluginConfig } from '../../../lib/core-types'
|
16
|
+
import type { ContextSubject, DefinePluginConfig } from '../../../lib/core-types'
|
13
17
|
import {
|
14
18
|
defineSeriesPlugin } from '../../../lib/core'
|
15
19
|
import type {
|
20
|
+
ComputedDataSeries,
|
16
21
|
ComputedDatumSeries,
|
17
22
|
ContainerPosition,
|
18
23
|
EventSeries,
|
@@ -23,16 +28,33 @@ import type { IndicatorParams } from '../../../lib/plugins-basic-types'
|
|
23
28
|
import { DEFAULT_INDICATOR_PARAMS } from '../defaults'
|
24
29
|
import { getDatumColor, getClassName } from '../../utils/orbchartsUtils'
|
25
30
|
import { seriesCenterSelectionObservable } from '../seriesObservables'
|
26
|
-
import {
|
31
|
+
import { LAYER_INDEX_OF_GRAPHIC_COVER } from '../../const'
|
32
|
+
|
33
|
+
interface RenderParams {
|
34
|
+
containerSelection: d3.Selection<SVGGElement, any, any, unknown>
|
35
|
+
angle: number
|
36
|
+
value: number
|
37
|
+
datum: ComputedDatumSeries | null
|
38
|
+
computedData: ComputedDataSeries
|
39
|
+
SeriesDataMap: Map<string, ComputedDatumSeries[]>
|
40
|
+
pointerDistance: number
|
41
|
+
fullParams: IndicatorParams
|
42
|
+
fullChartParams: ChartParams
|
43
|
+
graphicColor: string
|
44
|
+
event$: Subject<EventSeries>
|
45
|
+
}
|
27
46
|
|
28
47
|
const pluginName = 'Indicator'
|
29
48
|
const indicatorGClassName = getClassName(pluginName, 'indicator-g')
|
30
49
|
const triangleGClassName = getClassName(pluginName, 'triangle-g')
|
50
|
+
const lineGClassName = getClassName(pluginName, 'line-g')
|
51
|
+
const needleGClassName = getClassName(pluginName, 'needle-g')
|
52
|
+
const pinGClassName = getClassName(pluginName, 'pin-g')
|
31
53
|
|
32
54
|
const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_INDICATOR_PARAMS> = {
|
33
55
|
name: pluginName,
|
34
56
|
defaultParams: DEFAULT_INDICATOR_PARAMS,
|
35
|
-
layerIndex:
|
57
|
+
layerIndex: LAYER_INDEX_OF_GRAPHIC_COVER,
|
36
58
|
validator: (params, { validateColumns }) => {
|
37
59
|
const result = validateColumns(params, {
|
38
60
|
startAngle: {
|
@@ -44,12 +66,19 @@ const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_INDICAT
|
|
44
66
|
radius: {
|
45
67
|
toBeTypes: ['number'],
|
46
68
|
},
|
69
|
+
indicatorType: {
|
70
|
+
toBe: '"line" | "needle" | "pin" | "triangle"',
|
71
|
+
test: (value: any) => ['line', 'needle', 'pin', 'triangle'].includes(value)
|
72
|
+
},
|
47
73
|
size: {
|
48
74
|
toBeTypes: ['number'],
|
49
75
|
},
|
50
76
|
colorType: {
|
51
77
|
toBeOption: 'ColorType'
|
52
78
|
},
|
79
|
+
// autoHighlight: {
|
80
|
+
// toBeTypes: ['boolean'],
|
81
|
+
// },
|
53
82
|
value: {
|
54
83
|
toBeTypes: ['number'],
|
55
84
|
},
|
@@ -58,15 +87,17 @@ const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_INDICAT
|
|
58
87
|
}
|
59
88
|
}
|
60
89
|
|
61
|
-
function
|
90
|
+
function createIndicatorG({ containerSelection, angle, datum, value, computedData, SeriesDataMap, fullParams, fullChartParams, event$ }: {
|
62
91
|
containerSelection: d3.Selection<SVGGElement, any, any, unknown>
|
63
92
|
angle: number
|
64
|
-
|
93
|
+
datum: ComputedDatumSeries | null
|
94
|
+
value: number
|
95
|
+
computedData: ComputedDataSeries
|
96
|
+
SeriesDataMap: Map<string, ComputedDatumSeries[]>
|
65
97
|
fullParams: IndicatorParams
|
66
98
|
fullChartParams: ChartParams
|
67
|
-
|
99
|
+
event$: Subject<EventSeries>
|
68
100
|
}) {
|
69
|
-
|
70
101
|
const indicatorG = containerSelection.selectAll(`g.${indicatorGClassName}`)
|
71
102
|
.data([angle])
|
72
103
|
.join(
|
@@ -77,11 +108,56 @@ function renderIndicatorTriangle ({ containerSelection, angle, pointerDistance,
|
|
77
108
|
exit => exit.remove()
|
78
109
|
)
|
79
110
|
|
80
|
-
indicatorG
|
111
|
+
const transitionG = indicatorG
|
81
112
|
.transition()
|
82
113
|
.duration(fullChartParams.transitionDuration)
|
83
114
|
.attr('transform', `rotate(${angle})`)
|
84
115
|
|
116
|
+
const series = SeriesDataMap.get(datum.seriesLabel)!
|
117
|
+
|
118
|
+
// work around(暫時使用這個方式來共享value)
|
119
|
+
transitionG
|
120
|
+
.tween('move', (self, t) => {
|
121
|
+
return (t) => {
|
122
|
+
event$.next({
|
123
|
+
type: 'series',
|
124
|
+
pluginName,
|
125
|
+
eventName: 'transitionMove',
|
126
|
+
event: undefined,
|
127
|
+
highlightTarget: fullChartParams.highlightTarget,
|
128
|
+
datum: datum,
|
129
|
+
series: series,
|
130
|
+
seriesIndex: datum.seriesIndex,
|
131
|
+
seriesLabel: datum.seriesLabel,
|
132
|
+
data: computedData,
|
133
|
+
mark: value, // work around
|
134
|
+
tween: t
|
135
|
+
})
|
136
|
+
}
|
137
|
+
})
|
138
|
+
.on('end', (self, t) => {
|
139
|
+
event$.next({
|
140
|
+
type: 'series',
|
141
|
+
pluginName,
|
142
|
+
eventName: 'transitionEnd',
|
143
|
+
event: undefined,
|
144
|
+
highlightTarget: fullChartParams.highlightTarget,
|
145
|
+
datum: datum,
|
146
|
+
series: series,
|
147
|
+
seriesIndex: datum.seriesIndex,
|
148
|
+
seriesLabel: datum.seriesLabel,
|
149
|
+
data: computedData,
|
150
|
+
mark: value // work around
|
151
|
+
})
|
152
|
+
})
|
153
|
+
|
154
|
+
return indicatorG
|
155
|
+
}
|
156
|
+
|
157
|
+
function renderIndicatorTriangle ({ containerSelection, angle, value, datum, computedData, SeriesDataMap, pointerDistance, fullParams, fullChartParams, graphicColor, event$ }: RenderParams) {
|
158
|
+
|
159
|
+
const indicatorG = createIndicatorG({ containerSelection, angle, value, datum, computedData, SeriesDataMap, fullParams, fullChartParams, event$ })
|
160
|
+
|
85
161
|
indicatorG
|
86
162
|
.selectAll(`g.${triangleGClassName}`)
|
87
163
|
.data([pointerDistance])
|
@@ -98,16 +174,96 @@ function renderIndicatorTriangle ({ containerSelection, angle, pointerDistance,
|
|
98
174
|
.attr('fill', graphicColor)
|
99
175
|
}
|
100
176
|
|
177
|
+
function renderIndicatorLine ({ containerSelection, angle, value, datum, computedData, SeriesDataMap, pointerDistance, fullParams, fullChartParams, graphicColor, event$ }: RenderParams) {
|
178
|
+
const indicatorG = createIndicatorG({ containerSelection, angle, value, datum, computedData, SeriesDataMap, fullParams, fullChartParams, event$ })
|
179
|
+
|
180
|
+
indicatorG
|
181
|
+
.selectAll(`g.${lineGClassName}`)
|
182
|
+
.data([pointerDistance])
|
183
|
+
.join('g')
|
184
|
+
.attr('class', lineGClassName)
|
185
|
+
.selectAll('rect')
|
186
|
+
.data([fullParams.size])
|
187
|
+
.join('rect')
|
188
|
+
.attr('x', -fullParams.size / 2) // 水平置中
|
189
|
+
.attr('y', -pointerDistance) // 從中心向上延伸
|
190
|
+
.attr('width', fullParams.size) // 寬度為 size
|
191
|
+
.attr('height', pointerDistance) // 長度為 pointerDistance
|
192
|
+
.attr('fill', graphicColor)
|
193
|
+
}
|
194
|
+
|
195
|
+
function renderIndicatorNeedle ({ containerSelection, angle, value, datum, computedData, SeriesDataMap, pointerDistance, fullParams, fullChartParams, graphicColor, event$ }: RenderParams) {
|
196
|
+
const indicatorG = createIndicatorG({ containerSelection, angle, value, datum, computedData, SeriesDataMap, fullParams, fullChartParams, event$ })
|
197
|
+
|
198
|
+
indicatorG
|
199
|
+
.selectAll(`g.${needleGClassName}`)
|
200
|
+
.data([pointerDistance])
|
201
|
+
.join('g')
|
202
|
+
.attr('class', needleGClassName)
|
203
|
+
.selectAll('path')
|
204
|
+
.data([fullParams.size])
|
205
|
+
.join('path')
|
206
|
+
.attr('d', () => {
|
207
|
+
const width = fullParams.size
|
208
|
+
|
209
|
+
// 建構4角菱形路徑
|
210
|
+
const points = [
|
211
|
+
[0, -pointerDistance], // 頂點(針尖)
|
212
|
+
[width / 2, 0], // 右側最寬點
|
213
|
+
[0, width / 2], // 尾部
|
214
|
+
[-width / 2, 0] // 左側最寬點
|
215
|
+
]
|
216
|
+
|
217
|
+
return `M${points.map(p => p.join(',')).join('L')}Z`
|
218
|
+
})
|
219
|
+
.attr('fill', graphicColor)
|
220
|
+
}
|
221
|
+
|
222
|
+
function renderIndicatorPin ({ containerSelection, angle, value, datum, computedData, SeriesDataMap, pointerDistance, fullParams, fullChartParams, graphicColor, event$ }: RenderParams) {
|
223
|
+
const indicatorG = createIndicatorG({ containerSelection, angle, value, datum, computedData, SeriesDataMap, fullParams, fullChartParams, event$ })
|
224
|
+
|
225
|
+
const pinG = indicatorG
|
226
|
+
.selectAll(`g.${pinGClassName}`)
|
227
|
+
.data([pointerDistance])
|
228
|
+
.join('g')
|
229
|
+
.attr('class', pinGClassName)
|
230
|
+
|
231
|
+
// 繪製大頭針的針身(細線)- 從中心向外延伸
|
232
|
+
pinG
|
233
|
+
.selectAll('line.pin-shaft')
|
234
|
+
.data([1])
|
235
|
+
.join('line')
|
236
|
+
.attr('class', 'pin-shaft')
|
237
|
+
.attr('x1', 0)
|
238
|
+
.attr('y1', 0) // 從中心開始
|
239
|
+
.attr('x2', 0)
|
240
|
+
.attr('y2', -pointerDistance) // 向外延伸到 pointerDistance
|
241
|
+
.attr('stroke', graphicColor)
|
242
|
+
.attr('stroke-width', Math.min(fullParams.size * 0.2, 2)) // 針身較細
|
243
|
+
.attr('stroke-linecap', 'round')
|
244
|
+
|
245
|
+
// 繪製大頭針的頭部(圓形)- 放在中心位置
|
246
|
+
pinG
|
247
|
+
.selectAll('circle.pin-head')
|
248
|
+
.data([fullParams.size])
|
249
|
+
.join('circle')
|
250
|
+
.attr('class', 'pin-head')
|
251
|
+
.attr('cx', 0)
|
252
|
+
.attr('cy', 0) // 頭部在中心
|
253
|
+
.attr('r', fullParams.size / 2) // 頭部半徑為 size 的一半
|
254
|
+
.attr('fill', graphicColor)
|
255
|
+
}
|
256
|
+
|
101
257
|
function createEachGraphic (pluginName: string, context: {
|
102
258
|
containerSelection: d3.Selection<SVGGElement, any, any, unknown>
|
103
|
-
|
259
|
+
renderFn: (params: RenderParams) => void
|
104
260
|
containerVisibleComputedSortedData$: Observable<ComputedDatumSeries[]>
|
105
|
-
// SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
|
106
261
|
fullParams$: Observable<IndicatorParams>
|
107
262
|
fullChartParams$: Observable<ChartParams>
|
108
|
-
// textSizePx$: Observable<number>
|
109
|
-
// seriesHighlight$: Observable<ComputedDatumSeries[]>
|
110
263
|
seriesContainerPosition$: Observable<ContainerPosition>
|
264
|
+
computedData$: Observable<ComputedDatumSeries[][]>
|
265
|
+
SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
|
266
|
+
subject: ContextSubject<"series">
|
111
267
|
event$: Subject<EventSeries>
|
112
268
|
}) {
|
113
269
|
const destroy$ = new Subject()
|
@@ -119,7 +275,7 @@ function createEachGraphic (pluginName: string, context: {
|
|
119
275
|
distinctUntilChanged()
|
120
276
|
)
|
121
277
|
|
122
|
-
const
|
278
|
+
const valueToAngleScale$ = combineLatest({
|
123
279
|
fullParams: context.fullParams$,
|
124
280
|
containerValueSum: containerValueSum$,
|
125
281
|
}).pipe(
|
@@ -138,11 +294,14 @@ function createEachGraphic (pluginName: string, context: {
|
|
138
294
|
|
139
295
|
const angle$ = combineLatest({
|
140
296
|
value: value$,
|
141
|
-
|
297
|
+
valueToAngleScale: valueToAngleScale$,
|
298
|
+
containerValueSum: containerValueSum$,
|
142
299
|
}).pipe(
|
143
300
|
switchMap(async d => d),
|
144
|
-
map(({ value,
|
145
|
-
|
301
|
+
map(({ value, valueToAngleScale, containerValueSum }) => {
|
302
|
+
// value 限制在 0 ~ containerValueSum 之間
|
303
|
+
const validValue = Math.max(Math.min(value, containerValueSum), 0)
|
304
|
+
return valueToAngleScale(validValue)
|
146
305
|
}),
|
147
306
|
distinctUntilChanged()
|
148
307
|
)
|
@@ -162,30 +321,38 @@ function createEachGraphic (pluginName: string, context: {
|
|
162
321
|
)
|
163
322
|
|
164
323
|
// indicator 的 value 對應到 data 區間
|
165
|
-
const
|
324
|
+
const datum$ = combineLatest({
|
166
325
|
value: value$,
|
167
326
|
containerVisibleComputedSortedData: context.containerVisibleComputedSortedData$,
|
168
327
|
}).pipe(
|
169
328
|
switchMap(async d => d),
|
170
329
|
map(({ value, containerVisibleComputedSortedData }) => {
|
171
|
-
let
|
330
|
+
// let seriesIndex = 0
|
331
|
+
let datum: ComputedDatumSeries | null = null
|
172
332
|
let stackedValue = 0
|
173
333
|
for (let i = 0; i < containerVisibleComputedSortedData.length; i++) {
|
174
334
|
const datumValue = containerVisibleComputedSortedData[i].value ?? 0
|
175
335
|
stackedValue += datumValue
|
176
336
|
if (stackedValue >= value) {
|
177
|
-
|
337
|
+
// seriesIndex = containerVisibleComputedSortedData[i].seriesIndex
|
338
|
+
datum = containerVisibleComputedSortedData[i]
|
178
339
|
break
|
179
340
|
}
|
341
|
+
if (i === containerVisibleComputedSortedData.length - 1) {
|
342
|
+
// seriesIndex = containerVisibleComputedSortedData[i].seriesIndex
|
343
|
+
datum = containerVisibleComputedSortedData[i]
|
344
|
+
}
|
180
345
|
}
|
181
|
-
return
|
346
|
+
return datum
|
182
347
|
}),
|
183
348
|
distinctUntilChanged()
|
184
349
|
)
|
185
350
|
|
186
351
|
const graphicColor$ = combineLatest({
|
187
352
|
value: value$,
|
188
|
-
|
353
|
+
valueSeriesIndex: datum$.pipe(
|
354
|
+
map(d => d ? d.seriesIndex : 0),
|
355
|
+
),
|
189
356
|
// containerVisibleComputedSortedData: context.containerVisibleComputedSortedData$,
|
190
357
|
fullParams: context.fullParams$,
|
191
358
|
fullChartParams: context.fullChartParams$,
|
@@ -193,7 +360,7 @@ function createEachGraphic (pluginName: string, context: {
|
|
193
360
|
switchMap(async d => d),
|
194
361
|
map(data => {
|
195
362
|
const labelColor = data.fullParams.colorType === 'label'
|
196
|
-
? data.fullChartParams.colors[data.fullChartParams.colorScheme].label[data.
|
363
|
+
? data.fullChartParams.colors[data.fullChartParams.colorScheme].label[data.valueSeriesIndex]
|
197
364
|
: '' // 忽略
|
198
365
|
|
199
366
|
const datum: ComputedDatumBaseSeries = {
|
@@ -211,20 +378,71 @@ function createEachGraphic (pluginName: string, context: {
|
|
211
378
|
distinctUntilChanged()
|
212
379
|
)
|
213
380
|
|
381
|
+
// 紀錄目前的 chartParams
|
382
|
+
let chartParamsRef: ChartParams | null = null
|
383
|
+
context.fullChartParams$
|
384
|
+
.pipe(takeUntil(destroy$))
|
385
|
+
.subscribe(params => {
|
386
|
+
chartParamsRef = params
|
387
|
+
})
|
388
|
+
|
389
|
+
// const newDefaultHighlight$ = combineLatest({
|
390
|
+
// datum: datum$,
|
391
|
+
// fullChartParams: context.fullChartParams$,
|
392
|
+
// }).pipe(
|
393
|
+
// switchMap(async d => d),
|
394
|
+
// map(data => {
|
395
|
+
// return data.fullChartParams.highlightTarget === 'datum'
|
396
|
+
// ? data.datum.id
|
397
|
+
// : data.fullChartParams.highlightTarget === 'series'
|
398
|
+
// ? data.datum.seriesLabel
|
399
|
+
// : null
|
400
|
+
// }),
|
401
|
+
// distinctUntilChanged()
|
402
|
+
// )
|
403
|
+
|
404
|
+
// autoHighlight
|
405
|
+
// context.fullParams$.pipe(
|
406
|
+
// map(params => params.autoHighlight),
|
407
|
+
// filter(autoHighlight => autoHighlight === true),
|
408
|
+
// mergeWith(context.event$.pipe(
|
409
|
+
// filter(event => event.eventName === 'mouseout'),
|
410
|
+
// )),
|
411
|
+
// switchMap(() => newDefaultHighlight$),
|
412
|
+
// takeUntil(destroy$),
|
413
|
+
// ).subscribe(newDefaultHighlight => {
|
414
|
+
// if (!newDefaultHighlight) {
|
415
|
+
// return
|
416
|
+
// }
|
417
|
+
// context.subject.chartParams$.next({
|
418
|
+
// ...chartParamsRef,
|
419
|
+
// highlightDefault: newDefaultHighlight
|
420
|
+
// })
|
421
|
+
// })
|
422
|
+
|
214
423
|
combineLatest({
|
215
424
|
fullParams: context.fullParams$,
|
216
425
|
fullChartParams: context.fullChartParams$,
|
217
426
|
angle: angle$,
|
218
427
|
pointerDistance: pointerDistance$,
|
219
428
|
graphicColor: graphicColor$,
|
429
|
+
value: value$,
|
430
|
+
datum: datum$,
|
431
|
+
computedData: context.computedData$,
|
432
|
+
SeriesDataMap: context.SeriesDataMap$,
|
220
433
|
}).subscribe(data => {
|
221
|
-
|
434
|
+
context.renderFn({
|
222
435
|
containerSelection: context.containerSelection,
|
223
436
|
angle: data.angle,
|
437
|
+
value: data.fullParams.value,
|
438
|
+
datum: data.datum,
|
439
|
+
computedData: data.computedData,
|
440
|
+
SeriesDataMap: data.SeriesDataMap,
|
224
441
|
pointerDistance: data.pointerDistance,
|
225
442
|
fullParams: data.fullParams,
|
226
443
|
fullChartParams: data.fullChartParams,
|
227
444
|
graphicColor: data.graphicColor,
|
445
|
+
event$: context.event$
|
228
446
|
})
|
229
447
|
})
|
230
448
|
|
@@ -236,7 +454,15 @@ function createEachGraphic (pluginName: string, context: {
|
|
236
454
|
|
237
455
|
|
238
456
|
export const Indicator = defineSeriesPlugin(pluginConfig)(({ selection, observer, subject }) => {
|
239
|
-
|
457
|
+
subject.plugins$
|
458
|
+
// .pipe(
|
459
|
+
// map(plugins => plugins.find(p => p.name === 'Indicator')),
|
460
|
+
// filter(p => !!p),
|
461
|
+
// switchMap(p => p.params$)
|
462
|
+
// )
|
463
|
+
.subscribe(params => {
|
464
|
+
console.log('Indicator params', params)
|
465
|
+
})
|
240
466
|
const destroy$ = new Subject()
|
241
467
|
|
242
468
|
const { seriesCenterSelection$ } = seriesCenterSelectionObservable({
|
@@ -248,43 +474,61 @@ export const Indicator = defineSeriesPlugin(pluginConfig)(({ selection, observer
|
|
248
474
|
|
249
475
|
const unsubscribeFnArr: (() => void)[] = []
|
250
476
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
)
|
267
|
-
|
268
|
-
const containerPosition$ = observer.seriesContainerPosition$.pipe(
|
269
|
-
takeUntil(destroy$),
|
270
|
-
map(data => data[containerIndex] ?? data[0])
|
271
|
-
)
|
272
|
-
|
273
|
-
unsubscribeFnArr[containerIndex] = createEachGraphic(pluginName, {
|
274
|
-
containerSelection: containerSelection,
|
275
|
-
// computedData$: observer.computedData$,
|
276
|
-
containerVisibleComputedSortedData$: containerVisibleComputedSortedData$,
|
277
|
-
// SeriesDataMap$: observer.SeriesDataMap$,
|
278
|
-
fullParams$: observer.fullParams$,
|
279
|
-
fullChartParams$: observer.fullChartParams$,
|
280
|
-
// textSizePx$: observer.textSizePx$,
|
281
|
-
// seriesHighlight$: observer.seriesHighlight$,
|
282
|
-
seriesContainerPosition$: containerPosition$,
|
283
|
-
event$: subject.event$,
|
284
|
-
})
|
477
|
+
const renderFn$ = observer.fullParams$.pipe(
|
478
|
+
map(params => {
|
479
|
+
if (params.indicatorType === 'triangle') {
|
480
|
+
return renderIndicatorTriangle
|
481
|
+
} else if (params.indicatorType === 'line') {
|
482
|
+
return renderIndicatorLine
|
483
|
+
} else if (params.indicatorType === 'needle') {
|
484
|
+
return renderIndicatorNeedle
|
485
|
+
} else if (params.indicatorType === 'pin') {
|
486
|
+
return renderIndicatorPin
|
487
|
+
} else {
|
488
|
+
return renderIndicatorTriangle
|
489
|
+
}
|
490
|
+
}),
|
491
|
+
)
|
285
492
|
|
493
|
+
combineLatest({
|
494
|
+
seriesCenterSelection: seriesCenterSelection$,
|
495
|
+
renderFn: renderFn$,
|
496
|
+
}).pipe(
|
497
|
+
switchMap(async d => d),
|
498
|
+
takeUntil(destroy$)
|
499
|
+
).subscribe(data => {
|
500
|
+
// 每次重新計算時,清除之前的訂閱
|
501
|
+
unsubscribeFnArr.forEach(fn => fn())
|
502
|
+
|
503
|
+
data.seriesCenterSelection.each((d, containerIndex, g) => {
|
504
|
+
|
505
|
+
const containerSelection = d3.select(g[containerIndex])
|
506
|
+
|
507
|
+
const containerVisibleComputedSortedData$ = observer.visibleComputedSortedData$.pipe(
|
508
|
+
takeUntil(destroy$),
|
509
|
+
map(data => data[containerIndex] ?? data[0])
|
510
|
+
)
|
511
|
+
|
512
|
+
const containerPosition$ = observer.seriesContainerPosition$.pipe(
|
513
|
+
takeUntil(destroy$),
|
514
|
+
map(data => data[containerIndex] ?? data[0])
|
515
|
+
)
|
516
|
+
|
517
|
+
unsubscribeFnArr[containerIndex] = createEachGraphic(pluginName, {
|
518
|
+
containerSelection: containerSelection,
|
519
|
+
renderFn: data.renderFn,
|
520
|
+
containerVisibleComputedSortedData$: containerVisibleComputedSortedData$,
|
521
|
+
fullParams$: observer.fullParams$,
|
522
|
+
fullChartParams$: observer.fullChartParams$,
|
523
|
+
seriesContainerPosition$: containerPosition$,
|
524
|
+
computedData$: observer.computedData$,
|
525
|
+
SeriesDataMap$: observer.SeriesDataMap$,
|
526
|
+
subject,
|
527
|
+
event$: subject.event$,
|
286
528
|
})
|
529
|
+
|
287
530
|
})
|
531
|
+
})
|
288
532
|
|
289
533
|
return () => {
|
290
534
|
destroy$.next(undefined)
|