@orbcharts/core 3.0.0-alpha.60 → 3.0.0-alpha.62

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. package/LICENSE +200 -200
  2. package/dist/lib/core-types.d.ts +1 -0
  3. package/dist/orbcharts-core.es.js +3056 -2609
  4. package/dist/orbcharts-core.umd.js +6 -2
  5. package/dist/src/AbstractChart.d.ts +5 -3
  6. package/dist/src/GridChart.d.ts +1 -1
  7. package/dist/src/MultiGridChart.d.ts +1 -1
  8. package/dist/src/MultiValueChart.d.ts +1 -1
  9. package/dist/src/RelationshipChart.d.ts +1 -1
  10. package/dist/src/SeriesChart.d.ts +1 -1
  11. package/dist/src/TreeChart.d.ts +1 -1
  12. package/dist/src/base/createBaseChart.d.ts +1 -1
  13. package/dist/src/base/createBasePlugin.d.ts +1 -1
  14. package/dist/src/base/validators/chartOptionsValidator.d.ts +3 -0
  15. package/dist/src/base/validators/chartParamsValidator.d.ts +3 -0
  16. package/dist/src/base/validators/elementValidator.d.ts +3 -0
  17. package/dist/src/base/validators/pluginsValidator.d.ts +3 -0
  18. package/dist/src/defaults.d.ts +1 -16
  19. package/dist/src/defineGridPlugin.d.ts +1 -1
  20. package/dist/src/defineMultiGridPlugin.d.ts +1 -1
  21. package/dist/src/defineMultiValuePlugin.d.ts +1 -1
  22. package/dist/src/defineNoneDataPlugin.d.ts +1 -1
  23. package/dist/src/defineRelationshipPlugin.d.ts +1 -1
  24. package/dist/src/defineSeriesPlugin.d.ts +1 -1
  25. package/dist/src/defineTreePlugin.d.ts +1 -1
  26. package/dist/src/grid/computedDataFn.d.ts +4 -0
  27. package/dist/src/grid/contextObserverCallback.d.ts +3 -0
  28. package/dist/src/grid/dataFormatterValidator.d.ts +3 -0
  29. package/dist/src/grid/dataValidator.d.ts +3 -0
  30. package/dist/src/index.d.ts +1 -1
  31. package/dist/src/multiGrid/computedDataFn.d.ts +3 -0
  32. package/dist/src/multiGrid/contextObserverCallback.d.ts +3 -0
  33. package/dist/src/multiGrid/dataFormatterValidator.d.ts +3 -0
  34. package/dist/src/multiGrid/dataValidator.d.ts +3 -0
  35. package/dist/src/multiValue/computedDataFn.d.ts +3 -0
  36. package/dist/src/multiValue/contextObserverCallback.d.ts +3 -0
  37. package/dist/src/multiValue/dataFormatterValidator.d.ts +3 -0
  38. package/dist/src/multiValue/dataValidator.d.ts +3 -0
  39. package/dist/src/relationship/computedDataFn.d.ts +3 -0
  40. package/dist/src/relationship/contextObserverCallback.d.ts +3 -0
  41. package/dist/src/relationship/dataFormatterValidator.d.ts +3 -0
  42. package/dist/src/relationship/dataValidator.d.ts +3 -0
  43. package/dist/src/series/computedDataFn.d.ts +3 -0
  44. package/dist/src/series/contextObserverCallback.d.ts +3 -0
  45. package/dist/src/series/dataFormatterValidator.d.ts +3 -0
  46. package/dist/src/series/dataValidator.d.ts +3 -0
  47. package/dist/src/tree/computedDataFn.d.ts +3 -0
  48. package/dist/src/tree/contextObserverCallback.d.ts +3 -0
  49. package/dist/src/tree/dataFormatterValidator.d.ts +3 -0
  50. package/dist/src/tree/dataValidator.d.ts +3 -0
  51. package/dist/src/utils/commonUtils.d.ts +1 -0
  52. package/dist/src/utils/errorMessage.d.ts +14 -0
  53. package/dist/src/{grid → utils}/gridObservables.d.ts +2 -2
  54. package/dist/src/utils/index.d.ts +7 -3
  55. package/dist/src/{multiGrid → utils}/multiGridObservables.d.ts +1 -1
  56. package/dist/src/utils/observables.d.ts +2 -1
  57. package/dist/src/utils/orbchartsUtils.d.ts +1 -12
  58. package/dist/src/{series → utils}/seriesObservables.d.ts +3 -3
  59. package/dist/src/{tree → utils}/treeObservables.d.ts +1 -1
  60. package/dist/src/utils/validator.d.ts +3 -0
  61. package/lib/core-types.ts +7 -0
  62. package/package.json +42 -41
  63. package/src/AbstractChart.ts +57 -48
  64. package/src/GridChart.ts +24 -20
  65. package/src/MultiGridChart.ts +24 -20
  66. package/src/MultiValueChart.ts +24 -20
  67. package/src/RelationshipChart.ts +24 -20
  68. package/src/SeriesChart.ts +24 -20
  69. package/src/TreeChart.ts +24 -20
  70. package/src/base/createBaseChart.ts +500 -386
  71. package/src/base/createBasePlugin.ts +152 -95
  72. package/src/base/validators/chartOptionsValidator.ts +24 -0
  73. package/src/base/validators/chartParamsValidator.ts +134 -0
  74. package/src/base/validators/elementValidator.ts +14 -0
  75. package/src/base/validators/pluginsValidator.ts +15 -0
  76. package/src/defaults.ts +232 -226
  77. package/src/defineGridPlugin.ts +3 -3
  78. package/src/defineMultiGridPlugin.ts +3 -3
  79. package/src/defineMultiValuePlugin.ts +3 -3
  80. package/src/defineNoneDataPlugin.ts +4 -4
  81. package/src/defineRelationshipPlugin.ts +3 -3
  82. package/src/defineSeriesPlugin.ts +3 -3
  83. package/src/defineTreePlugin.ts +3 -3
  84. package/src/grid/{computeGridData.ts → computedDataFn.ts} +129 -134
  85. package/src/grid/{createGridContextObserver.ts → contextObserverCallback.ts} +155 -155
  86. package/src/grid/dataFormatterValidator.ts +9 -0
  87. package/src/grid/dataValidator.ts +9 -0
  88. package/src/index.ts +20 -21
  89. package/src/multiGrid/{computeMultiGridData.ts → computedDataFn.ts} +123 -130
  90. package/src/multiGrid/{createMultiGridContextObserver.ts → contextObserverCallback.ts} +41 -41
  91. package/src/multiGrid/dataFormatterValidator.ts +9 -0
  92. package/src/multiGrid/dataValidator.ts +9 -0
  93. package/src/multiValue/{computeMultiValueData.ts → computedDataFn.ts} +176 -179
  94. package/src/multiValue/{createMultiValueContextObserver.ts → contextObserverCallback.ts} +12 -12
  95. package/src/multiValue/dataFormatterValidator.ts +9 -0
  96. package/src/multiValue/dataValidator.ts +9 -0
  97. package/src/relationship/{computeRelationshipData.ts → computedDataFn.ts} +125 -118
  98. package/src/relationship/{createRelationshipContextObserver.ts → contextObserverCallback.ts} +12 -12
  99. package/src/relationship/dataFormatterValidator.ts +9 -0
  100. package/src/relationship/dataValidator.ts +9 -0
  101. package/src/series/{computeSeriesData.ts → computedDataFn.ts} +88 -90
  102. package/src/series/{createSeriesContextObserver.ts → contextObserverCallback.ts} +100 -93
  103. package/src/series/dataFormatterValidator.ts +9 -0
  104. package/src/series/dataValidator.ts +9 -0
  105. package/src/tree/{computeTreeData.ts → computedDataFn.ts} +130 -132
  106. package/src/tree/{createTreeContextObserver.ts → contextObserverCallback.ts} +61 -61
  107. package/src/tree/dataFormatterValidator.ts +9 -0
  108. package/src/tree/dataValidator.ts +9 -0
  109. package/src/utils/commonUtils.ts +54 -50
  110. package/src/utils/d3Utils.ts +108 -108
  111. package/src/utils/errorMessage.ts +43 -0
  112. package/src/{grid → utils}/gridObservables.ts +611 -614
  113. package/src/utils/index.ts +10 -4
  114. package/src/{multiGrid → utils}/multiGridObservables.ts +366 -365
  115. package/src/utils/observables.ts +218 -202
  116. package/src/utils/orbchartsUtils.ts +352 -349
  117. package/src/{series → utils}/seriesObservables.ts +175 -175
  118. package/src/{tree → utils}/treeObservables.ts +94 -94
  119. package/src/utils/validator.ts +126 -0
  120. package/tsconfig.base.json +13 -13
  121. package/tsconfig.json +2 -2
  122. package/vite-env.d.ts +7 -0
  123. package/vite.config.js +22 -22
  124. package/dist/src/grid/computeGridData.d.ts +0 -6
  125. package/dist/src/grid/createGridContextObserver.d.ts +0 -3
  126. package/dist/src/multiGrid/computeMultiGridData.d.ts +0 -3
  127. package/dist/src/multiGrid/createMultiGridContextObserver.d.ts +0 -3
  128. package/dist/src/multiValue/computeMultiValueData.d.ts +0 -3
  129. package/dist/src/multiValue/createMultiValueContextObserver.d.ts +0 -3
  130. package/dist/src/relationship/computeRelationshipData.d.ts +0 -3
  131. package/dist/src/relationship/createRelationshipContextObserver.d.ts +0 -3
  132. package/dist/src/series/computeSeriesData.d.ts +0 -3
  133. package/dist/src/series/createSeriesContextObserver.d.ts +0 -3
  134. package/dist/src/tree/computeTreeData.d.ts +0 -3
  135. package/dist/src/tree/createTreeContextObserver.d.ts +0 -3
  136. package/dist/src/types/Axis.d.ts +0 -1
  137. package/dist/src/types/Chart.d.ts +0 -45
  138. package/dist/src/types/ChartParams.d.ts +0 -36
  139. package/dist/src/types/ComputedData.d.ts +0 -42
  140. package/dist/src/types/ComputedDataGrid.d.ts +0 -5
  141. package/dist/src/types/ComputedDataMultiGrid.d.ts +0 -3
  142. package/dist/src/types/ComputedDataMultiValue.d.ts +0 -6
  143. package/dist/src/types/ComputedDataRelationship.d.ts +0 -18
  144. package/dist/src/types/ComputedDataSeries.d.ts +0 -5
  145. package/dist/src/types/ComputedDataTree.d.ts +0 -7
  146. package/dist/src/types/ContextObserver.d.ts +0 -28
  147. package/dist/src/types/ContextObserverGrid.d.ts +0 -41
  148. package/dist/src/types/ContextObserverMultiGrid.d.ts +0 -15
  149. package/dist/src/types/ContextObserverMultiValue.d.ts +0 -4
  150. package/dist/src/types/ContextObserverRelationship.d.ts +0 -4
  151. package/dist/src/types/ContextObserverSeries.d.ts +0 -27
  152. package/dist/src/types/ContextObserverTree.d.ts +0 -11
  153. package/dist/src/types/ContextSubject.d.ts +0 -15
  154. package/dist/src/types/Data.d.ts +0 -19
  155. package/dist/src/types/DataFormatter.d.ts +0 -41
  156. package/dist/src/types/DataFormatterGrid.d.ts +0 -34
  157. package/dist/src/types/DataFormatterMultiGrid.d.ts +0 -20
  158. package/dist/src/types/DataFormatterMultiValue.d.ts +0 -18
  159. package/dist/src/types/DataFormatterRelationship.d.ts +0 -10
  160. package/dist/src/types/DataFormatterSeries.d.ts +0 -19
  161. package/dist/src/types/DataFormatterTree.d.ts +0 -7
  162. package/dist/src/types/DataGrid.d.ts +0 -6
  163. package/dist/src/types/DataMultiGrid.d.ts +0 -6
  164. package/dist/src/types/DataMultiValue.d.ts +0 -7
  165. package/dist/src/types/DataRelationship.d.ts +0 -21
  166. package/dist/src/types/DataSeries.d.ts +0 -6
  167. package/dist/src/types/DataTree.d.ts +0 -15
  168. package/dist/src/types/Event.d.ts +0 -56
  169. package/dist/src/types/Layout.d.ts +0 -8
  170. package/dist/src/types/Padding.d.ts +0 -6
  171. package/dist/src/types/Plugin.d.ts +0 -37
  172. package/dist/src/types/TransformData.d.ts +0 -8
  173. package/dist/src/types/index.d.ts +0 -37
  174. package/src/types/Axis.ts +0 -1
  175. package/src/types/Chart.ts +0 -54
  176. package/src/types/ChartParams.ts +0 -51
  177. package/src/types/ComputedData.ts +0 -84
  178. package/src/types/ComputedDataGrid.ts +0 -14
  179. package/src/types/ComputedDataMultiGrid.ts +0 -3
  180. package/src/types/ComputedDataMultiValue.ts +0 -9
  181. package/src/types/ComputedDataRelationship.ts +0 -20
  182. package/src/types/ComputedDataSeries.ts +0 -8
  183. package/src/types/ComputedDataTree.ts +0 -20
  184. package/src/types/ContextObserver.ts +0 -38
  185. package/src/types/ContextObserverGrid.ts +0 -43
  186. package/src/types/ContextObserverMultiGrid.ts +0 -17
  187. package/src/types/ContextObserverMultiValue.ts +0 -5
  188. package/src/types/ContextObserverRelationship.ts +0 -5
  189. package/src/types/ContextObserverSeries.ts +0 -29
  190. package/src/types/ContextObserverTree.ts +0 -11
  191. package/src/types/ContextSubject.ts +0 -18
  192. package/src/types/Data.ts +0 -45
  193. package/src/types/DataFormatter.ts +0 -74
  194. package/src/types/DataFormatterGrid.ts +0 -68
  195. package/src/types/DataFormatterMultiGrid.ts +0 -45
  196. package/src/types/DataFormatterMultiValue.ts +0 -24
  197. package/src/types/DataFormatterRelationship.ts +0 -26
  198. package/src/types/DataFormatterSeries.ts +0 -20
  199. package/src/types/DataFormatterTree.ts +0 -12
  200. package/src/types/DataGrid.ts +0 -11
  201. package/src/types/DataMultiGrid.ts +0 -7
  202. package/src/types/DataMultiValue.ts +0 -12
  203. package/src/types/DataRelationship.ts +0 -28
  204. package/src/types/DataSeries.ts +0 -11
  205. package/src/types/DataTree.ts +0 -20
  206. package/src/types/Event.ts +0 -153
  207. package/src/types/Layout.ts +0 -12
  208. package/src/types/Padding.ts +0 -6
  209. package/src/types/Plugin.ts +0 -60
  210. package/src/types/TransformData.ts +0 -8
  211. package/src/types/index.ts +0 -37
  212. /package/dist/src/{multiValue → utils}/multiValueObservables.d.ts +0 -0
  213. /package/dist/src/{relationship → utils}/relationshipObservables.d.ts +0 -0
  214. /package/src/{multiValue → utils}/multiValueObservables.ts +0 -0
  215. /package/src/{relationship → utils}/relationshipObservables.ts +0 -0
@@ -1,203 +1,219 @@
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
- EventTypeMap,
19
- HighlightTarget,
20
- Layout,
21
- TransformData } from '../types'
22
-
23
- // interface DatumUnknown {
24
- // value: number | null
25
- // id: string
26
- // // label: string
27
- // seriesLabel?: string // 要符合每一種computedData所以不一定會有seriesLabel
28
- // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
29
- // }
30
-
31
- // 通用 highlight Observable
32
- export const highlightObservable = <T extends ChartType, D>({ datumList$, fullChartParams$, event$ }: {
33
- datumList$: Observable<D[]>
34
- fullChartParams$: Observable<ChartParams>
35
- event$: Subject<EventTypeMap<T>>
36
- }): Observable<D[]> => {
37
- const destroy$ = new Subject()
38
-
39
- // 預設的highlight
40
- const highlightDefault$ = fullChartParams$.pipe(
41
- takeUntil(destroy$),
42
- map(d => {
43
- return {
44
- id: null,
45
- seriesLabel: null,
46
- groupLabel: null,
47
- categoryLabel: null,
48
- highlightDefault: d.highlightDefault
49
- }
50
- }),
51
- distinctUntilChanged()
52
- )
53
-
54
- // 事件觸發的highlight
55
- const highlightMouseover$ = event$.pipe(
56
- takeUntil(destroy$),
57
- // filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
58
- filter(d => d.eventName === 'mouseover'),
59
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
60
- map(d => {
61
- return d.datum
62
- ? {
63
- id: (d.datum as any).id,
64
- seriesLabel: (d.datum as any).seriesLabel,
65
- groupLabel: (d.datum as any).groupLabel,
66
- categoryLabel: (d.datum as any).categoryLabel,
67
- highlightDefault: null
68
- }
69
- : {
70
- id: null,
71
- seriesLabel: null,
72
- groupLabel: null,
73
- categoryLabel: null,
74
- highlightDefault: null
75
- }
76
- })
77
- )
78
- const highlightMouseout$ = event$.pipe(
79
- takeUntil(destroy$),
80
- filter(d => d.eventName === 'mouseout'),
81
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
82
- // map(d => {
83
- // return { id: '', label: '' }
84
- // })
85
- switchMap(d => highlightDefault$)
86
- )
87
-
88
- function getDatumIds (datumList: ComputedDatumTypeMap<T>[], id: string | null) {
89
- const datum = datumList.find(d => d.id === id)
90
- return datum ? [datum] : []
91
- }
92
-
93
- function getSeriesIds (datumList: ComputedDatumTypeMap<T>[], seriesLabel: string | null) {
94
- return seriesLabel == null
95
- ? []
96
- : datumList.filter(d => (d as ComputedDatumTypeMap<"series">).seriesLabel === seriesLabel)
97
- }
98
-
99
- function getGroupIds (datumList: ComputedDatumTypeMap<T>[], groupLabel: string | null) {
100
- return groupLabel == null
101
- ? []
102
- : datumList.filter(d => (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel)
103
- }
104
-
105
- function getCategoryIds (datumList: ComputedDatumTypeMap<T>[], categoryLabel: string | null) {
106
- return categoryLabel == null
107
- ? []
108
- : datumList.filter(d => (d as ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">).categoryLabel === categoryLabel)
109
- }
110
-
111
- return new Observable<D[]>(subscriber => {
112
- combineLatest({
113
- target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
114
- datumList: datumList$,
115
- fullChartParams: fullChartParams$,
116
- }).pipe(
117
- takeUntil(destroy$),
118
- switchMap(async d => d)
119
- ).subscribe(data => {
120
- let datumList: ComputedDatumTypeMap<T>[] = []
121
- if (data.fullChartParams.highlightTarget === 'datum') {
122
- datumList = getDatumIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.id)
123
- } else if (data.fullChartParams.highlightTarget === 'series') {
124
- datumList = getSeriesIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.seriesLabel)
125
- } else if (data.fullChartParams.highlightTarget === 'group') {
126
- datumList = getGroupIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.groupLabel)
127
- } else if (data.fullChartParams.highlightTarget === 'category') {
128
- datumList = getCategoryIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.categoryLabel)
129
- }
130
- subscriber.next(datumList as D[])
131
- })
132
-
133
- return function unsubscribe () {
134
- destroy$.next(undefined)
135
- }
136
- })
137
- }
138
-
139
- export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<'series' | 'grid'>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
140
- return datumList$.pipe(
141
- map(data => {
142
- const SeriesDataMap: Map<string, DatumType[]> = new Map()
143
- data.forEach(d => {
144
- const seriesData = SeriesDataMap.get(d.seriesLabel) ?? []
145
- seriesData.push(d)
146
- SeriesDataMap.set(d.seriesLabel, seriesData)
147
- })
148
- return SeriesDataMap
149
- })
150
- )
151
- }
152
-
153
- export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<'grid'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
154
- return datumList$.pipe(
155
- map(data => {
156
- const GroupDataMap: Map<string, DatumType[]> = new Map()
157
- data.forEach(d => {
158
- const groupData = GroupDataMap.get(d.groupLabel) ?? []
159
- groupData.push(d)
160
- GroupDataMap.set(d.groupLabel, groupData)
161
- })
162
- return GroupDataMap
163
- })
164
- )
165
- }
166
-
167
- export const categoryDataMapObservable = <DatumType extends ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
168
- return datumList$.pipe(
169
- map(data => {
170
- const GroupDataMap: Map<string, DatumType[]> = new Map()
171
- data
172
- .filter(d => d.categoryLabel != null)
173
- .forEach(d => {
174
- const groupData = GroupDataMap.get(d.categoryLabel) ?? []
175
- groupData.push(d)
176
- GroupDataMap.set(d.categoryLabel, groupData)
177
- })
178
- return GroupDataMap
179
- })
180
- )
181
- }
182
-
183
- export const textSizePxObservable = (chartParams$: Observable<ChartParams>) => {
184
- return chartParams$.pipe(
185
- map(d => d.styles.textSize),
186
- distinctUntilChanged(),
187
- map(data => {
188
- let value = NaN
189
- if (typeof data === 'string') {
190
- if (data.includes('rem')) {
191
- const rootFontSizePx = parseFloat(getComputedStyle(document.documentElement).fontSize)
192
- const num = parseFloat(data)
193
- value = num * rootFontSizePx
194
- } else if (data.includes('px')) {
195
- value = parseFloat(data)
196
- }
197
- } else if (typeof data === 'number') {
198
- return data
199
- }
200
- return value ? value : 14 // default
201
- })
202
- )
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
+ EventTypeMap,
19
+ HighlightTarget,
20
+ Layout,
21
+ TransformData } from '../../lib/core-types'
22
+
23
+ // interface DatumUnknown {
24
+ // value: number | null
25
+ // id: string
26
+ // // label: string
27
+ // seriesLabel?: string // 要符合每一種computedData所以不一定會有seriesLabel
28
+ // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
29
+ // }
30
+
31
+ export function resizeObservable(elem: HTMLElement | Element): Observable<DOMRectReadOnly> {
32
+ return new Observable(subscriber => {
33
+ const ro = new ResizeObserver(entries => {
34
+ const entry = entries[0]
35
+ if (entry && entry.contentRect) {
36
+ subscriber.next(entry.contentRect)
37
+ }
38
+ })
39
+
40
+ ro.observe(elem)
41
+ return function unsubscribe() {
42
+ ro.unobserve(elem)
43
+ }
44
+ })
45
+ }
46
+
47
+ // 通用 highlight Observable
48
+ export const highlightObservable = <T extends ChartType, D>({ datumList$, fullChartParams$, event$ }: {
49
+ datumList$: Observable<D[]>
50
+ fullChartParams$: Observable<ChartParams>
51
+ event$: Subject<EventTypeMap<T>>
52
+ }): Observable<D[]> => {
53
+ const destroy$ = new Subject()
54
+
55
+ // 預設的highlight
56
+ const highlightDefault$ = fullChartParams$.pipe(
57
+ takeUntil(destroy$),
58
+ map(d => {
59
+ return {
60
+ id: null,
61
+ seriesLabel: null,
62
+ groupLabel: null,
63
+ categoryLabel: null,
64
+ highlightDefault: d.highlightDefault
65
+ }
66
+ }),
67
+ distinctUntilChanged()
68
+ )
69
+
70
+ // 事件觸發的highlight
71
+ const highlightMouseover$ = event$.pipe(
72
+ takeUntil(destroy$),
73
+ // filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
74
+ filter(d => d.eventName === 'mouseover'),
75
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
76
+ map(d => {
77
+ return d.datum
78
+ ? {
79
+ id: (d.datum as any).id,
80
+ seriesLabel: (d.datum as any).seriesLabel,
81
+ groupLabel: (d.datum as any).groupLabel,
82
+ categoryLabel: (d.datum as any).categoryLabel,
83
+ highlightDefault: null
84
+ }
85
+ : {
86
+ id: null,
87
+ seriesLabel: null,
88
+ groupLabel: null,
89
+ categoryLabel: null,
90
+ highlightDefault: null
91
+ }
92
+ })
93
+ )
94
+ const highlightMouseout$ = event$.pipe(
95
+ takeUntil(destroy$),
96
+ filter(d => d.eventName === 'mouseout'),
97
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
98
+ // map(d => {
99
+ // return { id: '', label: '' }
100
+ // })
101
+ switchMap(d => highlightDefault$)
102
+ )
103
+
104
+ function getDatumIds (datumList: ComputedDatumTypeMap<T>[], id: string | null) {
105
+ const datum = datumList.find(d => d.id === id)
106
+ return datum ? [datum] : []
107
+ }
108
+
109
+ function getSeriesIds (datumList: ComputedDatumTypeMap<T>[], seriesLabel: string | null) {
110
+ return seriesLabel == null
111
+ ? []
112
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"series">).seriesLabel === seriesLabel)
113
+ }
114
+
115
+ function getGroupIds (datumList: ComputedDatumTypeMap<T>[], groupLabel: string | null) {
116
+ return groupLabel == null
117
+ ? []
118
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel)
119
+ }
120
+
121
+ function getCategoryIds (datumList: ComputedDatumTypeMap<T>[], categoryLabel: string | null) {
122
+ return categoryLabel == null
123
+ ? []
124
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">).categoryLabel === categoryLabel)
125
+ }
126
+
127
+ return new Observable<D[]>(subscriber => {
128
+ combineLatest({
129
+ target: merge(highlightMouseover$, highlightMouseout$, highlightDefault$),
130
+ datumList: datumList$,
131
+ fullChartParams: fullChartParams$,
132
+ }).pipe(
133
+ takeUntil(destroy$),
134
+ switchMap(async d => d)
135
+ ).subscribe(data => {
136
+ let datumList: ComputedDatumTypeMap<T>[] = []
137
+ if (data.fullChartParams.highlightTarget === 'datum') {
138
+ datumList = getDatumIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.id)
139
+ } else if (data.fullChartParams.highlightTarget === 'series') {
140
+ datumList = getSeriesIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.seriesLabel)
141
+ } else if (data.fullChartParams.highlightTarget === 'group') {
142
+ datumList = getGroupIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.groupLabel)
143
+ } else if (data.fullChartParams.highlightTarget === 'category') {
144
+ datumList = getCategoryIds(data.datumList as ComputedDatumTypeMap<T>[], data.target.categoryLabel)
145
+ }
146
+ subscriber.next(datumList as D[])
147
+ })
148
+
149
+ return function unsubscribe () {
150
+ destroy$.next(undefined)
151
+ }
152
+ })
153
+ }
154
+
155
+ export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<'series' | 'grid'>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
156
+ return datumList$.pipe(
157
+ map(data => {
158
+ const SeriesDataMap: Map<string, DatumType[]> = new Map()
159
+ data.forEach(d => {
160
+ const seriesData = SeriesDataMap.get(d.seriesLabel) ?? []
161
+ seriesData.push(d)
162
+ SeriesDataMap.set(d.seriesLabel, seriesData)
163
+ })
164
+ return SeriesDataMap
165
+ })
166
+ )
167
+ }
168
+
169
+ export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<'grid'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
170
+ return datumList$.pipe(
171
+ map(data => {
172
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
173
+ data.forEach(d => {
174
+ const groupData = GroupDataMap.get(d.groupLabel) ?? []
175
+ groupData.push(d)
176
+ GroupDataMap.set(d.groupLabel, groupData)
177
+ })
178
+ return GroupDataMap
179
+ })
180
+ )
181
+ }
182
+
183
+ export const categoryDataMapObservable = <DatumType extends ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
184
+ return datumList$.pipe(
185
+ map(data => {
186
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
187
+ data
188
+ .filter(d => d.categoryLabel != null)
189
+ .forEach(d => {
190
+ const groupData = GroupDataMap.get(d.categoryLabel) ?? []
191
+ groupData.push(d)
192
+ GroupDataMap.set(d.categoryLabel, groupData)
193
+ })
194
+ return GroupDataMap
195
+ })
196
+ )
197
+ }
198
+
199
+ export const textSizePxObservable = (chartParams$: Observable<ChartParams>) => {
200
+ return chartParams$.pipe(
201
+ map(d => d.styles.textSize),
202
+ distinctUntilChanged(),
203
+ map(data => {
204
+ let value = NaN
205
+ if (typeof data === 'string') {
206
+ if (data.includes('rem')) {
207
+ const rootFontSizePx = parseFloat(getComputedStyle(document.documentElement).fontSize)
208
+ const num = parseFloat(data)
209
+ value = num * rootFontSizePx
210
+ } else if (data.includes('px')) {
211
+ value = parseFloat(data)
212
+ }
213
+ } else if (typeof data === 'number') {
214
+ return data
215
+ }
216
+ return value ? value : 14 // default
217
+ })
218
+ )
203
219
  }