@orbcharts/core 3.0.0-alpha.33 → 3.0.0-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/orbcharts-core.es.js +1852 -1776
- package/dist/orbcharts-core.umd.js +2 -2
- package/dist/src/grid/computeGridData.d.ts +10 -3
- package/dist/src/types/ComputedDataGrid.d.ts +0 -1
- package/dist/src/utils/commonUtils.d.ts +1 -1
- package/dist/src/utils/orbchartsUtils.d.ts +12 -2
- package/package.json +1 -1
- package/src/base/createBaseChart.ts +26 -9
- package/src/defaults.ts +0 -1
- package/src/grid/computeGridData.ts +67 -119
- package/src/multiGrid/computeMultiGridData.ts +142 -31
- package/src/multiValue/computeMultiValueData.ts +1 -0
- package/src/tree/computeTreeData.ts +2 -2
- package/src/types/ComputedDataGrid.ts +1 -1
- package/src/utils/commonUtils.ts +6 -6
- package/src/utils/orbchartsUtils.ts +41 -7
|
@@ -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
|
|
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
|
|
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
|
@@ -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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
140
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
125
|
+
export const computeGridData: ComputedDataFn<'grid'> = (context) => {
|
|
126
|
+
const { data = [], dataFormatter, chartParams, layout } = context
|
|
127
|
+
if (!data.length) {
|
|
128
|
+
return []
|
|
129
|
+
}
|
|
147
130
|
|
|
148
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
//
|
|
197
|
-
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
95
|
+
// 計算每個grid的dataFormatter
|
|
96
|
+
const gridDataFormatterList: DataFormatterGrid[] = data.map((gridData, gridIndex) => {
|
|
21
97
|
const currentDataFormatterGrid = dataFormatter.gridList[gridIndex] || defaultGrid
|
|
22
98
|
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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 {
|
|
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 (
|
|
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
|
package/src/utils/commonUtils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// import * as d3 from 'd3'
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
export function
|
|
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 (
|
|
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 (
|
|
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
|
}
|