@orbcharts/core 3.0.0-alpha.31 → 3.0.0-alpha.33

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,15 +19,18 @@ import type {
19
19
  DataTypeMap,
20
20
  DataFormatterTypeMap,
21
21
  DataFormatterGrid,
22
- DataFormatterContext,
22
+ DataFormatterGridContainer,
23
23
  DataFormatterValueAxis,
24
24
  DataFormatterGroupAxis,
25
+ ContainerPosition,
25
26
  HighlightTarget,
26
27
  Layout,
27
28
  TransformData } from '../types'
28
- import { getMinAndMaxGrid, transposeData } from '../utils/orbchartsUtils'
29
+ import { getMinAndMaxGrid } from '../utils/orbchartsUtils'
29
30
  import { createAxisLinearScale, createAxisPointScale, createAxisQuantizeScale } from '../utils/d3Utils'
30
31
  import { highlightObservable } from '../utils/observables'
32
+ import { calcGridContainerPosition } from '../utils/orbchartsUtils'
33
+ import { DATA_FORMATTER_GRID_GRID_DEFAULT } from '../defaults'
31
34
 
32
35
  export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
33
36
  fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
@@ -44,7 +47,7 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
44
47
  if (!xAxis || !yAxis) {
45
48
  return {
46
49
  translate: [0, 0],
47
- scale: [0, 0],
50
+ scale: [1, 1],
48
51
  rotate: 0,
49
52
  rotateX: 0,
50
53
  rotateY: 0,
@@ -102,6 +105,8 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
102
105
  translateX = width
103
106
  } else if (yAxis.position === 'top') {
104
107
  rotate = -90
108
+ rotateX = 180
109
+ rotateY = 180
105
110
  translateX = width
106
111
  } else {
107
112
  // 預設
@@ -109,12 +114,11 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
109
114
  translateY = height
110
115
  }
111
116
  }
112
-
113
117
  // selection.style('transform', `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`)
114
118
 
115
119
  return {
116
120
  translate: [translateX, translateY],
117
- scale: [0, 0],
121
+ scale: [1, 1],
118
122
  rotate,
119
123
  rotateX,
120
124
  rotateY,
@@ -131,8 +135,8 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
131
135
  switchMap(async (d) => d),
132
136
  ).subscribe(data => {
133
137
  const axesTransformData = calcAxesTransform({
134
- xAxis: data.fullDataFormatter.groupAxis,
135
- yAxis: data.fullDataFormatter.valueAxis,
138
+ xAxis: data.fullDataFormatter.grid.groupAxis,
139
+ yAxis: data.fullDataFormatter.grid.valueAxis,
136
140
  width: data.layout.width,
137
141
  height: data.layout.height
138
142
  })
@@ -146,6 +150,30 @@ export const gridAxesTransformObservable = ({ fullDataFormatter$, layout$ }: {
146
150
  })
147
151
  }
148
152
 
153
+
154
+ export const gridAxesReverseTransformObservable = ({ gridAxesTransform$ }: {
155
+ gridAxesTransform$: Observable<TransformData>
156
+ }): Observable<TransformData> => {
157
+ return gridAxesTransform$.pipe(
158
+ map(d => {
159
+ // const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
160
+ const translate: [number, number] = [0, 0] // 無需逆轉
161
+ const scale: [number, number] = [1 / d.scale[0], 1 / d.scale[1]]
162
+ const rotate = d.rotate * -1
163
+ const rotateX = d.rotateX * -1
164
+ const rotateY = d.rotateY * -1
165
+ return {
166
+ translate,
167
+ scale,
168
+ rotate,
169
+ rotateX,
170
+ rotateY,
171
+ value: `translate(${translate[0]}px, ${translate[1]}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`
172
+ }
173
+ }),
174
+ )
175
+ }
176
+
149
177
  export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
150
178
  computedData$: Observable<ComputedDataTypeMap<'grid'>>
151
179
  fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
@@ -244,8 +272,8 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
244
272
  ).subscribe(data => {
245
273
  const dataAreaTransformData = calcGridDataAreaTransform ({
246
274
  data: data.computedData,
247
- groupAxis: data.fullDataFormatter.groupAxis,
248
- valueAxis: data.fullDataFormatter.valueAxis,
275
+ groupAxis: data.fullDataFormatter.grid.groupAxis,
276
+ valueAxis: data.fullDataFormatter.grid.valueAxis,
249
277
  width: data.layout.width,
250
278
  height: data.layout.height
251
279
  })
@@ -259,24 +287,33 @@ export const gridGraphicTransformObservable = ({ computedData$, fullDataFormatte
259
287
  })
260
288
  }
261
289
 
262
- export const gridAxesOppositeTransformObservable = ({ gridAxesTransform$ }: {
290
+ export const gridGraphicReverseScaleObservable = ({ gridContainer$, gridAxesTransform$, gridGraphicTransform$ }: {
291
+ gridContainer$: Observable<ContainerPosition[]>
263
292
  gridAxesTransform$: Observable<TransformData>
264
- }): Observable<TransformData> => {
265
- return gridAxesTransform$.pipe(
266
- map(d => {
267
- // const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
268
- const translate: [number, number] = [0, 0] // 無需逆轉
269
- const scale: [number, number] = [d.scale[0] * -1, d.scale[1] * -1]
270
- const rotate = d.rotate * -1
271
- const rotateX = d.rotateX * -1
272
- const rotateY = d.rotateY * -1
273
- return {
274
- translate,
275
- scale,
276
- rotate,
277
- rotateX,
278
- rotateY,
279
- value: `translate(${translate[0]}px, ${translate[1]}px) rotate(${rotate}deg) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`
293
+ gridGraphicTransform$: Observable<TransformData>
294
+ }): Observable<[number, number][]> => {
295
+ return combineLatest({
296
+ gridContainer: gridContainer$,
297
+ gridAxesTransform: gridAxesTransform$,
298
+ gridGraphicTransform: gridGraphicTransform$,
299
+ }).pipe(
300
+ switchMap(async (d) => d),
301
+ map(data => {
302
+ if (data.gridAxesTransform.rotate == 0 || data.gridAxesTransform.rotate == 180) {
303
+ return data.gridContainer.map((series, seriesIndex) => {
304
+ return [
305
+ 1 / data.gridGraphicTransform.scale[0] / data.gridContainer[seriesIndex].scale[0],
306
+ 1 / data.gridGraphicTransform.scale[1] / data.gridContainer[seriesIndex].scale[1],
307
+ ]
308
+ })
309
+ } else {
310
+ return data.gridContainer.map((series, seriesIndex) => {
311
+ // 由於有垂直的旋轉,所以外層 (container) x和y的scale要互換
312
+ return [
313
+ 1 / data.gridGraphicTransform.scale[0] / data.gridContainer[seriesIndex].scale[1],
314
+ 1 / data.gridGraphicTransform.scale[1] / data.gridContainer[seriesIndex].scale[0],
315
+ ]
316
+ })
280
317
  }
281
318
  }),
282
319
  )
@@ -317,8 +354,8 @@ export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
317
354
  ).subscribe(data => {
318
355
 
319
356
  const axisSize = calcAxesSize({
320
- xAxisPosition: data.fullDataFormatter.groupAxis.position,
321
- yAxisPosition: data.fullDataFormatter.valueAxis.position,
357
+ xAxisPosition: data.fullDataFormatter.grid.groupAxis.position,
358
+ yAxisPosition: data.fullDataFormatter.grid.valueAxis.position,
322
359
  width: data.layout.width,
323
360
  height: data.layout.height,
324
361
  })
@@ -343,6 +380,21 @@ export const gridAxesSizeObservable = ({ fullDataFormatter$, layout$ }: {
343
380
  // return highlightObservable ({ datumList$, fullChartParams$, event$ })
344
381
  // }
345
382
 
383
+ export const existedSeriesLabelsObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
384
+ return computedData$.pipe(
385
+ map(data => {
386
+ return data
387
+ .filter(series => series.length)
388
+ .map(series => {
389
+ return series[0].seriesLabel
390
+ })
391
+ }),
392
+ distinctUntilChanged((a, b) => {
393
+ return JSON.stringify(a).length === JSON.stringify(b).length
394
+ }),
395
+ )
396
+ }
397
+
346
398
  export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'grid'>> }) => {
347
399
  return computedData$.pipe(
348
400
  map(data => {
@@ -358,3 +410,78 @@ export const gridVisibleComputedDataObservable = ({ computedData$ }: { computedD
358
410
  )
359
411
  }
360
412
 
413
+ export const isSeriesPositionSeprateObservable = ({ computedData$, fullDataFormatter$ }: {
414
+ computedData$: Observable<ComputedDataTypeMap<'grid'>>
415
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
416
+ }) => {
417
+ return combineLatest({
418
+ computedData: computedData$,
419
+ fullDataFormatter: fullDataFormatter$
420
+ }).pipe(
421
+ map(data => {
422
+ return data.fullDataFormatter.grid.seriesSlotIndexes && data.fullDataFormatter.grid.seriesSlotIndexes.length === data.computedData.length
423
+ ? true
424
+ : false
425
+ }),
426
+ distinctUntilChanged()
427
+ )
428
+ }
429
+
430
+ // 所有container位置(對應series)
431
+ export const gridContainerObservable = ({ computedData$, fullDataFormatter$, fullChartParams$, layout$ }: {
432
+ computedData$: Observable<ComputedDataTypeMap<'grid'>>
433
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'grid'>>
434
+ fullChartParams$: Observable<ChartParams>
435
+ layout$: Observable<Layout>
436
+ }) => {
437
+
438
+ const gridContainer$ = combineLatest({
439
+ computedData: computedData$,
440
+ fullDataFormatter: fullDataFormatter$,
441
+ fullChartParams: fullChartParams$,
442
+ layout: layout$,
443
+ }).pipe(
444
+ switchMap(async (d) => d),
445
+ map(data => {
446
+
447
+ const grid = data.fullDataFormatter.grid
448
+
449
+ // 有設定series定位
450
+ const hasSeriesPosition = grid.seriesSlotIndexes && grid.seriesSlotIndexes.length === data.computedData.length
451
+ ? true
452
+ : false
453
+
454
+ if (hasSeriesPosition) {
455
+ // -- 依seriesSlotIndexes計算 --
456
+ return data.computedData.map((seriesData, seriesIndex) => {
457
+ const columnIndex = grid.seriesSlotIndexes[seriesIndex] % data.fullDataFormatter.container.columnAmount
458
+ const rowIndex = Math.floor(grid.seriesSlotIndexes[seriesIndex] / data.fullDataFormatter.container.columnAmount)
459
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
460
+ return {
461
+ slotIndex: grid.seriesSlotIndexes[seriesIndex],
462
+ rowIndex,
463
+ columnIndex,
464
+ translate,
465
+ scale,
466
+ }
467
+ })
468
+ } else {
469
+ // -- 依grid的slotIndex計算 --
470
+ const columnIndex = grid.slotIndex % data.fullDataFormatter.container.columnAmount
471
+ const rowIndex = Math.floor(grid.slotIndex / data.fullDataFormatter.container.columnAmount)
472
+ return data.computedData.map((seriesData, seriesIndex) => {
473
+ const { translate, scale } = calcGridContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
474
+ return {
475
+ slotIndex: grid.slotIndex,
476
+ rowIndex,
477
+ columnIndex,
478
+ translate,
479
+ scale,
480
+ }
481
+ })
482
+ }
483
+ })
484
+ )
485
+
486
+ return gridContainer$
487
+ }
@@ -1,9 +1,9 @@
1
1
  import type { DataGrid } from '../types/DataGrid'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
- import type { DataFormatterMultiGrid } from '../types/DataFormatterMultiGrid'
4
- import type { ComputedDataGrid } from '../types/ComputedDataGrid'
3
+ import type { DataFormatterGrid } from '../types/DataFormatterGrid'
4
+ import type { ComputedDataMultiGrid } from '../types/ComputedDataMultiGrid'
5
5
  import { computeBaseGridData } from '../grid/computeGridData'
6
- import { DATA_FORMATTER_MULTI_GRID_DEFAULT } from '../defaults'
6
+ import { DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT } from '../defaults'
7
7
  import { seriesColorPredicate } from '../utils/orbchartsUtils'
8
8
 
9
9
  export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], dataFormatter, chartParams, layout }) => {
@@ -11,23 +11,27 @@ export const computeMultiGridData: ComputedDataFn<'multiGrid'> = ({ data = [], d
11
11
  return []
12
12
  }
13
13
 
14
- let multiGridData: ComputedDataGrid[] = []
14
+ let multiGridData: ComputedDataMultiGrid = []
15
15
 
16
16
  try {
17
- const defaultDataFormatterGrid = Object.assign({}, DATA_FORMATTER_MULTI_GRID_DEFAULT.multiGrid[0])
17
+ const defaultGrid = dataFormatter.gridList[0] || DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
18
18
 
19
19
  // 計算每個grid的資料
20
20
  multiGridData = data.map((gridData, gridIndex) => {
21
- const currentDataFormatterGrid = dataFormatter.multiGrid[gridIndex] || defaultDataFormatterGrid
22
- // const dataFormatterGrid: DataFormatterGrid = {
23
- // ...currentDataFormatterGrid,
24
- // type: `multiGrid` as any,
25
- // visibleFilter: dataFormatter.visibleFilter as any,
26
- // }
21
+ const currentDataFormatterGrid = dataFormatter.gridList[gridIndex] || defaultGrid
22
+
27
23
  return computeBaseGridData(
28
24
  {
29
25
  data: gridData,
30
- dataFormatter: currentDataFormatterGrid,
26
+ dataFormatter: {
27
+ type: 'grid',
28
+ grid: {
29
+ ...currentDataFormatterGrid
30
+ },
31
+ container: {
32
+ ...dataFormatter.container
33
+ }
34
+ },
31
35
  chartParams,
32
36
  layout
33
37
  },
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  shareReplay } from 'rxjs'
3
3
  import type { ContextObserverFn } from '../types'
4
- import { multiGridEachDetailObservable } from './multiGridObservables'
4
+ import { multiGridEachDetailObservable, multiGridContainerObservable } from './multiGridObservables'
5
5
 
6
6
  export const createMultiGridContextObserver: ContextObserverFn<'multiGrid'> = ({ subject, observer }) => {
7
7
 
@@ -15,12 +15,20 @@ export const createMultiGridContextObserver: ContextObserverFn<'multiGrid'> = ({
15
15
  shareReplay(1)
16
16
  )
17
17
 
18
+ const multiGridContainer$ = multiGridContainerObservable({
19
+ computedData$: observer.computedData$,
20
+ fullDataFormatter$: observer.fullDataFormatter$,
21
+ fullChartParams$: observer.fullChartParams$,
22
+ layout$: observer.layout$,
23
+ })
24
+
18
25
  return {
19
26
  fullParams$: observer.fullParams$,
20
27
  fullChartParams$: observer.fullChartParams$,
21
28
  fullDataFormatter$: observer.fullDataFormatter$,
22
29
  computedData$: observer.computedData$,
23
30
  layout$: observer.layout$,
24
- multiGridEachDetail$
31
+ multiGridEachDetail$,
32
+ multiGridContainer$
25
33
  }
26
34
  }