@orbcharts/plugins-basic 3.0.0-alpha.44 → 3.0.0-alpha.46

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 (57) hide show
  1. package/dist/orbcharts-plugins-basic.es.js +7770 -7580
  2. package/dist/orbcharts-plugins-basic.umd.js +8 -8
  3. package/dist/src/base/BaseBarStack.d.ts +6 -4
  4. package/dist/src/base/BaseBars.d.ts +6 -4
  5. package/dist/src/base/BaseBarsTriangle.d.ts +7 -4
  6. package/dist/src/base/BaseDots.d.ts +5 -3
  7. package/dist/src/base/BaseGroupAxis.d.ts +3 -3
  8. package/dist/src/base/BaseLineAreas.d.ts +6 -3
  9. package/dist/src/base/BaseLines.d.ts +6 -3
  10. package/dist/src/base/BaseValueAxis.d.ts +3 -3
  11. package/dist/src/grid/gridObservables.d.ts +4 -4
  12. package/dist/src/multiGrid/multiGridObservables.d.ts +2 -6
  13. package/dist/src/series/plugins/PieEventTexts.d.ts +3 -1
  14. package/dist/src/series/seriesObservables.d.ts +21 -0
  15. package/dist/src/series/seriesUtils.d.ts +3 -3
  16. package/package.json +2 -2
  17. package/src/base/BaseBarStack.ts +105 -208
  18. package/src/base/BaseBars.ts +78 -64
  19. package/src/base/BaseBarsTriangle.ts +76 -63
  20. package/src/base/BaseDots.ts +41 -178
  21. package/src/base/BaseGroupAxis.ts +13 -13
  22. package/src/base/BaseLineAreas.ts +85 -81
  23. package/src/base/BaseLines.ts +82 -75
  24. package/src/base/BaseValueAxis.ts +14 -15
  25. package/src/grid/gridObservables.ts +22 -38
  26. package/src/grid/plugins/BarStack.ts +16 -3
  27. package/src/grid/plugins/Bars.ts +18 -4
  28. package/src/grid/plugins/BarsDiverging.ts +6 -4
  29. package/src/grid/plugins/BarsTriangle.ts +20 -4
  30. package/src/grid/plugins/Dots.ts +4 -2
  31. package/src/grid/plugins/GroupAux.ts +1 -2
  32. package/src/grid/plugins/GroupAxis.ts +15 -3
  33. package/src/grid/plugins/LineAreas.ts +5 -2
  34. package/src/grid/plugins/Lines.ts +5 -2
  35. package/src/grid/plugins/ScalingArea.ts +0 -1
  36. package/src/grid/plugins/ValueAxis.ts +15 -3
  37. package/src/grid/plugins/ValueStackAxis.ts +14 -5
  38. package/src/multiGrid/multiGridObservables.ts +14 -261
  39. package/src/multiGrid/plugins/MultiBarStack.ts +22 -8
  40. package/src/multiGrid/plugins/MultiBars.ts +21 -7
  41. package/src/multiGrid/plugins/MultiBarsTriangle.ts +22 -7
  42. package/src/multiGrid/plugins/MultiDots.ts +7 -5
  43. package/src/multiGrid/plugins/MultiGridLegend.ts +1 -1
  44. package/src/multiGrid/plugins/MultiGroupAxis.ts +19 -7
  45. package/src/multiGrid/plugins/MultiLineAreas.ts +9 -6
  46. package/src/multiGrid/plugins/MultiLines.ts +9 -6
  47. package/src/multiGrid/plugins/MultiValueAxis.ts +19 -7
  48. package/src/multiGrid/plugins/OverlappingValueAxes.ts +52 -47
  49. package/src/noneData/defaults.ts +3 -0
  50. package/src/series/defaults.ts +13 -3
  51. package/src/series/plugins/Bubbles.ts +139 -88
  52. package/src/series/plugins/Pie.ts +307 -352
  53. package/src/series/plugins/PieEventTexts.ts +102 -38
  54. package/src/series/plugins/PieLabels.ts +95 -48
  55. package/src/series/seriesObservables.ts +145 -0
  56. package/src/series/seriesUtils.ts +4 -4
  57. package/tsconfig.json +1 -1
@@ -1,44 +1,46 @@
1
1
  import * as d3 from 'd3'
2
2
  import {
3
- of,
4
3
  combineLatest,
5
4
  map,
6
- merge,
7
- take,
8
- filter,
9
5
  switchMap,
10
- first,
11
6
  takeUntil,
12
7
  distinctUntilChanged,
13
- BehaviorSubject,
14
- Subject,
15
- Observable } from 'rxjs'
16
- import {
17
- defineSeriesPlugin } from '@orbcharts/core'
8
+ shareReplay,
9
+ Observable,
10
+ Subject } from 'rxjs'
18
11
  import type {
19
- ChartParams } from '@orbcharts/core'
20
- import type { PieParams } from '../types'
12
+ ComputedDataSeries,
13
+ ComputedDatumSeries,
14
+ SeriesContainerPosition,
15
+ ChartParams,
16
+ EventSeries,
17
+ Layout } from '@orbcharts/core'
21
18
  import type { PieDatum } from '../seriesUtils'
19
+ import type { PieParams } from '../types'
20
+ import {
21
+ defineSeriesPlugin } from '@orbcharts/core'
22
22
  import { DEFAULT_PIE_PARAMS } from '../defaults'
23
23
  import { makePieData } from '../seriesUtils'
24
24
  import { getD3TransitionEase, makeD3Arc } from '../../utils/d3Utils'
25
25
  import { getClassName } from '../../utils/orbchartsUtils'
26
+ import { seriesCenterSelectionObservable } from '../seriesObservables'
27
+
26
28
 
27
29
  const pluginName = 'Pie'
28
- const pathClassName = getClassName(pluginName, 'path')
29
30
 
30
- function makeTweenPieRenderDataFn ({ enter, exit, data, lastData, fullParams }: {
31
+
32
+ function makeTweenPieRenderDataFn ({ enter, exit, data, lastTweenData, fullParams }: {
31
33
  enter: d3.Selection<d3.EnterElement, PieDatum, any, any>
32
34
  exit: d3.Selection<SVGPathElement, unknown, any, any>
33
35
  data: PieDatum[]
34
- lastData: PieDatum[]
36
+ lastTweenData: PieDatum[]
35
37
  fullParams: PieParams
36
38
  }): (t: number) => PieDatum[] {
37
39
  // 無更新資料項目則只計算資料變化 (新資料 * t + 舊資料 * (1 - t))
38
40
  if (!enter.size() && !exit.size()) {
39
41
  return (t: number) => {
40
42
  const tweenData: PieDatum[] = data.map((_d, _i) => {
41
- const lastDatum = lastData[_i] ?? {
43
+ const lastDatum = lastTweenData[_i] ?? {
42
44
  startAngle: 0,
43
45
  endAngle: 0,
44
46
  value: 0
@@ -83,31 +85,23 @@ function makePieRenderData (data: PieDatum[], startAngle: number, endAngle: numb
83
85
  })
84
86
  }
85
87
 
86
- function renderPie ({ selection, renderData, arc }: {
88
+ function renderPie ({ selection, data, arc, pathClassName }: {
87
89
  selection: d3.Selection<SVGGElement, unknown, any, unknown>
88
- renderData: PieDatum[]
90
+ data: PieDatum[]
89
91
  arc: d3.Arc<any, d3.DefaultArcObject>
92
+ pathClassName: string
90
93
  }): d3.Selection<SVGPathElement, PieDatum, any, any> {
91
- let update: d3.Selection<SVGPathElement, PieDatum, any, any> = selection
94
+ // console.log('data', data)
95
+ const pathSelection: d3.Selection<SVGPathElement, PieDatum, any, any> = selection
92
96
  .selectAll<SVGPathElement, PieDatum>('path')
93
- .data(renderData, d => d.id)
94
- let enter = update.enter()
95
- .append<SVGPathElement>('path')
97
+ .data(data, d => d.id)
98
+ .join('path')
96
99
  .classed(pathClassName, true)
97
- let exit = update.exit()
98
-
99
- enter
100
- .append('path')
101
-
102
- const pathSelection = update.merge(enter)
103
- pathSelection
104
100
  .style('cursor', 'pointer')
105
101
  .attr('fill', (d, i) => d.data.color)
106
- // .transition()
107
102
  .attr('d', (d, i) => {
108
103
  return arc!(d as any)
109
104
  })
110
- exit.remove()
111
105
 
112
106
  return pathSelection
113
107
  }
@@ -162,60 +156,70 @@ function highlight ({ pathSelection, ids, fullChartParams, arc, arcMouseover }:
162
156
  })
163
157
  }
164
158
 
165
-
166
- export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selection, name, observer, subject }) => {
167
-
159
+ // 各別的pie
160
+ function createEachPie (pluginName: string, context: {
161
+ containerSelection: d3.Selection<SVGGElement, any, any, unknown>
162
+ computedData$: Observable<ComputedDatumSeries[][]>
163
+ containerComputedLayoutData$: Observable<ComputedDatumSeries[]>
164
+ SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
165
+ fullParams$: Observable<PieParams>
166
+ fullChartParams$: Observable<ChartParams>
167
+ seriesHighlight$: Observable<ComputedDatumSeries[]>
168
+ seriesContainerPosition$: Observable<SeriesContainerPosition>
169
+ event$: Subject<EventSeries>
170
+ }) {
168
171
  const destroy$ = new Subject()
169
172
 
170
- const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
171
- // let pathSelection: d3.Selection<SVGPathElement, PieDatum, any, any> | undefined
172
- const pathSelection$: Subject<d3.Selection<SVGPathElement, PieDatum, any, any>> = new Subject()
173
- let lastData: PieDatum[] = []
174
- let renderData: PieDatum[] = []
173
+ const pathClassName = getClassName(pluginName, 'path')
174
+
175
+ let lastTweenData: PieDatum[] = [] // 紀錄補間動畫前次的資料
176
+ let tweenData: PieDatum[] = [] // 紀錄補間動畫用的資料
175
177
  // let originHighlight: Highlight | null = null
176
178
 
177
- observer.layout$
178
- .pipe(
179
- first()
180
- )
181
- .subscribe(size => {
182
- selection
183
- .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
184
- observer.layout$
185
- .pipe(
186
- takeUntil(destroy$)
187
- )
188
- .subscribe(size => {
189
- selection
190
- .transition()
191
- .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
192
- })
193
- })
179
+ // context.layout$
180
+ // .pipe(
181
+ // first()
182
+ // )
183
+ // .subscribe(size => {
184
+ // selection
185
+ // .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
186
+ // context.layout$
187
+ // .pipe(
188
+ // takeUntil(destroy$)
189
+ // )
190
+ // .subscribe(size => {
191
+ // selection
192
+ // .transition()
193
+ // .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
194
+ // })
195
+ // })
194
196
 
195
- const shorterSideWith$ = observer.layout$.pipe(
197
+
198
+ const shorterSideWith$ = context.seriesContainerPosition$.pipe(
196
199
  takeUntil(destroy$),
197
200
  map(d => d.width < d.height ? d.width : d.height)
198
201
  )
199
202
 
200
203
  const pieData$: Observable<PieDatum[]> = new Observable(subscriber => {
201
204
  combineLatest({
202
- computedData: observer.computedData$,
203
- fullParams: observer.fullParams$,
205
+ containerComputedLayoutData: context.containerComputedLayoutData$,
206
+ fullParams: context.fullParams$,
204
207
  }).pipe(
205
208
  takeUntil(destroy$),
206
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
207
209
  switchMap(async (d) => d),
208
210
  ).subscribe(data => {
211
+ // console.log('pieData', data)
209
212
  const pieData: PieDatum[] = makePieData({
210
- computedDataSeries: data.computedData,
213
+ data: data.containerComputedLayoutData,
211
214
  startAngle: data.fullParams.startAngle,
212
215
  endAngle: data.fullParams.endAngle
213
216
  })
217
+ // console.log('pieData', pieData)
214
218
  subscriber.next(pieData)
215
219
  })
216
220
  })
217
221
 
218
- // const SeriesDataMap$ = observer.computedData$.pipe(
222
+ // const SeriesDataMap$ = context.computedData$.pipe(
219
223
  // takeUntil(destroy$),
220
224
  // map(d => makeSeriesDataMap(d))
221
225
  // )
@@ -223,10 +227,9 @@ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selecti
223
227
  const arc$: Observable<d3.Arc<any, d3.DefaultArcObject>> = new Observable(subscriber => {
224
228
  combineLatest({
225
229
  shorterSideWith: shorterSideWith$,
226
- fullParams: observer.fullParams$,
230
+ fullParams: context.fullParams$,
227
231
  }).pipe(
228
232
  takeUntil(destroy$),
229
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
230
233
  switchMap(async (d) => d),
231
234
  ).subscribe(data => {
232
235
  const arc = makeD3Arc({
@@ -243,10 +246,9 @@ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selecti
243
246
  const arcMouseover$: Observable<d3.Arc<any, d3.DefaultArcObject>> = new Observable(subscriber => {
244
247
  combineLatest({
245
248
  shorterSideWith: shorterSideWith$,
246
- fullParams: observer.fullParams$,
249
+ fullParams: context.fullParams$,
247
250
  }).pipe(
248
251
  takeUntil(destroy$),
249
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
250
252
  switchMap(async (d) => d),
251
253
  ).subscribe(data => {
252
254
  const arcMouseover = makeD3Arc({
@@ -260,76 +262,112 @@ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selecti
260
262
  })
261
263
  })
262
264
 
263
- // combineLatest({
264
- // pieData: pieData$,
265
- // SeriesDataMap: SeriesDataMap$,
266
- // arc: arc$,
267
- // arcMouseover: arcMouseover$,
268
- // computedData: computedData$,
269
- // fullParams: fullParams$,
270
- // // fullChartParams: fullChartParams$
271
- // }).pipe(
272
- // takeUntil(destroy$),
273
- // // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
274
- // switchMap(d => combineLatest({
275
- // pieData: pieData$,
276
- // SeriesDataMap: SeriesDataMap$,
277
- // arc: arc$,
278
- // arcMouseover: arcMouseover$,
279
- // computedData: computedData$,
280
- // fullParams: fullParams$,
281
- // fullChartParams: fullChartParams$
282
- // })),
283
- // take(1)
284
- const highlightTarget$ = observer.fullChartParams$.pipe(
265
+ const highlightTarget$ = context.fullChartParams$.pipe(
285
266
  takeUntil(destroy$),
286
267
  map(d => d.highlightTarget),
287
268
  distinctUntilChanged()
288
269
  )
289
270
 
290
- combineLatest({
291
- pieData: pieData$,
292
- SeriesDataMap: observer.SeriesDataMap$,
293
- arc: arc$,
294
- arcMouseover: arcMouseover$,
295
- computedData: observer.computedData$,
296
- fullParams: observer.fullParams$,
297
- fullChartParams: observer.fullChartParams$,
298
- highlightTarget: highlightTarget$
299
- }).pipe(
300
- takeUntil(destroy$),
301
- switchMap(async d => d)
302
- ).subscribe(data => {
303
- graphicGSelection.interrupt('graphicMove')
304
- // console.log('graphic', data)
305
- let update: d3.Selection<SVGPathElement, PieDatum, any, any> = selection
306
- .selectAll<SVGPathElement, PieDatum>('path')
307
- .data(data.pieData, d => d.data.id)
308
- let enter = update.enter()
309
- let exit = update.exit()
310
-
311
- const makeTweenPieRenderData = makeTweenPieRenderDataFn({
312
- enter,
313
- exit,
314
- data: data.pieData,
315
- lastData,
316
- fullParams: data.fullParams
317
- })
318
-
319
- graphicGSelection
320
- .transition('graphicMove')
321
- .duration(data.fullChartParams.transitionDuration)
322
- .ease(getD3TransitionEase(data.fullChartParams.transitionEase))
323
- .tween('move', (self, t) => {
324
- return (t) => {
325
- renderData = makeTweenPieRenderData(t)
326
-
327
- const pathSelection = renderPie({ selection: graphicGSelection, renderData, arc: data.arc })
328
-
329
- subject.event$.next({
271
+ const pathSelection$ = new Observable<d3.Selection<SVGPathElement, PieDatum, any, any>>(subscriber => {
272
+ combineLatest({
273
+ pieData: pieData$,
274
+ arc: arc$,
275
+ computedData: context.computedData$,
276
+ fullParams: context.fullParams$,
277
+ fullChartParams: context.fullChartParams$,
278
+ highlightTarget: highlightTarget$
279
+ }).pipe(
280
+ takeUntil(destroy$),
281
+ switchMap(async d => d)
282
+ ).subscribe(data => {
283
+ context.containerSelection.interrupt('graphicMove')
284
+ // console.log('graphic', data)
285
+ let update: d3.Selection<SVGPathElement, PieDatum, any, any> = context.containerSelection
286
+ .selectAll<SVGPathElement, PieDatum>('path')
287
+ .data(data.pieData, d => d.id)
288
+ let enter = update.enter()
289
+ let exit = update.exit()
290
+
291
+ const makeTweenPieRenderData = makeTweenPieRenderDataFn({
292
+ enter,
293
+ exit,
294
+ data: data.pieData,
295
+ lastTweenData,
296
+ fullParams: data.fullParams
297
+ })
298
+
299
+ // -- enter資料使用補間動畫 --
300
+ enter
301
+ .transition('graphicMove')
302
+ .duration(data.fullChartParams.transitionDuration)
303
+ .ease(getD3TransitionEase(data.fullChartParams.transitionEase))
304
+ .tween('move', (self, t) => {
305
+ return (t) => {
306
+ tweenData = makeTweenPieRenderData(t)
307
+
308
+ const pathSelection = renderPie({
309
+ selection: context.containerSelection,
310
+ data: tweenData,
311
+ arc: data.arc,
312
+ pathClassName
313
+ })
314
+
315
+ context.event$.next({
316
+ type: 'series',
317
+ pluginName,
318
+ eventName: 'transitionMove',
319
+ event: undefined,
320
+ highlightTarget: data.highlightTarget,
321
+ datum: null,
322
+ series: [],
323
+ seriesIndex: -1,
324
+ seriesLabel: '',
325
+ data: data.computedData
326
+ })
327
+ // const callbackData = makeEnterDurationCallbackData(data.computedData, )
328
+ // enterDurationCallback(callbackData, t)
329
+ }
330
+ })
331
+ .on('end', (self, t) => {
332
+ tweenData = makePieRenderData(
333
+ data.pieData,
334
+ data.fullParams.startAngle,
335
+ data.fullParams.endAngle,
336
+ 1
337
+ )
338
+ // console.log('tweenData', tweenData)
339
+ const pathSelection = renderPie({
340
+ selection: context.containerSelection,
341
+ data: tweenData,
342
+ arc: data.arc,
343
+ pathClassName
344
+ })
345
+
346
+ // if (data.fullParams.highlightTarget && data.fullParams.highlightTarget != 'none') {
347
+ // if (data.fullChartParams.highlightTarget && data.fullChartParams.highlightTarget != 'none') {
348
+ // pathSelection!.style('cursor', 'pointer')
349
+ // }
350
+
351
+ subscriber.next(pathSelection)
352
+
353
+ // pathSelection && setPathEvent({
354
+ // pathSelection,
355
+ // pluginName: name,
356
+ // data: data.computedData,
357
+ // fullChartParams: data.fullChartParams,
358
+ // arc: data.arc,
359
+ // arcMouseover: data.arcMouseover,
360
+ // SeriesDataMap: data.SeriesDataMap,
361
+ // event$: store.event$
362
+ // })
363
+
364
+ // 渲染完後紀錄為前次的資料
365
+ lastTweenData = Object.assign([], data.pieData)
366
+
367
+ context.event$.next({
330
368
  type: 'series',
331
- pluginName: name,
332
- eventName: 'transitionMove',
369
+ pluginName,
370
+ eventName: 'transitionEnd',
333
371
  event: undefined,
334
372
  highlightTarget: data.highlightTarget,
335
373
  datum: null,
@@ -338,183 +376,106 @@ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selecti
338
376
  seriesLabel: '',
339
377
  data: data.computedData
340
378
  })
341
- // const callbackData = makeEnterDurationCallbackData(data.computedData, )
342
- // enterDurationCallback(callbackData, t)
343
- }
344
- })
345
- .on('end', (self, t) => {
346
- renderData = makePieRenderData(
347
- data.pieData,
348
- data.fullParams.startAngle,
349
- data.fullParams.endAngle,
350
- 1
351
- )
352
- // console.log('renderData', renderData)
353
- const pathSelection = renderPie({ selection: graphicGSelection, renderData, arc: data.arc })
354
-
355
- // if (data.fullParams.highlightTarget && data.fullParams.highlightTarget != 'none') {
356
- // if (data.fullChartParams.highlightTarget && data.fullChartParams.highlightTarget != 'none') {
357
- // pathSelection!.style('cursor', 'pointer')
358
- // }
359
-
360
- pathSelection$.next(pathSelection)
361
-
362
- // pathSelection && setPathEvent({
363
- // pathSelection,
364
- // pluginName: name,
365
- // data: data.computedData,
366
- // fullChartParams: data.fullChartParams,
367
- // arc: data.arc,
368
- // arcMouseover: data.arcMouseover,
369
- // SeriesDataMap: data.SeriesDataMap,
370
- // event$: store.event$
371
- // })
379
+
380
+
381
+ })
382
+
383
+ // -- 更新資料 --
384
+ if (!enter.size() && update.size() > 0) {
385
+ // console.log('test')
386
+ const pathSelection = renderPie({
387
+ selection: context.containerSelection,
388
+ data: data.pieData,
389
+ arc: data.arc,
390
+ pathClassName
391
+ })
392
+ subscriber.next(pathSelection)
393
+ }
394
+ })
395
+ })
372
396
 
373
- // 渲染完後紀錄為前次的資料
374
- lastData = Object.assign([], data.pieData)
397
+ combineLatest({
398
+ pathSelection: pathSelection$,
399
+ SeriesDataMap: context.SeriesDataMap$,
400
+ computedData: context.computedData$,
401
+ highlightTarget: highlightTarget$
402
+ }).pipe(
403
+ takeUntil(destroy$),
404
+ switchMap(async d => d)
405
+ ).subscribe(data => {
406
+ data.pathSelection
407
+ .on('mouseover', (event, pieDatum) => {
408
+ event.stopPropagation()
375
409
 
376
- subject.event$.next({
410
+ context.event$.next({
377
411
  type: 'series',
378
- pluginName: name,
379
- eventName: 'transitionEnd',
380
- event: undefined,
412
+ eventName: 'mouseover',
413
+ pluginName,
381
414
  highlightTarget: data.highlightTarget,
382
- datum: null,
383
- series: [],
384
- seriesIndex: -1,
385
- seriesLabel: '',
415
+ datum: pieDatum.data,
416
+ series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
417
+ seriesIndex: pieDatum.data.seriesIndex,
418
+ seriesLabel: pieDatum.data.seriesLabel,
419
+ event,
386
420
  data: data.computedData
387
421
  })
422
+ })
423
+ .on('mousemove', (event, pieDatum) => {
424
+ event.stopPropagation()
388
425
 
389
- pathSelection!
390
- .on('mouseover', (event, pieDatum) => {
391
- event.stopPropagation()
392
-
393
- subject.event$.next({
394
- type: 'series',
395
- eventName: 'mouseover',
396
- pluginName: name,
397
- highlightTarget: data.highlightTarget,
398
- datum: pieDatum.data,
399
- series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
400
- seriesIndex: pieDatum.data.seriesIndex,
401
- seriesLabel: pieDatum.data.seriesLabel,
402
- event,
403
- data: data.computedData
404
- })
405
- })
406
- .on('mousemove', (event, pieDatum) => {
407
- event.stopPropagation()
408
-
409
- subject.event$.next({
410
- type: 'series',
411
- eventName: 'mousemove',
412
- pluginName: name,
413
- highlightTarget: data.highlightTarget,
414
- datum: pieDatum.data,
415
- series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
416
- seriesIndex: pieDatum.data.seriesIndex,
417
- seriesLabel: pieDatum.data.seriesLabel,
418
- event,
419
- data: data.computedData,
420
- })
421
- })
422
- .on('mouseout', (event, pieDatum) => {
423
- event.stopPropagation()
426
+ context.event$.next({
427
+ type: 'series',
428
+ eventName: 'mousemove',
429
+ pluginName,
430
+ highlightTarget: data.highlightTarget,
431
+ datum: pieDatum.data,
432
+ series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
433
+ seriesIndex: pieDatum.data.seriesIndex,
434
+ seriesLabel: pieDatum.data.seriesLabel,
435
+ event,
436
+ data: data.computedData,
437
+ })
438
+ })
439
+ .on('mouseout', (event, pieDatum) => {
440
+ event.stopPropagation()
424
441
 
425
- subject.event$.next({
426
- type: 'series',
427
- eventName: 'mouseout',
428
- pluginName: name,
429
- highlightTarget: data.highlightTarget,
430
- datum: pieDatum.data,
431
- series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
432
- seriesIndex: pieDatum.data.seriesIndex,
433
- seriesLabel: pieDatum.data.seriesLabel,
434
- event,
435
- data: data.computedData,
436
- })
437
- })
438
- .on('click', (event, pieDatum) => {
439
- event.stopPropagation()
442
+ context.event$.next({
443
+ type: 'series',
444
+ eventName: 'mouseout',
445
+ pluginName,
446
+ highlightTarget: data.highlightTarget,
447
+ datum: pieDatum.data,
448
+ series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
449
+ seriesIndex: pieDatum.data.seriesIndex,
450
+ seriesLabel: pieDatum.data.seriesLabel,
451
+ event,
452
+ data: data.computedData,
453
+ })
454
+ })
455
+ .on('click', (event, pieDatum) => {
456
+ event.stopPropagation()
440
457
 
441
- subject.event$.next({
442
- type: 'series',
443
- eventName: 'click',
444
- pluginName: name,
445
- highlightTarget: data.highlightTarget,
446
- datum: pieDatum.data,
447
- series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
448
- seriesIndex: pieDatum.data.seriesIndex,
449
- seriesLabel: pieDatum.data.seriesLabel,
450
- event,
451
- data: data.computedData,
452
- })
453
- })
458
+ context.event$.next({
459
+ type: 'series',
460
+ eventName: 'click',
461
+ pluginName,
462
+ highlightTarget: data.highlightTarget,
463
+ datum: pieDatum.data,
464
+ series: data.SeriesDataMap.get(pieDatum.data.seriesLabel)!,
465
+ seriesIndex: pieDatum.data.seriesIndex,
466
+ seriesLabel: pieDatum.data.seriesLabel,
467
+ event,
468
+ data: data.computedData,
469
+ })
454
470
  })
455
471
  })
456
472
 
457
- // 事件觸發的highlight
458
- // const highlightMouseover$ = store.event$.pipe(
459
- // takeUntil(destroy$),
460
- // filter(d => d.eventName === 'mouseover'),
461
- // // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
462
- // map(d => {
463
- // return d.datum
464
- // ? { id: d.datum?.id, label: d.datum.label }
465
- // : { id: '', label: '' }
466
- // })
467
- // )
468
- // const highlightMouseout$ = store.event$.pipe(
469
- // takeUntil(destroy$),
470
- // filter(d => d.eventName === 'mouseout'),
471
- // // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
472
- // map(d => {
473
- // return { id: '', label: '' }
474
- // })
475
- // )
476
-
477
- // // 預設的highlight
478
- // const highlightDefault$ = fullChartParams$.pipe(
479
- // takeUntil(destroy$),
480
- // map(d => {
481
- // return { id: d.highlightDefault, label: d.highlightDefault }
482
- // })
483
- // )
484
-
485
- // combineLatest({
486
- // target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
487
- // pathSelection: pathSelection$,
488
- // computedData: computedData$,
489
- // fullChartParams: fullChartParams$,
490
- // arc: arc$,
491
- // arcMouseover: arcMouseover$
492
- // }).pipe(
493
- // takeUntil(destroy$)
494
- // ).subscribe(data => {
495
- // // console.log('target', data.target)
496
- // const ids = getSeriesHighlightIds({
497
- // id: data.target.id,
498
- // label: data.target.label,
499
- // trigger: data.fullChartParams.highlightDefault.trigger,
500
- // data: data.computedData
501
- // })
502
- // // console.log('ids', ids)
503
- // highlight({
504
- // pathSelection: data.pathSelection,
505
- // ids: ids,
506
- // fullChartParams: data.fullChartParams,
507
- // arc: data.arc,
508
- // arcMouseover: data.arcMouseover
509
- // })
510
- // })
511
-
512
473
  combineLatest({
513
474
  pathSelection: pathSelection$,
514
- highlight: observer.seriesHighlight$.pipe(
475
+ highlight: context.seriesHighlight$.pipe(
515
476
  map(data => data.map(d => d.id))
516
477
  ),
517
- fullChartParams: observer.fullChartParams$,
478
+ fullChartParams: context.fullChartParams$,
518
479
  arc: arc$,
519
480
  arcMouseover: arcMouseover$
520
481
  }).pipe(
@@ -530,72 +491,66 @@ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selecti
530
491
  })
531
492
  })
532
493
 
533
- // d.fullParams
494
+ return () => {
495
+ destroy$.next(undefined)
496
+ }
497
+ }
534
498
 
535
- // console.log('selection', selection)
499
+ export const Pie = defineSeriesPlugin(pluginName, DEFAULT_PIE_PARAMS)(({ selection, name, subject, observer }) => {
500
+ const destroy$ = new Subject()
536
501
 
537
- // fullChartParams$
538
- // .subscribe(d => {
539
- // console.log('fullChartParams', d)
540
- // })
502
+ const { seriesCenterSelection$ } = seriesCenterSelectionObservable({
503
+ selection: selection,
504
+ pluginName,
505
+ separateSeries$: observer.separateSeries$,
506
+ seriesLabels$: observer.seriesLabels$,
507
+ seriesContainerPosition$: observer.seriesContainerPosition$
508
+ })
541
509
 
542
- // computedData$
543
- // .subscribe(d => {
544
- // console.log('computedData', d)
545
- // })
546
- // console.log('-- defineSeriesPlugin --')
547
- // console.log('selector', selector)
548
- // // data$.subscribe(d => {
549
- // // console.log('data$', d)
550
- // // })
551
-
552
- // store.dataFormatter$.subscribe(d => {
553
- // console.log('store.dataFormatter$', d)
554
- // })
555
-
556
- // computedData$.subscribe(d => {
557
- // console.log('computedData$', d)
558
- // })
559
-
560
- // event$.subscribe(d => {
561
- // console.log('event$', d)
562
- // })
563
-
564
- // fullParams$.subscribe(d => {
565
- // console.log('fullParams$', d)
566
- // })
567
-
568
- // store.data$.subscribe(d => {
569
- // console.log('store.data$', d)
570
- // })
571
-
572
- // store.dataFormatter$.subscribe(d => {
573
- // console.log('store.dataFormatter$', d)
574
- // })
575
-
576
- // store.event$.subscribe(d => {
577
- // console.log('store.event$', d)
578
- // })
579
-
580
- // store.fullParams$.subscribe(d => {
581
- // console.log('store.fullParams$', d)
582
- // })
583
-
584
- // layout$.subscribe(d => {
585
- // console.log('layout$', d)
586
- // })
587
-
588
- // console.log('-- end --')
589
- // // const newData = data.map(d => d.map(_d => {
590
- // // return {
591
- // // ..._d as any,
592
- // // value: (_d as any).value + 10
593
- // // }
594
- // // }))
595
-
596
- // // data$.next(newData)
510
+ const unsubscribeFnArr: (() => void)[] = []
511
+
512
+ // @Q@ 在seriesCenterSelection$之後才訂閱會造成fullParams$訂閱不到最初次的值,還需找時間研究先workaround
513
+ observer.fullParams$.subscribe()
514
+
515
+ seriesCenterSelection$.subscribe(seriesCenterSelection => {
516
+ // 每次重新計算時,清除之前的訂閱
517
+ unsubscribeFnArr.forEach(fn => fn())
518
+
519
+ // observer.fullParams$.subscribe(data => {
520
+ // console.log('observer.fullParams$', data)
521
+ // })
522
+
523
+ seriesCenterSelection.each((d, containerIndex, g) => {
524
+ // console.log('containerIndex', containerIndex)
525
+ const containerSelection = d3.select(g[containerIndex])
526
+
527
+ const containerComputedLayoutData$ = observer.computedLayoutData$.pipe(
528
+ takeUntil(destroy$),
529
+ map(data => data[containerIndex] ?? data[0])
530
+ )
531
+
532
+ const containerPosition$ = observer.seriesContainerPosition$.pipe(
533
+ takeUntil(destroy$),
534
+ map(data => data[containerIndex] ?? data[0])
535
+ )
536
+
537
+ unsubscribeFnArr[containerIndex] = createEachPie(pluginName, {
538
+ containerSelection: containerSelection,
539
+ computedData$: observer.computedData$,
540
+ containerComputedLayoutData$: containerComputedLayoutData$,
541
+ SeriesDataMap$: observer.SeriesDataMap$,
542
+ fullParams$: observer.fullParams$,
543
+ fullChartParams$: observer.fullChartParams$,
544
+ seriesHighlight$: observer.seriesHighlight$,
545
+ seriesContainerPosition$: containerPosition$,
546
+ event$: subject.event$,
547
+ })
548
+
549
+ })
550
+ })
597
551
 
598
552
  return () => {
599
553
  destroy$.next(undefined)
554
+ unsubscribeFnArr.forEach(fn => fn())
600
555
  }
601
556
  })