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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }),