@orbcharts/core 3.0.0-beta.3 → 3.0.0-beta.5
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-core.es.js +2665 -2376
- package/dist/orbcharts-core.umd.js +4 -4
- package/dist/src/utils/d3Scale.d.ts +28 -0
- package/dist/src/utils/gridObservables.d.ts +29 -19
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/multiGridObservables.d.ts +2 -2
- package/dist/src/utils/multiValueObservables.d.ts +73 -0
- package/dist/src/utils/orbchartsUtils.d.ts +19 -5
- package/dist/src/utils/seriesObservables.d.ts +4 -4
- package/dist/src/utils/treeObservables.d.ts +2 -5
- package/package.json +2 -2
- package/src/defaults.ts +4 -1
- package/src/grid/contextObserverCallback.ts +57 -36
- package/src/multiValue/computedDataFn.ts +81 -147
- package/src/multiValue/contextObserverCallback.ts +150 -2
- package/src/relationship/computedDataFn.ts +1 -1
- package/src/tree/computedDataFn.ts +9 -10
- package/src/tree/contextObserverCallback.ts +6 -9
- package/src/utils/d3Scale.ts +198 -0
- package/src/utils/gridObservables.ts +303 -234
- package/src/utils/index.ts +1 -1
- package/src/utils/multiGridObservables.ts +68 -42
- package/src/utils/multiValueObservables.ts +662 -0
- package/src/utils/orbchartsUtils.ts +70 -45
- package/src/utils/seriesObservables.ts +7 -7
- package/src/utils/treeObservables.ts +44 -33
- package/src/utils/validator.ts +3 -2
- package/dist/src/utils/d3Utils.d.ts +0 -19
- package/src/utils/d3Utils.ts +0 -108
@@ -26,12 +26,12 @@ import type {
|
|
26
26
|
DataFormatterGroupAxis,
|
27
27
|
ComputedLayoutDatumGrid,
|
28
28
|
ComputedLayoutDataGrid,
|
29
|
-
|
29
|
+
ContainerPositionScaled,
|
30
30
|
HighlightTarget,
|
31
31
|
Layout,
|
32
32
|
TransformData } from '../../lib/core-types'
|
33
33
|
import { getMinAndMaxGrid } from './orbchartsUtils'
|
34
|
-
import {
|
34
|
+
import { createValueToAxisScale, createLabelToAxisScale, createAxisToLabelIndexScale } from './d3Scale'
|
35
35
|
import { calcGridContainerLayout } from './orbchartsUtils'
|
36
36
|
import { getMinAndMaxValue } from './orbchartsUtils'
|
37
37
|
|
@@ -47,7 +47,7 @@ export const gridComputedLayoutDataObservable = ({ computedData$, fullDataFormat
|
|
47
47
|
? layout.width
|
48
48
|
: layout.height
|
49
49
|
const groupEndIndex = computedData[0] ? computedData[0].length - 1 : 0
|
50
|
-
const groupScale: d3.ScaleLinear<number, number> =
|
50
|
+
const groupScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
|
51
51
|
maxValue: groupEndIndex,
|
52
52
|
minValue: 0,
|
53
53
|
axisWidth: groupAxisWidth,
|
@@ -65,9 +65,13 @@ export const gridComputedLayoutDataObservable = ({ computedData$, fullDataFormat
|
|
65
65
|
: layout.width
|
66
66
|
|
67
67
|
const listData = computedData.flat()
|
68
|
-
|
68
|
+
let [minValue, maxValue] = getMinAndMaxValue(listData)
|
69
|
+
if (minValue === maxValue && maxValue === 0) {
|
70
|
+
// 避免最大及最小值相同造成無法計算scale
|
71
|
+
maxValue = 1
|
72
|
+
}
|
69
73
|
|
70
|
-
const valueScale: d3.ScaleLinear<number, number> =
|
74
|
+
const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
|
71
75
|
maxValue,
|
72
76
|
minValue,
|
73
77
|
axisWidth: valueAxisWidth,
|
@@ -106,6 +110,261 @@ export const gridComputedLayoutDataObservable = ({ computedData$, fullDataFormat
|
|
106
110
|
)
|
107
111
|
}
|
108
112
|
|
113
|
+
export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
|
114
|
+
fullDataFormatter$: Observable<DataFormatterGrid>
|
115
|
+
layout$: Observable<Layout>
|
116
|
+
}): Observable<{
|
117
|
+
width: number;
|
118
|
+
height: number;
|
119
|
+
}> => {
|
120
|
+
const destroy$ = new Subject()
|
121
|
+
|
122
|
+
function calcAxesSize ({ xAxisPosition, yAxisPosition, width, height }: {
|
123
|
+
xAxisPosition: AxisPosition
|
124
|
+
yAxisPosition: AxisPosition
|
125
|
+
width: number
|
126
|
+
height: number
|
127
|
+
}) {
|
128
|
+
if ((xAxisPosition === 'bottom' || xAxisPosition === 'top') && (yAxisPosition === 'left' || yAxisPosition === 'right')) {
|
129
|
+
return { width, height }
|
130
|
+
} else if ((xAxisPosition === 'left' || xAxisPosition === 'right') && (yAxisPosition === 'bottom' || yAxisPosition === 'top')) {
|
131
|
+
return {
|
132
|
+
width: height,
|
133
|
+
height: width
|
134
|
+
}
|
135
|
+
} else {
|
136
|
+
// default
|
137
|
+
return { width, height }
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
return new Observable(subscriber => {
|
142
|
+
combineLatest({
|
143
|
+
fullDataFormatter: fullDataFormatter$,
|
144
|
+
layout: layout$
|
145
|
+
}).pipe(
|
146
|
+
takeUntil(destroy$),
|
147
|
+
switchMap(async (d) => d),
|
148
|
+
).subscribe(data => {
|
149
|
+
|
150
|
+
const axisSize = calcAxesSize({
|
151
|
+
xAxisPosition: data.fullDataFormatter.grid.groupAxis.position,
|
152
|
+
yAxisPosition: data.fullDataFormatter.grid.valueAxis.position,
|
153
|
+
width: data.layout.width,
|
154
|
+
height: data.layout.height,
|
155
|
+
})
|
156
|
+
|
157
|
+
subscriber.next(axisSize)
|
158
|
+
|
159
|
+
return function unsubscribe () {
|
160
|
+
destroy$.next(undefined)
|
161
|
+
}
|
162
|
+
})
|
163
|
+
})
|
164
|
+
}
|
165
|
+
|
166
|
+
// export const gridHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
|
167
|
+
// computedData$: Observable<ComputedDataTypeMap<'grid'>>
|
168
|
+
// fullChartParams$: Observable<ChartParams>
|
169
|
+
// event$: Subject<any>
|
170
|
+
// }): Observable<string[]> => {
|
171
|
+
// const datumList$ = computedData$.pipe(
|
172
|
+
// map(d => d.flat())
|
173
|
+
// )
|
174
|
+
// return highlightObservable ({ datumList$, fullChartParams$, event$ })
|
175
|
+
// }
|
176
|
+
|
177
|
+
export const gridSeriesLabelsObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
|
178
|
+
return computedData$.pipe(
|
179
|
+
map(data => {
|
180
|
+
return data
|
181
|
+
.filter(series => series.length)
|
182
|
+
.map(series => {
|
183
|
+
return series[0].seriesLabel
|
184
|
+
})
|
185
|
+
}),
|
186
|
+
distinctUntilChanged((a, b) => {
|
187
|
+
return JSON.stringify(a).length === JSON.stringify(b).length
|
188
|
+
}),
|
189
|
+
)
|
190
|
+
}
|
191
|
+
|
192
|
+
export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
|
193
|
+
return computedData$.pipe(
|
194
|
+
map(data => {
|
195
|
+
const visibleComputedData = data
|
196
|
+
.map(d => {
|
197
|
+
return d.filter(_d => {
|
198
|
+
return _d.visible == true
|
199
|
+
})
|
200
|
+
})
|
201
|
+
.filter(d => d.length)
|
202
|
+
return visibleComputedData
|
203
|
+
})
|
204
|
+
)
|
205
|
+
}
|
206
|
+
|
207
|
+
export const gridVisibleComputedLayoutDataObservable = ({ computedLayoutData$ }: { computedLayoutData$: Observable<ComputedLayoutDataGrid> }) => {
|
208
|
+
return computedLayoutData$.pipe(
|
209
|
+
map(data => {
|
210
|
+
const visibleComputedData = data
|
211
|
+
.map(d => {
|
212
|
+
return d.filter(_d => {
|
213
|
+
return _d.visible == true
|
214
|
+
})
|
215
|
+
})
|
216
|
+
.filter(d => d.length)
|
217
|
+
return visibleComputedData
|
218
|
+
})
|
219
|
+
)
|
220
|
+
}
|
221
|
+
|
222
|
+
// 所有container位置(對應series)
|
223
|
+
export const gridContainerPositionObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
|
224
|
+
computedData$: Observable<ComputedDataTypeMap<'grid'>>
|
225
|
+
fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
226
|
+
layout$: Observable<Layout>
|
227
|
+
}): Observable<ContainerPositionScaled[]> => {
|
228
|
+
|
229
|
+
const gridContainerPosition$ = combineLatest({
|
230
|
+
computedData: computedData$,
|
231
|
+
fullDataFormatter: fullDataFormatter$,
|
232
|
+
layout: layout$,
|
233
|
+
}).pipe(
|
234
|
+
switchMap(async (d) => d),
|
235
|
+
map(data => {
|
236
|
+
|
237
|
+
if (data.fullDataFormatter.grid.separateSeries) {
|
238
|
+
// -- 依slotIndexes計算 --
|
239
|
+
return calcGridContainerLayout(data.layout, data.fullDataFormatter.container, data.computedData.length)
|
240
|
+
// return data.computedData.map((seriesData, seriesIndex) => {
|
241
|
+
// const columnIndex = seriesIndex % data.fullDataFormatter.container.columnAmount
|
242
|
+
// const rowIndex = Math.floor(seriesIndex / data.fullDataFormatter.container.columnAmount)
|
243
|
+
// const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
|
244
|
+
// return {
|
245
|
+
// slotIndex: seriesIndex,
|
246
|
+
// rowIndex,
|
247
|
+
// columnIndex,
|
248
|
+
// translate,
|
249
|
+
// scale,
|
250
|
+
// }
|
251
|
+
// })
|
252
|
+
} else {
|
253
|
+
// -- 無拆分 --
|
254
|
+
const gridContainerPositionArr = calcGridContainerLayout(data.layout, data.fullDataFormatter.container, 1)
|
255
|
+
return data.computedData.map((d, i) => gridContainerPositionArr[0]) // 每個series相同位置
|
256
|
+
// const columnIndex = 0
|
257
|
+
// const rowIndex = 0
|
258
|
+
// return data.computedData.map((seriesData, seriesIndex) => {
|
259
|
+
// const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
|
260
|
+
// return {
|
261
|
+
// slotIndex: 0,
|
262
|
+
// rowIndex,
|
263
|
+
// columnIndex,
|
264
|
+
// translate,
|
265
|
+
// scale,
|
266
|
+
// }
|
267
|
+
// })
|
268
|
+
}
|
269
|
+
})
|
270
|
+
)
|
271
|
+
|
272
|
+
return gridContainerPosition$
|
273
|
+
}
|
274
|
+
|
275
|
+
// 將原本的value全部替換成加總後的value
|
276
|
+
export const computedStackedDataObservables = ({ isSeriesSeprate$, computedData$ }: {
|
277
|
+
isSeriesSeprate$: Observable<boolean>
|
278
|
+
computedData$: Observable<ComputedDataGrid>
|
279
|
+
}): Observable<ComputedDataGrid> => {
|
280
|
+
const stackedData$: Observable<ComputedDataGrid> = computedData$.pipe(
|
281
|
+
map(data => {
|
282
|
+
// 將同一group的value加總起來
|
283
|
+
const stackedValue = new Array(data[0] ? data[0].length : 0)
|
284
|
+
.fill(null)
|
285
|
+
.map((_, i) => {
|
286
|
+
return data.reduce((prev, current) => {
|
287
|
+
if (current && current[i]) {
|
288
|
+
const currentValue = current[i].value == null || current[i].visible == false
|
289
|
+
? 0
|
290
|
+
: current[i].value!
|
291
|
+
return prev + currentValue
|
292
|
+
}
|
293
|
+
return prev
|
294
|
+
}, 0)
|
295
|
+
})
|
296
|
+
// 將原本的value全部替換成加總後的value
|
297
|
+
const computedData = data.map((series, seriesIndex) => {
|
298
|
+
return series.map((d, i) => {
|
299
|
+
return {
|
300
|
+
...d,
|
301
|
+
value: stackedValue[i],
|
302
|
+
}
|
303
|
+
})
|
304
|
+
})
|
305
|
+
return computedData
|
306
|
+
}),
|
307
|
+
)
|
308
|
+
|
309
|
+
return isSeriesSeprate$.pipe(
|
310
|
+
switchMap(isSeriesSeprate => {
|
311
|
+
return iif(() => isSeriesSeprate, computedData$, stackedData$)
|
312
|
+
})
|
313
|
+
)
|
314
|
+
}
|
315
|
+
|
316
|
+
export const groupScaleDomainValueObservable = ({ computedData$, fullDataFormatter$ }: {
|
317
|
+
computedData$: Observable<ComputedDataGrid>
|
318
|
+
fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
319
|
+
}): Observable<[number, number]> => {
|
320
|
+
return combineLatest({
|
321
|
+
computedData: computedData$,
|
322
|
+
fullDataFormatter: fullDataFormatter$
|
323
|
+
}).pipe(
|
324
|
+
switchMap(async (d) => d),
|
325
|
+
map(data => {
|
326
|
+
const groupAxis = data.fullDataFormatter.grid.groupAxis
|
327
|
+
const groupMin = 0
|
328
|
+
const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
329
|
+
// const groupScaleDomainMin = groupAxis.scaleDomain[0] === 'min'
|
330
|
+
// ? groupMin - groupAxis.scalePadding
|
331
|
+
// : groupAxis.scaleDomain[0] as number - groupAxis.scalePadding
|
332
|
+
const groupScaleDomainMin = groupAxis.scaleDomain[0] - groupAxis.scalePadding
|
333
|
+
const groupScaleDomainMax = groupAxis.scaleDomain[1] === 'max'
|
334
|
+
? groupMax + groupAxis.scalePadding
|
335
|
+
: groupAxis.scaleDomain[1] as number + groupAxis.scalePadding
|
336
|
+
|
337
|
+
return [groupScaleDomainMin, groupScaleDomainMax]
|
338
|
+
})
|
339
|
+
)
|
340
|
+
}
|
341
|
+
|
342
|
+
export const filteredMinMaxValueObservable = ({ computedData$, groupScaleDomainValue$ }: {
|
343
|
+
computedData$: Observable<ComputedDataGrid>
|
344
|
+
// fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
345
|
+
groupScaleDomainValue$: Observable<[number, number]>
|
346
|
+
}) => {
|
347
|
+
return combineLatest({
|
348
|
+
computedData: computedData$,
|
349
|
+
// fullDataFormatter: fullDataFormatter$,
|
350
|
+
groupScaleDomainValue: groupScaleDomainValue$
|
351
|
+
}).pipe(
|
352
|
+
map(data => {
|
353
|
+
const filteredData = data.computedData.map((d, i) => {
|
354
|
+
return d.filter((_d, _i) => {
|
355
|
+
return _i >= data.groupScaleDomainValue[0] && _i <= data.groupScaleDomainValue[1] && _d.visible == true
|
356
|
+
})
|
357
|
+
})
|
358
|
+
|
359
|
+
const filteredMinAndMax = getMinAndMaxGrid(filteredData)
|
360
|
+
// if (filteredMinAndMax[0] === filteredMinAndMax[1]) {
|
361
|
+
// filteredMinAndMax[0] = filteredMinAndMax[1] - 1 // 避免最大及最小值相同造成無法計算scale
|
362
|
+
// }
|
363
|
+
return filteredMinAndMax
|
364
|
+
}),
|
365
|
+
)
|
366
|
+
}
|
367
|
+
|
109
368
|
export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
|
110
369
|
fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
111
370
|
layout$: Observable<Layout>
|
@@ -252,17 +511,21 @@ export const gridAxesReverseTransformObservable = ({ gridAxesTransform$ }: {
|
|
252
511
|
)
|
253
512
|
}
|
254
513
|
|
255
|
-
export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
|
514
|
+
export const gridGraphicTransformObservable = ({ computedData$, groupScaleDomainValue$, filteredMinMaxValue$, fullDataFormatter$, layout$ }: {
|
256
515
|
computedData$: Observable<ComputedDataTypeMap<'grid'>>
|
516
|
+
groupScaleDomainValue$: Observable<[number, number]>
|
517
|
+
filteredMinMaxValue$: Observable<[number, number]>
|
257
518
|
fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
258
519
|
layout$: Observable<Layout>
|
259
520
|
}): Observable<TransformData> => {
|
260
521
|
const destroy$ = new Subject()
|
261
522
|
|
262
|
-
function calcGridDataAreaTransform ({ data, groupAxis, valueAxis, width, height }: {
|
523
|
+
function calcGridDataAreaTransform ({ data, groupAxis, valueAxis, groupScaleDomainValue, filteredMinMaxValue, width, height }: {
|
263
524
|
data: ComputedDataTypeMap<'grid'>
|
264
525
|
groupAxis: DataFormatterGroupAxis
|
265
526
|
valueAxis: DataFormatterValueAxis
|
527
|
+
groupScaleDomainValue: [number, number],
|
528
|
+
filteredMinMaxValue: [number, number],
|
266
529
|
width: number
|
267
530
|
height: number
|
268
531
|
}): TransformData {
|
@@ -277,20 +540,17 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
|
|
277
540
|
: height
|
278
541
|
const groupMin = 0
|
279
542
|
const groupMax = data[0] ? data[0].length - 1 : 0
|
280
|
-
// const groupScaleDomainMin = groupAxis.scaleDomain[0]
|
281
|
-
//
|
282
|
-
//
|
283
|
-
|
284
|
-
const groupScaleDomainMax = groupAxis.scaleDomain[1] === 'max'
|
285
|
-
? groupMax + groupAxis.scalePadding
|
286
|
-
: groupAxis.scaleDomain[1] as number + groupAxis.scalePadding
|
543
|
+
// const groupScaleDomainMin = groupAxis.scaleDomain[0] - groupAxis.scalePadding
|
544
|
+
// const groupScaleDomainMax = groupAxis.scaleDomain[1] === 'max'
|
545
|
+
// ? groupMax + groupAxis.scalePadding
|
546
|
+
// : groupAxis.scaleDomain[1] as number + groupAxis.scalePadding
|
287
547
|
|
288
|
-
const groupScale: d3.ScaleLinear<number, number> =
|
548
|
+
const groupScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
|
289
549
|
maxValue: groupMax,
|
290
550
|
minValue: groupMin,
|
291
551
|
axisWidth: groupAxisWidth,
|
292
552
|
// scaleDomain: groupAxis.scaleDomain,
|
293
|
-
scaleDomain:
|
553
|
+
scaleDomain: groupScaleDomainValue,
|
294
554
|
scaleRange: [0, 1]
|
295
555
|
})
|
296
556
|
|
@@ -308,33 +568,41 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
|
|
308
568
|
}
|
309
569
|
|
310
570
|
// -- valueScale --
|
311
|
-
const filteredData = data.map((d, i) => {
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
})
|
571
|
+
// const filteredData = data.map((d, i) => {
|
572
|
+
// return d.filter((_d, _i) => {
|
573
|
+
// return _i >= groupScaleDomainMin && _i <= groupScaleDomainMax && _d.visible == true
|
574
|
+
// })
|
575
|
+
// })
|
316
576
|
|
317
|
-
const filteredMinAndMax = getMinAndMaxGrid(filteredData)
|
318
|
-
if (
|
319
|
-
|
577
|
+
// const filteredMinAndMax = getMinAndMaxGrid(filteredData)
|
578
|
+
if (filteredMinMaxValue[0] === filteredMinMaxValue[1] && filteredMinMaxValue[1] === 0) {
|
579
|
+
// filteredMinMaxValue[0] = filteredMinMaxValue[1] - 1 // 避免最大及最小值相同造成無法計算scale
|
580
|
+
filteredMinMaxValue[1] = 1 // 避免最大及最小值同等於 0 造成無法計算scale
|
320
581
|
}
|
321
582
|
|
322
583
|
const valueAxisWidth = (valueAxis.position === 'left' || valueAxis.position === 'right')
|
323
584
|
? height
|
324
585
|
: width
|
325
586
|
|
326
|
-
const valueScale: d3.ScaleLinear<number, number> =
|
327
|
-
maxValue:
|
328
|
-
minValue:
|
587
|
+
const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
|
588
|
+
maxValue: filteredMinMaxValue[1],
|
589
|
+
minValue: filteredMinMaxValue[0],
|
329
590
|
axisWidth: valueAxisWidth,
|
330
591
|
scaleDomain: valueAxis.scaleDomain,
|
331
592
|
scaleRange: valueAxis.scaleRange
|
332
593
|
})
|
333
|
-
|
594
|
+
// console.log({
|
595
|
+
// maxValue: filteredMinMaxValue[1],
|
596
|
+
// minValue: filteredMinMaxValue[0],
|
597
|
+
// axisWidth: valueAxisWidth,
|
598
|
+
// scaleDomain: valueAxis.scaleDomain,
|
599
|
+
// scaleRange: valueAxis.scaleRange
|
600
|
+
// })
|
334
601
|
// -- translateY, scaleY --
|
335
602
|
const minAndMax = getMinAndMaxGrid(data)
|
336
|
-
if (minAndMax[0] === minAndMax[1]) {
|
337
|
-
minAndMax[0] = minAndMax[1] - 1 // 避免最大及最小值相同造成無法計算scale
|
603
|
+
if (minAndMax[0] === minAndMax[1] && minAndMax[1] === 0) {
|
604
|
+
// minAndMax[0] = minAndMax[1] - 1 // 避免最大及最小值相同造成無法計算scale
|
605
|
+
minAndMax[1] = 1 // 避免最大及最小值同等於 0 造成無法計算scale
|
338
606
|
}
|
339
607
|
// const rangeMinY = valueScale(minAndMax[0])
|
340
608
|
const rangeMinY = valueScale(minAndMax[0] > 0 ? 0 : minAndMax[0]) // * 因為原本的座標就是以 0 到最大值或最小值範範圍計算的,所以這邊也是用同樣的方式計算
|
@@ -356,6 +624,8 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
|
|
356
624
|
return new Observable(subscriber => {
|
357
625
|
combineLatest({
|
358
626
|
computedData: computedData$,
|
627
|
+
groupScaleDomainValue: groupScaleDomainValue$,
|
628
|
+
filteredMinMaxValue: filteredMinMaxValue$,
|
359
629
|
fullDataFormatter: fullDataFormatter$,
|
360
630
|
layout: layout$
|
361
631
|
}).pipe(
|
@@ -366,6 +636,8 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
|
|
366
636
|
data: data.computedData,
|
367
637
|
groupAxis: data.fullDataFormatter.grid.groupAxis,
|
368
638
|
valueAxis: data.fullDataFormatter.grid.valueAxis,
|
639
|
+
groupScaleDomainValue: data.groupScaleDomainValue,
|
640
|
+
filteredMinMaxValue: data.filteredMinMaxValue,
|
369
641
|
width: data.layout.width,
|
370
642
|
height: data.layout.height
|
371
643
|
})
|
@@ -380,7 +652,7 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
|
|
380
652
|
}
|
381
653
|
|
382
654
|
export const gridGraphicReverseScaleObservable = ({ gridContainerPosition$, gridAxesTransform$, gridGraphicTransform$ }: {
|
383
|
-
gridContainerPosition$: Observable<
|
655
|
+
gridContainerPosition$: Observable<ContainerPositionScaled[]>
|
384
656
|
gridAxesTransform$: Observable<TransformData>
|
385
657
|
gridGraphicTransform$: Observable<TransformData>
|
386
658
|
}): Observable<[number, number][]> => {
|
@@ -409,207 +681,4 @@ export const gridGraphicReverseScaleObservable = ({ gridContainerPosition$, grid
|
|
409
681
|
}
|
410
682
|
}),
|
411
683
|
)
|
412
|
-
}
|
413
|
-
|
414
|
-
export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
|
415
|
-
fullDataFormatter$: Observable<DataFormatterGrid>
|
416
|
-
layout$: Observable<Layout>
|
417
|
-
}): Observable<{
|
418
|
-
width: number;
|
419
|
-
height: number;
|
420
|
-
}> => {
|
421
|
-
const destroy$ = new Subject()
|
422
|
-
|
423
|
-
function calcAxesSize ({ xAxisPosition, yAxisPosition, width, height }: {
|
424
|
-
xAxisPosition: AxisPosition
|
425
|
-
yAxisPosition: AxisPosition
|
426
|
-
width: number
|
427
|
-
height: number
|
428
|
-
}) {
|
429
|
-
if ((xAxisPosition === 'bottom' || xAxisPosition === 'top') && (yAxisPosition === 'left' || yAxisPosition === 'right')) {
|
430
|
-
return { width, height }
|
431
|
-
} else if ((xAxisPosition === 'left' || xAxisPosition === 'right') && (yAxisPosition === 'bottom' || yAxisPosition === 'top')) {
|
432
|
-
return {
|
433
|
-
width: height,
|
434
|
-
height: width
|
435
|
-
}
|
436
|
-
} else {
|
437
|
-
// default
|
438
|
-
return { width, height }
|
439
|
-
}
|
440
|
-
}
|
441
|
-
|
442
|
-
return new Observable(subscriber => {
|
443
|
-
combineLatest({
|
444
|
-
fullDataFormatter: fullDataFormatter$,
|
445
|
-
layout: layout$
|
446
|
-
}).pipe(
|
447
|
-
takeUntil(destroy$),
|
448
|
-
switchMap(async (d) => d),
|
449
|
-
).subscribe(data => {
|
450
|
-
|
451
|
-
const axisSize = calcAxesSize({
|
452
|
-
xAxisPosition: data.fullDataFormatter.grid.groupAxis.position,
|
453
|
-
yAxisPosition: data.fullDataFormatter.grid.valueAxis.position,
|
454
|
-
width: data.layout.width,
|
455
|
-
height: data.layout.height,
|
456
|
-
})
|
457
|
-
|
458
|
-
subscriber.next(axisSize)
|
459
|
-
|
460
|
-
return function unsubscribe () {
|
461
|
-
destroy$.next(undefined)
|
462
|
-
}
|
463
|
-
})
|
464
|
-
})
|
465
|
-
}
|
466
|
-
|
467
|
-
// export const gridHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
|
468
|
-
// computedData$: Observable<ComputedDataTypeMap<'grid'>>
|
469
|
-
// fullChartParams$: Observable<ChartParams>
|
470
|
-
// event$: Subject<any>
|
471
|
-
// }): Observable<string[]> => {
|
472
|
-
// const datumList$ = computedData$.pipe(
|
473
|
-
// map(d => d.flat())
|
474
|
-
// )
|
475
|
-
// return highlightObservable ({ datumList$, fullChartParams$, event$ })
|
476
|
-
// }
|
477
|
-
|
478
|
-
export const gridSeriesLabelsObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
|
479
|
-
return computedData$.pipe(
|
480
|
-
map(data => {
|
481
|
-
return data
|
482
|
-
.filter(series => series.length)
|
483
|
-
.map(series => {
|
484
|
-
return series[0].seriesLabel
|
485
|
-
})
|
486
|
-
}),
|
487
|
-
distinctUntilChanged((a, b) => {
|
488
|
-
return JSON.stringify(a).length === JSON.stringify(b).length
|
489
|
-
}),
|
490
|
-
)
|
491
|
-
}
|
492
|
-
|
493
|
-
export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
|
494
|
-
return computedData$.pipe(
|
495
|
-
map(data => {
|
496
|
-
const visibleComputedData = data
|
497
|
-
.map(d => {
|
498
|
-
return d.filter(_d => {
|
499
|
-
return _d.visible == true
|
500
|
-
})
|
501
|
-
})
|
502
|
-
.filter(d => d.length)
|
503
|
-
return visibleComputedData
|
504
|
-
})
|
505
|
-
)
|
506
|
-
}
|
507
|
-
|
508
|
-
export const gridVisibleComputedLayoutDataObservable = ({ computedLayoutData$ }: { computedLayoutData$: Observable<ComputedLayoutDataGrid> }) => {
|
509
|
-
return computedLayoutData$.pipe(
|
510
|
-
map(data => {
|
511
|
-
const visibleComputedData = data
|
512
|
-
.map(d => {
|
513
|
-
return d.filter(_d => {
|
514
|
-
return _d.visible == true
|
515
|
-
})
|
516
|
-
})
|
517
|
-
.filter(d => d.length)
|
518
|
-
return visibleComputedData
|
519
|
-
})
|
520
|
-
)
|
521
|
-
}
|
522
|
-
|
523
|
-
// 所有container位置(對應series)
|
524
|
-
export const gridContainerPositionObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
|
525
|
-
computedData$: Observable<ComputedDataTypeMap<'grid'>>
|
526
|
-
fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
|
527
|
-
layout$: Observable<Layout>
|
528
|
-
}): Observable<GridContainerPosition[]> => {
|
529
|
-
|
530
|
-
const gridContainerPosition$ = combineLatest({
|
531
|
-
computedData: computedData$,
|
532
|
-
fullDataFormatter: fullDataFormatter$,
|
533
|
-
layout: layout$,
|
534
|
-
}).pipe(
|
535
|
-
switchMap(async (d) => d),
|
536
|
-
map(data => {
|
537
|
-
|
538
|
-
if (data.fullDataFormatter.grid.separateSeries) {
|
539
|
-
// -- 依slotIndexes計算 --
|
540
|
-
return calcGridContainerLayout(data.layout, data.fullDataFormatter.container, data.computedData.length)
|
541
|
-
// return data.computedData.map((seriesData, seriesIndex) => {
|
542
|
-
// const columnIndex = seriesIndex % data.fullDataFormatter.container.columnAmount
|
543
|
-
// const rowIndex = Math.floor(seriesIndex / data.fullDataFormatter.container.columnAmount)
|
544
|
-
// const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
|
545
|
-
// return {
|
546
|
-
// slotIndex: seriesIndex,
|
547
|
-
// rowIndex,
|
548
|
-
// columnIndex,
|
549
|
-
// translate,
|
550
|
-
// scale,
|
551
|
-
// }
|
552
|
-
// })
|
553
|
-
} else {
|
554
|
-
// -- 無拆分 --
|
555
|
-
const gridContainerPositionArr = calcGridContainerLayout(data.layout, data.fullDataFormatter.container, 1)
|
556
|
-
return data.computedData.map((d, i) => gridContainerPositionArr[0]) // 每個series相同位置
|
557
|
-
// const columnIndex = 0
|
558
|
-
// const rowIndex = 0
|
559
|
-
// return data.computedData.map((seriesData, seriesIndex) => {
|
560
|
-
// const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
|
561
|
-
// return {
|
562
|
-
// slotIndex: 0,
|
563
|
-
// rowIndex,
|
564
|
-
// columnIndex,
|
565
|
-
// translate,
|
566
|
-
// scale,
|
567
|
-
// }
|
568
|
-
// })
|
569
|
-
}
|
570
|
-
})
|
571
|
-
)
|
572
|
-
|
573
|
-
return gridContainerPosition$
|
574
|
-
}
|
575
|
-
|
576
|
-
// 將原本的value全部替換成加總後的value
|
577
|
-
export const computedStackedDataObservables = ({ isSeriesSeprate$, computedData$ }: {
|
578
|
-
isSeriesSeprate$: Observable<boolean>
|
579
|
-
computedData$: Observable<ComputedDataGrid>
|
580
|
-
}): Observable<ComputedDataGrid> => {
|
581
|
-
const stackedData$: Observable<ComputedDataGrid> = computedData$.pipe(
|
582
|
-
map(data => {
|
583
|
-
// 將同一group的value加總起來
|
584
|
-
const stackedValue = new Array(data[0] ? data[0].length : 0)
|
585
|
-
.fill(null)
|
586
|
-
.map((_, i) => {
|
587
|
-
return data.reduce((prev, current) => {
|
588
|
-
if (current && current[i]) {
|
589
|
-
const currentValue = current[i].value == null || current[i].visible == false
|
590
|
-
? 0
|
591
|
-
: current[i].value!
|
592
|
-
return prev + currentValue
|
593
|
-
}
|
594
|
-
return prev
|
595
|
-
}, 0)
|
596
|
-
})
|
597
|
-
// 將原本的value全部替換成加總後的value
|
598
|
-
const computedData = data.map((series, seriesIndex) => {
|
599
|
-
return series.map((d, i) => {
|
600
|
-
return {
|
601
|
-
...d,
|
602
|
-
value: stackedValue[i],
|
603
|
-
}
|
604
|
-
})
|
605
|
-
})
|
606
|
-
return computedData
|
607
|
-
}),
|
608
|
-
)
|
609
|
-
|
610
|
-
return isSeriesSeprate$.pipe(
|
611
|
-
switchMap(isSeriesSeprate => {
|
612
|
-
return iif(() => isSeriesSeprate, computedData$, stackedData$)
|
613
|
-
})
|
614
|
-
)
|
615
684
|
}
|
package/src/utils/index.ts
CHANGED