@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/BaseLines.ts
CHANGED
@@ -12,9 +12,11 @@ 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'
|
@@ -38,7 +40,10 @@ export interface BaseLinesParams {
|
|
38
40
|
interface BaseLinesContext {
|
39
41
|
selection: d3.Selection<any, unknown, any, unknown>
|
40
42
|
computedData$: Observable<ComputedDataGrid>
|
41
|
-
|
43
|
+
computedLayoutData$: Observable<ComputedLayoutDataGrid>
|
44
|
+
visibleComputedData$: Observable<ComputedDatumGrid[][]>
|
45
|
+
visibleComputedLayoutData$: Observable<ComputedLayoutDataGrid>
|
46
|
+
seriesLabels$: Observable<string[]>
|
42
47
|
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
43
48
|
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
44
49
|
fullDataFormatter$: Observable<DataFormatterGrid>
|
@@ -51,7 +56,7 @@ interface BaseLinesContext {
|
|
51
56
|
height: number;
|
52
57
|
}>
|
53
58
|
gridHighlight$: Observable<ComputedDatumGrid[]>
|
54
|
-
|
59
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
55
60
|
event$: Subject<EventGrid>
|
56
61
|
}
|
57
62
|
|
@@ -68,16 +73,16 @@ type ClipPathDatum = {
|
|
68
73
|
// const pathClassName = getClassName(pluginName, 'path')
|
69
74
|
|
70
75
|
|
71
|
-
function createLinePath (lineCurve: string = 'curveLinear'): d3.Line<
|
72
|
-
return d3.line<
|
76
|
+
function createLinePath (lineCurve: string = 'curveLinear'): d3.Line<ComputedLayoutDatumGrid> {
|
77
|
+
return d3.line<ComputedLayoutDatumGrid>()
|
73
78
|
.x((d) => d.axisX)
|
74
79
|
.y((d) => d.axisY)
|
75
80
|
.curve((d3 as any)[lineCurve])
|
76
81
|
}
|
77
82
|
|
78
83
|
// 依無值的資料分段
|
79
|
-
function
|
80
|
-
let segmentData:
|
84
|
+
function makeSegmentData (data: ComputedLayoutDatumGrid[]): ComputedLayoutDatumGrid[][] {
|
85
|
+
let segmentData: ComputedLayoutDatumGrid[][] = [[]]
|
81
86
|
|
82
87
|
let currentIndex = 0
|
83
88
|
for (let i in data) {
|
@@ -99,16 +104,16 @@ function makeSegmentData (data: ComputedDatumGrid[]): ComputedDatumGrid[][] {
|
|
99
104
|
function renderLines ({ selection, pathClassName, segmentData, linePath, params }: {
|
100
105
|
selection: d3.Selection<SVGGElement, unknown, any, unknown>
|
101
106
|
pathClassName: string
|
102
|
-
segmentData:
|
103
|
-
linePath: d3.Line<
|
107
|
+
segmentData: ComputedLayoutDatumGrid[][]
|
108
|
+
linePath: d3.Line<ComputedLayoutDatumGrid>
|
104
109
|
params: BaseLinesParams
|
105
|
-
}): d3.Selection<SVGPathElement,
|
110
|
+
}): d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any> {
|
106
111
|
// if (!data[0]) {
|
107
112
|
// return undefined
|
108
113
|
// }
|
109
114
|
|
110
115
|
const lines = selection
|
111
|
-
.selectAll<SVGPathElement,
|
116
|
+
.selectAll<SVGPathElement, ComputedLayoutDatumGrid[]>('path')
|
112
117
|
.data(segmentData, (d, i) => d.length ? `${d[0].id}_${d[d.length - 1].id}` : i) // 以線段起迄id結合為線段id
|
113
118
|
.join(
|
114
119
|
enter => {
|
@@ -221,7 +226,10 @@ function renderClipPath ({ defsSelection, clipPathData, transitionDuration, tran
|
|
221
226
|
export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: string, {
|
222
227
|
selection,
|
223
228
|
computedData$,
|
224
|
-
|
229
|
+
computedLayoutData$,
|
230
|
+
visibleComputedData$,
|
231
|
+
visibleComputedLayoutData$,
|
232
|
+
seriesLabels$,
|
225
233
|
SeriesDataMap$,
|
226
234
|
GroupDataMap$,
|
227
235
|
fullParams$,
|
@@ -231,7 +239,7 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
231
239
|
gridGraphicTransform$,
|
232
240
|
gridAxesSize$,
|
233
241
|
gridHighlight$,
|
234
|
-
|
242
|
+
gridContainerPosition$,
|
235
243
|
event$
|
236
244
|
}) => {
|
237
245
|
|
@@ -322,7 +330,7 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
322
330
|
|
323
331
|
// combineLatest({
|
324
332
|
// seriesSelection: seriesSelection$,
|
325
|
-
//
|
333
|
+
// gridContainerPosition: gridContainerPosition$
|
326
334
|
// }).pipe(
|
327
335
|
// takeUntil(destroy$),
|
328
336
|
// switchMap(async d => d)
|
@@ -330,8 +338,8 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
330
338
|
// data.seriesSelection
|
331
339
|
// .transition()
|
332
340
|
// .attr('transform', (d, i) => {
|
333
|
-
// const translate = data.
|
334
|
-
// const scale = data.
|
341
|
+
// const translate = data.gridContainerPosition[i].translate
|
342
|
+
// const scale = data.gridContainerPosition[i].scale
|
335
343
|
// return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
336
344
|
// })
|
337
345
|
// })
|
@@ -382,13 +390,13 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
382
390
|
selection,
|
383
391
|
pluginName,
|
384
392
|
clipPathID,
|
385
|
-
|
386
|
-
|
393
|
+
seriesLabels$,
|
394
|
+
gridContainerPosition$,
|
387
395
|
gridAxesTransform$,
|
388
396
|
gridGraphicTransform$
|
389
397
|
})
|
390
398
|
|
391
|
-
const linePath$: Observable<d3.Line<
|
399
|
+
const linePath$: Observable<d3.Line<ComputedLayoutDatumGrid>> = new Observable(subscriber => {
|
392
400
|
const paramsSubscription = fullParams$
|
393
401
|
.pipe(
|
394
402
|
takeUntil(destroy$)
|
@@ -403,19 +411,18 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
403
411
|
}
|
404
412
|
})
|
405
413
|
|
406
|
-
// 顯示範圍內的series labels
|
407
|
-
const seriesLabels$: Observable<string[]> = new Observable(subscriber => {
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
})
|
414
|
+
// // 顯示範圍內的series labels
|
415
|
+
// const seriesLabels$: Observable<string[]> = new Observable(subscriber => {
|
416
|
+
// computedData$.pipe(
|
417
|
+
// takeUntil(destroy$),
|
418
|
+
// switchMap(async (d) => d),
|
419
|
+
// ).subscribe(data => {
|
420
|
+
// const labels = data[0] && data[0][0]
|
421
|
+
// ? data.map(d => d[0].seriesLabel)
|
422
|
+
// : []
|
423
|
+
// subscriber.next(labels)
|
424
|
+
// })
|
425
|
+
// })
|
419
426
|
|
420
427
|
// const axisSize$ = gridAxisSizeObservable({
|
421
428
|
// fullDataFormatter$,
|
@@ -442,7 +449,6 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
442
449
|
transitionEase: transitionEase$
|
443
450
|
}).pipe(
|
444
451
|
takeUntil(destroy$),
|
445
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
446
452
|
switchMap(async (d) => d),
|
447
453
|
).subscribe(data => {
|
448
454
|
// 外層的遮罩
|
@@ -499,45 +505,58 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
499
505
|
distinctUntilChanged()
|
500
506
|
)
|
501
507
|
|
502
|
-
const
|
508
|
+
const pathSelectionArr$ = combineLatest({
|
503
509
|
graphicGSelection: graphicGSelection$,
|
504
|
-
|
510
|
+
visibleComputedLayoutData: visibleComputedLayoutData$,
|
511
|
+
linePath: linePath$,
|
512
|
+
params: fullParams$,
|
513
|
+
}).pipe(
|
514
|
+
takeUntil(destroy$),
|
515
|
+
switchMap(async (d) => d),
|
516
|
+
map(data => {
|
517
|
+
// const updateGraphic = data.graphicGSelection
|
518
|
+
// .selectAll<SVGGElement, number>('g')
|
519
|
+
// .data(data.seriesLabels, (d, i) => d)
|
520
|
+
// const enterGraphic = updateGraphic.enter()
|
521
|
+
// .append('g')
|
522
|
+
// .classed(graphicClassName, true)
|
523
|
+
// updateGraphic.exit().remove()
|
524
|
+
// const graphicSelection = updateGraphic.merge(enterGraphic)
|
525
|
+
// .attr('clip-path', (d, i) => `url(#orbcharts__clipPath_${d})`)
|
526
|
+
let pathSelectionArr: d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any>[] = []
|
527
|
+
|
528
|
+
// 繪圖
|
529
|
+
data.graphicGSelection.each((d, i, all) => {
|
530
|
+
// 將資料分段
|
531
|
+
const segmentData = makeSegmentData(data.visibleComputedLayoutData[i] ?? [])
|
532
|
+
|
533
|
+
pathSelectionArr[i] = renderLines({
|
534
|
+
selection: d3.select(all[i]),
|
535
|
+
pathClassName,
|
536
|
+
linePath: data.linePath,
|
537
|
+
segmentData: segmentData,
|
538
|
+
params: data.params
|
539
|
+
})
|
540
|
+
})
|
541
|
+
|
542
|
+
return pathSelectionArr
|
543
|
+
})
|
544
|
+
|
545
|
+
|
546
|
+
)
|
547
|
+
|
548
|
+
combineLatest({
|
549
|
+
pathSelectionArr: pathSelectionArr$,
|
505
550
|
computedData: computedData$,
|
506
551
|
SeriesDataMap: SeriesDataMap$,
|
507
552
|
GroupDataMap: GroupDataMap$,
|
508
|
-
linePath: linePath$,
|
509
|
-
params: fullParams$,
|
510
553
|
highlightTarget: highlightTarget$,
|
511
554
|
gridGroupPositionFn: gridGroupPositionFn$,
|
512
555
|
}).pipe(
|
513
556
|
takeUntil(destroy$),
|
514
|
-
|
515
|
-
switchMap(async (d) => d),
|
557
|
+
switchMap(async (d) => d)
|
516
558
|
).subscribe(data => {
|
517
|
-
|
518
|
-
// const updateGraphic = data.graphicGSelection
|
519
|
-
// .selectAll<SVGGElement, number>('g')
|
520
|
-
// .data(data.seriesLabels, (d, i) => d)
|
521
|
-
// const enterGraphic = updateGraphic.enter()
|
522
|
-
// .append('g')
|
523
|
-
// .classed(graphicClassName, true)
|
524
|
-
// updateGraphic.exit().remove()
|
525
|
-
// const graphicSelection = updateGraphic.merge(enterGraphic)
|
526
|
-
// .attr('clip-path', (d, i) => `url(#orbcharts__clipPath_${d})`)
|
527
|
-
|
528
|
-
// 繪圖
|
529
|
-
data.graphicGSelection.each((d, i, all) => {
|
530
|
-
// 將資料分段
|
531
|
-
const segmentData = makeSegmentData(data.computedData[i] ?? [])
|
532
|
-
|
533
|
-
const pathSelection = renderLines({
|
534
|
-
selection: d3.select(all[i]),
|
535
|
-
pathClassName,
|
536
|
-
linePath: data.linePath,
|
537
|
-
segmentData: segmentData,
|
538
|
-
params: data.params
|
539
|
-
})
|
540
|
-
|
559
|
+
data.pathSelectionArr.forEach(pathSelection => {
|
541
560
|
pathSelection
|
542
561
|
.on('mouseover', (event, datum) => {
|
543
562
|
event.stopPropagation()
|
@@ -643,19 +662,7 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
643
662
|
data: data.computedData
|
644
663
|
})
|
645
664
|
})
|
646
|
-
|
647
665
|
})
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
// graphicSelection$.next(graphicSelection)
|
652
|
-
|
653
|
-
|
654
|
-
// pathSelection = renderLines({
|
655
|
-
// selection: graphicSelection,
|
656
|
-
// linePath: d.linePath,
|
657
|
-
// data: d.computedData
|
658
|
-
// })
|
659
666
|
})
|
660
667
|
|
661
668
|
// const datumList$ = computedData$.pipe(
|
@@ -15,7 +15,7 @@ import type {
|
|
15
15
|
DataFormatterGrid,
|
16
16
|
ChartParams,
|
17
17
|
ComputedDatumGrid,
|
18
|
-
|
18
|
+
GridContainerPosition,
|
19
19
|
TransformData,
|
20
20
|
EventGrid,
|
21
21
|
ColorType } from '@orbcharts/core'
|
@@ -50,8 +50,8 @@ interface BaseLinesContext {
|
|
50
50
|
width: number;
|
51
51
|
height: number;
|
52
52
|
}>
|
53
|
-
|
54
|
-
|
53
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
54
|
+
isSeriesSeprate$: Observable<boolean>
|
55
55
|
}
|
56
56
|
|
57
57
|
interface TextAlign {
|
@@ -175,8 +175,8 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
175
175
|
gridAxesTransform$,
|
176
176
|
gridAxesReverseTransform$,
|
177
177
|
gridAxesSize$,
|
178
|
-
|
179
|
-
|
178
|
+
gridContainerPosition$,
|
179
|
+
isSeriesSeprate$,
|
180
180
|
}) => {
|
181
181
|
|
182
182
|
const destroy$ = new Subject()
|
@@ -193,12 +193,12 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
193
193
|
return a.length === b.length
|
194
194
|
}),
|
195
195
|
),
|
196
|
-
|
196
|
+
isSeriesSeprate: isSeriesSeprate$
|
197
197
|
}).pipe(
|
198
198
|
takeUntil(destroy$),
|
199
199
|
switchMap(async (d) => d),
|
200
200
|
map(data => {
|
201
|
-
return data.
|
201
|
+
return data.isSeriesSeprate
|
202
202
|
// series分開的時候顯示各別axis
|
203
203
|
? data.computedData
|
204
204
|
// series合併的時候只顯示第一個axis
|
@@ -226,16 +226,16 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
226
226
|
|
227
227
|
combineLatest({
|
228
228
|
containerSelection: containerSelection$,
|
229
|
-
|
229
|
+
gridContainerPosition: gridContainerPosition$
|
230
230
|
}).pipe(
|
231
231
|
takeUntil(destroy$),
|
232
232
|
switchMap(async d => d)
|
233
233
|
).subscribe(data => {
|
234
234
|
data.containerSelection
|
235
235
|
.attr('transform', (d, i) => {
|
236
|
-
const
|
237
|
-
const translate =
|
238
|
-
const scale =
|
236
|
+
const gridContainerPosition = data.gridContainerPosition[i] ?? data.gridContainerPosition[0]
|
237
|
+
const translate = gridContainerPosition.translate
|
238
|
+
const scale = gridContainerPosition.scale
|
239
239
|
return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
240
240
|
})
|
241
241
|
// .attr('opacity', 0)
|
@@ -308,14 +308,14 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
308
308
|
fullParams: fullParams$,
|
309
309
|
fullDataFormatter: fullDataFormatter$,
|
310
310
|
gridAxesReverseTransform: gridAxesReverseTransform$,
|
311
|
-
|
311
|
+
gridContainerPosition: gridContainerPosition$
|
312
312
|
}).pipe(
|
313
313
|
takeUntil(destroy$),
|
314
314
|
switchMap(async (d) => d),
|
315
315
|
map(data => {
|
316
316
|
const axisReverseTranslateValue = `translate(${data.gridAxesReverseTransform.translate[0]}px, ${data.gridAxesReverseTransform.translate[1]}px)`
|
317
317
|
const axisReverseRotateValue = `rotate(${data.gridAxesReverseTransform.rotate}deg) rotateX(${data.gridAxesReverseTransform.rotateX}deg) rotateY(${data.gridAxesReverseTransform.rotateY}deg)`
|
318
|
-
const containerScaleReverseScaleValue = `scale(${1 / data.
|
318
|
+
const containerScaleReverseScaleValue = `scale(${1 / data.gridContainerPosition[0].scale[0]}, ${1 / data.gridContainerPosition[0].scale[1]})`
|
319
319
|
const tickTextRotateDeg = (data.fullDataFormatter.grid.groupAxis.position === 'left' && data.fullDataFormatter.grid.valueAxis.position === 'top')
|
320
320
|
|| (data.fullDataFormatter.grid.groupAxis.position === 'right' && data.fullDataFormatter.grid.valueAxis.position === 'bottom')
|
321
321
|
? data.fullParams.tickTextRotate + 180 // 修正文字倒轉
|
@@ -354,7 +354,7 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
354
354
|
})
|
355
355
|
|
356
356
|
const filteredMinAndMax = getMinAndMaxValue(filteredData.flat())
|
357
|
-
|
357
|
+
|
358
358
|
subscriber.next(filteredMinAndMax)
|
359
359
|
})
|
360
360
|
})
|
@@ -366,7 +366,6 @@ export const createBaseValueAxis: BasePluginFn<BaseLinesContext> = (pluginName:
|
|
366
366
|
minAndMax: minAndMax$
|
367
367
|
}).pipe(
|
368
368
|
takeUntil(destroy$),
|
369
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
370
369
|
switchMap(async (d) => d),
|
371
370
|
).subscribe(data => {
|
372
371
|
|
@@ -19,18 +19,19 @@ import type {
|
|
19
19
|
ComputedDataGrid,
|
20
20
|
ComputedDatumGrid,
|
21
21
|
TransformData,
|
22
|
-
|
22
|
+
GridContainerPosition,
|
23
23
|
Layout } from '@orbcharts/core'
|
24
24
|
import { createAxisQuantizeScale } from '@orbcharts/core'
|
25
25
|
import { getClassName, getUniID } from '../utils/orbchartsUtils'
|
26
26
|
|
27
|
-
|
27
|
+
// grid選取器
|
28
|
+
export const gridSelectionsObservable = ({ selection, pluginName, clipPathID, seriesLabels$, gridContainerPosition$, gridAxesTransform$, gridGraphicTransform$ }: {
|
28
29
|
selection: d3.Selection<any, unknown, any, unknown>
|
29
30
|
pluginName: string
|
30
31
|
clipPathID: string
|
31
32
|
// computedData$: Observable<ComputedDataGrid>
|
32
|
-
|
33
|
-
|
33
|
+
seriesLabels$: Observable<string[]>
|
34
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
34
35
|
gridAxesTransform$: Observable<TransformData>
|
35
36
|
gridGraphicTransform$: Observable<TransformData>
|
36
37
|
}) => {
|
@@ -38,7 +39,7 @@ export const gridSelectionsObservable = ({ selection, pluginName, clipPathID, ex
|
|
38
39
|
const axesClassName = getClassName(pluginName, 'axes')
|
39
40
|
const graphicClassName = getClassName(pluginName, 'graphic')
|
40
41
|
|
41
|
-
const seriesSelection$ =
|
42
|
+
const seriesSelection$ = seriesLabels$.pipe(
|
42
43
|
map((existSeriesLabels, i) => {
|
43
44
|
return selection
|
44
45
|
.selectAll<SVGGElement, string>(`g.${seriesClassName}`)
|
@@ -80,39 +81,24 @@ export const gridSelectionsObservable = ({ selection, pluginName, clipPathID, ex
|
|
80
81
|
exit => exit.remove()
|
81
82
|
)
|
82
83
|
}),
|
83
|
-
switchMap(selection => combineLatest({
|
84
|
-
seriesSelection: of(selection),
|
85
|
-
gridContainer: gridContainer$
|
86
|
-
})),
|
87
|
-
map(data => {
|
88
|
-
data.seriesSelection
|
89
|
-
.transition()
|
90
|
-
.attr('transform', (d, i) => {
|
91
|
-
const gridContainer = data.gridContainer[i] ?? data.gridContainer[0]
|
92
|
-
const translate = gridContainer.translate
|
93
|
-
const scale = gridContainer.scale
|
94
|
-
return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
95
|
-
})
|
96
|
-
return data.seriesSelection
|
97
|
-
}),
|
98
84
|
shareReplay(1)
|
99
85
|
)
|
100
86
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
87
|
+
combineLatest({
|
88
|
+
seriesSelection: seriesSelection$,
|
89
|
+
gridContainerPosition: gridContainerPosition$
|
90
|
+
}).pipe(
|
91
|
+
switchMap(async d => d)
|
92
|
+
).subscribe(data => {
|
93
|
+
data.seriesSelection
|
94
|
+
.transition()
|
95
|
+
.attr('transform', (d, i) => {
|
96
|
+
const gridContainerPosition = data.gridContainerPosition[i] ?? data.gridContainerPosition[0]
|
97
|
+
const translate = gridContainerPosition.translate
|
98
|
+
const scale = gridContainerPosition.scale
|
99
|
+
return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
100
|
+
})
|
101
|
+
})
|
116
102
|
|
117
103
|
const axesSelection$ = combineLatest({
|
118
104
|
seriesSelection: seriesSelection$,
|
@@ -177,7 +163,6 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
177
163
|
computedData: computedData$
|
178
164
|
}).pipe(
|
179
165
|
takeUntil(destroy$),
|
180
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
181
166
|
switchMap(async (d) => d),
|
182
167
|
).subscribe(data => {
|
183
168
|
const groupMin = 0
|
@@ -193,7 +178,7 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
193
178
|
// ? data.computedData[0].length
|
194
179
|
// : 0
|
195
180
|
|
196
|
-
let _labels = data.dataFormatter.grid.
|
181
|
+
let _labels = data.dataFormatter.grid.seriesDirection === 'row'
|
197
182
|
? (data.computedData[0] ?? []).map(d => d.groupLabel)
|
198
183
|
: data.computedData.map(d => d[0].groupLabel)
|
199
184
|
|
@@ -220,7 +205,6 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
220
205
|
scaleRangeGroupLabels: scaleRangeGroupLabels$
|
221
206
|
}).pipe(
|
222
207
|
takeUntil(destroy$),
|
223
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
224
208
|
switchMap(async (d) => d),
|
225
209
|
).subscribe(data => {
|
226
210
|
|
@@ -1,4 +1,8 @@
|
|
1
1
|
import {
|
2
|
+
map,
|
3
|
+
distinctUntilChanged,
|
4
|
+
shareReplay,
|
5
|
+
takeUntil,
|
2
6
|
Subject,
|
3
7
|
Observable } from 'rxjs'
|
4
8
|
import { defineGridPlugin } from '@orbcharts/core'
|
@@ -11,11 +15,20 @@ const pluginName = 'BarStack'
|
|
11
15
|
export const BarStack = defineGridPlugin(pluginName, DEFAULT_BAR_STACK_PARAMS)(({ selection, name, subject, observer }) => {
|
12
16
|
const destroy$ = new Subject()
|
13
17
|
|
18
|
+
const isSeriesSeprate$ = observer.fullDataFormatter$.pipe(
|
19
|
+
takeUntil(destroy$),
|
20
|
+
map(d => d.grid.separateSeries),
|
21
|
+
distinctUntilChanged(),
|
22
|
+
shareReplay(1)
|
23
|
+
)
|
24
|
+
|
14
25
|
const unsubscribeBaseBars = createBaseBarStack(pluginName, {
|
15
26
|
selection,
|
16
27
|
computedData$: observer.computedData$,
|
28
|
+
computedLayoutData$: observer.computedLayoutData$,
|
17
29
|
visibleComputedData$: observer.visibleComputedData$,
|
18
|
-
|
30
|
+
visibleComputedLayoutData$: observer.visibleComputedLayoutData$,
|
31
|
+
seriesLabels$: observer.seriesLabels$,
|
19
32
|
SeriesDataMap$: observer.SeriesDataMap$,
|
20
33
|
GroupDataMap$: observer.GroupDataMap$,
|
21
34
|
fullParams$: observer.fullParams$,
|
@@ -26,8 +39,8 @@ export const BarStack = defineGridPlugin(pluginName, DEFAULT_BAR_STACK_PARAMS)((
|
|
26
39
|
gridGraphicReverseScale$: observer.gridGraphicReverseScale$,
|
27
40
|
gridAxesSize$: observer.gridAxesSize$,
|
28
41
|
gridHighlight$: observer.gridHighlight$,
|
29
|
-
|
30
|
-
|
42
|
+
gridContainerPosition$: observer.gridContainerPosition$,
|
43
|
+
isSeriesSeprate$,
|
31
44
|
event$: subject.event$,
|
32
45
|
})
|
33
46
|
|
package/src/grid/plugins/Bars.ts
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
import {
|
2
2
|
Subject,
|
3
|
-
Observable
|
3
|
+
Observable,
|
4
|
+
map,
|
5
|
+
distinctUntilChanged,
|
6
|
+
shareReplay,
|
7
|
+
takeUntil
|
8
|
+
} from 'rxjs'
|
4
9
|
import {
|
5
10
|
defineGridPlugin } from '@orbcharts/core'
|
6
11
|
import { DEFAULT_BARS_PARAMS } from '../defaults'
|
@@ -11,11 +16,20 @@ const pluginName = 'Bars'
|
|
11
16
|
export const Bars = defineGridPlugin(pluginName, DEFAULT_BARS_PARAMS)(({ selection, name, subject, observer }) => {
|
12
17
|
const destroy$ = new Subject()
|
13
18
|
|
19
|
+
const isSeriesSeprate$ = observer.fullDataFormatter$.pipe(
|
20
|
+
takeUntil(destroy$),
|
21
|
+
map(d => d.grid.separateSeries),
|
22
|
+
distinctUntilChanged(),
|
23
|
+
shareReplay(1)
|
24
|
+
)
|
25
|
+
|
14
26
|
const unsubscribeBaseBars = createBaseBars(pluginName, {
|
15
27
|
selection,
|
16
28
|
computedData$: observer.computedData$,
|
29
|
+
computedLayoutData$: observer.computedLayoutData$,
|
17
30
|
visibleComputedData$: observer.visibleComputedData$,
|
18
|
-
|
31
|
+
visibleComputedLayoutData$: observer.visibleComputedLayoutData$,
|
32
|
+
seriesLabels$: observer.seriesLabels$,
|
19
33
|
SeriesDataMap$: observer.SeriesDataMap$,
|
20
34
|
GroupDataMap$: observer.GroupDataMap$,
|
21
35
|
fullParams$: observer.fullParams$,
|
@@ -25,8 +39,8 @@ export const Bars = defineGridPlugin(pluginName, DEFAULT_BARS_PARAMS)(({ selecti
|
|
25
39
|
gridGraphicReverseScale$: observer.gridGraphicReverseScale$,
|
26
40
|
gridAxesSize$: observer.gridAxesSize$,
|
27
41
|
gridHighlight$: observer.gridHighlight$,
|
28
|
-
|
29
|
-
|
42
|
+
gridContainerPosition$: observer.gridContainerPosition$,
|
43
|
+
isSeriesSeprate$: isSeriesSeprate$,
|
30
44
|
event$: subject.event$,
|
31
45
|
})
|
32
46
|
|
@@ -15,8 +15,10 @@ export const BarsDiverging = defineGridPlugin(pluginName, DEFAULT_BARS_PARAMS)((
|
|
15
15
|
const unsubscribeBaseBars = createBaseBars(pluginName, {
|
16
16
|
selection,
|
17
17
|
computedData$: observer.computedData$,
|
18
|
+
computedLayoutData$: observer.computedLayoutData$,
|
18
19
|
visibleComputedData$: observer.visibleComputedData$,
|
19
|
-
|
20
|
+
visibleComputedLayoutData$: observer.visibleComputedLayoutData$,
|
21
|
+
seriesLabels$: observer.seriesLabels$,
|
20
22
|
SeriesDataMap$: observer.SeriesDataMap$,
|
21
23
|
GroupDataMap$: observer.GroupDataMap$,
|
22
24
|
fullParams$: observer.fullParams$,
|
@@ -26,9 +28,9 @@ export const BarsDiverging = defineGridPlugin(pluginName, DEFAULT_BARS_PARAMS)((
|
|
26
28
|
gridGraphicReverseScale$: observer.gridGraphicReverseScale$,
|
27
29
|
gridAxesSize$: observer.gridAxesSize$,
|
28
30
|
gridHighlight$: observer.gridHighlight$,
|
29
|
-
|
30
|
-
//
|
31
|
-
|
31
|
+
gridContainerPosition$: observer.gridContainerPosition$,
|
32
|
+
// isSeriesSeprate$: observer.isSeriesSeprate$,
|
33
|
+
isSeriesSeprate$: of(true), // hack: 永遠為true,可以強制讓每組series的bars的x位置都是一樣的
|
32
34
|
event$: subject.event$,
|
33
35
|
})
|
34
36
|
|
@@ -1,6 +1,11 @@
|
|
1
1
|
import {
|
2
2
|
Subject,
|
3
|
-
Observable
|
3
|
+
Observable,
|
4
|
+
takeUntil,
|
5
|
+
map,
|
6
|
+
distinctUntilChanged,
|
7
|
+
shareReplay
|
8
|
+
} from 'rxjs'
|
4
9
|
import { defineGridPlugin } from '@orbcharts/core'
|
5
10
|
import { DEFAULT_BARS_TRIANGLE_PARAMS } from '../defaults'
|
6
11
|
import { createBaseBarsTriangle } from '../../base/BaseBarsTriangle'
|
@@ -10,11 +15,22 @@ const pluginName = 'BarsTriangle'
|
|
10
15
|
export const BarsTriangle = defineGridPlugin(pluginName, DEFAULT_BARS_TRIANGLE_PARAMS)(({ selection, name, subject, observer }) => {
|
11
16
|
const destroy$ = new Subject()
|
12
17
|
|
18
|
+
|
19
|
+
const isSeriesSeprate$ = observer.fullDataFormatter$.pipe(
|
20
|
+
takeUntil(destroy$),
|
21
|
+
map(d => d.grid.separateSeries),
|
22
|
+
distinctUntilChanged(),
|
23
|
+
shareReplay(1)
|
24
|
+
)
|
25
|
+
|
13
26
|
const unsubscribeBaseBars = createBaseBarsTriangle(pluginName, {
|
14
27
|
selection,
|
15
28
|
computedData$: observer.computedData$,
|
29
|
+
computedLayoutData$: observer.computedLayoutData$,
|
16
30
|
visibleComputedData$: observer.visibleComputedData$,
|
17
|
-
|
31
|
+
visibleComputedLayoutData$: observer.visibleComputedLayoutData$,
|
32
|
+
fullDataFormatter$: observer.fullDataFormatter$,
|
33
|
+
seriesLabels$: observer.seriesLabels$,
|
18
34
|
SeriesDataMap$: observer.SeriesDataMap$,
|
19
35
|
GroupDataMap$: observer.GroupDataMap$,
|
20
36
|
fullParams$: observer.fullParams$,
|
@@ -23,8 +39,8 @@ export const BarsTriangle = defineGridPlugin(pluginName, DEFAULT_BARS_TRIANGLE_P
|
|
23
39
|
gridGraphicTransform$: observer.gridGraphicTransform$,
|
24
40
|
gridAxesSize$: observer.gridAxesSize$,
|
25
41
|
gridHighlight$: observer.gridHighlight$,
|
26
|
-
|
27
|
-
|
42
|
+
gridContainerPosition$: observer.gridContainerPosition$,
|
43
|
+
isSeriesSeprate$,
|
28
44
|
event$: subject.event$,
|
29
45
|
})
|
30
46
|
|
package/src/grid/plugins/Dots.ts
CHANGED
@@ -14,8 +14,10 @@ export const Dots = defineGridPlugin(pluginName, DEFAULT_DOTS_PARAMS)(({ selecti
|
|
14
14
|
const unsubscribeBaseBars = createBaseDots(pluginName, {
|
15
15
|
selection,
|
16
16
|
computedData$: observer.computedData$,
|
17
|
+
computedLayoutData$: observer.computedLayoutData$,
|
17
18
|
visibleComputedData$: observer.visibleComputedData$,
|
18
|
-
|
19
|
+
visibleComputedLayoutData$: observer.visibleComputedLayoutData$,
|
20
|
+
seriesLabels$: observer.seriesLabels$,
|
19
21
|
SeriesDataMap$: observer.SeriesDataMap$,
|
20
22
|
GroupDataMap$: observer.GroupDataMap$,
|
21
23
|
fullParams$: observer.fullParams$,
|
@@ -25,7 +27,7 @@ export const Dots = defineGridPlugin(pluginName, DEFAULT_DOTS_PARAMS)(({ selecti
|
|
25
27
|
gridGraphicReverseScale$: observer.gridGraphicReverseScale$,
|
26
28
|
gridAxesSize$: observer.gridAxesSize$,
|
27
29
|
gridHighlight$: observer.gridHighlight$,
|
28
|
-
|
30
|
+
gridContainerPosition$: observer.gridContainerPosition$,
|
29
31
|
event$: subject.event$,
|
30
32
|
})
|
31
33
|
|