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