@orbcharts/plugins-basic 3.0.0-alpha.29 → 3.0.0-alpha.31

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