@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,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
+ })