@orbcharts/plugins-basic 3.0.0-alpha.24

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.
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
+ })