@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,661 @@
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
+ ComputedDataGrid,
15
+ ComputedDatumGrid,
16
+ EventSeries,
17
+ ChartParams,
18
+ DataSeriesDatum,
19
+ Layout } from '@orbcharts/core'
20
+ import type { BarStackPluginParams } from '../types'
21
+ import { DEFAULT_BAR_STACK_PLUGIN_PARAMS } from '../defaults'
22
+ import { getD3TransitionEase } from '../../utils/d3Utils'
23
+ import { getClassName, getUniID } from '../../utils/orbchartsUtils'
24
+
25
+ interface GraphicDatum extends ComputedDatumGrid {
26
+ _barStartY: number // bar的起點y座標
27
+ _barHeight: number // bar的高度
28
+ }
29
+
30
+ interface RenderBarParams {
31
+ selection: d3.Selection<SVGGElement, unknown, any, any>
32
+ data: GraphicDatum[][]
33
+ zeroY: number
34
+ groupLabels: string[]
35
+ // barScale: d3.ScalePoint<string>
36
+ params: BarStackPluginParams
37
+ chartParams: ChartParams
38
+ barWidth: number
39
+ transformedBarRadius: [number, number]
40
+ delayGroup: number
41
+ transitionItem: number
42
+ }
43
+
44
+ type ClipPathDatum = {
45
+ id: string;
46
+ // x: number;
47
+ // y: number;
48
+ width: number;
49
+ height: number;
50
+ }
51
+
52
+ const pluginName = 'BarStack'
53
+ const gClassName = getClassName(pluginName, 'g')
54
+ const gContentClassName = getClassName(pluginName, 'g-content')
55
+ // group的delay在動畫中的佔比(剩餘部份的時間為圖形本身的動畫時間,因為delay時間和最後一個group的動畫時間加總為1)
56
+ const groupDelayProportionOfDuration = 0.3
57
+
58
+ function calcBarWidth ({ axisWidth, groupAmount, barGroupPadding = 0 }: {
59
+ axisWidth: number
60
+ groupAmount: number
61
+ barGroupPadding: number
62
+ }) {
63
+ const eachGroupWidth = axisWidth / (groupAmount - 1)
64
+ const width = eachGroupWidth - barGroupPadding
65
+ return width > 1 ? width : 1
66
+
67
+ }
68
+
69
+ // function makeBarScale (barWidth: number, seriesLabels: string[], params: BarStackPluginParams) {
70
+ // const barHalfWidth = barWidth! / 2
71
+ // const barGroupWidth = barWidth * seriesLabels.length + params.barPadding! * seriesLabels.length
72
+ // return d3.scalePoint()
73
+ // .domain(seriesLabels)
74
+ // .range([-barGroupWidth / 2 + barHalfWidth, barGroupWidth / 2 - barHalfWidth])
75
+ // }
76
+
77
+ function calcDelayGroup (barGroupAmount: number, totalDuration: number) {
78
+ if (barGroupAmount <= 1) {
79
+ // 一筆內計算會出錯所以不算
80
+ return 0
81
+ }
82
+ return totalDuration / (barGroupAmount - 1) * groupDelayProportionOfDuration // 依group數量計算
83
+ }
84
+
85
+ function calctransitionItem (barGroupAmount: number, totalDuration: number) {
86
+ if (barGroupAmount <= 1) {
87
+ // 一筆內不會有delay
88
+ return totalDuration
89
+ }
90
+ return totalDuration * (1 - groupDelayProportionOfDuration) // delay後剩餘的時間
91
+ }
92
+
93
+ function renderRectBars ({ selection, data, zeroY, groupLabels, params, chartParams, barWidth, transformedBarRadius, delayGroup, transitionItem }: RenderBarParams) {
94
+
95
+ const barHalfWidth = barWidth! / 2
96
+
97
+ const barGroup = selection
98
+ .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${gClassName}`)
99
+ .data(data, (d, i) => groupLabels[i])
100
+ .join(
101
+ enter => {
102
+ return enter
103
+ .append('g')
104
+ .classed(gClassName, true)
105
+ .attr('cursor', 'pointer')
106
+ },
107
+ update => update,
108
+ exit => exit.remove()
109
+ )
110
+ .attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
111
+ .each((d, i, g) => {
112
+ const bars = d3.select(g[i])
113
+ .selectAll<SVGGElement, ComputedDatumGrid>('g')
114
+ .data(d, _d => _d.id)
115
+ .join(
116
+ enter => {
117
+ return enter
118
+ .append('g')
119
+ .classed(gContentClassName, true)
120
+ },
121
+ update => update,
122
+ exit => exit.remove()
123
+ )
124
+ .each((_d, _i, _g) => {
125
+ const rect = d3.select(_g[_i])
126
+ .selectAll<SVGRectElement, ComputedDatumGrid>('rect')
127
+ .data([_d], _d => _d.id)
128
+ .join(
129
+ enter => {
130
+ return enter
131
+ .append('rect')
132
+ .attr('y', d => zeroY)
133
+ .attr('height', d => 0)
134
+ },
135
+ update => update,
136
+ exit => exit.remove()
137
+ )
138
+ .attr('rx', transformedBarRadius[0])
139
+ .attr('ry', transformedBarRadius[1])
140
+ .attr('fill', d => d.color)
141
+ .attr('transform', `translate(${-barHalfWidth}, 0)`)
142
+ .attr('x', d => 0)
143
+ .attr('width', barWidth!)
144
+ .transition()
145
+ .duration(transitionItem)
146
+ .ease(getD3TransitionEase(chartParams.transitionEase))
147
+ .delay((d, i) => d.groupIndex * delayGroup)
148
+ .attr('y', d => d._barStartY)
149
+ .attr('height', d => Math.abs(d._barHeight))
150
+ })
151
+
152
+ })
153
+
154
+ const graphicBarSelection: d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown> = barGroup.selectAll(`g.${gContentClassName}`)
155
+
156
+
157
+ return graphicBarSelection
158
+ }
159
+
160
+ function renderClipPath ({ defsSelection, clipPathData }: {
161
+ defsSelection: d3.Selection<SVGDefsElement, any, any, any>
162
+ clipPathData: ClipPathDatum[]
163
+ }) {
164
+ const clipPath = defsSelection
165
+ .selectAll<SVGClipPathElement, Layout>('clipPath')
166
+ .data(clipPathData)
167
+ .join(
168
+ enter => {
169
+ return enter
170
+ .append('clipPath')
171
+ },
172
+ update => update,
173
+ exit => exit.remove()
174
+ )
175
+ .attr('id', d => d.id)
176
+ .each((d, i, g) => {
177
+ const rect = d3.select(g[i])
178
+ .selectAll<SVGRectElement, typeof d>('rect')
179
+ .data([d])
180
+ .join(
181
+ enter => {
182
+ return enter
183
+ .append('rect')
184
+ },
185
+ update => update,
186
+ exit => exit.remove()
187
+ )
188
+ .attr('x', 0)
189
+ .attr('y', 0)
190
+ .attr('width', _d => _d.width)
191
+ .attr('height', _d => _d.height)
192
+ })
193
+ }
194
+
195
+ function highlight ({ selection, ids, fullChartParams }: {
196
+ selection: d3.Selection<any, ComputedDatumGrid, any, any>
197
+ ids: string[]
198
+ fullChartParams: ChartParams
199
+ }) {
200
+ selection.interrupt('highlight')
201
+
202
+ if (!ids.length) {
203
+ // remove highlight
204
+ selection
205
+ .transition('highlight')
206
+ .duration(200)
207
+ .style('opacity', 1)
208
+ return
209
+ }
210
+
211
+ selection
212
+ .each((d, i, n) => {
213
+ if (ids.includes(d.id)) {
214
+ d3.select(n[i])
215
+ .style('opacity', 1)
216
+ } else {
217
+ d3.select(n[i])
218
+ .style('opacity', fullChartParams.styles.unhighlightedOpacity)
219
+ }
220
+ })
221
+ }
222
+
223
+
224
+ export const BarStack = defineGridPlugin(pluginName, DEFAULT_BAR_STACK_PLUGIN_PARAMS)(({ selection, name, subject, observer }) => {
225
+ const destroy$ = new Subject()
226
+
227
+ const clipPathID = getUniID(pluginName, 'clipPath-box')
228
+
229
+ const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection
230
+ .append('g')
231
+ .attr('clip-path', `url(#${clipPathID})`)
232
+ const defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any> = axisSelection.append('defs')
233
+ const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = axisSelection.append('g')
234
+ const barSelection$: Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>> = new Subject()
235
+
236
+ observer.gridAxesTransform$
237
+ .pipe(
238
+ takeUntil(destroy$),
239
+ map(d => d.value),
240
+ distinctUntilChanged()
241
+ ).subscribe(d => {
242
+ axisSelection
243
+ .style('transform', d)
244
+ })
245
+
246
+ observer.gridGraphicTransform$
247
+ .pipe(
248
+ takeUntil(destroy$),
249
+ switchMap(async d => d.value),
250
+ distinctUntilChanged()
251
+ ).subscribe(d => {
252
+ graphicGSelection
253
+ .transition()
254
+ .duration(50)
255
+ .style('transform', d)
256
+ })
257
+
258
+ // const axisSize$ = gridAxisSizeObservable({
259
+ // dataFormatter$,
260
+ // observer.layout$
261
+ // })
262
+
263
+ // const visibleComputedData$ = observer.computedData$.pipe(
264
+ // takeUntil(destroy$),
265
+ // map(data => {
266
+ // const visibleComputedData = data
267
+ // .map(d => {
268
+ // return d.filter(_d => {
269
+ // return _d.visible == true
270
+ // })
271
+ // })
272
+ // .filter(d => d.length)
273
+ // // console.log('visibleComputedData', visibleComputedData)
274
+ // return visibleComputedData
275
+ // })
276
+ // )
277
+
278
+ const zeroY$ = observer.visibleComputedData$.pipe(
279
+ map(d => d[0] && d[0][0]
280
+ ? d[0][0].axisY - d[0][0].axisYFromZero
281
+ : 0),
282
+ distinctUntilChanged()
283
+ )
284
+
285
+ const barWidth$ = new Observable<number>(subscriber => {
286
+ combineLatest({
287
+ computedData: observer.computedData$,
288
+ // visibleComputedData: observer.visibleComputedData$,
289
+ params: observer.fullParams$,
290
+ axisSize: observer.gridAxesSize$
291
+ }).pipe(
292
+ switchMap(async d => d)
293
+ ).subscribe(data => {
294
+ const barWidth = data.params.barWidth
295
+ ? data.params.barWidth
296
+ : calcBarWidth({
297
+ axisWidth: data.axisSize.width,
298
+ groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
299
+ barGroupPadding: data.params.barGroupPadding
300
+ })
301
+ subscriber.next(barWidth)
302
+ })
303
+ }).pipe(
304
+ takeUntil(destroy$),
305
+ distinctUntilChanged()
306
+ )
307
+
308
+ // 圓角的值 [rx, ry]
309
+ const transformedBarRadius$: Observable<[number, number]> = combineLatest({
310
+ gridGraphicTransform: observer.gridGraphicTransform$,
311
+ barWidth: barWidth$,
312
+ params: observer.fullParams$
313
+ }).pipe(
314
+ takeUntil(destroy$),
315
+ switchMap(async data => data),
316
+ map(data => {
317
+ const barHalfWidth = data.barWidth! / 2
318
+ const radius = data.params.barRadius === true ? barHalfWidth
319
+ : data.params.barRadius === false ? 0
320
+ : typeof data.params.barRadius == 'number' ? data.params.barRadius
321
+ : 0
322
+ const transformedRx = radius == 0
323
+ ? 0
324
+ : radius / data.gridGraphicTransform.scale[0] // 反向外層scale的變型
325
+ const transformedRy = radius == 0
326
+ ? 0
327
+ : radius / data.gridGraphicTransform.scale[1]
328
+ return [transformedRx, transformedRy]
329
+ })
330
+ )
331
+
332
+ // const seriesLabels$ = observer.visibleComputedData$.pipe(
333
+ // takeUntil(destroy$),
334
+ // map(data => {
335
+ // const SeriesLabelSet: Set<string> = new Set()
336
+ // data.forEach(d => {
337
+ // d.forEach(_d => {
338
+ // SeriesLabelSet.add(_d.seriesLabel)
339
+ // })
340
+ // })
341
+ // return Array.from(SeriesLabelSet)
342
+ // })
343
+ // )
344
+
345
+ const groupLabels$ = observer.visibleComputedData$.pipe(
346
+ takeUntil(destroy$),
347
+ map(data => {
348
+ const GroupLabelSet: Set<string> = new Set()
349
+ data.forEach(d => {
350
+ d.forEach(_d => {
351
+ GroupLabelSet.add(_d.groupLabel)
352
+ })
353
+ })
354
+ return Array.from(GroupLabelSet)
355
+ })
356
+ )
357
+
358
+ // const barScale$: Observable<d3.ScalePoint<string>> = new Observable(subscriber => {
359
+ // combineLatest({
360
+ // seriesLabels: seriesLabels$,
361
+ // barWidth: barWidth$,
362
+ // params: observer.fullParams$,
363
+ // }).pipe(
364
+ // takeUntil(destroy$),
365
+ // switchMap(async d => d)
366
+ // ).subscribe(data => {
367
+ // const barScale = makeBarScale(data.barWidth, data.seriesLabels, data.params)
368
+ // subscriber.next(barScale)
369
+ // })
370
+ // })
371
+
372
+ const transitionDuration$ = observer.fullChartParams$.pipe(
373
+ takeUntil(destroy$),
374
+ map(d => d.transitionDuration),
375
+ distinctUntilChanged()
376
+ )
377
+
378
+ const delayGroup$ = new Observable<number>(subscriber => {
379
+ combineLatest({
380
+ groupLabels: groupLabels$,
381
+ transitionDuration: transitionDuration$,
382
+ }).pipe(
383
+ switchMap(async d => d)
384
+ ).subscribe(data => {
385
+ const delay = calcDelayGroup(data.groupLabels.length, data.transitionDuration)
386
+ subscriber.next(delay)
387
+ })
388
+ }).pipe(
389
+ takeUntil(destroy$),
390
+ distinctUntilChanged()
391
+ )
392
+
393
+ const transitionItem$ = new Observable<number>(subscriber => {
394
+ combineLatest({
395
+ groupLabels: groupLabels$,
396
+ transitionDuration: transitionDuration$
397
+ }).pipe(
398
+ switchMap(async d => d)
399
+ ).subscribe(data => {
400
+ const transition = calctransitionItem(data.groupLabels.length, data.transitionDuration)
401
+ subscriber.next(transition)
402
+ })
403
+ }).pipe(
404
+ takeUntil(destroy$),
405
+ distinctUntilChanged()
406
+ )
407
+
408
+ const transposedVisibleData$: Observable<ComputedDataGrid> = observer.visibleComputedData$.pipe(
409
+ takeUntil(destroy$),
410
+ map(data => {
411
+ console.log('visibleComputedData', data)
412
+ // 取得原始陣列的維度
413
+ const rows = data.length;
414
+ const cols = data.reduce((prev, current) => {
415
+ return Math.max(prev, current.length)
416
+ }, 0)
417
+
418
+ // 初始化轉換後的陣列
419
+ const transposedArray = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
420
+
421
+ // 遍歷原始陣列,進行轉換
422
+ for (let i = 0; i < rows; i++) {
423
+ for (let j = 0; j < cols; j++) {
424
+ transposedArray[j][i] = data[i][j]
425
+ }
426
+ }
427
+ return transposedArray
428
+ })
429
+ )
430
+
431
+ const yRatio$ = combineLatest({
432
+ transposedVisibleData: transposedVisibleData$,
433
+ dataFormatter: observer.fullDataFormatter$,
434
+ }).pipe(
435
+ takeUntil(destroy$),
436
+ switchMap(async d => d),
437
+ map(data => {
438
+ const groupMin = 0
439
+ const groupMax = data.transposedVisibleData.length - 1
440
+ const groupScaleDomainMin = data.dataFormatter.groupAxis.scaleDomain[0] === 'auto'
441
+ ? groupMin - data.dataFormatter.groupAxis.scalePadding
442
+ : data.dataFormatter.groupAxis.scaleDomain[0] as number - data.dataFormatter.groupAxis.scalePadding
443
+ const groupScaleDomainMax = data.dataFormatter.groupAxis.scaleDomain[1] === 'auto'
444
+ ? groupMax + data.dataFormatter.groupAxis.scalePadding
445
+ : data.dataFormatter.groupAxis.scaleDomain[1] as number + data.dataFormatter.groupAxis.scalePadding
446
+
447
+ const filteredData = data.transposedVisibleData
448
+ .map(d => {
449
+ return d.filter((_d, i) => {
450
+ return _d.groupIndex >= groupScaleDomainMin && _d.groupIndex <= groupScaleDomainMax
451
+ })
452
+ })
453
+ // console.log('filteredData', filteredData)
454
+
455
+ if (!filteredData.flat().length) {
456
+ return 1
457
+ } else {
458
+ const yArr = filteredData.flat().map(d => d.axisYFromZero)
459
+ const barMaxY = Math.max(...yArr)
460
+ const stackYArr = filteredData.map(d => d.reduce((prev, current) => prev + current.axisYFromZero, 0))
461
+ const barStackMaxY = Math.max(...stackYArr)
462
+
463
+ return barMaxY / barStackMaxY
464
+ }
465
+ })
466
+ )
467
+
468
+ const graphicData$ = combineLatest({
469
+ transposedVisibleData: transposedVisibleData$,
470
+ yRatio: yRatio$,
471
+ zeroY: zeroY$
472
+ }).pipe(
473
+ takeUntil(destroy$),
474
+ map(data => {
475
+ console.log(data.transposedVisibleData)
476
+ return data.transposedVisibleData.map(d => {
477
+ let accY = data.zeroY
478
+ return d.map(_d => {
479
+ const _barStartY = accY
480
+ const _barHeight = _d.axisYFromZero * data.yRatio
481
+ accY = accY + _barHeight
482
+ return <GraphicDatum>{
483
+ ..._d,
484
+ _barStartY,
485
+ _barHeight
486
+ }
487
+ })
488
+ })
489
+ })
490
+ )
491
+
492
+ observer.gridAxesSize$.pipe(
493
+ takeUntil(destroy$)
494
+ ).subscribe(data => {
495
+ const clipPathData = [{
496
+ id: clipPathID,
497
+ width: data.width,
498
+ height: data.height
499
+ }]
500
+ renderClipPath({
501
+ defsSelection,
502
+ clipPathData
503
+ })
504
+ })
505
+
506
+ // const SeriesDataMap$ = visibleComputedData$.pipe(
507
+ // map(d => makeGridSeriesDataMap(d))
508
+ // )
509
+
510
+ // const GroupDataMap$ = visibleComputedData$.pipe(
511
+ // map(d => makeGridGroupDataMap(d))
512
+ // )
513
+
514
+ const highlightTarget$ = observer.fullChartParams$.pipe(
515
+ takeUntil(destroy$),
516
+ map(d => d.highlightTarget),
517
+ distinctUntilChanged()
518
+ )
519
+
520
+ combineLatest({
521
+ // renderBarsFn: renderBarsFn$,
522
+ graphicData: graphicData$,
523
+ zeroY: zeroY$,
524
+ groupLabels: groupLabels$,
525
+ // barScale: barScale$,
526
+ params: observer.fullParams$,
527
+ chartParams: observer.fullChartParams$,
528
+ highlightTarget: highlightTarget$,
529
+ barWidth: barWidth$,
530
+ transformedBarRadius: transformedBarRadius$,
531
+ delayGroup: delayGroup$,
532
+ transitionItem: transitionItem$,
533
+ SeriesDataMap: observer.SeriesDataMap$,
534
+ GroupDataMap: observer.GroupDataMap$
535
+ }).pipe(
536
+ takeUntil(destroy$),
537
+ // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
538
+ switchMap(async (d) => d),
539
+ ).subscribe(data => {
540
+ const barSelection = renderRectBars({
541
+ selection: graphicGSelection,
542
+ data: data.graphicData,
543
+ zeroY: data.zeroY,
544
+ groupLabels: data.groupLabels,
545
+ // barScale: data.barScale,
546
+ params: data.params,
547
+ chartParams: data.chartParams,
548
+ barWidth: data.barWidth,
549
+ transformedBarRadius: data.transformedBarRadius,
550
+ delayGroup: data.delayGroup,
551
+ transitionItem: data.transitionItem
552
+ })
553
+
554
+ barSelection!
555
+ .on('mouseover', (event, datum) => {
556
+ event.stopPropagation()
557
+
558
+ subject.event$.next({
559
+ type: 'grid',
560
+ eventName: 'mouseover',
561
+ pluginName: name,
562
+ highlightTarget: data.highlightTarget,
563
+ datum,
564
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
565
+ seriesIndex: datum.seriesIndex,
566
+ seriesLabel: datum.seriesLabel,
567
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
568
+ groupIndex: datum.groupIndex,
569
+ groupLabel: datum.groupLabel,
570
+ event,
571
+ data: data.graphicData
572
+ })
573
+ })
574
+ .on('mousemove', (event, datum) => {
575
+ event.stopPropagation()
576
+
577
+ subject.event$.next({
578
+ type: 'grid',
579
+ eventName: 'mousemove',
580
+ pluginName: name,
581
+ highlightTarget: data.highlightTarget,
582
+ datum,
583
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
584
+ seriesIndex: datum.seriesIndex,
585
+ seriesLabel: datum.seriesLabel,
586
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
587
+ groupIndex: datum.groupIndex,
588
+ groupLabel: datum.groupLabel,
589
+ event,
590
+ data: data.graphicData
591
+ })
592
+ })
593
+ .on('mouseout', (event, datum) => {
594
+ event.stopPropagation()
595
+
596
+ subject.event$.next({
597
+ type: 'grid',
598
+ eventName: 'mouseout',
599
+ pluginName: name,
600
+ highlightTarget: data.highlightTarget,
601
+ datum,
602
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
603
+ seriesIndex: datum.seriesIndex,
604
+ seriesLabel: datum.seriesLabel,
605
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
606
+ groupIndex: datum.groupIndex,
607
+ groupLabel: datum.groupLabel,
608
+ event,
609
+ data: data.graphicData
610
+ })
611
+ })
612
+ .on('click', (event, datum) => {
613
+ event.stopPropagation()
614
+
615
+ subject.event$.next({
616
+ type: 'grid',
617
+ eventName: 'click',
618
+ pluginName: name,
619
+ highlightTarget: data.highlightTarget,
620
+ datum,
621
+ series: data.SeriesDataMap.get(datum.seriesLabel)!,
622
+ seriesIndex: datum.seriesIndex,
623
+ seriesLabel: datum.seriesLabel,
624
+ groups: data.GroupDataMap.get(datum.groupLabel)!,
625
+ groupIndex: datum.groupIndex,
626
+ groupLabel: datum.groupLabel,
627
+ event,
628
+ data: data.graphicData
629
+ })
630
+ })
631
+
632
+ barSelection$.next(barSelection!)
633
+ })
634
+
635
+ // const datumList$ = observer.computedData$.pipe(
636
+ // takeUntil(destroy$),
637
+ // map(d => d.flat())
638
+ // )
639
+ // const highlight$ = highlightObservable({ datumList$, chartParams$, event$: store.event$ })
640
+ const highlightSubscription = observer.gridHighlight$.subscribe()
641
+
642
+ combineLatest({
643
+ barSelection: barSelection$,
644
+ highlight: observer.gridHighlight$,
645
+ fullChartParams: observer.fullChartParams$
646
+ }).pipe(
647
+ takeUntil(destroy$),
648
+ switchMap(async d => d)
649
+ ).subscribe(data => {
650
+ highlight({
651
+ selection: data.barSelection,
652
+ ids: data.highlight,
653
+ fullChartParams: data.fullChartParams
654
+ })
655
+ })
656
+
657
+ return () => {
658
+ destroy$.next(undefined)
659
+ highlightSubscription.unsubscribe()
660
+ }
661
+ })