@orbcharts/plugins-basic 3.0.0-alpha.56 → 3.0.0-alpha.58
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.
- 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
|
+
// }
|