@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
@@ -12,11 +12,13 @@ import type {
|
|
12
12
|
ComputedDatumGrid,
|
13
13
|
ComputedDataGrid,
|
14
14
|
EventGrid,
|
15
|
-
ChartParams,
|
15
|
+
ChartParams,
|
16
|
+
ContainerPosition,
|
16
17
|
Layout,
|
17
18
|
TransformData } from '@orbcharts/core'
|
18
19
|
import { getD3TransitionEase } from '../utils/d3Utils'
|
19
20
|
import { getClassName, getUniID } from '../utils/orbchartsUtils'
|
21
|
+
import { gridSelectionsObservable } from '../grid/gridObservables'
|
20
22
|
|
21
23
|
export interface BaseBarsTriangleParams {
|
22
24
|
barWidth: number
|
@@ -28,6 +30,8 @@ export interface BaseBarsTriangleParams {
|
|
28
30
|
interface BaseBarsContext {
|
29
31
|
selection: d3.Selection<any, unknown, any, unknown>
|
30
32
|
computedData$: Observable<ComputedDataGrid>
|
33
|
+
visibleComputedData$: Observable<ComputedDatumGrid[][]>
|
34
|
+
existedSeriesLabels$: Observable<string[]>
|
31
35
|
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
32
36
|
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
33
37
|
fullParams$: Observable<BaseBarsTriangleParams>
|
@@ -39,14 +43,18 @@ interface BaseBarsContext {
|
|
39
43
|
height: number;
|
40
44
|
}>
|
41
45
|
gridHighlight$: Observable<string[]>
|
46
|
+
gridContainer$: Observable<ContainerPosition[]>
|
47
|
+
isSeriesPositionSeprate$: Observable<boolean>
|
42
48
|
event$: Subject<EventGrid>
|
43
49
|
}
|
44
50
|
|
45
51
|
|
46
52
|
interface RenderBarParams {
|
47
|
-
|
53
|
+
graphicGSelection: d3.Selection<SVGGElement, unknown, any, any>
|
54
|
+
pathGClassName: string
|
55
|
+
pathClassName: string
|
48
56
|
barData: BarDatumGrid[][]
|
49
|
-
|
57
|
+
zeroYArr: number[]
|
50
58
|
groupLabels: string[]
|
51
59
|
barScale: d3.ScalePoint<string>
|
52
60
|
params: BaseBarsTriangleParams
|
@@ -54,6 +62,7 @@ interface RenderBarParams {
|
|
54
62
|
barWidth: number
|
55
63
|
delayGroup: number
|
56
64
|
transitionItem: number
|
65
|
+
isSeriesPositionSeprate: boolean
|
57
66
|
}
|
58
67
|
|
59
68
|
interface BarDatumGrid extends ComputedDatumGrid {
|
@@ -68,9 +77,9 @@ type ClipPathDatum = {
|
|
68
77
|
height: number;
|
69
78
|
}
|
70
79
|
|
71
|
-
const pluginName = 'BaseBarsTriangle'
|
72
|
-
const
|
73
|
-
const
|
80
|
+
// const pluginName = 'BaseBarsTriangle'
|
81
|
+
// const pathGClassName = getClassName(pluginName, 'pathG')
|
82
|
+
// const pathClassName = getClassName(pluginName, 'path')
|
74
83
|
// group的delay在動畫中的佔比(剩餘部份的時間為圖形本身的動畫時間,因為delay時間和最後一個group的動畫時間加總為1)
|
75
84
|
const groupDelayProportionOfDuration = 0.3
|
76
85
|
|
@@ -81,7 +90,8 @@ function calcBarWidth ({ axisWidth, groupAmount, barAmountOfGroup, barPadding =
|
|
81
90
|
barPadding: number
|
82
91
|
barGroupPadding: number
|
83
92
|
}) {
|
84
|
-
const
|
93
|
+
const eachGroupWidth = axisWidth / (groupAmount - 1)
|
94
|
+
const width = (eachGroupWidth - barGroupPadding) / barAmountOfGroup - barPadding
|
85
95
|
return width > 1 ? width : 1
|
86
96
|
}
|
87
97
|
|
@@ -109,102 +119,99 @@ function calctransitionItem (barGroupAmount: number, totalDuration: number) {
|
|
109
119
|
return totalDuration * (1 - groupDelayProportionOfDuration) // delay後剩餘的時間
|
110
120
|
}
|
111
121
|
|
112
|
-
function renderTriangleBars ({
|
113
|
-
|
114
|
-
// if (barWidth <= 0) {
|
115
|
-
// return
|
116
|
-
// }
|
117
|
-
const update = selection!
|
118
|
-
.selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${gClassName}`)
|
119
|
-
.data(barData, (d, i) => groupLabels[i])
|
120
|
-
const enter = update.enter()
|
121
|
-
.append('g')
|
122
|
-
.classed(gClassName, true)
|
123
|
-
.attr('cursor', 'pointer')
|
124
|
-
update.exit().remove()
|
125
|
-
const graphicGroupSelection = update.merge(enter)
|
126
|
-
enter
|
127
|
-
.attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
|
128
|
-
update
|
129
|
-
// .transition()
|
130
|
-
// .duration(200)
|
131
|
-
.attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
|
132
|
-
|
122
|
+
function renderTriangleBars ({ graphicGSelection, pathGClassName, pathClassName, barData, zeroYArr, groupLabels, barScale, params, chartParams, barWidth, delayGroup, transitionItem, isSeriesPositionSeprate }: RenderBarParams) {
|
123
|
+
|
133
124
|
const barHalfWidth = barWidth! / 2
|
134
125
|
|
135
|
-
|
136
|
-
.each((d,
|
137
|
-
|
138
|
-
|
139
|
-
.
|
140
|
-
|
141
|
-
.
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
126
|
+
graphicGSelection
|
127
|
+
.each((d, seriesIndex, g) => {
|
128
|
+
// g
|
129
|
+
const gSelection = d3.select(g[seriesIndex])
|
130
|
+
.selectAll<SVGGElement, ComputedDatumGrid>(`g.${pathGClassName}`)
|
131
|
+
.data(barData[seriesIndex] ?? [])
|
132
|
+
.join(
|
133
|
+
enter => {
|
134
|
+
const enterSelection = enter
|
135
|
+
.append('g')
|
136
|
+
.classed(pathGClassName, true)
|
137
|
+
.attr('cursor', 'pointer')
|
138
|
+
enterSelection
|
139
|
+
.append('path')
|
140
|
+
.classed(pathClassName, true)
|
141
|
+
.style('vector-effect', 'non-scaling-stroke')
|
142
|
+
.attr('d', (d) => {
|
143
|
+
const x = -barHalfWidth
|
144
|
+
const y1 = zeroYArr[seriesIndex]
|
145
|
+
const y2 = zeroYArr[seriesIndex]
|
146
|
+
return `M${x},${y1} L${x + (barWidth! / 2)},${y2} ${x + barWidth!},${y1}`
|
147
|
+
})
|
148
|
+
return enterSelection
|
149
|
+
},
|
150
|
+
update => update,
|
151
|
+
exit => exit.remove()
|
152
|
+
)
|
153
|
+
.attr('transform', d => `translate(${isSeriesPositionSeprate ? 0 : barScale(d.seriesLabel)!}, 0)`)
|
154
|
+
|
155
|
+
// path
|
156
|
+
gSelection.select(`path.${pathClassName}`)
|
157
|
+
.attr('height', d => Math.abs(d.axisYFromZero))
|
158
|
+
.attr('y', d => d.axisY < zeroYArr[seriesIndex] ? d.axisY : zeroYArr[seriesIndex])
|
159
|
+
.attr('x', d => isSeriesPositionSeprate ? 0 : barScale(d.seriesLabel)!)
|
159
160
|
.style('fill', d => `url(#${d.linearGradientId})`)
|
160
161
|
.attr('stroke', d => d.color)
|
161
|
-
.attr('transform', `translate(${
|
162
|
+
.attr('transform', d => `translate(${(d ? d.axisX : 0)}, ${0})`)
|
162
163
|
.transition()
|
163
164
|
.duration(transitionItem)
|
164
165
|
.ease(getD3TransitionEase(chartParams.transitionEase))
|
165
166
|
.delay((d, i) => d.groupIndex * delayGroup)
|
166
|
-
.attr('transform', `translate(${-barHalfWidth}, 0)`)
|
167
|
+
// .attr('transform', `translate(${-barHalfWidth}, 0)`)
|
167
168
|
// .attr('x', d => itemScale(d.itemLabel)!)
|
168
169
|
// .attr('y', d => -d.y)
|
169
|
-
.attr('height', d => Math.abs(d.axisYFromZero))
|
170
170
|
.attr('d', (d) => {
|
171
|
-
const x =
|
172
|
-
const y1 =
|
171
|
+
const x = -barHalfWidth
|
172
|
+
const y1 = zeroYArr[seriesIndex]
|
173
173
|
const y2 = d.axisY
|
174
174
|
return `M${x},${y1} L${x + (barWidth! / 2)},${y2} ${x + barWidth!},${y1}`
|
175
175
|
})
|
176
|
-
|
177
|
-
pathUpdate.exit().remove()
|
178
|
-
})
|
176
|
+
})
|
179
177
|
|
180
|
-
const graphicBarSelection: d3.Selection<SVGPathElement, ComputedDatumGrid, any, any> =
|
178
|
+
const graphicBarSelection: d3.Selection<SVGPathElement, ComputedDatumGrid, any, any> = graphicGSelection.selectAll(`path.${pathClassName}`)
|
181
179
|
|
182
180
|
return graphicBarSelection
|
183
181
|
}
|
184
182
|
|
185
183
|
function renderLinearGradient ({ defsSelection, barData, params }: {
|
186
|
-
defsSelection: d3.Selection<SVGDefsElement,
|
184
|
+
defsSelection: d3.Selection<SVGDefsElement, any, any, any>
|
187
185
|
barData: BarDatumGrid[][]
|
188
186
|
params: BaseBarsTriangleParams
|
189
187
|
}) {
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
188
|
+
defsSelection!
|
189
|
+
.selectAll<SVGLinearGradientElement, ComputedDatumGrid>('linearGradient')
|
190
|
+
.data(barData ?? [])
|
191
|
+
.join(
|
192
|
+
enter => {
|
193
|
+
return enter
|
194
|
+
.append('linearGradient')
|
195
|
+
.attr('x1', '0%')
|
196
|
+
.attr('x2', '0%')
|
197
|
+
.attr('y1', '100%')
|
198
|
+
.attr('y2', '0%')
|
199
|
+
.attr('spreadMethod', 'pad')
|
200
|
+
},
|
201
|
+
update => update,
|
202
|
+
exit => exit.remove()
|
203
|
+
)
|
204
|
+
.attr('id', (d, i) => {
|
205
|
+
return d[0] ? d[0].linearGradientId : ''
|
206
|
+
})
|
207
|
+
.html((d, i) => {
|
208
|
+
const color = d[0] ? d[0].color : ''
|
209
|
+
return `
|
210
|
+
<stop offset="0%" stop-color="${color}" stop-opacity="${params.linearGradientOpacity[0]}"/>
|
211
|
+
<stop offset="100%" stop-color="${color}" stop-opacity="${params.linearGradientOpacity[1]}"/>
|
212
|
+
`
|
213
|
+
})
|
214
|
+
|
208
215
|
}
|
209
216
|
|
210
217
|
|
@@ -212,27 +219,35 @@ function renderClipPath ({ defsSelection, clipPathData }: {
|
|
212
219
|
defsSelection: d3.Selection<SVGDefsElement, any, any, any>
|
213
220
|
clipPathData: ClipPathDatum[]
|
214
221
|
}) {
|
215
|
-
const
|
222
|
+
const clipPath = defsSelection
|
216
223
|
.selectAll<SVGClipPathElement, Layout>('clipPath')
|
217
224
|
.data(clipPathData)
|
218
|
-
|
219
|
-
|
220
|
-
|
225
|
+
.join(
|
226
|
+
enter => {
|
227
|
+
return enter
|
228
|
+
.append('clipPath')
|
229
|
+
},
|
230
|
+
update => update,
|
231
|
+
exit => exit.remove()
|
232
|
+
)
|
221
233
|
.attr('id', d => d.id)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
234
|
+
.each((d, i, g) => {
|
235
|
+
const rect = d3.select(g[i])
|
236
|
+
.selectAll<SVGRectElement, typeof d>('rect')
|
237
|
+
.data([d])
|
238
|
+
.join(
|
239
|
+
enter => {
|
240
|
+
return enter
|
241
|
+
.append('rect')
|
242
|
+
},
|
243
|
+
update => update,
|
244
|
+
exit => exit.remove()
|
245
|
+
)
|
246
|
+
.attr('x', 0)
|
247
|
+
.attr('y', 0)
|
248
|
+
.attr('width', _d => _d.width)
|
249
|
+
.attr('height', _d => _d.height)
|
250
|
+
})
|
236
251
|
}
|
237
252
|
|
238
253
|
function highlight ({ selection, ids, fullChartParams }: {
|
@@ -270,6 +285,8 @@ function highlight ({ selection, ids, fullChartParams }: {
|
|
270
285
|
export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName: string, {
|
271
286
|
selection,
|
272
287
|
computedData$,
|
288
|
+
visibleComputedData$,
|
289
|
+
existedSeriesLabels$,
|
273
290
|
SeriesDataMap$,
|
274
291
|
GroupDataMap$,
|
275
292
|
fullParams$,
|
@@ -278,86 +295,199 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
278
295
|
gridGraphicTransform$,
|
279
296
|
gridAxesSize$,
|
280
297
|
gridHighlight$,
|
298
|
+
gridContainer$,
|
299
|
+
isSeriesPositionSeprate$,
|
281
300
|
event$
|
282
301
|
}) => {
|
283
302
|
const destroy$ = new Subject()
|
284
303
|
|
285
304
|
const clipPathID = getUniID(pluginName, 'clipPath-box')
|
305
|
+
const pathGClassName = getClassName(pluginName, 'pathG')
|
306
|
+
const pathClassName = getClassName(pluginName, 'path')
|
286
307
|
|
287
|
-
const
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
//
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
308
|
+
// const seriesSelection$ = computedData$.pipe(
|
309
|
+
// takeUntil(destroy$),
|
310
|
+
// distinctUntilChanged((a, b) => {
|
311
|
+
// // 只有當series的數量改變時,才重新計算
|
312
|
+
// return a.length === b.length
|
313
|
+
// }),
|
314
|
+
// map((computedData, i) => {
|
315
|
+
// return selection
|
316
|
+
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${seriesClassName}`)
|
317
|
+
// .data(computedData, d => d[0] ? d[0].seriesIndex : i)
|
318
|
+
// .join(
|
319
|
+
// enter => {
|
320
|
+
// return enter
|
321
|
+
// .append('g')
|
322
|
+
// .classed(seriesClassName, true)
|
323
|
+
// .each((d, i, g) => {
|
324
|
+
// const axesSelection = d3.select(g[i])
|
325
|
+
// .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${axesClassName}`)
|
326
|
+
// .data([i])
|
327
|
+
// .join(
|
328
|
+
// enter => {
|
329
|
+
// return enter
|
330
|
+
// .append('g')
|
331
|
+
// .classed(axesClassName, true)
|
332
|
+
// .attr('clip-path', `url(#${clipPathID})`)
|
333
|
+
// .each((d, i, g) => {
|
334
|
+
// const defsSelection = d3.select(g[i])
|
335
|
+
// .selectAll<SVGDefsElement, any>('defs')
|
336
|
+
// .data([i])
|
337
|
+
// .join('defs')
|
338
|
+
|
339
|
+
// const graphicGSelection = d3.select(g[i])
|
340
|
+
// .selectAll<SVGGElement, any>('g')
|
341
|
+
// .data([i])
|
342
|
+
// .join('g')
|
343
|
+
// .classed(graphicClassName, true)
|
344
|
+
// })
|
345
|
+
// },
|
346
|
+
// update => update,
|
347
|
+
// exit => exit.remove()
|
348
|
+
// )
|
349
|
+
// })
|
350
|
+
// },
|
351
|
+
// update => update,
|
352
|
+
// exit => exit.remove()
|
353
|
+
// )
|
354
|
+
// })
|
355
|
+
// )
|
317
356
|
|
318
|
-
//
|
319
|
-
//
|
320
|
-
//
|
357
|
+
// combineLatest({
|
358
|
+
// seriesSelection: seriesSelection$,
|
359
|
+
// gridContainer: gridContainer$
|
360
|
+
// }).pipe(
|
361
|
+
// takeUntil(destroy$),
|
362
|
+
// switchMap(async d => d)
|
363
|
+
// ).subscribe(data => {
|
364
|
+
// data.seriesSelection
|
365
|
+
// .transition()
|
366
|
+
// .attr('transform', (d, i) => {
|
367
|
+
// const translate = data.gridContainer[i].translate
|
368
|
+
// const scale = data.gridContainer[i].scale
|
369
|
+
// return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
|
370
|
+
// })
|
321
371
|
// })
|
322
372
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
373
|
+
|
374
|
+
// const axesSelection$ = combineLatest({
|
375
|
+
// seriesSelection: seriesSelection$,
|
376
|
+
// gridAxesTransform: gridAxesTransform$
|
377
|
+
// }).pipe(
|
378
|
+
// takeUntil(destroy$),
|
379
|
+
// switchMap(async d => d),
|
380
|
+
// map(data => {
|
381
|
+
// return data.seriesSelection
|
382
|
+
// .select<SVGGElement>(`g.${axesClassName}`)
|
383
|
+
// .style('transform', data.gridAxesTransform.value)
|
384
|
+
// })
|
385
|
+
// )
|
386
|
+
// const defsSelection$ = axesSelection$.pipe(
|
387
|
+
// takeUntil(destroy$),
|
388
|
+
// map(axesSelection => {
|
389
|
+
// return axesSelection.select<SVGDefsElement>('defs')
|
390
|
+
// })
|
391
|
+
// )
|
392
|
+
// const graphicGSelection$ = combineLatest({
|
393
|
+
// axesSelection: axesSelection$,
|
394
|
+
// gridGraphicTransform: gridGraphicTransform$
|
395
|
+
// }).pipe(
|
396
|
+
// takeUntil(destroy$),
|
397
|
+
// switchMap(async d => d),
|
398
|
+
// map(data => {
|
399
|
+
// const graphicGSelection = data.axesSelection
|
400
|
+
// .select<SVGGElement>(`g.${graphicClassName}`)
|
401
|
+
// graphicGSelection
|
402
|
+
// .transition()
|
403
|
+
// .duration(50)
|
404
|
+
// .style('transform', data.gridGraphicTransform.value)
|
405
|
+
// return graphicGSelection
|
406
|
+
// })
|
407
|
+
// )
|
408
|
+
|
409
|
+
const {
|
410
|
+
seriesSelection$,
|
411
|
+
axesSelection$,
|
412
|
+
defsSelection$,
|
413
|
+
graphicGSelection$
|
414
|
+
} = gridSelectionsObservable({
|
415
|
+
selection,
|
416
|
+
pluginName,
|
417
|
+
clipPathID,
|
418
|
+
existedSeriesLabels$,
|
419
|
+
gridContainer$,
|
420
|
+
gridAxesTransform$,
|
421
|
+
gridGraphicTransform$
|
422
|
+
})
|
423
|
+
|
424
|
+
const zeroYArr$ = visibleComputedData$.pipe(
|
425
|
+
// map(d => d[0] && d[0][0]
|
426
|
+
// ? d[0][0].axisY - d[0][0].axisYFromZero
|
427
|
+
// : 0),
|
428
|
+
map(data => {
|
429
|
+
return data.map(d => {
|
430
|
+
return d[0] ? d[0].axisY - d[0].axisYFromZero : 0
|
431
|
+
})
|
432
|
+
}),
|
327
433
|
distinctUntilChanged()
|
328
434
|
)
|
329
435
|
|
330
|
-
const barWidth$ =
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
switchMap(async d => d)
|
337
|
-
).subscribe(data => {
|
338
|
-
const barWidth = calcBarWidth({
|
339
|
-
axisWidth: data.axisSize.width,
|
340
|
-
groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
|
341
|
-
barAmountOfGroup: data.computedData.length,
|
342
|
-
barPadding: data.params.barPadding,
|
343
|
-
barGroupPadding: data.params.barGroupPadding
|
344
|
-
})
|
345
|
-
subscriber.next(barWidth)
|
346
|
-
})
|
436
|
+
const barWidth$ = combineLatest({
|
437
|
+
computedData: computedData$,
|
438
|
+
visibleComputedData: visibleComputedData$,
|
439
|
+
params: fullParams$,
|
440
|
+
gridAxesSize: gridAxesSize$,
|
441
|
+
isSeriesPositionSeprate: isSeriesPositionSeprate$
|
347
442
|
}).pipe(
|
348
443
|
takeUntil(destroy$),
|
349
|
-
|
444
|
+
switchMap(async d => d),
|
445
|
+
map(data => {
|
446
|
+
if (data.params.barWidth) {
|
447
|
+
return data.params.barWidth
|
448
|
+
} else if (data.isSeriesPositionSeprate) {
|
449
|
+
return calcBarWidth({
|
450
|
+
axisWidth: data.gridAxesSize.width,
|
451
|
+
groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
|
452
|
+
barAmountOfGroup: 1,
|
453
|
+
barPadding: data.params.barPadding,
|
454
|
+
barGroupPadding: data.params.barGroupPadding
|
455
|
+
})
|
456
|
+
} else {
|
457
|
+
return calcBarWidth({
|
458
|
+
axisWidth: data.gridAxesSize.width,
|
459
|
+
groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
|
460
|
+
barAmountOfGroup: data.visibleComputedData.length,
|
461
|
+
barPadding: data.params.barPadding,
|
462
|
+
barGroupPadding: data.params.barGroupPadding
|
463
|
+
})
|
464
|
+
}
|
465
|
+
})
|
350
466
|
)
|
351
|
-
|
352
|
-
const seriesLabels$ =
|
467
|
+
|
468
|
+
const seriesLabels$ = visibleComputedData$.pipe(
|
353
469
|
takeUntil(destroy$),
|
354
|
-
map(data =>
|
470
|
+
map(data => {
|
471
|
+
const SeriesLabelSet: Set<string> = new Set()
|
472
|
+
data.forEach(d => {
|
473
|
+
d.forEach(_d => {
|
474
|
+
SeriesLabelSet.add(_d.seriesLabel)
|
475
|
+
})
|
476
|
+
})
|
477
|
+
return Array.from(SeriesLabelSet)
|
478
|
+
})
|
355
479
|
)
|
356
480
|
|
357
|
-
const groupLabels$ =
|
481
|
+
const groupLabels$ = visibleComputedData$.pipe(
|
358
482
|
takeUntil(destroy$),
|
359
483
|
map(data => {
|
360
|
-
|
484
|
+
const GroupLabelSet: Set<string> = new Set()
|
485
|
+
data.forEach(d => {
|
486
|
+
d.forEach(_d => {
|
487
|
+
GroupLabelSet.add(_d.groupLabel)
|
488
|
+
})
|
489
|
+
})
|
490
|
+
return Array.from(GroupLabelSet)
|
361
491
|
})
|
362
492
|
)
|
363
493
|
|
@@ -411,67 +541,26 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
411
541
|
distinctUntilChanged()
|
412
542
|
)
|
413
543
|
|
414
|
-
|
415
|
-
takeUntil(destroy$),
|
416
|
-
map(data => {
|
417
|
-
// 取得原始陣列的維度
|
418
|
-
const rows = data.length;
|
419
|
-
const cols = data.reduce((prev, current) => {
|
420
|
-
return Math.max(prev, current.length)
|
421
|
-
}, 0)
|
422
|
-
|
423
|
-
// 初始化轉換後的陣列
|
424
|
-
const transposedArray: typeof data = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
|
425
|
-
|
426
|
-
// 遍歷原始陣列,進行轉換
|
427
|
-
for (let i = 0; i < rows; i++) {
|
428
|
-
for (let j = 0; j < cols; j++) {
|
429
|
-
transposedArray[j][i] = data[i][j]
|
430
|
-
}
|
431
|
-
}
|
432
|
-
|
433
|
-
return transposedArray
|
434
|
-
})
|
435
|
-
)
|
544
|
+
//
|
436
545
|
|
437
|
-
|
546
|
+
combineLatest({
|
547
|
+
defsSelection: defsSelection$,
|
548
|
+
gridAxesSize: gridAxesSize$,
|
549
|
+
}).pipe(
|
438
550
|
takeUntil(destroy$),
|
439
|
-
|
440
|
-
const linearGradientIds = data.length
|
441
|
-
? data[0].map(d => getUniID(pluginName, `lineargradient-${d.seriesLabel}`))
|
442
|
-
: []
|
443
|
-
return data.map(d => {
|
444
|
-
return d.map((_d, _i) => {
|
445
|
-
return <BarDatumGrid>{
|
446
|
-
linearGradientId: linearGradientIds[_i],
|
447
|
-
..._d
|
448
|
-
}
|
449
|
-
})
|
450
|
-
})
|
451
|
-
})
|
452
|
-
)
|
453
|
-
|
454
|
-
gridAxesSize$.pipe(
|
455
|
-
takeUntil(destroy$)
|
551
|
+
switchMap(async d => d)
|
456
552
|
).subscribe(data => {
|
457
553
|
const clipPathData = [{
|
458
554
|
id: clipPathID,
|
459
|
-
width: data.width,
|
460
|
-
height: data.height
|
555
|
+
width: data.gridAxesSize.width,
|
556
|
+
height: data.gridAxesSize.height
|
461
557
|
}]
|
462
558
|
renderClipPath({
|
463
|
-
defsSelection,
|
559
|
+
defsSelection: data.defsSelection,
|
464
560
|
clipPathData
|
465
561
|
})
|
466
562
|
})
|
467
563
|
|
468
|
-
// const SeriesDataMap$ = computedData$.pipe(
|
469
|
-
// map(d => makeGridSeriesDataMap(d))
|
470
|
-
// )
|
471
|
-
|
472
|
-
// const GroupDataMap$ = computedData$.pipe(
|
473
|
-
// map(d => makeGridGroupDataMap(d))
|
474
|
-
// )
|
475
564
|
|
476
565
|
const highlightTarget$ = fullChartParams$.pipe(
|
477
566
|
takeUntil(destroy$),
|
@@ -479,10 +568,39 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
479
568
|
distinctUntilChanged()
|
480
569
|
)
|
481
570
|
|
571
|
+
const barSelection$ = new Subject<d3.Selection<SVGPathElement, ComputedDatumGrid, SVGGElement, unknown>>()
|
572
|
+
|
573
|
+
const linearGradientIds$ = seriesLabels$.pipe(
|
574
|
+
takeUntil(destroy$),
|
575
|
+
map(d => d.map((d, i) => {
|
576
|
+
return getUniID(pluginName, `lineargradient-${d}`)
|
577
|
+
}))
|
578
|
+
)
|
579
|
+
|
580
|
+
const barData$ = combineLatest({
|
581
|
+
linearGradientIds: linearGradientIds$,
|
582
|
+
computedData: computedData$
|
583
|
+
}).pipe(
|
584
|
+
takeUntil(destroy$),
|
585
|
+
switchMap(async d => d),
|
586
|
+
map(data => {
|
587
|
+
return data.computedData.map((series, seriesIndex) => {
|
588
|
+
return series.map((_d, _i) => {
|
589
|
+
return <BarDatumGrid>{
|
590
|
+
linearGradientId: data.linearGradientIds[seriesIndex],
|
591
|
+
..._d
|
592
|
+
}
|
593
|
+
})
|
594
|
+
})
|
595
|
+
})
|
596
|
+
)
|
597
|
+
|
482
598
|
combineLatest({
|
483
|
-
|
599
|
+
graphicGSelection: graphicGSelection$,
|
600
|
+
defsSelection: defsSelection$,
|
484
601
|
computedData: computedData$,
|
485
|
-
|
602
|
+
barData: barData$,
|
603
|
+
zeroYArr: zeroYArr$,
|
486
604
|
groupLabels: groupLabels$,
|
487
605
|
barScale: barScale$,
|
488
606
|
params: fullParams$,
|
@@ -492,34 +610,38 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
492
610
|
delayGroup: delayGroup$,
|
493
611
|
transitionItem: transitionItem$,
|
494
612
|
SeriesDataMap: SeriesDataMap$,
|
495
|
-
GroupDataMap: GroupDataMap
|
613
|
+
GroupDataMap: GroupDataMap$,
|
614
|
+
isSeriesPositionSeprate: isSeriesPositionSeprate$
|
496
615
|
}).pipe(
|
497
616
|
takeUntil(destroy$),
|
498
|
-
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
499
617
|
switchMap(async (d) => d),
|
500
618
|
).subscribe(data => {
|
501
|
-
|
502
|
-
|
619
|
+
|
620
|
+
const barSelection = renderTriangleBars({
|
621
|
+
graphicGSelection: data.graphicGSelection,
|
622
|
+
pathGClassName,
|
623
|
+
pathClassName,
|
503
624
|
barData: data.barData,
|
504
|
-
|
625
|
+
zeroYArr: data.zeroYArr,
|
505
626
|
groupLabels: data.groupLabels,
|
506
627
|
barScale: data.barScale,
|
507
628
|
params: data.params,
|
508
629
|
chartParams: data.chartParams,
|
509
630
|
barWidth: data.barWidth,
|
510
631
|
delayGroup: data.delayGroup,
|
511
|
-
transitionItem: data.transitionItem
|
632
|
+
transitionItem: data.transitionItem,
|
633
|
+
isSeriesPositionSeprate: data.isSeriesPositionSeprate
|
512
634
|
})
|
513
635
|
renderLinearGradient({
|
514
|
-
defsSelection,
|
636
|
+
defsSelection: data.defsSelection,
|
515
637
|
barData: data.barData,
|
516
638
|
params: data.params
|
517
639
|
})
|
518
640
|
|
519
|
-
|
641
|
+
barSelection!
|
520
642
|
.on('mouseover', (event, datum) => {
|
521
643
|
event.stopPropagation()
|
522
|
-
|
644
|
+
|
523
645
|
event$.next({
|
524
646
|
type: 'grid',
|
525
647
|
eventName: 'mouseover',
|
@@ -594,18 +716,12 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
594
716
|
})
|
595
717
|
})
|
596
718
|
|
597
|
-
|
719
|
+
barSelection$.next(barSelection!)
|
598
720
|
})
|
599
721
|
|
600
|
-
// const datumList$ = computedData$.pipe(
|
601
|
-
// takeUntil(destroy$),
|
602
|
-
// map(d => d.flat())
|
603
|
-
// )
|
604
|
-
// const highlight$ = highlightObservable({ datumList$, fullChartParams$, event$: event$ })
|
605
|
-
const highlightSubscription = gridHighlight$.subscribe()
|
606
722
|
|
607
723
|
combineLatest({
|
608
|
-
|
724
|
+
barSelection: barSelection$,
|
609
725
|
highlight: gridHighlight$,
|
610
726
|
fullChartParams: fullChartParams$
|
611
727
|
}).pipe(
|
@@ -613,7 +729,7 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
613
729
|
switchMap(async d => d)
|
614
730
|
).subscribe(data => {
|
615
731
|
highlight({
|
616
|
-
selection: data.
|
732
|
+
selection: data.barSelection,
|
617
733
|
ids: data.highlight,
|
618
734
|
fullChartParams: data.fullChartParams
|
619
735
|
})
|
@@ -621,6 +737,5 @@ export const createBaseBarsTriangle: BasePluginFn<BaseBarsContext> = (pluginName
|
|
621
737
|
|
622
738
|
return () => {
|
623
739
|
destroy$.next(undefined)
|
624
|
-
highlightSubscription.unsubscribe()
|
625
740
|
}
|
626
741
|
}
|