@orbcharts/plugins-basic 3.0.0-beta.10 → 3.0.0-beta.11

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 (99) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-plugins-basic.es.js +177 -177
  3. package/dist/orbcharts-plugins-basic.umd.js +55 -55
  4. package/lib/core-types.ts +7 -7
  5. package/lib/core.ts +6 -6
  6. package/lib/plugins-basic-types.ts +6 -6
  7. package/package.json +44 -44
  8. package/src/base/BaseBars.ts +765 -765
  9. package/src/base/BaseBarsTriangle.ts +676 -676
  10. package/src/base/BaseDots.ts +464 -464
  11. package/src/base/BaseGroupAxis.ts +679 -679
  12. package/src/base/BaseLegend.ts +684 -684
  13. package/src/base/BaseLineAreas.ts +629 -629
  14. package/src/base/BaseLines.ts +706 -706
  15. package/src/base/BaseStackedBar.ts +782 -782
  16. package/src/base/BaseTooltip.ts +385 -385
  17. package/src/base/BaseValueAxis.ts +583 -583
  18. package/src/base/types.ts +2 -2
  19. package/src/const.ts +30 -30
  20. package/src/grid/defaults.ts +246 -246
  21. package/src/grid/gridObservables.ts +554 -554
  22. package/src/grid/index.ts +16 -16
  23. package/src/grid/plugins/Bars.ts +69 -69
  24. package/src/grid/plugins/BarsPN.ts +66 -66
  25. package/src/grid/plugins/BarsTriangle.ts +73 -73
  26. package/src/grid/plugins/Dots.ts +68 -68
  27. package/src/grid/plugins/GridLegend.ts +107 -107
  28. package/src/grid/plugins/GridTooltip.ts +66 -66
  29. package/src/grid/plugins/GridZoom.ts +218 -218
  30. package/src/grid/plugins/GroupAux.ts +1103 -1103
  31. package/src/grid/plugins/GroupAxis.ts +97 -97
  32. package/src/grid/plugins/LineAreas.ts +65 -65
  33. package/src/grid/plugins/Lines.ts +59 -59
  34. package/src/grid/plugins/StackedBar.ts +64 -64
  35. package/src/grid/plugins/StackedValueAxis.ts +96 -96
  36. package/src/grid/plugins/ValueAxis.ts +94 -94
  37. package/src/index.ts +6 -6
  38. package/src/multiGrid/defaults.ts +224 -224
  39. package/src/multiGrid/index.ts +14 -14
  40. package/src/multiGrid/multiGridObservables.ts +49 -49
  41. package/src/multiGrid/plugins/MultiBars.ts +108 -108
  42. package/src/multiGrid/plugins/MultiBarsTriangle.ts +114 -114
  43. package/src/multiGrid/plugins/MultiDots.ts +102 -102
  44. package/src/multiGrid/plugins/MultiGridLegend.ts +159 -159
  45. package/src/multiGrid/plugins/MultiGridTooltip.ts +66 -66
  46. package/src/multiGrid/plugins/MultiGroupAxis.ts +137 -137
  47. package/src/multiGrid/plugins/MultiLineAreas.ts +107 -107
  48. package/src/multiGrid/plugins/MultiLines.ts +101 -101
  49. package/src/multiGrid/plugins/MultiStackedBar.ts +106 -106
  50. package/src/multiGrid/plugins/MultiStackedValueAxis.ts +134 -134
  51. package/src/multiGrid/plugins/MultiValueAxis.ts +134 -134
  52. package/src/multiGrid/plugins/OverlappingStackedValueAxes.ts +299 -299
  53. package/src/multiGrid/plugins/OverlappingValueAxes.ts +300 -300
  54. package/src/multiValue/defaults.ts +166 -166
  55. package/src/multiValue/index.ts +8 -8
  56. package/src/multiValue/multiValueObservables.ts +297 -297
  57. package/src/multiValue/plugins/MultiValueLegend.ts +107 -107
  58. package/src/multiValue/plugins/MultiValueTooltip.ts +66 -66
  59. package/src/multiValue/plugins/Scatter.ts +426 -426
  60. package/src/multiValue/plugins/ScatterBubbles.ts +554 -554
  61. package/src/multiValue/plugins/XYAux.ts +681 -681
  62. package/src/multiValue/plugins/XYAxes.ts +684 -684
  63. package/src/multiValue/plugins/XYZoom.ts +299 -299
  64. package/src/noneData/defaults.ts +102 -102
  65. package/src/noneData/index.ts +3 -3
  66. package/src/noneData/plugins/Container.ts +27 -27
  67. package/src/noneData/plugins/Tooltip.ts +373 -373
  68. package/src/relationship/defaults.ts +196 -195
  69. package/src/relationship/index.ts +5 -5
  70. package/src/relationship/plugins/ForceDirected.ts +1168 -1166
  71. package/src/relationship/plugins/ForceDirectedBubbles.ts +1393 -1390
  72. package/src/relationship/plugins/RelationshipLegend.ts +100 -100
  73. package/src/relationship/plugins/RelationshipTooltip.ts +66 -66
  74. package/src/relationship/relationshipObservables.ts +49 -49
  75. package/src/series/defaults.ts +207 -206
  76. package/src/series/index.ts +9 -9
  77. package/src/series/plugins/Bubbles.ts +603 -606
  78. package/src/series/plugins/Pie.ts +623 -623
  79. package/src/series/plugins/PieEventTexts.ts +284 -284
  80. package/src/series/plugins/PieLabels.ts +640 -640
  81. package/src/series/plugins/Rose.ts +516 -516
  82. package/src/series/plugins/RoseLabels.ts +600 -600
  83. package/src/series/plugins/SeriesLegend.ts +107 -107
  84. package/src/series/plugins/SeriesTooltip.ts +66 -66
  85. package/src/series/seriesObservables.ts +145 -145
  86. package/src/series/seriesUtils.ts +51 -51
  87. package/src/tree/defaults.ts +78 -78
  88. package/src/tree/index.ts +4 -4
  89. package/src/tree/plugins/TreeLegend.ts +100 -100
  90. package/src/tree/plugins/TreeMap.ts +333 -333
  91. package/src/tree/plugins/TreeTooltip.ts +66 -66
  92. package/src/utils/commonUtils.ts +21 -21
  93. package/src/utils/d3Graphics.ts +174 -174
  94. package/src/utils/d3Utils.ts +74 -74
  95. package/src/utils/observables.ts +14 -14
  96. package/src/utils/orbchartsUtils.ts +115 -115
  97. package/tsconfig.base.json +13 -13
  98. package/tsconfig.json +2 -2
  99. package/vite.config.js +22 -22
@@ -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
  })