@orbcharts/plugins-basic 3.0.0-alpha.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. package/LICENSE +201 -0
  2. package/package.json +41 -0
  3. package/src/grid/defaults.ts +95 -0
  4. package/src/grid/gridObservables.ts +114 -0
  5. package/src/grid/index.ts +12 -0
  6. package/src/grid/plugins/BarStack.ts +661 -0
  7. package/src/grid/plugins/Bars.ts +604 -0
  8. package/src/grid/plugins/BarsTriangle.ts +594 -0
  9. package/src/grid/plugins/Dots.ts +427 -0
  10. package/src/grid/plugins/GroupArea.ts +636 -0
  11. package/src/grid/plugins/GroupAxis.ts +363 -0
  12. package/src/grid/plugins/Lines.ts +528 -0
  13. package/src/grid/plugins/Ranking.ts +0 -0
  14. package/src/grid/plugins/RankingAxis.ts +0 -0
  15. package/src/grid/plugins/ScalingArea.ts +168 -0
  16. package/src/grid/plugins/ValueAxis.ts +356 -0
  17. package/src/grid/plugins/ValueStackAxis.ts +372 -0
  18. package/src/grid/types.ts +102 -0
  19. package/src/index.ts +7 -0
  20. package/src/multiGrid/index.ts +0 -0
  21. package/src/multiGrid/plugins/Diverging.ts +0 -0
  22. package/src/multiGrid/plugins/DivergingAxes.ts +0 -0
  23. package/src/multiGrid/plugins/TwoScaleAxes.ts +0 -0
  24. package/src/multiGrid/plugins/TwoScales.ts +0 -0
  25. package/src/multiValue/index.ts +0 -0
  26. package/src/multiValue/plugins/Scatter.ts +0 -0
  27. package/src/multiValue/plugins/ScatterAxes.ts +0 -0
  28. package/src/noneData/defaults.ts +47 -0
  29. package/src/noneData/index.ts +4 -0
  30. package/src/noneData/plugins/Container.ts +11 -0
  31. package/src/noneData/plugins/Tooltip.ts +305 -0
  32. package/src/noneData/types.ts +26 -0
  33. package/src/relationship/index.ts +0 -0
  34. package/src/relationship/plugins/Relationship.ts +0 -0
  35. package/src/series/defaults.ts +82 -0
  36. package/src/series/index.ts +6 -0
  37. package/src/series/plugins/Bubbles.ts +553 -0
  38. package/src/series/plugins/Pie.ts +603 -0
  39. package/src/series/plugins/PieEventTexts.ts +194 -0
  40. package/src/series/plugins/PieLabels.ts +289 -0
  41. package/src/series/plugins/Waffle.ts +0 -0
  42. package/src/series/seriesUtils.ts +51 -0
  43. package/src/series/types.ts +53 -0
  44. package/src/tree/index.ts +0 -0
  45. package/src/tree/plugins/TreeMap.ts +0 -0
  46. package/src/utils/commonUtils.ts +22 -0
  47. package/src/utils/d3Graphics.ts +125 -0
  48. package/src/utils/d3Utils.ts +73 -0
  49. package/src/utils/observables.ts +14 -0
  50. package/src/utils/orbchartsUtils.ts +70 -0
  51. package/tsconfig.json +14 -0
  52. package/vite.config.js +45 -0
@@ -0,0 +1,594 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ combineLatest,
4
+ switchMap,
5
+ map,
6
+ first,
7
+ takeUntil,
8
+ distinctUntilChanged,
9
+ Subject,
10
+ Observable } from 'rxjs'
11
+ // import type { Subject } from 'rxjs'
12
+ import { defineGridPlugin } from '@orbcharts/core'
13
+ import type {
14
+ ComputedDatumGrid,
15
+ EventSeries,
16
+ ChartParams,
17
+ DataSeriesDatum,
18
+ Layout } from '@orbcharts/core'
19
+ import type { BarsTrianglePluginParams } from '../types'
20
+ import { DEFAULT_BARS_TRIANGLE_PLUGIN_PARAMS } from '../defaults'
21
+ import { getD3TransitionEase } from '../../utils/d3Utils'
22
+ import {
23
+ getClassName,
24
+ getUniID } from '../../utils/orbchartsUtils'
25
+
26
+ interface RenderBarParams {
27
+ selection: d3.Selection<SVGGElement, unknown, any, any>
28
+ barData: BarDatumGrid[][]
29
+ zeroY: number
30
+ groupLabels: string[]
31
+ barScale: d3.ScalePoint<string>
32
+ params: BarsTrianglePluginParams
33
+ chartParams: ChartParams
34
+ barWidth: number
35
+ delayGroup: number
36
+ transitionItem: number
37
+ }
38
+
39
+ interface BarDatumGrid extends ComputedDatumGrid {
40
+ linearGradientId: string
41
+ }
42
+
43
+ type ClipPathDatum = {
44
+ id: string;
45
+ // x: number;
46
+ // y: number;
47
+ width: number;
48
+ height: number;
49
+ }
50
+
51
+ const pluginName = 'BarsTriangle'
52
+ const gClassName = getClassName(pluginName, 'g')
53
+ const gContentClassName = getClassName(pluginName, 'g-content')
54
+ // group的delay在動畫中的佔比(剩餘部份的時間為圖形本身的動畫時間,因為delay時間和最後一個group的動畫時間加總為1)
55
+ const groupDelayProportionOfDuration = 0.3
56
+
57
+ function calcBarWidth ({ axisWidth, groupAmount, barAmountOfGroup, barPadding = 0, barGroupPadding = 0 }: {
58
+ axisWidth: number
59
+ groupAmount: number
60
+ barAmountOfGroup: number
61
+ barPadding: number
62
+ barGroupPadding: number
63
+ }) {
64
+ const width = (axisWidth / groupAmount - barGroupPadding) / barAmountOfGroup - barPadding
65
+ return width > 1 ? width : 1
66
+ }
67
+
68
+ function makeBarScale (barWidth: number, seriesLabels: string[], params: BarsTrianglePluginParams) {
69
+ const barHalfWidth = barWidth! / 2
70
+ const barGroupWidth = barWidth * seriesLabels.length + params.barPadding! * seriesLabels.length
71
+ return d3.scalePoint()
72
+ .domain(seriesLabels)
73
+ .range([-barGroupWidth / 2 + barHalfWidth, barGroupWidth / 2 - barHalfWidth])
74
+ }
75
+
76
+ function calcDelayGroup (barGroupAmount: number, totalDuration: number) {
77
+ if (barGroupAmount <= 1) {
78
+ // 一筆內計算會出錯所以不算
79
+ return 0
80
+ }
81
+ return totalDuration / (barGroupAmount - 1) * groupDelayProportionOfDuration // 依group數量計算
82
+ }
83
+
84
+ function calctransitionItem (barGroupAmount: number, totalDuration: number) {
85
+ if (barGroupAmount <= 1) {
86
+ // 一筆內不會有delay
87
+ return totalDuration
88
+ }
89
+ return totalDuration * (1 - groupDelayProportionOfDuration) // delay後剩餘的時間
90
+ }
91
+
92
+ function renderTriangleBars ({ selection, barData, zeroY, groupLabels, barScale, params, chartParams, barWidth, delayGroup, transitionItem }: RenderBarParams) {
93
+ // console.log({ selection, data, zeroY, seriesLabels, barScale, params, chartParams, barWidth, delayGroup })
94
+ // if (barWidth <= 0) {
95
+ // return
96
+ // }
97
+ const update = selection!
98
+ .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${gClassName}`)
99
+ .data(barData, (d, i) => groupLabels[i])
100
+ const enter = update.enter()
101
+ .append('g')
102
+ .classed(gClassName, true)
103
+ .attr('cursor', 'pointer')
104
+ update.exit().remove()
105
+ const graphicGroupSelection = update.merge(enter)
106
+ enter
107
+ .attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
108
+ update
109
+ // .transition()
110
+ // .duration(200)
111
+ .attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
112
+
113
+ const barHalfWidth = barWidth! / 2
114
+
115
+ graphicGroupSelection
116
+ .each((d, i, g) => {
117
+ const pathUpdate = d3.select(g[i])
118
+ .selectAll<SVGGElement, ComputedDatumGrid>('g')
119
+ .data(d, _d => _d.id)
120
+ const pathEnter = pathUpdate
121
+ .enter()
122
+ .append('g')
123
+ .classed(gContentClassName, true)
124
+ pathEnter
125
+ .append('path')
126
+ // .attr('transform', `translate(${-barHalfWidth}, 0)`)
127
+ // .attr('x', d => itemScale(d.itemLabel)!)
128
+ // .attr('y', d => 0)
129
+ .style('vector-effect', 'non-scaling-stroke')
130
+ .attr('height', d => 0)
131
+ .attr('d', (d) => {
132
+ const x = barScale(d.seriesLabel)!
133
+ const y1 = zeroY
134
+ const y2 = y1
135
+ return `M${x - (barWidth! / 2)},${y1} L${x},${y2} ${x + (barWidth! / 2)},${y1}`
136
+ })
137
+ pathUpdate.merge(pathEnter)
138
+ .select('path')
139
+ .style('fill', d => `url(#${d.linearGradientId})`)
140
+ .attr('stroke', d => d.color)
141
+ .attr('transform', `translate(${-barHalfWidth}, 0)`)
142
+ .transition()
143
+ .duration(transitionItem)
144
+ .ease(getD3TransitionEase(chartParams.transitionEase))
145
+ .delay((d, i) => d.groupIndex * delayGroup)
146
+ .attr('transform', `translate(${-barHalfWidth}, 0)`)
147
+ // .attr('x', d => itemScale(d.itemLabel)!)
148
+ // .attr('y', d => -d.y)
149
+ .attr('height', d => Math.abs(d.axisYFromZero))
150
+ .attr('d', (d) => {
151
+ const x = barScale(d.seriesLabel)!
152
+ const y1 = zeroY
153
+ const y2 = d.axisY
154
+ return `M${x},${y1} L${x + (barWidth! / 2)},${y2} ${x + barWidth!},${y1}`
155
+ })
156
+ // .on('end', () => initHighlight())
157
+ pathUpdate.exit().remove()
158
+ })
159
+
160
+ const graphicBarSelection: d3.Selection<SVGPathElement, ComputedDatumGrid, any, any> = graphicGroupSelection.selectAll(`g.${gContentClassName}`)
161
+
162
+ return graphicBarSelection
163
+ }
164
+
165
+ function renderLinearGradient ({ defsSelection, barData, params }: {
166
+ defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any>
167
+ barData: BarDatumGrid[][]
168
+ params: BarsTrianglePluginParams
169
+ }) {
170
+ const linearGradientUpdate = defsSelection!
171
+ .selectAll<SVGLinearGradientElement, ComputedDatumGrid>('linearGradient')
172
+ .data(barData[0] ?? [], d => d.seriesLabel)
173
+ const linearGradientEnter = linearGradientUpdate
174
+ .enter()
175
+ .append('linearGradient')
176
+ .attr('x1', '0%')
177
+ .attr('x2', '0%')
178
+ .attr('y1', '100%')
179
+ .attr('y2', '0%')
180
+ .attr('spreadMethod', 'pad')
181
+ linearGradientUpdate.merge(linearGradientEnter)
182
+ .attr('id', (d, i) => d.linearGradientId)
183
+ .html((d, i) => `
184
+ <stop offset="0%" stop-color="${d.color}" stop-opacity="${params.linearGradientOpacity[0]}"/>
185
+ <stop offset="100%" stop-color="${d.color}" stop-opacity="${params.linearGradientOpacity[1]}"/>
186
+ `)
187
+ linearGradientUpdate.exit().remove()
188
+ }
189
+
190
+
191
+ function renderClipPath ({ defsSelection, clipPathData }: {
192
+ defsSelection: d3.Selection<SVGDefsElement, any, any, any>
193
+ clipPathData: ClipPathDatum[]
194
+ }) {
195
+ const update = defsSelection
196
+ .selectAll<SVGClipPathElement, Layout>('clipPath')
197
+ .data(clipPathData)
198
+ const enter = update.enter()
199
+ .append('clipPath')
200
+ const cutRect = update.merge(enter)
201
+ .attr('id', d => d.id)
202
+ update.exit().remove()
203
+
204
+ update.merge(enter).each((d, i, g) => {
205
+ const updateRect = d3.select(g[i])
206
+ .selectAll<SVGRectElement, typeof d>('rect')
207
+ .data([d])
208
+ const enterRect = updateRect.enter().append('rect')
209
+ updateRect.merge(enterRect)
210
+ .attr('x', 0)
211
+ .attr('y', 0)
212
+ .attr('width', _d => _d.width)
213
+ .attr('height', _d => _d.height)
214
+ updateRect.exit().remove()
215
+ })
216
+ }
217
+
218
+ function highlight ({ selection, ids, fullChartParams }: {
219
+ selection: d3.Selection<SVGPathElement, ComputedDatumGrid, any, any>
220
+ ids: string[]
221
+ fullChartParams: ChartParams
222
+ }) {
223
+ selection.interrupt('highlight')
224
+
225
+ const removeHighlight = () => {
226
+ selection
227
+ .transition('highlight')
228
+ .duration(200)
229
+ .style('opacity', 1)
230
+ }
231
+
232
+ if (!ids.length) {
233
+ removeHighlight()
234
+ return
235
+ }
236
+
237
+ selection
238
+ .each((d, i, n) => {
239
+ if (ids.includes(d.id)) {
240
+ d3.select(n[i])
241
+ .style('opacity', 1)
242
+ } else {
243
+ d3.select(n[i])
244
+ .style('opacity', fullChartParams.styles.unhighlightedOpacity)
245
+ }
246
+ })
247
+ }
248
+
249
+ export const BarsTriangle = defineGridPlugin(pluginName, DEFAULT_BARS_TRIANGLE_PLUGIN_PARAMS)(({ selection, name, subject, observer }) => {
250
+ const destroy$ = new Subject()
251
+
252
+ const clipPathID = getUniID(pluginName, 'clipPath-box')
253
+
254
+ const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection
255
+ .append('g')
256
+ .attr('clip-path', `url(#${clipPathID})`)
257
+ const defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any> = axisSelection.append('defs')
258
+ const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = axisSelection.append('g')
259
+ let graphicSelection: d3.Selection<SVGGElement, any, any, any> | undefined
260
+ const pathSelection$: Subject<d3.Selection<SVGPathElement, ComputedDatumGrid, any, any>> = new Subject()
261
+ // .style('transform', 'translate(0px, 0px) scale(1)')
262
+
263
+ observer.gridAxesTransform$
264
+ .pipe(
265
+ takeUntil(destroy$),
266
+ map(d => d.value),
267
+ distinctUntilChanged()
268
+ ).subscribe(d => {
269
+ axisSelection
270
+ .style('transform', d)
271
+ })
272
+
273
+ observer.gridGraphicTransform$
274
+ .pipe(
275
+ takeUntil(destroy$),
276
+ switchMap(async d => d.value),
277
+ distinctUntilChanged()
278
+ ).subscribe(d => {
279
+ graphicGSelection
280
+ .transition()
281
+ .duration(50)
282
+ .style('transform', d)
283
+ })
284
+
285
+ // const axisSize$ = gridAxisSizeObservable({
286
+ // dataFormatter$,
287
+ // observer.layout$
288
+ // })
289
+
290
+ const zeroY$ = observer.computedData$.pipe(
291
+ map(d => d[0] && d[0][0]
292
+ ? d[0][0].axisY - d[0][0].axisYFromZero
293
+ : 0),
294
+ distinctUntilChanged()
295
+ )
296
+
297
+ const barWidth$ = new Observable<number>(subscriber => {
298
+ combineLatest({
299
+ computedData: observer.computedData$,
300
+ params: observer.fullParams$,
301
+ axisSize: observer.gridAxesSize$
302
+ }).pipe(
303
+ switchMap(async d => d)
304
+ ).subscribe(data => {
305
+ const barWidth = calcBarWidth({
306
+ axisWidth: data.axisSize.width,
307
+ groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
308
+ barAmountOfGroup: data.computedData.length,
309
+ barPadding: data.params.barPadding,
310
+ barGroupPadding: data.params.barGroupPadding
311
+ })
312
+ subscriber.next(barWidth)
313
+ })
314
+ }).pipe(
315
+ takeUntil(destroy$),
316
+ distinctUntilChanged()
317
+ )
318
+
319
+ const seriesLabels$ = observer.computedData$.pipe(
320
+ takeUntil(destroy$),
321
+ map(data => data.map((d, i) => d[0] ? d[0].seriesLabel : String(i)))
322
+ )
323
+
324
+ const groupLabels$ = observer.computedData$.pipe(
325
+ takeUntil(destroy$),
326
+ map(data => {
327
+ return data[0] ? data[0].map(d => d.groupLabel) : []
328
+ })
329
+ )
330
+
331
+ const barScale$: Observable<d3.ScalePoint<string>> = new Observable(subscriber => {
332
+ combineLatest({
333
+ seriesLabels: seriesLabels$,
334
+ barWidth: barWidth$,
335
+ params: observer.fullParams$,
336
+ }).pipe(
337
+ takeUntil(destroy$),
338
+ switchMap(async d => d)
339
+ ).subscribe(data => {
340
+ const barScale = makeBarScale(data.barWidth, data.seriesLabels, data.params)
341
+ subscriber.next(barScale)
342
+ })
343
+ })
344
+
345
+ const transitionDuration$ = observer.fullChartParams$.pipe(
346
+ takeUntil(destroy$),
347
+ map(d => d.transitionDuration),
348
+ distinctUntilChanged()
349
+ )
350
+
351
+ const delayGroup$ = new Observable<number>(subscriber => {
352
+ combineLatest({
353
+ groupLabels: groupLabels$,
354
+ transitionDuration: transitionDuration$,
355
+ }).pipe(
356
+ switchMap(async d => d)
357
+ ).subscribe(data => {
358
+ const delay = calcDelayGroup(data.groupLabels.length, data.transitionDuration)
359
+ subscriber.next(delay)
360
+ })
361
+ }).pipe(
362
+ takeUntil(destroy$),
363
+ distinctUntilChanged()
364
+ )
365
+
366
+ const transitionItem$ = new Observable<number>(subscriber => {
367
+ combineLatest({
368
+ groupLabels: groupLabels$,
369
+ transitionDuration: transitionDuration$
370
+ }).pipe(
371
+ switchMap(async d => d)
372
+ ).subscribe(data => {
373
+ const transition = calctransitionItem(data.groupLabels.length, data.transitionDuration)
374
+ subscriber.next(transition)
375
+ })
376
+ }).pipe(
377
+ takeUntil(destroy$),
378
+ distinctUntilChanged()
379
+ )
380
+
381
+ const transposedData$ = observer.computedData$.pipe(
382
+ takeUntil(destroy$),
383
+ map(data => {
384
+ // 取得原始陣列的維度
385
+ const rows = data.length;
386
+ const cols = data.reduce((prev, current) => {
387
+ return Math.max(prev, current.length)
388
+ }, 0)
389
+
390
+ // 初始化轉換後的陣列
391
+ const transposedArray: typeof data = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
392
+
393
+ // 遍歷原始陣列,進行轉換
394
+ for (let i = 0; i < rows; i++) {
395
+ for (let j = 0; j < cols; j++) {
396
+ transposedArray[j][i] = data[i][j]
397
+ }
398
+ }
399
+
400
+ return transposedArray
401
+ })
402
+ )
403
+
404
+ const barData$ = transposedData$.pipe(
405
+ takeUntil(destroy$),
406
+ map(data => {
407
+ const linearGradientIds = data.length
408
+ ? data[0].map(d => getUniID(name, `lineargradient-${d.seriesLabel}`))
409
+ : []
410
+ return data.map(d => {
411
+ return d.map((_d, _i) => {
412
+ return <BarDatumGrid>{
413
+ linearGradientId: linearGradientIds[_i],
414
+ ..._d
415
+ }
416
+ })
417
+ })
418
+ })
419
+ )
420
+
421
+ observer.gridAxesSize$.pipe(
422
+ takeUntil(destroy$)
423
+ ).subscribe(data => {
424
+ const clipPathData = [{
425
+ id: clipPathID,
426
+ width: data.width,
427
+ height: data.height
428
+ }]
429
+ renderClipPath({
430
+ defsSelection,
431
+ clipPathData
432
+ })
433
+ })
434
+
435
+ // const SeriesDataMap$ = observer.computedData$.pipe(
436
+ // map(d => makeGridSeriesDataMap(d))
437
+ // )
438
+
439
+ // const GroupDataMap$ = observer.computedData$.pipe(
440
+ // map(d => makeGridGroupDataMap(d))
441
+ // )
442
+
443
+ const highlightTarget$ = observer.fullChartParams$.pipe(
444
+ takeUntil(destroy$),
445
+ map(d => d.highlightTarget),
446
+ distinctUntilChanged()
447
+ )
448
+
449
+ combineLatest({
450
+ barData: barData$,
451
+ computedData: observer.computedData$,
452
+ zeroY: zeroY$,
453
+ groupLabels: groupLabels$,
454
+ barScale: barScale$,
455
+ params: observer.fullParams$,
456
+ chartParams: observer.fullChartParams$,
457
+ highlightTarget: highlightTarget$,
458
+ barWidth: barWidth$,
459
+ delayGroup: delayGroup$,
460
+ transitionItem: transitionItem$,
461
+ SeriesDataMap: observer.SeriesDataMap$,
462
+ GroupDataMap: observer.GroupDataMap$
463
+ }).pipe(
464
+ takeUntil(destroy$),
465
+ // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
466
+ switchMap(async (d) => d),
467
+ ).subscribe(data => {
468
+ const pathSelection = renderTriangleBars({
469
+ selection: graphicGSelection,
470
+ barData: data.barData,
471
+ zeroY: data.zeroY,
472
+ groupLabels: data.groupLabels,
473
+ barScale: data.barScale,
474
+ params: data.params,
475
+ chartParams: data.chartParams,
476
+ barWidth: data.barWidth,
477
+ delayGroup: data.delayGroup,
478
+ transitionItem: data.transitionItem
479
+ })
480
+ renderLinearGradient({
481
+ defsSelection,
482
+ barData: data.barData,
483
+ params: data.params
484
+ })
485
+
486
+ pathSelection!
487
+ .on('mouseover', (event, datum) => {
488
+ event.stopPropagation()
489
+
490
+ subject.event$.next({
491
+ type: 'grid',
492
+ eventName: 'mouseover',
493
+ pluginName: name,
494
+ highlightTarget: data.highlightTarget,
495
+ datum,
496
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
497
+ seriesIndex: datum.seriesIndex,
498
+ seriesLabel: datum.seriesLabel,
499
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
500
+ groupIndex: datum.groupIndex,
501
+ groupLabel: datum.groupLabel,
502
+ event,
503
+ data: data.computedData
504
+ })
505
+ })
506
+ .on('mousemove', (event, datum) => {
507
+ event.stopPropagation()
508
+
509
+ subject.event$.next({
510
+ type: 'grid',
511
+ eventName: 'mousemove',
512
+ pluginName: name,
513
+ highlightTarget: data.highlightTarget,
514
+ datum,
515
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
516
+ seriesIndex: datum.seriesIndex,
517
+ seriesLabel: datum.seriesLabel,
518
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
519
+ groupIndex: datum.groupIndex,
520
+ groupLabel: datum.groupLabel,
521
+ event,
522
+ data: data.computedData
523
+ })
524
+ })
525
+ .on('mouseout', (event, datum) => {
526
+ event.stopPropagation()
527
+
528
+ subject.event$.next({
529
+ type: 'grid',
530
+ eventName: 'mouseout',
531
+ pluginName: name,
532
+ highlightTarget: data.highlightTarget,
533
+ datum,
534
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
535
+ seriesIndex: datum.seriesIndex,
536
+ seriesLabel: datum.seriesLabel,
537
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
538
+ groupIndex: datum.groupIndex,
539
+ groupLabel: datum.groupLabel,
540
+ event,
541
+ data: data.computedData
542
+ })
543
+ })
544
+ .on('click', (event, datum) => {
545
+ event.stopPropagation()
546
+
547
+ subject.event$.next({
548
+ type: 'grid',
549
+ eventName: 'click',
550
+ pluginName: name,
551
+ highlightTarget: data.highlightTarget,
552
+ datum,
553
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
554
+ seriesIndex: datum.seriesIndex,
555
+ seriesLabel: datum.seriesLabel,
556
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
557
+ groupIndex: datum.groupIndex,
558
+ groupLabel: datum.groupLabel,
559
+ event,
560
+ data: data.computedData
561
+ })
562
+ })
563
+
564
+ pathSelection$.next(pathSelection)
565
+ })
566
+
567
+ // const datumList$ = observer.computedData$.pipe(
568
+ // takeUntil(destroy$),
569
+ // map(d => d.flat())
570
+ // )
571
+ // const highlight$ = highlightObservable({ datumList$, observer.fullChartParams$, event$: subject.event$ })
572
+ const highlightSubscription = observer.gridHighlight$.subscribe()
573
+
574
+ combineLatest({
575
+ pathSelection: pathSelection$,
576
+ highlight: observer.gridHighlight$,
577
+ fullChartParams: observer.fullChartParams$
578
+ }).pipe(
579
+ takeUntil(destroy$),
580
+ switchMap(async d => d)
581
+ ).subscribe(data => {
582
+ highlight({
583
+ selection: data.pathSelection,
584
+ ids: data.highlight,
585
+ fullChartParams: data.fullChartParams
586
+ })
587
+ })
588
+
589
+
590
+ return () => {
591
+ destroy$.next(undefined)
592
+ highlightSubscription.unsubscribe()
593
+ }
594
+ })