@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.
- package/dist/orbcharts-plugins-basic.es.js +7770 -7580
- package/dist/orbcharts-plugins-basic.umd.js +8 -8
- package/dist/src/base/BaseBarStack.d.ts +6 -4
- package/dist/src/base/BaseBars.d.ts +6 -4
- package/dist/src/base/BaseBarsTriangle.d.ts +7 -4
- package/dist/src/base/BaseDots.d.ts +5 -3
- package/dist/src/base/BaseGroupAxis.d.ts +3 -3
- package/dist/src/base/BaseLineAreas.d.ts +6 -3
- package/dist/src/base/BaseLines.d.ts +6 -3
- package/dist/src/base/BaseValueAxis.d.ts +3 -3
- package/dist/src/grid/gridObservables.d.ts +4 -4
- package/dist/src/multiGrid/multiGridObservables.d.ts +2 -6
- package/dist/src/series/plugins/PieEventTexts.d.ts +3 -1
- package/dist/src/series/seriesObservables.d.ts +21 -0
- package/dist/src/series/seriesUtils.d.ts +3 -3
- package/package.json +2 -2
- package/src/base/BaseBarStack.ts +105 -208
- package/src/base/BaseBars.ts +78 -64
- package/src/base/BaseBarsTriangle.ts +76 -63
- package/src/base/BaseDots.ts +41 -178
- package/src/base/BaseGroupAxis.ts +13 -13
- package/src/base/BaseLineAreas.ts +85 -81
- package/src/base/BaseLines.ts +82 -75
- package/src/base/BaseValueAxis.ts +14 -15
- package/src/grid/gridObservables.ts +22 -38
- package/src/grid/plugins/BarStack.ts +16 -3
- package/src/grid/plugins/Bars.ts +18 -4
- package/src/grid/plugins/BarsDiverging.ts +6 -4
- package/src/grid/plugins/BarsTriangle.ts +20 -4
- package/src/grid/plugins/Dots.ts +4 -2
- package/src/grid/plugins/GroupAux.ts +1 -2
- package/src/grid/plugins/GroupAxis.ts +15 -3
- package/src/grid/plugins/LineAreas.ts +5 -2
- package/src/grid/plugins/Lines.ts +5 -2
- package/src/grid/plugins/ScalingArea.ts +0 -1
- package/src/grid/plugins/ValueAxis.ts +15 -3
- package/src/grid/plugins/ValueStackAxis.ts +14 -5
- package/src/multiGrid/multiGridObservables.ts +14 -261
- package/src/multiGrid/plugins/MultiBarStack.ts +22 -8
- package/src/multiGrid/plugins/MultiBars.ts +21 -7
- package/src/multiGrid/plugins/MultiBarsTriangle.ts +22 -7
- package/src/multiGrid/plugins/MultiDots.ts +7 -5
- package/src/multiGrid/plugins/MultiGridLegend.ts +1 -1
- package/src/multiGrid/plugins/MultiGroupAxis.ts +19 -7
- package/src/multiGrid/plugins/MultiLineAreas.ts +9 -6
- package/src/multiGrid/plugins/MultiLines.ts +9 -6
- package/src/multiGrid/plugins/MultiValueAxis.ts +19 -7
- package/src/multiGrid/plugins/OverlappingValueAxes.ts +52 -47
- package/src/noneData/defaults.ts +3 -0
- package/src/series/defaults.ts +13 -3
- package/src/series/plugins/Bubbles.ts +139 -88
- package/src/series/plugins/Pie.ts +307 -352
- package/src/series/plugins/PieEventTexts.ts +102 -38
- package/src/series/plugins/PieLabels.ts +95 -48
- package/src/series/seriesObservables.ts +145 -0
- package/src/series/seriesUtils.ts +4 -4
- package/tsconfig.json +1 -1
package/src/base/BaseDots.ts
CHANGED
@@ -11,9 +11,10 @@ import type { BasePluginFn } from './types'
|
|
11
11
|
import type {
|
12
12
|
ComputedDatumGrid,
|
13
13
|
ComputedDataGrid,
|
14
|
+
ComputedLayoutDataGrid,
|
14
15
|
EventGrid,
|
15
16
|
ChartParams,
|
16
|
-
|
17
|
+
GridContainerPosition,
|
17
18
|
Layout,
|
18
19
|
TransformData,
|
19
20
|
ColorType } from '@orbcharts/core'
|
@@ -31,8 +32,10 @@ export interface BaseDotsParams {
|
|
31
32
|
interface BaseDotsContext {
|
32
33
|
selection: d3.Selection<any, unknown, any, unknown>
|
33
34
|
computedData$: Observable<ComputedDataGrid>
|
35
|
+
computedLayoutData$: Observable<ComputedLayoutDataGrid>
|
34
36
|
visibleComputedData$: Observable<ComputedDatumGrid[][]>
|
35
|
-
|
37
|
+
visibleComputedLayoutData$: Observable<ComputedLayoutDataGrid>
|
38
|
+
seriesLabels$: Observable<string[]>
|
36
39
|
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
37
40
|
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
38
41
|
fullParams$: Observable<BaseDotsParams>
|
@@ -45,7 +48,7 @@ interface BaseDotsContext {
|
|
45
48
|
height: number;
|
46
49
|
}>
|
47
50
|
gridHighlight$: Observable<ComputedDatumGrid[]>
|
48
|
-
|
51
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
49
52
|
event$: Subject<EventGrid>
|
50
53
|
}
|
51
54
|
|
@@ -62,11 +65,11 @@ type ClipPathDatum = {
|
|
62
65
|
// const circleGClassName = getClassName(pluginName, 'circleG')
|
63
66
|
// const circleClassName = getClassName(pluginName, 'circle')
|
64
67
|
|
65
|
-
function renderDots ({ graphicGSelection, circleGClassName, circleClassName,
|
68
|
+
function renderDots ({ graphicGSelection, circleGClassName, circleClassName, visibleComputedLayoutData, fullParams, fullChartParams, graphicReverseScale }: {
|
66
69
|
graphicGSelection: d3.Selection<SVGGElement, any, any, any>
|
67
70
|
circleGClassName: string
|
68
71
|
circleClassName: string
|
69
|
-
|
72
|
+
visibleComputedLayoutData: ComputedLayoutDataGrid
|
70
73
|
fullParams: BaseDotsParams
|
71
74
|
fullChartParams: ChartParams
|
72
75
|
graphicReverseScale: [number, number][]
|
@@ -83,7 +86,7 @@ function renderDots ({ graphicGSelection, circleGClassName, circleClassName, dat
|
|
83
86
|
.each((seriesData, seriesIndex, g) => {
|
84
87
|
d3.select(g[seriesIndex])
|
85
88
|
.selectAll<SVGGElement, ComputedDatumGrid>('g')
|
86
|
-
.data(
|
89
|
+
.data(visibleComputedLayoutData[seriesIndex], d => d.id)
|
87
90
|
.join(
|
88
91
|
enter => {
|
89
92
|
// enterDuration
|
@@ -256,8 +259,10 @@ function renderClipPath ({ defsSelection, clipPathData }: {
|
|
256
259
|
export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string, {
|
257
260
|
selection,
|
258
261
|
computedData$,
|
262
|
+
computedLayoutData$,
|
259
263
|
visibleComputedData$,
|
260
|
-
|
264
|
+
visibleComputedLayoutData$,
|
265
|
+
seriesLabels$,
|
261
266
|
SeriesDataMap$,
|
262
267
|
GroupDataMap$,
|
263
268
|
fullParams$,
|
@@ -267,7 +272,7 @@ export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string
|
|
267
272
|
gridGraphicReverseScale$,
|
268
273
|
gridAxesSize$,
|
269
274
|
gridHighlight$,
|
270
|
-
|
275
|
+
gridContainerPosition$,
|
271
276
|
event$
|
272
277
|
}) => {
|
273
278
|
|
@@ -282,130 +287,7 @@ export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string
|
|
282
287
|
// .attr('clip-path', `url(#${clipPathID})`)
|
283
288
|
// const defsSelection: d3.Selection<SVGDefsElement, any, any, any> = axisSelection.append('defs')
|
284
289
|
// const dataAreaSelection: d3.Selection<SVGGElement, any, any, any> = axisSelection.append('g')
|
285
|
-
const graphicSelection$: Subject<d3.Selection<SVGGElement, ComputedDatumGrid, any, any>> = new Subject()
|
286
|
-
|
287
|
-
// gridAxesTransform$
|
288
|
-
// .pipe(
|
289
|
-
// takeUntil(destroy$),
|
290
|
-
// map(d => d.value),
|
291
|
-
// distinctUntilChanged()
|
292
|
-
// ).subscribe(d => {
|
293
|
-
// axisSelection
|
294
|
-
// .style('transform', d)
|
295
|
-
// })
|
296
|
-
|
297
|
-
// gridGraphicTransform$
|
298
|
-
// .pipe(
|
299
|
-
// takeUntil(destroy$),
|
300
|
-
// switchMap(async d => d.value),
|
301
|
-
// distinctUntilChanged()
|
302
|
-
// ).subscribe(d => {
|
303
|
-
// dataAreaSelection
|
304
|
-
// .transition()
|
305
|
-
// .duration(50)
|
306
|
-
// .style('transform', d)
|
307
|
-
// })
|
308
|
-
|
309
|
-
// const seriesSelection$ = computedData$.pipe(
|
310
|
-
// takeUntil(destroy$),
|
311
|
-
// distinctUntilChanged((a, b) => {
|
312
|
-
// // 只有當series的數量改變時,才重新計算
|
313
|
-
// return a.length === b.length
|
314
|
-
// }),
|
315
|
-
// map((computedData, i) => {
|
316
|
-
// return selection
|
317
|
-
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${seriesClassName}`)
|
318
|
-
// .data(computedData, d => d[0] ? d[0].seriesIndex : i)
|
319
|
-
// .join(
|
320
|
-
// enter => {
|
321
|
-
// return enter
|
322
|
-
// .append('g')
|
323
|
-
// .classed(seriesClassName, true)
|
324
|
-
// .each((d, i, g) => {
|
325
|
-
// const axesSelection = d3.select(g[i])
|
326
|
-
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${axesClassName}`)
|
327
|
-
// .data([i])
|
328
|
-
// .join(
|
329
|
-
// enter => {
|
330
|
-
// return enter
|
331
|
-
// .append('g')
|
332
|
-
// .classed(axesClassName, true)
|
333
|
-
// .attr('clip-path', `url(#${clipPathID})`)
|
334
|
-
// .each((d, i, g) => {
|
335
|
-
// const defsSelection = d3.select(g[i])
|
336
|
-
// .selectAll<SVGDefsElement, any>('defs')
|
337
|
-
// .data([i])
|
338
|
-
// .join('defs')
|
339
|
-
|
340
|
-
// const graphicGSelection = d3.select(g[i])
|
341
|
-
// .selectAll<SVGGElement, any>('g')
|
342
|
-
// .data([i])
|
343
|
-
// .join('g')
|
344
|
-
// .classed(graphicClassName, true)
|
345
|
-
// })
|
346
|
-
// },
|
347
|
-
// update => update,
|
348
|
-
// exit => exit.remove()
|
349
|
-
// )
|
350
|
-
// })
|
351
|
-
// },
|
352
|
-
// update => update,
|
353
|
-
// exit => exit.remove()
|
354
|
-
// )
|
355
|
-
// })
|
356
|
-
// )
|
357
|
-
|
358
|
-
// combineLatest({
|
359
|
-
// seriesSelection: seriesSelection$,
|
360
|
-
// gridContainer: gridContainer$
|
361
|
-
// }).pipe(
|
362
|
-
// takeUntil(destroy$),
|
363
|
-
// switchMap(async d => d)
|
364
|
-
// ).subscribe(data => {
|
365
|
-
// data.seriesSelection
|
366
|
-
// .transition()
|
367
|
-
// .attr('transform', (d, i) => {
|
368
|
-
// const translate = data.gridContainer[i].translate
|
369
|
-
// const scale = data.gridContainer[i].scale
|
370
|
-
// return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
371
|
-
// })
|
372
|
-
// })
|
373
|
-
|
374
|
-
|
375
|
-
// const axesSelection$ = combineLatest({
|
376
|
-
// seriesSelection: seriesSelection$,
|
377
|
-
// gridAxesTransform: gridAxesTransform$
|
378
|
-
// }).pipe(
|
379
|
-
// takeUntil(destroy$),
|
380
|
-
// switchMap(async d => d),
|
381
|
-
// map(data => {
|
382
|
-
// return data.seriesSelection
|
383
|
-
// .select<SVGGElement>(`g.${axesClassName}`)
|
384
|
-
// .style('transform', data.gridAxesTransform.value)
|
385
|
-
// })
|
386
|
-
// )
|
387
|
-
// const defsSelection$ = axesSelection$.pipe(
|
388
|
-
// takeUntil(destroy$),
|
389
|
-
// map(axesSelection => {
|
390
|
-
// return axesSelection.select<SVGDefsElement>('defs')
|
391
|
-
// })
|
392
|
-
// )
|
393
|
-
// const graphicGSelection$ = combineLatest({
|
394
|
-
// axesSelection: axesSelection$,
|
395
|
-
// gridGraphicTransform: gridGraphicTransform$
|
396
|
-
// }).pipe(
|
397
|
-
// takeUntil(destroy$),
|
398
|
-
// switchMap(async d => d),
|
399
|
-
// map(data => {
|
400
|
-
// const graphicGSelection = data.axesSelection
|
401
|
-
// .select<SVGGElement>(`g.${graphicClassName}`)
|
402
|
-
// graphicGSelection
|
403
|
-
// .transition()
|
404
|
-
// .duration(50)
|
405
|
-
// .style('transform', data.gridGraphicTransform.value)
|
406
|
-
// return graphicGSelection
|
407
|
-
// })
|
408
|
-
// )
|
290
|
+
// const graphicSelection$: Subject<d3.Selection<SVGGElement, ComputedDatumGrid, any, any>> = new Subject()
|
409
291
|
|
410
292
|
const {
|
411
293
|
seriesSelection$,
|
@@ -416,15 +298,15 @@ export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string
|
|
416
298
|
selection,
|
417
299
|
pluginName,
|
418
300
|
clipPathID,
|
419
|
-
|
420
|
-
|
301
|
+
seriesLabels$,
|
302
|
+
gridContainerPosition$,
|
421
303
|
gridAxesTransform$,
|
422
304
|
gridGraphicTransform$
|
423
305
|
})
|
424
306
|
|
425
307
|
const graphicReverseScale$: Observable<[number, number][]> = combineLatest({
|
426
308
|
// gridGraphicTransform: gridGraphicTransform$,
|
427
|
-
//
|
309
|
+
// gridContainerPosition: gridContainerPosition$,
|
428
310
|
// gridAxesTransform: gridAxesTransform$
|
429
311
|
computedData: computedData$,
|
430
312
|
gridGraphicReverseScale: gridGraphicReverseScale$
|
@@ -457,63 +339,46 @@ export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string
|
|
457
339
|
})
|
458
340
|
})
|
459
341
|
|
460
|
-
// const visibleComputedData$ = computedData$.pipe(
|
461
|
-
// map(computedData => {
|
462
|
-
// return computedData
|
463
|
-
// .map(d => {
|
464
|
-
// return d.filter(_d => _d.visible == true)
|
465
|
-
// })
|
466
|
-
// })
|
467
|
-
// )
|
468
|
-
|
469
|
-
// const SeriesDataMap$ = visibleComputedData$.pipe(
|
470
|
-
// map(d => makeGridSeriesDataMap(d))
|
471
|
-
// )
|
472
|
-
|
473
|
-
// const GroupDataMap$ = visibleComputedData$.pipe(
|
474
|
-
// map(d => makeGridGroupDataMap(d))
|
475
|
-
// )
|
476
|
-
|
477
|
-
// const DataMap$ = computedData$.pipe(
|
478
|
-
// map(d => {
|
479
|
-
// const DataMap: Map<string, ComputedDatumGrid> = new Map()
|
480
|
-
// d.flat().forEach(_d => DataMap.set(_d.id, _d))
|
481
|
-
// return DataMap
|
482
|
-
// })
|
483
|
-
// )
|
484
|
-
|
485
342
|
const highlightTarget$ = fullChartParams$.pipe(
|
486
343
|
takeUntil(destroy$),
|
487
344
|
map(d => d.highlightTarget),
|
488
345
|
distinctUntilChanged()
|
489
346
|
)
|
490
347
|
|
491
|
-
combineLatest({
|
348
|
+
const graphicSelection$ = combineLatest({
|
492
349
|
graphicGSelection: graphicGSelection$,
|
493
|
-
|
494
|
-
visibleComputedData: visibleComputedData$,
|
495
|
-
SeriesDataMap: SeriesDataMap$,
|
496
|
-
GroupDataMap: GroupDataMap$,
|
350
|
+
visibleComputedLayoutData: visibleComputedLayoutData$,
|
497
351
|
graphicReverseScale: graphicReverseScale$,
|
498
352
|
fullChartParams: fullChartParams$,
|
499
353
|
fullParams: fullParams$,
|
354
|
+
}).pipe(
|
355
|
+
takeUntil(destroy$),
|
356
|
+
switchMap(async (d) => d),
|
357
|
+
map(data => {
|
358
|
+
return renderDots({
|
359
|
+
graphicGSelection: data.graphicGSelection,
|
360
|
+
circleGClassName,
|
361
|
+
circleClassName,
|
362
|
+
visibleComputedLayoutData: data.visibleComputedLayoutData,
|
363
|
+
fullParams: data.fullParams,
|
364
|
+
fullChartParams: data.fullChartParams,
|
365
|
+
graphicReverseScale: data.graphicReverseScale
|
366
|
+
})
|
367
|
+
})
|
368
|
+
)
|
369
|
+
|
370
|
+
combineLatest({
|
371
|
+
graphicSelection: graphicSelection$,
|
372
|
+
computedData: computedData$,
|
373
|
+
SeriesDataMap: SeriesDataMap$,
|
374
|
+
GroupDataMap: GroupDataMap$,
|
500
375
|
highlightTarget: highlightTarget$
|
501
376
|
}).pipe(
|
502
377
|
takeUntil(destroy$),
|
503
378
|
switchMap(async (d) => d),
|
504
379
|
).subscribe(data => {
|
505
380
|
|
506
|
-
|
507
|
-
graphicGSelection: data.graphicGSelection,
|
508
|
-
circleGClassName,
|
509
|
-
circleClassName,
|
510
|
-
data: data.visibleComputedData,
|
511
|
-
fullParams: data.fullParams,
|
512
|
-
fullChartParams: data.fullChartParams,
|
513
|
-
graphicReverseScale: data.graphicReverseScale
|
514
|
-
})
|
515
|
-
|
516
|
-
graphicSelection
|
381
|
+
data.graphicSelection
|
517
382
|
.on('mouseover', (event, datum) => {
|
518
383
|
event.stopPropagation()
|
519
384
|
|
@@ -595,8 +460,6 @@ export const createBaseDots: BasePluginFn<BaseDotsContext> = (pluginName: string
|
|
595
460
|
})
|
596
461
|
})
|
597
462
|
|
598
|
-
graphicSelection$.next(graphicSelection)
|
599
|
-
|
600
463
|
})
|
601
464
|
|
602
465
|
// const datumList$ = computedData$.pipe(
|
@@ -10,7 +10,7 @@ import {
|
|
10
10
|
Observable,
|
11
11
|
Subject } from 'rxjs'
|
12
12
|
import { createAxisPointScale } from '@orbcharts/core'
|
13
|
-
import type { ColorType, ComputedDataGrid,
|
13
|
+
import type { ColorType, ComputedDataGrid, GridContainerPosition } from '@orbcharts/core'
|
14
14
|
import type { BasePluginFn } from './types'
|
15
15
|
import type {
|
16
16
|
ComputedDatumGrid,
|
@@ -51,8 +51,8 @@ interface BaseGroupAxisContext {
|
|
51
51
|
width: number;
|
52
52
|
height: number;
|
53
53
|
}>
|
54
|
-
|
55
|
-
|
54
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
55
|
+
isSeriesSeprate$: Observable<boolean>
|
56
56
|
}
|
57
57
|
|
58
58
|
interface TextAlign {
|
@@ -184,8 +184,8 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
184
184
|
gridAxesTransform$,
|
185
185
|
gridAxesReverseTransform$,
|
186
186
|
gridAxesSize$,
|
187
|
-
|
188
|
-
|
187
|
+
gridContainerPosition$,
|
188
|
+
isSeriesSeprate$,
|
189
189
|
}) => {
|
190
190
|
|
191
191
|
const destroy$ = new Subject()
|
@@ -202,12 +202,12 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
202
202
|
return a.length === b.length
|
203
203
|
}),
|
204
204
|
),
|
205
|
-
|
205
|
+
isSeriesSeprate: isSeriesSeprate$
|
206
206
|
}).pipe(
|
207
207
|
takeUntil(destroy$),
|
208
208
|
switchMap(async (d) => d),
|
209
209
|
map(data => {
|
210
|
-
return data.
|
210
|
+
return data.isSeriesSeprate
|
211
211
|
// series分開的時候顯示各別axis
|
212
212
|
? data.computedData
|
213
213
|
// series合併的時候只顯示第一個axis
|
@@ -235,16 +235,16 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
235
235
|
|
236
236
|
combineLatest({
|
237
237
|
containerSelection: containerSelection$,
|
238
|
-
|
238
|
+
gridContainerPosition: gridContainerPosition$
|
239
239
|
}).pipe(
|
240
240
|
takeUntil(destroy$),
|
241
241
|
switchMap(async d => d)
|
242
242
|
).subscribe(data => {
|
243
243
|
data.containerSelection
|
244
244
|
.attr('transform', (d, i) => {
|
245
|
-
const
|
246
|
-
const translate =
|
247
|
-
const scale =
|
245
|
+
const gridContainerPosition = data.gridContainerPosition[i] ?? data.gridContainerPosition[0]
|
246
|
+
const translate = gridContainerPosition.translate
|
247
|
+
const scale = gridContainerPosition.scale
|
248
248
|
return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
249
249
|
})
|
250
250
|
// .attr('opacity', 0)
|
@@ -326,14 +326,14 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
326
326
|
fullParams: fullParams$,
|
327
327
|
fullDataFormatter: fullDataFormatter$,
|
328
328
|
gridAxesReverseTransform: gridAxesReverseTransform$,
|
329
|
-
|
329
|
+
gridContainerPosition: gridContainerPosition$
|
330
330
|
}).pipe(
|
331
331
|
takeUntil(destroy$),
|
332
332
|
switchMap(async (d) => d),
|
333
333
|
map(data => {
|
334
334
|
const axisReverseTranslateValue = `translate(${data.gridAxesReverseTransform.translate[0]}px, ${data.gridAxesReverseTransform.translate[1]}px)`
|
335
335
|
const axisReverseRotateValue = `rotate(${data.gridAxesReverseTransform.rotate}deg) rotateX(${data.gridAxesReverseTransform.rotateX}deg) rotateY(${data.gridAxesReverseTransform.rotateY}deg)`
|
336
|
-
const containerScaleReverseScaleValue = `scale(${1 / data.
|
336
|
+
const containerScaleReverseScaleValue = `scale(${1 / data.gridContainerPosition[0].scale[0]}, ${1 / data.gridContainerPosition[0].scale[1]})`
|
337
337
|
const tickTextRotateDeg = (data.fullDataFormatter.grid.groupAxis.position === 'left' && data.fullDataFormatter.grid.valueAxis.position === 'top')
|
338
338
|
|| (data.fullDataFormatter.grid.groupAxis.position === 'right' && data.fullDataFormatter.grid.valueAxis.position === 'bottom')
|
339
339
|
? data.fullParams.tickTextRotate + 180 // 修正文字倒轉
|
@@ -12,13 +12,14 @@ import type { BasePluginFn } from './types'
|
|
12
12
|
import type {
|
13
13
|
ComputedDatumGrid,
|
14
14
|
ComputedDataGrid,
|
15
|
+
ComputedLayoutDatumGrid,
|
16
|
+
ComputedLayoutDataGrid,
|
15
17
|
DataFormatterGrid,
|
16
18
|
EventGrid,
|
17
|
-
|
19
|
+
GridContainerPosition,
|
18
20
|
ChartParams,
|
19
21
|
Layout,
|
20
22
|
TransformData } from '@orbcharts/core'
|
21
|
-
import { DATA_FORMATTER_VALUE_AXIS } from '@orbcharts/core/src/defaults'
|
22
23
|
import { createAxisLinearScale } from '@orbcharts/core'
|
23
24
|
import { getD3TransitionEase } from '../utils/d3Utils'
|
24
25
|
import { getClassName, getUniID, getMinAndMaxValue } from '../utils/orbchartsUtils'
|
@@ -34,7 +35,10 @@ export interface BaseLineAreasParams {
|
|
34
35
|
interface BaseLineAreasContext {
|
35
36
|
selection: d3.Selection<any, unknown, any, unknown>
|
36
37
|
computedData$: Observable<ComputedDataGrid>
|
37
|
-
|
38
|
+
computedLayoutData$: Observable<ComputedLayoutDataGrid>
|
39
|
+
visibleComputedData$: Observable<ComputedDatumGrid[][]>
|
40
|
+
visibleComputedLayoutData$: Observable<ComputedLayoutDataGrid>
|
41
|
+
seriesLabels$: Observable<string[]>
|
38
42
|
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
39
43
|
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
40
44
|
fullDataFormatter$: Observable<DataFormatterGrid>
|
@@ -47,7 +51,7 @@ interface BaseLineAreasContext {
|
|
47
51
|
height: number;
|
48
52
|
}>
|
49
53
|
gridHighlight$: Observable<ComputedDatumGrid[]>
|
50
|
-
|
54
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
51
55
|
layout$: Observable<Layout>
|
52
56
|
event$: Subject<EventGrid>
|
53
57
|
}
|
@@ -64,8 +68,8 @@ type ClipPathDatum = {
|
|
64
68
|
// const pathClassName = getClassName(pluginName, 'path')
|
65
69
|
|
66
70
|
|
67
|
-
function createAreaPath (lineCurve: string = 'curveLinear', valueAxisStart: number): d3.Line<
|
68
|
-
return d3.area<
|
71
|
+
function createAreaPath (lineCurve: string = 'curveLinear', valueAxisStart: number): d3.Line<ComputedLayoutDatumGrid> {
|
72
|
+
return d3.area<ComputedLayoutDatumGrid>()
|
69
73
|
.x((d) => d.axisX)
|
70
74
|
.y0(d => valueAxisStart)
|
71
75
|
.y1((d) => d.axisY)
|
@@ -74,8 +78,8 @@ function createAreaPath (lineCurve: string = 'curveLinear', valueAxisStart: numb
|
|
74
78
|
}
|
75
79
|
|
76
80
|
// 依無值的資料分段
|
77
|
-
function makeSegmentData (data:
|
78
|
-
let segmentData:
|
81
|
+
function makeSegmentData (data: ComputedLayoutDatumGrid[]): ComputedLayoutDatumGrid[][] {
|
82
|
+
let segmentData: ComputedLayoutDatumGrid[][] = [[]]
|
79
83
|
|
80
84
|
let currentIndex = 0
|
81
85
|
for (let i in data) {
|
@@ -97,17 +101,17 @@ function makeSegmentData (data: ComputedDatumGrid[]): ComputedDatumGrid[][] {
|
|
97
101
|
function renderLineAreas ({ selection, pathClassName, segmentData, areaPath, linearGradientIds, params }: {
|
98
102
|
selection: d3.Selection<SVGGElement, unknown, any, unknown>
|
99
103
|
pathClassName: string
|
100
|
-
segmentData:
|
101
|
-
areaPath: d3.Line<
|
104
|
+
segmentData: ComputedLayoutDatumGrid[][]
|
105
|
+
areaPath: d3.Line<ComputedLayoutDatumGrid>
|
102
106
|
linearGradientIds: string[]
|
103
107
|
params: BaseLineAreasParams
|
104
|
-
}): d3.Selection<SVGPathElement,
|
108
|
+
}): d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any> {
|
105
109
|
// if (!data[0]) {
|
106
110
|
// return undefined
|
107
111
|
// }
|
108
112
|
|
109
113
|
const lineAreas = selection
|
110
|
-
.selectAll<SVGPathElement,
|
114
|
+
.selectAll<SVGPathElement, ComputedLayoutDatumGrid[]>('path')
|
111
115
|
.data(segmentData, (d, i) => d.length ? `${d[0].id}_${d[d.length - 1].id}` : i) // 以線段起迄id結合為線段id
|
112
116
|
.join(
|
113
117
|
enter => {
|
@@ -256,7 +260,10 @@ function renderClipPath ({ defsSelection, clipPathData, transitionDuration, tran
|
|
256
260
|
export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginName: string, {
|
257
261
|
selection,
|
258
262
|
computedData$,
|
259
|
-
|
263
|
+
computedLayoutData$,
|
264
|
+
visibleComputedData$,
|
265
|
+
visibleComputedLayoutData$,
|
266
|
+
seriesLabels$,
|
260
267
|
SeriesDataMap$,
|
261
268
|
GroupDataMap$,
|
262
269
|
fullParams$,
|
@@ -266,7 +273,7 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
266
273
|
gridGraphicTransform$,
|
267
274
|
gridAxesSize$,
|
268
275
|
gridHighlight$,
|
269
|
-
|
276
|
+
gridContainerPosition$,
|
270
277
|
layout$,
|
271
278
|
event$
|
272
279
|
}) => {
|
@@ -285,8 +292,8 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
285
292
|
selection,
|
286
293
|
pluginName,
|
287
294
|
clipPathID,
|
288
|
-
|
289
|
-
|
295
|
+
seriesLabels$,
|
296
|
+
gridContainerPosition$,
|
290
297
|
gridAxesTransform$,
|
291
298
|
gridGraphicTransform$
|
292
299
|
})
|
@@ -300,7 +307,7 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
300
307
|
})
|
301
308
|
)
|
302
309
|
|
303
|
-
const areaPath$: Observable<d3.Line<
|
310
|
+
const areaPath$: Observable<d3.Line<ComputedLayoutDatumGrid>> = new Observable(subscriber => {
|
304
311
|
const paramsSubscription = combineLatest({
|
305
312
|
fullParams: fullParams$,
|
306
313
|
valueAxisStart: valueAxisStart$
|
@@ -316,19 +323,18 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
316
323
|
}
|
317
324
|
})
|
318
325
|
|
319
|
-
// 顯示範圍內的series labels
|
320
|
-
const seriesLabels$: Observable<string[]> = new Observable(subscriber => {
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
})
|
326
|
+
// // 顯示範圍內的series labels
|
327
|
+
// const seriesLabels$: Observable<string[]> = new Observable(subscriber => {
|
328
|
+
// computedData$.pipe(
|
329
|
+
// takeUntil(destroy$),
|
330
|
+
// switchMap(async (d) => d),
|
331
|
+
// ).subscribe(data => {
|
332
|
+
// const labels = data[0] && data[0][0]
|
333
|
+
// ? data.map(d => d[0].seriesLabel)
|
334
|
+
// : []
|
335
|
+
// subscriber.next(labels)
|
336
|
+
// })
|
337
|
+
// })
|
332
338
|
|
333
339
|
// const axisSize$ = gridAxisSizeObservable({
|
334
340
|
// fullDataFormatter$,
|
@@ -355,7 +361,6 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
355
361
|
transitionEase: transitionEase$
|
356
362
|
}).pipe(
|
357
363
|
takeUntil(destroy$),
|
358
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
359
364
|
switchMap(async (d) => d),
|
360
365
|
).subscribe(data => {
|
361
366
|
// 外層的遮罩
|
@@ -419,54 +424,65 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
419
424
|
}))
|
420
425
|
)
|
421
426
|
|
422
|
-
const
|
427
|
+
const pathSelectionArr$ = combineLatest({
|
423
428
|
graphicGSelection: graphicGSelection$,
|
424
429
|
defsSelection: defsSelection$,
|
425
|
-
|
426
|
-
computedData: computedData$,
|
430
|
+
visibleComputedLayoutData: visibleComputedLayoutData$,
|
427
431
|
linearGradientIds: linearGradientIds$,
|
428
|
-
SeriesDataMap: SeriesDataMap$,
|
429
|
-
GroupDataMap: GroupDataMap$,
|
430
432
|
areaPath: areaPath$,
|
431
433
|
params: fullParams$,
|
434
|
+
}).pipe(
|
435
|
+
takeUntil(destroy$),
|
436
|
+
switchMap(async (d) => d),
|
437
|
+
map(data => {
|
438
|
+
// const updateGraphic = data.graphicGSelection
|
439
|
+
// .selectAll<SVGGElement, number>('g')
|
440
|
+
// .data(data.seriesLabels, (d, i) => d)
|
441
|
+
// const enterGraphic = updateGraphic.enter()
|
442
|
+
// .append('g')
|
443
|
+
// .classed(graphicClassName, true)
|
444
|
+
// updateGraphic.exit().remove()
|
445
|
+
// const graphicSelection = updateGraphic.merge(enterGraphic)
|
446
|
+
// .attr('clip-path', (d, i) => `url(#orbcharts__clipPath_${d})`)
|
447
|
+
let pathSelectionArr: d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any>[] = []
|
448
|
+
|
449
|
+
// 繪圖
|
450
|
+
data.graphicGSelection.each((d, i, all) => {
|
451
|
+
// 將資料分段
|
452
|
+
const segmentData = makeSegmentData(data.visibleComputedLayoutData[i] ?? [])
|
453
|
+
|
454
|
+
pathSelectionArr[i] = renderLineAreas({
|
455
|
+
selection: d3.select(all[i]),
|
456
|
+
pathClassName,
|
457
|
+
areaPath: data.areaPath,
|
458
|
+
segmentData: segmentData,
|
459
|
+
linearGradientIds: data.linearGradientIds,
|
460
|
+
params: data.params
|
461
|
+
})
|
462
|
+
renderLinearGradient({
|
463
|
+
defsSelection: data.defsSelection,
|
464
|
+
computedData: data.visibleComputedLayoutData,
|
465
|
+
linearGradientIds: data.linearGradientIds,
|
466
|
+
params: data.params
|
467
|
+
})
|
468
|
+
})
|
469
|
+
|
470
|
+
return pathSelectionArr
|
471
|
+
})
|
472
|
+
)
|
473
|
+
|
474
|
+
combineLatest({
|
475
|
+
pathSelectionArr: pathSelectionArr$,
|
476
|
+
computedData: computedData$,
|
477
|
+
SeriesDataMap: SeriesDataMap$,
|
478
|
+
GroupDataMap: GroupDataMap$,
|
432
479
|
highlightTarget: highlightTarget$,
|
433
480
|
gridGroupPositionFn: gridGroupPositionFn$,
|
434
481
|
}).pipe(
|
435
482
|
takeUntil(destroy$),
|
436
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
437
483
|
switchMap(async (d) => d),
|
438
484
|
).subscribe(data => {
|
439
|
-
|
440
|
-
// const updateGraphic = data.graphicGSelection
|
441
|
-
// .selectAll<SVGGElement, number>('g')
|
442
|
-
// .data(data.seriesLabels, (d, i) => d)
|
443
|
-
// const enterGraphic = updateGraphic.enter()
|
444
|
-
// .append('g')
|
445
|
-
// .classed(graphicClassName, true)
|
446
|
-
// updateGraphic.exit().remove()
|
447
|
-
// const graphicSelection = updateGraphic.merge(enterGraphic)
|
448
|
-
// .attr('clip-path', (d, i) => `url(#orbcharts__clipPath_${d})`)
|
449
|
-
|
450
|
-
// 繪圖
|
451
|
-
data.graphicGSelection.each((d, i, all) => {
|
452
|
-
// 將資料分段
|
453
|
-
const segmentData = makeSegmentData(data.computedData[i] ?? [])
|
454
|
-
|
455
|
-
const pathSelection = renderLineAreas({
|
456
|
-
selection: d3.select(all[i]),
|
457
|
-
pathClassName,
|
458
|
-
areaPath: data.areaPath,
|
459
|
-
segmentData: segmentData,
|
460
|
-
linearGradientIds: data.linearGradientIds,
|
461
|
-
params: data.params
|
462
|
-
})
|
463
|
-
renderLinearGradient({
|
464
|
-
defsSelection: data.defsSelection,
|
465
|
-
computedData: data.computedData,
|
466
|
-
linearGradientIds: data.linearGradientIds,
|
467
|
-
params: data.params
|
468
|
-
})
|
469
|
-
|
485
|
+
data.pathSelectionArr.forEach(pathSelection => {
|
470
486
|
pathSelection
|
471
487
|
.on('mouseover', (event, datum) => {
|
472
488
|
event.stopPropagation()
|
@@ -570,21 +586,9 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
570
586
|
groupLabel: _datum.groupLabel,
|
571
587
|
event,
|
572
588
|
data: data.computedData
|
573
|
-
})
|
574
589
|
})
|
575
|
-
|
590
|
+
})
|
576
591
|
})
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
// graphicSelection$.next(graphicSelection)
|
581
|
-
|
582
|
-
|
583
|
-
// pathSelection = renderLineAreas({
|
584
|
-
// selection: graphicSelection,
|
585
|
-
// areaPath: d.areaPath,
|
586
|
-
// data: d.computedData
|
587
|
-
// })
|
588
592
|
})
|
589
593
|
|
590
594
|
// const datumList$ = computedData$.pipe(
|