@orbcharts/core 3.0.0-alpha.40 → 3.0.0-alpha.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +1152 -1124
  3. package/dist/orbcharts-core.umd.js +2 -2
  4. package/dist/src/types/ChartParams.d.ts +1 -1
  5. package/dist/src/types/ContextObserverGrid.d.ts +1 -0
  6. package/dist/src/types/ContextObserverMultiGrid.d.ts +1 -0
  7. package/dist/src/types/ContextObserverSeries.d.ts +1 -0
  8. package/dist/src/types/ContextObserverTree.d.ts +1 -0
  9. package/dist/src/utils/observables.d.ts +1 -0
  10. package/package.json +41 -41
  11. package/src/AbstractChart.ts +48 -48
  12. package/src/GridChart.ts +20 -20
  13. package/src/MultiGridChart.ts +20 -20
  14. package/src/MultiValueChart.ts +20 -20
  15. package/src/RelationshipChart.ts +20 -20
  16. package/src/SeriesChart.ts +20 -20
  17. package/src/TreeChart.ts +20 -20
  18. package/src/base/createBaseChart.ts +367 -367
  19. package/src/base/createBasePlugin.ts +89 -89
  20. package/src/defaults.ts +248 -247
  21. package/src/defineGridPlugin.ts +3 -3
  22. package/src/defineMultiGridPlugin.ts +3 -3
  23. package/src/defineMultiValuePlugin.ts +3 -3
  24. package/src/defineNoneDataPlugin.ts +4 -4
  25. package/src/defineRelationshipPlugin.ts +3 -3
  26. package/src/defineSeriesPlugin.ts +3 -3
  27. package/src/defineTreePlugin.ts +3 -3
  28. package/src/grid/computeGridData.ts +205 -205
  29. package/src/grid/createGridContextObserver.ts +130 -124
  30. package/src/grid/gridObservables.ts +486 -486
  31. package/src/index.ts +21 -21
  32. package/src/multiGrid/computeMultiGridData.ts +173 -173
  33. package/src/multiGrid/createMultiGridContextObserver.ts +40 -34
  34. package/src/multiGrid/multiGridObservables.ts +285 -285
  35. package/src/multiValue/computeMultiValueData.ts +136 -136
  36. package/src/multiValue/createMultiValueContextObserver.ts +12 -12
  37. package/src/relationship/computeRelationshipData.ts +106 -106
  38. package/src/relationship/createRelationshipContextObserver.ts +12 -12
  39. package/src/series/computeSeriesData.ts +153 -153
  40. package/src/series/createSeriesContextObserver.ts +38 -33
  41. package/src/series/seriesObservables.ts +23 -23
  42. package/src/tree/computeTreeData.ts +128 -128
  43. package/src/tree/createTreeContextObserver.ts +61 -56
  44. package/src/tree/treeObservables.ts +94 -94
  45. package/src/types/Chart.ts +48 -48
  46. package/src/types/ChartParams.ts +51 -51
  47. package/src/types/ComputedData.ts +82 -82
  48. package/src/types/ComputedDataGrid.ts +13 -13
  49. package/src/types/ComputedDataMultiGrid.ts +2 -2
  50. package/src/types/ComputedDataMultiValue.ts +9 -9
  51. package/src/types/ComputedDataRelationship.ts +19 -19
  52. package/src/types/ComputedDataSeries.ts +7 -7
  53. package/src/types/ComputedDataTree.ts +19 -19
  54. package/src/types/ContextObserver.ts +38 -38
  55. package/src/types/ContextObserverGrid.ts +33 -33
  56. package/src/types/ContextObserverMultiGrid.ts +28 -27
  57. package/src/types/ContextObserverMultiValue.ts +4 -4
  58. package/src/types/ContextObserverRelationship.ts +4 -4
  59. package/src/types/ContextObserverSeries.ts +8 -7
  60. package/src/types/ContextObserverTree.ts +11 -10
  61. package/src/types/ContextSubject.ts +18 -18
  62. package/src/types/Data.ts +45 -45
  63. package/src/types/DataFormatter.ts +95 -95
  64. package/src/types/DataFormatterGrid.ts +55 -55
  65. package/src/types/DataFormatterMultiGrid.ts +42 -42
  66. package/src/types/DataFormatterMultiValue.ts +20 -20
  67. package/src/types/DataFormatterRelationship.ts +22 -22
  68. package/src/types/DataFormatterSeries.ts +29 -29
  69. package/src/types/DataFormatterTree.ts +12 -12
  70. package/src/types/DataGrid.ts +11 -11
  71. package/src/types/DataMultiGrid.ts +6 -6
  72. package/src/types/DataMultiValue.ts +12 -12
  73. package/src/types/DataRelationship.ts +27 -27
  74. package/src/types/DataSeries.ts +11 -11
  75. package/src/types/DataTree.ts +20 -20
  76. package/src/types/Event.ts +153 -153
  77. package/src/types/Layout.ts +11 -11
  78. package/src/types/Padding.ts +5 -5
  79. package/src/types/Plugin.ts +60 -60
  80. package/src/types/TransformData.ts +7 -7
  81. package/src/types/index.ts +37 -37
  82. package/src/utils/commonUtils.ts +50 -50
  83. package/src/utils/d3Utils.ts +89 -89
  84. package/src/utils/index.ts +4 -4
  85. package/src/utils/observables.ts +202 -181
  86. package/src/utils/orbchartsUtils.ts +253 -253
  87. package/tsconfig.json +13 -13
  88. package/vite.config.js +44 -44
@@ -1,136 +1,136 @@
1
- import type { DataMultiValue, DataMultiValueDatum } from '../types/DataMultiValue'
2
- import type { DataFormatterContext } from '../types/DataFormatter'
3
- import type { ComputedDataFn } from '../types/ComputedData'
4
- import type { ComputedDataMultiValue, ComputedDatumMultiValue } from '../types/ComputedDataMultiValue'
5
- import { formatValueToLabel, createDefaultDatumId } from '../utils/orbchartsUtils'
6
- import { createAxisLinearScale, createAxisPointScale } from '../utils/d3Utils'
7
- import { getMinAndMaxValue } from '../utils/orbchartsUtils'
8
-
9
- export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) => {
10
- const { data, dataFormatter, chartParams, layout } = context
11
- if (!data.length) {
12
- return []
13
- }
14
-
15
- let computedDataMultiValue: ComputedDatumMultiValue[][] = []
16
-
17
- try {
18
- const dataMultiValue: DataMultiValueDatum[][] = data.map((d, i) => {
19
- return d.map((_d, _i) => {
20
- const datum: DataMultiValueDatum = typeof _d === 'number'
21
- ? {
22
- id: '',
23
- label: '',
24
- description: '',
25
- // tooltipContent: '',
26
- data: {},
27
- categoryLabel: '',
28
- value: _d
29
- }
30
- : {
31
- id: _d.id ?? '',
32
- label: _d.label ?? '',
33
- description: _d.description ?? '',
34
- // tooltipContent: _d.tooltipContent ?? '',
35
- data: _d.data ?? {},
36
- categoryLabel: _d.categoryLabel ??'',
37
- value: _d.value
38
- }
39
-
40
- return datum
41
- })
42
- })
43
-
44
- // x軸資料最小及最大值(第二維陣列中的第1筆為x軸資料)
45
- const [xMinValue, xMaxValue] = getMinAndMaxValue(dataMultiValue.map(d => d[0]))
46
- // y軸資料最小及最大值(第二維陣列中的第2筆為y軸資料)
47
- const [yMinValue, yMaxValue] = getMinAndMaxValue(dataMultiValue.map(d => d[1]))
48
-
49
- // const axisWidth = layout.width - dataFormatter.padding.left - dataFormatter.padding.right
50
- // const axisHeight = layout.height - dataFormatter.padding.top - dataFormatter.padding.bottom
51
- // const axisWidth = layout.width
52
- // const axisHeight = layout.height
53
- const xAxisWidth = (dataFormatter.xAxis.position === 'top' || dataFormatter.xAxis.position === 'bottom')
54
- ? layout.width
55
- : layout.height
56
- const yAxisWidth = (dataFormatter.yAxis.position === 'left' || dataFormatter.yAxis.position === 'right')
57
- ? layout.height
58
- : layout.width
59
-
60
- const xScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
61
- maxValue: xMaxValue,
62
- minValue: xMinValue,
63
- axisWidth: xAxisWidth,
64
- // scaleDomain: dataFormatter.xAxis.scaleDomain,
65
- // scaleRange: dataFormatter.xAxis.scaleRange
66
- scaleDomain: [xMinValue, xMaxValue],
67
- scaleRange: [0, 1]
68
- })
69
- const yScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
70
- maxValue: yMaxValue,
71
- minValue: yMinValue,
72
- axisWidth: yAxisWidth,
73
- // scaleDomain: dataFormatter.yAxis.scaleDomain,
74
- // scaleRange: dataFormatter.yAxis.scaleRange
75
- scaleDomain: [yMinValue, yMaxValue],
76
- scaleRange: [0, 1]
77
- })
78
-
79
- const _xScaleDoamin: [number, number] = [
80
- dataFormatter.xAxis.scaleDomain[0] === 'auto' ? xMinValue : dataFormatter.xAxis.scaleDomain[0],
81
- dataFormatter.xAxis.scaleDomain[1] === 'auto' ? xMaxValue : dataFormatter.xAxis.scaleDomain[1]
82
- ]
83
- const _yScaleDoamin: [number, number] = [
84
- dataFormatter.yAxis.scaleDomain[0] === 'auto' ? yMinValue : dataFormatter.yAxis.scaleDomain[0],
85
- dataFormatter.yAxis.scaleDomain[1] === 'auto' ? yMaxValue : dataFormatter.yAxis.scaleDomain[1]
86
- ]
87
-
88
- // 篩選顯示狀態
89
- const visibleFilter = (datum: DataMultiValueDatum, rowIndex: number, columnIndex: number, context: DataFormatterContext<"multiValue">) => {
90
- // 如果不在scale的範圍內則為false,不再做visibleFilter的判斷
91
- if (columnIndex === 0 && datum.value != null && ((datum.value as number) < _xScaleDoamin[0] || datum.value > _xScaleDoamin[1])) {
92
- return false
93
- }
94
- if (columnIndex === 1 && datum.value != null && (datum.value < _yScaleDoamin[0] || datum.value > _yScaleDoamin[1])) {
95
- return false
96
- }
97
-
98
- return dataFormatter.visibleFilter(datum, rowIndex, columnIndex, context)
99
- }
100
-
101
- let index = 0
102
-
103
- computedDataMultiValue = dataMultiValue.map((d, i) => {
104
- return d.map((_d, _i) => {
105
- const currentIndex = index
106
- index++
107
-
108
- const defaultId = createDefaultDatumId(dataFormatter.type, i, _i)
109
- // const visible = dataFormatter.visibleFilter(_d, i, _i, context)
110
- const visible = visibleFilter(_d, i, _i, context)
111
-
112
- const computedDatum: ComputedDatumMultiValue = {
113
- id: _d.id ? _d.id : defaultId,
114
- index: currentIndex,
115
- label: _d.label ? _d.label : defaultId,
116
- description: _d.description ?? '',
117
- // tooltipContent: _d.tooltipContent ? _d.tooltipContent : dataFormatter.tooltipContentFormat(_d, i, _i, context),
118
- data: _d.data,
119
- value: _d.value,
120
- categoryIndex: 0, // @Q@ 未完成
121
- categoryLabel: '', // @Q@ 未完成
122
- // valueLabel: formatValueToLabel(_d.value, dataFormatter.multiValue[_i].valueFormat),
123
- axis: _i == 0 ? xScale(_d.value) : yScale(_d.value),
124
- visible,
125
- color: '' // @Q@ 未完成
126
- }
127
- return computedDatum
128
- })
129
- })
130
- } catch (e) {
131
- // console.error(e)
132
- throw Error(e)
133
- }
134
-
135
- return computedDataMultiValue
136
- }
1
+ import type { DataMultiValue, DataMultiValueDatum } from '../types/DataMultiValue'
2
+ import type { DataFormatterContext } from '../types/DataFormatter'
3
+ import type { ComputedDataFn } from '../types/ComputedData'
4
+ import type { ComputedDataMultiValue, ComputedDatumMultiValue } from '../types/ComputedDataMultiValue'
5
+ import { formatValueToLabel, createDefaultDatumId } from '../utils/orbchartsUtils'
6
+ import { createAxisLinearScale, createAxisPointScale } from '../utils/d3Utils'
7
+ import { getMinAndMaxValue } from '../utils/orbchartsUtils'
8
+
9
+ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) => {
10
+ const { data, dataFormatter, chartParams, layout } = context
11
+ if (!data.length) {
12
+ return []
13
+ }
14
+
15
+ let computedDataMultiValue: ComputedDatumMultiValue[][] = []
16
+
17
+ try {
18
+ const dataMultiValue: DataMultiValueDatum[][] = data.map((d, i) => {
19
+ return d.map((_d, _i) => {
20
+ const datum: DataMultiValueDatum = typeof _d === 'number'
21
+ ? {
22
+ id: '',
23
+ label: '',
24
+ description: '',
25
+ // tooltipContent: '',
26
+ data: {},
27
+ categoryLabel: '',
28
+ value: _d
29
+ }
30
+ : {
31
+ id: _d.id ?? '',
32
+ label: _d.label ?? '',
33
+ description: _d.description ?? '',
34
+ // tooltipContent: _d.tooltipContent ?? '',
35
+ data: _d.data ?? {},
36
+ categoryLabel: _d.categoryLabel ??'',
37
+ value: _d.value
38
+ }
39
+
40
+ return datum
41
+ })
42
+ })
43
+
44
+ // x軸資料最小及最大值(第二維陣列中的第1筆為x軸資料)
45
+ const [xMinValue, xMaxValue] = getMinAndMaxValue(dataMultiValue.map(d => d[0]))
46
+ // y軸資料最小及最大值(第二維陣列中的第2筆為y軸資料)
47
+ const [yMinValue, yMaxValue] = getMinAndMaxValue(dataMultiValue.map(d => d[1]))
48
+
49
+ // const axisWidth = layout.width - dataFormatter.padding.left - dataFormatter.padding.right
50
+ // const axisHeight = layout.height - dataFormatter.padding.top - dataFormatter.padding.bottom
51
+ // const axisWidth = layout.width
52
+ // const axisHeight = layout.height
53
+ const xAxisWidth = (dataFormatter.xAxis.position === 'top' || dataFormatter.xAxis.position === 'bottom')
54
+ ? layout.width
55
+ : layout.height
56
+ const yAxisWidth = (dataFormatter.yAxis.position === 'left' || dataFormatter.yAxis.position === 'right')
57
+ ? layout.height
58
+ : layout.width
59
+
60
+ const xScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
61
+ maxValue: xMaxValue,
62
+ minValue: xMinValue,
63
+ axisWidth: xAxisWidth,
64
+ // scaleDomain: dataFormatter.xAxis.scaleDomain,
65
+ // scaleRange: dataFormatter.xAxis.scaleRange
66
+ scaleDomain: [xMinValue, xMaxValue],
67
+ scaleRange: [0, 1]
68
+ })
69
+ const yScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
70
+ maxValue: yMaxValue,
71
+ minValue: yMinValue,
72
+ axisWidth: yAxisWidth,
73
+ // scaleDomain: dataFormatter.yAxis.scaleDomain,
74
+ // scaleRange: dataFormatter.yAxis.scaleRange
75
+ scaleDomain: [yMinValue, yMaxValue],
76
+ scaleRange: [0, 1]
77
+ })
78
+
79
+ const _xScaleDoamin: [number, number] = [
80
+ dataFormatter.xAxis.scaleDomain[0] === 'auto' ? xMinValue : dataFormatter.xAxis.scaleDomain[0],
81
+ dataFormatter.xAxis.scaleDomain[1] === 'auto' ? xMaxValue : dataFormatter.xAxis.scaleDomain[1]
82
+ ]
83
+ const _yScaleDoamin: [number, number] = [
84
+ dataFormatter.yAxis.scaleDomain[0] === 'auto' ? yMinValue : dataFormatter.yAxis.scaleDomain[0],
85
+ dataFormatter.yAxis.scaleDomain[1] === 'auto' ? yMaxValue : dataFormatter.yAxis.scaleDomain[1]
86
+ ]
87
+
88
+ // 篩選顯示狀態
89
+ const visibleFilter = (datum: DataMultiValueDatum, rowIndex: number, columnIndex: number, context: DataFormatterContext<"multiValue">) => {
90
+ // 如果不在scale的範圍內則為false,不再做visibleFilter的判斷
91
+ if (columnIndex === 0 && datum.value != null && ((datum.value as number) < _xScaleDoamin[0] || datum.value > _xScaleDoamin[1])) {
92
+ return false
93
+ }
94
+ if (columnIndex === 1 && datum.value != null && (datum.value < _yScaleDoamin[0] || datum.value > _yScaleDoamin[1])) {
95
+ return false
96
+ }
97
+
98
+ return dataFormatter.visibleFilter(datum, rowIndex, columnIndex, context)
99
+ }
100
+
101
+ let index = 0
102
+
103
+ computedDataMultiValue = dataMultiValue.map((d, i) => {
104
+ return d.map((_d, _i) => {
105
+ const currentIndex = index
106
+ index++
107
+
108
+ const defaultId = createDefaultDatumId(dataFormatter.type, i, _i)
109
+ // const visible = dataFormatter.visibleFilter(_d, i, _i, context)
110
+ const visible = visibleFilter(_d, i, _i, context)
111
+
112
+ const computedDatum: ComputedDatumMultiValue = {
113
+ id: _d.id ? _d.id : defaultId,
114
+ index: currentIndex,
115
+ label: _d.label ? _d.label : defaultId,
116
+ description: _d.description ?? '',
117
+ // tooltipContent: _d.tooltipContent ? _d.tooltipContent : dataFormatter.tooltipContentFormat(_d, i, _i, context),
118
+ data: _d.data,
119
+ value: _d.value,
120
+ categoryIndex: 0, // @Q@ 未完成
121
+ categoryLabel: '', // @Q@ 未完成
122
+ // valueLabel: formatValueToLabel(_d.value, dataFormatter.multiValue[_i].valueFormat),
123
+ axis: _i == 0 ? xScale(_d.value) : yScale(_d.value),
124
+ visible,
125
+ color: '' // @Q@ 未完成
126
+ }
127
+ return computedDatum
128
+ })
129
+ })
130
+ } catch (e) {
131
+ // console.error(e)
132
+ throw Error(e)
133
+ }
134
+
135
+ return computedDataMultiValue
136
+ }
@@ -1,12 +1,12 @@
1
- import type { ContextObserverFn } from '../types'
2
-
3
- export const createMultiValueContextObserver: ContextObserverFn<'multiValue'> = ({ subject, observer }) => {
4
-
5
- return {
6
- fullParams$: observer.fullParams$,
7
- fullChartParams$: observer.fullChartParams$,
8
- fullDataFormatter$: observer.fullDataFormatter$,
9
- computedData$: observer.computedData$,
10
- layout$: observer.layout$,
11
- }
12
- }
1
+ import type { ContextObserverFn } from '../types'
2
+
3
+ export const createMultiValueContextObserver: ContextObserverFn<'multiValue'> = ({ subject, observer }) => {
4
+
5
+ return {
6
+ fullParams$: observer.fullParams$,
7
+ fullChartParams$: observer.fullChartParams$,
8
+ fullDataFormatter$: observer.fullDataFormatter$,
9
+ computedData$: observer.computedData$,
10
+ layout$: observer.layout$,
11
+ }
12
+ }
@@ -1,106 +1,106 @@
1
- import type { DataRelationship, DataRelationshipObj, DataRelationshipList, Node, Edge } from '../types/DataRelationship'
2
- import type { ComputedDataFn } from '../types/ComputedData'
3
- import type { ComputedDataRelationship, ComputedNode, ComputedEdge } from '../types/ComputedDataRelationship'
4
-
5
- export const computeRelationshipData: ComputedDataFn<'relationship'> = (context) => {
6
- const { data, dataFormatter, chartParams } = context
7
-
8
- let computedNodes: ComputedNode[] = []
9
- let computedEdges: ComputedEdge[] = []
10
-
11
- try {
12
- // -- 取得nodes和edges資料 --
13
- let nodes: Node[] = []
14
- let edges: Edge[] = []
15
- if ((data as DataRelationshipObj).nodes) {
16
- nodes = (data as DataRelationshipObj).nodes
17
- edges = (data as DataRelationshipObj).edges
18
- } else if ((data as DataRelationshipList)[0]) {
19
- nodes = (data as DataRelationshipList)[0]
20
- edges = (data as DataRelationshipList)[1]
21
- } else {
22
- // 無值直接回傳
23
- return {
24
- nodes: [],
25
- edges: []
26
- } as ComputedDataRelationship
27
- }
28
-
29
- // -- nodes --
30
- computedNodes = nodes.map((node, i) => {
31
- return {
32
- id: node.id,
33
- index: i,
34
- label: node.label ?? '',
35
- description: node.description ?? '',
36
- // tooltipContent: node.tooltipContent ? node.tooltipContent : dataFormatter.tooltipContentFormat(node, 0, i, context), // 0代表node
37
- data: node.data ?? {},
38
- value: node.value ?? 0,
39
- categoryIndex: 0, // @Q@ 未完成
40
- categoryLabel: '', // @Q@ 未完成
41
- color: '', // @Q@ 未完成
42
- startNodes: [], // 後面再取得資料
43
- startNodeIds: [], // 後面再取得資料
44
- endNodes: [], // 後面再取得資料
45
- endNodeIds: [], // 後面再取得資料
46
- visible: dataFormatter.visibleFilter(node, 0, i, context) // 0代表node
47
- }
48
- })
49
-
50
- const NodesMap: Map<string, ComputedNode> = new Map(computedNodes.map(d => [d.id, d]))
51
-
52
- // -- edges --
53
- computedEdges = edges.map((edge, i) => {
54
- return {
55
- id: edge.id,
56
- index: i,
57
- label: edge.label ?? '',
58
- description: edge.description ?? '',
59
- // tooltipContent: edge.tooltipContent ? edge.tooltipContent : dataFormatter.tooltipContentFormat(edge, 1, i, context), // 1代表edge
60
- data: edge.data ?? {},
61
- value: edge.value ?? 0,
62
- startNode: NodesMap.get(edge.start),
63
- startNodeId: edge.start,
64
- endNode: NodesMap.get(edge.end),
65
- endNodeId: edge.end,
66
- visible: dataFormatter.visibleFilter(edge, 1, i, context) // 1代表edge
67
- }
68
- })
69
-
70
- const StartNodesMap: Map<string, ComputedNode[]> = (function () {
71
- const _StartNodesMap = new Map()
72
- computedEdges.forEach(edge => {
73
- const startNodes: ComputedNode[] = _StartNodesMap.get(edge.endNodeId) ?? []
74
- startNodes.push(edge.startNode)
75
- _StartNodesMap.set(edge.endNodeId, startNodes)
76
- })
77
- return _StartNodesMap
78
- })()
79
-
80
- const EndNodesMap: Map<string, ComputedNode[]> = (function () {
81
- const _EndNodesMap = new Map()
82
- computedEdges.forEach(edge => {
83
- const endNodes: ComputedNode[] = _EndNodesMap.get(edge.startNodeId) ?? []
84
- endNodes.push(edge.endNode)
85
- _EndNodesMap.set(edge.startNodeId, endNodes)
86
- })
87
- return _EndNodesMap
88
- })()
89
-
90
- // -- 補齊nodes資料 --
91
- Array.from(NodesMap).forEach(([nodeId, node]) => {
92
- node.startNodes = StartNodesMap.get(nodeId)
93
- node.startNodeIds = node.startNodes.map(d => d.id)
94
- node.endNodes = EndNodesMap.get(nodeId)
95
- node.endNodeIds = node.endNodes.map(d => d.id)
96
- })
97
- } catch (e) {
98
- // console.error(e)
99
- throw Error(e)
100
- }
101
-
102
- return {
103
- nodes: computedNodes,
104
- edges: computedEdges
105
- }
106
- }
1
+ import type { DataRelationship, DataRelationshipObj, DataRelationshipList, Node, Edge } from '../types/DataRelationship'
2
+ import type { ComputedDataFn } from '../types/ComputedData'
3
+ import type { ComputedDataRelationship, ComputedNode, ComputedEdge } from '../types/ComputedDataRelationship'
4
+
5
+ export const computeRelationshipData: ComputedDataFn<'relationship'> = (context) => {
6
+ const { data, dataFormatter, chartParams } = context
7
+
8
+ let computedNodes: ComputedNode[] = []
9
+ let computedEdges: ComputedEdge[] = []
10
+
11
+ try {
12
+ // -- 取得nodes和edges資料 --
13
+ let nodes: Node[] = []
14
+ let edges: Edge[] = []
15
+ if ((data as DataRelationshipObj).nodes) {
16
+ nodes = (data as DataRelationshipObj).nodes
17
+ edges = (data as DataRelationshipObj).edges
18
+ } else if ((data as DataRelationshipList)[0]) {
19
+ nodes = (data as DataRelationshipList)[0]
20
+ edges = (data as DataRelationshipList)[1]
21
+ } else {
22
+ // 無值直接回傳
23
+ return {
24
+ nodes: [],
25
+ edges: []
26
+ } as ComputedDataRelationship
27
+ }
28
+
29
+ // -- nodes --
30
+ computedNodes = nodes.map((node, i) => {
31
+ return {
32
+ id: node.id,
33
+ index: i,
34
+ label: node.label ?? '',
35
+ description: node.description ?? '',
36
+ // tooltipContent: node.tooltipContent ? node.tooltipContent : dataFormatter.tooltipContentFormat(node, 0, i, context), // 0代表node
37
+ data: node.data ?? {},
38
+ value: node.value ?? 0,
39
+ categoryIndex: 0, // @Q@ 未完成
40
+ categoryLabel: '', // @Q@ 未完成
41
+ color: '', // @Q@ 未完成
42
+ startNodes: [], // 後面再取得資料
43
+ startNodeIds: [], // 後面再取得資料
44
+ endNodes: [], // 後面再取得資料
45
+ endNodeIds: [], // 後面再取得資料
46
+ visible: dataFormatter.visibleFilter(node, 0, i, context) // 0代表node
47
+ }
48
+ })
49
+
50
+ const NodesMap: Map<string, ComputedNode> = new Map(computedNodes.map(d => [d.id, d]))
51
+
52
+ // -- edges --
53
+ computedEdges = edges.map((edge, i) => {
54
+ return {
55
+ id: edge.id,
56
+ index: i,
57
+ label: edge.label ?? '',
58
+ description: edge.description ?? '',
59
+ // tooltipContent: edge.tooltipContent ? edge.tooltipContent : dataFormatter.tooltipContentFormat(edge, 1, i, context), // 1代表edge
60
+ data: edge.data ?? {},
61
+ value: edge.value ?? 0,
62
+ startNode: NodesMap.get(edge.start),
63
+ startNodeId: edge.start,
64
+ endNode: NodesMap.get(edge.end),
65
+ endNodeId: edge.end,
66
+ visible: dataFormatter.visibleFilter(edge, 1, i, context) // 1代表edge
67
+ }
68
+ })
69
+
70
+ const StartNodesMap: Map<string, ComputedNode[]> = (function () {
71
+ const _StartNodesMap = new Map()
72
+ computedEdges.forEach(edge => {
73
+ const startNodes: ComputedNode[] = _StartNodesMap.get(edge.endNodeId) ?? []
74
+ startNodes.push(edge.startNode)
75
+ _StartNodesMap.set(edge.endNodeId, startNodes)
76
+ })
77
+ return _StartNodesMap
78
+ })()
79
+
80
+ const EndNodesMap: Map<string, ComputedNode[]> = (function () {
81
+ const _EndNodesMap = new Map()
82
+ computedEdges.forEach(edge => {
83
+ const endNodes: ComputedNode[] = _EndNodesMap.get(edge.startNodeId) ?? []
84
+ endNodes.push(edge.endNode)
85
+ _EndNodesMap.set(edge.startNodeId, endNodes)
86
+ })
87
+ return _EndNodesMap
88
+ })()
89
+
90
+ // -- 補齊nodes資料 --
91
+ Array.from(NodesMap).forEach(([nodeId, node]) => {
92
+ node.startNodes = StartNodesMap.get(nodeId)
93
+ node.startNodeIds = node.startNodes.map(d => d.id)
94
+ node.endNodes = EndNodesMap.get(nodeId)
95
+ node.endNodeIds = node.endNodes.map(d => d.id)
96
+ })
97
+ } catch (e) {
98
+ // console.error(e)
99
+ throw Error(e)
100
+ }
101
+
102
+ return {
103
+ nodes: computedNodes,
104
+ edges: computedEdges
105
+ }
106
+ }
@@ -1,12 +1,12 @@
1
- import type { ContextObserverFn } from '../types'
2
-
3
- export const createRelationshipContextObserver: ContextObserverFn<'relationship'> = ({ subject, observer }) => {
4
-
5
- return {
6
- fullParams$: observer.fullParams$,
7
- fullChartParams$: observer.fullChartParams$,
8
- fullDataFormatter$: observer.fullDataFormatter$,
9
- computedData$: observer.computedData$,
10
- layout$: observer.layout$,
11
- }
12
- }
1
+ import type { ContextObserverFn } from '../types'
2
+
3
+ export const createRelationshipContextObserver: ContextObserverFn<'relationship'> = ({ subject, observer }) => {
4
+
5
+ return {
6
+ fullParams$: observer.fullParams$,
7
+ fullChartParams$: observer.fullChartParams$,
8
+ fullDataFormatter$: observer.fullDataFormatter$,
9
+ computedData$: observer.computedData$,
10
+ layout$: observer.layout$,
11
+ }
12
+ }