@orbcharts/core 3.0.6 → 4.0.0-pre-alpha.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 (198) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +2795 -6591
  3. package/dist/orbcharts-core.umd.js +6 -6
  4. package/dist/src/OrbCharts.d.ts +18 -0
  5. package/dist/src/chart/createChart.d.ts +3 -0
  6. package/dist/src/chart/createGraphData.d.ts +3 -0
  7. package/dist/src/chart/createGridData.d.ts +3 -0
  8. package/dist/src/chart/createMultivariateData.d.ts +3 -0
  9. package/dist/src/chart/createSeriesData.d.ts +3 -0
  10. package/dist/src/chart/createTreeData.d.ts +3 -0
  11. package/dist/src/chart/defaults.d.ts +5 -0
  12. package/dist/src/defineCanvasLayer.d.ts +16 -0
  13. package/dist/src/defineCanvasPlugin.d.ts +22 -0
  14. package/dist/src/defineSVGLayer.d.ts +16 -0
  15. package/dist/src/defineSVGPlugin.d.ts +22 -0
  16. package/dist/src/index.d.ts +6 -14
  17. package/dist/src/layer/createLayer.d.ts +3 -0
  18. package/dist/src/plugin/createPlugin.d.ts +3 -0
  19. package/dist/src/test/createGraphData.test.d.ts +1 -0
  20. package/dist/src/test/createTreeData.test.d.ts +1 -0
  21. package/dist/src/test/simple-graph-test.d.ts +74 -0
  22. package/dist/src/test/simple-tree-test.d.ts +13 -0
  23. package/dist/src/types/Chart.d.ts +39 -0
  24. package/dist/src/types/ChartContext.d.ts +27 -0
  25. package/dist/src/types/Common.d.ts +3 -0
  26. package/dist/src/types/Encoding.d.ts +33 -0
  27. package/dist/src/types/Event.d.ts +12 -0
  28. package/dist/src/types/Layers.d.ts +55 -0
  29. package/dist/src/types/ModelData.d.ts +70 -0
  30. package/dist/src/types/Plugin.d.ts +39 -0
  31. package/dist/src/types/RawData.d.ts +18 -0
  32. package/dist/src/types/RenderData.d.ts +4 -0
  33. package/dist/src/types/Theme.d.ts +17 -0
  34. package/dist/src/types/Validator.d.ts +20 -0
  35. package/dist/src/types/index.d.ts +12 -0
  36. package/dist/src/utils/aggregateUtils.d.ts +37 -0
  37. package/dist/src/utils/colorUtils.d.ts +22 -0
  38. package/dist/src/utils/commonUtils.d.ts +3 -5
  39. package/dist/src/utils/dom-lifecycle.d.ts +37 -0
  40. package/dist/src/utils/dom.d.ts +6 -0
  41. package/dist/src/utils/index.d.ts +5 -1
  42. package/dist/src/utils/observables.d.ts +1 -25
  43. package/dist/src/utils/orbchartsUtils.d.ts +2 -53
  44. package/dist/src/utils/validator.d.ts +2 -2
  45. package/dist/test/aggregateTest.d.ts +1 -0
  46. package/package.json +59 -46
  47. package/src/OrbCharts.ts +35 -0
  48. package/src/chart/createChart.ts +997 -0
  49. package/src/chart/createGraphData.ts +391 -0
  50. package/src/chart/createGridData.ts +247 -0
  51. package/src/chart/createMultivariateData.ts +181 -0
  52. package/src/chart/createSeriesData.ts +297 -0
  53. package/src/chart/createTreeData.ts +344 -0
  54. package/src/chart/defaults.ts +100 -0
  55. package/src/defineCanvasLayer.ts +24 -0
  56. package/src/defineCanvasPlugin.ts +39 -0
  57. package/src/defineSVGLayer.ts +24 -0
  58. package/src/defineSVGPlugin.ts +39 -0
  59. package/src/index.ts +8 -20
  60. package/src/layer/createLayer.ts +138 -0
  61. package/src/plugin/createPlugin.ts +470 -0
  62. package/src/test/createGraphData.test.ts +103 -0
  63. package/src/test/createTreeData.test.ts +97 -0
  64. package/src/test/simple-graph-test.js +51 -0
  65. package/src/test/simple-tree-test.js +58 -0
  66. package/src/types/Chart.ts +62 -0
  67. package/src/types/ChartContext.ts +42 -0
  68. package/src/types/Common.ts +5 -0
  69. package/src/types/Encoding.ts +43 -0
  70. package/src/types/Event.ts +26 -0
  71. package/src/types/Layers.ts +93 -0
  72. package/src/types/ModelData.ts +95 -0
  73. package/src/types/Plugin.ts +98 -0
  74. package/src/types/RawData.ts +67 -0
  75. package/src/types/RenderData.ts +16 -0
  76. package/src/types/Theme.ts +21 -0
  77. package/src/types/Validator.ts +36 -0
  78. package/src/types/index.ts +12 -0
  79. package/src/utils/aggregateUtils.ts +99 -0
  80. package/src/utils/colorUtils.ts +63 -0
  81. package/src/utils/commonUtils.ts +56 -55
  82. package/src/utils/dom-lifecycle.ts +164 -0
  83. package/src/utils/dom.ts +55 -0
  84. package/src/utils/errorMessage.ts +40 -40
  85. package/src/utils/index.ts +8 -4
  86. package/src/utils/observables.ts +16 -308
  87. package/src/utils/orbchartsUtils.ts +9 -396
  88. package/src/utils/validator.ts +127 -126
  89. package/dist/lib/core-types.d.ts +0 -1
  90. package/dist/src/AbstractChart.d.ts +0 -19
  91. package/dist/src/GridChart.d.ts +0 -6
  92. package/dist/src/MultiGridChart.d.ts +0 -6
  93. package/dist/src/MultiValueChart.d.ts +0 -6
  94. package/dist/src/RelationshipChart.d.ts +0 -6
  95. package/dist/src/SeriesChart.d.ts +0 -6
  96. package/dist/src/TreeChart.d.ts +0 -6
  97. package/dist/src/base/createBaseChart.d.ts +0 -3
  98. package/dist/src/base/createBasePlugin.d.ts +0 -3
  99. package/dist/src/base/validators/chartOptionsValidator.d.ts +0 -3
  100. package/dist/src/base/validators/chartParamsValidator.d.ts +0 -3
  101. package/dist/src/base/validators/elementValidator.d.ts +0 -3
  102. package/dist/src/base/validators/pluginsValidator.d.ts +0 -3
  103. package/dist/src/defaults.d.ts +0 -25
  104. package/dist/src/defineGridPlugin.d.ts +0 -1
  105. package/dist/src/defineMultiGridPlugin.d.ts +0 -1
  106. package/dist/src/defineMultiValuePlugin.d.ts +0 -1
  107. package/dist/src/defineNoneDataPlugin.d.ts +0 -1
  108. package/dist/src/defineRelationshipPlugin.d.ts +0 -1
  109. package/dist/src/defineSeriesPlugin.d.ts +0 -1
  110. package/dist/src/defineTreePlugin.d.ts +0 -1
  111. package/dist/src/grid/computedDataFn.d.ts +0 -4
  112. package/dist/src/grid/contextObserverCallback.d.ts +0 -3
  113. package/dist/src/grid/dataFormatterValidator.d.ts +0 -3
  114. package/dist/src/grid/dataValidator.d.ts +0 -3
  115. package/dist/src/grid/gridObservables.d.ts +0 -64
  116. package/dist/src/multiGrid/computedDataFn.d.ts +0 -3
  117. package/dist/src/multiGrid/contextObserverCallback.d.ts +0 -3
  118. package/dist/src/multiGrid/dataFormatterValidator.d.ts +0 -3
  119. package/dist/src/multiGrid/dataValidator.d.ts +0 -3
  120. package/dist/src/multiGrid/multiGridObservables.d.ts +0 -16
  121. package/dist/src/multiValue/computedDataFn.d.ts +0 -3
  122. package/dist/src/multiValue/contextObserverCallback.d.ts +0 -3
  123. package/dist/src/multiValue/dataFormatterValidator.d.ts +0 -3
  124. package/dist/src/multiValue/dataValidator.d.ts +0 -3
  125. package/dist/src/multiValue/multiValueObservables.d.ts +0 -130
  126. package/dist/src/relationship/computedDataFn.d.ts +0 -3
  127. package/dist/src/relationship/contextObserverCallback.d.ts +0 -3
  128. package/dist/src/relationship/dataFormatterValidator.d.ts +0 -3
  129. package/dist/src/relationship/dataValidator.d.ts +0 -3
  130. package/dist/src/relationship/relationshipObservables.d.ts +0 -13
  131. package/dist/src/series/computedDataFn.d.ts +0 -3
  132. package/dist/src/series/contextObserverCallback.d.ts +0 -3
  133. package/dist/src/series/dataFormatterValidator.d.ts +0 -3
  134. package/dist/src/series/dataValidator.d.ts +0 -3
  135. package/dist/src/series/seriesObservables.d.ts +0 -37
  136. package/dist/src/tree/computedDataFn.d.ts +0 -3
  137. package/dist/src/tree/contextObserverCallback.d.ts +0 -3
  138. package/dist/src/tree/dataFormatterValidator.d.ts +0 -3
  139. package/dist/src/tree/dataValidator.d.ts +0 -3
  140. package/dist/src/tree/treeObservables.d.ts +0 -10
  141. package/dist/src/utils/d3Scale.d.ts +0 -28
  142. package/lib/core-types.ts +0 -7
  143. package/src/AbstractChart.ts +0 -57
  144. package/src/GridChart.ts +0 -25
  145. package/src/MultiGridChart.ts +0 -25
  146. package/src/MultiValueChart.ts +0 -25
  147. package/src/RelationshipChart.ts +0 -25
  148. package/src/SeriesChart.ts +0 -25
  149. package/src/TreeChart.ts +0 -25
  150. package/src/base/createBaseChart.ts +0 -524
  151. package/src/base/createBasePlugin.ts +0 -154
  152. package/src/base/validators/chartOptionsValidator.ts +0 -24
  153. package/src/base/validators/chartParamsValidator.ts +0 -134
  154. package/src/base/validators/elementValidator.ts +0 -14
  155. package/src/base/validators/pluginsValidator.ts +0 -15
  156. package/src/defaults.ts +0 -284
  157. package/src/defineGridPlugin.ts +0 -3
  158. package/src/defineMultiGridPlugin.ts +0 -3
  159. package/src/defineMultiValuePlugin.ts +0 -3
  160. package/src/defineNoneDataPlugin.ts +0 -4
  161. package/src/defineRelationshipPlugin.ts +0 -3
  162. package/src/defineSeriesPlugin.ts +0 -3
  163. package/src/defineTreePlugin.ts +0 -3
  164. package/src/grid/computedDataFn.ts +0 -129
  165. package/src/grid/contextObserverCallback.ts +0 -209
  166. package/src/grid/dataFormatterValidator.ts +0 -126
  167. package/src/grid/dataValidator.ts +0 -13
  168. package/src/grid/gridObservables.ts +0 -699
  169. package/src/multiGrid/computedDataFn.ts +0 -123
  170. package/src/multiGrid/contextObserverCallback.ts +0 -109
  171. package/src/multiGrid/dataFormatterValidator.ts +0 -121
  172. package/src/multiGrid/dataValidator.ts +0 -13
  173. package/src/multiGrid/multiGridObservables.ts +0 -367
  174. package/src/multiValue/computedDataFn.ts +0 -113
  175. package/src/multiValue/contextObserverCallback.ts +0 -328
  176. package/src/multiValue/dataFormatterValidator.ts +0 -95
  177. package/src/multiValue/dataValidator.ts +0 -13
  178. package/src/multiValue/multiValueObservables.ts +0 -865
  179. package/src/relationship/computedDataFn.ts +0 -159
  180. package/src/relationship/contextObserverCallback.ts +0 -80
  181. package/src/relationship/dataFormatterValidator.ts +0 -14
  182. package/src/relationship/dataValidator.ts +0 -14
  183. package/src/relationship/relationshipObservables.ts +0 -85
  184. package/src/series/computedDataFn.ts +0 -88
  185. package/src/series/contextObserverCallback.ts +0 -132
  186. package/src/series/dataFormatterValidator.ts +0 -47
  187. package/src/series/dataValidator.ts +0 -13
  188. package/src/series/seriesObservables.ts +0 -210
  189. package/src/tree/computedDataFn.ts +0 -129
  190. package/src/tree/contextObserverCallback.ts +0 -58
  191. package/src/tree/dataFormatterValidator.ts +0 -14
  192. package/src/tree/dataValidator.ts +0 -14
  193. package/src/tree/treeObservables.ts +0 -106
  194. package/src/utils/d3Scale.ts +0 -198
  195. package/tsconfig.base.json +0 -14
  196. package/tsconfig.json +0 -3
  197. package/vite-env.d.ts +0 -7
  198. 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,5 @@
1
+
2
+
3
+ export type DeepPartial<T> = Partial<{
4
+ [P in keyof T]: DeepPartial<T[P]>
5
+ }>
@@ -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