@orbcharts/plugins-basic 3.0.0-alpha.56 → 3.0.0-alpha.58
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/orbcharts-plugins-basic.es.js +7070 -7068
- package/dist/orbcharts-plugins-basic.umd.js +10 -10
- package/dist/src/base/BaseLineAreas.d.ts +1 -0
- package/dist/src/base/BaseLines.d.ts +3 -1
- package/dist/src/grid/gridObservables.d.ts +19 -2
- package/dist/src/grid/types.d.ts +1 -0
- package/dist/vite.config.d.mts +2 -0
- package/package.json +5 -4
- package/src/base/BaseGroupAxis.ts +1 -1
- package/src/base/BaseLineAreas.ts +4 -1
- package/src/base/BaseLines.ts +8 -3
- package/src/base/BaseValueAxis.ts +1 -1
- package/src/grid/defaults.ts +1 -0
- package/src/grid/gridObservables.ts +329 -35
- package/src/grid/plugins/GroupAux.ts +144 -90
- package/src/grid/plugins/LineAreas.ts +1 -0
- package/src/grid/plugins/Lines.ts +3 -1
- package/src/grid/types.ts +1 -0
- package/src/multiGrid/plugins/MultiLineAreas.ts +10 -0
- package/src/multiGrid/plugins/MultiLines.ts +12 -1
- package/{tsconfig.json → tsconfig.base.json} +1 -1
- package/tsconfig.json.bak.vite-plugin-tsconfig +8 -0
- package/tsconfig.prod.json +1 -12
- package/vite.config.mjs +41 -0
- package/dist/vite.config.d.ts +0 -2
- package/tsconfig.dev.json +0 -17
- package/vite.config.js +0 -50
@@ -26,6 +26,7 @@ interface BaseLineAreasContext {
|
|
26
26
|
}>;
|
27
27
|
gridHighlight$: Observable<ComputedDatumGrid[]>;
|
28
28
|
gridContainerPosition$: Observable<GridContainerPosition[]>;
|
29
|
+
allContainerPosition$: Observable<GridContainerPosition[]>;
|
29
30
|
layout$: Observable<Layout>;
|
30
31
|
event$: Subject<EventGrid>;
|
31
32
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Observable, Subject } from 'rxjs';
|
2
2
|
import { BasePluginFn } from './types';
|
3
|
-
import { ComputedDatumGrid, ComputedDataGrid, ComputedLayoutDataGrid, DataFormatterGrid, EventGrid, GridContainerPosition, ChartParams, TransformData } from '@orbcharts/core';
|
3
|
+
import { ComputedDatumGrid, ComputedDataGrid, ComputedLayoutDataGrid, DataFormatterGrid, EventGrid, GridContainerPosition, ChartParams, Layout, TransformData } from '@orbcharts/core';
|
4
4
|
import * as d3 from 'd3';
|
5
5
|
export interface BaseLinesParams {
|
6
6
|
lineCurve: string;
|
@@ -26,6 +26,8 @@ interface BaseLinesContext {
|
|
26
26
|
}>;
|
27
27
|
gridHighlight$: Observable<ComputedDatumGrid[]>;
|
28
28
|
gridContainerPosition$: Observable<GridContainerPosition[]>;
|
29
|
+
allContainerPosition$: Observable<GridContainerPosition[]>;
|
30
|
+
layout$: Observable<Layout>;
|
29
31
|
event$: Subject<EventGrid>;
|
30
32
|
}
|
31
33
|
export declare const createBaseLines: BasePluginFn<BaseLinesContext>;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Observable } from 'rxjs';
|
2
|
-
import { ChartParams, DataFormatterGrid, ComputedDataGrid, TransformData, GridContainerPosition } from '@orbcharts/core';
|
2
|
+
import { ChartParams, DataFormatterGrid, ComputedDataGrid, TransformData, GridContainerPosition, Layout } from '@orbcharts/core';
|
3
3
|
import * as d3 from 'd3';
|
4
4
|
export declare const gridSelectionsObservable: ({ selection, pluginName, clipPathID, seriesLabels$, gridContainerPosition$, gridAxesTransform$, gridGraphicTransform$ }: {
|
5
5
|
selection: d3.Selection<any, unknown, any, unknown>;
|
@@ -15,7 +15,7 @@ export declare const gridSelectionsObservable: ({ selection, pluginName, clipPat
|
|
15
15
|
defsSelection$: Observable<d3.Selection<SVGDefsElement, string, any, unknown>>;
|
16
16
|
graphicGSelection$: Observable<d3.Selection<SVGGElement, string, any, unknown>>;
|
17
17
|
};
|
18
|
-
export declare const gridGroupPositionFnObservable: ({ fullDataFormatter$, gridAxesSize$, computedData$, fullChartParams$ }: {
|
18
|
+
export declare const gridGroupPositionFnObservable: ({ fullDataFormatter$, gridAxesSize$, computedData$, fullChartParams$, gridContainerPosition$, layout$ }: {
|
19
19
|
fullDataFormatter$: Observable<DataFormatterGrid>;
|
20
20
|
gridAxesSize$: Observable<{
|
21
21
|
width: number;
|
@@ -23,7 +23,24 @@ export declare const gridGroupPositionFnObservable: ({ fullDataFormatter$, gridA
|
|
23
23
|
}>;
|
24
24
|
computedData$: Observable<ComputedDataGrid>;
|
25
25
|
fullChartParams$: Observable<ChartParams>;
|
26
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>;
|
27
|
+
layout$: Observable<Layout>;
|
26
28
|
}) => Observable<(event: any) => {
|
27
29
|
groupIndex: number;
|
28
30
|
groupLabel: string;
|
29
31
|
}>;
|
32
|
+
export declare const gridGroupPosition: ({ rootSelection, fullDataFormatter$, gridAxesSize$, computedData$, fullChartParams$, gridContainerPosition$, layout$ }: {
|
33
|
+
rootSelection: d3.Selection<any, unknown, any, unknown>;
|
34
|
+
fullDataFormatter$: Observable<DataFormatterGrid>;
|
35
|
+
gridAxesSize$: Observable<{
|
36
|
+
width: number;
|
37
|
+
height: number;
|
38
|
+
}>;
|
39
|
+
computedData$: Observable<ComputedDataGrid>;
|
40
|
+
fullChartParams$: Observable<ChartParams>;
|
41
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>;
|
42
|
+
layout$: Observable<Layout>;
|
43
|
+
}) => Observable<{
|
44
|
+
groupIndex: number;
|
45
|
+
groupLabel: string;
|
46
|
+
}>;
|
package/dist/src/grid/types.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orbcharts/plugins-basic",
|
3
|
-
"version": "3.0.0-alpha.
|
3
|
+
"version": "3.0.0-alpha.58",
|
4
4
|
"description": "plugins for OrbCharts",
|
5
5
|
"author": "Blue Planet Inc.",
|
6
6
|
"license": "Apache-2.0",
|
@@ -25,17 +25,18 @@
|
|
25
25
|
"types": "./dist/src/index.d.ts",
|
26
26
|
"scripts": {
|
27
27
|
"test": "echo \"Error: no test specified\" && exit 1",
|
28
|
-
"build": "vite build --mode
|
28
|
+
"build": "vite build --mode production"
|
29
29
|
},
|
30
30
|
"devDependencies": {
|
31
31
|
"@types/d3": "^7.4.0",
|
32
32
|
"ts-loader": "^9.4.2",
|
33
33
|
"typescript": "^5.0.4",
|
34
34
|
"vite": "^5.3.5",
|
35
|
-
"vite-plugin-dts": "^3.7.3"
|
35
|
+
"vite-plugin-dts": "^3.7.3",
|
36
|
+
"vite-plugin-tsconfig": "^1.0.5"
|
36
37
|
},
|
37
38
|
"dependencies": {
|
38
|
-
"@orbcharts/core": "^3.0.0-alpha.
|
39
|
+
"@orbcharts/core": "^3.0.0-alpha.54",
|
39
40
|
"d3": "^7.8.5",
|
40
41
|
"rxjs": "^7.8.1"
|
41
42
|
}
|
@@ -115,7 +115,7 @@ function renderAxis ({ selection, xAxisClassName, groupingLabelClassName, params
|
|
115
115
|
.attr('dominant-baseline', axisLabelAlign.dominantBaseline)
|
116
116
|
.attr('font-size', chartParams.styles.textSize)
|
117
117
|
.style('fill', getColor(params.labelColorType, chartParams))
|
118
|
-
.style('transform', textTransform)
|
118
|
+
// .style('transform', textTransform)
|
119
119
|
.text(d => fullDataFormatter.grid.groupAxis.label)
|
120
120
|
})
|
121
121
|
.attr('transform', d => `translate(${gridAxesSize.width + d.tickPadding + params.labelOffset[0]}, ${- d.tickPadding - defaultTickSize - params.labelOffset[1]})`)
|
@@ -52,6 +52,7 @@ interface BaseLineAreasContext {
|
|
52
52
|
}>
|
53
53
|
gridHighlight$: Observable<ComputedDatumGrid[]>
|
54
54
|
gridContainerPosition$: Observable<GridContainerPosition[]>
|
55
|
+
allContainerPosition$: Observable<GridContainerPosition[]>
|
55
56
|
layout$: Observable<Layout>
|
56
57
|
event$: Subject<EventGrid>
|
57
58
|
}
|
@@ -408,7 +409,9 @@ export const createBaseLineAreas: BasePluginFn<BaseLineAreasContext> = (pluginNa
|
|
408
409
|
fullDataFormatter$,
|
409
410
|
gridAxesSize$: gridAxesSize$,
|
410
411
|
computedData$: computedData$,
|
411
|
-
fullChartParams$: fullChartParams
|
412
|
+
fullChartParams$: fullChartParams$,
|
413
|
+
gridContainerPosition$: gridContainerPosition$,
|
414
|
+
layout$: layout$
|
412
415
|
})
|
413
416
|
|
414
417
|
const highlightTarget$ = fullChartParams$.pipe(
|
package/src/base/BaseLines.ts
CHANGED
@@ -57,6 +57,8 @@ interface BaseLinesContext {
|
|
57
57
|
}>
|
58
58
|
gridHighlight$: Observable<ComputedDatumGrid[]>
|
59
59
|
gridContainerPosition$: Observable<GridContainerPosition[]>
|
60
|
+
allContainerPosition$: Observable<GridContainerPosition[]>
|
61
|
+
layout$: Observable<Layout>
|
60
62
|
event$: Subject<EventGrid>
|
61
63
|
}
|
62
64
|
|
@@ -240,6 +242,8 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
240
242
|
gridAxesSize$,
|
241
243
|
gridHighlight$,
|
242
244
|
gridContainerPosition$,
|
245
|
+
allContainerPosition$,
|
246
|
+
layout$,
|
243
247
|
event$
|
244
248
|
}) => {
|
245
249
|
|
@@ -496,7 +500,9 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
496
500
|
fullDataFormatter$,
|
497
501
|
gridAxesSize$: gridAxesSize$,
|
498
502
|
computedData$: computedData$,
|
499
|
-
fullChartParams$: fullChartParams
|
503
|
+
fullChartParams$: fullChartParams$,
|
504
|
+
gridContainerPosition$: allContainerPosition$,
|
505
|
+
layout$: layout$
|
500
506
|
})
|
501
507
|
|
502
508
|
const highlightTarget$ = fullChartParams$.pipe(
|
@@ -541,8 +547,6 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
541
547
|
|
542
548
|
return pathSelectionArr
|
543
549
|
})
|
544
|
-
|
545
|
-
|
546
550
|
)
|
547
551
|
|
548
552
|
combineLatest({
|
@@ -563,6 +567,7 @@ export const createBaseLines: BasePluginFn<BaseLinesContext> = (pluginName: stri
|
|
563
567
|
|
564
568
|
const seriesLabel = datum[0] ? datum[0].seriesLabel : ''
|
565
569
|
const { groupIndex, groupLabel } = data.gridGroupPositionFn(event)
|
570
|
+
// console.log('groupIndex', groupIndex)
|
566
571
|
const groupData = data.GroupDataMap.get(groupLabel)!
|
567
572
|
const targetDatum = groupData.find(d => d.seriesLabel === seriesLabel)
|
568
573
|
const _datum = targetDatum ?? datum[0]
|
@@ -109,7 +109,7 @@ function renderAxis ({ selection, yAxisClassName, textClassName, fullParams, tic
|
|
109
109
|
.attr('dominant-baseline', axisLabelAlign.dominantBaseline)
|
110
110
|
.attr('font-size', fullChartParams.styles.textSize)
|
111
111
|
.style('fill', getColor(fullParams.labelColorType, fullChartParams))
|
112
|
-
.style('transform', textTransform)
|
112
|
+
// .style('transform', textTransform)
|
113
113
|
.text(d => fullDataFormatter.grid.valueAxis.label)
|
114
114
|
})
|
115
115
|
.attr('transform', d => `translate(${- d.tickPadding + fullParams.labelOffset[0]}, ${gridAxesSize.height + d.tickPadding + fullParams.labelOffset[1]})`)
|
package/src/grid/defaults.ts
CHANGED
@@ -23,6 +23,7 @@ import type {
|
|
23
23
|
Layout } from '@orbcharts/core'
|
24
24
|
import { createAxisQuantizeScale } from '@orbcharts/core'
|
25
25
|
import { getClassName, getUniID } from '../utils/orbchartsUtils'
|
26
|
+
import { d3EventObservable } from '../utils/observables'
|
26
27
|
|
27
28
|
// grid選取器
|
28
29
|
export const gridSelectionsObservable = ({ selection, pluginName, clipPathID, seriesLabels$, gridContainerPosition$, gridAxesTransform$, gridGraphicTransform$ }: {
|
@@ -144,7 +145,8 @@ export const gridSelectionsObservable = ({ selection, pluginName, clipPathID, se
|
|
144
145
|
}
|
145
146
|
|
146
147
|
// 由事件取得group data的function
|
147
|
-
|
148
|
+
// @Q@ 之後重構改用 gridGroupPosition
|
149
|
+
export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize$, computedData$, fullChartParams$, gridContainerPosition$, layout$ }: {
|
148
150
|
fullDataFormatter$: Observable<DataFormatterGrid>
|
149
151
|
gridAxesSize$: Observable<{
|
150
152
|
width: number;
|
@@ -153,56 +155,128 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
153
155
|
computedData$: Observable<ComputedDataGrid>
|
154
156
|
// GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
155
157
|
fullChartParams$: Observable<ChartParams>
|
158
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
159
|
+
layout$: Observable<Layout>
|
156
160
|
}): Observable<(event: any) => { groupIndex: number; groupLabel: string }> => {
|
157
161
|
const destroy$ = new Subject()
|
158
162
|
|
159
163
|
// 顯示範圍內的group labels
|
160
|
-
const scaleRangeGroupLabels$: Observable<string[]> = new Observable(subscriber => {
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
// const scaleRangeGroupLabels$: Observable<string[]> = new Observable(subscriber => {
|
165
|
+
// combineLatest({
|
166
|
+
// dataFormatter: fullDataFormatter$,
|
167
|
+
// computedData: computedData$
|
168
|
+
// }).pipe(
|
169
|
+
// takeUntil(destroy$),
|
170
|
+
// switchMap(async (d) => d),
|
171
|
+
// ).subscribe(data => {
|
172
|
+
// const groupMin = 0
|
173
|
+
// const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
174
|
+
// const groupScaleDomainMin = data.dataFormatter.grid.groupAxis.scaleDomain[0] === 'auto'
|
175
|
+
// ? groupMin - data.dataFormatter.grid.groupAxis.scalePadding
|
176
|
+
// : data.dataFormatter.grid.groupAxis.scaleDomain[0] as number - data.dataFormatter.grid.groupAxis.scalePadding
|
177
|
+
// const groupScaleDomainMax = data.dataFormatter.grid.groupAxis.scaleDomain[1] === 'auto'
|
178
|
+
// ? groupMax + data.dataFormatter.grid.groupAxis.scalePadding
|
179
|
+
// : data.dataFormatter.grid.groupAxis.scaleDomain[1] as number + data.dataFormatter.grid.groupAxis.scalePadding
|
180
|
+
|
181
|
+
// // const groupingAmount = data.computedData[0]
|
182
|
+
// // ? data.computedData[0].length
|
183
|
+
// // : 0
|
184
|
+
|
185
|
+
// let _labels = data.dataFormatter.grid.seriesDirection === 'row'
|
186
|
+
// ? (data.computedData[0] ?? []).map(d => d.groupLabel)
|
187
|
+
// : data.computedData.map(d => d[0].groupLabel)
|
188
|
+
|
189
|
+
// const _axisLabels =
|
190
|
+
// // new Array(groupingAmount).fill(0)
|
191
|
+
// // .map((d, i) => {
|
192
|
+
// // return _labels[i] != null
|
193
|
+
// // ? _labels[i]
|
194
|
+
// // : String(i) // 沒有label則用序列號填充
|
195
|
+
// // })
|
196
|
+
// _labels
|
197
|
+
// .filter((d, i) => {
|
198
|
+
// return i >= groupScaleDomainMin && i <= groupScaleDomainMax
|
199
|
+
// })
|
200
|
+
// subscriber.next(_axisLabels)
|
201
|
+
// })
|
202
|
+
// })
|
203
|
+
const groupScaleDomain$ = combineLatest({
|
204
|
+
fullDataFormatter: fullDataFormatter$,
|
205
|
+
gridAxesSize: gridAxesSize$,
|
206
|
+
computedData: computedData$
|
207
|
+
}).pipe(
|
208
|
+
switchMap(async (d) => d),
|
209
|
+
map(data => {
|
168
210
|
const groupMin = 0
|
169
211
|
const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
170
|
-
const groupScaleDomainMin = data.
|
171
|
-
? groupMin - data.
|
172
|
-
: data.
|
173
|
-
const groupScaleDomainMax = data.
|
174
|
-
? groupMax + data.
|
175
|
-
: data.
|
176
|
-
|
177
|
-
// const groupingAmount = data.computedData[0]
|
178
|
-
// ? data.computedData[0].length
|
179
|
-
// : 0
|
212
|
+
const groupScaleDomainMin = data.fullDataFormatter.grid.groupAxis.scaleDomain[0] === 'auto'
|
213
|
+
? groupMin - data.fullDataFormatter.grid.groupAxis.scalePadding
|
214
|
+
: data.fullDataFormatter.grid.groupAxis.scaleDomain[0] as number - data.fullDataFormatter.grid.groupAxis.scalePadding
|
215
|
+
const groupScaleDomainMax = data.fullDataFormatter.grid.groupAxis.scaleDomain[1] === 'auto'
|
216
|
+
? groupMax + data.fullDataFormatter.grid.groupAxis.scalePadding
|
217
|
+
: data.fullDataFormatter.grid.groupAxis.scaleDomain[1] as number + data.fullDataFormatter.grid.groupAxis.scalePadding
|
180
218
|
|
181
|
-
|
219
|
+
return [groupScaleDomainMin, groupScaleDomainMax]
|
220
|
+
}),
|
221
|
+
shareReplay(1)
|
222
|
+
)
|
223
|
+
|
224
|
+
const groupLabels$ = combineLatest({
|
225
|
+
fullDataFormatter: fullDataFormatter$,
|
226
|
+
computedData: computedData$
|
227
|
+
}).pipe(
|
228
|
+
switchMap(async d => d),
|
229
|
+
map(data => {
|
230
|
+
return data.fullDataFormatter.grid.seriesDirection === 'row'
|
182
231
|
? (data.computedData[0] ?? []).map(d => d.groupLabel)
|
183
232
|
: data.computedData.map(d => d[0].groupLabel)
|
233
|
+
})
|
234
|
+
)
|
184
235
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
236
|
+
// 顯示範圍內的group labels
|
237
|
+
const scaleRangeGroupLabels$ = combineLatest({
|
238
|
+
groupScaleDomain: groupScaleDomain$,
|
239
|
+
groupLabels: groupLabels$
|
240
|
+
}).pipe(
|
241
|
+
switchMap(async d => d),
|
242
|
+
map(data => {
|
243
|
+
return data.groupLabels
|
193
244
|
.filter((d, i) => {
|
194
|
-
return i >=
|
245
|
+
return i >= data.groupScaleDomain[0] && i <= data.groupScaleDomain[1]
|
195
246
|
})
|
196
|
-
subscriber.next(_axisLabels)
|
197
247
|
})
|
198
|
-
|
248
|
+
)
|
249
|
+
|
250
|
+
const columnAmount$ = gridContainerPosition$.pipe(
|
251
|
+
map(gridContainerPosition => {
|
252
|
+
const maxColumnIndex = gridContainerPosition.reduce((acc, current) => {
|
253
|
+
return current.columnIndex > acc ? current.columnIndex : acc
|
254
|
+
}, 0)
|
255
|
+
return maxColumnIndex + 1
|
256
|
+
}),
|
257
|
+
distinctUntilChanged()
|
258
|
+
)
|
259
|
+
|
260
|
+
const rowAmount$ = gridContainerPosition$.pipe(
|
261
|
+
map(gridContainerPosition => {
|
262
|
+
const maxRowIndex = gridContainerPosition.reduce((acc, current) => {
|
263
|
+
return current.rowIndex > acc ? current.rowIndex : acc
|
264
|
+
}, 0)
|
265
|
+
return maxRowIndex + 1
|
266
|
+
}),
|
267
|
+
distinctUntilChanged()
|
268
|
+
)
|
199
269
|
|
200
270
|
return new Observable<(event: any) => { groupIndex: number; groupLabel: string }>(subscriber => {
|
201
271
|
combineLatest({
|
202
272
|
dataFormatter: fullDataFormatter$,
|
203
273
|
axisSize: gridAxesSize$,
|
204
274
|
fullChartParams: fullChartParams$,
|
205
|
-
scaleRangeGroupLabels: scaleRangeGroupLabels
|
275
|
+
scaleRangeGroupLabels: scaleRangeGroupLabels$,
|
276
|
+
groupScaleDomain: groupScaleDomain$,
|
277
|
+
columnAmount: columnAmount$,
|
278
|
+
rowAmount: rowAmount$,
|
279
|
+
layout: layout$
|
206
280
|
}).pipe(
|
207
281
|
takeUntil(destroy$),
|
208
282
|
switchMap(async (d) => d),
|
@@ -213,9 +287,10 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
213
287
|
? true : false
|
214
288
|
|
215
289
|
// 比例尺座標對應非連續資料索引
|
216
|
-
const
|
290
|
+
const xIndexScale = createAxisQuantizeScale({
|
217
291
|
axisLabels: data.scaleRangeGroupLabels,
|
218
292
|
axisWidth: data.axisSize.width,
|
293
|
+
padding: data.dataFormatter.grid.groupAxis.scalePadding,
|
219
294
|
reverse
|
220
295
|
})
|
221
296
|
|
@@ -229,8 +304,16 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
229
304
|
|
230
305
|
// 比例尺座標取得groupData的function
|
231
306
|
const createEventGroupData: (event: any) => { groupIndex: number; groupLabel: string } = (event: any) => {
|
232
|
-
|
233
|
-
const
|
307
|
+
// 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
|
308
|
+
const eventData = {
|
309
|
+
offsetX: event.offsetX * data.columnAmount % data.layout.rootWidth,
|
310
|
+
offsetY: event.offsetY * data.rowAmount % data.layout.rootHeight
|
311
|
+
}
|
312
|
+
// console.log('data.columnAmount', data.columnAmount, 'data.rowAmount', data.rowAmount, 'data.layout.rootWidth', data.layout.rootWidth, 'data.layout.rootHeight', data.layout.rootHeight)
|
313
|
+
const axisValue = axisValuePredicate(eventData)
|
314
|
+
const xIndex = xIndexScale(axisValue)
|
315
|
+
const currentxIndexStart = Math.ceil(data.groupScaleDomain[0]) // 因為有padding所以會有小數點,所以要無條件進位
|
316
|
+
const groupIndex = xIndex + currentxIndexStart
|
234
317
|
return {
|
235
318
|
groupIndex,
|
236
319
|
groupLabel: data.scaleRangeGroupLabels[groupIndex] ?? ''
|
@@ -246,3 +329,214 @@ export const gridGroupPositionFnObservable = ({ fullDataFormatter$, gridAxesSize
|
|
246
329
|
})
|
247
330
|
}
|
248
331
|
|
332
|
+
export const gridGroupPosition = ({ rootSelection, fullDataFormatter$, gridAxesSize$, computedData$, fullChartParams$, gridContainerPosition$, layout$ }: {
|
333
|
+
rootSelection: d3.Selection<any, unknown, any, unknown>
|
334
|
+
fullDataFormatter$: Observable<DataFormatterGrid>
|
335
|
+
gridAxesSize$: Observable<{
|
336
|
+
width: number;
|
337
|
+
height: number;
|
338
|
+
}>
|
339
|
+
computedData$: Observable<ComputedDataGrid>
|
340
|
+
fullChartParams$: Observable<ChartParams>
|
341
|
+
gridContainerPosition$: Observable<GridContainerPosition[]>
|
342
|
+
layout$: Observable<Layout>
|
343
|
+
}) => {
|
344
|
+
const rootMousemove$: Observable<any> = d3EventObservable(rootSelection, 'mousemove')
|
345
|
+
|
346
|
+
const groupScaleDomain$ = combineLatest({
|
347
|
+
fullDataFormatter: fullDataFormatter$,
|
348
|
+
gridAxesSize: gridAxesSize$,
|
349
|
+
computedData: computedData$
|
350
|
+
}).pipe(
|
351
|
+
switchMap(async (d) => d),
|
352
|
+
map(data => {
|
353
|
+
const groupMin = 0
|
354
|
+
const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
355
|
+
const groupScaleDomainMin = data.fullDataFormatter.grid.groupAxis.scaleDomain[0] === 'auto'
|
356
|
+
? groupMin - data.fullDataFormatter.grid.groupAxis.scalePadding
|
357
|
+
: data.fullDataFormatter.grid.groupAxis.scaleDomain[0] as number - data.fullDataFormatter.grid.groupAxis.scalePadding
|
358
|
+
const groupScaleDomainMax = data.fullDataFormatter.grid.groupAxis.scaleDomain[1] === 'auto'
|
359
|
+
? groupMax + data.fullDataFormatter.grid.groupAxis.scalePadding
|
360
|
+
: data.fullDataFormatter.grid.groupAxis.scaleDomain[1] as number + data.fullDataFormatter.grid.groupAxis.scalePadding
|
361
|
+
|
362
|
+
return [groupScaleDomainMin, groupScaleDomainMax]
|
363
|
+
}),
|
364
|
+
shareReplay(1)
|
365
|
+
)
|
366
|
+
|
367
|
+
const groupLabels$ = combineLatest({
|
368
|
+
fullDataFormatter: fullDataFormatter$,
|
369
|
+
computedData: computedData$
|
370
|
+
}).pipe(
|
371
|
+
switchMap(async d => d),
|
372
|
+
map(data => {
|
373
|
+
return data.fullDataFormatter.grid.seriesDirection === 'row'
|
374
|
+
? (data.computedData[0] ?? []).map(d => d.groupLabel)
|
375
|
+
: data.computedData.map(d => d[0].groupLabel)
|
376
|
+
})
|
377
|
+
)
|
378
|
+
|
379
|
+
const scaleRangeGroupLabels$ = combineLatest({
|
380
|
+
groupScaleDomain: groupScaleDomain$,
|
381
|
+
groupLabels: groupLabels$
|
382
|
+
}).pipe(
|
383
|
+
switchMap(async d => d),
|
384
|
+
map(data => {
|
385
|
+
return data.groupLabels
|
386
|
+
.filter((d, i) => {
|
387
|
+
return i >= data.groupScaleDomain[0] && i <= data.groupScaleDomain[1]
|
388
|
+
})
|
389
|
+
})
|
390
|
+
)
|
391
|
+
|
392
|
+
const reverse$ = fullDataFormatter$.pipe(
|
393
|
+
map(d => {
|
394
|
+
return d.grid.valueAxis.position === 'right' || d.grid.valueAxis.position === 'bottom'
|
395
|
+
? true
|
396
|
+
: false
|
397
|
+
})
|
398
|
+
)
|
399
|
+
|
400
|
+
// 比例尺座標對應非連續資料索引
|
401
|
+
const xIndexScale$ = combineLatest({
|
402
|
+
reverse: reverse$,
|
403
|
+
gridAxesSize: gridAxesSize$,
|
404
|
+
scaleRangeGroupLabels: scaleRangeGroupLabels$,
|
405
|
+
fullDataFormatter: fullDataFormatter$
|
406
|
+
}).pipe(
|
407
|
+
switchMap(async d => d),
|
408
|
+
map(data => {
|
409
|
+
return createAxisQuantizeScale({
|
410
|
+
axisLabels: data.scaleRangeGroupLabels,
|
411
|
+
axisWidth: data.gridAxesSize.width,
|
412
|
+
padding: data.fullDataFormatter.grid.groupAxis.scalePadding,
|
413
|
+
reverse: data.reverse
|
414
|
+
})
|
415
|
+
})
|
416
|
+
)
|
417
|
+
|
418
|
+
const columnAmount$ = gridContainerPosition$.pipe(
|
419
|
+
map(gridContainerPosition => {
|
420
|
+
const maxColumnIndex = gridContainerPosition.reduce((acc, current) => {
|
421
|
+
return current.columnIndex > acc ? current.columnIndex : acc
|
422
|
+
}, 0)
|
423
|
+
return maxColumnIndex + 1
|
424
|
+
}),
|
425
|
+
distinctUntilChanged()
|
426
|
+
)
|
427
|
+
|
428
|
+
const rowAmount$ = gridContainerPosition$.pipe(
|
429
|
+
map(gridContainerPosition => {
|
430
|
+
const maxRowIndex = gridContainerPosition.reduce((acc, current) => {
|
431
|
+
return current.rowIndex > acc ? current.rowIndex : acc
|
432
|
+
}, 0)
|
433
|
+
return maxRowIndex + 1
|
434
|
+
}),
|
435
|
+
distinctUntilChanged()
|
436
|
+
)
|
437
|
+
|
438
|
+
const axisValue$ = combineLatest({
|
439
|
+
fullDataFormatter: fullDataFormatter$,
|
440
|
+
fullChartParams: fullChartParams$,
|
441
|
+
rootMousemove: rootMousemove$,
|
442
|
+
columnAmount: columnAmount$,
|
443
|
+
rowAmount: rowAmount$,
|
444
|
+
layout: layout$
|
445
|
+
}).pipe(
|
446
|
+
switchMap(async d => d),
|
447
|
+
map(data => {
|
448
|
+
// 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
|
449
|
+
const eventData = {
|
450
|
+
offsetX: data.rootMousemove.offsetX * data.columnAmount % data.layout.rootWidth,
|
451
|
+
offsetY: data.rootMousemove.offsetY * data.rowAmount % data.layout.rootHeight
|
452
|
+
}
|
453
|
+
return data.fullDataFormatter.grid.groupAxis.position === 'bottom'
|
454
|
+
|| data.fullDataFormatter.grid.groupAxis.position === 'top'
|
455
|
+
? eventData.offsetX - data.fullChartParams.padding.left
|
456
|
+
: eventData.offsetY - data.fullChartParams.padding.top
|
457
|
+
})
|
458
|
+
)
|
459
|
+
|
460
|
+
const groupIndex$ = combineLatest({
|
461
|
+
xIndexScale: xIndexScale$,
|
462
|
+
axisValue: axisValue$,
|
463
|
+
groupScaleDomain: groupScaleDomain$
|
464
|
+
}).pipe(
|
465
|
+
switchMap(async d => d),
|
466
|
+
map(data => {
|
467
|
+
const xIndex = data.xIndexScale(data.axisValue)
|
468
|
+
const currentxIndexStart = Math.ceil(data.groupScaleDomain[0]) // 因為有padding所以會有小數點,所以要無條件進位
|
469
|
+
return xIndex + currentxIndexStart
|
470
|
+
})
|
471
|
+
)
|
472
|
+
|
473
|
+
const groupLabel$ = combineLatest({
|
474
|
+
groupIndex: groupIndex$,
|
475
|
+
groupLabels: groupLabels$
|
476
|
+
}).pipe(
|
477
|
+
switchMap(async d => d),
|
478
|
+
map(data => {
|
479
|
+
return data.groupLabels[data.groupIndex] ?? ''
|
480
|
+
})
|
481
|
+
)
|
482
|
+
|
483
|
+
return combineLatest({
|
484
|
+
groupIndex: groupIndex$,
|
485
|
+
groupLabel: groupLabel$
|
486
|
+
}).pipe(
|
487
|
+
switchMap(async d => d),
|
488
|
+
map(data => {
|
489
|
+
return {
|
490
|
+
groupIndex: data.groupIndex,
|
491
|
+
groupLabel: data.groupLabel
|
492
|
+
}
|
493
|
+
})
|
494
|
+
)
|
495
|
+
}
|
496
|
+
|
497
|
+
// const gridContainerEventData$ = ({ eventData$, gridContainerPosition$, layout$ }: {
|
498
|
+
// eventData$: Observable<any>
|
499
|
+
// gridContainerPosition$: Observable<GridContainerPosition[]>
|
500
|
+
// layout$: Observable<Layout>
|
501
|
+
// }): Observable<{
|
502
|
+
// offsetX: number;
|
503
|
+
// offsetY: number;
|
504
|
+
// }> => {
|
505
|
+
// const columnAmount$ = gridContainerPosition$.pipe(
|
506
|
+
// map(gridContainerPosition => {
|
507
|
+
// const maxColumnIndex = gridContainerPosition.reduce((acc, current) => {
|
508
|
+
// return current.columnIndex > acc ? current.columnIndex : acc
|
509
|
+
// }, 0)
|
510
|
+
// return maxColumnIndex + 1
|
511
|
+
// }),
|
512
|
+
// distinctUntilChanged()
|
513
|
+
// )
|
514
|
+
|
515
|
+
// const rowAmount$ = gridContainerPosition$.pipe(
|
516
|
+
// map(gridContainerPosition => {
|
517
|
+
// const maxRowIndex = gridContainerPosition.reduce((acc, current) => {
|
518
|
+
// return current.rowIndex > acc ? current.rowIndex : acc
|
519
|
+
// }, 0)
|
520
|
+
// return maxRowIndex + 1
|
521
|
+
// }),
|
522
|
+
// distinctUntilChanged()
|
523
|
+
// )
|
524
|
+
|
525
|
+
// return combineLatest({
|
526
|
+
// eventData: eventData$,
|
527
|
+
// gridContainerPosition: gridContainerPosition$,
|
528
|
+
// layout: layout$,
|
529
|
+
// columnAmount: columnAmount$,
|
530
|
+
// rowAmount: rowAmount$
|
531
|
+
// }).pipe(
|
532
|
+
// switchMap(async d => d),
|
533
|
+
// map(data => {
|
534
|
+
// // 由於event座標是基於底層的,但是container會有多欄,所以要重新計算
|
535
|
+
// const eventData = {
|
536
|
+
// offsetX: data.eventData.offsetX * data.columnAmount % data.layout.rootWidth,
|
537
|
+
// offsetY: data.eventData.offsetY * data.rowAmount % data.layout.rootHeight
|
538
|
+
// }
|
539
|
+
// return eventData
|
540
|
+
// })
|
541
|
+
// )
|
542
|
+
// }
|