@orbcharts/plugin-basic 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 (208) hide show
  1. package/LICENSE +201 -0
  2. package/dist/orbcharts-plugin-basic.es.js +25335 -0
  3. package/dist/orbcharts-plugin-basic.umd.js +341 -0
  4. package/dist/plugin-basic/src/baseLayers/BaseBars.d.ts +38 -0
  5. package/dist/plugin-basic/src/baseLayers/BaseBarsTriangle.d.ts +37 -0
  6. package/dist/plugin-basic/src/baseLayers/BaseCategoryAxis.d.ts +42 -0
  7. package/dist/plugin-basic/src/baseLayers/BaseDots.d.ts +38 -0
  8. package/dist/plugin-basic/src/baseLayers/BaseLegend.d.ts +31 -0
  9. package/dist/plugin-basic/src/baseLayers/BaseLineAreas.d.ts +36 -0
  10. package/dist/plugin-basic/src/baseLayers/BaseLines.d.ts +36 -0
  11. package/dist/plugin-basic/src/baseLayers/BaseStackedBars.d.ts +41 -0
  12. package/dist/plugin-basic/src/baseLayers/BaseTooltip.d.ts +47 -0
  13. package/dist/plugin-basic/src/baseLayers/BaseValueAxis.d.ts +38 -0
  14. package/dist/plugin-basic/src/baseLayers/BaseXAxis.d.ts +25 -0
  15. package/dist/plugin-basic/src/baseLayers/BaseXZoom.d.ts +22 -0
  16. package/dist/plugin-basic/src/baseLayers/BaseYAxis.d.ts +23 -0
  17. package/dist/plugin-basic/src/baseLayers/types.d.ts +171 -0
  18. package/dist/plugin-basic/src/const/layerIndex.d.ts +10 -0
  19. package/dist/plugin-basic/src/const/sharedPluginParams.d.ts +6 -0
  20. package/dist/plugin-basic/src/index.d.ts +2 -0
  21. package/dist/plugin-basic/src/plugins/CompositionPlot/CompositionPlot.d.ts +22 -0
  22. package/dist/plugin-basic/src/plugins/CompositionPlot/contextObservables.d.ts +40 -0
  23. package/dist/plugin-basic/src/plugins/CompositionPlot/defaults.d.ts +10 -0
  24. package/dist/plugin-basic/src/plugins/CompositionPlot/index.d.ts +3 -0
  25. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Bubbles.d.ts +16 -0
  26. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Indicator.d.ts +0 -0
  27. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Pie.d.ts +16 -0
  28. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieEventTexts.d.ts +16 -0
  29. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieLabels.d.ts +16 -0
  30. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Rose.d.ts +16 -0
  31. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/RoseLabels.d.ts +16 -0
  32. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Waffle.d.ts +0 -0
  33. package/dist/plugin-basic/src/plugins/CompositionPlot/types.d.ts +110 -0
  34. package/dist/plugin-basic/src/plugins/CompositionPlot/utils.d.ts +19 -0
  35. package/dist/plugin-basic/src/plugins/HierarchyPlot/HierarchyPlot.d.ts +22 -0
  36. package/dist/plugin-basic/src/plugins/HierarchyPlot/contextObservables.d.ts +16 -0
  37. package/dist/plugin-basic/src/plugins/HierarchyPlot/defaults.d.ts +4 -0
  38. package/dist/plugin-basic/src/plugins/HierarchyPlot/index.d.ts +3 -0
  39. package/dist/plugin-basic/src/plugins/HierarchyPlot/layers/TreeMap.d.ts +16 -0
  40. package/dist/plugin-basic/src/plugins/HierarchyPlot/types.d.ts +29 -0
  41. package/dist/plugin-basic/src/plugins/Legend/Legend.d.ts +22 -0
  42. package/dist/plugin-basic/src/plugins/Legend/contextObservables.d.ts +9 -0
  43. package/dist/plugin-basic/src/plugins/Legend/defaults.d.ts +4 -0
  44. package/dist/plugin-basic/src/plugins/Legend/index.d.ts +3 -0
  45. package/dist/plugin-basic/src/plugins/Legend/layers/Legend.d.ts +16 -0
  46. package/dist/plugin-basic/src/plugins/Legend/types.d.ts +31 -0
  47. package/dist/plugin-basic/src/plugins/Legend/utils.d.ts +19 -0
  48. package/dist/plugin-basic/src/plugins/NetworkPlot/NetworkPlot.d.ts +22 -0
  49. package/dist/plugin-basic/src/plugins/NetworkPlot/contextObservables.d.ts +19 -0
  50. package/dist/plugin-basic/src/plugins/NetworkPlot/defaults.d.ts +5 -0
  51. package/dist/plugin-basic/src/plugins/NetworkPlot/index.d.ts +3 -0
  52. package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirected.d.ts +16 -0
  53. package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.d.ts +16 -0
  54. package/dist/plugin-basic/src/plugins/NetworkPlot/types.d.ts +117 -0
  55. package/dist/plugin-basic/src/plugins/ScatterPlot/ScatterPlot.d.ts +22 -0
  56. package/dist/plugin-basic/src/plugins/ScatterPlot/contextObservables.d.ts +140 -0
  57. package/dist/plugin-basic/src/plugins/ScatterPlot/defaults.d.ts +8 -0
  58. package/dist/plugin-basic/src/plugins/ScatterPlot/index.d.ts +3 -0
  59. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/Scatter.d.ts +16 -0
  60. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/ScatterBubbles.d.ts +16 -0
  61. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAux.d.ts +16 -0
  62. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAxes.d.ts +16 -0
  63. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XZoom.d.ts +16 -0
  64. package/dist/plugin-basic/src/plugins/ScatterPlot/types.d.ts +146 -0
  65. package/dist/plugin-basic/src/plugins/SeriesPlot/SeriesPlot.d.ts +22 -0
  66. package/dist/plugin-basic/src/plugins/SeriesPlot/contextObservables.d.ts +77 -0
  67. package/dist/plugin-basic/src/plugins/SeriesPlot/defaults.d.ts +15 -0
  68. package/dist/plugin-basic/src/plugins/SeriesPlot/index.d.ts +3 -0
  69. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Bars.d.ts +16 -0
  70. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsPN.d.ts +16 -0
  71. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsTriangle.d.ts +16 -0
  72. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAux.d.ts +16 -0
  73. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAxis.d.ts +16 -0
  74. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryZoom.d.ts +16 -0
  75. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Dots.d.ts +16 -0
  76. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/LineAreas.d.ts +16 -0
  77. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Lines.d.ts +16 -0
  78. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedBars.d.ts +16 -0
  79. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedValueAxis.d.ts +16 -0
  80. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/ValueAxis.d.ts +16 -0
  81. package/dist/plugin-basic/src/plugins/SeriesPlot/types.d.ts +140 -0
  82. package/dist/plugin-basic/src/plugins/Tooltip/Tooltip.d.ts +22 -0
  83. package/dist/plugin-basic/src/plugins/Tooltip/contextObservables.d.ts +9 -0
  84. package/dist/plugin-basic/src/plugins/Tooltip/defaults.d.ts +4 -0
  85. package/dist/plugin-basic/src/plugins/Tooltip/index.d.ts +3 -0
  86. package/dist/plugin-basic/src/plugins/Tooltip/layers/Tooltip.d.ts +16 -0
  87. package/dist/plugin-basic/src/plugins/Tooltip/types.d.ts +35 -0
  88. package/dist/plugin-basic/src/plugins/Tooltip/utils.d.ts +19 -0
  89. package/dist/plugin-basic/src/plugins/index.d.ts +7 -0
  90. package/dist/plugin-basic/src/types/BaseLayer.d.ts +3 -0
  91. package/dist/plugin-basic/src/types/Common.d.ts +14 -0
  92. package/dist/plugin-basic/src/types/ComputedData.d.ts +27 -0
  93. package/dist/plugin-basic/src/types/PluginParams.d.ts +66 -0
  94. package/dist/plugin-basic/src/types/index.d.ts +3 -0
  95. package/dist/plugin-basic/src/utils/commonUtils.d.ts +3 -0
  96. package/dist/plugin-basic/src/utils/d3Graphics.d.ts +24 -0
  97. package/dist/plugin-basic/src/utils/d3Scale.d.ts +28 -0
  98. package/dist/plugin-basic/src/utils/d3Utils.d.ts +14 -0
  99. package/dist/plugin-basic/src/utils/graphObservables.d.ts +0 -0
  100. package/dist/plugin-basic/src/utils/gridObservables.d.ts +51 -0
  101. package/dist/plugin-basic/src/utils/multivariateObservables.d.ts +74 -0
  102. package/dist/plugin-basic/src/utils/observables.d.ts +34 -0
  103. package/dist/plugin-basic/src/utils/orbchartsUtils.d.ts +26 -0
  104. package/dist/plugin-basic/src/utils/seriesObservables.d.ts +22 -0
  105. package/dist/plugin-basic/vite.config.d.ts +2 -0
  106. package/dist/src/index.d.ts +1 -0
  107. package/package.json +62 -0
  108. package/src/baseLayers/BaseBars.ts +783 -0
  109. package/src/baseLayers/BaseBarsTriangle.ts +692 -0
  110. package/src/baseLayers/BaseCategoryAxis.ts +708 -0
  111. package/src/baseLayers/BaseDots.ts +495 -0
  112. package/src/baseLayers/BaseLegend.ts +684 -0
  113. package/src/baseLayers/BaseLineAreas.ts +644 -0
  114. package/src/baseLayers/BaseLines.ts +721 -0
  115. package/src/baseLayers/BaseStackedBars.ts +818 -0
  116. package/src/baseLayers/BaseTooltip.ts +435 -0
  117. package/src/baseLayers/BaseValueAxis.ts +612 -0
  118. package/src/baseLayers/BaseXAxis.ts +412 -0
  119. package/src/baseLayers/BaseXZoom.ts +250 -0
  120. package/src/baseLayers/BaseYAxis.ts +371 -0
  121. package/src/baseLayers/types.ts +174 -0
  122. package/src/const/layerIndex.ts +36 -0
  123. package/src/const/sharedPluginParams.ts +29 -0
  124. package/src/index.ts +3 -0
  125. package/src/plugins/CompositionPlot/CompositionPlot.ts +308 -0
  126. package/src/plugins/CompositionPlot/contextObservables.ts +251 -0
  127. package/src/plugins/CompositionPlot/defaults.ts +162 -0
  128. package/src/plugins/CompositionPlot/index.ts +3 -0
  129. package/src/plugins/CompositionPlot/layers/Bubbles.ts +808 -0
  130. package/src/plugins/CompositionPlot/layers/Indicator.ts +0 -0
  131. package/src/plugins/CompositionPlot/layers/Pie.ts +776 -0
  132. package/src/plugins/CompositionPlot/layers/PieEventTexts.ts +326 -0
  133. package/src/plugins/CompositionPlot/layers/PieLabels.ts +651 -0
  134. package/src/plugins/CompositionPlot/layers/Rose.ts +546 -0
  135. package/src/plugins/CompositionPlot/layers/RoseLabels.ts +616 -0
  136. package/src/plugins/CompositionPlot/layers/Waffle.ts +0 -0
  137. package/src/plugins/CompositionPlot/types.ts +129 -0
  138. package/src/plugins/CompositionPlot/utils.ts +53 -0
  139. package/src/plugins/HierarchyPlot/HierarchyPlot.ts +190 -0
  140. package/src/plugins/HierarchyPlot/contextObservables.ts +136 -0
  141. package/src/plugins/HierarchyPlot/defaults.ts +31 -0
  142. package/src/plugins/HierarchyPlot/index.ts +3 -0
  143. package/src/plugins/HierarchyPlot/layers/TreeMap.ts +371 -0
  144. package/src/plugins/HierarchyPlot/types.ts +36 -0
  145. package/src/plugins/Legend/Legend.ts +151 -0
  146. package/src/plugins/Legend/contextObservables.ts +55 -0
  147. package/src/plugins/Legend/defaults.ts +37 -0
  148. package/src/plugins/Legend/index.ts +3 -0
  149. package/src/plugins/Legend/layers/Legend.ts +114 -0
  150. package/src/plugins/Legend/types.ts +45 -0
  151. package/src/plugins/Legend/utils.ts +53 -0
  152. package/src/plugins/NetworkPlot/NetworkPlot.ts +228 -0
  153. package/src/plugins/NetworkPlot/contextObservables.ts +123 -0
  154. package/src/plugins/NetworkPlot/defaults.ts +147 -0
  155. package/src/plugins/NetworkPlot/index.ts +3 -0
  156. package/src/plugins/NetworkPlot/layers/ForceDirected.ts +1048 -0
  157. package/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.ts +1318 -0
  158. package/src/plugins/NetworkPlot/types.ts +146 -0
  159. package/src/plugins/ScatterPlot/ScatterPlot.ts +569 -0
  160. package/src/plugins/ScatterPlot/contextObservables.ts +901 -0
  161. package/src/plugins/ScatterPlot/defaults.ts +212 -0
  162. package/src/plugins/ScatterPlot/index.ts +3 -0
  163. package/src/plugins/ScatterPlot/layers/Scatter.ts +518 -0
  164. package/src/plugins/ScatterPlot/layers/ScatterBubbles.ts +670 -0
  165. package/src/plugins/ScatterPlot/layers/XYAux.ts +686 -0
  166. package/src/plugins/ScatterPlot/layers/XYAxes.ts +205 -0
  167. package/src/plugins/ScatterPlot/layers/XZoom.ts +48 -0
  168. package/src/plugins/ScatterPlot/types.ts +179 -0
  169. package/src/plugins/SeriesPlot/SeriesPlot.ts +494 -0
  170. package/src/plugins/SeriesPlot/contextObservables.ts +726 -0
  171. package/src/plugins/SeriesPlot/defaults.ts +142 -0
  172. package/src/plugins/SeriesPlot/index.ts +3 -0
  173. package/src/plugins/SeriesPlot/layers/Bars.ts +84 -0
  174. package/src/plugins/SeriesPlot/layers/BarsPN.ts +85 -0
  175. package/src/plugins/SeriesPlot/layers/BarsTriangle.ts +89 -0
  176. package/src/plugins/SeriesPlot/layers/CategoryAux.ts +1131 -0
  177. package/src/plugins/SeriesPlot/layers/CategoryAxis.ts +92 -0
  178. package/src/plugins/SeriesPlot/layers/CategoryZoom.ts +233 -0
  179. package/src/plugins/SeriesPlot/layers/Dots.ts +91 -0
  180. package/src/plugins/SeriesPlot/layers/LineAreas.ts +82 -0
  181. package/src/plugins/SeriesPlot/layers/Lines.ts +75 -0
  182. package/src/plugins/SeriesPlot/layers/StackedBars.ts +85 -0
  183. package/src/plugins/SeriesPlot/layers/StackedValueAxis.ts +111 -0
  184. package/src/plugins/SeriesPlot/layers/ValueAxis.ts +111 -0
  185. package/src/plugins/SeriesPlot/types.ts +201 -0
  186. package/src/plugins/Tooltip/Tooltip.ts +159 -0
  187. package/src/plugins/Tooltip/contextObservables.ts +55 -0
  188. package/src/plugins/Tooltip/defaults.ts +458 -0
  189. package/src/plugins/Tooltip/index.ts +3 -0
  190. package/src/plugins/Tooltip/layers/Tooltip.ts +90 -0
  191. package/src/plugins/Tooltip/types.ts +55 -0
  192. package/src/plugins/Tooltip/utils.ts +53 -0
  193. package/src/plugins/index.ts +8 -0
  194. package/src/types/BaseLayer.ts +3 -0
  195. package/src/types/Common.ts +20 -0
  196. package/src/types/ComputedData.ts +55 -0
  197. package/src/types/PluginParams.ts +81 -0
  198. package/src/types/index.ts +3 -0
  199. package/src/utils/commonUtils.ts +31 -0
  200. package/src/utils/d3Graphics.ts +177 -0
  201. package/src/utils/d3Scale.ts +198 -0
  202. package/src/utils/d3Utils.ts +92 -0
  203. package/src/utils/graphObservables.ts +0 -0
  204. package/src/utils/gridObservables.ts +637 -0
  205. package/src/utils/multivariateObservables.ts +790 -0
  206. package/src/utils/observables.ts +357 -0
  207. package/src/utils/orbchartsUtils.ts +335 -0
  208. package/src/utils/seriesObservables.ts +172 -0
@@ -0,0 +1,790 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ Observable,
4
+ Subject,
5
+ debounceTime,
6
+ iif,
7
+ of,
8
+ takeUntil,
9
+ filter,
10
+ map,
11
+ switchMap,
12
+ combineLatest,
13
+ merge,
14
+ shareReplay,
15
+ distinctUntilChanged
16
+ } from 'rxjs'
17
+ import type {
18
+ ComputedData,
19
+ XYAxis
20
+ } from '../types'
21
+ import type {
22
+ ComputedDatumMultivariate,
23
+ TransformData,
24
+ ContainerSize,
25
+ ContainerPositionScaled,
26
+ Layout,
27
+ } from '../types'
28
+ import type {
29
+ ComputedXYDatumMultivariate,
30
+ } from '../plugins/ScatterPlot/types'
31
+ import {
32
+ createAxisToLabelIndexScale,
33
+ createAxisToValueScale,
34
+ createLabelToAxisScale,
35
+ createValueToAxisScale,
36
+ } from './d3Scale'
37
+ import { createClassName } from './orbchartsUtils'
38
+ import { d3EventObservable } from './observables'
39
+
40
+ // 建立 multivariate 主要的 selection
41
+ export const multivariateSelectionsObservable = ({ selection, pluginName, layerName, clipPathID, seriesLabels$, containerPosition$, graphicTransform$ }: {
42
+ selection: d3.Selection<any, unknown, any, unknown>
43
+ pluginName: string
44
+ layerName: string
45
+ clipPathID: string
46
+ // computedData$: Observable<ComputedData<'multivariate'>>
47
+ seriesLabels$: Observable<string[]>
48
+ containerPosition$: Observable<ContainerPositionScaled[]>
49
+ // multivariateAxesTransform$: Observable<TransformData>
50
+ graphicTransform$: Observable<TransformData>
51
+ }) => {
52
+ const categoryClassName = createClassName(pluginName, layerName, 'category')
53
+ const axesClassName = createClassName(pluginName, layerName, 'axes')
54
+ const graphicClassName = createClassName(pluginName, layerName, 'graphic')
55
+
56
+ // <g> category selection(container排放位置)
57
+ // <g> axes selection(圖軸)
58
+ // <defs> clipPath selection
59
+ // <g> graphic selection(圖形 scale 範圍的變形)
60
+ const seriesSelection$ = seriesLabels$.pipe(
61
+ map((categoryLabels, i) => {
62
+ return selection
63
+ .selectAll<SVGGElement, string>(`g.${categoryClassName}`)
64
+ .data(categoryLabels, d => d)
65
+ .join(
66
+ enter => {
67
+ return enter
68
+ .append('g')
69
+ .classed(categoryClassName, true)
70
+ .each((d, i, g) => {
71
+ const axesSelection = d3.select(g[i])
72
+ .selectAll<SVGGElement, ComputedDatumMultivariate[]>(`g.${axesClassName}`)
73
+ .data([i])
74
+ .join(
75
+ enter => {
76
+ return enter
77
+ .append('g')
78
+ .classed(axesClassName, true)
79
+ .attr('clip-path', `url(#${clipPathID})`)
80
+ .each((d, i, g) => {
81
+ const defsSelection = d3.select(g[i])
82
+ .selectAll<SVGDefsElement, any>('defs')
83
+ .data([i])
84
+ .join('defs')
85
+
86
+ const graphicGSelection = d3.select(g[i])
87
+ .selectAll<SVGGElement, any>('g')
88
+ .data([i])
89
+ .join('g')
90
+ .classed(graphicClassName, true)
91
+ })
92
+ },
93
+ update => update,
94
+ exit => exit.remove()
95
+ )
96
+ })
97
+ },
98
+ update => update,
99
+ exit => exit.remove()
100
+ )
101
+ }),
102
+ shareReplay(1)
103
+ )
104
+
105
+ // <g> category selection
106
+ combineLatest({
107
+ seriesSelection: seriesSelection$,
108
+ containerPosition: containerPosition$
109
+ }).pipe(
110
+ debounceTime(0)
111
+ ).subscribe(data => {
112
+ data.seriesSelection
113
+ .transition()
114
+ .attr('transform', (d, i) => {
115
+ const containerPosition = data.containerPosition[i] ?? data.containerPosition[0]
116
+ const translate = containerPosition.translate
117
+ const scale = containerPosition.scale
118
+ return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
119
+ })
120
+ })
121
+
122
+ // <g> axes selection
123
+ const axesSelection$ = seriesSelection$.pipe(
124
+ map(seriesSelection => {
125
+ return seriesSelection
126
+ .select<SVGGElement>(`g.${axesClassName}`)
127
+ }),
128
+ shareReplay(1)
129
+ )
130
+
131
+ // <defs> clipPath selection
132
+ const defsSelection$ = axesSelection$.pipe(
133
+ map(axesSelection => {
134
+ return axesSelection.select<SVGDefsElement>('defs')
135
+ }),
136
+ shareReplay(1)
137
+ )
138
+
139
+ // <g> graphic selection
140
+ const graphicGSelection$ = combineLatest({
141
+ axesSelection: axesSelection$,
142
+ graphicTransform: graphicTransform$
143
+ }).pipe(
144
+ debounceTime(0),
145
+ map(data => {
146
+ const graphicGSelection = data.axesSelection
147
+ .select<SVGGElement>(`g.${graphicClassName}`)
148
+ graphicGSelection
149
+ .transition()
150
+ .duration(50)
151
+ .style('transform', data.graphicTransform.value)
152
+ return graphicGSelection
153
+ }),
154
+ shareReplay(1)
155
+ )
156
+
157
+ return {
158
+ seriesSelection$,
159
+ axesSelection$,
160
+ defsSelection$,
161
+ graphicGSelection$
162
+ }
163
+ }
164
+
165
+ // 建立 multivariate 主要的 selection - 只取無scale的container selection
166
+ export const multivariateContainerSelectionsObservable = ({ selection, pluginName, layerName, clipPathID, computedData$, containerPosition$, isSeriesSeprate$ }: {
167
+ selection: d3.Selection<any, unknown, any, unknown>
168
+ pluginName: string
169
+ layerName: string
170
+ clipPathID: string | null
171
+ computedData$: Observable<ComputedData<'multivariate'>>
172
+ containerPosition$: Observable<ContainerPositionScaled[]>
173
+ isSeriesSeprate$: Observable<boolean>
174
+ }) => {
175
+ const containerClassName = createClassName(pluginName, layerName, 'container')
176
+
177
+ const containerSelection$ = combineLatest({
178
+ computedData: computedData$.pipe(
179
+ distinctUntilChanged((a, b) => {
180
+ // 只有當series的數量改變時,才重新計算
181
+ return a.length === b.length
182
+ }),
183
+ ),
184
+ isSeriesSeprate: isSeriesSeprate$
185
+ }).pipe(
186
+ switchMap(async (d) => d),
187
+ map(data => {
188
+ return data.isSeriesSeprate
189
+ // category分開的時候顯示各別axis
190
+ ? data.computedData
191
+ // category合併的時候只顯示第一個axis
192
+ : [data.computedData[0]]
193
+ }),
194
+ map((computedData, i) => {
195
+ return selection
196
+ .selectAll<SVGGElement, ComputedDatumMultivariate[]>(`g.${containerClassName}`)
197
+ .data(computedData, d => (d && d[0]) ? d[0].categoryIndex : i)
198
+ .join('g')
199
+ .classed(containerClassName, true)
200
+ .attr('clip-path', _ => clipPathID ? `url(#${clipPathID})` : 'none')
201
+ }),
202
+ shareReplay(1)
203
+ )
204
+
205
+ combineLatest({
206
+ containerSelection: containerSelection$,
207
+ gridContainerPosition: containerPosition$
208
+ }).pipe(
209
+ debounceTime(0)
210
+ ).subscribe(data => {
211
+ data.containerSelection
212
+ .attr('transform', (d, i) => {
213
+ const gridContainerPosition = data.gridContainerPosition[i] ?? data.gridContainerPosition[0]
214
+ const translate = gridContainerPosition.translate
215
+ const scale = gridContainerPosition.scale
216
+ // return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
217
+ return `translate(${translate[0]}, ${translate[1]})`
218
+ })
219
+ // .attr('opacity', 0)
220
+ // .transition()
221
+ // .attr('opacity', 1)
222
+ })
223
+
224
+ return containerSelection$
225
+ }
226
+
227
+
228
+ export const multivariateXYPositionObservable = ({ rootSelection, xAxis$, yAxis$, xyValueIndex$, filteredXYMinMaxData$, containerPosition$, containerSize$, layout$ }: {
229
+ rootSelection: d3.Selection<any, unknown, any, unknown>
230
+ xAxis$: Observable<XYAxis>
231
+ yAxis$: Observable<XYAxis>
232
+ xyValueIndex$: Observable<[number, number]>
233
+ // computedData$: Observable<ComputedData<'multivariate'>>
234
+ // xyMinMax$: Observable<{ minX: number, maxX: number, minY: number, maxY: number }>
235
+ filteredXYMinMaxData$: Observable<{
236
+ minXDatum: ComputedXYDatumMultivariate
237
+ maxXDatum: ComputedXYDatumMultivariate
238
+ minYDatum: ComputedXYDatumMultivariate
239
+ maxYDatum: ComputedXYDatumMultivariate
240
+ }>
241
+ containerPosition$: Observable<ContainerPositionScaled[]>
242
+ containerSize$: Observable<ContainerSize>
243
+ layout$: Observable<Layout>
244
+ }) => {
245
+ const rootMousemove$ = d3EventObservable(rootSelection, 'mousemove').pipe(
246
+ debounceTime(2) // 避免過度頻繁觸發,實測時沒加電腦容易卡頓
247
+ )
248
+
249
+ // const columnAmount$ = containerPosition$.pipe(
250
+ // map(containerPosition => {
251
+ // const maxColumnIndex = containerPosition.reduce((acc, current) => {
252
+ // return current.columnIndex > acc ? current.columnIndex : acc
253
+ // }, 0)
254
+ // return maxColumnIndex + 1
255
+ // }),
256
+ // distinctUntilChanged(),
257
+ // shareReplay(1)
258
+ // )
259
+
260
+ // const rowAmount$ = containerPosition$.pipe(
261
+ // map(containerPosition => {
262
+ // const maxRowIndex = containerPosition.reduce((acc, current) => {
263
+ // return current.rowIndex > acc ? current.rowIndex : acc
264
+ // }, 0)
265
+ // return maxRowIndex + 1
266
+ // }),
267
+ // distinctUntilChanged(),
268
+ // shareReplay(1)
269
+ // )
270
+
271
+ // const xyScale$ = combineLatest({
272
+ // layout: layout$,
273
+ // filteredXYMinMaxData: filteredXYMinMaxData$,
274
+ // fullDataFormatter: fullDataFormatter$,
275
+ // columnAmount: columnAmount$,
276
+ // rowAmount: rowAmount$
277
+ // }).pipe(
278
+ // debounceTime(0),
279
+ // map(data => {
280
+ // const xScale = createAxisToValueScale({
281
+ // maxValue: data.filteredXYMinMaxData.maxXDatum.value[0],
282
+ // minValue: data.filteredXYMinMaxData.minXDatum.value[0],
283
+ // axisWidth: data.layout.width,
284
+ // scaleDomain: data.fullDataFormatter.xAxis.scaleDomain,
285
+ // scaleRange: data.fullDataFormatter.xAxis.scaleRange,
286
+ // })
287
+ // const yScale = createAxisToValueScale({
288
+ // maxValue: data.filteredXYMinMaxData.maxYDatum.value[1],
289
+ // minValue: data.filteredXYMinMaxData.minYDatum.value[1],
290
+ // axisWidth: data.layout.height,
291
+ // scaleDomain: data.fullDataFormatter.yAxis.scaleDomain,
292
+ // scaleRange: data.fullDataFormatter.yAxis.scaleRange,
293
+ // reverse: true
294
+ // })
295
+ // return { xScale, yScale }
296
+ // })
297
+ // )
298
+
299
+ const xyScale$: Observable<{
300
+ xScale: d3.ScaleLinear<number, number, never>;
301
+ yScale: d3.ScaleLinear<number, number, never>;
302
+ }> = new Observable(subscriber => {
303
+ combineLatest({
304
+ // layout: layout$,
305
+ containerSize: containerSize$,
306
+ filteredXYMinMaxData: filteredXYMinMaxData$,
307
+ xAxis: xAxis$,
308
+ yAxis: yAxis$,
309
+ xyValueIndex: xyValueIndex$,
310
+ // columnAmount: columnAmount$,
311
+ // rowAmount: rowAmount$
312
+ }).pipe(
313
+ debounceTime(0),
314
+ ).subscribe(data => {
315
+ // const xValueIndex = data.xAxis.valueIndex
316
+ // const yValueIndex = data.yAxis.valueIndex
317
+ const [xValueIndex, yValueIndex] = data.xyValueIndex
318
+ if (!data.filteredXYMinMaxData.minXDatum || !data.filteredXYMinMaxData.maxXDatum
319
+ || data.filteredXYMinMaxData.minXDatum.multivariate[xValueIndex].value == null || data.filteredXYMinMaxData.maxXDatum.multivariate[xValueIndex].value == null
320
+ || !data.filteredXYMinMaxData.minYDatum || !data.filteredXYMinMaxData.maxYDatum
321
+ || data.filteredXYMinMaxData.minYDatum.multivariate[yValueIndex].value == null || data.filteredXYMinMaxData.maxYDatum.multivariate[yValueIndex].value == null
322
+ ) {
323
+ return
324
+ }
325
+ const xScale = createAxisToValueScale({
326
+ maxValue: data.filteredXYMinMaxData.maxXDatum.multivariate[xValueIndex].value,
327
+ minValue: data.filteredXYMinMaxData.minXDatum.multivariate[xValueIndex].value,
328
+ axisWidth: data.containerSize.width,
329
+ scaleDomain: data.xAxis.scaleDomain,
330
+ scaleRange: data.xAxis.scaleRange,
331
+ })
332
+ const yScale = createAxisToValueScale({
333
+ maxValue: data.filteredXYMinMaxData.maxYDatum.multivariate[yValueIndex].value,
334
+ minValue: data.filteredXYMinMaxData.minYDatum.multivariate[yValueIndex].value,
335
+ axisWidth: data.containerSize.height,
336
+ scaleDomain: data.yAxis.scaleDomain,
337
+ scaleRange: data.yAxis.scaleRange,
338
+ reverse: true
339
+ })
340
+ subscriber.next({ xScale, yScale })
341
+ })
342
+ })
343
+
344
+ const axisValue$ = combineLatest({
345
+ rootMousemove: rootMousemove$,
346
+ // columnAmount: columnAmount$,
347
+ // rowAmount: rowAmount$,
348
+ layout: layout$,
349
+ containerPosition: containerPosition$
350
+ }).pipe(
351
+ debounceTime(0),
352
+ map(data => {
353
+ // 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
354
+ // return {
355
+ // x: ((data.rootMousemove.offsetX - data.layout.left) / data.containerPosition[0].scale[0])
356
+ // % (data.layout.rootWidth / data.columnAmount / data.containerPosition[0].scale[0]),
357
+ // y: ((data.rootMousemove.offsetY - data.layout.top) / data.containerPosition[0].scale[1])
358
+ // % (data.layout.rootHeight / data.rowAmount / data.containerPosition[0].scale[1])
359
+ // }
360
+ const x = (() => {
361
+ let x = data.rootMousemove.offsetX
362
+ const rangeArr = data.containerPosition
363
+ .map((d, i) => [d.translate[0], data.containerPosition[i + 1]?.translate[0] ?? data.layout.rootWidth])
364
+ .filter(d => d[0] < d[1])
365
+ const range = rangeArr.find(d => x >= d[0] && x <= d[1])
366
+ if (range) {
367
+ x = x - range[0]
368
+ }
369
+ return x - data.layout.left
370
+ })()
371
+
372
+ const y = (() => {
373
+ let y = data.rootMousemove.offsetY
374
+ const rangeArr = data.containerPosition
375
+ .map((d, i) => [d.translate[1], data.containerPosition[i + 1]?.translate[1] ?? data.layout.rootHeight])
376
+ .filter(d => d[0] < d[1])
377
+ const range = rangeArr.find(d => y >= d[0] && y <= d[1])
378
+ if (range) {
379
+ y = y - range[0]
380
+ }
381
+ return y - data.layout.top
382
+ })()
383
+
384
+ return { x, y }
385
+ })
386
+ )
387
+
388
+ return combineLatest({
389
+ xyScale: xyScale$,
390
+ axisValue: axisValue$,
391
+ containerPosition: containerPosition$
392
+ }).pipe(
393
+ debounceTime(0),
394
+ map(data => {
395
+ return {
396
+ x: data.axisValue.x / data.containerPosition[0].scale[0],
397
+ y: data.axisValue.y / data.containerPosition[0].scale[1],
398
+ xValue: data.xyScale.xScale(data.axisValue.x),
399
+ yValue: data.xyScale.yScale(data.axisValue.y)
400
+ }
401
+ })
402
+ )
403
+ }
404
+
405
+ export const ordinalPositionObservable = ({ rootSelection, ordinalScaleDomain$, ordinalScale$, ordinalPadding$, containerSize$, containerPosition$, layout$ }: {
406
+ rootSelection: d3.Selection<any, unknown, any, unknown>
407
+ ordinalScaleDomain$: Observable<[number, number]>
408
+ ordinalScale$: Observable<d3.ScaleLinear<number, number>>
409
+ ordinalPadding$: Observable<number>
410
+ containerSize$: Observable<ContainerSize>
411
+ containerPosition$: Observable<ContainerPositionScaled[]>
412
+ layout$: Observable<Layout>
413
+ }) => {
414
+ const rootMousemove$ = d3EventObservable(rootSelection, 'mousemove').pipe(
415
+ debounceTime(2) // 避免過度頻繁觸發,實測時沒加電腦容易卡頓
416
+ )
417
+
418
+ // const columnAmount$ = containerPosition$.pipe(
419
+ // map(containerPosition => {
420
+ // const maxColumnIndex = containerPosition.reduce((acc, current) => {
421
+ // return current.columnIndex > acc ? current.columnIndex : acc
422
+ // }, 0)
423
+ // return maxColumnIndex + 1
424
+ // }),
425
+ // distinctUntilChanged(),
426
+ // shareReplay(1)
427
+ // )
428
+
429
+ const axisX$ = combineLatest({
430
+ rootMousemove: rootMousemove$,
431
+ // columnAmount: columnAmount$,
432
+ layout: layout$,
433
+ // containerSize: containerSize$,
434
+ containerPosition: containerPosition$,
435
+ }).pipe(
436
+ debounceTime(0),
437
+ map(data => {
438
+ // 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
439
+ // return ((data.rootMousemove.offsetX - data.layout.left) / data.containerPosition[0].scale[0])
440
+ // % (data.layout.rootWidth / data.columnAmount / data.containerPosition[0].scale[0])
441
+
442
+ let x = data.rootMousemove.offsetX
443
+ const rangeArr = data.containerPosition
444
+ .map((d, i) => [d.translate[0], data.containerPosition[i + 1]?.translate[0] ?? data.layout.rootWidth])
445
+ .filter(d => d[0] < d[1])
446
+ const range = rangeArr.find(d => x >= d[0] && x <= d[1])
447
+ if (range) {
448
+ x = x - range[0]
449
+ }
450
+ return x - data.layout.left
451
+ })
452
+ )
453
+
454
+ const scaleRangeLabels$ = ordinalScaleDomain$.pipe(
455
+ map(data => {
456
+ const range = data[1] - data[0] + 1
457
+ return new Array(range).fill(0).map((d, i) => String(i + data[0]))
458
+ })
459
+ )
460
+
461
+ return combineLatest({
462
+ scaleRangeLabels: scaleRangeLabels$,
463
+ // layout: layout$,
464
+ containerSize: containerSize$,
465
+ axisX: axisX$,
466
+ ordinalScale: ordinalScale$,
467
+ ordinalPadding: ordinalPadding$,
468
+ ordinalScaleDomain: ordinalScaleDomain$,
469
+ containerPosition: containerPosition$
470
+ }).pipe(
471
+ debounceTime(0),
472
+ map(data => {
473
+ // 比例尺座標對應非連續資料索引
474
+ const xIndexScale = createAxisToLabelIndexScale({
475
+ axisLabels: data.scaleRangeLabels,
476
+ axisWidth: data.containerSize.width,
477
+ padding: 0.5,
478
+ reverse: false
479
+ })
480
+
481
+ const seq = xIndexScale(data.axisX)
482
+ const xIndex = seq + data.ordinalScaleDomain[0]
483
+ const x = (data.ordinalScale(xIndex) + data.ordinalPadding) / data.containerPosition[0].scale[0]
484
+
485
+ return {
486
+ x: x,
487
+ xValue: xIndex,
488
+ }
489
+ })
490
+ )
491
+ }
492
+
493
+ // 排名數量
494
+ export const computedRankingAmountObservable = ({ containerSize$, visibleComputedData$, textSizePx$, rankingAmount$ }: {
495
+ containerSize$: Observable<ContainerSize>
496
+ visibleComputedData$: Observable<ComputedDatumMultivariate[][]>
497
+ textSizePx$: Observable<number>
498
+ rankingAmount$: Observable<'auto' | number>
499
+ }) => {
500
+ const minLineHeightObservable = ({ textSizePx$ }: {
501
+ textSizePx$: Observable<number>
502
+ }) => {
503
+ return textSizePx$.pipe(
504
+ map(textSizePx => textSizePx * 2), // 2倍行高
505
+ shareReplay(1)
506
+ )
507
+ }
508
+
509
+ const containerHeightObservable = ({ minLineHeight$, containerSize$ }: {
510
+ minLineHeight$: Observable<number>
511
+ containerSize$: Observable<ContainerSize>
512
+ }) => {
513
+ return combineLatest({
514
+ minLineHeight: minLineHeight$,
515
+ containerSize: containerSize$
516
+ }).pipe(
517
+ switchMap(async (d) => d),
518
+ map(data => {
519
+ // 避免過小造成計算 scale 錯誤
520
+ return data.containerSize.height > data.minLineHeight
521
+ ? data.containerSize.height
522
+ : data.minLineHeight
523
+ }),
524
+ distinctUntilChanged(),
525
+ shareReplay(1)
526
+ )
527
+ }
528
+
529
+ const rankingAmountLimitObservable = ({ minLineHeight$, containerHeight$ }: {
530
+ containerHeight$: Observable<number>
531
+ minLineHeight$: Observable<number>
532
+ }) => {
533
+
534
+ return combineLatest({
535
+ minLineHeight: minLineHeight$,
536
+ containerHeight: containerHeight$
537
+ }).pipe(
538
+ switchMap(async (d) => d),
539
+ map(data => {
540
+ const labelAmountLimit = Math.floor(data.containerHeight / data.minLineHeight)
541
+ return labelAmountLimit
542
+ }),
543
+ distinctUntilChanged(),
544
+ shareReplay(1)
545
+ )
546
+ }
547
+
548
+ const minLineHeight$ = minLineHeightObservable({ textSizePx$ })
549
+
550
+ const containerHeight$ = containerHeightObservable({
551
+ minLineHeight$,
552
+ containerSize$
553
+ })
554
+
555
+ const rankingAmountLimit$ = rankingAmountLimitObservable({
556
+ containerHeight$,
557
+ minLineHeight$
558
+ })
559
+
560
+ // 計算要排名的數量
561
+ return rankingAmount$.pipe(
562
+ switchMap(rankingAmount => {
563
+ return iif(
564
+ () => rankingAmount === 'auto',
565
+ // 'auto': 不超過限制
566
+ combineLatest({
567
+ visibleComputedData: visibleComputedData$,
568
+ rankingAmountLimit: rankingAmountLimit$,
569
+ }).pipe(
570
+ debounceTime(0),
571
+ map(data => {
572
+ const rankingAmountArr = data.visibleComputedData.map(categoryData => {
573
+ return Math.min(data.rankingAmountLimit, categoryData.length)
574
+ })
575
+ return Math.max(...rankingAmountArr) // 取所有 container 計算出來的最大值
576
+ })
577
+ ),
578
+ // number: 指定數量
579
+ rankingAmount$ as Observable<number>,
580
+ )
581
+ })
582
+ )
583
+ }
584
+
585
+ export const rankingItemHeightObservable = ({ containerSize$, textSizePx$, computedRankingAmount$ }: {
586
+ containerSize$: Observable<ContainerSize>
587
+ // visibleComputedRankingData$: Observable<ComputedDatumMultivariate[][]>
588
+ textSizePx$: Observable<number>
589
+ // rankingAmount$: Observable<'auto' | number>
590
+ computedRankingAmount$: Observable<number>
591
+ }) => {
592
+ const minLineHeightObservable = ({ textSizePx$ }: {
593
+ textSizePx$: Observable<number>
594
+ }) => {
595
+ return textSizePx$.pipe(
596
+ map(textSizePx => textSizePx * 2), // 2倍行高
597
+ shareReplay(1)
598
+ )
599
+ }
600
+
601
+ const containerHeightObservable = ({ minLineHeight$, containerSize$ }: {
602
+ minLineHeight$: Observable<number>
603
+ containerSize$: Observable<ContainerSize>
604
+ }) => {
605
+ return combineLatest({
606
+ minLineHeight: minLineHeight$,
607
+ containerSize: containerSize$
608
+ }).pipe(
609
+ switchMap(async (d) => d),
610
+ map(data => {
611
+ // 避免過小造成計算 scale 錯誤
612
+ return data.containerSize.height > data.minLineHeight
613
+ ? data.containerSize.height
614
+ : data.minLineHeight
615
+ }),
616
+ distinctUntilChanged(),
617
+ shareReplay(1)
618
+ )
619
+ }
620
+
621
+ const minLineHeight$ = minLineHeightObservable({ textSizePx$ })
622
+
623
+ const containerHeight$ = containerHeightObservable({
624
+ minLineHeight$,
625
+ containerSize$
626
+ })
627
+
628
+ return combineLatest({
629
+ containerHeight: containerHeight$,
630
+ computedRankingAmount: computedRankingAmount$
631
+ }).pipe(
632
+ switchMap(async (d) => d),
633
+ map(data => {
634
+ // // 依每個 category 計算 scale
635
+ // return data.visibleComputedRankingData.map((categoryData, i) => {
636
+ // const rankingAmount = data.computedRankingAmountList[i]
637
+ // const rankingItemHeight = data.containerHeight / rankingAmount
638
+ // return rankingItemHeight
639
+ // })
640
+ const rankingItemHeight = data.containerHeight / data.computedRankingAmount
641
+ return rankingItemHeight
642
+ })
643
+ )
644
+ }
645
+
646
+ export const rankingScaleListObservable = ({ visibleComputedRankingData$, rankingItemHeight$ }: {
647
+ visibleComputedRankingData$: Observable<ComputedDatumMultivariate[][]>
648
+ rankingItemHeight$: Observable<number>
649
+ }) => {
650
+
651
+ return combineLatest({
652
+ visibleComputedRankingData: visibleComputedRankingData$,
653
+ rankingItemHeight: rankingItemHeight$,
654
+ }).pipe(
655
+ switchMap(async (d) => d),
656
+ map(data => {
657
+ // 依每個 category 計算 scale
658
+ return data.visibleComputedRankingData.map((categoryData, i) => {
659
+ const allLabelAmount = categoryData.length
660
+ // const rankingItemHeight = data.rankingItemHeightList[i]
661
+ const totalHeight = data.rankingItemHeight * allLabelAmount // 有可能超出圖軸高度
662
+
663
+ return createLabelToAxisScale({
664
+ axisLabels: categoryData.map(d => d.name),
665
+ axisWidth: totalHeight,
666
+ padding: 0.5
667
+ })
668
+ })
669
+ })
670
+ )
671
+ }
672
+
673
+
674
+ // // Ranking資料 - 有 XY 資料 @Q@ 若沒用到要棄用
675
+ // export const computedRankingWithXYDataObservable = ({ visibleComputedRankingData$, computedRankingAmountList$, xyValueIndex$, layout$ }: {
676
+ // visibleComputedRankingData$: Observable<ComputedDatumMultivariate[][]>
677
+ // computedRankingAmountList$: Observable<number[]>
678
+ // xyValueIndex$: Observable<[number, number]>
679
+ // layout$: Observable<Layout>
680
+ // }): Observable<ComputedXYDataMultivariate> => {
681
+
682
+ // // // 未篩選範圍前的 scale
683
+ // // function createOriginXScale (xMinMax: { minX: number, maxX: number }, layout: Layout) {
684
+ // // let maxValue = xMinMax.maxX
685
+ // // let minValue = xMinMax.minX
686
+ // // if (minValue === maxValue && maxValue === 0) {
687
+ // // // 避免最大及最小值相同造成無法計算scale
688
+ // // maxValue = 1
689
+ // // }
690
+ // // const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
691
+ // // maxValue,
692
+ // // minValue,
693
+ // // axisWidth: layout.width,
694
+ // // scaleDomain: ['auto', 'auto'], // 不使用dataFormatter設定 --> 以0為基準到最大或最小值為範圍( * 如果是使用[minValue, maxValue]的話,在兩者很接近的情況下有可能造成scale倍率過高而svg變型時失真的情況)
695
+ // // scaleRange: [0, 1] // 不使用dataFormatter設定
696
+ // // })
697
+
698
+ // // return valueScale
699
+ // // }
700
+
701
+ // // 未篩選範圍及visible前的 scale
702
+ // function createOriginYScale (yMinMax: { minY: number, maxY: number }, layout: Layout) {
703
+ // let maxValue = yMinMax.maxY
704
+ // let minValue = yMinMax.minY
705
+ // if (minValue === maxValue && maxValue === 0) {
706
+ // // 避免最大及最小值相同造成無法計算scale
707
+ // maxValue = 1
708
+ // }
709
+ // const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
710
+ // maxValue,
711
+ // minValue,
712
+ // axisWidth: layout.height,
713
+ // scaleDomain: ['auto', 'auto'], // 不使用dataFormatter設定 --> 以0為基準到最大或最小值為範圍( * 如果是使用[minValue, maxValue]的話,在兩者很接近的情況下有可能造成scale倍率過高而svg變型時失真的情況)
714
+ // scaleRange: [0, 1], // 不使用dataFormatter設定
715
+ // // reverse: true
716
+ // })
717
+
718
+ // return valueScale
719
+ // }
720
+
721
+ // return combineLatest({
722
+ // visibleComputedRankingData: visibleComputedRankingData$,
723
+ // computedRankingAmountList: computedRankingAmountList$,
724
+ // xyValueIndex: xyValueIndex$,
725
+ // layout: layout$
726
+ // }).pipe(
727
+ // debounceTime(0),
728
+ // map(data => {
729
+
730
+ // // const maxX = data.visibleComputedRankingData
731
+ // // .flat()
732
+ // // .reduce((acc, current) => {
733
+ // // const maxXIndex = current.value.length - 1
734
+ // // return maxXIndex > acc ? maxXIndex : acc
735
+ // // }, 0)
736
+ // // const xMinMax = {
737
+ // // minX: 0,
738
+ // // maxX
739
+ // // }
740
+ // // const xScale = createOriginXScale(xMinMax, data.layout)
741
+ // // console.log('data.visibleComputedRankingData', data.visibleComputedRankingData)
742
+ // return data.visibleComputedRankingData
743
+ // .map((categoryData, categoryIndex) => {
744
+ // const yMinMax = {
745
+ // minY: 0,
746
+ // maxY: data.computedRankingAmountList[categoryIndex]
747
+ // }
748
+ // const yScale = createOriginYScale(yMinMax, data.layout)
749
+
750
+ // return categoryData.map((datum, datumIndex) => {
751
+ // return {
752
+ // ...datum,
753
+ // // axisX: xScale(datum.value[data.xyValueIndex[0]] ?? 0),
754
+ // axisX: 0,
755
+ // // axisY: yScale(datum.value[data.xyValueIndex[1]] ?? 0), // y軸的繪圖座標是從上到下,所以反轉
756
+ // axisY: yScale(datumIndex),
757
+ // }
758
+ // })
759
+ // })
760
+ // })
761
+ // )
762
+ // }
763
+
764
+ // // Ranking資料 - 有 XY 資料 @Q@ 若沒用到要棄用
765
+ // export const computedRankingWithXYDataObservable = ({ visibleComputedRankingData$, rankingScaleList$ }: {
766
+ // visibleComputedRankingData$: Observable<ComputedDatumMultivariate[][]>
767
+ // rankingScaleList$: Observable<d3.ScalePoint<string>[]>
768
+ // }): Observable<ComputedXYDataMultivariate> => {
769
+
770
+ // return combineLatest({
771
+ // visibleComputedRankingData: visibleComputedRankingData$,
772
+ // rankingScaleList: rankingScaleList$
773
+ // }).pipe(
774
+ // debounceTime(0),
775
+ // map(data => {
776
+ // return data.visibleComputedRankingData
777
+ // .map((categoryData, categoryIndex) => {
778
+ // const yScale = data.rankingScaleList[categoryIndex]
779
+
780
+ // return categoryData.map((datum, datumIndex) => {
781
+ // return {
782
+ // ...datum,
783
+ // axisX: 0,
784
+ // axisY: yScale(datum.label),
785
+ // }
786
+ // })
787
+ // })
788
+ // })
789
+ // )
790
+ // }