@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
@@ -6,16 +6,23 @@ import {
|
|
6
6
|
takeUntil,
|
7
7
|
map,
|
8
8
|
distinctUntilChanged,
|
9
|
+
Observable,
|
9
10
|
Subject } from 'rxjs'
|
10
11
|
import type { Subscription } from 'rxjs'
|
11
12
|
import {
|
12
13
|
defineSeriesPlugin} from '@orbcharts/core'
|
13
14
|
import type {
|
15
|
+
ComputedDatumSeries,
|
16
|
+
ChartParams,
|
17
|
+
SeriesContainerPosition,
|
14
18
|
EventName,
|
15
19
|
EventSeries } from '@orbcharts/core'
|
20
|
+
import type { PieEventTextsParams } from '../types'
|
16
21
|
import { DEFAULT_PIE_EVENT_TEXTS_PARAMS } from '../defaults'
|
17
22
|
import { getD3TransitionEase } from '../../utils/d3Utils'
|
18
23
|
import { getClassName } from '../../utils/orbchartsUtils'
|
24
|
+
import { seriesCenterSelectionObservable } from '../seriesObservables'
|
25
|
+
|
19
26
|
|
20
27
|
type TextDatum = {
|
21
28
|
text: string
|
@@ -74,62 +81,67 @@ function makeTextData ({ eventData, eventName, t, eventFn, textAttrs, textStyles
|
|
74
81
|
})
|
75
82
|
}
|
76
83
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
84
|
+
function createEachPieEventTexts (pluginName: string, context: {
|
85
|
+
containerSelection: d3.Selection<SVGGElement, any, any, unknown>
|
86
|
+
computedData$: Observable<ComputedDatumSeries[][]>
|
87
|
+
containerComputedLayoutData$: Observable<ComputedDatumSeries[]>
|
88
|
+
SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
|
89
|
+
fullParams$: Observable<PieEventTextsParams>
|
90
|
+
fullChartParams$: Observable<ChartParams>
|
91
|
+
seriesHighlight$: Observable<ComputedDatumSeries[]>
|
92
|
+
seriesContainerPosition$: Observable<SeriesContainerPosition>
|
93
|
+
event$: Subject<EventSeries>
|
94
|
+
}) {
|
81
95
|
const destroy$ = new Subject()
|
82
96
|
|
83
|
-
const graphicSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
|
97
|
+
// const graphicSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
|
84
98
|
let centerTextSelection: d3.Selection<SVGTextElement, TextDatum, SVGGElement, unknown> | undefined
|
85
99
|
let storeEventSubscription: Subscription | undefined
|
86
100
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
// context.layout$
|
102
|
+
// .pipe(
|
103
|
+
// first()
|
104
|
+
// )
|
105
|
+
// .subscribe(size => {
|
106
|
+
// selection
|
107
|
+
// .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
|
108
|
+
// context.layout$
|
109
|
+
// .pipe(
|
110
|
+
// takeUntil(destroy$)
|
111
|
+
// )
|
112
|
+
// .subscribe(size => {
|
113
|
+
// selection
|
114
|
+
// .transition()
|
115
|
+
// .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
|
116
|
+
// })
|
117
|
+
// })
|
105
118
|
|
106
|
-
const highlightTarget$ =
|
119
|
+
const highlightTarget$ = context.fullChartParams$.pipe(
|
107
120
|
takeUntil(destroy$),
|
108
121
|
map(d => d.highlightTarget),
|
109
122
|
distinctUntilChanged()
|
110
123
|
)
|
111
124
|
|
112
125
|
combineLatest({
|
113
|
-
computedData:
|
114
|
-
fullParams:
|
115
|
-
fullChartParams:
|
116
|
-
highlightTarget: highlightTarget
|
126
|
+
computedData: context.computedData$,
|
127
|
+
fullParams: context.fullParams$,
|
128
|
+
fullChartParams: context.fullChartParams$,
|
129
|
+
highlightTarget: highlightTarget$,
|
117
130
|
}).pipe(
|
118
131
|
takeUntil(destroy$),
|
119
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
120
132
|
switchMap(async (d) => d),
|
121
133
|
).subscribe(data => {
|
122
134
|
|
123
|
-
|
124
|
-
.transition()
|
135
|
+
context.containerSelection
|
136
|
+
.transition('move')
|
125
137
|
.duration(data.fullChartParams.transitionDuration!)
|
126
|
-
.ease(getD3TransitionEase(data.fullChartParams.transitionEase!))
|
138
|
+
// .ease(getD3TransitionEase(data.fullChartParams.transitionEase!))
|
127
139
|
.tween('move', (event, datum) => {
|
128
140
|
return (t) => {
|
129
141
|
const renderData = makeTextData({
|
130
142
|
eventData: {
|
131
143
|
type: 'series',
|
132
|
-
pluginName
|
144
|
+
pluginName,
|
133
145
|
eventName: 'transitionMove',
|
134
146
|
event,
|
135
147
|
highlightTarget: data.highlightTarget,
|
@@ -145,14 +157,14 @@ export const PieEventTexts = defineSeriesPlugin(pluginName, DEFAULT_PIE_EVENT_TE
|
|
145
157
|
textAttrs: data.fullParams.textAttrs!,
|
146
158
|
textStyles: data.fullParams.textStyles!
|
147
159
|
})
|
148
|
-
centerTextSelection = renderText(
|
160
|
+
centerTextSelection = renderText(context.containerSelection, renderData)
|
149
161
|
}
|
150
162
|
})
|
151
163
|
.on('end', (event, datum) => {
|
152
164
|
const renderData = makeTextData({
|
153
165
|
eventData: {
|
154
166
|
type: 'series',
|
155
|
-
pluginName
|
167
|
+
pluginName,
|
156
168
|
eventName: 'transitionEnd',
|
157
169
|
event,
|
158
170
|
highlightTarget: data.highlightTarget,
|
@@ -168,12 +180,12 @@ export const PieEventTexts = defineSeriesPlugin(pluginName, DEFAULT_PIE_EVENT_TE
|
|
168
180
|
textAttrs: data.fullParams.textAttrs!,
|
169
181
|
textStyles: data.fullParams.textStyles!
|
170
182
|
})
|
171
|
-
centerTextSelection = renderText(
|
183
|
+
centerTextSelection = renderText(context.containerSelection, renderData)
|
172
184
|
|
173
185
|
if (storeEventSubscription) {
|
174
186
|
storeEventSubscription.unsubscribe()
|
175
187
|
}
|
176
|
-
storeEventSubscription =
|
188
|
+
storeEventSubscription = context.event$
|
177
189
|
.subscribe(eventData => {
|
178
190
|
const renderData = makeTextData({
|
179
191
|
eventData,
|
@@ -183,7 +195,7 @@ export const PieEventTexts = defineSeriesPlugin(pluginName, DEFAULT_PIE_EVENT_TE
|
|
183
195
|
textAttrs: data.fullParams.textAttrs!,
|
184
196
|
textStyles: data.fullParams.textStyles!
|
185
197
|
})
|
186
|
-
centerTextSelection = renderText(
|
198
|
+
centerTextSelection = renderText(context.containerSelection, renderData)
|
187
199
|
})
|
188
200
|
})
|
189
201
|
})
|
@@ -191,4 +203,56 @@ export const PieEventTexts = defineSeriesPlugin(pluginName, DEFAULT_PIE_EVENT_TE
|
|
191
203
|
return () => {
|
192
204
|
destroy$.next(undefined)
|
193
205
|
}
|
206
|
+
}
|
207
|
+
|
208
|
+
export const PieEventTexts = defineSeriesPlugin(pluginName, DEFAULT_PIE_EVENT_TEXTS_PARAMS)(({ selection, name, observer, subject }) => {
|
209
|
+
const destroy$ = new Subject()
|
210
|
+
|
211
|
+
const { seriesCenterSelection$ } = seriesCenterSelectionObservable({
|
212
|
+
selection: selection,
|
213
|
+
pluginName,
|
214
|
+
separateSeries$: observer.separateSeries$,
|
215
|
+
seriesLabels$: observer.seriesLabels$,
|
216
|
+
seriesContainerPosition$: observer.seriesContainerPosition$
|
217
|
+
})
|
218
|
+
|
219
|
+
const unsubscribeFnArr: (() => void)[] = []
|
220
|
+
|
221
|
+
seriesCenterSelection$.subscribe(seriesCenterSelection => {
|
222
|
+
// 每次重新計算時,清除之前的訂閱
|
223
|
+
unsubscribeFnArr.forEach(fn => fn())
|
224
|
+
|
225
|
+
seriesCenterSelection.each((d, containerIndex, g) => {
|
226
|
+
|
227
|
+
const containerSelection = d3.select(g[containerIndex])
|
228
|
+
|
229
|
+
const containerComputedLayoutData$ = observer.computedLayoutData$.pipe(
|
230
|
+
takeUntil(destroy$),
|
231
|
+
map(data => data[containerIndex] ?? data[0])
|
232
|
+
)
|
233
|
+
|
234
|
+
const containerPosition$ = observer.seriesContainerPosition$.pipe(
|
235
|
+
takeUntil(destroy$),
|
236
|
+
map(data => data[containerIndex] ?? data[0])
|
237
|
+
)
|
238
|
+
|
239
|
+
unsubscribeFnArr[containerIndex] = createEachPieEventTexts(pluginName, {
|
240
|
+
containerSelection: containerSelection,
|
241
|
+
computedData$: observer.computedData$,
|
242
|
+
containerComputedLayoutData$: containerComputedLayoutData$,
|
243
|
+
SeriesDataMap$: observer.SeriesDataMap$,
|
244
|
+
fullParams$: observer.fullParams$,
|
245
|
+
fullChartParams$: observer.fullChartParams$,
|
246
|
+
seriesHighlight$: observer.seriesHighlight$,
|
247
|
+
seriesContainerPosition$: containerPosition$,
|
248
|
+
event$: subject.event$,
|
249
|
+
})
|
250
|
+
|
251
|
+
})
|
252
|
+
})
|
253
|
+
|
254
|
+
return () => {
|
255
|
+
destroy$.next(undefined)
|
256
|
+
unsubscribeFnArr.forEach(fn => fn())
|
257
|
+
}
|
194
258
|
})
|
@@ -5,11 +5,15 @@ import {
|
|
5
5
|
first,
|
6
6
|
map,
|
7
7
|
takeUntil,
|
8
|
+
Observable,
|
8
9
|
Subject,
|
9
10
|
BehaviorSubject } from 'rxjs'
|
10
11
|
import {
|
11
12
|
defineSeriesPlugin } from '@orbcharts/core'
|
12
13
|
import type {
|
14
|
+
ComputedDatumSeries,
|
15
|
+
SeriesContainerPosition,
|
16
|
+
EventSeries,
|
13
17
|
ChartParams } from '@orbcharts/core'
|
14
18
|
import type { PieLabelsParams } from '../types'
|
15
19
|
import type { PieDatum } from '../seriesUtils'
|
@@ -17,6 +21,7 @@ import { DEFAULT_PIE_LABELS_PARAMS } from '../defaults'
|
|
17
21
|
import { makePieData } from '../seriesUtils'
|
18
22
|
import { makeD3Arc } from '../../utils/d3Utils'
|
19
23
|
import { getDatumColor, getClassName } from '../../utils/orbchartsUtils'
|
24
|
+
import { seriesCenterSelectionObservable } from '../seriesObservables'
|
20
25
|
|
21
26
|
interface RenderDatum {
|
22
27
|
pieDatum: PieDatum
|
@@ -152,52 +157,42 @@ function highlight ({ labelSelection, ids, fullChartParams }: {
|
|
152
157
|
}
|
153
158
|
|
154
159
|
|
155
|
-
|
156
|
-
|
157
|
-
//
|
158
|
-
|
159
|
-
//
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
// .attr('transform', (d) => {
|
167
|
-
// return 'translate(' + d.x + ',' + d.y + ')'
|
168
|
-
// })
|
169
|
-
// .style('opacity', 1)
|
170
|
-
|
171
|
-
// }
|
172
|
-
|
173
|
-
|
174
|
-
export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAMS)(({ selection, observer, subject }) => {
|
175
|
-
|
160
|
+
function createEachPieLabel (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<PieLabelsParams>
|
166
|
+
fullChartParams$: Observable<ChartParams>
|
167
|
+
seriesHighlight$: Observable<ComputedDatumSeries[]>
|
168
|
+
seriesContainerPosition$: Observable<SeriesContainerPosition>
|
169
|
+
event$: Subject<EventSeries>
|
170
|
+
}) {
|
176
171
|
const destroy$ = new Subject()
|
177
172
|
|
178
|
-
const graphicSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
|
173
|
+
// const graphicSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
|
179
174
|
let labelSelection$: Subject<d3.Selection<SVGPathElement, RenderDatum, any, any>> = new Subject()
|
180
175
|
let renderData: RenderDatum[] = []
|
181
176
|
// let highlightTarget: HighlightTarget | undefined
|
182
177
|
// let fullChartParams: ChartParams | undefined
|
183
178
|
|
184
|
-
observer.layout$
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
179
|
+
// observer.layout$
|
180
|
+
// .pipe(
|
181
|
+
// first()
|
182
|
+
// )
|
183
|
+
// .subscribe(size => {
|
184
|
+
// selection
|
185
|
+
// .attr('transform', `translate(${size.width / 2}, ${size.height / 2})`)
|
186
|
+
// observer.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
|
+
// })
|
201
196
|
|
202
197
|
|
203
198
|
|
@@ -222,13 +217,12 @@ export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAM
|
|
222
217
|
// })
|
223
218
|
|
224
219
|
combineLatest({
|
225
|
-
layout:
|
226
|
-
|
227
|
-
fullParams:
|
228
|
-
fullChartParams:
|
220
|
+
layout: context.seriesContainerPosition$,
|
221
|
+
containerComputedLayoutData: context.containerComputedLayoutData$,
|
222
|
+
fullParams: context.fullParams$,
|
223
|
+
fullChartParams: context.fullChartParams$
|
229
224
|
}).pipe(
|
230
225
|
takeUntil(destroy$),
|
231
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
232
226
|
switchMap(async (d) => d),
|
233
227
|
).subscribe(data => {
|
234
228
|
|
@@ -252,14 +246,14 @@ export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAM
|
|
252
246
|
})
|
253
247
|
|
254
248
|
const pieData = makePieData({
|
255
|
-
|
249
|
+
data: data.containerComputedLayoutData,
|
256
250
|
startAngle: data.fullParams.startAngle,
|
257
251
|
endAngle: data.fullParams.endAngle
|
258
252
|
})
|
259
253
|
|
260
254
|
renderData = makeRenderData(pieData, arc, arcMouseover, data.fullParams.labelCentroid)
|
261
255
|
|
262
|
-
const labelSelection = renderLabel(
|
256
|
+
const labelSelection = renderLabel(context.containerSelection, renderData, data.fullParams, data.fullChartParams)
|
263
257
|
|
264
258
|
labelSelection$.next(labelSelection)
|
265
259
|
|
@@ -267,10 +261,10 @@ export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAM
|
|
267
261
|
|
268
262
|
combineLatest({
|
269
263
|
labelSelection: labelSelection$,
|
270
|
-
highlight:
|
264
|
+
highlight: context.seriesHighlight$.pipe(
|
271
265
|
map(data => data.map(d => d.id))
|
272
266
|
),
|
273
|
-
fullChartParams:
|
267
|
+
fullChartParams: context.fullChartParams$,
|
274
268
|
}).pipe(
|
275
269
|
takeUntil(destroy$),
|
276
270
|
switchMap(async d => d)
|
@@ -282,6 +276,59 @@ export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAM
|
|
282
276
|
})
|
283
277
|
})
|
284
278
|
|
279
|
+
return () => {
|
280
|
+
destroy$.next(undefined)
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
|
285
|
+
export const PieLabels = defineSeriesPlugin(pluginName, DEFAULT_PIE_LABELS_PARAMS)(({ selection, observer, subject }) => {
|
286
|
+
|
287
|
+
const destroy$ = new Subject()
|
288
|
+
|
289
|
+
const { seriesCenterSelection$ } = seriesCenterSelectionObservable({
|
290
|
+
selection: selection,
|
291
|
+
pluginName,
|
292
|
+
separateSeries$: observer.separateSeries$,
|
293
|
+
seriesLabels$: observer.seriesLabels$,
|
294
|
+
seriesContainerPosition$: observer.seriesContainerPosition$
|
295
|
+
})
|
296
|
+
|
297
|
+
const unsubscribeFnArr: (() => void)[] = []
|
298
|
+
|
299
|
+
seriesCenterSelection$.subscribe(seriesCenterSelection => {
|
300
|
+
// 每次重新計算時,清除之前的訂閱
|
301
|
+
unsubscribeFnArr.forEach(fn => fn())
|
302
|
+
|
303
|
+
seriesCenterSelection.each((d, containerIndex, g) => {
|
304
|
+
|
305
|
+
const containerSelection = d3.select(g[containerIndex])
|
306
|
+
|
307
|
+
const containerComputedLayoutData$ = observer.computedLayoutData$.pipe(
|
308
|
+
takeUntil(destroy$),
|
309
|
+
map(data => data[containerIndex] ?? data[0])
|
310
|
+
)
|
311
|
+
|
312
|
+
const containerPosition$ = observer.seriesContainerPosition$.pipe(
|
313
|
+
takeUntil(destroy$),
|
314
|
+
map(data => data[containerIndex] ?? data[0])
|
315
|
+
)
|
316
|
+
|
317
|
+
unsubscribeFnArr[containerIndex] = createEachPieLabel(pluginName, {
|
318
|
+
containerSelection: containerSelection,
|
319
|
+
// computedData$: observer.computedData$,
|
320
|
+
containerComputedLayoutData$: containerComputedLayoutData$,
|
321
|
+
// SeriesDataMap$: observer.SeriesDataMap$,
|
322
|
+
fullParams$: observer.fullParams$,
|
323
|
+
fullChartParams$: observer.fullChartParams$,
|
324
|
+
seriesHighlight$: observer.seriesHighlight$,
|
325
|
+
seriesContainerPosition$: containerPosition$,
|
326
|
+
event$: subject.event$,
|
327
|
+
})
|
328
|
+
|
329
|
+
})
|
330
|
+
})
|
331
|
+
|
285
332
|
return () => {
|
286
333
|
destroy$.next(undefined)
|
287
334
|
}
|
@@ -0,0 +1,145 @@
|
|
1
|
+
import * as d3 from 'd3'
|
2
|
+
import {
|
3
|
+
Observable,
|
4
|
+
Subject,
|
5
|
+
of,
|
6
|
+
takeUntil,
|
7
|
+
filter,
|
8
|
+
first,
|
9
|
+
map,
|
10
|
+
switchMap,
|
11
|
+
combineLatest,
|
12
|
+
merge,
|
13
|
+
shareReplay,
|
14
|
+
distinctUntilChanged
|
15
|
+
} from 'rxjs'
|
16
|
+
import type {
|
17
|
+
SeriesContainerPosition } from '@orbcharts/core'
|
18
|
+
import { getClassName, getUniID } from '../utils/orbchartsUtils'
|
19
|
+
|
20
|
+
function createSeriesSelection ({ selection, pluginName, separateSeries$, seriesLabels$ }: {
|
21
|
+
selection: d3.Selection<any, unknown, any, unknown>
|
22
|
+
pluginName: string
|
23
|
+
separateSeries$: Observable<boolean>
|
24
|
+
seriesLabels$: Observable<string[]>
|
25
|
+
}) {
|
26
|
+
const seriesClassName = getClassName(pluginName, 'series')
|
27
|
+
|
28
|
+
return combineLatest({
|
29
|
+
seriesLabels: seriesLabels$,
|
30
|
+
separateSeries: separateSeries$
|
31
|
+
}).pipe(
|
32
|
+
switchMap(async d => d),
|
33
|
+
map((data, i) => {
|
34
|
+
const selectionData = data.separateSeries ? data.seriesLabels : [data.seriesLabels.join('')]
|
35
|
+
return selection
|
36
|
+
.selectAll<SVGGElement, string>(`g.${seriesClassName}`)
|
37
|
+
.data(selectionData, d => d)
|
38
|
+
.join(
|
39
|
+
enter => {
|
40
|
+
return enter
|
41
|
+
.append('g')
|
42
|
+
.classed(seriesClassName, true)
|
43
|
+
},
|
44
|
+
update => update,
|
45
|
+
exit => exit.remove()
|
46
|
+
)
|
47
|
+
}),
|
48
|
+
shareReplay(1)
|
49
|
+
)
|
50
|
+
}
|
51
|
+
|
52
|
+
// series選取器,以起始座標位置為基準
|
53
|
+
export const seriesStartSelectionObservable = ({ selection, pluginName, separateSeries$, seriesLabels$, seriesContainerPosition$ }: {
|
54
|
+
selection: d3.Selection<any, unknown, any, unknown>
|
55
|
+
pluginName: string
|
56
|
+
separateSeries$: Observable<boolean>
|
57
|
+
seriesLabels$: Observable<string[]>
|
58
|
+
seriesContainerPosition$: Observable<SeriesContainerPosition[]>
|
59
|
+
}) => {
|
60
|
+
|
61
|
+
const seriesStartSelection$ = createSeriesSelection({ selection, pluginName, separateSeries$, seriesLabels$ })
|
62
|
+
|
63
|
+
combineLatest({
|
64
|
+
seriesStartSelection: seriesStartSelection$,
|
65
|
+
seriesContainerPosition: seriesContainerPosition$
|
66
|
+
}).pipe(
|
67
|
+
switchMap(async d => d),
|
68
|
+
// selection數量相同的時候才執行
|
69
|
+
distinctUntilChanged((a, b) => a.seriesContainerPosition.length === b.seriesContainerPosition.length)
|
70
|
+
).subscribe(data => {
|
71
|
+
// 無transition動畫
|
72
|
+
data.seriesStartSelection
|
73
|
+
.attr('transform', (d, i) => {
|
74
|
+
const seriesContainerPosition = data.seriesContainerPosition[i] ?? data.seriesContainerPosition[0]
|
75
|
+
return `translate(${seriesContainerPosition.startX}, ${seriesContainerPosition.startY})`
|
76
|
+
})
|
77
|
+
})
|
78
|
+
|
79
|
+
combineLatest({
|
80
|
+
seriesStartSelection: seriesStartSelection$,
|
81
|
+
seriesContainerPosition: seriesContainerPosition$
|
82
|
+
}).pipe(
|
83
|
+
switchMap(async d => d),
|
84
|
+
).subscribe(data => {
|
85
|
+
// 有transition動畫
|
86
|
+
data.seriesStartSelection
|
87
|
+
.transition()
|
88
|
+
.attr('transform', (d, i) => {
|
89
|
+
const seriesContainerPosition = data.seriesContainerPosition[i] ?? data.seriesContainerPosition[0]
|
90
|
+
return `translate(${seriesContainerPosition.startX}, ${seriesContainerPosition.startY})`
|
91
|
+
})
|
92
|
+
})
|
93
|
+
|
94
|
+
return {
|
95
|
+
seriesStartSelection$
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
// series選取器,以中心座標位置為基準
|
100
|
+
export const seriesCenterSelectionObservable = ({ selection, pluginName, separateSeries$, seriesLabels$, seriesContainerPosition$ }: {
|
101
|
+
selection: d3.Selection<any, unknown, any, unknown>
|
102
|
+
pluginName: string
|
103
|
+
separateSeries$: Observable<boolean>
|
104
|
+
seriesLabels$: Observable<string[]>
|
105
|
+
seriesContainerPosition$: Observable<SeriesContainerPosition[]>
|
106
|
+
}) => {
|
107
|
+
|
108
|
+
const seriesCenterSelection$ = createSeriesSelection({ selection, pluginName, separateSeries$, seriesLabels$ })
|
109
|
+
|
110
|
+
combineLatest({
|
111
|
+
seriesCenterSelection: seriesCenterSelection$,
|
112
|
+
seriesContainerPosition: seriesContainerPosition$
|
113
|
+
}).pipe(
|
114
|
+
switchMap(async d => d),
|
115
|
+
// selection數量相同的時候才執行
|
116
|
+
distinctUntilChanged((a, b) => a.seriesContainerPosition.length === b.seriesContainerPosition.length)
|
117
|
+
).subscribe(data => {
|
118
|
+
// 無transition動畫
|
119
|
+
data.seriesCenterSelection
|
120
|
+
.attr('transform', (d, i) => {
|
121
|
+
const seriesContainerPosition = data.seriesContainerPosition[i] ?? data.seriesContainerPosition[0]
|
122
|
+
return `translate(${seriesContainerPosition.centerX}, ${seriesContainerPosition.centerY})`
|
123
|
+
})
|
124
|
+
})
|
125
|
+
|
126
|
+
combineLatest({
|
127
|
+
seriesCenterSelection: seriesCenterSelection$,
|
128
|
+
seriesContainerPosition: seriesContainerPosition$
|
129
|
+
}).pipe(
|
130
|
+
switchMap(async d => d),
|
131
|
+
).subscribe(data => {
|
132
|
+
// 有transition動畫
|
133
|
+
data.seriesCenterSelection
|
134
|
+
.transition()
|
135
|
+
.attr('transform', (d, i) => {
|
136
|
+
const seriesContainerPosition = data.seriesContainerPosition[i] ?? data.seriesContainerPosition[0]
|
137
|
+
return `translate(${seriesContainerPosition.centerX}, ${seriesContainerPosition.centerY})`
|
138
|
+
})
|
139
|
+
})
|
140
|
+
|
141
|
+
return {
|
142
|
+
seriesCenterSelection$,
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
@@ -17,8 +17,8 @@ export interface PieDatum extends D3PieDatum {
|
|
17
17
|
id: string
|
18
18
|
}
|
19
19
|
|
20
|
-
export function makePieData ({
|
21
|
-
|
20
|
+
export function makePieData ({ data, startAngle, endAngle }: {
|
21
|
+
data: ComputedDatumSeries[]
|
22
22
|
startAngle: number
|
23
23
|
endAngle: number
|
24
24
|
// itemLabels: string[]
|
@@ -30,12 +30,12 @@ export function makePieData ({ computedDataSeries, startAngle, endAngle }: {
|
|
30
30
|
.endAngle(endAngle)
|
31
31
|
.value((d) => d.visible == false ? 0 : d.value)
|
32
32
|
// .sort(null) // 不要排序
|
33
|
-
.sort((a, b) => a.
|
33
|
+
.sort((a, b) => a.seq - b.seq)
|
34
34
|
// .sort((a: any, b: any) => {
|
35
35
|
// return b.value - a.value
|
36
36
|
// })
|
37
37
|
// .sort(d3.ascending)
|
38
|
-
const pieData = pie(
|
38
|
+
const pieData = pie(data)
|
39
39
|
return pieData.map((d: D3PieDatum, i: number) => {
|
40
40
|
// const itemLabel = d.data.itemLabel
|
41
41
|
let _d: any = d
|