@orbcharts/plugins-basic 3.0.0-alpha.33 → 3.0.0-alpha.35
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 +10246 -9523
- package/dist/orbcharts-plugins-basic.umd.js +10 -10
- package/dist/src/base/BaseBarStack.d.ts +5 -1
- package/dist/src/base/BaseBars.d.ts +5 -1
- package/dist/src/base/BaseBarsTriangle.d.ts +5 -1
- package/dist/src/base/BaseDots.d.ts +33 -0
- package/dist/src/base/BaseGroupAxis.d.ts +35 -0
- package/dist/src/base/BaseLines.d.ts +3 -1
- package/dist/src/base/BaseValueAxis.d.ts +36 -0
- package/dist/src/grid/defaults.d.ts +3 -3
- package/dist/src/grid/gridObservables.d.ts +18 -4
- package/dist/src/grid/index.d.ts +1 -1
- package/dist/src/grid/plugins/Dots.d.ts +1 -3
- package/dist/src/grid/plugins/GroupAux.d.ts +3 -0
- package/dist/src/grid/plugins/GroupAxis.d.ts +1 -3
- package/dist/src/grid/plugins/ValueAxis.d.ts +1 -3
- package/dist/src/grid/plugins/ValueStackAxis.d.ts +1 -3
- package/dist/src/grid/types.d.ts +1 -1
- package/dist/src/multiGrid/defaults.d.ts +9 -2
- package/dist/src/multiGrid/index.d.ts +8 -1
- package/dist/src/multiGrid/multiGridObservables.d.ts +12 -0
- package/dist/src/multiGrid/plugins/MultiBarStack.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiBars.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiBarsTriangle.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiDots.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiGroupAxis.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiLines.d.ts +1 -0
- package/dist/src/multiGrid/plugins/MultiValueAxis.d.ts +1 -0
- package/dist/src/multiGrid/plugins/OverlappingValueAxes.d.ts +1 -0
- package/dist/src/multiGrid/types.d.ts +31 -0
- package/package.json +2 -2
- package/src/base/BaseBarStack.ts +375 -198
- package/src/base/BaseBars.ts +297 -191
- package/src/base/BaseBarsTriangle.ts +344 -229
- package/src/base/BaseDots.ts +634 -0
- package/src/base/BaseGroupAxis.ts +497 -0
- package/src/base/BaseLines.ts +180 -50
- package/src/base/BaseValueAxis.ts +475 -0
- package/src/grid/defaults.ts +3 -3
- package/src/grid/gridObservables.ts +147 -14
- package/src/grid/index.ts +1 -1
- package/src/grid/plugins/BarStack.ts +4 -0
- package/src/grid/plugins/Bars.ts +4 -0
- package/src/grid/plugins/BarsTriangle.ts +4 -0
- package/src/grid/plugins/Dots.ts +19 -410
- package/src/grid/plugins/{GroupArea.ts → GroupAux.ts} +24 -24
- package/src/grid/plugins/GroupAxis.ts +16 -348
- package/src/grid/plugins/Lines.ts +2 -0
- package/src/grid/plugins/ScalingArea.ts +9 -6
- package/src/grid/plugins/ValueAxis.ts +13 -337
- package/src/grid/plugins/ValueStackAxis.ts +35 -336
- package/src/grid/types.ts +1 -1
- package/src/index.ts +1 -0
- package/src/multiGrid/defaults.ts +120 -14
- package/src/multiGrid/index.ts +9 -2
- package/src/multiGrid/multiGridObservables.ts +279 -0
- package/src/multiGrid/plugins/MultiBarStack.ts +60 -0
- package/src/multiGrid/plugins/MultiBars.ts +59 -0
- package/src/multiGrid/plugins/MultiBarsTriangle.ts +58 -0
- package/src/multiGrid/plugins/MultiDots.ts +58 -0
- package/src/multiGrid/plugins/MultiGridLegend.ts +9 -10
- package/src/multiGrid/plugins/MultiGroupAxis.ts +53 -0
- package/src/multiGrid/plugins/MultiLines.ts +58 -0
- package/src/multiGrid/plugins/MultiValueAxis.ts +53 -0
- package/src/multiGrid/plugins/OverlappingValueAxes.ts +165 -0
- package/src/multiGrid/types.ts +39 -0
- package/tsconfig.dev.json +17 -0
- package/tsconfig.prod.json +14 -0
- package/vite.config.js +5 -0
- package/dist/src/grid/plugins/GroupArea.d.ts +0 -3
- package/dist/src/multiGrid/plugins/BarsAndLines.d.ts +0 -1
- package/dist/src/multiGrid/plugins/FirstGroupScaleAxis.d.ts +0 -0
- package/dist/src/multiGrid/plugins/TwoValueScaleAxes.d.ts +0 -0
- package/src/multiGrid/plugins/BarStackAndLines.ts +0 -0
- package/src/multiGrid/plugins/BarsAndLines.ts +0 -126
- package/src/multiGrid/plugins/BarsTriangleAndLines.ts +0 -0
- package/src/multiGrid/plugins/FirstGroupScaleAxis.ts +0 -0
- package/src/multiGrid/plugins/TwoValueScaleAxes.ts +0 -0
- /package/dist/src/{multiGrid/plugins/BarStackAndLines.d.ts → base/BaseGroupArea.d.ts} +0 -0
- /package/{dist/src/multiGrid/plugins/BarsTriangleAndLines.d.ts → src/base/BaseGroupArea.ts} +0 -0
package/src/base/BaseBarStack.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import * as d3 from 'd3'
|
2
2
|
import {
|
3
|
+
iif,
|
3
4
|
combineLatest,
|
4
5
|
map,
|
5
6
|
switchMap,
|
@@ -13,11 +14,13 @@ import type {
|
|
13
14
|
ComputedDataGrid,
|
14
15
|
DataFormatterGrid,
|
15
16
|
EventGrid,
|
16
|
-
ChartParams,
|
17
|
+
ChartParams,
|
18
|
+
ContainerPosition,
|
17
19
|
Layout,
|
18
20
|
TransformData } from '@orbcharts/core'
|
19
21
|
import { getD3TransitionEase } from '../utils/d3Utils'
|
20
22
|
import { getClassName, getUniID } from '../utils/orbchartsUtils'
|
23
|
+
import { gridSelectionsObservable } from '../grid/gridObservables'
|
21
24
|
|
22
25
|
export interface BaseBarStackParams {
|
23
26
|
barWidth: number
|
@@ -29,6 +32,7 @@ interface BaseBarStackContext {
|
|
29
32
|
selection: d3.Selection<any, unknown, any, unknown>
|
30
33
|
computedData$: Observable<ComputedDataGrid>
|
31
34
|
visibleComputedData$: Observable<ComputedDatumGrid[][]>
|
35
|
+
existedSeriesLabels$: Observable<string[]>
|
32
36
|
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
33
37
|
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
34
38
|
fullParams$: Observable<BaseBarStackParams>
|
@@ -36,11 +40,14 @@ interface BaseBarStackContext {
|
|
36
40
|
fullChartParams$: Observable<ChartParams>
|
37
41
|
gridAxesTransform$: Observable<TransformData>
|
38
42
|
gridGraphicTransform$: Observable<TransformData>
|
43
|
+
gridGraphicReverseScale$: Observable<[number, number][]>
|
39
44
|
gridAxesSize$: Observable<{
|
40
45
|
width: number;
|
41
46
|
height: number;
|
42
47
|
}>
|
43
48
|
gridHighlight$: Observable<string[]>
|
49
|
+
gridContainer$: Observable<ContainerPosition[]>
|
50
|
+
isSeriesPositionSeprate$: Observable<boolean>
|
44
51
|
event$: Subject<EventGrid>
|
45
52
|
}
|
46
53
|
|
@@ -51,17 +58,19 @@ interface GraphicDatum extends ComputedDatumGrid {
|
|
51
58
|
}
|
52
59
|
|
53
60
|
interface RenderBarParams {
|
54
|
-
|
55
|
-
|
61
|
+
graphicGSelection: d3.Selection<SVGGElement, unknown, any, any>
|
62
|
+
rectClassName: string
|
63
|
+
barData: GraphicDatum[][]
|
56
64
|
zeroY: number
|
57
65
|
groupLabels: string[]
|
58
66
|
// barScale: d3.ScalePoint<string>
|
59
67
|
params: BaseBarStackParams
|
60
68
|
chartParams: ChartParams
|
61
69
|
barWidth: number
|
62
|
-
transformedBarRadius: [number, number]
|
70
|
+
transformedBarRadius: [number, number][]
|
63
71
|
delayGroup: number
|
64
72
|
transitionItem: number
|
73
|
+
isSeriesPositionSeprate: boolean
|
65
74
|
}
|
66
75
|
|
67
76
|
type ClipPathDatum = {
|
@@ -72,9 +81,8 @@ type ClipPathDatum = {
|
|
72
81
|
height: number;
|
73
82
|
}
|
74
83
|
|
75
|
-
const pluginName = 'BarStack'
|
76
|
-
const
|
77
|
-
const gContentClassName = getClassName(pluginName, 'g-content')
|
84
|
+
// const pluginName = 'BarStack'
|
85
|
+
// const rectClassName = getClassName(pluginName, 'rect')
|
78
86
|
// group的delay在動畫中的佔比(剩餘部份的時間為圖形本身的動畫時間,因為delay時間和最後一個group的動畫時間加總為1)
|
79
87
|
const groupDelayProportionOfDuration = 0.3
|
80
88
|
|
@@ -113,68 +121,100 @@ function calctransitionItem (barGroupAmount: number, totalDuration: number) {
|
|
113
121
|
return totalDuration * (1 - groupDelayProportionOfDuration) // delay後剩餘的時間
|
114
122
|
}
|
115
123
|
|
116
|
-
function renderRectBars ({
|
124
|
+
function renderRectBars ({ graphicGSelection, rectClassName, barData, zeroY, groupLabels, params, chartParams, barWidth, transformedBarRadius, delayGroup, transitionItem, isSeriesPositionSeprate }: RenderBarParams) {
|
117
125
|
|
118
126
|
const barHalfWidth = barWidth! / 2
|
119
127
|
|
120
|
-
|
121
|
-
.
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
return enter
|
126
|
-
.append('g')
|
127
|
-
.classed(gClassName, true)
|
128
|
-
.attr('cursor', 'pointer')
|
129
|
-
},
|
130
|
-
update => update,
|
131
|
-
exit => exit.remove()
|
132
|
-
)
|
133
|
-
.attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
|
134
|
-
.each((d, i, g) => {
|
135
|
-
const bars = d3.select(g[i])
|
136
|
-
.selectAll<SVGGElement, ComputedDatumGrid>('g')
|
137
|
-
.data(d, _d => _d.id)
|
128
|
+
graphicGSelection
|
129
|
+
.each((seriesData, seriesIndex, g) => {
|
130
|
+
d3.select(g[seriesIndex])
|
131
|
+
.selectAll<SVGGElement, ComputedDatumGrid>(`rect.${rectClassName}`)
|
132
|
+
.data(barData[seriesIndex] ?? [], d => d.id)
|
138
133
|
.join(
|
139
134
|
enter => {
|
135
|
+
// console.log('enter')
|
140
136
|
return enter
|
141
|
-
.append('
|
142
|
-
.classed(
|
137
|
+
.append('rect')
|
138
|
+
.classed(rectClassName, true)
|
139
|
+
.attr('cursor', 'pointer')
|
140
|
+
.attr('height', d => 0)
|
143
141
|
},
|
144
142
|
update => update,
|
145
143
|
exit => exit.remove()
|
146
144
|
)
|
147
|
-
.
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
)
|
161
|
-
.attr('rx', transformedBarRadius[0])
|
162
|
-
.attr('ry', transformedBarRadius[1])
|
163
|
-
.attr('fill', d => d.color)
|
164
|
-
.attr('transform', `translate(${-barHalfWidth}, 0)`)
|
165
|
-
.attr('x', d => 0)
|
166
|
-
.attr('width', barWidth!)
|
167
|
-
.transition()
|
168
|
-
.duration(transitionItem)
|
169
|
-
.ease(getD3TransitionEase(chartParams.transitionEase))
|
170
|
-
.delay((d, i) => d.groupIndex * delayGroup)
|
171
|
-
.attr('y', d => d._barStartY)
|
172
|
-
.attr('height', d => Math.abs(d._barHeight))
|
173
|
-
})
|
174
|
-
|
145
|
+
.attr('transform', (d, i) => `translate(${(d ? d.axisX : 0) - barHalfWidth}, ${0})`)
|
146
|
+
.attr('fill', d => d.color)
|
147
|
+
.attr('y', d => zeroY)
|
148
|
+
.attr('x', d =>0)
|
149
|
+
.attr('width', barWidth!)
|
150
|
+
.attr('rx', transformedBarRadius[seriesIndex][0] ?? 1)
|
151
|
+
.attr('ry', transformedBarRadius[seriesIndex][1] ?? 1)
|
152
|
+
.transition()
|
153
|
+
.duration(transitionItem)
|
154
|
+
.ease(getD3TransitionEase(chartParams.transitionEase))
|
155
|
+
.delay((d, i) => d.groupIndex * delayGroup)
|
156
|
+
.attr('y', d => d._barStartY)
|
157
|
+
.attr('height', d => Math.abs(d._barHeight))
|
175
158
|
})
|
176
159
|
|
177
|
-
const
|
160
|
+
// const barGroup = graphicGSelection
|
161
|
+
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${gClassName}`)
|
162
|
+
// .data(data, (d, i) => groupLabels[i])
|
163
|
+
// .join(
|
164
|
+
// enter => {
|
165
|
+
// return enter
|
166
|
+
// .append('g')
|
167
|
+
// .classed(gClassName, true)
|
168
|
+
// .attr('cursor', 'pointer')
|
169
|
+
// },
|
170
|
+
// update => update,
|
171
|
+
// exit => exit.remove()
|
172
|
+
// )
|
173
|
+
// .attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
|
174
|
+
// .each((d, i, g) => {
|
175
|
+
// const bars = d3.select(g[i])
|
176
|
+
// .selectAll<SVGGElement, ComputedDatumGrid>('g')
|
177
|
+
// .data(d, _d => _d.id)
|
178
|
+
// .join(
|
179
|
+
// enter => {
|
180
|
+
// return enter
|
181
|
+
// .append('g')
|
182
|
+
// .classed(gContentClassName, true)
|
183
|
+
// },
|
184
|
+
// update => update,
|
185
|
+
// exit => exit.remove()
|
186
|
+
// )
|
187
|
+
// .each((_d, _i, _g) => {
|
188
|
+
// const rect = d3.select(_g[_i])
|
189
|
+
// .selectAll<SVGRectElement, ComputedDatumGrid>('rect')
|
190
|
+
// .data([_d], _d => _d.id)
|
191
|
+
// .join(
|
192
|
+
// enter => {
|
193
|
+
// return enter
|
194
|
+
// .append('rect')
|
195
|
+
// .attr('y', d => zeroY)
|
196
|
+
// .attr('height', d => 0)
|
197
|
+
// },
|
198
|
+
// update => update,
|
199
|
+
// exit => exit.remove()
|
200
|
+
// )
|
201
|
+
// .attr('rx', transformedBarRadius[0])
|
202
|
+
// .attr('ry', transformedBarRadius[1])
|
203
|
+
// .attr('fill', d => d.color)
|
204
|
+
// .attr('transform', `translate(${-barHalfWidth}, 0)`)
|
205
|
+
// .attr('x', d => 0)
|
206
|
+
// .attr('width', barWidth!)
|
207
|
+
// .transition()
|
208
|
+
// .duration(transitionItem)
|
209
|
+
// .ease(getD3TransitionEase(chartParams.transitionEase))
|
210
|
+
// .delay((d, i) => d.groupIndex * delayGroup)
|
211
|
+
// .attr('y', d => d._barStartY)
|
212
|
+
// .attr('height', d => Math.abs(d._barHeight))
|
213
|
+
// })
|
214
|
+
|
215
|
+
// })
|
216
|
+
|
217
|
+
const graphicBarSelection: d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown> = graphicGSelection.selectAll(`rect.${rectClassName}`)
|
178
218
|
|
179
219
|
|
180
220
|
return graphicBarSelection
|
@@ -248,6 +288,7 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
248
288
|
selection,
|
249
289
|
computedData$,
|
250
290
|
visibleComputedData$,
|
291
|
+
existedSeriesLabels$,
|
251
292
|
SeriesDataMap$,
|
252
293
|
GroupDataMap$,
|
253
294
|
fullParams$,
|
@@ -255,80 +296,183 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
255
296
|
fullChartParams$,
|
256
297
|
gridAxesTransform$,
|
257
298
|
gridGraphicTransform$,
|
299
|
+
gridGraphicReverseScale$,
|
258
300
|
gridAxesSize$,
|
259
301
|
gridHighlight$,
|
302
|
+
gridContainer$,
|
303
|
+
isSeriesPositionSeprate$,
|
260
304
|
event$
|
261
305
|
}) => {
|
262
306
|
|
263
307
|
const destroy$ = new Subject()
|
264
308
|
|
265
309
|
const clipPathID = getUniID(pluginName, 'clipPath-box')
|
310
|
+
const rectClassName = getClassName(pluginName, 'rect')
|
266
311
|
|
267
|
-
const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection
|
268
|
-
|
269
|
-
|
270
|
-
const defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any> = axisSelection.append('defs')
|
271
|
-
const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = axisSelection.append('g')
|
272
|
-
const barSelection$: Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>> = new Subject()
|
273
|
-
|
274
|
-
gridAxesTransform$
|
275
|
-
.pipe(
|
276
|
-
takeUntil(destroy$),
|
277
|
-
map(d => d.value),
|
278
|
-
distinctUntilChanged()
|
279
|
-
).subscribe(d => {
|
280
|
-
axisSelection
|
281
|
-
.style('transform', d)
|
282
|
-
})
|
312
|
+
// const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection
|
313
|
+
// .append('g')
|
314
|
+
// .attr('clip-path', `url(#${clipPathID})`)
|
315
|
+
// const defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any> = axisSelection.append('defs')
|
316
|
+
// const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = axisSelection.append('g')
|
317
|
+
// const barSelection$: Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>> = new Subject()
|
283
318
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
319
|
+
// gridAxesTransform$
|
320
|
+
// .pipe(
|
321
|
+
// takeUntil(destroy$),
|
322
|
+
// map(d => d.value),
|
323
|
+
// distinctUntilChanged()
|
324
|
+
// ).subscribe(d => {
|
325
|
+
// axisSelection
|
326
|
+
// .style('transform', d)
|
327
|
+
// })
|
328
|
+
|
329
|
+
// gridGraphicTransform$
|
330
|
+
// .pipe(
|
331
|
+
// takeUntil(destroy$),
|
332
|
+
// switchMap(async d => d.value),
|
333
|
+
// distinctUntilChanged()
|
334
|
+
// ).subscribe(d => {
|
335
|
+
// graphicGSelection
|
336
|
+
// .transition()
|
337
|
+
// .duration(50)
|
338
|
+
// .style('transform', d)
|
339
|
+
// })
|
295
340
|
|
296
|
-
// const
|
297
|
-
//
|
298
|
-
//
|
341
|
+
// const seriesSelection$ = computedData$.pipe(
|
342
|
+
// takeUntil(destroy$),
|
343
|
+
// distinctUntilChanged((a, b) => {
|
344
|
+
// // 只有當series的數量改變時,才重新計算
|
345
|
+
// return a.length === b.length
|
346
|
+
// }),
|
347
|
+
// map((computedData, i) => {
|
348
|
+
// return selection
|
349
|
+
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${seriesClassName}`)
|
350
|
+
// .data(computedData, d => d[0] ? d[0].seriesIndex : i)
|
351
|
+
// .join(
|
352
|
+
// enter => {
|
353
|
+
// return enter
|
354
|
+
// .append('g')
|
355
|
+
// .classed(seriesClassName, true)
|
356
|
+
// .each((d, i, g) => {
|
357
|
+
// const axesSelection = d3.select(g[i])
|
358
|
+
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${axesClassName}`)
|
359
|
+
// .data([i])
|
360
|
+
// .join(
|
361
|
+
// enter => {
|
362
|
+
// return enter
|
363
|
+
// .append('g')
|
364
|
+
// .classed(axesClassName, true)
|
365
|
+
// .attr('clip-path', `url(#${clipPathID})`)
|
366
|
+
// .each((d, i, g) => {
|
367
|
+
// const defsSelection = d3.select(g[i])
|
368
|
+
// .selectAll<SVGDefsElement, any>('defs')
|
369
|
+
// .data([i])
|
370
|
+
// .join('defs')
|
371
|
+
|
372
|
+
// const graphicGSelection = d3.select(g[i])
|
373
|
+
// .selectAll<SVGGElement, any>('g')
|
374
|
+
// .data([i])
|
375
|
+
// .join('g')
|
376
|
+
// .classed(graphicClassName, true)
|
377
|
+
// })
|
378
|
+
// },
|
379
|
+
// update => update,
|
380
|
+
// exit => exit.remove()
|
381
|
+
// )
|
382
|
+
// })
|
383
|
+
// },
|
384
|
+
// update => update,
|
385
|
+
// exit => exit.remove()
|
386
|
+
// )
|
387
|
+
// })
|
388
|
+
// )
|
389
|
+
|
390
|
+
// combineLatest({
|
391
|
+
// seriesSelection: seriesSelection$,
|
392
|
+
// gridContainer: gridContainer$
|
393
|
+
// }).pipe(
|
394
|
+
// takeUntil(destroy$),
|
395
|
+
// switchMap(async d => d)
|
396
|
+
// ).subscribe(data => {
|
397
|
+
// data.seriesSelection
|
398
|
+
// .transition()
|
399
|
+
// .attr('transform', (d, i) => {
|
400
|
+
// const translate = data.gridContainer[i].translate
|
401
|
+
// const scale = data.gridContainer[i].scale
|
402
|
+
// return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
403
|
+
// })
|
299
404
|
// })
|
300
405
|
|
301
|
-
|
406
|
+
|
407
|
+
// const axesSelection$ = combineLatest({
|
408
|
+
// seriesSelection: seriesSelection$,
|
409
|
+
// gridAxesTransform: gridAxesTransform$
|
410
|
+
// }).pipe(
|
302
411
|
// takeUntil(destroy$),
|
412
|
+
// switchMap(async d => d),
|
303
413
|
// map(data => {
|
304
|
-
//
|
305
|
-
// .
|
306
|
-
//
|
307
|
-
//
|
308
|
-
//
|
309
|
-
//
|
310
|
-
//
|
311
|
-
//
|
312
|
-
// return
|
414
|
+
// return data.seriesSelection
|
415
|
+
// .select<SVGGElement>(`g.${axesClassName}`)
|
416
|
+
// .style('transform', data.gridAxesTransform.value)
|
417
|
+
// })
|
418
|
+
// )
|
419
|
+
// const defsSelection$ = axesSelection$.pipe(
|
420
|
+
// takeUntil(destroy$),
|
421
|
+
// map(axesSelection => {
|
422
|
+
// return axesSelection.select<SVGDefsElement>('defs')
|
423
|
+
// })
|
424
|
+
// )
|
425
|
+
// const graphicGSelection$ = combineLatest({
|
426
|
+
// axesSelection: axesSelection$,
|
427
|
+
// gridGraphicTransform: gridGraphicTransform$
|
428
|
+
// }).pipe(
|
429
|
+
// takeUntil(destroy$),
|
430
|
+
// switchMap(async d => d),
|
431
|
+
// map(data => {
|
432
|
+
// const graphicGSelection = data.axesSelection
|
433
|
+
// .select<SVGGElement>(`g.${graphicClassName}`)
|
434
|
+
// graphicGSelection
|
435
|
+
// .transition()
|
436
|
+
// .duration(50)
|
437
|
+
// .style('transform', data.gridGraphicTransform.value)
|
438
|
+
// return graphicGSelection
|
313
439
|
// })
|
314
440
|
// )
|
315
441
|
|
442
|
+
const {
|
443
|
+
seriesSelection$,
|
444
|
+
axesSelection$,
|
445
|
+
defsSelection$,
|
446
|
+
graphicGSelection$
|
447
|
+
} = gridSelectionsObservable({
|
448
|
+
selection,
|
449
|
+
pluginName,
|
450
|
+
clipPathID,
|
451
|
+
existedSeriesLabels$,
|
452
|
+
gridContainer$,
|
453
|
+
gridAxesTransform$,
|
454
|
+
gridGraphicTransform$
|
455
|
+
})
|
456
|
+
|
457
|
+
|
316
458
|
const zeroY$ = visibleComputedData$.pipe(
|
459
|
+
takeUntil(destroy$),
|
317
460
|
map(d => d[0] && d[0][0]
|
318
461
|
? d[0][0].axisY - d[0][0].axisYFromZero
|
319
462
|
: 0),
|
320
463
|
distinctUntilChanged()
|
321
464
|
)
|
322
465
|
|
323
|
-
const barWidth$ =
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
466
|
+
const barWidth$ = combineLatest({
|
467
|
+
computedData: computedData$,
|
468
|
+
// visibleComputedData: visibleComputedData$,
|
469
|
+
params: fullParams$,
|
470
|
+
axisSize: gridAxesSize$,
|
471
|
+
isSeriesPositionSeprate: isSeriesPositionSeprate$
|
472
|
+
}).pipe(
|
473
|
+
takeUntil(destroy$),
|
474
|
+
switchMap(async d => d),
|
475
|
+
map(data => {
|
332
476
|
const barWidth = data.params.barWidth
|
333
477
|
? data.params.barWidth
|
334
478
|
: calcBarWidth({
|
@@ -336,18 +480,18 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
336
480
|
groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
|
337
481
|
barGroupPadding: data.params.barGroupPadding
|
338
482
|
})
|
339
|
-
|
340
|
-
})
|
341
|
-
}).pipe(
|
342
|
-
takeUntil(destroy$),
|
483
|
+
return barWidth
|
484
|
+
}),
|
343
485
|
distinctUntilChanged()
|
344
486
|
)
|
345
487
|
|
346
488
|
// 圓角的值 [rx, ry]
|
347
|
-
const transformedBarRadius$: Observable<[number, number]> = combineLatest({
|
348
|
-
|
489
|
+
const transformedBarRadius$: Observable<[number, number][]> = combineLatest({
|
490
|
+
computedData: computedData$,
|
491
|
+
// gridGraphicTransform: gridGraphicTransform$,
|
349
492
|
barWidth: barWidth$,
|
350
|
-
params: fullParams
|
493
|
+
params: fullParams$,
|
494
|
+
gridGraphicReverseScale: gridGraphicReverseScale$
|
351
495
|
}).pipe(
|
352
496
|
takeUntil(destroy$),
|
353
497
|
switchMap(async data => data),
|
@@ -357,13 +501,15 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
357
501
|
: data.params.barRadius === false ? 0
|
358
502
|
: typeof data.params.barRadius == 'number' ? data.params.barRadius
|
359
503
|
: 0
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
504
|
+
|
505
|
+
return data.computedData.map((series, seriesIndex) => {
|
506
|
+
const gridGraphicReverseScale = data.gridGraphicReverseScale[seriesIndex] ?? data.gridGraphicReverseScale[0]
|
507
|
+
|
508
|
+
const transformedRx = radius * gridGraphicReverseScale[0]
|
509
|
+
const transformedRy = radius * gridGraphicReverseScale[1]
|
510
|
+
|
511
|
+
return [transformedRx, transformedRy]
|
512
|
+
})
|
367
513
|
})
|
368
514
|
)
|
369
515
|
|
@@ -393,20 +539,6 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
393
539
|
})
|
394
540
|
)
|
395
541
|
|
396
|
-
// const barScale$: Observable<d3.ScalePoint<string>> = new Observable(subscriber => {
|
397
|
-
// combineLatest({
|
398
|
-
// seriesLabels: seriesLabels$,
|
399
|
-
// barWidth: barWidth$,
|
400
|
-
// params: fullParams$,
|
401
|
-
// }).pipe(
|
402
|
-
// takeUntil(destroy$),
|
403
|
-
// switchMap(async d => d)
|
404
|
-
// ).subscribe(data => {
|
405
|
-
// const barScale = makeBarScale(data.barWidth, data.seriesLabels, data.params)
|
406
|
-
// subscriber.next(barScale)
|
407
|
-
// })
|
408
|
-
// })
|
409
|
-
|
410
542
|
const transitionDuration$ = fullChartParams$.pipe(
|
411
543
|
takeUntil(destroy$),
|
412
544
|
map(d => d.transitionDuration),
|
@@ -443,46 +575,46 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
443
575
|
distinctUntilChanged()
|
444
576
|
)
|
445
577
|
|
446
|
-
const transposedVisibleData$: Observable<ComputedDataGrid> = visibleComputedData$.pipe(
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
)
|
578
|
+
// const transposedVisibleData$: Observable<ComputedDataGrid> = visibleComputedData$.pipe(
|
579
|
+
// takeUntil(destroy$),
|
580
|
+
// map(data => {
|
581
|
+
// console.log('visibleComputedData', data)
|
582
|
+
// // 取得原始陣列的維度
|
583
|
+
// const rows = data.length;
|
584
|
+
// const cols = data.reduce((prev, current) => {
|
585
|
+
// return Math.max(prev, current.length)
|
586
|
+
// }, 0)
|
587
|
+
|
588
|
+
// // 初始化轉換後的陣列
|
589
|
+
// const transposedArray = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
|
590
|
+
|
591
|
+
// // 遍歷原始陣列,進行轉換
|
592
|
+
// for (let i = 0; i < rows; i++) {
|
593
|
+
// for (let j = 0; j < cols; j++) {
|
594
|
+
// transposedArray[j][i] = data[i][j]
|
595
|
+
// }
|
596
|
+
// }
|
597
|
+
// return transposedArray
|
598
|
+
// })
|
599
|
+
// )
|
468
600
|
|
469
601
|
const yRatio$ = combineLatest({
|
470
|
-
|
602
|
+
computedData: computedData$,
|
471
603
|
dataFormatter: fullDataFormatter$,
|
472
604
|
}).pipe(
|
473
605
|
takeUntil(destroy$),
|
474
606
|
switchMap(async d => d),
|
475
607
|
map(data => {
|
476
608
|
const groupMin = 0
|
477
|
-
const groupMax = data.
|
478
|
-
const groupScaleDomainMin = data.dataFormatter.groupAxis.scaleDomain[0] === 'auto'
|
479
|
-
? groupMin - data.dataFormatter.groupAxis.scalePadding
|
480
|
-
: data.dataFormatter.groupAxis.scaleDomain[0] as number - data.dataFormatter.groupAxis.scalePadding
|
481
|
-
const groupScaleDomainMax = data.dataFormatter.groupAxis.scaleDomain[1] === 'auto'
|
482
|
-
? groupMax + data.dataFormatter.groupAxis.scalePadding
|
483
|
-
: data.dataFormatter.groupAxis.scaleDomain[1] as number + data.dataFormatter.groupAxis.scalePadding
|
609
|
+
const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
610
|
+
const groupScaleDomainMin = data.dataFormatter.grid.groupAxis.scaleDomain[0] === 'auto'
|
611
|
+
? groupMin - data.dataFormatter.grid.groupAxis.scalePadding
|
612
|
+
: data.dataFormatter.grid.groupAxis.scaleDomain[0] as number - data.dataFormatter.grid.groupAxis.scalePadding
|
613
|
+
const groupScaleDomainMax = data.dataFormatter.grid.groupAxis.scaleDomain[1] === 'auto'
|
614
|
+
? groupMax + data.dataFormatter.grid.groupAxis.scalePadding
|
615
|
+
: data.dataFormatter.grid.groupAxis.scaleDomain[1] as number + data.dataFormatter.grid.groupAxis.scalePadding
|
484
616
|
|
485
|
-
const filteredData = data.
|
617
|
+
const filteredData = data.computedData
|
486
618
|
.map(d => {
|
487
619
|
return d.filter((_d, i) => {
|
488
620
|
return _d.groupIndex >= groupScaleDomainMin && _d.groupIndex <= groupScaleDomainMax
|
@@ -490,12 +622,20 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
490
622
|
})
|
491
623
|
// console.log('filteredData', filteredData)
|
492
624
|
|
493
|
-
if (
|
625
|
+
if (filteredData.length <= 1) {
|
494
626
|
return 1
|
495
627
|
} else {
|
496
628
|
const yArr = filteredData.flat().map(d => d.axisYFromZero)
|
497
629
|
const barMaxY = Math.max(...yArr)
|
498
|
-
const stackYArr = filteredData.map(d => d.reduce((prev, current) => prev + current.axisYFromZero, 0))
|
630
|
+
// const stackYArr = filteredData.map(d => d.reduce((prev, current) => prev + current.axisYFromZero, 0))
|
631
|
+
const stackYArr = data.computedData[0]
|
632
|
+
? data.computedData[0].map((_, groupIndex) => {
|
633
|
+
// 加總同一group的value
|
634
|
+
return data.computedData.reduce((prev, current) => {
|
635
|
+
return prev + current[groupIndex].axisYFromZero
|
636
|
+
}, 0)
|
637
|
+
})
|
638
|
+
: []
|
499
639
|
const barStackMaxY = Math.max(...stackYArr)
|
500
640
|
|
501
641
|
return barMaxY / barStackMaxY
|
@@ -503,60 +643,97 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
503
643
|
})
|
504
644
|
)
|
505
645
|
|
506
|
-
const
|
507
|
-
|
646
|
+
const stackedData$ = combineLatest({
|
647
|
+
computedData: computedData$,
|
508
648
|
yRatio: yRatio$,
|
509
649
|
zeroY: zeroY$
|
510
650
|
}).pipe(
|
511
651
|
takeUntil(destroy$),
|
512
652
|
map(data => {
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
const
|
519
|
-
|
653
|
+
let accYArr: number[] = data.computedData[0]
|
654
|
+
? data.computedData[0].map(() => data.zeroY)
|
655
|
+
: []
|
656
|
+
return data.computedData.map((series, seriesIndex) => {
|
657
|
+
return series.map((datum, groupIndex) => {
|
658
|
+
const _barStartY = accYArr[groupIndex] // 前一次的累加高度
|
659
|
+
const _barHeight = datum.axisYFromZero * data.yRatio
|
660
|
+
accYArr[groupIndex] = accYArr[groupIndex] + _barHeight // 累加高度
|
520
661
|
return <GraphicDatum>{
|
521
|
-
...
|
662
|
+
...datum,
|
522
663
|
_barStartY,
|
523
664
|
_barHeight
|
524
665
|
}
|
525
666
|
})
|
526
667
|
})
|
668
|
+
// return data.computedData.map(d => {
|
669
|
+
// let accY = data.zeroY
|
670
|
+
// return d.map(_d => {
|
671
|
+
// const _barStartY = accY
|
672
|
+
// const _barHeight = _d.axisYFromZero * data.yRatio
|
673
|
+
// accY = accY + _barHeight
|
674
|
+
// return <GraphicDatum>{
|
675
|
+
// ..._d,
|
676
|
+
// _barStartY,
|
677
|
+
// _barHeight
|
678
|
+
// }
|
679
|
+
// })
|
680
|
+
// })
|
681
|
+
})
|
682
|
+
)
|
683
|
+
|
684
|
+
const noneStackedData$ = combineLatest({
|
685
|
+
computedData: computedData$,
|
686
|
+
// yRatio: yRatio$,
|
687
|
+
zeroY: zeroY$
|
688
|
+
}).pipe(
|
689
|
+
takeUntil(destroy$),
|
690
|
+
map(data => {
|
691
|
+
return data.computedData.map((series, seriesIndex) => {
|
692
|
+
return series.map((datum, groupIndex) => {
|
693
|
+
return <GraphicDatum>{
|
694
|
+
...datum,
|
695
|
+
_barStartY: data.zeroY,
|
696
|
+
_barHeight: datum.axisYFromZero
|
697
|
+
}
|
698
|
+
})
|
699
|
+
})
|
527
700
|
})
|
528
701
|
)
|
529
702
|
|
530
|
-
|
531
|
-
|
703
|
+
const graphicData$ = isSeriesPositionSeprate$.pipe(
|
704
|
+
switchMap(isSeriesPositionSeprate => {
|
705
|
+
return iif(() => isSeriesPositionSeprate, noneStackedData$, stackedData$)
|
706
|
+
})
|
707
|
+
)
|
708
|
+
|
709
|
+
combineLatest({
|
710
|
+
defsSelection: defsSelection$,
|
711
|
+
gridAxesSize: gridAxesSize$,
|
712
|
+
}).pipe(
|
713
|
+
takeUntil(destroy$),
|
714
|
+
switchMap(async d => d)
|
532
715
|
).subscribe(data => {
|
533
716
|
const clipPathData = [{
|
534
717
|
id: clipPathID,
|
535
|
-
width: data.width,
|
536
|
-
height: data.height
|
718
|
+
width: data.gridAxesSize.width,
|
719
|
+
height: data.gridAxesSize.height
|
537
720
|
}]
|
538
721
|
renderClipPath({
|
539
|
-
defsSelection,
|
722
|
+
defsSelection: data.defsSelection,
|
540
723
|
clipPathData
|
541
724
|
})
|
542
725
|
})
|
543
726
|
|
544
|
-
// const SeriesDataMap$ = visibleComputedData$.pipe(
|
545
|
-
// map(d => makeGridSeriesDataMap(d))
|
546
|
-
// )
|
547
|
-
|
548
|
-
// const GroupDataMap$ = visibleComputedData$.pipe(
|
549
|
-
// map(d => makeGridGroupDataMap(d))
|
550
|
-
// )
|
551
|
-
|
552
727
|
const highlightTarget$ = fullChartParams$.pipe(
|
553
728
|
takeUntil(destroy$),
|
554
729
|
map(d => d.highlightTarget),
|
555
730
|
distinctUntilChanged()
|
556
731
|
)
|
557
732
|
|
733
|
+
const barSelection$ = new Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>>()
|
734
|
+
|
558
735
|
combineLatest({
|
559
|
-
|
736
|
+
graphicGSelection: graphicGSelection$,
|
560
737
|
graphicData: graphicData$,
|
561
738
|
zeroY: zeroY$,
|
562
739
|
groupLabels: groupLabels$,
|
@@ -569,15 +746,16 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
569
746
|
delayGroup: delayGroup$,
|
570
747
|
transitionItem: transitionItem$,
|
571
748
|
SeriesDataMap: SeriesDataMap$,
|
572
|
-
GroupDataMap: GroupDataMap
|
749
|
+
GroupDataMap: GroupDataMap$,
|
750
|
+
isSeriesPositionSeprate: isSeriesPositionSeprate$
|
573
751
|
}).pipe(
|
574
752
|
takeUntil(destroy$),
|
575
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
576
753
|
switchMap(async (d) => d),
|
577
754
|
).subscribe(data => {
|
578
755
|
const barSelection = renderRectBars({
|
579
|
-
|
580
|
-
|
756
|
+
graphicGSelection: data.graphicGSelection,
|
757
|
+
rectClassName,
|
758
|
+
barData: data.graphicData,
|
581
759
|
zeroY: data.zeroY,
|
582
760
|
groupLabels: data.groupLabels,
|
583
761
|
// barScale: data.barScale,
|
@@ -586,7 +764,8 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
586
764
|
barWidth: data.barWidth,
|
587
765
|
transformedBarRadius: data.transformedBarRadius,
|
588
766
|
delayGroup: data.delayGroup,
|
589
|
-
transitionItem: data.transitionItem
|
767
|
+
transitionItem: data.transitionItem,
|
768
|
+
isSeriesPositionSeprate: data.isSeriesPositionSeprate
|
590
769
|
})
|
591
770
|
|
592
771
|
barSelection!
|
@@ -675,7 +854,6 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
675
854
|
// map(d => d.flat())
|
676
855
|
// )
|
677
856
|
// const highlight$ = highlightObservable({ datumList$, chartParams$, event$: store.event$ })
|
678
|
-
const highlightSubscription = gridHighlight$.subscribe()
|
679
857
|
|
680
858
|
combineLatest({
|
681
859
|
barSelection: barSelection$,
|
@@ -694,6 +872,5 @@ export const createBaseBarStack: BasePluginFn<BaseBarStackContext> = (pluginName
|
|
694
872
|
|
695
873
|
return () => {
|
696
874
|
destroy$.next(undefined)
|
697
|
-
highlightSubscription.unsubscribe()
|
698
875
|
}
|
699
876
|
}
|