@orbcharts/core 3.0.7 → 4.0.0-pre-alpha.1
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 +2795 -6591
- package/dist/orbcharts-core.umd.js +6 -6
- package/dist/src/OrbCharts.d.ts +18 -0
- package/dist/src/chart/createChart.d.ts +3 -0
- package/dist/src/chart/createGraphData.d.ts +3 -0
- package/dist/src/chart/createGridData.d.ts +3 -0
- package/dist/src/chart/createMultivariateData.d.ts +3 -0
- package/dist/src/chart/createSeriesData.d.ts +3 -0
- package/dist/src/chart/createTreeData.d.ts +3 -0
- package/dist/src/chart/defaults.d.ts +5 -0
- package/dist/src/defineCanvasLayer.d.ts +16 -0
- package/dist/src/defineCanvasPlugin.d.ts +22 -0
- package/dist/src/defineSVGLayer.d.ts +16 -0
- package/dist/src/defineSVGPlugin.d.ts +22 -0
- package/dist/src/index.d.ts +6 -14
- package/dist/src/layer/createLayer.d.ts +3 -0
- package/dist/src/plugin/createPlugin.d.ts +3 -0
- package/dist/src/test/createGraphData.test.d.ts +1 -0
- package/dist/src/test/createTreeData.test.d.ts +1 -0
- package/dist/src/test/simple-graph-test.d.ts +74 -0
- package/dist/src/test/simple-tree-test.d.ts +13 -0
- package/dist/src/types/Chart.d.ts +39 -0
- package/dist/src/types/ChartContext.d.ts +27 -0
- package/dist/src/types/Common.d.ts +3 -0
- package/dist/src/types/Encoding.d.ts +33 -0
- package/dist/src/types/Event.d.ts +12 -0
- package/dist/src/types/Layers.d.ts +55 -0
- package/dist/src/types/ModelData.d.ts +70 -0
- package/dist/src/types/Plugin.d.ts +39 -0
- package/dist/src/types/RawData.d.ts +18 -0
- package/dist/src/types/RenderData.d.ts +4 -0
- package/dist/src/types/Theme.d.ts +17 -0
- package/dist/src/types/Validator.d.ts +20 -0
- package/dist/src/types/index.d.ts +12 -0
- package/dist/src/utils/aggregateUtils.d.ts +37 -0
- package/dist/src/utils/colorUtils.d.ts +22 -0
- package/dist/src/utils/commonUtils.d.ts +3 -5
- package/dist/src/utils/dom-lifecycle.d.ts +37 -0
- package/dist/src/utils/dom.d.ts +6 -0
- package/dist/src/utils/index.d.ts +5 -1
- package/dist/src/utils/observables.d.ts +1 -25
- package/dist/src/utils/orbchartsUtils.d.ts +2 -53
- package/dist/src/utils/validator.d.ts +2 -2
- package/dist/test/aggregateTest.d.ts +1 -0
- package/package.json +26 -13
- package/src/OrbCharts.ts +35 -0
- package/src/chart/createChart.ts +997 -0
- package/src/chart/createGraphData.ts +391 -0
- package/src/chart/createGridData.ts +247 -0
- package/src/chart/createMultivariateData.ts +181 -0
- package/src/chart/createSeriesData.ts +297 -0
- package/src/chart/createTreeData.ts +344 -0
- package/src/chart/defaults.ts +100 -0
- package/src/defineCanvasLayer.ts +24 -0
- package/src/defineCanvasPlugin.ts +39 -0
- package/src/defineSVGLayer.ts +24 -0
- package/src/defineSVGPlugin.ts +39 -0
- package/src/index.ts +6 -18
- package/src/layer/createLayer.ts +138 -0
- package/src/plugin/createPlugin.ts +470 -0
- package/src/test/createGraphData.test.ts +103 -0
- package/src/test/createTreeData.test.ts +97 -0
- package/src/test/simple-graph-test.js +51 -0
- package/src/test/simple-tree-test.js +58 -0
- package/src/types/Chart.ts +62 -0
- package/src/types/ChartContext.ts +42 -0
- package/src/types/Common.ts +5 -0
- package/src/types/Encoding.ts +43 -0
- package/src/types/Event.ts +26 -0
- package/src/types/Layers.ts +93 -0
- package/src/types/ModelData.ts +95 -0
- package/src/types/Plugin.ts +98 -0
- package/src/types/RawData.ts +67 -0
- package/src/types/RenderData.ts +16 -0
- package/src/types/Theme.ts +21 -0
- package/src/types/Validator.ts +36 -0
- package/src/types/index.ts +12 -0
- package/src/utils/aggregateUtils.ts +99 -0
- package/src/utils/colorUtils.ts +63 -0
- package/src/utils/commonUtils.ts +12 -11
- package/src/utils/dom-lifecycle.ts +164 -0
- package/src/utils/dom.ts +55 -0
- package/src/utils/index.ts +6 -2
- package/src/utils/observables.ts +1 -292
- package/src/utils/orbchartsUtils.ts +6 -393
- package/src/utils/validator.ts +15 -14
- package/dist/lib/core-types.d.ts +0 -1
- package/dist/src/AbstractChart.d.ts +0 -19
- package/dist/src/GridChart.d.ts +0 -6
- package/dist/src/MultiGridChart.d.ts +0 -6
- package/dist/src/MultiValueChart.d.ts +0 -6
- package/dist/src/RelationshipChart.d.ts +0 -6
- package/dist/src/SeriesChart.d.ts +0 -6
- package/dist/src/TreeChart.d.ts +0 -6
- package/dist/src/base/createBaseChart.d.ts +0 -3
- package/dist/src/base/createBasePlugin.d.ts +0 -3
- package/dist/src/base/validators/chartOptionsValidator.d.ts +0 -3
- package/dist/src/base/validators/chartParamsValidator.d.ts +0 -3
- package/dist/src/base/validators/elementValidator.d.ts +0 -3
- package/dist/src/base/validators/pluginsValidator.d.ts +0 -3
- package/dist/src/defaults.d.ts +0 -25
- package/dist/src/defineGridPlugin.d.ts +0 -1
- package/dist/src/defineMultiGridPlugin.d.ts +0 -1
- package/dist/src/defineMultiValuePlugin.d.ts +0 -1
- package/dist/src/defineNoneDataPlugin.d.ts +0 -1
- package/dist/src/defineRelationshipPlugin.d.ts +0 -1
- package/dist/src/defineSeriesPlugin.d.ts +0 -1
- package/dist/src/defineTreePlugin.d.ts +0 -1
- package/dist/src/grid/computedDataFn.d.ts +0 -4
- package/dist/src/grid/contextObserverCallback.d.ts +0 -3
- package/dist/src/grid/dataFormatterValidator.d.ts +0 -3
- package/dist/src/grid/dataValidator.d.ts +0 -3
- package/dist/src/grid/gridObservables.d.ts +0 -64
- package/dist/src/multiGrid/computedDataFn.d.ts +0 -3
- package/dist/src/multiGrid/contextObserverCallback.d.ts +0 -3
- package/dist/src/multiGrid/dataFormatterValidator.d.ts +0 -3
- package/dist/src/multiGrid/dataValidator.d.ts +0 -3
- package/dist/src/multiGrid/multiGridObservables.d.ts +0 -16
- package/dist/src/multiValue/computedDataFn.d.ts +0 -3
- package/dist/src/multiValue/contextObserverCallback.d.ts +0 -3
- package/dist/src/multiValue/dataFormatterValidator.d.ts +0 -3
- package/dist/src/multiValue/dataValidator.d.ts +0 -3
- package/dist/src/multiValue/multiValueObservables.d.ts +0 -130
- package/dist/src/relationship/computedDataFn.d.ts +0 -3
- package/dist/src/relationship/contextObserverCallback.d.ts +0 -3
- package/dist/src/relationship/dataFormatterValidator.d.ts +0 -3
- package/dist/src/relationship/dataValidator.d.ts +0 -3
- package/dist/src/relationship/relationshipObservables.d.ts +0 -13
- package/dist/src/series/computedDataFn.d.ts +0 -3
- package/dist/src/series/contextObserverCallback.d.ts +0 -3
- package/dist/src/series/dataFormatterValidator.d.ts +0 -3
- package/dist/src/series/dataValidator.d.ts +0 -3
- package/dist/src/series/seriesObservables.d.ts +0 -37
- package/dist/src/tree/computedDataFn.d.ts +0 -3
- package/dist/src/tree/contextObserverCallback.d.ts +0 -3
- package/dist/src/tree/dataFormatterValidator.d.ts +0 -3
- package/dist/src/tree/dataValidator.d.ts +0 -3
- package/dist/src/tree/treeObservables.d.ts +0 -10
- package/dist/src/utils/d3Scale.d.ts +0 -28
- package/lib/core-types.ts +0 -7
- package/src/AbstractChart.ts +0 -57
- package/src/GridChart.ts +0 -25
- package/src/MultiGridChart.ts +0 -25
- package/src/MultiValueChart.ts +0 -25
- package/src/RelationshipChart.ts +0 -25
- package/src/SeriesChart.ts +0 -25
- package/src/TreeChart.ts +0 -25
- package/src/base/createBaseChart.ts +0 -524
- package/src/base/createBasePlugin.ts +0 -154
- package/src/base/validators/chartOptionsValidator.ts +0 -24
- package/src/base/validators/chartParamsValidator.ts +0 -134
- package/src/base/validators/elementValidator.ts +0 -14
- package/src/base/validators/pluginsValidator.ts +0 -15
- package/src/defaults.ts +0 -284
- package/src/defineGridPlugin.ts +0 -3
- package/src/defineMultiGridPlugin.ts +0 -3
- package/src/defineMultiValuePlugin.ts +0 -3
- package/src/defineNoneDataPlugin.ts +0 -4
- package/src/defineRelationshipPlugin.ts +0 -3
- package/src/defineSeriesPlugin.ts +0 -3
- package/src/defineTreePlugin.ts +0 -3
- package/src/grid/computedDataFn.ts +0 -129
- package/src/grid/contextObserverCallback.ts +0 -209
- package/src/grid/dataFormatterValidator.ts +0 -126
- package/src/grid/dataValidator.ts +0 -13
- package/src/grid/gridObservables.ts +0 -699
- package/src/multiGrid/computedDataFn.ts +0 -123
- package/src/multiGrid/contextObserverCallback.ts +0 -109
- package/src/multiGrid/dataFormatterValidator.ts +0 -121
- package/src/multiGrid/dataValidator.ts +0 -13
- package/src/multiGrid/multiGridObservables.ts +0 -367
- package/src/multiValue/computedDataFn.ts +0 -113
- package/src/multiValue/contextObserverCallback.ts +0 -328
- package/src/multiValue/dataFormatterValidator.ts +0 -95
- package/src/multiValue/dataValidator.ts +0 -13
- package/src/multiValue/multiValueObservables.ts +0 -865
- package/src/relationship/computedDataFn.ts +0 -159
- package/src/relationship/contextObserverCallback.ts +0 -80
- package/src/relationship/dataFormatterValidator.ts +0 -14
- package/src/relationship/dataValidator.ts +0 -14
- package/src/relationship/relationshipObservables.ts +0 -85
- package/src/series/computedDataFn.ts +0 -88
- package/src/series/contextObserverCallback.ts +0 -132
- package/src/series/dataFormatterValidator.ts +0 -47
- package/src/series/dataValidator.ts +0 -13
- package/src/series/seriesObservables.ts +0 -210
- package/src/tree/computedDataFn.ts +0 -129
- package/src/tree/contextObserverCallback.ts +0 -58
- package/src/tree/dataFormatterValidator.ts +0 -14
- package/src/tree/dataValidator.ts +0 -14
- package/src/tree/treeObservables.ts +0 -106
- package/src/utils/d3Scale.ts +0 -198
- package/tsconfig.base.json +0 -14
- package/tsconfig.json +0 -3
- package/vite-env.d.ts +0 -7
- package/vite.config.js +0 -23
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createGraphData } from '../chart/createGraphData'
|
|
2
|
+
import type { RawDataColumn, Encoding, Theme } from '../types'
|
|
3
|
+
|
|
4
|
+
// 測試資料:包含 nodes 和 edges
|
|
5
|
+
const testRawData: RawDataColumn[] = [
|
|
6
|
+
// Nodes
|
|
7
|
+
{ id: 'node1', name: 'Node 1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 10 },
|
|
8
|
+
{ id: 'node2', name: 'Node 2', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 20 },
|
|
9
|
+
{ id: 'node3', name: 'Node 3', dataset: 'dataset1', series: 'series2', category: 'cat1', value: 15 },
|
|
10
|
+
{ id: 'node4', name: 'Node 4', dataset: 'dataset1', series: 'series2', category: 'cat2', value: 25 },
|
|
11
|
+
|
|
12
|
+
// Edges
|
|
13
|
+
{ id: 'edge1', name: 'Edge 1', source: 'node1', target: 'node2', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 5 },
|
|
14
|
+
{ id: 'edge2', name: 'Edge 2', source: 'node2', target: 'node3', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 8 },
|
|
15
|
+
{ id: 'edge3', name: 'Edge 3', source: 'node3', target: 'node4', dataset: 'dataset1', series: 'series2', category: 'cat1', value: 12 },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
const testEncoding: Encoding = {
|
|
19
|
+
dataset: { from: 'dataset', sort: 'original' },
|
|
20
|
+
series: { from: 'series', sort: 'original' },
|
|
21
|
+
category: { from: 'category', sort: 'original' },
|
|
22
|
+
value: { from: 'value', sort: 'original', aggregate: 'none' },
|
|
23
|
+
multivariate: [],
|
|
24
|
+
color: { from: 'category' }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const testTheme: Theme = {
|
|
28
|
+
colorScheme: 'light',
|
|
29
|
+
colors: {
|
|
30
|
+
light: {
|
|
31
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
32
|
+
primary: '#000000',
|
|
33
|
+
secondary: '#666666',
|
|
34
|
+
dataContrast: ['#ffffff', '#000000'],
|
|
35
|
+
background: '#ffffff'
|
|
36
|
+
},
|
|
37
|
+
dark: {
|
|
38
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
39
|
+
primary: '#ffffff',
|
|
40
|
+
secondary: '#999999',
|
|
41
|
+
dataContrast: ['#000000', '#ffffff'],
|
|
42
|
+
background: '#000000'
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
fontSize: 12
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 測試基本功能
|
|
49
|
+
console.log('=== Test createGraphData ===')
|
|
50
|
+
|
|
51
|
+
const result = createGraphData(testRawData, testEncoding, testTheme)
|
|
52
|
+
console.log('Result length:', result.length)
|
|
53
|
+
console.log('First dataset nodes:', result[0]?.nodes.length)
|
|
54
|
+
console.log('First dataset edges:', result[0]?.edges.length)
|
|
55
|
+
|
|
56
|
+
// 檢查 nodes 結構
|
|
57
|
+
console.log('\n=== Nodes Structure ===')
|
|
58
|
+
result[0]?.nodes.forEach((node, i) => {
|
|
59
|
+
console.log(`Node ${i}:`, {
|
|
60
|
+
id: node.id,
|
|
61
|
+
name: node.name,
|
|
62
|
+
series: node.series,
|
|
63
|
+
category: node.category,
|
|
64
|
+
value: node.value,
|
|
65
|
+
index: node.index
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// 檢查 edges 結構
|
|
70
|
+
console.log('\n=== Edges Structure ===')
|
|
71
|
+
result[0]?.edges.forEach((edge, i) => {
|
|
72
|
+
console.log(`Edge ${i}:`, {
|
|
73
|
+
id: edge.id,
|
|
74
|
+
name: edge.name,
|
|
75
|
+
source: edge.source,
|
|
76
|
+
target: edge.target,
|
|
77
|
+
sourceIndex: edge.sourceIndex,
|
|
78
|
+
targetIndex: edge.targetIndex,
|
|
79
|
+
value: edge.value
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// 測試聚合功能
|
|
84
|
+
console.log('\n=== Test Aggregation ===')
|
|
85
|
+
const aggregateEncoding: Encoding = {
|
|
86
|
+
...testEncoding,
|
|
87
|
+
value: { from: 'value', sort: 'original', aggregate: 'sum' }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const aggregatedResult = createGraphData(testRawData, aggregateEncoding, testTheme)
|
|
91
|
+
console.log('Aggregated nodes count:', aggregatedResult[0]?.nodes.length)
|
|
92
|
+
console.log('Aggregated edges count:', aggregatedResult[0]?.edges.length)
|
|
93
|
+
|
|
94
|
+
console.log('\nAggregated nodes:')
|
|
95
|
+
aggregatedResult[0]?.nodes.forEach((node, i) => {
|
|
96
|
+
console.log(`Node ${i}:`, {
|
|
97
|
+
id: node.id,
|
|
98
|
+
name: node.name,
|
|
99
|
+
series: node.series,
|
|
100
|
+
category: node.category,
|
|
101
|
+
value: node.value
|
|
102
|
+
})
|
|
103
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createTreeData } from '../chart/createTreeData'
|
|
2
|
+
import type { RawDataColumn, Encoding, Theme } from '../types'
|
|
3
|
+
|
|
4
|
+
// 測試資料:樹狀結構
|
|
5
|
+
const testRawData: RawDataColumn[] = [
|
|
6
|
+
// 根節點
|
|
7
|
+
{ id: 'root', name: 'Root Node', parent: null, dataset: 'dataset1', series: 'series1', category: 'cat1', value: 100 },
|
|
8
|
+
|
|
9
|
+
// 第一層子節點
|
|
10
|
+
{ id: 'child1', name: 'Child 1', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 40 },
|
|
11
|
+
{ id: 'child2', name: 'Child 2', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 60 },
|
|
12
|
+
|
|
13
|
+
// 第二層子節點
|
|
14
|
+
{ id: 'grandchild1', name: 'Grandchild 1', parent: 'child1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 20 },
|
|
15
|
+
{ id: 'grandchild2', name: 'Grandchild 2', parent: 'child1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 20 },
|
|
16
|
+
{ id: 'grandchild3', name: 'Grandchild 3', parent: 'child2', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 30 },
|
|
17
|
+
{ id: 'grandchild4', name: 'Grandchild 4', parent: 'child2', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 30 },
|
|
18
|
+
|
|
19
|
+
// 第二個 series 的資料
|
|
20
|
+
{ id: 'root2', name: 'Root Node 2', parent: null, dataset: 'dataset1', series: 'series2', category: 'cat1', value: 80 },
|
|
21
|
+
{ id: 'child3', name: 'Child 3', parent: 'root2', dataset: 'dataset1', series: 'series2', category: 'cat1', value: 80 },
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
const testEncoding: Encoding = {
|
|
25
|
+
dataset: { from: 'dataset', sort: 'original' },
|
|
26
|
+
series: { from: 'series', sort: 'original' },
|
|
27
|
+
category: { from: 'category', sort: 'original' },
|
|
28
|
+
value: { from: 'value', sort: 'original', aggregate: 'none' },
|
|
29
|
+
multivariate: [],
|
|
30
|
+
color: { from: 'category' }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const testTheme: Theme = {
|
|
34
|
+
colorScheme: 'light',
|
|
35
|
+
colors: {
|
|
36
|
+
light: {
|
|
37
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
38
|
+
primary: '#000000',
|
|
39
|
+
secondary: '#666666',
|
|
40
|
+
dataContrast: ['#ffffff', '#000000'],
|
|
41
|
+
background: '#ffffff'
|
|
42
|
+
},
|
|
43
|
+
dark: {
|
|
44
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
45
|
+
primary: '#ffffff',
|
|
46
|
+
secondary: '#999999',
|
|
47
|
+
dataContrast: ['#000000', '#ffffff'],
|
|
48
|
+
background: '#000000'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
fontSize: 12
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 遞迴列印樹狀結構的函數
|
|
55
|
+
function printTree(node: any, indent: string = ''): void {
|
|
56
|
+
console.log(`${indent}${node.name} (id: ${node.id}, depth: ${node.depth}, seq: ${node.seq}, value: ${node.value}, parent: ${node.parent})`)
|
|
57
|
+
if (node.children && node.children.length > 0) {
|
|
58
|
+
node.children.forEach((child: any) => {
|
|
59
|
+
printTree(child, indent + ' ')
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 測試基本功能
|
|
65
|
+
console.log('=== Test createTreeData ===')
|
|
66
|
+
|
|
67
|
+
const result = createTreeData(testRawData, testEncoding, testTheme)
|
|
68
|
+
console.log('Result length:', result.length)
|
|
69
|
+
|
|
70
|
+
// 列印每個樹的結構
|
|
71
|
+
result.forEach((tree, index) => {
|
|
72
|
+
console.log(`\n=== Tree ${index + 1} (Series: ${tree.series}) ===`)
|
|
73
|
+
printTree(tree)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// 測試聚合功能
|
|
77
|
+
console.log('\n=== Test Aggregation ===')
|
|
78
|
+
|
|
79
|
+
// 建立有重複 id 的測試資料
|
|
80
|
+
const duplicateRawData: RawDataColumn[] = [
|
|
81
|
+
{ id: 'root', name: 'Root Node', parent: null, dataset: 'dataset1', series: 'series1', category: 'cat1', value: 50 },
|
|
82
|
+
{ id: 'root', name: 'Root Node', parent: null, dataset: 'dataset1', series: 'series1', category: 'cat1', value: 50 }, // 重複
|
|
83
|
+
{ id: 'child1', name: 'Child 1', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 20 },
|
|
84
|
+
{ id: 'child1', name: 'Child 1', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 30 }, // 重複
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
const aggregateEncoding: Encoding = {
|
|
88
|
+
...testEncoding,
|
|
89
|
+
value: { from: 'value', sort: 'original', aggregate: 'sum' }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const aggregatedResult = createTreeData(duplicateRawData, aggregateEncoding, testTheme)
|
|
93
|
+
console.log('\nAggregated tree:')
|
|
94
|
+
aggregatedResult.forEach((tree, index) => {
|
|
95
|
+
console.log(`\n=== Aggregated Tree ${index + 1} ===`)
|
|
96
|
+
printTree(tree)
|
|
97
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Simple test for createGraphData functionality
|
|
2
|
+
// This is a minimal test to verify the basic structure
|
|
3
|
+
|
|
4
|
+
const testRawData = [
|
|
5
|
+
// Nodes
|
|
6
|
+
{ id: 'node1', name: 'Node 1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 10 },
|
|
7
|
+
{ id: 'node2', name: 'Node 2', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 20 },
|
|
8
|
+
{ id: 'node3', name: 'Node 3', dataset: 'dataset1', series: 'series2', category: 'cat1', value: 15 },
|
|
9
|
+
{ id: 'node4', name: 'Node 4', dataset: 'dataset1', series: 'series2', category: 'cat2', value: 25 },
|
|
10
|
+
|
|
11
|
+
// Edges
|
|
12
|
+
{ id: 'edge1', name: 'Edge 1', source: 'node1', target: 'node2', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 5 },
|
|
13
|
+
{ id: 'edge2', name: 'Edge 2', source: 'node2', target: 'node3', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 8 },
|
|
14
|
+
{ id: 'edge3', name: 'Edge 3', source: 'node3', target: 'node4', dataset: 'dataset1', series: 'series2', category: 'cat1', value: 12 },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
const testEncoding = {
|
|
18
|
+
dataset: { from: 'dataset', sort: 'original' },
|
|
19
|
+
series: { from: 'series', sort: 'original' },
|
|
20
|
+
category: { from: 'category', sort: 'original' },
|
|
21
|
+
value: { from: 'value', sort: 'original', aggregate: 'none' },
|
|
22
|
+
multivariate: [],
|
|
23
|
+
color: { from: 'category' }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const testTheme = {
|
|
27
|
+
colorScheme: 'light',
|
|
28
|
+
colors: {
|
|
29
|
+
light: {
|
|
30
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
31
|
+
primary: '#000000',
|
|
32
|
+
secondary: '#666666',
|
|
33
|
+
dataContrast: ['#ffffff', '#000000'],
|
|
34
|
+
background: '#ffffff'
|
|
35
|
+
},
|
|
36
|
+
dark: {
|
|
37
|
+
data: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],
|
|
38
|
+
primary: '#ffffff',
|
|
39
|
+
secondary: '#999999',
|
|
40
|
+
dataContrast: ['#000000', '#ffffff'],
|
|
41
|
+
background: '#000000'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
fontSize: 12
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log('Test data ready')
|
|
48
|
+
console.log('Raw data has', testRawData.length, 'items')
|
|
49
|
+
console.log('Nodes:', testRawData.filter(d => !d.source && !d.target).length)
|
|
50
|
+
console.log('Edges:', testRawData.filter(d => d.source && d.target).length)
|
|
51
|
+
console.log('Test completed successfully!')
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Simple test for createTreeData functionality
|
|
2
|
+
// This verifies the basic tree structure logic
|
|
3
|
+
|
|
4
|
+
const testRawData = [
|
|
5
|
+
// 根節點
|
|
6
|
+
{ id: 'root', name: 'Root Node', parent: null, dataset: 'dataset1', series: 'series1', category: 'cat1', value: 100 },
|
|
7
|
+
|
|
8
|
+
// 第一層子節點
|
|
9
|
+
{ id: 'child1', name: 'Child 1', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 40 },
|
|
10
|
+
{ id: 'child2', name: 'Child 2', parent: 'root', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 60 },
|
|
11
|
+
|
|
12
|
+
// 第二層子節點
|
|
13
|
+
{ id: 'grandchild1', name: 'Grandchild 1', parent: 'child1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 20 },
|
|
14
|
+
{ id: 'grandchild2', name: 'Grandchild 2', parent: 'child1', dataset: 'dataset1', series: 'series1', category: 'cat1', value: 20 },
|
|
15
|
+
{ id: 'grandchild3', name: 'Grandchild 3', parent: 'child2', dataset: 'dataset1', series: 'series1', category: 'cat2', value: 30 },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
// 測試樹狀結構邏輯
|
|
19
|
+
const nodeMap = new Map()
|
|
20
|
+
testRawData.forEach(d => {
|
|
21
|
+
nodeMap.set(d.id, d)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const rootNodes = []
|
|
25
|
+
const childrenMap = new Map()
|
|
26
|
+
|
|
27
|
+
testRawData.forEach(node => {
|
|
28
|
+
if (node.parent === null) {
|
|
29
|
+
rootNodes.push(node)
|
|
30
|
+
} else {
|
|
31
|
+
if (!childrenMap.has(node.parent)) {
|
|
32
|
+
childrenMap.set(node.parent, [])
|
|
33
|
+
}
|
|
34
|
+
childrenMap.get(node.parent).push(node)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
function printTree(node, depth = 0) {
|
|
39
|
+
const indent = ' '.repeat(depth)
|
|
40
|
+
console.log(`${indent}${node.name} (id: ${node.id}, parent: ${node.parent})`)
|
|
41
|
+
|
|
42
|
+
const children = childrenMap.get(node.id) || []
|
|
43
|
+
children.forEach(child => {
|
|
44
|
+
printTree(child, depth + 1)
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log('=== Tree Structure Test ===')
|
|
49
|
+
console.log('Total nodes:', testRawData.length)
|
|
50
|
+
console.log('Root nodes:', rootNodes.length)
|
|
51
|
+
console.log('Children map size:', childrenMap.size)
|
|
52
|
+
|
|
53
|
+
console.log('\nTree structure:')
|
|
54
|
+
rootNodes.forEach(root => {
|
|
55
|
+
printTree(root)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
console.log('\nTest completed successfully!')
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DeepPartial,
|
|
3
|
+
ChartContext,
|
|
4
|
+
Encoding,
|
|
5
|
+
PluginEntity,
|
|
6
|
+
RawData,
|
|
7
|
+
Theme
|
|
8
|
+
} from './index'
|
|
9
|
+
|
|
10
|
+
export interface SizeConfig {
|
|
11
|
+
width: number | 'auto'
|
|
12
|
+
height: number | 'auto'
|
|
13
|
+
resizeDebounce: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// export interface ChartDefaults {
|
|
17
|
+
// theme: Theme
|
|
18
|
+
// encoding: Encoding
|
|
19
|
+
// }
|
|
20
|
+
|
|
21
|
+
export interface ChartOptions {
|
|
22
|
+
size: SizeConfig
|
|
23
|
+
// defaults: ChartDefaults
|
|
24
|
+
theme: Theme
|
|
25
|
+
data: RawData
|
|
26
|
+
encoding: Encoding
|
|
27
|
+
plugins: PluginEntity<any, any, any>[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PartialChartOptions {
|
|
31
|
+
size?: Partial<SizeConfig>
|
|
32
|
+
theme?: DeepPartial<Theme>
|
|
33
|
+
data?: RawData
|
|
34
|
+
encoding?: DeepPartial<Encoding>
|
|
35
|
+
plugins?: PluginEntity<any, any, any>[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CreateChart {
|
|
39
|
+
(element: HTMLElement | Element, options?: PartialChartOptions): ChartEntity
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ChartEntity {
|
|
43
|
+
// Commands
|
|
44
|
+
resize(sizeConfig: SizeConfig): void
|
|
45
|
+
setData(data: RawData): void // replace
|
|
46
|
+
// setEncoding(partial: Partial<Encoding>): void // deep-merge with default
|
|
47
|
+
updateEncoding(patch: DeepPartial<Encoding>): void // deep-merge with previous
|
|
48
|
+
forceReplaceEncoding(full: Encoding): void // replace
|
|
49
|
+
getEncoding(): Readonly<Encoding>
|
|
50
|
+
setPlugins(plugins: PluginEntity<any, any, any>[]): void // replace all
|
|
51
|
+
addPlugin(plugin: PluginEntity<any, any, any>): void
|
|
52
|
+
removePlugin(id: string): void
|
|
53
|
+
// setTheme(theme: Theme): void // replace all
|
|
54
|
+
updateTheme(patch: DeepPartial<Theme>): void // deep-merge with previous
|
|
55
|
+
forceReplaceTheme(full: Theme): void // replace all
|
|
56
|
+
getTheme(): Readonly<Theme>
|
|
57
|
+
destroy(): void;
|
|
58
|
+
|
|
59
|
+
// context
|
|
60
|
+
context: ChartContext<{}>
|
|
61
|
+
}
|
|
62
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Observable, Subject } from 'rxjs'
|
|
2
|
+
import type {
|
|
3
|
+
RawData,
|
|
4
|
+
Encoding,
|
|
5
|
+
ModelData,
|
|
6
|
+
PluginInfo,
|
|
7
|
+
Theme,
|
|
8
|
+
EventData,
|
|
9
|
+
LayerInfo,
|
|
10
|
+
} from './index'
|
|
11
|
+
|
|
12
|
+
export interface Size {
|
|
13
|
+
width: number
|
|
14
|
+
height: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 定義可擴展的 context 類型 - 只包含新增的欄位
|
|
18
|
+
export interface ExtendableContext {
|
|
19
|
+
// 只能添加新的欄位,不能修改現有的 ChartContext
|
|
20
|
+
[key: string]: Observable<any> | Subject<any> | Function | any
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ChartContext<ExtendContext extends ExtendableContext> = {
|
|
24
|
+
// svgSelection: d3.Selection<SVGGElement, unknown, HTMLElement, any>
|
|
25
|
+
// canvasSelection: d3.Selection<HTMLCanvasElement, unknown, HTMLElement, any>
|
|
26
|
+
root: HTMLElement | Element
|
|
27
|
+
svg: SVGElement | null
|
|
28
|
+
canvas: HTMLCanvasElement | null
|
|
29
|
+
// rawData$: Observable<RawData>
|
|
30
|
+
encoding$: Observable<Encoding>
|
|
31
|
+
seriesData$: Observable<ModelData<'series'>[]>
|
|
32
|
+
gridData$: Observable<ModelData<'grid'>[]>
|
|
33
|
+
multivariateData$: Observable<ModelData<'multivariate'>[]>
|
|
34
|
+
graphData$: Observable<ModelData<'graph'>[]>
|
|
35
|
+
treeData$: Observable<ModelData<'tree'>[]>
|
|
36
|
+
plugins$: Observable<readonly PluginInfo[]>
|
|
37
|
+
theme$: Observable<Theme>
|
|
38
|
+
event$: Observable<EventData>
|
|
39
|
+
eventTrigger$: Subject<EventData>
|
|
40
|
+
size$: Observable<Size>
|
|
41
|
+
_updateLayerElements: <ElementType extends "svg" | "canvas">(elementType: ElementType, fromPluginName: string, fetchLayerInfo: LayerInfo[]) => Record<string, ElementType extends "svg" ? SVGGElement : HTMLCanvasElement>
|
|
42
|
+
} & ExtendContext
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export interface EncodingDataset {
|
|
5
|
+
from: string
|
|
6
|
+
sort: 'original' | 'alphabetical' | string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface EncodingSeries {
|
|
10
|
+
from: string
|
|
11
|
+
sort: 'original' | 'alphabetical' | string[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface EncodingCategory {
|
|
15
|
+
from: string
|
|
16
|
+
sort: 'original' | 'alphabetical' | string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface EncodingValue {
|
|
20
|
+
from: string
|
|
21
|
+
sort: 'original' | 'asc' | 'desc'
|
|
22
|
+
aggregate: 'sum' | 'mean' | 'median' | 'min' | 'max' | 'count' | 'none'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface EncodingMultivariateItem {
|
|
26
|
+
from: string
|
|
27
|
+
name: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type EncodingMultivariate = EncodingMultivariateItem[]
|
|
31
|
+
|
|
32
|
+
export interface EncodingColor {
|
|
33
|
+
from: 'index' | 'series' | 'category' | 'dataset'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface Encoding {
|
|
37
|
+
dataset: EncodingDataset
|
|
38
|
+
series: EncodingSeries
|
|
39
|
+
category: EncodingCategory
|
|
40
|
+
value: EncodingValue
|
|
41
|
+
multivariate: EncodingMultivariate
|
|
42
|
+
color: EncodingColor
|
|
43
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ModelType,
|
|
3
|
+
RenderDatumBase
|
|
4
|
+
} from '../../../core/src/types/index'
|
|
5
|
+
|
|
6
|
+
export type EventType = 'click'
|
|
7
|
+
| 'mouseover'
|
|
8
|
+
| 'mousemove'
|
|
9
|
+
| 'mouseout'
|
|
10
|
+
| 'dragstart'
|
|
11
|
+
| 'drag'
|
|
12
|
+
| 'dragend'
|
|
13
|
+
// | 'resize'
|
|
14
|
+
| 'zoom'
|
|
15
|
+
| 'transitionMove'
|
|
16
|
+
| 'transitionEnd'
|
|
17
|
+
|
|
18
|
+
export interface EventData<T extends ModelType = ModelType, ExtendTypes extends Record<string, any> = {}> {
|
|
19
|
+
eventName: EventType
|
|
20
|
+
pluginName: string
|
|
21
|
+
layerName: string
|
|
22
|
+
target: RenderDatumBase<T, ExtendTypes> | null
|
|
23
|
+
data?: any
|
|
24
|
+
tween?: number
|
|
25
|
+
event?: Event
|
|
26
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Observable } from 'rxjs'
|
|
2
|
+
import type { DeepPartial, ChartContext, ExtendableContext, ValidatorResult } from './index'
|
|
3
|
+
|
|
4
|
+
// export type LayerParamsBase<LayerName extends string> = {
|
|
5
|
+
// [K in LayerName]: unknown
|
|
6
|
+
// }
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// export type LayerParams<LayerName extends string, Params = any> = Record<LayerName, Params>
|
|
10
|
+
|
|
11
|
+
// export interface LayerContext<ExtendContext extends ExtendableContext = {}> {
|
|
12
|
+
// svgSelection: d3.Selection<SVGGElement, unknown, HTMLElement, any>
|
|
13
|
+
// canvasSelection: d3.Selection<HTMLCanvasElement, unknown, HTMLElement, any>
|
|
14
|
+
// name: string
|
|
15
|
+
// context: ChartContext<ExtendContext>
|
|
16
|
+
// }
|
|
17
|
+
|
|
18
|
+
// export type LayerContext<ExtendContext, LayerParams extends Record<string, any> = Record<string, any>> = ChartContext<ExtendContext> & {
|
|
19
|
+
// layerParams$: Observable<LayerParams>
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
export interface LayerInfo {
|
|
23
|
+
pluginId: string
|
|
24
|
+
pluginName: string
|
|
25
|
+
layerName: string
|
|
26
|
+
layerIndex: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SVGLayerEnableProps<ExtendContext extends ExtendableContext, PluginParams, LayerParams> {
|
|
30
|
+
context: ChartContext<ExtendContext>
|
|
31
|
+
svgG: SVGGElement
|
|
32
|
+
// canvas: HTMLCanvasElement
|
|
33
|
+
pluginParams$: Observable<PluginParams>
|
|
34
|
+
initLayerParams: DeepPartial<LayerParams>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CanvasLayerEnableProps<ExtendContext extends ExtendableContext, PluginParams, LayerParams> {
|
|
38
|
+
context: ChartContext<ExtendContext>
|
|
39
|
+
// svgG: SVGGElement
|
|
40
|
+
canvas: HTMLCanvasElement
|
|
41
|
+
pluginParams$: Observable<PluginParams>
|
|
42
|
+
initLayerParams: DeepPartial<LayerParams>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type LayerEnableProps<ElementType extends 'svg' | 'canvas', ExtendContext extends ExtendableContext, PluginParams, LayerParams> =
|
|
46
|
+
ElementType extends 'svg' ? SVGLayerEnableProps<ExtendContext, PluginParams, LayerParams> :
|
|
47
|
+
ElementType extends 'canvas' ? CanvasLayerEnableProps<ExtendContext, PluginParams, LayerParams> :
|
|
48
|
+
never
|
|
49
|
+
|
|
50
|
+
export interface SVGLayerSetupProps<ExtendContext extends ExtendableContext, PluginParams, LayerParams> {
|
|
51
|
+
context: ChartContext<ExtendContext>
|
|
52
|
+
svgG: SVGGElement
|
|
53
|
+
// canvas: HTMLCanvasElement
|
|
54
|
+
pluginParams$: Observable<PluginParams>
|
|
55
|
+
layerParams$: Observable<LayerParams>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface CanvasLayerSetupProps<ExtendContext extends ExtendableContext, PluginParams, LayerParams> {
|
|
59
|
+
context: ChartContext<ExtendContext>
|
|
60
|
+
// svgG: SVGGElement
|
|
61
|
+
canvas: HTMLCanvasElement
|
|
62
|
+
pluginParams$: Observable<PluginParams>
|
|
63
|
+
layerParams$: Observable<LayerParams>
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type LayerSetupProps<ElementType extends 'svg' | 'canvas', ExtendContext extends ExtendableContext, PluginParams, LayerParams> =
|
|
67
|
+
ElementType extends 'svg' ? SVGLayerSetupProps<ExtendContext, PluginParams, LayerParams> :
|
|
68
|
+
ElementType extends 'canvas' ? CanvasLayerSetupProps<ExtendContext, PluginParams, LayerParams> :
|
|
69
|
+
never
|
|
70
|
+
|
|
71
|
+
export interface DefineLayerConfig<ElementType extends 'svg' | 'canvas', ExtendContext extends ExtendableContext, PluginParams extends Record<string, any>, LayerParams extends Record<string, any>> {
|
|
72
|
+
name: string
|
|
73
|
+
defaultParams: LayerParams
|
|
74
|
+
layerIndex: number
|
|
75
|
+
initShow: boolean
|
|
76
|
+
validator?: (params: DeepPartial<LayerParams>) => ValidatorResult
|
|
77
|
+
setup: (setupProps: LayerSetupProps<ElementType, ExtendContext, PluginParams, LayerParams>) => () => void
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface LayerEntity<ExtendContext extends ExtendableContext, PluginParams, LayerParams> {
|
|
81
|
+
readonly _name: string
|
|
82
|
+
readonly _defaultParams: LayerParams
|
|
83
|
+
readonly _layerIndex: number
|
|
84
|
+
readonly _initShow: boolean
|
|
85
|
+
// _enable(el: { svg: SVGSVGElement; canvas: HTMLCanvasElement }, context: ChartContext<ExtendContext>): void
|
|
86
|
+
_enable(enableProps: LayerEnableProps<'svg' | 'canvas', ExtendContext, PluginParams, LayerParams>): void
|
|
87
|
+
_disable(): void
|
|
88
|
+
// _setParams(params: DeepPartial<LayerParams>): void
|
|
89
|
+
_updateParams(params: DeepPartial<LayerParams>): void
|
|
90
|
+
_forceReplaceParams(params: LayerParams): void
|
|
91
|
+
_getParams: () => LayerParams
|
|
92
|
+
_destroy(): void
|
|
93
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export type ModelType = 'series' | 'grid' | 'multivariate' | 'graph' | 'tree'
|
|
2
|
+
|
|
3
|
+
export interface ModelDatumBase {
|
|
4
|
+
id: string
|
|
5
|
+
index: number // 在同類別中的索引
|
|
6
|
+
modelType: ModelType
|
|
7
|
+
name: string // 原始資料的 name 欄位
|
|
8
|
+
data: any // 原始資料的 data 欄位
|
|
9
|
+
value: number | null // 經過 aggregate 後的數值
|
|
10
|
+
color: string // 經過色彩對應後的顏色(hex)
|
|
11
|
+
// rawData: RawDataColumn // 原始資料
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ModelDatumSeries extends ModelDatumBase {
|
|
15
|
+
series: string
|
|
16
|
+
seriesIndex: number
|
|
17
|
+
category: string
|
|
18
|
+
categoryIndex: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ModelDatumGrid extends ModelDatumBase {
|
|
22
|
+
series: string
|
|
23
|
+
seriesIndex: number
|
|
24
|
+
category: string
|
|
25
|
+
categoryIndex: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ModelDatumMultivariate extends ModelDatumBase {
|
|
29
|
+
series: string
|
|
30
|
+
seriesIndex: number
|
|
31
|
+
category: string
|
|
32
|
+
categoryIndex: number
|
|
33
|
+
multivariate: Array<{
|
|
34
|
+
index: number // 維度
|
|
35
|
+
name: string // multivariate 的 label
|
|
36
|
+
value: number | null
|
|
37
|
+
}>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ModelDatumGraphNode extends ModelDatumBase {
|
|
41
|
+
series: string
|
|
42
|
+
seriesIndex: number
|
|
43
|
+
category: string
|
|
44
|
+
categoryIndex: number
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ModelDatumGraphEdge extends ModelDatumBase {
|
|
48
|
+
series: string
|
|
49
|
+
seriesIndex: number
|
|
50
|
+
category: string
|
|
51
|
+
categoryIndex: number
|
|
52
|
+
source: string // 來源節點名稱
|
|
53
|
+
sourceIndex: number // 來源節點在所有節點中的索引
|
|
54
|
+
target: string // 目標節點名稱
|
|
55
|
+
targetIndex: number // 目標節點在所有節點中的索引
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ModelDatumTree extends ModelDatumBase {
|
|
59
|
+
parent: string | null // 父節點名稱
|
|
60
|
+
parentIndex: number | null // 父節點在所有節點中的索引
|
|
61
|
+
depth: number // 節點深度(根節點為 0)
|
|
62
|
+
seq: number // 同一層級中的順序
|
|
63
|
+
children: ModelDatumTree[] // 子節點
|
|
64
|
+
series: string
|
|
65
|
+
seriesIndex: number
|
|
66
|
+
category: string
|
|
67
|
+
categoryIndex: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type ModelDatum<T extends ModelType> = T extends 'series' ? ModelDatumSeries
|
|
71
|
+
: T extends 'grid' ? ModelDatumGrid
|
|
72
|
+
: T extends 'multivariate' ? ModelDatumMultivariate
|
|
73
|
+
: T extends 'graph' ? ModelDatumGraphNode
|
|
74
|
+
: T extends 'tree' ? ModelDatumTree
|
|
75
|
+
: unknown
|
|
76
|
+
|
|
77
|
+
export type ModelDataSeries = ModelDatum<'series'>[][]
|
|
78
|
+
|
|
79
|
+
export type ModelDataGrid = ModelDatum<'grid'>[][]
|
|
80
|
+
|
|
81
|
+
export type ModelDataMultivariate = ModelDatum<'multivariate'>[][]
|
|
82
|
+
|
|
83
|
+
export interface ModelDataGraph {
|
|
84
|
+
nodes: ModelDatumGraphNode[]
|
|
85
|
+
edges: ModelDatumGraphEdge[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ModelDataTree = ModelDatum<'tree'>
|
|
89
|
+
|
|
90
|
+
export type ModelData<T extends ModelType = ModelType> = T extends 'series' ? ModelDataSeries
|
|
91
|
+
: T extends 'grid' ? ModelDataGrid
|
|
92
|
+
: T extends 'multivariate' ? ModelDataMultivariate
|
|
93
|
+
: T extends 'graph' ? ModelDataGraph
|
|
94
|
+
: T extends 'tree' ? ModelDataTree
|
|
95
|
+
: unknown
|