@orbcharts/plugins-basic 3.0.0-beta.7 → 3.0.0-beta.8

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 (126) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-plugins-basic/src/base/{BaseBarStack.d.ts → BaseStackedBar.d.ts} +4 -4
  3. package/dist/orbcharts-plugins-basic/src/grid/defaults.d.ts +3 -3
  4. package/dist/orbcharts-plugins-basic/src/grid/index.d.ts +2 -2
  5. package/dist/orbcharts-plugins-basic/src/grid/plugins/StackedBar.d.ts +1 -0
  6. package/dist/orbcharts-plugins-basic/src/grid/plugins/StackedValueAxis.d.ts +1 -0
  7. package/dist/orbcharts-plugins-basic/src/index.d.ts +1 -0
  8. package/dist/orbcharts-plugins-basic/src/multiGrid/defaults.d.ts +4 -4
  9. package/dist/orbcharts-plugins-basic/src/multiGrid/index.d.ts +3 -3
  10. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/MultiStackedBar.d.ts +1 -0
  11. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/MultiStackedValueAxis.d.ts +1 -0
  12. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/OverlappingStackedValueAxes.d.ts +1 -0
  13. package/dist/orbcharts-plugins-basic/src/noneData/plugins/Container.d.ts +0 -1
  14. package/dist/orbcharts-plugins-basic/src/noneData/plugins/Tooltip.d.ts +0 -3
  15. package/dist/orbcharts-plugins-basic/src/relationship/defaults.d.ts +5 -0
  16. package/dist/orbcharts-plugins-basic/src/relationship/index.d.ts +4 -0
  17. package/dist/orbcharts-plugins-basic/src/relationship/plugins/ForceDirected.d.ts +3 -0
  18. package/dist/orbcharts-plugins-basic/src/relationship/plugins/RelationshipLegend.d.ts +1 -0
  19. package/dist/orbcharts-plugins-basic/src/relationship/plugins/RelationshipTooltip.d.ts +1 -0
  20. package/dist/orbcharts-plugins-basic/src/relationship/relationshipObservables.d.ts +1 -0
  21. package/dist/orbcharts-plugins-basic/src/utils/commonUtils.d.ts +1 -1
  22. package/dist/orbcharts-plugins-basic/src/utils/orbchartsUtils.d.ts +1 -1
  23. package/dist/orbcharts-plugins-basic.es.js +8122 -7467
  24. package/dist/orbcharts-plugins-basic.umd.js +45 -32
  25. package/lib/core-types.ts +7 -7
  26. package/lib/core.ts +6 -6
  27. package/lib/plugins-basic-types.ts +6 -6
  28. package/package.json +44 -44
  29. package/src/base/BaseBars.ts +765 -765
  30. package/src/base/BaseBarsTriangle.ts +676 -676
  31. package/src/base/BaseDots.ts +464 -464
  32. package/src/base/BaseGroupAxis.ts +679 -679
  33. package/src/base/BaseLegend.ts +684 -684
  34. package/src/base/BaseLineAreas.ts +629 -629
  35. package/src/base/BaseLines.ts +706 -706
  36. package/src/base/{BaseBarStack.ts → BaseStackedBar.ts} +782 -782
  37. package/src/base/BaseTooltip.ts +385 -385
  38. package/src/base/BaseValueAxis.ts +583 -583
  39. package/src/base/types.ts +2 -2
  40. package/src/const.ts +30 -30
  41. package/src/grid/defaults.ts +246 -246
  42. package/src/grid/gridObservables.ts +554 -554
  43. package/src/grid/index.ts +16 -16
  44. package/src/grid/plugins/Bars.ts +69 -69
  45. package/src/grid/plugins/BarsPN.ts +66 -66
  46. package/src/grid/plugins/BarsTriangle.ts +73 -73
  47. package/src/grid/plugins/Dots.ts +68 -68
  48. package/src/grid/plugins/GridLegend.ts +107 -107
  49. package/src/grid/plugins/GridTooltip.ts +66 -66
  50. package/src/grid/plugins/GridZoom.ts +218 -218
  51. package/src/grid/plugins/GroupAux.ts +1103 -1103
  52. package/src/grid/plugins/GroupAxis.ts +97 -97
  53. package/src/grid/plugins/LineAreas.ts +65 -65
  54. package/src/grid/plugins/Lines.ts +59 -59
  55. package/src/grid/plugins/{BarStack.ts → StackedBar.ts} +64 -64
  56. package/src/grid/plugins/{ValueStackAxis.ts → StackedValueAxis.ts} +96 -96
  57. package/src/grid/plugins/ValueAxis.ts +94 -94
  58. package/src/index.ts +6 -10
  59. package/src/multiGrid/defaults.ts +224 -224
  60. package/src/multiGrid/index.ts +15 -15
  61. package/src/multiGrid/multiGridObservables.ts +49 -49
  62. package/src/multiGrid/plugins/MultiBars.ts +108 -108
  63. package/src/multiGrid/plugins/MultiBarsTriangle.ts +114 -114
  64. package/src/multiGrid/plugins/MultiDots.ts +102 -102
  65. package/src/multiGrid/plugins/MultiGridLegend.ts +159 -159
  66. package/src/multiGrid/plugins/MultiGridTooltip.ts +66 -66
  67. package/src/multiGrid/plugins/MultiGroupAxis.ts +137 -137
  68. package/src/multiGrid/plugins/MultiLineAreas.ts +107 -107
  69. package/src/multiGrid/plugins/MultiLines.ts +101 -101
  70. package/src/multiGrid/plugins/{MultiBarStack.ts → MultiStackedBar.ts} +106 -106
  71. package/src/multiGrid/plugins/{MultiValueStackAxis.ts → MultiStackedValueAxis.ts} +134 -134
  72. package/src/multiGrid/plugins/MultiValueAxis.ts +134 -134
  73. package/src/multiGrid/plugins/{OverlappingValueStackAxes.ts → OverlappingStackedValueAxes.ts} +299 -299
  74. package/src/multiGrid/plugins/OverlappingValueAxes.ts +300 -300
  75. package/src/multiValue/defaults.ts +166 -166
  76. package/src/multiValue/index.ts +8 -8
  77. package/src/multiValue/multiValueObservables.ts +297 -297
  78. package/src/multiValue/plugins/MultiValueLegend.ts +107 -107
  79. package/src/multiValue/plugins/MultiValueTooltip.ts +66 -66
  80. package/src/multiValue/plugins/Scatter.ts +426 -426
  81. package/src/multiValue/plugins/ScatterBubbles.ts +554 -554
  82. package/src/multiValue/plugins/XYAux.ts +681 -681
  83. package/src/multiValue/plugins/XYAxes.ts +684 -684
  84. package/src/multiValue/plugins/XYZoom.ts +299 -299
  85. package/src/noneData/defaults.ts +102 -102
  86. package/src/noneData/index.ts +3 -3
  87. package/src/noneData/plugins/Container.ts +28 -28
  88. package/src/noneData/plugins/Tooltip.ts +374 -374
  89. package/src/relationship/defaults.ts +113 -0
  90. package/src/relationship/index.ts +4 -0
  91. package/src/relationship/plugins/ForceDirected.ts +1148 -0
  92. package/src/relationship/plugins/RelationshipLegend.ts +100 -0
  93. package/src/relationship/plugins/RelationshipTooltip.ts +66 -0
  94. package/src/relationship/relationshipObservables.ts +50 -0
  95. package/src/series/defaults.ts +206 -206
  96. package/src/series/index.ts +9 -9
  97. package/src/series/plugins/Bubbles.ts +604 -603
  98. package/src/series/plugins/Pie.ts +623 -623
  99. package/src/series/plugins/PieEventTexts.ts +284 -283
  100. package/src/series/plugins/PieLabels.ts +640 -640
  101. package/src/series/plugins/Rose.ts +516 -516
  102. package/src/series/plugins/RoseLabels.ts +600 -600
  103. package/src/series/plugins/SeriesLegend.ts +107 -107
  104. package/src/series/plugins/SeriesTooltip.ts +66 -66
  105. package/src/series/seriesObservables.ts +145 -145
  106. package/src/series/seriesUtils.ts +51 -51
  107. package/src/tree/defaults.ts +78 -78
  108. package/src/tree/index.ts +4 -4
  109. package/src/tree/plugins/TreeLegend.ts +100 -100
  110. package/src/tree/plugins/TreeMap.ts +333 -333
  111. package/src/tree/plugins/TreeTooltip.ts +66 -66
  112. package/src/utils/commonUtils.ts +21 -21
  113. package/src/utils/d3Graphics.ts +174 -174
  114. package/src/utils/d3Utils.ts +74 -74
  115. package/src/utils/observables.ts +14 -14
  116. package/src/utils/orbchartsUtils.ts +115 -115
  117. package/tsconfig.base.json +13 -13
  118. package/tsconfig.json +2 -2
  119. package/vite.config.js +22 -22
  120. package/dist/orbcharts-plugins-basic/src/grid/plugins/BarStack.d.ts +0 -1
  121. package/dist/orbcharts-plugins-basic/src/grid/plugins/ValueStackAxis.d.ts +0 -1
  122. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/MultiBarStack.d.ts +0 -1
  123. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/MultiValueStackAxis.d.ts +0 -1
  124. package/dist/orbcharts-plugins-basic/src/multiGrid/plugins/OverlappingValueStackAxes.d.ts +0 -1
  125. /package/dist/orbcharts-plugins-basic/src/relationship/plugins/{Relationship.d.ts → ForceDirectedBubbles.d.ts} +0 -0
  126. /package/src/relationship/plugins/{Relationship.ts → ForceDirectedBubbles.ts} +0 -0
@@ -1,300 +1,300 @@
1
- import * as d3 from 'd3'
2
- import {
3
- Observable,
4
- combineLatest,
5
- switchMap,
6
- distinctUntilChanged,
7
- first,
8
- map,
9
- takeUntil,
10
- debounceTime,
11
- Subject } from 'rxjs'
12
- import type { DefinePluginConfig } from '../../../lib/core-types'
13
- import type { DataFormatterMultiValue } from '../../../lib/core-types'
14
- import {
15
- defineMultiValuePlugin, createValueToAxisScale } from '../../../lib/core'
16
- import { DEFAULT_X_Y_ZOOM_PARAMS } from '../defaults'
17
- import { getClassName, getUniID } from '../../utils/orbchartsUtils'
18
- import { LAYER_INDEX_OF_ROOT } from '../../const'
19
-
20
- const pluginName = 'XYZoom'
21
- const rectClassName = getClassName(pluginName, 'rect')
22
-
23
- const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_X_Y_ZOOM_PARAMS> = {
24
- name: pluginName,
25
- defaultParams: DEFAULT_X_Y_ZOOM_PARAMS,
26
- layerIndex: LAYER_INDEX_OF_ROOT,
27
- validator: (params, { validateColumns }) => {
28
- return {
29
- status: 'success',
30
- columnName: '',
31
- expectToBe: ''
32
- }
33
- }
34
- }
35
-
36
- export const XYZoom = defineMultiValuePlugin(pluginConfig)(({ selection, rootSelection, name, observer, subject }) => {
37
-
38
- const destroy$ = new Subject()
39
-
40
- // const rootRectSelection: d3.Selection<SVGRectElement, any, any, any> = rootSelection
41
- // .append('rect')
42
- // .classed(rectClassName, true)
43
- // .attr('opacity', 0)
44
-
45
- // 紀錄zoom最後一次的transform
46
- let lastTransform = {
47
- k: 1,
48
- x: 0,
49
- y: 0
50
- }
51
- // let lastDomain: [number, number] = [0, 0]
52
-
53
- // observer.layout$.pipe(
54
- // takeUntil(destroy$),
55
- // ).subscribe(d => {
56
- // rootRectSelection
57
- // .attr('width', d.width)
58
- // .attr('height', d.height)
59
- // .attr('x', d.left)
60
- // .attr('y', d.top)
61
- // })
62
-
63
- // const groupMax$ = observer.computedData$.pipe(
64
- // map(d => d[0] ? d[0].length - 1 : 0),
65
- // distinctUntilChanged()
66
- // )
67
-
68
- // const fullDataFormatterEvent$: Subject<DataFormatterMultiValue> = new Subject()
69
- // fullDataFormatterEvent$
70
- // .pipe(
71
- // takeUntil(destroy$),
72
- // debounceTime(50)
73
- // )
74
- // .subscribe(fullDataFormatter => {
75
- // store.fullDataFormatter$.next(fullDataFormatter)
76
- // })
77
-
78
- const initXAxis$ = observer.fullDataFormatter$.pipe(
79
- map(d => d.xAxis),
80
- // 只用第一次資料來計算scale才不會造成每次變動都受到影響
81
- first()
82
- )
83
-
84
- const initYAxis$ = observer.fullDataFormatter$.pipe(
85
- map(d => d.yAxis),
86
- // 只用第一次資料來計算scale才不會造成每次變動都受到影響
87
- first()
88
- )
89
-
90
-
91
- // const groupScale$ = combineLatest({
92
- // initXAxis: initXAxis$,
93
- // fullDataFormatter: observer.fullDataFormatter$,
94
- // groupMax: groupMax$,
95
- // layout: observer.layout$,
96
- // // axisSize: observer.gridAxesSize$
97
- // }).pipe(
98
- // takeUntil(destroy$),
99
- // switchMap(async (d) => d),
100
- // map(data => {
101
- // // const groupMin = 0
102
- // const groupScaleDomainMin = data.initXAxis.scaleDomain[0] - data.initXAxis.scalePadding
103
- // const groupScaleDomainMax = data.initXAxis.scaleDomain[1] === 'max'
104
- // ? data.groupMax + data.initXAxis.scalePadding
105
- // : data.initXAxis.scaleDomain[1] as number + data.initXAxis.scalePadding
106
-
107
- // const groupScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
108
- // maxValue: data.groupMax,
109
- // minValue: 0,
110
- // axisWidth: data.layout.width,
111
- // scaleDomain: [groupScaleDomainMin, groupScaleDomainMax],
112
- // scaleRange: [0, 1]
113
- // })
114
-
115
- // return groupScale
116
- // })
117
- // )
118
- const initXScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
119
- combineLatest({
120
- initXAxis: initXAxis$,
121
- layout: observer.layout$,
122
- minMaxXY: observer.minMaxXY$
123
- }).pipe(
124
- takeUntil(destroy$),
125
- switchMap(async (d) => d),
126
- ).subscribe(data => {
127
-
128
- const xScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
129
- maxValue: data.minMaxXY.maxX,
130
- minValue: data.minMaxXY.minX,
131
- axisWidth: data.layout.width,
132
- scaleDomain: data.initXAxis.scaleDomain,
133
- scaleRange: data.initXAxis.scaleRange,
134
- })
135
-
136
- subscriber.next(xScale)
137
- })
138
- })
139
-
140
- const initYScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
141
- combineLatest({
142
- initYAxis: initYAxis$,
143
- layout: observer.layout$,
144
- minMaxXY: observer.minMaxXY$
145
- }).pipe(
146
- takeUntil(destroy$),
147
- switchMap(async (d) => d),
148
- ).subscribe(data => {
149
-
150
- const yScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
151
- maxValue: data.minMaxXY.maxY,
152
- minValue: data.minMaxXY.minY,
153
- axisWidth: data.layout.height,
154
- scaleDomain: data.initYAxis.scaleDomain,
155
- scaleRange: data.initYAxis.scaleRange,
156
- reverse: true
157
- })
158
-
159
- subscriber.next(yScale)
160
- })
161
- })
162
-
163
- const minMaxScaleDomain$ = combineLatest({
164
- initXAxis: initXAxis$,
165
- initYAxis: initYAxis$,
166
- minMaxXY: observer.minMaxXY$
167
- }).pipe(
168
- takeUntil(destroy$),
169
- switchMap(async (d) => d),
170
- map(data => {
171
- let minX = data.minMaxXY.minX
172
- let maxX = data.minMaxXY.maxX
173
- let minY = data.minMaxXY.minY
174
- let maxY = data.minMaxXY.maxY
175
-
176
- // 原始設定為auto時要額外判斷
177
- if (data.initXAxis.scaleDomain[0] === 'auto' && minX > 0) {
178
- minX = 0
179
- }
180
- if (data.initXAxis.scaleDomain[1] === 'auto' && maxX < 0) {
181
- maxX = 0
182
- }
183
- if (data.initYAxis.scaleDomain[0] === 'auto' && minY > 0) {
184
- minY = 0
185
- }
186
- if (data.initYAxis.scaleDomain[1] === 'auto' && maxY < 0) {
187
- maxY = 0
188
- }
189
-
190
- return {
191
- minX,
192
- maxX,
193
- minY,
194
- maxY
195
- }
196
- }),
197
- )
198
-
199
- combineLatest({
200
- initXScale: initXScale$,
201
- // initXAxis: initXAxis$,
202
- // fullDataFormatter: fullDataFormatter$.pipe(first()), // 只用第一次資料來計算scale才不會造成每次變動都受到影響
203
- fullDataFormatter: observer.fullDataFormatter$,
204
- // groupMax: groupMax$,
205
- // minMaxXY: observer.minMaxXY$,
206
- minMaxScaleDomain: minMaxScaleDomain$,
207
- // layout: observer.layout$,
208
- // axisSize: observer.gridAxesSize$
209
- }).pipe(
210
- takeUntil(destroy$),
211
- switchMap(async (d) => d),
212
- ).subscribe(data => {
213
- // const groupMin = 0
214
-
215
- const shadowScale = data.initXScale.copy()
216
-
217
- const zoom = d3.zoom()
218
- // .scaleExtent([1, data.groupMaxIndex])
219
- // .translateExtent([[0, 0], [data.layout.rootWidth, data.layout.rootWidth]])
220
- .on("zoom", function zoomed(event) {
221
- // debugger
222
- // console.log('event', event)
223
- const t = event.transform;
224
-
225
- // if (event.sourceEvent.type === 'mousemove') {
226
- // // 當進行平移時,反向計算 x 軸
227
- // const dx = event.transform.x - currentTransform.x; // 本次平移增量
228
- // const reversedX = currentTransform.x - dx; // 反向累積平移
229
- // // 更新變換狀態
230
- // currentTransform = d3.zoomIdentity
231
- // .translate(reversedX, event.transform.y)
232
- // .scale(event.transform.k);
233
- // } else {
234
- // // 縮放操作:只更新縮放比例
235
- // currentTransform = d3.zoomIdentity
236
- // .translate(currentTransform.x, currentTransform.y)
237
- // .scale(event.transform.k);
238
- // }
239
- // console.log('currentTransform', currentTransform)
240
-
241
- // console.log('t.x', t.x)
242
- const mapGroupindex = (d: number) => {
243
- const n = Math.round(d)
244
- return Math.min(data.minMaxScaleDomain.maxX, Math.max(data.minMaxScaleDomain.minX, n));
245
- }
246
-
247
- const zoomedDomain = t.rescaleX(shadowScale)
248
- .domain()
249
- .map(mapGroupindex)
250
-
251
-
252
- // domain超過極限值
253
- if (zoomedDomain[0] <= data.minMaxScaleDomain.minX && zoomedDomain[1] >= data.minMaxScaleDomain.maxX) {
254
- // 繼續縮小
255
- if (t.k < lastTransform.k) {
256
- // 維持前一次的transform
257
- t.k = lastTransform.k
258
- t.x = lastTransform.x
259
- t.y = lastTransform.y
260
- }
261
- // domain間距小於1
262
- } else if ((zoomedDomain[1] - zoomedDomain[0]) <= 1) {
263
- // 繼續放大
264
- if (t.k > lastTransform.k) {
265
- // 維持前一次的transform
266
- t.k = lastTransform.k
267
- t.x = lastTransform.x
268
- t.y = lastTransform.y
269
- }
270
- }
271
-
272
- // 紀錄transform
273
- lastTransform.k = t.k
274
- lastTransform.x = t.x
275
- lastTransform.y = t.y
276
-
277
- // console.log(zoomedDomain)
278
- const newDataFormatter: DataFormatterMultiValue = {
279
- ...data.fullDataFormatter,
280
- xAxis: {
281
- ...data.fullDataFormatter.xAxis,
282
- scaleDomain: zoomedDomain
283
- }
284
- }
285
- subject.dataFormatter$.next(newDataFormatter)
286
- })
287
-
288
- // 傳入外層selection
289
- // subject.selection.call(zoom as any)
290
- rootSelection.call(zoom)
291
-
292
- })
293
-
294
- return () => {
295
- destroy$.next(undefined)
296
- // rootRectSelection.remove()
297
-
298
- rootSelection.call(d3.zoom().on('zoom', null))
299
- }
1
+ import * as d3 from 'd3'
2
+ import {
3
+ Observable,
4
+ combineLatest,
5
+ switchMap,
6
+ distinctUntilChanged,
7
+ first,
8
+ map,
9
+ takeUntil,
10
+ debounceTime,
11
+ Subject } from 'rxjs'
12
+ import type { DefinePluginConfig } from '../../../lib/core-types'
13
+ import type { DataFormatterMultiValue } from '../../../lib/core-types'
14
+ import {
15
+ defineMultiValuePlugin, createValueToAxisScale } from '../../../lib/core'
16
+ import { DEFAULT_X_Y_ZOOM_PARAMS } from '../defaults'
17
+ import { getClassName, getUniID } from '../../utils/orbchartsUtils'
18
+ import { LAYER_INDEX_OF_ROOT } from '../../const'
19
+
20
+ const pluginName = 'XYZoom'
21
+ const rectClassName = getClassName(pluginName, 'rect')
22
+
23
+ const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_X_Y_ZOOM_PARAMS> = {
24
+ name: pluginName,
25
+ defaultParams: DEFAULT_X_Y_ZOOM_PARAMS,
26
+ layerIndex: LAYER_INDEX_OF_ROOT,
27
+ validator: (params, { validateColumns }) => {
28
+ return {
29
+ status: 'success',
30
+ columnName: '',
31
+ expectToBe: ''
32
+ }
33
+ }
34
+ }
35
+
36
+ export const XYZoom = defineMultiValuePlugin(pluginConfig)(({ selection, rootSelection, name, observer, subject }) => {
37
+
38
+ const destroy$ = new Subject()
39
+
40
+ // const rootRectSelection: d3.Selection<SVGRectElement, any, any, any> = rootSelection
41
+ // .append('rect')
42
+ // .classed(rectClassName, true)
43
+ // .attr('opacity', 0)
44
+
45
+ // 紀錄zoom最後一次的transform
46
+ let lastTransform = {
47
+ k: 1,
48
+ x: 0,
49
+ y: 0
50
+ }
51
+ // let lastDomain: [number, number] = [0, 0]
52
+
53
+ // observer.layout$.pipe(
54
+ // takeUntil(destroy$),
55
+ // ).subscribe(d => {
56
+ // rootRectSelection
57
+ // .attr('width', d.width)
58
+ // .attr('height', d.height)
59
+ // .attr('x', d.left)
60
+ // .attr('y', d.top)
61
+ // })
62
+
63
+ // const groupMax$ = observer.computedData$.pipe(
64
+ // map(d => d[0] ? d[0].length - 1 : 0),
65
+ // distinctUntilChanged()
66
+ // )
67
+
68
+ // const fullDataFormatterEvent$: Subject<DataFormatterMultiValue> = new Subject()
69
+ // fullDataFormatterEvent$
70
+ // .pipe(
71
+ // takeUntil(destroy$),
72
+ // debounceTime(50)
73
+ // )
74
+ // .subscribe(fullDataFormatter => {
75
+ // store.fullDataFormatter$.next(fullDataFormatter)
76
+ // })
77
+
78
+ const initXAxis$ = observer.fullDataFormatter$.pipe(
79
+ map(d => d.xAxis),
80
+ // 只用第一次資料來計算scale才不會造成每次變動都受到影響
81
+ first()
82
+ )
83
+
84
+ const initYAxis$ = observer.fullDataFormatter$.pipe(
85
+ map(d => d.yAxis),
86
+ // 只用第一次資料來計算scale才不會造成每次變動都受到影響
87
+ first()
88
+ )
89
+
90
+
91
+ // const groupScale$ = combineLatest({
92
+ // initXAxis: initXAxis$,
93
+ // fullDataFormatter: observer.fullDataFormatter$,
94
+ // groupMax: groupMax$,
95
+ // layout: observer.layout$,
96
+ // // axisSize: observer.gridAxesSize$
97
+ // }).pipe(
98
+ // takeUntil(destroy$),
99
+ // switchMap(async (d) => d),
100
+ // map(data => {
101
+ // // const groupMin = 0
102
+ // const groupScaleDomainMin = data.initXAxis.scaleDomain[0] - data.initXAxis.scalePadding
103
+ // const groupScaleDomainMax = data.initXAxis.scaleDomain[1] === 'max'
104
+ // ? data.groupMax + data.initXAxis.scalePadding
105
+ // : data.initXAxis.scaleDomain[1] as number + data.initXAxis.scalePadding
106
+
107
+ // const groupScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
108
+ // maxValue: data.groupMax,
109
+ // minValue: 0,
110
+ // axisWidth: data.layout.width,
111
+ // scaleDomain: [groupScaleDomainMin, groupScaleDomainMax],
112
+ // scaleRange: [0, 1]
113
+ // })
114
+
115
+ // return groupScale
116
+ // })
117
+ // )
118
+ const initXScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
119
+ combineLatest({
120
+ initXAxis: initXAxis$,
121
+ layout: observer.layout$,
122
+ minMaxXY: observer.minMaxXY$
123
+ }).pipe(
124
+ takeUntil(destroy$),
125
+ switchMap(async (d) => d),
126
+ ).subscribe(data => {
127
+
128
+ const xScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
129
+ maxValue: data.minMaxXY.maxX,
130
+ minValue: data.minMaxXY.minX,
131
+ axisWidth: data.layout.width,
132
+ scaleDomain: data.initXAxis.scaleDomain,
133
+ scaleRange: data.initXAxis.scaleRange,
134
+ })
135
+
136
+ subscriber.next(xScale)
137
+ })
138
+ })
139
+
140
+ const initYScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
141
+ combineLatest({
142
+ initYAxis: initYAxis$,
143
+ layout: observer.layout$,
144
+ minMaxXY: observer.minMaxXY$
145
+ }).pipe(
146
+ takeUntil(destroy$),
147
+ switchMap(async (d) => d),
148
+ ).subscribe(data => {
149
+
150
+ const yScale: d3.ScaleLinear<number, number> = createValueToAxisScale({
151
+ maxValue: data.minMaxXY.maxY,
152
+ minValue: data.minMaxXY.minY,
153
+ axisWidth: data.layout.height,
154
+ scaleDomain: data.initYAxis.scaleDomain,
155
+ scaleRange: data.initYAxis.scaleRange,
156
+ reverse: true
157
+ })
158
+
159
+ subscriber.next(yScale)
160
+ })
161
+ })
162
+
163
+ const minMaxScaleDomain$ = combineLatest({
164
+ initXAxis: initXAxis$,
165
+ initYAxis: initYAxis$,
166
+ minMaxXY: observer.minMaxXY$
167
+ }).pipe(
168
+ takeUntil(destroy$),
169
+ switchMap(async (d) => d),
170
+ map(data => {
171
+ let minX = data.minMaxXY.minX
172
+ let maxX = data.minMaxXY.maxX
173
+ let minY = data.minMaxXY.minY
174
+ let maxY = data.minMaxXY.maxY
175
+
176
+ // 原始設定為auto時要額外判斷
177
+ if (data.initXAxis.scaleDomain[0] === 'auto' && minX > 0) {
178
+ minX = 0
179
+ }
180
+ if (data.initXAxis.scaleDomain[1] === 'auto' && maxX < 0) {
181
+ maxX = 0
182
+ }
183
+ if (data.initYAxis.scaleDomain[0] === 'auto' && minY > 0) {
184
+ minY = 0
185
+ }
186
+ if (data.initYAxis.scaleDomain[1] === 'auto' && maxY < 0) {
187
+ maxY = 0
188
+ }
189
+
190
+ return {
191
+ minX,
192
+ maxX,
193
+ minY,
194
+ maxY
195
+ }
196
+ }),
197
+ )
198
+
199
+ combineLatest({
200
+ initXScale: initXScale$,
201
+ // initXAxis: initXAxis$,
202
+ // fullDataFormatter: fullDataFormatter$.pipe(first()), // 只用第一次資料來計算scale才不會造成每次變動都受到影響
203
+ fullDataFormatter: observer.fullDataFormatter$,
204
+ // groupMax: groupMax$,
205
+ // minMaxXY: observer.minMaxXY$,
206
+ minMaxScaleDomain: minMaxScaleDomain$,
207
+ // layout: observer.layout$,
208
+ // axisSize: observer.gridAxesSize$
209
+ }).pipe(
210
+ takeUntil(destroy$),
211
+ switchMap(async (d) => d),
212
+ ).subscribe(data => {
213
+ // const groupMin = 0
214
+
215
+ const shadowScale = data.initXScale.copy()
216
+
217
+ const zoom = d3.zoom()
218
+ // .scaleExtent([1, data.groupMaxIndex])
219
+ // .translateExtent([[0, 0], [data.layout.rootWidth, data.layout.rootWidth]])
220
+ .on("zoom", function zoomed(event) {
221
+ // debugger
222
+ // console.log('event', event)
223
+ const t = event.transform;
224
+
225
+ // if (event.sourceEvent.type === 'mousemove') {
226
+ // // 當進行平移時,反向計算 x 軸
227
+ // const dx = event.transform.x - currentTransform.x; // 本次平移增量
228
+ // const reversedX = currentTransform.x - dx; // 反向累積平移
229
+ // // 更新變換狀態
230
+ // currentTransform = d3.zoomIdentity
231
+ // .translate(reversedX, event.transform.y)
232
+ // .scale(event.transform.k);
233
+ // } else {
234
+ // // 縮放操作:只更新縮放比例
235
+ // currentTransform = d3.zoomIdentity
236
+ // .translate(currentTransform.x, currentTransform.y)
237
+ // .scale(event.transform.k);
238
+ // }
239
+ // console.log('currentTransform', currentTransform)
240
+
241
+ // console.log('t.x', t.x)
242
+ const mapGroupindex = (d: number) => {
243
+ const n = Math.round(d)
244
+ return Math.min(data.minMaxScaleDomain.maxX, Math.max(data.minMaxScaleDomain.minX, n));
245
+ }
246
+
247
+ const zoomedDomain = t.rescaleX(shadowScale)
248
+ .domain()
249
+ .map(mapGroupindex)
250
+
251
+
252
+ // domain超過極限值
253
+ if (zoomedDomain[0] <= data.minMaxScaleDomain.minX && zoomedDomain[1] >= data.minMaxScaleDomain.maxX) {
254
+ // 繼續縮小
255
+ if (t.k < lastTransform.k) {
256
+ // 維持前一次的transform
257
+ t.k = lastTransform.k
258
+ t.x = lastTransform.x
259
+ t.y = lastTransform.y
260
+ }
261
+ // domain間距小於1
262
+ } else if ((zoomedDomain[1] - zoomedDomain[0]) <= 1) {
263
+ // 繼續放大
264
+ if (t.k > lastTransform.k) {
265
+ // 維持前一次的transform
266
+ t.k = lastTransform.k
267
+ t.x = lastTransform.x
268
+ t.y = lastTransform.y
269
+ }
270
+ }
271
+
272
+ // 紀錄transform
273
+ lastTransform.k = t.k
274
+ lastTransform.x = t.x
275
+ lastTransform.y = t.y
276
+
277
+ // console.log(zoomedDomain)
278
+ const newDataFormatter: DataFormatterMultiValue = {
279
+ ...data.fullDataFormatter,
280
+ xAxis: {
281
+ ...data.fullDataFormatter.xAxis,
282
+ scaleDomain: zoomedDomain
283
+ }
284
+ }
285
+ subject.dataFormatter$.next(newDataFormatter)
286
+ })
287
+
288
+ // 傳入外層selection
289
+ // subject.selection.call(zoom as any)
290
+ rootSelection.call(zoom)
291
+
292
+ })
293
+
294
+ return () => {
295
+ destroy$.next(undefined)
296
+ // rootRectSelection.remove()
297
+
298
+ rootSelection.call(d3.zoom().on('zoom', null))
299
+ }
300
300
  })