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