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

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,13 +12,23 @@ export declare function formatValueToLabel(value: any, valueFormatter: string |
12
12
  export declare function createDefaultDatumId(chartTypeOrPrefix: string, levelOneIndex: number, levelTwoIndex: number, levelThreeIndex?: number): string;
13
13
  export declare function createDefaultSeriesLabel(chartTypeOrPrefix: string, seriesIndex: number): string;
14
14
  export declare function createDefaultGroupLabel(chartTypeOrPrefix: string, groupIndex: number): string;
15
- export declare function createGridSeriesLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex }: {
15
+ export declare function createGridSeriesLabels({ transposedDataGrid, dataFormatter, chartType }: {
16
+ transposedDataGrid: DataGridDatum[][];
17
+ dataFormatter: DataFormatterGrid;
18
+ chartType?: ChartType;
19
+ }): string[];
20
+ export declare function createMultiGridSeriesLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex }: {
16
21
  transposedDataGrid: DataGridDatum[][];
17
22
  dataFormatter: DataFormatterGrid;
18
23
  chartType?: ChartType;
19
24
  gridIndex?: number;
20
25
  }): string[];
21
- export declare function createGridGroupLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex }: {
26
+ export declare function createGridGroupLabels({ transposedDataGrid, dataFormatter, chartType }: {
27
+ transposedDataGrid: DataGridDatum[][];
28
+ dataFormatter: DataFormatterGrid;
29
+ chartType?: ChartType;
30
+ }): string[];
31
+ export declare function createMultiGridGroupLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex }: {
22
32
  transposedDataGrid: DataGridDatum[][];
23
33
  dataFormatter: DataFormatterGrid;
24
34
  chartType?: ChartType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbcharts/core",
3
- "version": "3.0.0-alpha.33",
3
+ "version": "3.0.0-alpha.35",
4
4
  "description": "OrbCharts is an open source chart library based on d3.js and rx.js",
5
5
  "author": "Blue Planet Inc.",
6
6
  "license": "Apache-2.0",
@@ -84,6 +84,20 @@ function resizeObservable(elem: HTMLElement | Element): Observable<DOMRectReadOn
84
84
  })
85
85
  }
86
86
 
87
+ function mergeDataFormatter <T>(dataFormatter: any, defaultDataFormatter: T, chartType: ChartType): T {
88
+ const mergedData = mergeOptionsWithDefault(dataFormatter, defaultDataFormatter)
89
+
90
+ if (chartType === 'multiGrid' && (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList != null) {
91
+ // multiGrid欄位為陣列,需要各別來merge預設值
92
+ (mergedData as DataFormatterTypeMap<'multiGrid'>).gridList = (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList.map((d, i) => {
93
+ const defaultGrid = (defaultDataFormatter as DataFormatterTypeMap<'multiGrid'>).gridList[i] || (defaultDataFormatter as DataFormatterTypeMap<'multiGrid'>).gridList[0]
94
+ return mergeOptionsWithDefault(d, defaultGrid)
95
+ })
96
+ }
97
+ console.log(mergedData)
98
+ return mergedData
99
+ }
100
+
87
101
  export const createBaseChart: CreateBaseChart = <T extends ChartType>({ defaultDataFormatter, computedDataFn, contextObserverFn }: {
88
102
  defaultDataFormatter: DataFormatterTypeMap<T>
89
103
  computedDataFn: ComputedDataFn<T>
@@ -127,12 +141,14 @@ export const createBaseChart: CreateBaseChart = <T extends ChartType>({ defaultD
127
141
  const mergedPresetWithDefault: Preset<T> = ((options) => {
128
142
  const _options = options ? options : CHART_OPTIONS_DEFAULT as ChartOptionsPartial<T>
129
143
  const preset = _options.preset ? _options.preset : {} as PresetPartial<T>
144
+
130
145
  return {
131
146
  chartParams: preset.chartParams
132
147
  ? mergeOptionsWithDefault(preset.chartParams, CHART_PARAMS_DEFAULT)
133
148
  : CHART_PARAMS_DEFAULT,
134
149
  dataFormatter: preset.dataFormatter
135
- ? mergeOptionsWithDefault(preset.dataFormatter, defaultDataFormatter)
150
+ // ? mergeOptionsWithDefault(preset.dataFormatter, defaultDataFormatter)
151
+ ? mergeDataFormatter(preset.dataFormatter, defaultDataFormatter, chartType)
136
152
  : defaultDataFormatter,
137
153
  allPluginParams: preset.allPluginParams
138
154
  ? preset.allPluginParams
@@ -147,15 +163,16 @@ export const createBaseChart: CreateBaseChart = <T extends ChartType>({ defaultD
147
163
  takeUntil(destroy$),
148
164
  startWith({}),
149
165
  map((dataFormatter) => {
150
- const mergedData = mergeOptionsWithDefault(dataFormatter, mergedPresetWithDefault.dataFormatter)
166
+ // const mergedData = mergeOptionsWithDefault(dataFormatter, mergedPresetWithDefault.dataFormatter)
151
167
 
152
- if (chartType === 'multiGrid' && (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList != null) {
153
- // multiGrid欄位為陣列,需要各別來merge預設值
154
- (mergedData as DataFormatterTypeMap<'multiGrid'>).gridList = (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList.map(d => {
155
- return mergeOptionsWithDefault(d, (mergedPresetWithDefault.dataFormatter as DataFormatterTypeMap<'multiGrid'>).gridList[0])
156
- })
157
- }
158
- return mergedData
168
+ // if (chartType === 'multiGrid' && (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList != null) {
169
+ // // multiGrid欄位為陣列,需要各別來merge預設值
170
+ // (mergedData as DataFormatterTypeMap<'multiGrid'>).gridList = (dataFormatter as DataFormatterPartialTypeMap<'multiGrid'>).gridList.map(d => {
171
+ // return mergeOptionsWithDefault(d, (mergedPresetWithDefault.dataFormatter as DataFormatterTypeMap<'multiGrid'>).gridList[0])
172
+ // })
173
+ // }
174
+ // return mergedData
175
+ return mergeDataFormatter(dataFormatter, mergedPresetWithDefault.dataFormatter, chartType)
159
176
  }),
160
177
  shareReplay(1)
161
178
  )
package/src/defaults.ts CHANGED
@@ -34,7 +34,6 @@ export const CHART_OPTIONS_DEFAULT: ChartOptionsPartial<any> = {
34
34
  // }
35
35
 
36
36
  // export const COLORS_DEFAULT = ['#67B7DC', '#6794DC', '#6771DC', '#8067DC', '#A367DC', '#C767DC', '#DC67CE', '#DC67AB', '#DC6788', '#DC6967', '#DC8C67', '#DCAF67']
37
- // @Q@ 桃園儀表板
38
37
  // ['#ff7ab9', '#66dec8', '#84c8ff', '#30ad1b', '#f8c43e', '#fa5640', '#9d79d7', '#ea4f98']
39
38
 
40
39
  export const PADDING_DEFAULT: Padding = {
@@ -4,28 +4,21 @@ import type { DataGrid, DataGridDatum } from '../types/DataGrid'
4
4
  import type { DataFormatterContext } from '../types/DataFormatter'
5
5
  import type { DataFormatterGrid } from '../types/DataFormatterGrid'
6
6
  import type { ComputedDataGrid, ComputedDatumGrid } from '../types/ComputedDataGrid'
7
+ import type { Layout } from '../types/Layout'
7
8
  import { formatValueToLabel, createDefaultDatumId, createDefaultSeriesLabel, createDefaultGroupLabel } from '../utils/orbchartsUtils'
8
9
  import { createAxisLinearScale, createAxisPointScale } from '../utils/d3Utils'
9
10
  import { getMinAndMaxValue, transposeData, createGridSeriesLabels, createGridGroupLabels, seriesColorPredicate } from '../utils/orbchartsUtils'
10
11
 
11
- interface DataGridDatumTemp extends DataGridDatum {
12
+ export interface DataGridDatumTemp extends DataGridDatum {
12
13
  // _color: string // 暫放的顏色資料
13
14
  _visible: boolean // 暫放的visible
14
15
  }
15
16
 
16
- export const computeGridData: ComputedDataFn<'grid'> = (context) => {
17
- return computeBaseGridData(context, 'grid', 0)
18
- }
19
-
20
- // 共用的計算grid資料 - 只有multiGrid計算時才會有gridIndex參數
21
- export const computeBaseGridData = (context: DataFormatterContext<'grid'>, chartType: 'grid' | 'multiGrid', gridIndex = 0) => {
17
+ export function createTransposedDataGrid (context: DataFormatterContext<'grid'>): DataGridDatumTemp[][] {
22
18
  const { data = [], dataFormatter, chartParams, layout } = context
23
19
  if (!data.length) {
24
20
  return []
25
21
  }
26
-
27
- let computedDataGrid: ComputedDatumGrid[][]
28
-
29
22
  try {
30
23
  // 最多的array length
31
24
  const maxArrayLength = data.reduce((prev, current) => {
@@ -88,120 +81,75 @@ export const computeBaseGridData = (context: DataFormatterContext<'grid'>, chart
88
81
  // 依seriesDirection轉置資料矩陣
89
82
  const transposedDataGrid = transposeData(dataFormatter.grid.gridData.seriesDirection, dataGrid)
90
83
 
91
- // -- groupScale --
92
- const { groupScale } = (() => {
93
- const groupAxisWidth = (dataFormatter.grid.groupAxis.position === 'top' || dataFormatter.grid.groupAxis.position === 'bottom')
94
- ? layout.width
95
- : layout.height
96
- const groupEndIndex = transposedDataGrid[0] ? transposedDataGrid[0].length - 1 : 0
97
- const groupScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
98
- maxValue: groupEndIndex,
99
- minValue: 0,
100
- axisWidth: groupAxisWidth,
101
- scaleDomain: [0, groupEndIndex], // 不使用dataFormatter設定
102
- scaleRange: [0, 1] // 不使用dataFormatter設定
103
- })
104
- return { groupScale }
105
- })()
106
-
107
-
108
-
109
- // const seriesColors = chartParams.colors[chartParams.colorScheme].series
110
-
111
- // const groupScaleDomain = [
112
- // dataFormatter.groupAxis.scaleDomain[0] === 'auto'
113
- // ? 0
114
- // : dataFormatter.groupAxis.scaleDomain[0],
115
- // dataFormatter.groupAxis.scaleDomain[1] === 'auto'
116
- // ? groupEndIndex
117
- // : dataFormatter.groupAxis.scaleDomain[1]
118
- // ]
119
-
84
+ return transposedDataGrid
85
+ } catch (e) {
86
+ return []
87
+ }
88
+ }
120
89
 
121
- // -- 依groupScale算visible --
122
- // 篩選顯示狀態
123
- // const scaleDomainFilter = (columnIndex: number) => {
124
- // // 如果groupIndex不在scale的範圍內則為false,不再做visibleFilter的判斷
125
- // if (columnIndex < groupScaleDomain[0] || columnIndex > groupScaleDomain[1]) {
126
- // return false
127
- // }
128
- // return true
129
- // }
130
- // transposedDataGrid.forEach((seriesData, seriesIndex) => {
131
- // seriesData.forEach((groupDatum, groupIndex) => {
132
- // // in-place修改visible
133
- // groupDatum._visible = groupDatum._visible == true && scaleDomainFilter(groupIndex) == true
134
- // ? true
135
- // : false // 兩者有一個false即為false
136
- // })
137
- // })
90
+ export function createGroupScale (transposedDataGrid: DataGridDatumTemp[][], dataFormatter: DataFormatterGrid, layout: Layout) {
91
+ const groupAxisWidth = (dataFormatter.grid.groupAxis.position === 'top' || dataFormatter.grid.groupAxis.position === 'bottom')
92
+ ? layout.width
93
+ : layout.height
94
+ const groupEndIndex = transposedDataGrid[0] ? transposedDataGrid[0].length - 1 : 0
95
+ const groupScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
96
+ maxValue: groupEndIndex,
97
+ minValue: 0,
98
+ axisWidth: groupAxisWidth,
99
+ scaleDomain: [0, groupEndIndex], // 不使用dataFormatter設定
100
+ scaleRange: [0, 1] // 不使用dataFormatter設定
101
+ })
102
+ return groupScale
103
+ }
138
104
 
139
- const seriesLabels = createGridSeriesLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex })
140
- const groupLabels = createGridGroupLabels({ transposedDataGrid, dataFormatter, chartType, gridIndex })
105
+ export function createSeriesValueScaleArr (transposedDataGrid: DataGridDatumTemp[][], dataFormatter: DataFormatterGrid, layout: Layout) {
106
+ const valueAxisWidth = (dataFormatter.grid.valueAxis.position === 'left' || dataFormatter.grid.valueAxis.position === 'right')
107
+ ? layout.height
108
+ : layout.width
109
+
110
+ const visibleData = transposedDataGrid.flat().filter(d => d._visible != false)
111
+ const [minValue, maxValue] = getMinAndMaxValue(visibleData)
112
+
113
+ return transposedDataGrid.map((seriesData, seriesIndex) => {
114
+ const valueScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
115
+ maxValue,
116
+ minValue,
117
+ axisWidth: valueAxisWidth,
118
+ scaleDomain: [minValue, maxValue], // 不使用dataFormatter設定
119
+ scaleRange: [0, 1] // 不使用dataFormatter設定
120
+ })
121
+ return valueScale
122
+ })
123
+ }
141
124
 
142
- // 每一個series的valueScale
143
- const seriesValueScaleArr = (() => {
144
- const valueAxisWidth = (dataFormatter.grid.valueAxis.position === 'left' || dataFormatter.grid.valueAxis.position === 'right')
145
- ? layout.height
146
- : layout.width
125
+ export const computeGridData: ComputedDataFn<'grid'> = (context) => {
126
+ const { data = [], dataFormatter, chartParams, layout } = context
127
+ if (!data.length) {
128
+ return []
129
+ }
147
130
 
148
- // // 每一個series的 [minValue, maxValue]
149
- // const minAndMaxValueArr = (() => {
150
- // // 有設定series定位,各別series計算各自的最大最小值
151
- // if (dataFormatter.grid.seriesSlotIndexes
152
- // && dataFormatter.grid.seriesSlotIndexes.length === transposedDataGrid.length
153
- // ) {
154
- // return transposedDataGrid
155
- // .map(series => {
156
- // const visibleData = series.filter(d => d._visible != false)
157
- // return getMinAndMaxValue(visibleData)
158
- // })
159
- // } else {
160
- // // 沒有設定series定位,全部資料一起計算最大值最小值
161
- // const visibleData = transposedDataGrid.flat().filter(d => d._visible != false)
162
- // const [minValue, maxValue] = getMinAndMaxValue(visibleData)
163
- // return transposedDataGrid
164
- // .map(series => {
165
- // return [minValue, maxValue]
166
- // })
167
- // }
168
- // })()
131
+ let computedDataGrid: ComputedDatumGrid[][]
169
132
 
170
- const visibleData = transposedDataGrid.flat().filter(d => d._visible != false)
171
- const [minValue, maxValue] = getMinAndMaxValue(visibleData)
172
-
173
- return transposedDataGrid.map((seriesData, seriesIndex) => {
174
- // const minValue = minAndMaxValueArr[seriesIndex][0]
175
- // const maxValue = minAndMaxValueArr[seriesIndex][1]
176
- const valueScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
177
- maxValue,
178
- minValue,
179
- axisWidth: valueAxisWidth,
180
- scaleDomain: [minValue, maxValue], // 不使用dataFormatter設定
181
- scaleRange: [0, 1] // 不使用dataFormatter設定
182
- })
183
- return valueScale
184
- })
185
- })()
133
+ try {
134
+
135
+ // 依seriesDirection轉置資料矩陣
136
+ const transposedDataGrid = createTransposedDataGrid(context)
186
137
 
187
- // const { valueScale } = (() => {
188
-
189
- // const visibleData = transposedDataGrid.flat().filter(d => d._visible != false)
190
- // const [minValue, maxValue] = getMinAndMaxValue(visibleData)
138
+ const groupScale = createGroupScale(transposedDataGrid, dataFormatter, layout)
191
139
 
192
- // const valueAxisWidth = (dataFormatter.grid.valueAxis.position === 'left' || dataFormatter.grid.valueAxis.position === 'right')
193
- // ? layout.height
194
- // : layout.width
140
+ const seriesLabels = createGridSeriesLabels({
141
+ transposedDataGrid,
142
+ dataFormatter,
143
+ chartType: 'grid'
144
+ })
145
+ const groupLabels = createGridGroupLabels({
146
+ transposedDataGrid,
147
+ dataFormatter,
148
+ chartType: 'grid'
149
+ })
195
150
 
196
- // const valueScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
197
- // maxValue,
198
- // minValue,
199
- // axisWidth: valueAxisWidth,
200
- // scaleDomain: [minValue, maxValue], // 不使用dataFormatter設定
201
- // scaleRange: [0, 1] // 不使用dataFormatter設定
202
- // })
203
- // return { valueScale }
204
- // })()
151
+ // 每一個series的valueScale
152
+ const seriesValueScaleArr = createSeriesValueScaleArr(transposedDataGrid, dataFormatter, layout)
205
153
 
206
154
  const zeroYArr = transposedDataGrid.map((series, seriesIndex) => {
207
155
  return seriesValueScaleArr[seriesIndex]!(0)
@@ -211,7 +159,7 @@ export const computeBaseGridData = (context: DataFormatterContext<'grid'>, chart
211
159
  computedDataGrid = transposedDataGrid.map((seriesData, seriesIndex) => {
212
160
  return seriesData.map((groupDatum, groupIndex) => {
213
161
 
214
- const defaultId = createDefaultDatumId(chartType, gridIndex, seriesIndex, groupIndex)
162
+ const defaultId = createDefaultDatumId('grid', 0, seriesIndex, groupIndex)
215
163
  // const visible = visibleFilter(groupDatum, seriesIndex, groupIndex, context)
216
164
  const groupLabel = groupLabels[groupIndex]
217
165
  const valueScale = seriesValueScaleArr[seriesIndex]
@@ -227,8 +175,8 @@ export const computeBaseGridData = (context: DataFormatterContext<'grid'>, chart
227
175
  data: groupDatum.data,
228
176
  value: groupDatum.value,
229
177
  // valueLabel: formatValueToLabel(groupDatum.value, dataFormatter.valueFormat),
230
- gridIndex,
231
- accSeriesIndex: seriesIndex, // 預設為seriesIndex
178
+ gridIndex: 0,
179
+ // accSeriesIndex: seriesIndex, // 預設為seriesIndex
232
180
  seriesIndex,
233
181
  seriesLabel: seriesLabels[seriesIndex],
234
182
  groupIndex,
@@ -1,10 +1,86 @@
1
1
  import type { DataGrid } from '../types/DataGrid'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
+ import type { ComputedDatumGrid } from '../types/ComputedDataGrid'
4
+ import type { DataFormatterContext } from '../types/DataFormatter'
3
5
  import type { DataFormatterGrid } from '../types/DataFormatterGrid'
4
6
  import type { ComputedDataMultiGrid } from '../types/ComputedDataMultiGrid'
5
- import { computeBaseGridData } from '../grid/computeGridData'
7
+ // import { computeBaseGridData } from '../grid/computeGridData'
6
8
  import { DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT } from '../defaults'
7
- import { seriesColorPredicate } from '../utils/orbchartsUtils'
9
+ import {
10
+ createDefaultDatumId,
11
+ seriesColorPredicate,
12
+ createGridSeriesLabels,
13
+ createMultiGridSeriesLabels,
14
+ createMultiGridGroupLabels
15
+ } from '../utils/orbchartsUtils'
16
+ import type { DataGridDatumTemp } from '../grid/computeGridData'
17
+ import { createTransposedDataGrid, createGroupScale, createSeriesValueScaleArr } from '../grid/computeGridData'
18
+
19
+ function createGridData ({ context, gridIndex, transposedDataGrid, gridSeriesLabels, SeriesLabelColorMap }: {
20
+ context: DataFormatterContext<'grid'>
21
+ gridIndex: number
22
+ transposedDataGrid: DataGridDatumTemp[][]
23
+ gridSeriesLabels: string[]
24
+ SeriesLabelColorMap: Map<string, string>
25
+ }) {
26
+ const { data = [], dataFormatter, chartParams, layout } = context
27
+ if (!data.length) {
28
+ return []
29
+ }
30
+
31
+ const groupScale = createGroupScale(transposedDataGrid, dataFormatter, layout)
32
+
33
+ // const seriesLabels = createGridSeriesLabels({ transposedDataGrid, dataFormatter, chartType: 'multiGrid', gridIndex })
34
+
35
+ const groupLabels = createMultiGridGroupLabels({ transposedDataGrid, dataFormatter, chartType: 'multiGrid', gridIndex })
36
+
37
+ // 每一個series的valueScale
38
+ const seriesValueScaleArr = createSeriesValueScaleArr(transposedDataGrid, dataFormatter, layout)
39
+
40
+ const zeroYArr = transposedDataGrid.map((series, seriesIndex) => {
41
+ return seriesValueScaleArr[seriesIndex]!(0)
42
+ })
43
+
44
+ let _index = 0
45
+ let computedDataGrid: ComputedDatumGrid[][] = transposedDataGrid.map((seriesData, seriesIndex) => {
46
+ return seriesData.map((groupDatum, groupIndex) => {
47
+
48
+ const defaultId = createDefaultDatumId('multiGrid', gridIndex, seriesIndex, groupIndex)
49
+ const groupLabel = groupLabels[groupIndex]
50
+ const seriesLabel = gridSeriesLabels[seriesIndex]
51
+ const valueScale = seriesValueScaleArr[seriesIndex]
52
+ const axisY = valueScale(groupDatum.value ?? 0)
53
+ const zeroY = zeroYArr[seriesIndex]
54
+
55
+ const computedDatum: ComputedDatumGrid = {
56
+ id: groupDatum.id ? groupDatum.id : defaultId,
57
+ index: _index,
58
+ label: groupDatum.label ? groupDatum.label : defaultId,
59
+ description: groupDatum.description ?? '',
60
+ data: groupDatum.data,
61
+ value: groupDatum.value,
62
+ gridIndex,
63
+ // accSeriesIndex: seriesIndex, // 預設為seriesIndex
64
+ seriesIndex,
65
+ seriesLabel,
66
+ groupIndex,
67
+ groupLabel,
68
+ // color: seriesColorPredicate(seriesIndex, chartParams),
69
+ color: SeriesLabelColorMap.get(seriesLabel),
70
+ axisX: groupScale(groupIndex),
71
+ axisY,
72
+ axisYFromZero: axisY - zeroY,
73
+ visible: groupDatum._visible
74
+ }
75
+
76
+ _index ++
77
+
78
+ return computedDatum
79
+ })
80
+ })
81
+
82
+ return computedDataGrid
83
+ }
8
84
 
9
85
  export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], dataFormatter, chartParams, layout }) => {
10
86
  if (!data.length) {
@@ -16,43 +92,78 @@ export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], d
16
92
  try {
17
93
  const defaultGrid = dataFormatter.gridList[0] || DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
18
94
 
19
- // 計算每個grid的資料
20
- multiGridData = data.map((gridData, gridIndex) => {
95
+ // 計算每個grid的dataFormatter
96
+ const gridDataFormatterList: DataFormatterGrid[] = data.map((gridData, gridIndex) => {
21
97
  const currentDataFormatterGrid = dataFormatter.gridList[gridIndex] || defaultGrid
22
98
 
23
- return computeBaseGridData(
24
- {
25
- data: gridData,
26
- dataFormatter: {
27
- type: 'grid',
28
- grid: {
29
- ...currentDataFormatterGrid
30
- },
31
- container: {
32
- ...dataFormatter.container
33
- }
34
- },
35
- chartParams,
36
- layout
99
+ return {
100
+ type: 'grid',
101
+ grid: {
102
+ ...currentDataFormatterGrid
37
103
  },
38
- 'multiGrid',
39
- gridIndex
40
- )
104
+ container: {
105
+ ...dataFormatter.container
106
+ }
107
+ }
108
+ })
109
+
110
+ const gridContextList = data.map((gridData, gridIndex) => {
111
+ // grid context
112
+ return {
113
+ data: gridData,
114
+ dataFormatter: gridDataFormatterList[gridIndex],
115
+ chartParams,
116
+ layout
117
+ }
118
+ })
119
+
120
+ const transposedDataGridList = data.map((gridData, gridIndex) => {
121
+ // 依seriesDirection轉置資料矩陣
122
+ return createTransposedDataGrid(gridContextList[gridIndex])
123
+ })
124
+
125
+ const createSeriesLabelsFn = (() => {
126
+ const SlotIndexSet = new Set(gridDataFormatterList.map(d => d.grid.slotIndex))
127
+ // 判斷是否有重疊的grid
128
+ const isOverlappingMultiGrid = SlotIndexSet.size !== gridDataFormatterList.length
129
+ return isOverlappingMultiGrid
130
+ ? createMultiGridSeriesLabels // 有重疊的grid則使用「不同」的seriesLabels
131
+ : createGridSeriesLabels // 沒有重疊的grid則使用「相同」的seriesLabels
132
+ })()
133
+
134
+
135
+ const multiGridSeriesLabels = transposedDataGridList
136
+ .map((gridData, gridIndex) => {
137
+ return createSeriesLabelsFn({
138
+ transposedDataGrid: gridData,
139
+ dataFormatter: gridDataFormatterList[gridIndex],
140
+ chartType: 'multiGrid',
141
+ gridIndex
142
+ } as any)
143
+ })
144
+
145
+ const SeriesLabelColorMap: Map<string, string> = new Map()
146
+ let accIndex = 0
147
+ multiGridSeriesLabels.flat().forEach((label, i) => {
148
+ if (!SeriesLabelColorMap.has(label)) {
149
+ const color = seriesColorPredicate(accIndex, chartParams)
150
+ SeriesLabelColorMap.set(label, color)
151
+ accIndex ++
152
+ }
41
153
  })
42
154
 
43
- // 修正多個grid的欄位資料
44
- let accSeriesIndex = -1
45
- multiGridData = multiGridData.map((gridData, i) => {
46
- return gridData.map((series, j) => {
47
- accSeriesIndex ++
48
- return series.map(d => {
49
- d.accSeriesIndex = accSeriesIndex
50
- d.color = seriesColorPredicate(accSeriesIndex, chartParams)
51
- return d
52
- })
155
+ // 計算每個grid的資料
156
+ multiGridData = data.map((gridData, gridIndex) => {
157
+ return createGridData({
158
+ context: gridContextList[gridIndex],
159
+ gridIndex,
160
+ transposedDataGrid: transposedDataGridList[gridIndex],
161
+ gridSeriesLabels: multiGridSeriesLabels[gridIndex],
162
+ SeriesLabelColorMap
53
163
  })
54
164
  })
55
165
 
166
+
56
167
  } catch (e) {
57
168
  // console.error(e)
58
169
  throw Error(e)
@@ -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) {
@@ -2,7 +2,7 @@ import { ComputedDatumBase, ComputedDatumSeriesValue } from './ComputedData'
2
2
 
3
3
  export interface ComputedDatumGrid
4
4
  extends ComputedDatumBase, ComputedDatumSeriesValue {
5
- accSeriesIndex: number // 每一個grid累加的seriesIndex
5
+ // accSeriesIndex: number // 每一個grid累加的seriesIndex
6
6
  gridIndex: number
7
7
  groupIndex: number
8
8
  groupLabel: 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
  }