@orbcharts/core 3.0.0-alpha.21

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 (166) hide show
  1. package/.gitignore +23 -0
  2. package/LICENSE +201 -0
  3. package/dist/orbcharts-core.es.js +5096 -0
  4. package/dist/orbcharts-core.umd.js +3 -0
  5. package/dist/src/AbstractChart.d.ts +17 -0
  6. package/dist/src/GridChart.d.ts +6 -0
  7. package/dist/src/MultiGridChart.d.ts +6 -0
  8. package/dist/src/MultiValueChart.d.ts +6 -0
  9. package/dist/src/RelationshipChart.d.ts +6 -0
  10. package/dist/src/SeriesChart.d.ts +6 -0
  11. package/dist/src/TreeChart.d.ts +6 -0
  12. package/dist/src/base/createBaseChart.d.ts +3 -0
  13. package/dist/src/base/createBasePlugin.d.ts +3 -0
  14. package/dist/src/defaults.d.ts +37 -0
  15. package/dist/src/defineGridPlugin.d.ts +1 -0
  16. package/dist/src/defineMultiGridPlugin.d.ts +1 -0
  17. package/dist/src/defineMultiValuePlugin.d.ts +1 -0
  18. package/dist/src/defineNoneDataPlugin.d.ts +1 -0
  19. package/dist/src/defineRelationshipPlugin.d.ts +1 -0
  20. package/dist/src/defineSeriesPlugin.d.ts +1 -0
  21. package/dist/src/defineTreePlugin.d.ts +1 -0
  22. package/dist/src/grid/computeGridData.d.ts +3 -0
  23. package/dist/src/grid/createGridContextObserver.d.ts +3 -0
  24. package/dist/src/grid/gridObservables.d.ts +25 -0
  25. package/dist/src/index.d.ts +15 -0
  26. package/dist/src/multiGrid/computeMultiGridData.d.ts +3 -0
  27. package/dist/src/multiGrid/createMultiGridContextObserver.d.ts +3 -0
  28. package/dist/src/multiGrid/multiGridObservables.d.ts +0 -0
  29. package/dist/src/multiValue/computeMultiValueData.d.ts +3 -0
  30. package/dist/src/multiValue/createMultiValueContextObserver.d.ts +3 -0
  31. package/dist/src/multiValue/multiValueObservables.d.ts +0 -0
  32. package/dist/src/relationship/computeRelationshipData.d.ts +3 -0
  33. package/dist/src/relationship/createRelationshipContextObserver.d.ts +3 -0
  34. package/dist/src/relationship/relationshipObservables.d.ts +0 -0
  35. package/dist/src/series/computeSeriesData.d.ts +3 -0
  36. package/dist/src/series/createSeriesContextObserver.d.ts +3 -0
  37. package/dist/src/series/seriesObservables.d.ts +8 -0
  38. package/dist/src/tree/computeTreeData.d.ts +3 -0
  39. package/dist/src/tree/createTreeContextObserver.d.ts +3 -0
  40. package/dist/src/tree/treeObservables.d.ts +0 -0
  41. package/dist/src/types/Axis.d.ts +1 -0
  42. package/dist/src/types/Chart.d.ts +41 -0
  43. package/dist/src/types/ChartParams.d.ts +36 -0
  44. package/dist/src/types/ComputedData.d.ts +28 -0
  45. package/dist/src/types/ComputedDataGrid.d.ts +10 -0
  46. package/dist/src/types/ComputedDataMultiGrid.d.ts +3 -0
  47. package/dist/src/types/ComputedDataMultiValue.d.ts +6 -0
  48. package/dist/src/types/ComputedDataRelationship.d.ts +18 -0
  49. package/dist/src/types/ComputedDataSeries.d.ts +6 -0
  50. package/dist/src/types/ComputedDataTree.d.ts +7 -0
  51. package/dist/src/types/ContextObserver.d.ts +28 -0
  52. package/dist/src/types/ContextObserverGrid.d.ts +18 -0
  53. package/dist/src/types/ContextObserverMultiGrid.d.ts +4 -0
  54. package/dist/src/types/ContextObserverMultiValue.d.ts +4 -0
  55. package/dist/src/types/ContextObserverRelationship.d.ts +4 -0
  56. package/dist/src/types/ContextObserverSeries.d.ts +8 -0
  57. package/dist/src/types/ContextObserverTree.d.ts +4 -0
  58. package/dist/src/types/ContextSubject.d.ts +15 -0
  59. package/dist/src/types/Data.d.ts +19 -0
  60. package/dist/src/types/DataFormatter.d.ts +40 -0
  61. package/dist/src/types/DataFormatterGrid.d.ts +20 -0
  62. package/dist/src/types/DataFormatterMultiGrid.d.ts +16 -0
  63. package/dist/src/types/DataFormatterMultiValue.d.ts +13 -0
  64. package/dist/src/types/DataFormatterRelationship.d.ts +5 -0
  65. package/dist/src/types/DataFormatterSeries.d.ts +10 -0
  66. package/dist/src/types/DataFormatterTree.d.ts +5 -0
  67. package/dist/src/types/DataGrid.d.ts +6 -0
  68. package/dist/src/types/DataMultiGrid.d.ts +6 -0
  69. package/dist/src/types/DataMultiValue.d.ts +6 -0
  70. package/dist/src/types/DataRelationship.d.ts +20 -0
  71. package/dist/src/types/DataSeries.d.ts +6 -0
  72. package/dist/src/types/DataTree.d.ts +13 -0
  73. package/dist/src/types/Event.d.ts +64 -0
  74. package/dist/src/types/Layout.d.ts +8 -0
  75. package/dist/src/types/Padding.d.ts +6 -0
  76. package/dist/src/types/Plugin.d.ts +37 -0
  77. package/dist/src/types/TransformData.d.ts +8 -0
  78. package/dist/src/types/index.d.ts +37 -0
  79. package/dist/src/utils/commonUtils.d.ts +8 -0
  80. package/dist/src/utils/d3Utils.d.ts +25 -0
  81. package/dist/src/utils/index.d.ts +4 -0
  82. package/dist/src/utils/observables.d.ts +14 -0
  83. package/dist/src/utils/orbchartsUtils.d.ts +20 -0
  84. package/dist/vite.config.d.ts +2 -0
  85. package/package.json +40 -0
  86. package/src/AbstractChart.ts +48 -0
  87. package/src/GridChart.ts +21 -0
  88. package/src/MultiGridChart.ts +21 -0
  89. package/src/MultiValueChart.ts +21 -0
  90. package/src/RelationshipChart.ts +21 -0
  91. package/src/SeriesChart.ts +21 -0
  92. package/src/TreeChart.ts +21 -0
  93. package/src/base/createBaseChart.ts +329 -0
  94. package/src/base/createBasePlugin.ts +89 -0
  95. package/src/defaults.ts +229 -0
  96. package/src/defineGridPlugin.ts +3 -0
  97. package/src/defineMultiGridPlugin.ts +3 -0
  98. package/src/defineMultiValuePlugin.ts +3 -0
  99. package/src/defineNoneDataPlugin.ts +4 -0
  100. package/src/defineRelationshipPlugin.ts +3 -0
  101. package/src/defineSeriesPlugin.ts +3 -0
  102. package/src/defineTreePlugin.ts +3 -0
  103. package/src/grid/computeGridData.ts +192 -0
  104. package/src/grid/createGridContextObserver.ts +91 -0
  105. package/src/grid/gridObservables.ts +359 -0
  106. package/src/index.ts +21 -0
  107. package/src/multiGrid/computeMultiGridData.ts +48 -0
  108. package/src/multiGrid/createMultiGridContextObserver.ts +12 -0
  109. package/src/multiGrid/multiGridObservables.ts +0 -0
  110. package/src/multiValue/computeMultiValueData.ts +127 -0
  111. package/src/multiValue/createMultiValueContextObserver.ts +12 -0
  112. package/src/multiValue/multiValueObservables.ts +0 -0
  113. package/src/relationship/computeRelationshipData.ts +101 -0
  114. package/src/relationship/createRelationshipContextObserver.ts +12 -0
  115. package/src/relationship/relationshipObservables.ts +0 -0
  116. package/src/series/computeSeriesData.ts +154 -0
  117. package/src/series/createSeriesContextObserver.ts +33 -0
  118. package/src/series/seriesObservables.ts +23 -0
  119. package/src/tree/computeTreeData.ts +104 -0
  120. package/src/tree/createTreeContextObserver.ts +12 -0
  121. package/src/tree/treeObservables.ts +0 -0
  122. package/src/types/Axis.ts +1 -0
  123. package/src/types/Chart.ts +46 -0
  124. package/src/types/ChartParams.ts +50 -0
  125. package/src/types/ComputedData.ts +66 -0
  126. package/src/types/ComputedDataGrid.ts +12 -0
  127. package/src/types/ComputedDataMultiGrid.ts +3 -0
  128. package/src/types/ComputedDataMultiValue.ts +10 -0
  129. package/src/types/ComputedDataRelationship.ts +20 -0
  130. package/src/types/ComputedDataSeries.ts +8 -0
  131. package/src/types/ComputedDataTree.ts +20 -0
  132. package/src/types/ContextObserver.ts +38 -0
  133. package/src/types/ContextObserverGrid.ts +16 -0
  134. package/src/types/ContextObserverMultiGrid.ts +5 -0
  135. package/src/types/ContextObserverMultiValue.ts +5 -0
  136. package/src/types/ContextObserverRelationship.ts +5 -0
  137. package/src/types/ContextObserverSeries.ts +8 -0
  138. package/src/types/ContextObserverTree.ts +5 -0
  139. package/src/types/ContextSubject.ts +18 -0
  140. package/src/types/Data.ts +45 -0
  141. package/src/types/DataFormatter.ts +99 -0
  142. package/src/types/DataFormatterGrid.ts +40 -0
  143. package/src/types/DataFormatterMultiGrid.ts +23 -0
  144. package/src/types/DataFormatterMultiValue.ts +19 -0
  145. package/src/types/DataFormatterRelationship.ts +23 -0
  146. package/src/types/DataFormatterSeries.ts +26 -0
  147. package/src/types/DataFormatterTree.ts +10 -0
  148. package/src/types/DataGrid.ts +11 -0
  149. package/src/types/DataMultiGrid.ts +7 -0
  150. package/src/types/DataMultiValue.ts +11 -0
  151. package/src/types/DataRelationship.ts +27 -0
  152. package/src/types/DataSeries.ts +11 -0
  153. package/src/types/DataTree.ts +18 -0
  154. package/src/types/Event.ts +114 -0
  155. package/src/types/Layout.ts +12 -0
  156. package/src/types/Padding.ts +6 -0
  157. package/src/types/Plugin.ts +60 -0
  158. package/src/types/TransformData.ts +8 -0
  159. package/src/types/index.ts +37 -0
  160. package/src/utils/commonUtils.ts +50 -0
  161. package/src/utils/d3Utils.ts +87 -0
  162. package/src/utils/index.ts +4 -0
  163. package/src/utils/observables.ts +198 -0
  164. package/src/utils/orbchartsUtils.ts +150 -0
  165. package/tsconfig.json +14 -0
  166. package/vite.config.js +45 -0
@@ -0,0 +1,50 @@
1
+ // import * as d3 from 'd3'
2
+
3
+ // 是否為物件
4
+ export function isObject(variable: any) {
5
+ return Object.prototype.toString.call(variable) === "[object Object]";
6
+ }
7
+
8
+ // 是否為function
9
+ export function isFunction(fn: any) {
10
+ return !!fn && !fn.nodename && fn.constructor != String && fn.constructor != RegExp && fn.constructor != Array && /function/i.test(fn + "");
11
+ }
12
+
13
+ // 將可選的參數和預設值合併
14
+ export function mergeOptionsWithDefault<Options extends { [key: string]: any; }> (options: {[key: string]: any}, defaultOptions: Options): Options {
15
+ if (isObject(options) === false || isObject(defaultOptions) === false) {
16
+ return Object.assign({}, defaultOptions)
17
+ }
18
+ const mergeObjColumns = (_options: {[key: string]: any}, _defaultOptions: {[key: string]: any}) => {
19
+ const obj: Options = (Object.assign({}, _defaultOptions) as any)
20
+ for (let key of Object.keys(_options)) {
21
+ if ((key in _defaultOptions) == false) {
22
+ continue
23
+ }
24
+ let objValue: any = undefined
25
+ // 下一層的object
26
+ if (isObject(_options[key]) && isObject(_defaultOptions[key])) {
27
+ objValue = mergeObjColumns(_options[key], _defaultOptions[key])
28
+ obj[key as keyof Options] = objValue
29
+ }
30
+ // 不是object直接賦值
31
+ else {
32
+ obj[key as keyof Options] = _options[key]
33
+ }
34
+ }
35
+ return obj
36
+ }
37
+
38
+ return mergeObjColumns(options, defaultOptions)
39
+ }
40
+
41
+ // 加上千分位 ,
42
+ export function formatCommaNumber (num = 0): string {
43
+ try {
44
+ let parts = num.toString().split('.');
45
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
46
+ return parts.join('.');
47
+ } catch (e: any) {
48
+ console.error(e)
49
+ }
50
+ }
@@ -0,0 +1,87 @@
1
+ import * as d3 from 'd3'
2
+ import { DATA_FORMATTER_VALUE_AXIS } from '../defaults'
3
+
4
+ // scaleLinear - 連續資料對應到比較尺座標上
5
+ export const createAxisLinearScale = ({
6
+ maxValue = 1,
7
+ minValue = 0,
8
+ axisWidth,
9
+ scaleDomain = DATA_FORMATTER_VALUE_AXIS.scaleDomain,
10
+ scaleRange = DATA_FORMATTER_VALUE_AXIS.scaleRange,
11
+ }: {
12
+ maxValue: number
13
+ minValue: number
14
+ axisWidth: number
15
+ scaleDomain: [number | 'auto', number | 'auto']
16
+ scaleRange: [number, number] // 0-1
17
+ }) => {
18
+
19
+ const domainMin: number | 'auto' = scaleDomain[0] ?? DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
20
+ const domainMax: number | 'auto' = scaleDomain[1] ?? DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
21
+ const rangeMin: number = scaleRange[0] ?? DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
22
+ const rangeMax: number = scaleRange[1] ?? DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
23
+
24
+ // const _minValue = domainMin === 'auto' ? minValue : domainMin
25
+ // const domainMinValue: number = maxValue - (maxValue - _minValue) / (1 - rangeMin)
26
+ // const _maxValue = domainMax === 'auto' ? maxValue : domainMax
27
+ // const domainMaxValue: number = _maxValue / rangeMax
28
+
29
+ // return d3.scaleLinear()
30
+ // .domain([domainMinValue, domainMaxValue])
31
+ // .range([0, axisWidth])
32
+
33
+ const domainMinValue = domainMin === 'auto' ? minValue : domainMin
34
+ const domainMaxValue = domainMax === 'auto' ? maxValue : domainMax
35
+ let rangeMinValue = axisWidth * rangeMin
36
+ let rangeMaxValue = axisWidth * rangeMax
37
+ // if (padding > 0) {
38
+ // const stepAmount = maxValue - minValue + (padding * 2)
39
+ // const eachStepWidth = axisWidth / stepAmount
40
+ // const paddingWidth = eachStepWidth * padding
41
+ // rangeMinValue += paddingWidth
42
+ // rangeMaxValue -= paddingWidth
43
+ // }
44
+
45
+ return d3.scaleLinear()
46
+ .domain([domainMinValue, domainMaxValue])
47
+ .range([rangeMinValue, rangeMaxValue])
48
+ }
49
+
50
+ // scalePoint - 非連續資料對應到比例尺座標上
51
+ export const createAxisPointScale = ({ axisLabels, axisWidth, padding = 0.5 }: {
52
+ axisLabels: string[]
53
+ axisWidth: number
54
+ padding?: number
55
+ // reverse?: boolean
56
+ }) => {
57
+ let range: [d3.NumberValue, d3.NumberValue] = [0, axisWidth]
58
+
59
+ return d3.scalePoint()
60
+ .domain(axisLabels)
61
+ .range(range)
62
+ .padding(padding)
63
+ }
64
+
65
+ // scaleQuantize - 比例尺座標對應非連續資料索引
66
+ export const createAxisQuantizeScale = ({ axisLabels, axisWidth, padding = 0.5, reverse = false }:{
67
+ axisLabels: string[] | Date[],
68
+ axisWidth: number
69
+ padding?: number
70
+ reverse?: boolean
71
+ }) => {
72
+ const rangePadding = 0
73
+
74
+ let range: number[] = axisLabels.map((d: string | Date, i: number) => i)
75
+ if (reverse) {
76
+ range.reverse()
77
+ }
78
+ // if (reverse) {
79
+ // range = axisLabels.map((d: string | Date, i: number) => axisLabels.length - 1 - i)
80
+ // } else {
81
+ // range = axisLabels.map((d: string | Date, i: number) => i)
82
+ // }
83
+
84
+ return d3.scaleQuantize<number>()
85
+ .domain([- rangePadding, axisWidth + rangePadding])
86
+ .range(range)
87
+ }
@@ -0,0 +1,4 @@
1
+ export * from './orbchartsUtils'
2
+ export * from './observables'
3
+ export * from './d3Utils'
4
+ export * from './commonUtils'
@@ -0,0 +1,198 @@
1
+ import {
2
+ combineLatest,
3
+ distinctUntilChanged,
4
+ filter,
5
+ map,
6
+ merge,
7
+ takeUntil,
8
+ shareReplay,
9
+ switchMap,
10
+ Subject,
11
+ Observable } from 'rxjs'
12
+ import type {
13
+ ChartType,
14
+ ChartParams,
15
+ ComputedDataTypeMap,
16
+ ComputedDatumTypeMap,
17
+ DataFormatterTypeMap,
18
+ HighlightTarget,
19
+ Layout,
20
+ TransformData } from '../types'
21
+
22
+ // interface DatumUnknown {
23
+ // value: number | null
24
+ // id: string
25
+ // // label: string
26
+ // seriesLabel?: string // 要符合每一種computedData所以不一定會有seriesLabel
27
+ // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
28
+ // }
29
+
30
+ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
31
+ datumList$: Observable<ComputedDatumTypeMap<'series' | 'grid'>[]>
32
+ fullChartParams$: Observable<ChartParams>
33
+ event$: Subject<any>
34
+ }): Observable<string[]> => {
35
+ const destroy$ = new Subject()
36
+
37
+ // 預設的highlight
38
+ const highlightDefault$ = fullChartParams$.pipe(
39
+ takeUntil(destroy$),
40
+ map(d => {
41
+ return {
42
+ id: null,
43
+ seriesLabel: null,
44
+ groupLabel: null,
45
+ highlightDefault: d.highlightDefault
46
+ }
47
+ }),
48
+ distinctUntilChanged()
49
+ )
50
+
51
+ // 事件觸發的highlight
52
+ const highlightMouseover$ = event$.pipe(
53
+ takeUntil(destroy$),
54
+ filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
55
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
56
+ map(d => {
57
+ return d.datum
58
+ ? {
59
+ id: (d.datum as any).id,
60
+ seriesLabel: (d.datum as any).seriesLabel,
61
+ groupLabel: (d.datum as any).groupLabel,
62
+ highlightDefault: null
63
+ }
64
+ : {
65
+ id: null,
66
+ seriesLabel: null,
67
+ groupLabel: null,
68
+ highlightDefault: null
69
+ }
70
+ })
71
+ )
72
+ const highlightMouseout$ = event$.pipe(
73
+ takeUntil(destroy$),
74
+ filter(d => d.eventName === 'mouseout'),
75
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
76
+ // map(d => {
77
+ // return { id: '', label: '' }
78
+ // })
79
+ switchMap(d => highlightDefault$)
80
+ )
81
+
82
+ const getHighlightIds = ({ data, id, seriesLabel, groupLabel, highlightDefault, target }: {
83
+ data: ComputedDatumTypeMap<'series' | 'grid'>[]
84
+ id: string | null
85
+ seriesLabel: string | null
86
+ groupLabel: string | null
87
+ highlightDefault: string | null
88
+ target: HighlightTarget
89
+ }) => {
90
+ let ids: string[] = []
91
+ // if (id) {
92
+ // ids.push(id)
93
+ // }
94
+ // if (label) {
95
+ // if (target === 'group') {
96
+ // const _ids = data.flat()
97
+ // .filter(d => {
98
+ // return d.groupLabel === label
99
+ // || d.label === label
100
+ // })
101
+ // .map(d => d.id)
102
+ // ids = ids.concat(_ids)
103
+ // } else if (target === 'series') {
104
+ // const _ids = data.flat()
105
+ // .filter(d => {
106
+ // return d.seriesLabel === label
107
+ // || d.label === label
108
+ // })
109
+ // .map(d => d.id)
110
+ // ids = ids.concat(_ids)
111
+ // }
112
+ // }
113
+ // 依highlightDefault找到id/seriesLabel/groupLabel
114
+ if (highlightDefault != null && highlightDefault != '') {
115
+ if (target === 'datum') {
116
+ id = highlightDefault
117
+ } else if (target === 'series') {
118
+ const datum = data.flat().find(d => d.id === highlightDefault || d.seriesLabel === highlightDefault)
119
+ seriesLabel = (datum && datum.seriesLabel) ? datum.seriesLabel : null
120
+ } else if (target === 'group') {
121
+ const datum = data.flat().find(d => d.id === highlightDefault || (d as ComputedDatumTypeMap<"grid">).groupLabel === highlightDefault)
122
+ groupLabel = (datum && (datum as ComputedDatumTypeMap<"grid">).groupLabel) ? (datum as ComputedDatumTypeMap<"grid">).groupLabel : null
123
+ }
124
+ }
125
+ if (target === 'datum' && id != null && id != '') {
126
+ ids.push(id)
127
+ } else if (target === 'series' && seriesLabel != null && seriesLabel != '') {
128
+ const _ids = data.flat()
129
+ .filter(d => {
130
+ return d.seriesLabel === seriesLabel
131
+ })
132
+ .map(d => d.id)
133
+ ids = ids.concat(_ids)
134
+ } else if (target === 'group' && groupLabel != null && groupLabel != '') {
135
+ const _ids = data.flat()
136
+ .filter(d => {
137
+ return (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel
138
+ })
139
+ .map(d => d.id)
140
+ ids = ids.concat(_ids)
141
+ }
142
+
143
+ return ids
144
+ }
145
+
146
+ return new Observable<string[]>(subscriber => {
147
+ combineLatest({
148
+ target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
149
+ datumList: datumList$,
150
+ fullChartParams: fullChartParams$,
151
+ }).pipe(
152
+ takeUntil(destroy$)
153
+ ).subscribe(data => {
154
+ const ids = getHighlightIds({
155
+ data: data.datumList,
156
+ id: data.target.id,
157
+ seriesLabel: data.target.seriesLabel,
158
+ groupLabel: data.target.groupLabel,
159
+ highlightDefault: data.target.highlightDefault,
160
+ target: data.fullChartParams.highlightTarget,
161
+ })
162
+ subscriber.next(ids)
163
+ })
164
+
165
+ return function unsubscribe () {
166
+ destroy$.next(undefined)
167
+ }
168
+ })
169
+ }
170
+
171
+ export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<ChartType>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
172
+ return datumList$.pipe(
173
+ map(data => {
174
+ const SeriesDataMap: Map<string, DatumType[]> = new Map()
175
+ data.forEach(d => {
176
+ const seriesData = SeriesDataMap.get((d as ComputedDatumTypeMap<'series' | 'grid'>).seriesLabel) ?? []
177
+ seriesData.push(d)
178
+ SeriesDataMap.set((d as ComputedDatumTypeMap<'series' | 'grid'>).seriesLabel, seriesData)
179
+ })
180
+ return SeriesDataMap
181
+ })
182
+ )
183
+ }
184
+
185
+ export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<ChartType>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
186
+ return datumList$.pipe(
187
+ map(data => {
188
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
189
+ data.forEach(d => {
190
+ const groupData = GroupDataMap.get((d as ComputedDatumTypeMap<'grid'>).groupLabel) ?? []
191
+ groupData.push(d)
192
+ GroupDataMap.set((d as ComputedDatumTypeMap<'grid'>).groupLabel, groupData)
193
+ })
194
+ return GroupDataMap
195
+ })
196
+ )
197
+ }
198
+
@@ -0,0 +1,150 @@
1
+ import * as d3 from 'd3'
2
+ import type { DatumBase, DatumValue } from '../types/Data'
3
+ import type { DataSeries, DataSeriesDatum, DataSeriesValue } from '../types/DataSeries'
4
+ import type { DataGrid, DataGridDatum, DataGridValue } from '../types/DataGrid'
5
+ import type { DataMultiGrid } from '../types/DataMultiGrid'
6
+ import type { DataMultiValue, DataMultiValueDatum, DataMultiValueValue } from '../types/DataMultiValue'
7
+ import type { SeriesType, DataFormatterGrid } from '../types/DataFormatterGrid'
8
+ import { isObject } from './commonUtils'
9
+
10
+ export function formatValueToLabel (value: any, valueFormatter: string | ((text: d3.NumberValue) => string)) {
11
+ if (valueFormatter! instanceof Function == true) {
12
+ return (valueFormatter as ((text: d3.NumberValue) => string))(value)
13
+ }
14
+ return d3.format(valueFormatter as string)!(value)
15
+ }
16
+
17
+ export function createDefaultDatumId (type: string, levelOneIndex: number, levelTwoIndex: number) {
18
+ return `${type}_${levelOneIndex}_${levelTwoIndex}`
19
+ }
20
+
21
+ export function createDefaultSeriesLabel (type: string, seriesIndex: number) {
22
+ return `${type}_series${seriesIndex}`
23
+ }
24
+
25
+ export function createDefaultGroupLabel (type: string, groupIndex: number) {
26
+ return `${type}_group${groupIndex}`
27
+ }
28
+
29
+ export function createGridSeriesLabels (transposedDataGrid: DataGridDatum[][], dataFormatter: DataFormatterGrid) {
30
+ const labels = dataFormatter.grid.seriesType === 'row'
31
+ ? dataFormatter.grid.rowLabels
32
+ : dataFormatter.grid.columnLabels
33
+ return transposedDataGrid.map((_, rowIndex) => {
34
+ return labels[rowIndex] != null
35
+ ? labels[rowIndex]
36
+ : createDefaultSeriesLabel('grid', rowIndex)
37
+ })
38
+ }
39
+
40
+ export function createGridGroupLabels (transposedDataGrid: DataGridDatum[][], dataFormatter: DataFormatterGrid) {
41
+ if (transposedDataGrid[0] == null) {
42
+ return []
43
+ }
44
+ const labels = dataFormatter.grid.seriesType === 'row'
45
+ ? dataFormatter.grid.columnLabels
46
+ : dataFormatter.grid.rowLabels
47
+ return transposedDataGrid[0].map((_, columnLabels) => {
48
+ return labels[columnLabels] != null
49
+ ? labels[columnLabels]
50
+ : createDefaultGroupLabel('grid', columnLabels)
51
+ })
52
+ }
53
+
54
+ // 取得最小及最大值 - 數字陣列
55
+ export function getMinAndMax (data: number[]): [number, number] {
56
+ const defaultMinAndMax: [number, number] = [0, 0] // default
57
+ if (!data.length) {
58
+ return defaultMinAndMax
59
+ }
60
+ const minAndMax: [number, number] = data.reduce((prev, current) => {
61
+ // [min, max]
62
+ return [
63
+ current < prev[0] ? current : prev[0],
64
+ current > prev[1] ? current : prev[1]
65
+ ]
66
+ }, [data[0], data[0]])
67
+ return minAndMax
68
+ }
69
+
70
+ // 取得最小及最大值 - datum格式陣列資料
71
+ export function getMinAndMaxValue (data: DatumValue[]): [number, number] {
72
+ const arr = data
73
+ .filter(d => d != null && d.value != null)
74
+ .map(d => d.value )
75
+ return getMinAndMax(arr)
76
+ }
77
+
78
+ // 取得最小及最大值 - Series Data
79
+ export function getMinAndMaxSeries (data: DataSeries): [number, number] {
80
+ const flatData: (DataSeriesValue | DataSeriesDatum)[] = data[0] && Array.isArray((data as (DataSeriesValue | DataSeriesDatum)[][])[0])
81
+ ? data.flat()
82
+ : data as (DataSeriesValue | DataSeriesDatum)[]
83
+ const arr = flatData
84
+ .filter(d => (d == null || (isObject(d) && (d as DataSeriesDatum).value == null)) === false) // 過濾掉null &
85
+ .map(d => typeof d === 'number' ? d : d.value )
86
+ return getMinAndMax(arr)
87
+ }
88
+
89
+ // 取得最小及最大值 - Grid Data
90
+ export function getMinAndMaxGrid (data: DataGrid): [number, number] {
91
+ const flatData: (DataGridValue | DataGridDatum)[] = data.flat()
92
+ const arr = flatData
93
+ .filter(d => (d == null || (isObject(d) && (d as DataGridDatum).value == null)) === false) // 過濾掉null
94
+ .map(d => typeof d === 'number' ? d : d.value )
95
+ return getMinAndMax(arr)
96
+ }
97
+
98
+ // 取得最小及最大值 - MultiGrid Data
99
+ export function getMinAndMaxMultiGrid (data: DataMultiGrid): [number, number] {
100
+ const flatData: (DataGridValue | DataGridDatum)[] = data.flat().flat()
101
+ const arr = flatData
102
+ .filter(d => (d == null || (isObject(d) && (d as DataGridDatum).value == null)) === false) // 過濾掉null
103
+ .map(d => typeof d === 'number' ? d : d.value )
104
+ return getMinAndMax(arr)
105
+ }
106
+
107
+ // 取得最小及最大值 - MultiValue Data
108
+ export function getMinAndMaxMultiValue (data: DataMultiValue, valueIndex: number = 2): [number, number] {
109
+ const flatData: (DataMultiValueDatum | DataMultiValueValue)[] = data.flat().filter((d, i) => i == valueIndex)
110
+ const arr = flatData
111
+ .filter(d => (d == null || (isObject(d) && (d as DataMultiValueDatum).value == null)) === false) // 過濾掉null
112
+ .map(d => typeof d === 'number' ? d : d.value )
113
+ return getMinAndMax(arr)
114
+ }
115
+
116
+ // @Q@ 待處理
117
+ // // 取得最小及最大值 - Relationship Data
118
+ // export function getMinAndMaxRelationship (data: DataRelationship, target: 'nodes' | 'edges' = 'nodes'): [number, number] {
119
+
120
+ // }
121
+
122
+ // @Q@ 待處理
123
+ // // 取得最小及最大值 - Tree Data
124
+ // export function getMinAndMaxTree (data: DataTree): [number, number] {
125
+
126
+ // }
127
+
128
+ // 轉置成seriesType為main的陣列格式
129
+ export function transposeData<T> (seriesType: SeriesType, data: T[][]): T[][] {
130
+ if (seriesType === 'row') {
131
+ return Object.assign([], data)
132
+ }
133
+ // 取得原始陣列的維度
134
+ const rows = data.length;
135
+ const cols = data.reduce((prev, current) => {
136
+ return Math.max(prev, current.length)
137
+ }, 0)
138
+
139
+ // 初始化轉換後的陣列
140
+ const transposedArray = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
141
+
142
+ // 遍歷原始陣列,進行轉換
143
+ for (let i = 0; i < rows; i++) {
144
+ for (let j = 0; j < cols; j++) {
145
+ transposedArray[j][i] = data[i][j]
146
+ }
147
+ }
148
+
149
+ return transposedArray
150
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist/",
4
+ "sourceMap": true,
5
+ "noImplicitAny": true,
6
+ "module": "es6",
7
+ "target": "es5",
8
+ "jsx": "react",
9
+ "allowJs": true,
10
+ "moduleResolution": "node",
11
+ "allowSyntheticDefaultImports" : true,
12
+ "esModuleInterop" : true
13
+ }
14
+ }
package/vite.config.js ADDED
@@ -0,0 +1,45 @@
1
+ // import { fileURLToPath, URL } from 'node:url'
2
+
3
+ // import { resolve } from 'path'
4
+ import { defineConfig } from 'vite'
5
+ import dts from 'vite-plugin-dts'
6
+
7
+ const releaseConfig = {
8
+ plugins: [
9
+ dts({
10
+ insertTypesEntry: true
11
+ })
12
+ ],
13
+ compilerOptions: {
14
+ composite: true
15
+ },
16
+ build: {
17
+ lib: {
18
+ entry: "src/index.ts",
19
+ name: 'orbcharts-core',
20
+ formats: ["es", "umd"],
21
+ fileName: format => `orbcharts-core.${format}.js`
22
+ },
23
+ // rollupOptions: {
24
+ // input: {
25
+ // main: resolve(__dirname, "src/index.ts")
26
+ // },
27
+ // external: ['vue'],
28
+ // output: {
29
+ // assetFileNames: 'my-library.css',
30
+ // exports: "named",
31
+ // globals: {
32
+ // vue: 'Vue',
33
+ // },
34
+ // },
35
+ // },
36
+ }
37
+ }
38
+
39
+ export default defineConfig(({ command, mode }) => {
40
+ if (mode === 'release') {
41
+ return releaseConfig
42
+ } else {
43
+ return releaseConfig
44
+ }
45
+ })