@orbcharts/core 4.0.0-alpha.0 → 4.0.0-beta.0

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.
Files changed (47) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +876 -865
  3. package/dist/orbcharts-core.umd.js +3 -3
  4. package/dist/src/types/Plugin.d.ts +1 -1
  5. package/package.json +1 -1
  6. package/src/OrbCharts.ts +34 -34
  7. package/src/chart/createChart.ts +1013 -996
  8. package/src/chart/createGraphData.ts +391 -391
  9. package/src/chart/createGridData.ts +247 -247
  10. package/src/chart/createMultivariateData.ts +181 -181
  11. package/src/chart/createSeriesData.ts +297 -297
  12. package/src/chart/createTreeData.ts +344 -344
  13. package/src/chart/defaults.ts +119 -119
  14. package/src/defineCanvasLayer.ts +23 -23
  15. package/src/defineCanvasPlugin.ts +38 -38
  16. package/src/defineSVGLayer.ts +23 -23
  17. package/src/defineSVGPlugin.ts +38 -38
  18. package/src/index.ts +8 -8
  19. package/src/layer/createLayer.ts +137 -137
  20. package/src/plugin/createPlugin.ts +487 -469
  21. package/src/test/createGraphData.test.ts +103 -103
  22. package/src/test/createTreeData.test.ts +97 -97
  23. package/src/test/simple-graph-test.js +51 -51
  24. package/src/test/simple-tree-test.js +58 -58
  25. package/src/types/Chart.ts +62 -62
  26. package/src/types/ChartContext.ts +41 -41
  27. package/src/types/Common.ts +4 -4
  28. package/src/types/Encoding.ts +42 -42
  29. package/src/types/Event.ts +25 -25
  30. package/src/types/Layers.ts +92 -92
  31. package/src/types/ModelData.ts +94 -94
  32. package/src/types/Plugin.ts +101 -98
  33. package/src/types/RawData.ts +67 -67
  34. package/src/types/RenderData.ts +15 -15
  35. package/src/types/Theme.ts +20 -20
  36. package/src/types/Validator.ts +35 -35
  37. package/src/types/index.ts +12 -12
  38. package/src/utils/aggregateUtils.ts +99 -99
  39. package/src/utils/colorUtils.ts +63 -63
  40. package/src/utils/commonUtils.ts +56 -56
  41. package/src/utils/dom-lifecycle.ts +164 -164
  42. package/src/utils/dom.ts +54 -54
  43. package/src/utils/errorMessage.ts +40 -40
  44. package/src/utils/index.ts +7 -7
  45. package/src/utils/observables.ts +16 -16
  46. package/src/utils/orbchartsUtils.ts +8 -8
  47. package/src/utils/validator.ts +127 -127
@@ -1,103 +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
- })
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
+ })
@@ -1,97 +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
- })
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
+ })
@@ -1,51 +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!')
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!')
@@ -1,58 +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!')
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!')