@orbcharts/plugins-basic 3.0.0-beta.15 → 3.0.0-beta.16

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 (180) hide show
  1. package/dist/orbcharts-plugins-basic.es.js +15129 -13927
  2. package/dist/orbcharts-plugins-basic.umd.js +72 -72
  3. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseBars.d.ts +3 -3
  4. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseBarsTriangle.d.ts +3 -3
  5. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseDots.d.ts +3 -3
  6. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseLineAreas.d.ts +3 -3
  7. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseLines.d.ts +3 -3
  8. package/dist/src/base/BaseRacingBars.d.ts +23 -0
  9. package/dist/src/base/BaseRacingLabels.d.ts +20 -0
  10. package/dist/src/base/BaseRacingValueLabels.d.ts +20 -0
  11. package/dist/{orbcharts-plugins-basic/src/base/BaseStackedBar.d.ts → src/base/BaseStackedBars.d.ts} +7 -7
  12. package/dist/{orbcharts-plugins-basic/src → src}/base/BaseValueAxis.d.ts +4 -7
  13. package/dist/src/base/BaseXAxis.d.ts +20 -0
  14. package/dist/src/base/BaseYAxis.d.ts +18 -0
  15. package/dist/{orbcharts-plugins-basic/src → src}/grid/defaults.d.ts +3 -3
  16. package/dist/{orbcharts-plugins-basic/src → src}/grid/gridObservables.d.ts +8 -1
  17. package/dist/{orbcharts-plugins-basic/src → src}/grid/index.d.ts +2 -2
  18. package/dist/src/grid/plugins/GroupZoom.d.ts +1 -0
  19. package/dist/src/grid/plugins/StackedBars.d.ts +1 -0
  20. package/dist/src/index.d.ts +7 -1
  21. package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/defaults.d.ts +2 -2
  22. package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/index.d.ts +1 -1
  23. package/dist/src/multiGrid/plugins/MultiStackedBars.d.ts +1 -0
  24. package/dist/src/multiValue/defaults.d.ts +13 -0
  25. package/dist/{orbcharts-plugins-basic/src → src}/multiValue/index.d.ts +5 -1
  26. package/dist/src/multiValue/multiValueObservables.d.ts +56 -0
  27. package/dist/src/multiValue/plugins/RacingBars.d.ts +1 -0
  28. package/dist/src/multiValue/plugins/RacingCounterTexts.d.ts +3 -0
  29. package/dist/src/multiValue/plugins/RacingValueAxis.d.ts +1 -0
  30. package/dist/src/multiValue/plugins/XAxis.d.ts +1 -0
  31. package/dist/src/multiValue/plugins/XYAxes.d.ts +1 -0
  32. package/dist/src/multiValue/plugins/XZoom.d.ts +1 -0
  33. package/lib/core.ts +1 -1
  34. package/package.json +4 -4
  35. package/src/base/BaseBars.ts +11 -11
  36. package/src/base/BaseBarsTriangle.ts +11 -11
  37. package/src/base/BaseDots.ts +10 -10
  38. package/src/base/BaseGroupAxis.ts +2 -0
  39. package/src/base/BaseLineAreas.ts +8 -8
  40. package/src/base/BaseLines.ts +7 -7
  41. package/src/base/BaseRacingBars.ts +552 -0
  42. package/src/base/BaseRacingLabels.ts +392 -0
  43. package/src/base/BaseRacingValueLabels.ts +403 -0
  44. package/src/base/{BaseStackedBar.ts → BaseStackedBars.ts} +22 -22
  45. package/src/base/BaseValueAxis.ts +70 -53
  46. package/src/base/BaseXAxis.ts +427 -0
  47. package/src/base/BaseYAxis.ts +389 -0
  48. package/src/grid/defaults.ts +4 -56
  49. package/src/grid/gridObservables.ts +58 -0
  50. package/src/grid/index.ts +2 -2
  51. package/src/grid/plugins/Bars.ts +2 -2
  52. package/src/grid/plugins/BarsPN.ts +2 -2
  53. package/src/grid/plugins/BarsTriangle.ts +2 -2
  54. package/src/grid/plugins/Dots.ts +2 -2
  55. package/src/grid/plugins/GridLegend.ts +7 -7
  56. package/src/grid/plugins/GroupAxis.ts +0 -24
  57. package/src/grid/plugins/{GridZoom.ts → GroupZoom.ts} +2 -2
  58. package/src/grid/plugins/LineAreas.ts +2 -2
  59. package/src/grid/plugins/Lines.ts +2 -2
  60. package/src/grid/plugins/{StackedBar.ts → StackedBars.ts} +6 -6
  61. package/src/multiGrid/defaults.ts +2 -2
  62. package/src/multiGrid/index.ts +1 -1
  63. package/src/multiGrid/multiGridObservables.ts +1 -0
  64. package/src/multiGrid/plugins/MultiBars.ts +3 -3
  65. package/src/multiGrid/plugins/MultiBarsTriangle.ts +3 -3
  66. package/src/multiGrid/plugins/MultiDots.ts +3 -3
  67. package/src/multiGrid/plugins/MultiGridLegend.ts +20 -10
  68. package/src/multiGrid/plugins/MultiLineAreas.ts +3 -3
  69. package/src/multiGrid/plugins/MultiLines.ts +3 -3
  70. package/src/multiGrid/plugins/{MultiStackedBar.ts → MultiStackedBars.ts} +7 -7
  71. package/src/multiGrid/plugins/OverlappingStackedValueAxes.ts +1 -0
  72. package/src/multiValue/defaults.ts +137 -4
  73. package/src/multiValue/index.ts +5 -1
  74. package/src/multiValue/multiValueObservables.ts +414 -44
  75. package/src/multiValue/plugins/OrdinalBubbles.ts +0 -0
  76. package/src/multiValue/plugins/OrdinalXAxis.ts +0 -0
  77. package/src/multiValue/plugins/RacingBars.ts +362 -0
  78. package/src/multiValue/plugins/RacingCounterAxis.ts +0 -0
  79. package/src/multiValue/plugins/RacingCounterTexts.ts +300 -0
  80. package/src/multiValue/plugins/RacingValueAxis.ts +115 -0
  81. package/src/multiValue/plugins/RankingAxis_legacy.ts +109 -0
  82. package/src/multiValue/plugins/Scatter.ts +13 -13
  83. package/src/multiValue/plugins/ScatterBubbles.ts +13 -13
  84. package/src/multiValue/plugins/XAxis.ts +108 -0
  85. package/src/multiValue/plugins/XYAux.ts +13 -13
  86. package/src/multiValue/plugins/XYAxes.ts +38 -528
  87. package/src/multiValue/plugins/XYAxes_legacy.ts +684 -0
  88. package/src/multiValue/plugins/{XYZoom.ts → XZoom.ts} +14 -14
  89. package/src/series/defaults.ts +2 -13
  90. package/src/series/plugins/Bubbles.ts +45 -29
  91. package/src/series/plugins/Pie.ts +5 -5
  92. package/src/series/plugins/PieEventTexts.ts +3 -3
  93. package/src/series/plugins/PieLabels.ts +5 -5
  94. package/src/series/plugins/Rose.ts +11 -11
  95. package/src/series/plugins/RoseLabels.ts +9 -9
  96. package/dist/orbcharts-plugins-basic/src/grid/plugins/GridZoom.d.ts +0 -1
  97. package/dist/orbcharts-plugins-basic/src/grid/plugins/StackedBar.d.ts +0 -1
  98. package/dist/orbcharts-plugins-basic/src/index.d.ts +0 -7
  99. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/MultiStackedBar.d.ts +0 -1
  100. package/dist/orbcharts-plugins-basic/src/multiValue/defaults.d.ts +0 -9
  101. package/dist/orbcharts-plugins-basic/src/multiValue/multiValueObservables.d.ts +0 -33
  102. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/XYZoom.d.ts +0 -1
  103. /package/dist/{orbcharts-plugins-basic/lib → lib}/core-types.d.ts +0 -0
  104. /package/dist/{orbcharts-plugins-basic/lib → lib}/core.d.ts +0 -0
  105. /package/dist/{orbcharts-plugins-basic/lib → lib}/plugins-basic-types.d.ts +0 -0
  106. /package/dist/{orbcharts-plugins-basic/src → src}/base/BaseGroupAxis.d.ts +0 -0
  107. /package/dist/{orbcharts-plugins-basic/src → src}/base/BaseLegend.d.ts +0 -0
  108. /package/dist/{orbcharts-plugins-basic/src → src}/base/BaseTooltip.d.ts +0 -0
  109. /package/dist/{orbcharts-plugins-basic/src → src}/base/types.d.ts +0 -0
  110. /package/dist/{orbcharts-plugins-basic/src → src}/const.d.ts +0 -0
  111. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/Bars.d.ts +0 -0
  112. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/BarsPN.d.ts +0 -0
  113. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/BarsTriangle.d.ts +0 -0
  114. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/Dots.d.ts +0 -0
  115. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/GridLegend.d.ts +0 -0
  116. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/GridTooltip.d.ts +0 -0
  117. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/GroupAux.d.ts +0 -0
  118. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/GroupAxis.d.ts +0 -0
  119. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/LineAreas.d.ts +0 -0
  120. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/Lines.d.ts +0 -0
  121. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/StackedValueAxis.d.ts +0 -0
  122. /package/dist/{orbcharts-plugins-basic/src → src}/grid/plugins/ValueAxis.d.ts +0 -0
  123. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/multiGridObservables.d.ts +0 -0
  124. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiBars.d.ts +0 -0
  125. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiBarsTriangle.d.ts +0 -0
  126. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiDots.d.ts +0 -0
  127. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiGridLegend.d.ts +0 -0
  128. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiGridTooltip.d.ts +0 -0
  129. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiGroupAxis.d.ts +0 -0
  130. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiLineAreas.d.ts +0 -0
  131. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiLines.d.ts +0 -0
  132. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiStackedValueAxis.d.ts +0 -0
  133. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/MultiValueAxis.d.ts +0 -0
  134. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/OverlappingStackedValueAxes.d.ts +0 -0
  135. /package/dist/{orbcharts-plugins-basic/src → src}/multiGrid/plugins/OverlappingValueAxes.d.ts +0 -0
  136. /package/dist/{orbcharts-plugins-basic/src → src}/multiValue/plugins/MultiValueLegend.d.ts +0 -0
  137. /package/dist/{orbcharts-plugins-basic/src → src}/multiValue/plugins/MultiValueTooltip.d.ts +0 -0
  138. /package/dist/{orbcharts-plugins-basic/src/multiValue/plugins/Ranking.d.ts → src/multiValue/plugins/OrdinalBubbles.d.ts} +0 -0
  139. /package/dist/{orbcharts-plugins-basic/src/multiValue/plugins/RankingAxis.d.ts → src/multiValue/plugins/OrdinalXAxis.d.ts} +0 -0
  140. /package/dist/{orbcharts-plugins-basic/src/noneData/plugins/Container.d.ts → src/multiValue/plugins/RacingCounterAxis.d.ts} +0 -0
  141. /package/dist/{orbcharts-plugins-basic/src/noneData/plugins/Tooltip.d.ts → src/multiValue/plugins/RankingAxis_legacy.d.ts} +0 -0
  142. /package/dist/{orbcharts-plugins-basic/src → src}/multiValue/plugins/Scatter.d.ts +0 -0
  143. /package/dist/{orbcharts-plugins-basic/src → src}/multiValue/plugins/ScatterBubbles.d.ts +0 -0
  144. /package/dist/{orbcharts-plugins-basic/src → src}/multiValue/plugins/XYAux.d.ts +0 -0
  145. /package/dist/{orbcharts-plugins-basic/src/multiValue/plugins/XYAxes.d.ts → src/multiValue/plugins/XYAxes_legacy.d.ts} +0 -0
  146. /package/dist/{orbcharts-plugins-basic/src → src}/noneData/defaults.d.ts +0 -0
  147. /package/dist/{orbcharts-plugins-basic/src → src}/noneData/index.d.ts +0 -0
  148. /package/dist/{orbcharts-plugins-basic/src/series/plugins/Waffle.d.ts → src/noneData/plugins/Container.d.ts} +0 -0
  149. /package/{src/multiValue/plugins/Ranking.ts → dist/src/noneData/plugins/Tooltip.d.ts} +0 -0
  150. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/defaults.d.ts +0 -0
  151. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/index.d.ts +0 -0
  152. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/plugins/ForceDirected.d.ts +0 -0
  153. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/plugins/ForceDirectedBubbles.d.ts +0 -0
  154. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/plugins/RelationshipLegend.d.ts +0 -0
  155. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/plugins/RelationshipTooltip.d.ts +0 -0
  156. /package/dist/{orbcharts-plugins-basic/src → src}/relationship/relationshipObservables.d.ts +0 -0
  157. /package/dist/{orbcharts-plugins-basic/src → src}/series/defaults.d.ts +0 -0
  158. /package/dist/{orbcharts-plugins-basic/src → src}/series/index.d.ts +0 -0
  159. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/Bubbles.d.ts +0 -0
  160. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/Pie.d.ts +0 -0
  161. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/PieEventTexts.d.ts +0 -0
  162. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/PieLabels.d.ts +0 -0
  163. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/Rose.d.ts +0 -0
  164. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/RoseLabels.d.ts +0 -0
  165. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/SeriesLegend.d.ts +0 -0
  166. /package/dist/{orbcharts-plugins-basic/src → src}/series/plugins/SeriesTooltip.d.ts +0 -0
  167. /package/{src/multiValue/plugins/RankingAxis.ts → dist/src/series/plugins/Waffle.d.ts} +0 -0
  168. /package/dist/{orbcharts-plugins-basic/src → src}/series/seriesObservables.d.ts +0 -0
  169. /package/dist/{orbcharts-plugins-basic/src → src}/series/seriesUtils.d.ts +0 -0
  170. /package/dist/{orbcharts-plugins-basic/src → src}/tree/defaults.d.ts +0 -0
  171. /package/dist/{orbcharts-plugins-basic/src → src}/tree/index.d.ts +0 -0
  172. /package/dist/{orbcharts-plugins-basic/src → src}/tree/plugins/TreeLegend.d.ts +0 -0
  173. /package/dist/{orbcharts-plugins-basic/src → src}/tree/plugins/TreeMap.d.ts +0 -0
  174. /package/dist/{orbcharts-plugins-basic/src → src}/tree/plugins/TreeTooltip.d.ts +0 -0
  175. /package/dist/{orbcharts-plugins-basic/src → src}/utils/commonUtils.d.ts +0 -0
  176. /package/dist/{orbcharts-plugins-basic/src → src}/utils/d3Graphics.d.ts +0 -0
  177. /package/dist/{orbcharts-plugins-basic/src → src}/utils/d3Utils.d.ts +0 -0
  178. /package/dist/{orbcharts-plugins-basic/src → src}/utils/observables.d.ts +0 -0
  179. /package/dist/{orbcharts-plugins-basic/src → src}/utils/orbchartsUtils.d.ts +0 -0
  180. /package/dist/{orbcharts-plugins-basic/vite.config.d.ts → vite.config.d.ts} +0 -0
@@ -3,6 +3,7 @@ import {
3
3
  Observable,
4
4
  Subject,
5
5
  debounceTime,
6
+ iif,
6
7
  of,
7
8
  takeUntil,
8
9
  filter,
@@ -19,25 +20,32 @@ import type {
19
20
  DataFormatterMultiValue,
20
21
  ComputedDataMultiValue,
21
22
  ComputedDatumMultiValue,
22
- ComputedLayoutDatumMultiValue,
23
+ ComputedXYDatumMultiValue,
24
+ ComputedXYDataMultiValue,
23
25
  TransformData,
26
+ ContainerSize,
24
27
  ContainerPositionScaled,
25
28
  Layout,
26
29
  } from '../../lib/core-types'
27
- import { createAxisToLabelIndexScale, createAxisToValueScale } from '../../lib/core'
30
+ import {
31
+ createAxisToLabelIndexScale,
32
+ createAxisToValueScale,
33
+ createLabelToAxisScale,
34
+ createValueToAxisScale,
35
+ } from '../../lib/core'
28
36
  import { getClassName, getUniID } from '../utils/orbchartsUtils'
29
37
  import { d3EventObservable } from '../utils/observables'
30
38
 
31
39
  // 建立 multiValue 主要的 selection
32
- export const multiValueSelectionsObservable = ({ selection, pluginName, clipPathID, categoryLabels$, multiValueContainerPosition$, multiValueGraphicTransform$ }: {
40
+ export const multiValueSelectionsObservable = ({ selection, pluginName, clipPathID, categoryLabels$, containerPosition$, graphicTransform$ }: {
33
41
  selection: d3.Selection<any, unknown, any, unknown>
34
42
  pluginName: string
35
43
  clipPathID: string
36
44
  // computedData$: Observable<ComputedDataMultiValue>
37
45
  categoryLabels$: Observable<string[]>
38
- multiValueContainerPosition$: Observable<ContainerPositionScaled[]>
46
+ containerPosition$: Observable<ContainerPositionScaled[]>
39
47
  // multiValueAxesTransform$: Observable<TransformData>
40
- multiValueGraphicTransform$: Observable<TransformData>
48
+ graphicTransform$: Observable<TransformData>
41
49
  }) => {
42
50
  const categoryClassName = getClassName(pluginName, 'category')
43
51
  const axesClassName = getClassName(pluginName, 'axes')
@@ -95,16 +103,16 @@ export const multiValueSelectionsObservable = ({ selection, pluginName, clipPath
95
103
  // <g> category selection
96
104
  combineLatest({
97
105
  categorySelection: categorySelection$,
98
- multiValueContainerPosition: multiValueContainerPosition$
106
+ containerPosition: containerPosition$
99
107
  }).pipe(
100
108
  switchMap(async d => d)
101
109
  ).subscribe(data => {
102
110
  data.categorySelection
103
111
  .transition()
104
112
  .attr('transform', (d, i) => {
105
- const multiValueContainerPosition = data.multiValueContainerPosition[i] ?? data.multiValueContainerPosition[0]
106
- const translate = multiValueContainerPosition.translate
107
- const scale = multiValueContainerPosition.scale
113
+ const containerPosition = data.containerPosition[i] ?? data.containerPosition[0]
114
+ const translate = containerPosition.translate
115
+ const scale = containerPosition.scale
108
116
  return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
109
117
  })
110
118
  })
@@ -129,7 +137,7 @@ export const multiValueSelectionsObservable = ({ selection, pluginName, clipPath
129
137
  // <g> graphic selection
130
138
  const graphicGSelection$ = combineLatest({
131
139
  axesSelection: axesSelection$,
132
- multiValueGraphicTransform: multiValueGraphicTransform$
140
+ graphicTransform: graphicTransform$
133
141
  }).pipe(
134
142
  switchMap(async d => d),
135
143
  map(data => {
@@ -138,7 +146,7 @@ export const multiValueSelectionsObservable = ({ selection, pluginName, clipPath
138
146
  graphicGSelection
139
147
  .transition()
140
148
  .duration(50)
141
- .style('transform', data.multiValueGraphicTransform.value)
149
+ .style('transform', data.graphicTransform.value)
142
150
  return graphicGSelection
143
151
  }),
144
152
  shareReplay(1)
@@ -152,28 +160,89 @@ export const multiValueSelectionsObservable = ({ selection, pluginName, clipPath
152
160
  }
153
161
  }
154
162
 
163
+ // 建立 multiValue 主要的 selection - 只取無scale的container selection
164
+ export const multiValueContainerSelectionsObservable = ({ selection, pluginName, clipPathID, computedData$, containerPosition$, isCategorySeprate$ }: {
165
+ selection: d3.Selection<any, unknown, any, unknown>
166
+ pluginName: string
167
+ clipPathID: string | null
168
+ computedData$: Observable<ComputedDataMultiValue>
169
+ containerPosition$: Observable<ContainerPositionScaled[]>
170
+ isCategorySeprate$: Observable<boolean>
171
+ }) => {
172
+ const containerClassName = getClassName(pluginName, 'container')
173
+
174
+ const containerSelection$ = combineLatest({
175
+ computedData: computedData$.pipe(
176
+ distinctUntilChanged((a, b) => {
177
+ // 只有當series的數量改變時,才重新計算
178
+ return a.length === b.length
179
+ }),
180
+ ),
181
+ isCategorySeprate: isCategorySeprate$
182
+ }).pipe(
183
+ switchMap(async (d) => d),
184
+ map(data => {
185
+ return data.isCategorySeprate
186
+ // category分開的時候顯示各別axis
187
+ ? data.computedData
188
+ // category合併的時候只顯示第一個axis
189
+ : [data.computedData[0]]
190
+ }),
191
+ map((computedData, i) => {
192
+ return selection
193
+ .selectAll<SVGGElement, ComputedDatumMultiValue[]>(`g.${containerClassName}`)
194
+ .data(computedData, d => d[0] ? d[0].categoryIndex : i)
195
+ .join('g')
196
+ .classed(containerClassName, true)
197
+ .attr('clip-path', _ => clipPathID ? `url(#${clipPathID})` : 'none')
198
+ }),
199
+ shareReplay(1)
200
+ )
201
+
202
+ combineLatest({
203
+ containerSelection: containerSelection$,
204
+ gridContainerPosition: containerPosition$
205
+ }).pipe(
206
+ switchMap(async d => d)
207
+ ).subscribe(data => {
208
+ data.containerSelection
209
+ .attr('transform', (d, i) => {
210
+ const gridContainerPosition = data.gridContainerPosition[i] ?? data.gridContainerPosition[0]
211
+ const translate = gridContainerPosition.translate
212
+ const scale = gridContainerPosition.scale
213
+ // return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
214
+ return `translate(${translate[0]}, ${translate[1]})`
215
+ })
216
+ // .attr('opacity', 0)
217
+ // .transition()
218
+ // .attr('opacity', 1)
219
+ })
155
220
 
156
- export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatter$, filteredMinMaxXYData$, multiValueContainerPosition$, layout$ }: {
221
+ return containerSelection$
222
+ }
223
+
224
+
225
+ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatter$, filteredXYMinMaxData$, containerPosition$, layout$ }: {
157
226
  rootSelection: d3.Selection<any, unknown, any, unknown>
158
227
  fullDataFormatter$: Observable<DataFormatterMultiValue>
159
228
  // computedData$: Observable<ComputedDataMultiValue>
160
- // minMaxXY$: Observable<{ minX: number, maxX: number, minY: number, maxY: number }>
161
- filteredMinMaxXYData$: Observable<{
162
- minXDatum: ComputedLayoutDatumMultiValue
163
- maxXDatum: ComputedLayoutDatumMultiValue
164
- minYDatum: ComputedLayoutDatumMultiValue
165
- maxYDatum: ComputedLayoutDatumMultiValue
229
+ // xyMinMax$: Observable<{ minX: number, maxX: number, minY: number, maxY: number }>
230
+ filteredXYMinMaxData$: Observable<{
231
+ minXDatum: ComputedXYDatumMultiValue
232
+ maxXDatum: ComputedXYDatumMultiValue
233
+ minYDatum: ComputedXYDatumMultiValue
234
+ maxYDatum: ComputedXYDatumMultiValue
166
235
  }>
167
- multiValueContainerPosition$: Observable<ContainerPositionScaled[]>
236
+ containerPosition$: Observable<ContainerPositionScaled[]>
168
237
  layout$: Observable<Layout>
169
238
  }) => {
170
239
  const rootMousemove$ = d3EventObservable(rootSelection, 'mousemove').pipe(
171
240
  debounceTime(2) // 避免過度頻繁觸發,實測時沒加電腦容易卡頓
172
241
  )
173
242
 
174
- const columnAmount$ = multiValueContainerPosition$.pipe(
175
- map(multiValueContainerPosition => {
176
- const maxColumnIndex = multiValueContainerPosition.reduce((acc, current) => {
243
+ const columnAmount$ = containerPosition$.pipe(
244
+ map(containerPosition => {
245
+ const maxColumnIndex = containerPosition.reduce((acc, current) => {
177
246
  return current.columnIndex > acc ? current.columnIndex : acc
178
247
  }, 0)
179
248
  return maxColumnIndex + 1
@@ -182,9 +251,9 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
182
251
  shareReplay(1)
183
252
  )
184
253
 
185
- const rowAmount$ = multiValueContainerPosition$.pipe(
186
- map(multiValueContainerPosition => {
187
- const maxRowIndex = multiValueContainerPosition.reduce((acc, current) => {
254
+ const rowAmount$ = containerPosition$.pipe(
255
+ map(containerPosition => {
256
+ const maxRowIndex = containerPosition.reduce((acc, current) => {
188
257
  return current.rowIndex > acc ? current.rowIndex : acc
189
258
  }, 0)
190
259
  return maxRowIndex + 1
@@ -195,7 +264,7 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
195
264
 
196
265
  // const xyScale$ = combineLatest({
197
266
  // layout: layout$,
198
- // filteredMinMaxXYData: filteredMinMaxXYData$,
267
+ // filteredXYMinMaxData: filteredXYMinMaxData$,
199
268
  // fullDataFormatter: fullDataFormatter$,
200
269
  // columnAmount: columnAmount$,
201
270
  // rowAmount: rowAmount$
@@ -203,15 +272,15 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
203
272
  // switchMap(async d => d),
204
273
  // map(data => {
205
274
  // const xScale = createAxisToValueScale({
206
- // maxValue: data.filteredMinMaxXYData.maxXDatum.value[0],
207
- // minValue: data.filteredMinMaxXYData.minXDatum.value[0],
275
+ // maxValue: data.filteredXYMinMaxData.maxXDatum.value[0],
276
+ // minValue: data.filteredXYMinMaxData.minXDatum.value[0],
208
277
  // axisWidth: data.layout.width,
209
278
  // scaleDomain: data.fullDataFormatter.xAxis.scaleDomain,
210
279
  // scaleRange: data.fullDataFormatter.xAxis.scaleRange,
211
280
  // })
212
281
  // const yScale = createAxisToValueScale({
213
- // maxValue: data.filteredMinMaxXYData.maxYDatum.value[1],
214
- // minValue: data.filteredMinMaxXYData.minYDatum.value[1],
282
+ // maxValue: data.filteredXYMinMaxData.maxYDatum.value[1],
283
+ // minValue: data.filteredXYMinMaxData.minYDatum.value[1],
215
284
  // axisWidth: data.layout.height,
216
285
  // scaleDomain: data.fullDataFormatter.yAxis.scaleDomain,
217
286
  // scaleRange: data.fullDataFormatter.yAxis.scaleRange,
@@ -227,30 +296,32 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
227
296
  }> = new Observable(subscriber => {
228
297
  combineLatest({
229
298
  layout: layout$,
230
- filteredMinMaxXYData: filteredMinMaxXYData$,
299
+ filteredXYMinMaxData: filteredXYMinMaxData$,
231
300
  fullDataFormatter: fullDataFormatter$,
232
301
  columnAmount: columnAmount$,
233
302
  rowAmount: rowAmount$
234
303
  }).pipe(
235
304
  switchMap(async d => d),
236
305
  ).subscribe(data => {
237
- if (!data.filteredMinMaxXYData.minXDatum || !data.filteredMinMaxXYData.maxXDatum
238
- || data.filteredMinMaxXYData.minXDatum.value[0] == null || data.filteredMinMaxXYData.maxXDatum.value[0] == null
239
- || !data.filteredMinMaxXYData.minYDatum || !data.filteredMinMaxXYData.maxYDatum
240
- || data.filteredMinMaxXYData.minYDatum.value[1] == null || data.filteredMinMaxXYData.maxYDatum.value[1] == null
306
+ const xValueIndex = data.fullDataFormatter.xAxis.valueIndex
307
+ const yValueIndex = data.fullDataFormatter.yAxis.valueIndex
308
+ if (!data.filteredXYMinMaxData.minXDatum || !data.filteredXYMinMaxData.maxXDatum
309
+ || data.filteredXYMinMaxData.minXDatum.value[xValueIndex] == null || data.filteredXYMinMaxData.maxXDatum.value[xValueIndex] == null
310
+ || !data.filteredXYMinMaxData.minYDatum || !data.filteredXYMinMaxData.maxYDatum
311
+ || data.filteredXYMinMaxData.minYDatum.value[yValueIndex] == null || data.filteredXYMinMaxData.maxYDatum.value[yValueIndex] == null
241
312
  ) {
242
313
  return
243
314
  }
244
315
  const xScale = createAxisToValueScale({
245
- maxValue: data.filteredMinMaxXYData.maxXDatum.value[0],
246
- minValue: data.filteredMinMaxXYData.minXDatum.value[0],
316
+ maxValue: data.filteredXYMinMaxData.maxXDatum.value[xValueIndex],
317
+ minValue: data.filteredXYMinMaxData.minXDatum.value[xValueIndex],
247
318
  axisWidth: data.layout.width,
248
319
  scaleDomain: data.fullDataFormatter.xAxis.scaleDomain,
249
320
  scaleRange: data.fullDataFormatter.xAxis.scaleRange,
250
321
  })
251
322
  const yScale = createAxisToValueScale({
252
- maxValue: data.filteredMinMaxXYData.maxYDatum.value[1],
253
- minValue: data.filteredMinMaxXYData.minYDatum.value[1],
323
+ maxValue: data.filteredXYMinMaxData.maxYDatum.value[yValueIndex],
324
+ minValue: data.filteredXYMinMaxData.minYDatum.value[yValueIndex],
254
325
  axisWidth: data.layout.height,
255
326
  scaleDomain: data.fullDataFormatter.yAxis.scaleDomain,
256
327
  scaleRange: data.fullDataFormatter.yAxis.scaleRange,
@@ -266,16 +337,16 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
266
337
  columnAmount: columnAmount$,
267
338
  rowAmount: rowAmount$,
268
339
  layout: layout$,
269
- multiValueContainerPosition: multiValueContainerPosition$
340
+ containerPosition: containerPosition$
270
341
  }).pipe(
271
342
  switchMap(async d => d),
272
343
  map(data => {
273
344
  // 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
274
345
  return {
275
- x: ((data.rootMousemove.offsetX - data.layout.left) / data.multiValueContainerPosition[0].scale[0])
276
- % (data.layout.rootWidth / data.columnAmount / data.multiValueContainerPosition[0].scale[0]),
277
- y: ((data.rootMousemove.offsetY - data.layout.top) / data.multiValueContainerPosition[0].scale[1])
278
- % (data.layout.rootHeight / data.rowAmount / data.multiValueContainerPosition[0].scale[1])
346
+ x: ((data.rootMousemove.offsetX - data.layout.left) / data.containerPosition[0].scale[0])
347
+ % (data.layout.rootWidth / data.columnAmount / data.containerPosition[0].scale[0]),
348
+ y: ((data.rootMousemove.offsetY - data.layout.top) / data.containerPosition[0].scale[1])
349
+ % (data.layout.rootHeight / data.rowAmount / data.containerPosition[0].scale[1])
279
350
  }
280
351
  })
281
352
  )
@@ -295,3 +366,302 @@ export const multiValueXYPositionObservable = ({ rootSelection, fullDataFormatte
295
366
  })
296
367
  )
297
368
  }
369
+
370
+ // 排名數量
371
+ export const computedRankingAmountObservable = ({ containerSize$, visibleComputedData$, textSizePx$, rankingAmount$ }: {
372
+ containerSize$: Observable<ContainerSize>
373
+ visibleComputedData$: Observable<ComputedDatumMultiValue[][]>
374
+ textSizePx$: Observable<number>
375
+ rankingAmount$: Observable<'auto' | number>
376
+ }) => {
377
+ const minLineHeightObservable = ({ textSizePx$ }: {
378
+ textSizePx$: Observable<number>
379
+ }) => {
380
+ return textSizePx$.pipe(
381
+ map(textSizePx => textSizePx * 2), // 2倍行高
382
+ shareReplay(1)
383
+ )
384
+ }
385
+
386
+ const containerHeightObservable = ({ minLineHeight$, containerSize$ }: {
387
+ minLineHeight$: Observable<number>
388
+ containerSize$: Observable<ContainerSize>
389
+ }) => {
390
+ return combineLatest({
391
+ minLineHeight: minLineHeight$,
392
+ containerSize: containerSize$
393
+ }).pipe(
394
+ switchMap(async (d) => d),
395
+ map(data => {
396
+ // 避免過小造成計算 scale 錯誤
397
+ return data.containerSize.height > data.minLineHeight
398
+ ? data.containerSize.height
399
+ : data.minLineHeight
400
+ }),
401
+ distinctUntilChanged(),
402
+ shareReplay(1)
403
+ )
404
+ }
405
+
406
+ const rankingAmountLimitObservable = ({ minLineHeight$, containerHeight$ }: {
407
+ containerHeight$: Observable<number>
408
+ minLineHeight$: Observable<number>
409
+ }) => {
410
+
411
+ return combineLatest({
412
+ minLineHeight: minLineHeight$,
413
+ containerHeight: containerHeight$
414
+ }).pipe(
415
+ switchMap(async (d) => d),
416
+ map(data => {
417
+ const labelAmountLimit = Math.floor(data.containerHeight / data.minLineHeight)
418
+ return labelAmountLimit
419
+ }),
420
+ distinctUntilChanged(),
421
+ shareReplay(1)
422
+ )
423
+ }
424
+
425
+ const minLineHeight$ = minLineHeightObservable({ textSizePx$ })
426
+
427
+ const containerHeight$ = containerHeightObservable({
428
+ minLineHeight$,
429
+ containerSize$
430
+ })
431
+
432
+ const rankingAmountLimit$ = rankingAmountLimitObservable({
433
+ containerHeight$,
434
+ minLineHeight$
435
+ })
436
+
437
+ // 計算要排名的數量
438
+ return rankingAmount$.pipe(
439
+ switchMap(rankingAmount => {
440
+ return iif(
441
+ () => rankingAmount === 'auto',
442
+ // 'auto': 不超過限制
443
+ combineLatest({
444
+ visibleComputedData: visibleComputedData$,
445
+ rankingAmountLimit: rankingAmountLimit$,
446
+ }).pipe(
447
+ switchMap(async d => d),
448
+ map(data => {
449
+ const rankingAmountArr = data.visibleComputedData.map(categoryData => {
450
+ return Math.min(data.rankingAmountLimit, categoryData.length)
451
+ })
452
+ return Math.max(...rankingAmountArr) // 取所有 container 計算出來的最大值
453
+ })
454
+ ),
455
+ // number: 指定數量
456
+ rankingAmount$ as Observable<number>,
457
+ )
458
+ })
459
+ )
460
+ }
461
+
462
+ export const rankingItemHeightObservable = ({ containerSize$, textSizePx$, computedRankingAmount$ }: {
463
+ containerSize$: Observable<ContainerSize>
464
+ // visibleComputedRankingData$: Observable<ComputedDatumMultiValue[][]>
465
+ textSizePx$: Observable<number>
466
+ // rankingAmount$: Observable<'auto' | number>
467
+ computedRankingAmount$: Observable<number>
468
+ }) => {
469
+ const minLineHeightObservable = ({ textSizePx$ }: {
470
+ textSizePx$: Observable<number>
471
+ }) => {
472
+ return textSizePx$.pipe(
473
+ map(textSizePx => textSizePx * 2), // 2倍行高
474
+ shareReplay(1)
475
+ )
476
+ }
477
+
478
+ const containerHeightObservable = ({ minLineHeight$, containerSize$ }: {
479
+ minLineHeight$: Observable<number>
480
+ containerSize$: Observable<ContainerSize>
481
+ }) => {
482
+ return combineLatest({
483
+ minLineHeight: minLineHeight$,
484
+ containerSize: containerSize$
485
+ }).pipe(
486
+ switchMap(async (d) => d),
487
+ map(data => {
488
+ // 避免過小造成計算 scale 錯誤
489
+ return data.containerSize.height > data.minLineHeight
490
+ ? data.containerSize.height
491
+ : data.minLineHeight
492
+ }),
493
+ distinctUntilChanged(),
494
+ shareReplay(1)
495
+ )
496
+ }
497
+
498
+ const minLineHeight$ = minLineHeightObservable({ textSizePx$ })
499
+
500
+ const containerHeight$ = containerHeightObservable({
501
+ minLineHeight$,
502
+ containerSize$
503
+ })
504
+
505
+ return combineLatest({
506
+ containerHeight: containerHeight$,
507
+ computedRankingAmount: computedRankingAmount$
508
+ }).pipe(
509
+ switchMap(async (d) => d),
510
+ map(data => {
511
+ // // 依每個 category 計算 scale
512
+ // return data.visibleComputedRankingData.map((categoryData, i) => {
513
+ // const rankingAmount = data.computedRankingAmountList[i]
514
+ // const rankingItemHeight = data.containerHeight / rankingAmount
515
+ // return rankingItemHeight
516
+ // })
517
+ const rankingItemHeight = data.containerHeight / data.computedRankingAmount
518
+ return rankingItemHeight
519
+ })
520
+ )
521
+ }
522
+
523
+ export const rankingScaleListObservable = ({ visibleComputedRankingData$, rankingItemHeight$ }: {
524
+ visibleComputedRankingData$: Observable<ComputedDatumMultiValue[][]>
525
+ rankingItemHeight$: Observable<number>
526
+ }) => {
527
+
528
+ return combineLatest({
529
+ visibleComputedRankingData: visibleComputedRankingData$,
530
+ rankingItemHeight: rankingItemHeight$,
531
+ }).pipe(
532
+ switchMap(async (d) => d),
533
+ map(data => {
534
+ // 依每個 category 計算 scale
535
+ return data.visibleComputedRankingData.map((categoryData, i) => {
536
+ const allLabelAmount = categoryData.length
537
+ // const rankingItemHeight = data.rankingItemHeightList[i]
538
+ const totalHeight = data.rankingItemHeight * allLabelAmount // 有可能超出圖軸高度
539
+
540
+ return createLabelToAxisScale({
541
+ axisLabels: categoryData.map(d => d.label),
542
+ axisWidth: totalHeight,
543
+ padding: 0.5
544
+ })
545
+ })
546
+ })
547
+ )
548
+ }
549
+
550
+
551
+ // // Ranking資料 - 有 XY 資料 @Q@ 若沒用到要棄用
552
+ // export const computedRankingWithXYDataObservable = ({ visibleComputedRankingData$, computedRankingAmountList$, xyValueIndex$, layout$ }: {
553
+ // visibleComputedRankingData$: Observable<ComputedDatumMultiValue[][]>
554
+ // computedRankingAmountList$: Observable<number[]>
555
+ // xyValueIndex$: Observable<[number, number]>
556
+ // layout$: Observable<Layout>
557
+ // }): Observable<ComputedXYDataMultiValue> => {
558
+
559
+ // // // 未篩選範圍前的 scale
560
+ // // function createOriginXScale (xMinMax: { minX: number, maxX: number }, layout: Layout) {
561
+ // // let maxValue = xMinMax.maxX
562
+ // // let minValue = xMinMax.minX
563
+ // // if (minValue === maxValue && maxValue === 0) {
564
+ // // // 避免最大及最小值相同造成無法計算scale
565
+ // // maxValue = 1
566
+ // // }
567
+ // // const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
568
+ // // maxValue,
569
+ // // minValue,
570
+ // // axisWidth: layout.width,
571
+ // // scaleDomain: ['auto', 'auto'], // 不使用dataFormatter設定 --> 以0為基準到最大或最小值為範圍( * 如果是使用[minValue, maxValue]的話,在兩者很接近的情況下有可能造成scale倍率過高而svg變型時失真的情況)
572
+ // // scaleRange: [0, 1] // 不使用dataFormatter設定
573
+ // // })
574
+
575
+ // // return valueScale
576
+ // // }
577
+
578
+ // // 未篩選範圍及visible前的 scale
579
+ // function createOriginYScale (yMinMax: { minY: number, maxY: number }, layout: Layout) {
580
+ // let maxValue = yMinMax.maxY
581
+ // let minValue = yMinMax.minY
582
+ // if (minValue === maxValue && maxValue === 0) {
583
+ // // 避免最大及最小值相同造成無法計算scale
584
+ // maxValue = 1
585
+ // }
586
+ // const valueScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
587
+ // maxValue,
588
+ // minValue,
589
+ // axisWidth: layout.height,
590
+ // scaleDomain: ['auto', 'auto'], // 不使用dataFormatter設定 --> 以0為基準到最大或最小值為範圍( * 如果是使用[minValue, maxValue]的話,在兩者很接近的情況下有可能造成scale倍率過高而svg變型時失真的情況)
591
+ // scaleRange: [0, 1], // 不使用dataFormatter設定
592
+ // // reverse: true
593
+ // })
594
+
595
+ // return valueScale
596
+ // }
597
+
598
+ // return combineLatest({
599
+ // visibleComputedRankingData: visibleComputedRankingData$,
600
+ // computedRankingAmountList: computedRankingAmountList$,
601
+ // xyValueIndex: xyValueIndex$,
602
+ // layout: layout$
603
+ // }).pipe(
604
+ // switchMap(async d => d),
605
+ // map(data => {
606
+
607
+ // // const maxX = data.visibleComputedRankingData
608
+ // // .flat()
609
+ // // .reduce((acc, current) => {
610
+ // // const maxXIndex = current.value.length - 1
611
+ // // return maxXIndex > acc ? maxXIndex : acc
612
+ // // }, 0)
613
+ // // const xMinMax = {
614
+ // // minX: 0,
615
+ // // maxX
616
+ // // }
617
+ // // const xScale = createOriginXScale(xMinMax, data.layout)
618
+ // // console.log('data.visibleComputedRankingData', data.visibleComputedRankingData)
619
+ // return data.visibleComputedRankingData
620
+ // .map((categoryData, categoryIndex) => {
621
+ // const yMinMax = {
622
+ // minY: 0,
623
+ // maxY: data.computedRankingAmountList[categoryIndex]
624
+ // }
625
+ // const yScale = createOriginYScale(yMinMax, data.layout)
626
+
627
+ // return categoryData.map((datum, datumIndex) => {
628
+ // return {
629
+ // ...datum,
630
+ // // axisX: xScale(datum.value[data.xyValueIndex[0]] ?? 0),
631
+ // axisX: 0,
632
+ // // axisY: yScale(datum.value[data.xyValueIndex[1]] ?? 0), // y軸的繪圖座標是從上到下,所以反轉
633
+ // axisY: yScale(datumIndex),
634
+ // }
635
+ // })
636
+ // })
637
+ // })
638
+ // )
639
+ // }
640
+
641
+ // // Ranking資料 - 有 XY 資料 @Q@ 若沒用到要棄用
642
+ // export const computedRankingWithXYDataObservable = ({ visibleComputedRankingData$, rankingScaleList$ }: {
643
+ // visibleComputedRankingData$: Observable<ComputedDatumMultiValue[][]>
644
+ // rankingScaleList$: Observable<d3.ScalePoint<string>[]>
645
+ // }): Observable<ComputedXYDataMultiValue> => {
646
+
647
+ // return combineLatest({
648
+ // visibleComputedRankingData: visibleComputedRankingData$,
649
+ // rankingScaleList: rankingScaleList$
650
+ // }).pipe(
651
+ // switchMap(async d => d),
652
+ // map(data => {
653
+ // return data.visibleComputedRankingData
654
+ // .map((categoryData, categoryIndex) => {
655
+ // const yScale = data.rankingScaleList[categoryIndex]
656
+
657
+ // return categoryData.map((datum, datumIndex) => {
658
+ // return {
659
+ // ...datum,
660
+ // axisX: 0,
661
+ // axisY: yScale(datum.label),
662
+ // }
663
+ // })
664
+ // })
665
+ // })
666
+ // )
667
+ // }
File without changes
File without changes