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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,10 +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'
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'
44
45
 
46
+ // 每一個grid計算出來的所有Observable
45
47
  export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData$, layout$, fullChartParams$, event$ }: {
46
48
  fullDataFormatter$: Observable<DataFormatterTypeMap<'multiGrid'>>
47
49
  computedData$: Observable<ComputedDataTypeMap<'multiGrid'>>
@@ -49,6 +51,122 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
49
51
  fullChartParams$: Observable<ChartParams>
50
52
  event$: Subject<EventMultiGrid>
51
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
+
52
170
  const destroy$ = new Subject()
53
171
 
54
172
  return combineLatest({
@@ -56,19 +174,29 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
56
174
  computedData: computedData$,
57
175
  }).pipe(
58
176
  switchMap(async (d) => d),
59
- distinctUntilChanged((a, b) => {
60
- // 只有當computedData的長度改變時,才重新計算
61
- return a.computedData.length === b.computedData.length
62
- }),
177
+ // distinctUntilChanged((a, b) => {
178
+ // // 只有當computedData的長度改變時,才重新計算
179
+ // return a.computedData.length === b.computedData.length
180
+ // }),
63
181
  map(data => {
64
182
  // 每次重新計算時,清除之前的訂閱
65
183
  destroy$.next(undefined)
66
184
 
185
+ const defaultGrid = data.fullDataFormatter.gridList[0] ?? DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
186
+
67
187
  return data.computedData.map((gridComputedData, gridIndex) => {
68
188
 
69
189
  // -- 取得該grid的data和dataFormatter
70
- const gridDataFormatter = data.fullDataFormatter.multiGrid[gridIndex]
71
- ?? 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
+ }
72
200
  const gridDataFormatter$ = of(gridDataFormatter).pipe(
73
201
  takeUntil(destroy$),
74
202
  shareReplay(1)
@@ -79,130 +207,76 @@ export const multiGridEachDetailObservable = ({ fullDataFormatter$, computedData
79
207
  )
80
208
 
81
209
  // -- 建立Observables --
82
- const gridAxesTransform$ = gridAxesTransformObservable({
83
- fullDataFormatter$: gridDataFormatter$,
84
- layout$: layout$
85
- }).pipe(
86
- shareReplay(1)
87
- )
88
-
89
- const gridGraphicTransform$ = gridGraphicTransformObservable({
90
- computedData$: gridComputedData$,
91
- fullDataFormatter$: gridDataFormatter$,
92
- layout$: layout$
93
- }).pipe(
94
- shareReplay(1)
95
- )
96
-
97
- const gridAxesOppositeTransform$ = gridAxesOppositeTransformObservable({
98
- gridAxesTransform$
99
- }).pipe(
100
- shareReplay(1)
101
- )
102
-
103
- const gridAxesSize$ = gridAxesSizeObservable({
104
- fullDataFormatter$: gridDataFormatter$,
105
- layout$: layout$
106
- }).pipe(
107
- shareReplay(1)
108
- )
109
-
110
- const datumList$ = gridComputedData$.pipe(
111
- map(d => d.flat())
112
- ).pipe(
113
- shareReplay(1)
114
- )
115
-
116
- const gridHighlight$ = highlightObservable({
117
- datumList$,
118
- fullChartParams$: fullChartParams$,
119
- event$: event$
120
- }).pipe(
121
- shareReplay(1)
122
- )
123
-
124
- const SeriesDataMap$ = seriesDataMapObservable({
125
- datumList$: datumList$
126
- }).pipe(
127
- shareReplay(1)
128
- )
129
-
130
- const GroupDataMap$ = groupDataMapObservable({
131
- datumList$: datumList$
132
- }).pipe(
133
- shareReplay(1)
134
- )
135
-
136
- const visibleComputedData$ = gridVisibleComputedDataObservable({
137
- computedData$: gridComputedData$,
138
- }).pipe(
139
- shareReplay(1)
140
- )
141
-
142
- return {
143
- gridAxesTransform$,
144
- gridGraphicTransform$,
145
- gridAxesOppositeTransform$,
146
- gridAxesSize$,
147
- gridHighlight$,
148
- SeriesDataMap$,
149
- GroupDataMap$,
150
- visibleComputedData$
151
- }
210
+ return detailObservables ({
211
+ gridDataFormatter$,
212
+ gridComputedData$,
213
+ layout$,
214
+ fullChartParams$,
215
+ event$
216
+ })
152
217
  })
153
218
  })
154
219
  )
155
220
  }
156
221
 
157
- interface GridContainerBox {
158
- slotIndex: number
159
- rowIndex: number
160
- columnIndex: number
161
- translate: [number, number]
162
- scale: [number, number]
163
- }
164
222
 
165
- // 每一個grid的container位置
166
- export const multiGridContainerObservable = ({ fullDataFormatter$, layout$, fullChartParams$ }: {
223
+ // 所有container位置(對應series)
224
+ export const multiGridContainerObservable = ({ computedData$, fullDataFormatter$, fullChartParams$, layout$ }: {
225
+ computedData$: Observable<ComputedDataTypeMap<'multiGrid'>>
167
226
  fullDataFormatter$: Observable<DataFormatterTypeMap<'multiGrid'>>
168
- layout$: Observable<Layout>
169
227
  fullChartParams$: Observable<ChartParams>
228
+ layout$: Observable<Layout>
170
229
  }) => {
171
- function calcBox (layout: Layout, container: DataFormatterMultiGridContainer, rowIndex: number, columnIndex: number) {
172
- const { gap, rowAmount, columnAmount } = container
173
- const width = (layout.width / columnAmount) - (gap / 2)
174
- const height = (layout.height / rowAmount) - (gap / 2)
175
- const x = columnIndex * width + (columnIndex * gap)
176
- const y = rowIndex * height + (columnIndex * gap)
177
- const translate: [number, number] = [x, y]
178
- const scale: [number, number] = [width / layout.width, height / layout.height]
179
-
180
- return {
181
- translate,
182
- scale
183
- }
184
- }
185
230
 
186
231
  const multiGridContainer$ = combineLatest({
232
+ computedData: computedData$,
187
233
  fullDataFormatter: fullDataFormatter$,
234
+ fullChartParams: fullChartParams$,
188
235
  layout: layout$,
189
- fullChartParams: fullChartParams$
190
236
  }).pipe(
191
237
  switchMap(async (d) => d),
192
238
  map(data => {
193
- data.fullDataFormatter.container.rowAmount
194
- const boxArr: GridContainerBox[] = data.fullDataFormatter.multiGrid.map((grid, gridIndex) => {
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,
239
+
240
+ const defaultGrid = data.fullDataFormatter.gridList[0] ?? DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
241
+
242
+ const boxArr = data.computedData.map((gridData, gridIndex) => {
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
  }),
@@ -3,14 +3,32 @@ import type { ContextObserverBase } from './ContextObserver'
3
3
  import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
4
4
  import type { TransformData } from './TransformData'
5
5
 
6
- export interface ContextObserverGrid<PluginParams> extends ContextObserverBase<'grid', PluginParams> {
6
+ export interface ContextObserverGrid<PluginParams>
7
+ extends
8
+ ContextObserverBase<'grid', PluginParams>,
9
+ ContextObserverGridDetail {
10
+
11
+ }
12
+
13
+ export interface ContextObserverGridDetail {
14
+ gridContainer$: Observable<ContainerPosition[]>
7
15
  gridAxesTransform$: Observable<TransformData>
16
+ gridAxesReverseTransform$: Observable<TransformData>
8
17
  gridGraphicTransform$: Observable<TransformData>
9
- gridAxesOppositeTransform$: Observable<TransformData>
18
+ gridGraphicReverseScale$: Observable<[number, number][]>
10
19
  gridAxesSize$: Observable<{ width: number; height: number; }>
11
20
  gridHighlight$: Observable<string[]>
21
+ existedSeriesLabels$: Observable<string[]>
12
22
  SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
13
23
  GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
14
24
  visibleComputedData$: Observable<ComputedDataGrid>
25
+ isSeriesPositionSeprate$: Observable<boolean>
15
26
  }
16
27
 
28
+ export interface ContainerPosition {
29
+ slotIndex: number
30
+ rowIndex: number
31
+ columnIndex: number
32
+ translate: [number, number]
33
+ scale: [number, number]
34
+ }
@@ -1,19 +1,27 @@
1
1
  import { Observable } from 'rxjs'
2
2
  import type { ContextObserverBase } from './ContextObserver'
3
3
  import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
4
+ import type { ContainerPosition } from './ContextObserverGrid'
4
5
  import type { TransformData } from './TransformData'
6
+ import type { ContextObserverGridDetail } from './ContextObserverGrid'
5
7
 
6
8
  export interface ContextObserverMultiGrid<PluginParams> extends ContextObserverBase<'multiGrid', PluginParams> {
7
- multiGridEachDetail$: Observable<MultiGridObservableAll[]>
9
+ multiGridEachDetail$: Observable<ContextObserverGridDetail[]>
10
+ multiGridContainer$: Observable<ContainerPosition[][]>
8
11
  }
9
12
 
10
- export interface MultiGridObservableAll {
11
- gridAxesTransform$: Observable<TransformData>
12
- gridGraphicTransform$: Observable<TransformData>
13
- gridAxesOppositeTransform$: Observable<TransformData>
14
- gridAxesSize$: Observable<{ width: number; height: number; }>
15
- gridHighlight$: Observable<string[]>
16
- SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
17
- GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
18
- visibleComputedData$: Observable<ComputedDataGrid>
19
- }
13
+ // export interface MultiGridObservableAll {
14
+ // isSeriesPositionSeprate$: Observable<boolean>
15
+ // gridContainer$: Observable<ContainerPosition[]>
16
+ // gridAxesTransform$: Observable<TransformData>
17
+ // gridAxesReverseTransform$: Observable<TransformData>
18
+ // gridGraphicTransform$: Observable<TransformData>
19
+ // gridGraphicReverseScale$: Observable<[number, number][]>
20
+ // gridAxesSize$: Observable<{ width: number; height: number; }>
21
+ // gridHighlight$: Observable<string[]>
22
+ // existedSeriesLabels$: Observable<string[]>
23
+ // SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
24
+ // GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
25
+ // visibleComputedData$: Observable<ComputedDataGrid>
26
+ // }
27
+
@@ -2,34 +2,49 @@ import type { DataGridDatum, DataGridValue } from './DataGrid'
2
2
  import type { DataFormatterBase, DataFormatterBasePartial, DataFormatterValueAxis, DataFormatterGroupAxis, VisibleFilter } from './DataFormatter'
3
3
  // import type { AxisPosition } from './Axis'
4
4
 
5
- export type SeriesType = 'row' | 'column' // default: 'row'
5
+ export type SeriesDirection = 'row' | 'column' // default: 'row'
6
6
 
7
7
  export interface DataFormatterGrid extends DataFormatterBase<'grid'> {
8
- visibleFilter: VisibleFilter<'grid'>
9
8
  grid: DataFormatterGridGrid
10
- valueAxis: DataFormatterValueAxis
11
- groupAxis: DataFormatterGroupAxis
9
+ container: DataFormatterGridContainer
12
10
  // visibleGroupRange: [number, number] | null
13
11
  // colorsPredicate: (datum: DataGridDatum | DataGridValue, rowIndex: number, columnIndex: number, context: DataFormatterContext<'grid'>) => string
14
12
  }
15
13
 
16
14
  export interface DataFormatterGridPartial extends DataFormatterBasePartial<'grid'> {
17
- grid?: Partial<DataFormatterGridGrid>
15
+ grid?: DataFormatterGridGridPartial
16
+ container?: Partial<DataFormatterGridContainer>
17
+ }
18
+
19
+ export interface DataFormatterGridGrid {
20
+ visibleFilter: VisibleFilter<'grid'>
21
+ gridData: DataFormatterGridGridData
22
+ valueAxis: DataFormatterValueAxis
23
+ groupAxis: DataFormatterGroupAxis
24
+ slotIndex: number | null
25
+ seriesSlotIndexes: number[] | null
26
+ }
27
+
28
+ export interface DataFormatterGridGridPartial {
29
+ visibleFilter?: VisibleFilter<'grid'>
30
+ gridData?: Partial<DataFormatterGridGridData>
18
31
  valueAxis?: Partial<DataFormatterValueAxis>
19
32
  groupAxis?: Partial<DataFormatterGroupAxis>
20
- // colorsPredicate?: (datum: DataGridDatum | DataGridValue, rowIndex: number, columnIndex: number, context: DataFormatterContext<'grid'>) => string
33
+ slotIndex?: number | null
34
+ seriesSlotIndexes?: number[] | null
35
+ }
36
+
37
+ export interface DataFormatterGridContainer {
38
+ gap: number
39
+ rowAmount: number
40
+ columnAmount: number
21
41
  }
22
42
 
23
43
  // grid欄位
24
- export interface DataFormatterGridGrid {
25
- // labelFormat: (datum: DataGridDatum) => string
26
- // rowUnitLabel: string
44
+ export interface DataFormatterGridGridData {
45
+ seriesDirection: SeriesDirection
27
46
  rowLabels: string[]
28
- // rowLabelFormat: string | ((text: any) => string)
29
- // columnUnitLabel: string
30
47
  columnLabels: string[]
31
- // columnLabelFormat: string | ((text: any) => string)
32
- seriesType: SeriesType
33
48
  }
34
49
 
35
50
  // const test: DataFormatterGridPartial = {
@@ -1,5 +1,5 @@
1
1
  import type { VisibleFilter } from './DataFormatter'
2
- import type { DataFormatterGrid } from './DataFormatterGrid'
2
+ import type { DataFormatterGridGrid, DataFormatterGridGridPartial, DataFormatterGridContainer } from './DataFormatterGrid'
3
3
  import type {
4
4
  DataFormatterBase,
5
5
  DataFormatterBasePartial,
@@ -10,30 +10,32 @@ import type { AxisPosition } from './Axis'
10
10
 
11
11
  export interface DataFormatterMultiGrid extends DataFormatterBase<'multiGrid'> {
12
12
  visibleFilter: VisibleFilter<'multiGrid'>
13
- multiGrid: Array<DataFormatterMultiGridMultiGrid>
14
- // visibleGroupRange: [number, number] | null
13
+ gridList: Array<DataFormatterGridGrid>
15
14
  container: DataFormatterMultiGridContainer
16
15
  }
17
16
 
18
17
  export interface DataFormatterMultiGridPartial extends DataFormatterBasePartial<'multiGrid'> {
19
- multiGrid?: Array<Partial<DataFormatterMultiGridMultiGrid>>
18
+ visibleFilter?: VisibleFilter<'multiGrid'>
19
+ gridList?: Array<DataFormatterGridGridPartial>
20
+ container?: Partial<DataFormatterMultiGridContainer>
20
21
  }
21
22
 
22
- // 比grid還多出來的額外參數
23
- export interface DataFormatterMultiGridMultiGrid extends DataFormatterGrid {
24
- slotIndex: number
23
+ export interface DataFormatterMultiGridGrid extends DataFormatterGridGrid {
24
+
25
+ }
26
+
27
+ export interface DataFormatterMultiGridGridPartial extends DataFormatterGridGridPartial {
28
+
25
29
  }
26
30
 
27
31
  // container
28
- export interface DataFormatterMultiGridContainer {
29
- gap: number
30
- rowAmount: number
31
- columnAmount: number
32
+ export interface DataFormatterMultiGridContainer extends DataFormatterGridContainer {
33
+
32
34
  }
33
35
 
34
36
  // multiGrid欄位
35
37
  // export interface DataFormatterMultiGridMultiGrid {
36
- // grid: DataFormatterGridGrid
38
+ // grid: DataFormatterGridGridData
37
39
  // valueAxis: DataFormatterValueAxis // default: 'left'
38
40
  // groupAxis: DataFormatterGroupAxis // default: 'bottom'
39
41
  // colorsPredicate: (datum: DataGridDatum | DataGridValue, rowIndex: number, columnIndex: number, context: DataFormatterContext<'grid'>) => string
@@ -6,11 +6,12 @@ import type { DataSeries, DataSeriesDatum, DataSeriesValue } from '../types/Data
6
6
  import type { DataGrid, DataGridDatum, DataGridValue } from '../types/DataGrid'
7
7
  import type { DataMultiGrid } from '../types/DataMultiGrid'
8
8
  import type { DataMultiValue, DataMultiValueDatum, DataMultiValueValue } from '../types/DataMultiValue'
9
- import type { SeriesType, DataFormatterGrid } from '../types/DataFormatterGrid'
9
+ import type { SeriesDirection, DataFormatterGrid, DataFormatterGridContainer } from '../types/DataFormatterGrid'
10
10
  import type { ComputedDatumSeriesValue } from '../types/ComputedData'
11
11
  import type { ComputedDatumSeries } from '../types/ComputedDataSeries'
12
12
  import type { ComputedDatumGrid, ComputedDataGrid } from '../types/ComputedDataGrid'
13
13
  import type { ComputedDataMultiGrid } from '../types/ComputedDataMultiGrid'
14
+ import type { Layout } from '../types/Layout'
14
15
  // import type { ComputedDatumMultiGrid } from '../types/ComputedDataMultiGrid'
15
16
  import { isObject } from './commonUtils'
16
17
 
@@ -43,9 +44,9 @@ export function createGridSeriesLabels ({ transposedDataGrid, dataFormatter, cha
43
44
  chartType?: ChartType
44
45
  gridIndex?: number
45
46
  }) {
46
- const labels = dataFormatter.grid.seriesType === 'row'
47
- ? dataFormatter.grid.rowLabels
48
- : dataFormatter.grid.columnLabels
47
+ const labels = dataFormatter.grid.gridData.seriesDirection === 'row'
48
+ ? dataFormatter.grid.gridData.rowLabels
49
+ : dataFormatter.grid.gridData.columnLabels
49
50
  return transposedDataGrid.map((_, rowIndex) => {
50
51
  return labels[rowIndex] != null
51
52
  ? labels[rowIndex]
@@ -62,9 +63,9 @@ export function createGridGroupLabels ({ transposedDataGrid, dataFormatter, char
62
63
  if (transposedDataGrid[0] == null) {
63
64
  return []
64
65
  }
65
- const labels = dataFormatter.grid.seriesType === 'row'
66
- ? dataFormatter.grid.columnLabels
67
- : dataFormatter.grid.rowLabels
66
+ const labels = dataFormatter.grid.gridData.seriesDirection === 'row'
67
+ ? dataFormatter.grid.gridData.columnLabels
68
+ : dataFormatter.grid.gridData.rowLabels
68
69
  return transposedDataGrid[0].map((_, columnLabels) => {
69
70
  return labels[columnLabels] != null
70
71
  ? labels[columnLabels]
@@ -146,9 +147,9 @@ export function getMinAndMaxMultiValue (data: DataMultiValue, valueIndex: number
146
147
 
147
148
  // }
148
149
 
149
- // 轉置成seriesType為main的陣列格式
150
- export function transposeData<T> (seriesType: SeriesType, data: T[][]): T[][] {
151
- if (seriesType === 'row') {
150
+ // 轉置成seriesDirection為main的陣列格式
151
+ export function transposeData<T> (seriesDirection: SeriesDirection, data: T[][]): T[][] {
152
+ if (seriesDirection === 'row') {
152
153
  return Object.assign([], data)
153
154
  }
154
155
  // 取得原始陣列的維度
@@ -179,6 +180,21 @@ export function seriesColorPredicate (seriesIndex: number, chartParams: ChartPar
179
180
  ]
180
181
  }
181
182
 
183
+ export function calcGridContainerPosition (layout: Layout, container: DataFormatterGridContainer, rowIndex: number, columnIndex: number) {
184
+ const { gap, rowAmount, columnAmount } = container
185
+ const width = (layout.width - (gap * (columnAmount - 1))) / columnAmount
186
+ const height = (layout.height - (gap * (rowAmount - 1))) / rowAmount
187
+ const x = columnIndex * width + (columnIndex * gap)
188
+ const y = rowIndex * height + (rowIndex * gap)
189
+ const translate: [number, number] = [x, y]
190
+ const scale: [number, number] = [width / layout.width, height / layout.height]
191
+
192
+ return {
193
+ translate,
194
+ scale
195
+ }
196
+ }
197
+
182
198
  // // multiGrid datum color
183
199
  // export function multiGridColorPredicate ({ seriesIndex, groupIndex, data, chartParams }: {
184
200
  // seriesIndex: number