@orbcharts/plugins-basic 3.0.0-alpha.44 → 3.0.0-alpha.46
Sign up to get free protection for your applications and to get access to all the features.
- 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(
|