@orbcharts/core 3.0.0-alpha.32 → 3.0.0-alpha.33

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.
@@ -19,15 +19,18 @@ import type {
19
19
  DataTypeMap,
20
20
  DataFormatterTypeMap,
21
21
  DataFormatterGrid,
22
- DataFormatterContext,
22
+ DataFormatterGridContainer,
23
23
  DataFormatterValueAxis,
24
24
  DataFormatterGroupAxis,
25
+ ContainerPosition,
25
26
  HighlightTarget,
26
27
  Layout,
27
28
  TransformData } from '../types'
28
- import { getMinAndMaxGrid, transposeData } from '../utils/orbchartsUtils'
29
+ import { getMinAndMaxGrid } from '../utils/orbchartsUtils'
29
30
  import { createAxisLinearScale, createAxisPointScale, createAxisQuantizeScale } from '../utils/d3Utils'
30
31
  import { highlightObservable } from '../utils/observables'
32
+ import { calcGridContainerPosition } from '../utils/orbchartsUtils'
33
+ import { DATA_FORMATTER_GRID_GRID_DEFAULT } from '../defaults'
31
34
 
32
35
  export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
33
36
  fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
@@ -44,7 +47,7 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
44
47
  if (!xAxis || !yAxis) {
45
48
  return {
46
49
  translate: [0, 0],
47
- scale: [0, 0],
50
+ scale: [1, 1],
48
51
  rotate: 0,
49
52
  rotateX: 0,
50
53
  rotateY: 0,
@@ -102,6 +105,8 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
102
105
  translateX = width
103
106
  } else if (yAxis.position === 'top') {
104
107
  rotate = -90
108
+ rotateX = 180
109
+ rotateY = 180
105
110
  translateX = width
106
111
  } else {
107
112
  // 預設
@@ -109,12 +114,11 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
109
114
  translateY = height
110
115
  }
111
116
  }
112
-
113
117
  // selection.style('transform', `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`)
114
118
 
115
119
  return {
116
120
  translate: [translateX, translateY],
117
- scale: [0, 0],
121
+ scale: [1, 1],
118
122
  rotate,
119
123
  rotateX,
120
124
  rotateY,
@@ -131,8 +135,8 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
131
135
  switchMap(async (d) => d),
132
136
  ).subscribe(data => {
133
137
  const axesTransformData = calcAxesTransform({
134
- xAxis: data.fullDataFormatter.groupAxis,
135
- yAxis: data.fullDataFormatter.valueAxis,
138
+ xAxis: data.fullDataFormatter.grid.groupAxis,
139
+ yAxis: data.fullDataFormatter.grid.valueAxis,
136
140
  width: data.layout.width,
137
141
  height: data.layout.height
138
142
  })
@@ -146,6 +150,30 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
146
150
  })
147
151
  }
148
152
 
153
+
154
+ export const gridAxesReverseTransformObservable = ({ gridAxesTransform$ }: {
155
+ gridAxesTransform$: Observable<TransformData>
156
+ }): Observable<TransformData> => {
157
+ return gridAxesTransform$.pipe(
158
+ map(d => {
159
+ // const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
160
+ const translate: [number, number] = [0, 0] // 無需逆轉
161
+ const scale: [number, number] = [1 / d.scale[0], 1 / d.scale[1]]
162
+ const rotate = d.rotate * -1
163
+ const rotateX = d.rotateX * -1
164
+ const rotateY = d.rotateY * -1
165
+ return {
166
+ translate,
167
+ scale,
168
+ rotate,
169
+ rotateX,
170
+ rotateY,
171
+ value: `translate(${translate[0]}px, ${translate[1]}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`
172
+ }
173
+ }),
174
+ )
175
+ }
176
+
149
177
  export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
150
178
  computedData$: Observable<ComputedDataTypeMap<'grid'>>
151
179
  fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
@@ -244,8 +272,8 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
244
272
  ).subscribe(data => {
245
273
  const dataAreaTransformData = calcGridDataAreaTransform ({
246
274
  data: data.computedData,
247
- groupAxis: data.fullDataFormatter.groupAxis,
248
- valueAxis: data.fullDataFormatter.valueAxis,
275
+ groupAxis: data.fullDataFormatter.grid.groupAxis,
276
+ valueAxis: data.fullDataFormatter.grid.valueAxis,
249
277
  width: data.layout.width,
250
278
  height: data.layout.height
251
279
  })
@@ -259,24 +287,33 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
259
287
  })
260
288
  }
261
289
 
262
- export const gridAxesOppositeTransformObservable = ({ gridAxesTransform$ }: {
290
+ export const gridGraphicReverseScaleObservable = ({ gridContainer$, gridAxesTransform$, gridGraphicTransform$ }: {
291
+ gridContainer$: Observable<ContainerPosition[]>
263
292
  gridAxesTransform$: Observable<TransformData>
264
- }): Observable<TransformData> => {
265
- return gridAxesTransform$.pipe(
266
- map(d => {
267
- // const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
268
- const translate: [number, number] = [0, 0] // 無需逆轉
269
- const scale: [number, number] = [d.scale[0] * -1, d.scale[1] * -1]
270
- const rotate = d.rotate * -1
271
- const rotateX = d.rotateX * -1
272
- const rotateY = d.rotateY * -1
273
- return {
274
- translate,
275
- scale,
276
- rotate,
277
- rotateX,
278
- rotateY,
279
- value: `translate(${translate[0]}px, ${translate[1]}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`
293
+ gridGraphicTransform$: Observable<TransformData>
294
+ }): Observable<[number, number][]> => {
295
+ return combineLatest({
296
+ gridContainer: gridContainer$,
297
+ gridAxesTransform: gridAxesTransform$,
298
+ gridGraphicTransform: gridGraphicTransform$,
299
+ }).pipe(
300
+ switchMap(async (d) => d),
301
+ map(data => {
302
+ if (data.gridAxesTransform.rotate == 0 || data.gridAxesTransform.rotate == 180) {
303
+ return data.gridContainer.map((series, seriesIndex) => {
304
+ return [
305
+ 1 / data.gridGraphicTransform.scale[0] / data.gridContainer[seriesIndex].scale[0],
306
+ 1 / data.gridGraphicTransform.scale[1] / data.gridContainer[seriesIndex].scale[1],
307
+ ]
308
+ })
309
+ } else {
310
+ return data.gridContainer.map((series, seriesIndex) => {
311
+ // 由於有垂直的旋轉,所以外層 (container) x和y的scale要互換
312
+ return [
313
+ 1 / data.gridGraphicTransform.scale[0] / data.gridContainer[seriesIndex].scale[1],
314
+ 1 / data.gridGraphicTransform.scale[1] / data.gridContainer[seriesIndex].scale[0],
315
+ ]
316
+ })
280
317
  }
281
318
  }),
282
319
  )
@@ -317,8 +354,8 @@ export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
317
354
  ).subscribe(data => {
318
355
 
319
356
  const axisSize = calcAxesSize({
320
- xAxisPosition: data.fullDataFormatter.groupAxis.position,
321
- yAxisPosition: data.fullDataFormatter.valueAxis.position,
357
+ xAxisPosition: data.fullDataFormatter.grid.groupAxis.position,
358
+ yAxisPosition: data.fullDataFormatter.grid.valueAxis.position,
322
359
  width: data.layout.width,
323
360
  height: data.layout.height,
324
361
  })
@@ -343,6 +380,21 @@ export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
343
380
  // return highlightObservable ({ datumList$, fullChartParams$, event$ })
344
381
  // }
345
382
 
383
+ export const existedSeriesLabelsObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
384
+ return computedData$.pipe(
385
+ map(data => {
386
+ return data
387
+ .filter(series => series.length)
388
+ .map(series => {
389
+ return series[0].seriesLabel
390
+ })
391
+ }),
392
+ distinctUntilChanged((a, b) => {
393
+ return JSON.stringify(a).length === JSON.stringify(b).length
394
+ }),
395
+ )
396
+ }
397
+
346
398
  export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
347
399
  return computedData$.pipe(
348
400
  map(data => {
@@ -358,3 +410,78 @@ export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedD
358
410
  )
359
411
  }
360
412
 
413
+ export const isSeriesPositionSeprateObservable = ({ computedData$, fullDataFormatter$ }: {
414
+ computedData$: Observable<ComputedDataTypeMap<'grid'>>
415
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
416
+ }) => {
417
+ return combineLatest({
418
+ computedData: computedData$,
419
+ fullDataFormatter: fullDataFormatter$
420
+ }).pipe(
421
+ map(data => {
422
+ return data.fullDataFormatter.grid.seriesSlotIndexes && data.fullDataFormatter.grid.seriesSlotIndexes.length === data.computedData.length
423
+ ? true
424
+ : false
425
+ }),
426
+ distinctUntilChanged()
427
+ )
428
+ }
429
+
430
+ // 所有container位置(對應series)
431
+ export const gridContainerObservable = ({ computedData$, fullDataFormatter$, fullChartParams$, layout$ }: {
432
+ computedData$: Observable<ComputedDataTypeMap<'grid'>>
433
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
434
+ fullChartParams$: Observable<ChartParams>
435
+ layout$: Observable<Layout>
436
+ }) => {
437
+
438
+ const gridContainer$ = combineLatest({
439
+ computedData: computedData$,
440
+ fullDataFormatter: fullDataFormatter$,
441
+ fullChartParams: fullChartParams$,
442
+ layout: layout$,
443
+ }).pipe(
444
+ switchMap(async (d) => d),
445
+ map(data => {
446
+
447
+ const grid = data.fullDataFormatter.grid
448
+
449
+ // 有設定series定位
450
+ const hasSeriesPosition = grid.seriesSlotIndexes && grid.seriesSlotIndexes.length === data.computedData.length
451
+ ? true
452
+ : false
453
+
454
+ if (hasSeriesPosition) {
455
+ // -- 依seriesSlotIndexes計算 --
456
+ return data.computedData.map((seriesData, seriesIndex) => {
457
+ const columnIndex = grid.seriesSlotIndexes[seriesIndex] % data.fullDataFormatter.container.columnAmount
458
+ const rowIndex = Math.floor(grid.seriesSlotIndexes[seriesIndex] / data.fullDataFormatter.container.columnAmount)
459
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
460
+ return {
461
+ slotIndex: grid.seriesSlotIndexes[seriesIndex],
462
+ rowIndex,
463
+ columnIndex,
464
+ translate,
465
+ scale,
466
+ }
467
+ })
468
+ } else {
469
+ // -- 依grid的slotIndex計算 --
470
+ const columnIndex = grid.slotIndex % data.fullDataFormatter.container.columnAmount
471
+ const rowIndex = Math.floor(grid.slotIndex / data.fullDataFormatter.container.columnAmount)
472
+ return data.computedData.map((seriesData, seriesIndex) => {
473
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
474
+ return {
475
+ slotIndex: grid.slotIndex,
476
+ rowIndex,
477
+ columnIndex,
478
+ translate,
479
+ scale,
480
+ }
481
+ })
482
+ }
483
+ })
484
+ )
485
+
486
+ return gridContainer$
487
+ }
@@ -1,9 +1,9 @@
1
1
  import type { DataGrid } from '../types/DataGrid'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
- import type { DataFormatterMultiGrid } from '../types/DataFormatterMultiGrid'
4
- import type { ComputedDataGrid } from '../types/ComputedDataGrid'
3
+ import type { DataFormatterGrid } from '../types/DataFormatterGrid'
4
+ import type { ComputedDataMultiGrid } from '../types/ComputedDataMultiGrid'
5
5
  import { computeBaseGridData } from '../grid/computeGridData'
6
- import { DATA_FORMATTER_MULTI_GRID_DEFAULT } from '../defaults'
6
+ import { DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT } from '../defaults'
7
7
  import { seriesColorPredicate } from '../utils/orbchartsUtils'
8
8
 
9
9
  export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], dataFormatter, chartParams, layout }) => {
@@ -11,23 +11,27 @@ export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], d
11
11
  return []
12
12
  }
13
13
 
14
- let multiGridData: ComputedDataGrid[] = []
14
+ let multiGridData: ComputedDataMultiGrid = []
15
15
 
16
16
  try {
17
- const defaultDataFormatterGrid = Object.assign({}, DATA_FORMATTER_MULTI_GRID_DEFAULT.multiGrid[0])
17
+ const defaultGrid = dataFormatter.gridList[0] || DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
18
18
 
19
19
  // 計算每個grid的資料
20
20
  multiGridData = data.map((gridData, gridIndex) => {
21
- const currentDataFormatterGrid = dataFormatter.multiGrid[gridIndex] || defaultDataFormatterGrid
22
- // const dataFormatterGrid: DataFormatterGrid = {
23
- // ...currentDataFormatterGrid,
24
- // type: `multiGrid` as any,
25
- // visibleFilter: dataFormatter.visibleFilter as any,
26
- // }
21
+ const currentDataFormatterGrid = dataFormatter.gridList[gridIndex] || defaultGrid
22
+
27
23
  return computeBaseGridData(
28
24
  {
29
25
  data: gridData,
30
- dataFormatter: currentDataFormatterGrid,
26
+ dataFormatter: {
27
+ type: 'grid',
28
+ grid: {
29
+ ...currentDataFormatterGrid
30
+ },
31
+ container: {
32
+ ...dataFormatter.container
33
+ }
34
+ },
31
35
  chartParams,
32
36
  layout
33
37
  },
@@ -16,21 +16,16 @@ import type {
16
16
  ChartType,
17
17
  ChartParams,
18
18
  ComputedDataTypeMap,
19
- ComputedDatumTypeMap,
20
- ContextObserverFn,
19
+ ComputedDataGrid,
21
20
  DataTypeMap,
22
21
  DataFormatterTypeMap,
23
22
  DataFormatterGrid,
24
- DataFormatterContext,
25
- DataFormatterValueAxis,
26
- DataFormatterGroupAxis,
27
23
  DataFormatterMultiGridContainer,
28
24
  EventMultiGrid,
29
25
  HighlightTarget,
30
26
  Layout,
31
27
  TransformData } from '../types'
32
- import { getMinAndMaxGrid, transposeData } from '../utils/orbchartsUtils'
33
- import { createAxisLinearScale, createAxisPointScale, createAxisQuantizeScale } from '../utils/d3Utils'
28
+ import type { ContextObserverGridDetail } from '../types'
34
29
  import {
35
30
  highlightObservable,
36
31
  seriesDataMapObservable,
@@ -38,11 +33,17 @@ import {
38
33
  import {
39
34
  gridAxesTransformObservable,
40
35
  gridGraphicTransformObservable,
41
- gridAxesOppositeTransformObservable,
36
+ gridGraphicReverseScaleObservable,
37
+ gridAxesReverseTransformObservable,
42
38
  gridAxesSizeObservable,
43
- gridVisibleComputedDataObservable } from '../grid/gridObservables'
44
- import { DATA_FORMATTER_MULTI_GRID_MULTI_GRID_DEFAULT } from '../defaults'
39
+ existedSeriesLabelsObservable,
40
+ gridVisibleComputedDataObservable,
41
+ isSeriesPositionSeprateObservable,
42
+ gridContainerObservable } from '../grid/gridObservables'
43
+ import { DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT } from '../defaults'
44
+ import { calcGridContainerPosition } from '../utils/orbchartsUtils'
45
45
 
46
+ // 每一個grid計算出來的所有Observable
46
47
  export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData$, layout$, fullChartParams$, event$ }: {
47
48
  fullDataFormatter$: Observable<DataFormatterTypeMap<'multiGrid'>>
48
49
  computedData$: Observable<ComputedDataTypeMap<'multiGrid'>>
@@ -50,6 +51,122 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
50
51
  fullChartParams$: Observable<ChartParams>
51
52
  event$: Subject<EventMultiGrid>
52
53
  }) => {
54
+
55
+ // 建立Observables
56
+ function detailObservables ({ gridDataFormatter$, gridComputedData$, layout$, fullChartParams$, event$ }: {
57
+ // fullDataFormatter$: Observable<DataFormatterTypeMap<'multiGrid'>>
58
+ // computedData$: Observable<ComputedDataTypeMap<'multiGrid'>>
59
+ gridDataFormatter$: Observable<DataFormatterGrid>
60
+ gridComputedData$: Observable<ComputedDataGrid>
61
+ layout$: Observable<Layout>
62
+ fullChartParams$: Observable<ChartParams>
63
+ event$: Subject<EventMultiGrid>
64
+ }): ContextObserverGridDetail {
65
+
66
+ const isSeriesPositionSeprate$ = isSeriesPositionSeprateObservable({
67
+ computedData$: gridComputedData$,
68
+ fullDataFormatter$: gridDataFormatter$,
69
+ }).pipe(
70
+ shareReplay(1)
71
+ )
72
+
73
+ const gridContainer$ = gridContainerObservable({
74
+ computedData$: gridComputedData$,
75
+ fullDataFormatter$: gridDataFormatter$,
76
+ fullChartParams$,
77
+ layout$
78
+ }).pipe(
79
+ shareReplay(1)
80
+ )
81
+
82
+ const gridAxesTransform$ = gridAxesTransformObservable({
83
+ fullDataFormatter$: gridDataFormatter$,
84
+ layout$: layout$
85
+ }).pipe(
86
+ shareReplay(1)
87
+ )
88
+
89
+
90
+ const gridAxesReverseTransform$ = gridAxesReverseTransformObservable({
91
+ gridAxesTransform$
92
+ }).pipe(
93
+ shareReplay(1)
94
+ )
95
+
96
+ const gridGraphicTransform$ = gridGraphicTransformObservable({
97
+ computedData$: gridComputedData$,
98
+ fullDataFormatter$: gridDataFormatter$,
99
+ layout$: layout$
100
+ }).pipe(
101
+ shareReplay(1)
102
+ )
103
+
104
+ const gridGraphicReverseScale$ = gridGraphicReverseScaleObservable({
105
+ gridContainer$: gridContainer$,
106
+ gridAxesTransform$: gridAxesTransform$,
107
+ gridGraphicTransform$: gridGraphicTransform$,
108
+ })
109
+
110
+ const gridAxesSize$ = gridAxesSizeObservable({
111
+ fullDataFormatter$: gridDataFormatter$,
112
+ layout$: layout$
113
+ }).pipe(
114
+ shareReplay(1)
115
+ )
116
+
117
+ const datumList$ = gridComputedData$.pipe(
118
+ map(d => d.flat())
119
+ ).pipe(
120
+ shareReplay(1)
121
+ )
122
+
123
+ const gridHighlight$ = highlightObservable({
124
+ datumList$,
125
+ fullChartParams$: fullChartParams$,
126
+ event$: event$
127
+ }).pipe(
128
+ shareReplay(1)
129
+ )
130
+
131
+ const existedSeriesLabels$ = existedSeriesLabelsObservable({
132
+ computedData$: gridComputedData$,
133
+ })
134
+
135
+ const SeriesDataMap$ = seriesDataMapObservable({
136
+ datumList$: datumList$
137
+ }).pipe(
138
+ shareReplay(1)
139
+ )
140
+
141
+ const GroupDataMap$ = groupDataMapObservable({
142
+ datumList$: datumList$
143
+ }).pipe(
144
+ shareReplay(1)
145
+ )
146
+
147
+ const visibleComputedData$ = gridVisibleComputedDataObservable({
148
+ computedData$: gridComputedData$,
149
+ }).pipe(
150
+ shareReplay(1)
151
+ )
152
+
153
+
154
+ return {
155
+ isSeriesPositionSeprate$,
156
+ gridContainer$,
157
+ gridAxesTransform$,
158
+ gridAxesReverseTransform$,
159
+ gridGraphicTransform$,
160
+ gridGraphicReverseScale$,
161
+ gridAxesSize$,
162
+ gridHighlight$,
163
+ existedSeriesLabels$,
164
+ SeriesDataMap$,
165
+ GroupDataMap$,
166
+ visibleComputedData$,
167
+ }
168
+ }
169
+
53
170
  const destroy$ = new Subject()
54
171
 
55
172
  return combineLatest({
@@ -57,19 +174,29 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
57
174
  computedData: computedData$,
58
175
  }).pipe(
59
176
  switchMap(async (d) => d),
60
- distinctUntilChanged((a, b) => {
61
- // 只有當computedData的長度改變時,才重新計算
62
- return a.computedData.length === b.computedData.length
63
- }),
177
+ // distinctUntilChanged((a, b) => {
178
+ // // 只有當computedData的長度改變時,才重新計算
179
+ // return a.computedData.length === b.computedData.length
180
+ // }),
64
181
  map(data => {
65
182
  // 每次重新計算時,清除之前的訂閱
66
183
  destroy$.next(undefined)
67
184
 
185
+ const defaultGrid = data.fullDataFormatter.gridList[0] ?? DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
186
+
68
187
  return data.computedData.map((gridComputedData, gridIndex) => {
69
188
 
70
189
  // -- 取得該grid的data和dataFormatter
71
- const gridDataFormatter = data.fullDataFormatter.multiGrid[gridIndex]
72
- ?? data.fullDataFormatter.multiGrid[0] // 預設使用第0筆資料
190
+ const grid = data.fullDataFormatter.gridList[gridIndex] ?? defaultGrid
191
+ const gridDataFormatter: DataFormatterGrid = {
192
+ type: 'grid',
193
+ grid: {
194
+ ...grid
195
+ },
196
+ container: {
197
+ ...data.fullDataFormatter.container
198
+ }
199
+ }
73
200
  const gridDataFormatter$ = of(gridDataFormatter).pipe(
74
201
  takeUntil(destroy$),
75
202
  shareReplay(1)
@@ -80,104 +207,26 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
80
207
  )
81
208
 
82
209
  // -- 建立Observables --
83
- const gridAxesTransform$ = gridAxesTransformObservable({
84
- fullDataFormatter$: gridDataFormatter$,
85
- layout$: layout$
86
- }).pipe(
87
- shareReplay(1)
88
- )
89
-
90
- const gridGraphicTransform$ = gridGraphicTransformObservable({
91
- computedData$: gridComputedData$,
92
- fullDataFormatter$: gridDataFormatter$,
93
- layout$: layout$
94
- }).pipe(
95
- shareReplay(1)
96
- )
97
-
98
- const gridAxesOppositeTransform$ = gridAxesOppositeTransformObservable({
99
- gridAxesTransform$
100
- }).pipe(
101
- shareReplay(1)
102
- )
103
-
104
- const gridAxesSize$ = gridAxesSizeObservable({
105
- fullDataFormatter$: gridDataFormatter$,
106
- layout$: layout$
107
- }).pipe(
108
- shareReplay(1)
109
- )
110
-
111
- const datumList$ = gridComputedData$.pipe(
112
- map(d => d.flat())
113
- ).pipe(
114
- shareReplay(1)
115
- )
116
-
117
- const gridHighlight$ = highlightObservable({
118
- datumList$,
119
- fullChartParams$: fullChartParams$,
120
- event$: event$
121
- }).pipe(
122
- shareReplay(1)
123
- )
124
-
125
- const SeriesDataMap$ = seriesDataMapObservable({
126
- datumList$: datumList$
127
- }).pipe(
128
- shareReplay(1)
129
- )
130
-
131
- const GroupDataMap$ = groupDataMapObservable({
132
- datumList$: datumList$
133
- }).pipe(
134
- shareReplay(1)
135
- )
136
-
137
- const visibleComputedData$ = gridVisibleComputedDataObservable({
138
- computedData$: gridComputedData$,
139
- }).pipe(
140
- shareReplay(1)
141
- )
142
-
143
- return {
144
- gridAxesTransform$,
145
- gridGraphicTransform$,
146
- gridAxesOppositeTransform$,
147
- gridAxesSize$,
148
- gridHighlight$,
149
- SeriesDataMap$,
150
- GroupDataMap$,
151
- visibleComputedData$
152
- }
210
+ return detailObservables ({
211
+ gridDataFormatter$,
212
+ gridComputedData$,
213
+ layout$,
214
+ fullChartParams$,
215
+ event$
216
+ })
153
217
  })
154
218
  })
155
219
  )
156
220
  }
157
221
 
158
222
 
159
-
160
- // 每一個grid的container位置
223
+ // 所有container位置(對應series)
161
224
  export const multiGridContainerObservable = ({ computedData$, fullDataFormatter$, fullChartParams$, layout$ }: {
162
225
  computedData$: Observable<ComputedDataTypeMap<'multiGrid'>>
163
226
  fullDataFormatter$: Observable<DataFormatterTypeMap<'multiGrid'>>
164
227
  fullChartParams$: Observable<ChartParams>
165
228
  layout$: Observable<Layout>
166
229
  }) => {
167
- function calcBox (layout: Layout, container: DataFormatterMultiGridContainer, rowIndex: number, columnIndex: number) {
168
- const { gap, rowAmount, columnAmount } = container
169
- const width = (layout.width - (gap * (columnAmount - 1))) / columnAmount
170
- const height = (layout.height - (gap * (rowAmount - 1))) / rowAmount
171
- const x = columnIndex * width + (columnIndex * gap)
172
- const y = rowIndex * height + (rowIndex * gap)
173
- const translate: [number, number] = [x, y]
174
- const scale: [number, number] = [width / layout.width, height / layout.height]
175
-
176
- return {
177
- translate,
178
- scale
179
- }
180
- }
181
230
 
182
231
  const multiGridContainer$ = combineLatest({
183
232
  computedData: computedData$,
@@ -188,21 +237,46 @@ export const multiGridContainerObservable = ({ computedData$, fullDataFormatter$
188
237
  switchMap(async (d) => d),
189
238
  map(data => {
190
239
 
191
- const defaultGrid = data.fullDataFormatter.multiGrid[0] ?? DATA_FORMATTER_MULTI_GRID_MULTI_GRID_DEFAULT
240
+ const defaultGrid = data.fullDataFormatter.gridList[0] ?? DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
192
241
 
193
242
  const boxArr = data.computedData.map((gridData, gridIndex) => {
194
- const grid = data.fullDataFormatter.multiGrid[gridIndex] ?? defaultGrid
195
- const columnIndex = grid.slotIndex % data.fullDataFormatter.container.columnAmount
196
- const rowIndex = Math.floor(grid.slotIndex / data.fullDataFormatter.container.columnAmount)
197
- const { translate, scale } = calcBox(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
198
-
199
- return {
200
- slotIndex: grid.slotIndex,
201
- rowIndex,
202
- columnIndex,
203
- translate,
204
- scale,
243
+ const grid = data.fullDataFormatter.gridList[gridIndex] ?? defaultGrid
244
+
245
+ // 有設定series定位
246
+ const hasSeriesPosition = grid.seriesSlotIndexes && grid.seriesSlotIndexes.length === gridData.length
247
+ ? true
248
+ : false
249
+
250
+ if (hasSeriesPosition) {
251
+ // -- 依seriesSlotIndexes計算 --
252
+ return gridData.map((seriesData, seriesIndex) => {
253
+ const columnIndex = grid.seriesSlotIndexes[seriesIndex] % data.fullDataFormatter.container.columnAmount
254
+ const rowIndex = Math.floor(grid.seriesSlotIndexes[seriesIndex] / data.fullDataFormatter.container.columnAmount)
255
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
256
+ return {
257
+ slotIndex: grid.seriesSlotIndexes[seriesIndex],
258
+ rowIndex,
259
+ columnIndex,
260
+ translate,
261
+ scale,
262
+ }
263
+ })
264
+ } else {
265
+ // -- 依grid的slotIndex計算 --
266
+ const columnIndex = grid.slotIndex % data.fullDataFormatter.container.columnAmount
267
+ const rowIndex = Math.floor(grid.slotIndex / data.fullDataFormatter.container.columnAmount)
268
+ return gridData.map((seriesData, seriesIndex) => {
269
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
270
+ return {
271
+ slotIndex: grid.slotIndex,
272
+ rowIndex,
273
+ columnIndex,
274
+ translate,
275
+ scale,
276
+ }
277
+ })
205
278
  }
279
+
206
280
  })
207
281
  return boxArr
208
282
  }),