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

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,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
  }),
@@ -82,6 +82,7 @@ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) =>
82
82
  dataFormatter.yAxis.scaleDomain[0] === 'auto' ? yMinValue : dataFormatter.yAxis.scaleDomain[0],
83
83
  dataFormatter.yAxis.scaleDomain[1] === 'auto' ? yMaxValue : dataFormatter.yAxis.scaleDomain[1]
84
84
  ]
85
+ debugger
85
86
  // 篩選顯示狀態
86
87
  const visibleFilter = (datum: DataMultiValueDatum, rowIndex: number, columnIndex: number, context: DataFormatterContext<"multiValue">) => {
87
88
  // 如果不在scale的範圍內則為false,不再做visibleFilter的判斷
@@ -1,7 +1,7 @@
1
1
  import type { DataTree, DataTreeObj, DataTreeDatum } from '../types/DataTree'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
3
  import type { ComputedDataTree } from '../types/ComputedDataTree'
4
- import { isObject } from '../utils/commonUtils'
4
+ import { isPlainObject } from '../utils/commonUtils'
5
5
 
6
6
  export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
7
7
  const { data = [], dataFormatter, chartParams } = context
@@ -23,7 +23,7 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
23
23
  try {
24
24
  // 建立樹狀結構資料
25
25
  const dataTreeObj: DataTreeObj = (function () {
26
- if (isObject(data) === true) {
26
+ if (isPlainObject(data) === true) {
27
27
  // 原本就是樹狀結構則直接複製
28
28
  return structuredClone(data) as DataTreeObj
29
29
  } else if (Array.isArray(data) === false) {
@@ -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,28 +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[]>
8
- multiGridContainer$: Observable<GridContainerBox[]>
9
+ multiGridEachDetail$: Observable<ContextObserverGridDetail[]>
10
+ multiGridContainer$: Observable<ContainerPosition[][]>
9
11
  }
10
12
 
11
- export interface MultiGridObservableAll {
12
- gridAxesTransform$: Observable<TransformData>
13
- gridGraphicTransform$: Observable<TransformData>
14
- gridAxesOppositeTransform$: Observable<TransformData>
15
- gridAxesSize$: Observable<{ width: number; height: number; }>
16
- gridHighlight$: Observable<string[]>
17
- SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
18
- GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
19
- visibleComputedData$: Observable<ComputedDataGrid>
20
- }
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
+ // }
21
27
 
22
- export interface GridContainerBox {
23
- slotIndex: number
24
- rowIndex: number
25
- columnIndex: number
26
- translate: [number, number]
27
- scale: [number, number]
28
- }
@@ -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
@@ -1,7 +1,7 @@
1
1
  // import * as d3 from 'd3'
2
2
 
3
- // 是否為物件
4
- export function isObject(variable: any) {
3
+ // 是否為原始物件
4
+ export function isPlainObject(variable: any) {
5
5
  return Object.prototype.toString.call(variable) === "[object Object]";
6
6
  }
7
7
 
@@ -12,7 +12,7 @@ export function isFunction(fn: any) {
12
12
 
13
13
  // 將可選的參數和預設值合併
14
14
  export function mergeOptionsWithDefault<Options extends { [key: string]: any; }> (options: {[key: string]: any}, defaultOptions: Options): Options {
15
- if (isObject(options) === false || isObject(defaultOptions) === false) {
15
+ if (isPlainObject(options) === false || isPlainObject(defaultOptions) === false) {
16
16
  return Object.assign({}, defaultOptions)
17
17
  }
18
18
  const mergeObjColumns = (_options: {[key: string]: any}, _defaultOptions: {[key: string]: any}) => {
@@ -22,12 +22,12 @@ export function mergeOptionsWithDefault<Options extends { [key: string]: any; }>
22
22
  continue
23
23
  }
24
24
  let objValue: any = undefined
25
- // 下一層的object
26
- if (isObject(_options[key]) && isObject(_defaultOptions[key])) {
25
+ // 下一層的plain object
26
+ if (isPlainObject(_options[key]) && isPlainObject(_defaultOptions[key])) {
27
27
  objValue = mergeObjColumns(_options[key], _defaultOptions[key])
28
28
  obj[key as keyof Options] = objValue
29
29
  }
30
- // 不是object直接賦值
30
+ // 不是plain object直接賦值
31
31
  else {
32
32
  obj[key as keyof Options] = _options[key]
33
33
  }