@orbcharts/core 3.0.0-alpha.42 → 3.0.0-alpha.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/dist/orbcharts-core.es.js +1905 -1896
  2. package/dist/orbcharts-core.umd.js +2 -2
  3. package/dist/src/defaults.d.ts +4 -3
  4. package/dist/src/grid/computeGridData.d.ts +4 -11
  5. package/dist/src/grid/gridObservables.d.ts +15 -18
  6. package/dist/src/multiGrid/multiGridObservables.d.ts +4 -11
  7. package/dist/src/series/seriesObservables.d.ts +26 -1
  8. package/dist/src/types/ComputedData.d.ts +1 -0
  9. package/dist/src/types/ComputedDataGrid.d.ts +0 -3
  10. package/dist/src/types/ComputedDataSeries.d.ts +1 -2
  11. package/dist/src/types/ContextObserverGrid.d.ts +11 -4
  12. package/dist/src/types/ContextObserverMultiGrid.d.ts +8 -3
  13. package/dist/src/types/ContextObserverSeries.d.ts +18 -0
  14. package/dist/src/types/DataFormatter.d.ts +8 -5
  15. package/dist/src/types/DataFormatterGrid.d.ts +13 -16
  16. package/dist/src/types/DataFormatterMultiGrid.d.ts +6 -3
  17. package/dist/src/types/DataFormatterMultiValue.d.ts +3 -0
  18. package/dist/src/types/DataFormatterRelationship.d.ts +3 -0
  19. package/dist/src/types/DataFormatterSeries.d.ts +11 -4
  20. package/dist/src/utils/orbchartsUtils.d.ts +14 -13
  21. package/package.json +1 -1
  22. package/src/base/createBaseChart.ts +10 -10
  23. package/src/defaults.ts +36 -64
  24. package/src/grid/computeGridData.ts +15 -86
  25. package/src/grid/createGridContextObserver.ts +33 -16
  26. package/src/grid/gridObservables.ts +157 -70
  27. package/src/multiGrid/computeMultiGridData.ts +77 -120
  28. package/src/multiGrid/createMultiGridContextObserver.ts +8 -8
  29. package/src/multiGrid/multiGridObservables.ts +236 -171
  30. package/src/multiValue/computeMultiValueData.ts +22 -15
  31. package/src/relationship/computeRelationshipData.ts +16 -4
  32. package/src/series/computeSeriesData.ts +51 -114
  33. package/src/series/createSeriesContextObserver.ts +59 -4
  34. package/src/series/seriesObservables.ts +162 -10
  35. package/src/tree/computeTreeData.ts +6 -3
  36. package/src/types/ComputedData.ts +1 -0
  37. package/src/types/ComputedDataGrid.ts +3 -3
  38. package/src/types/ComputedDataSeries.ts +2 -2
  39. package/src/types/ContextObserverGrid.ts +18 -10
  40. package/src/types/ContextObserverMultiGrid.ts +6 -18
  41. package/src/types/ContextObserverSeries.ts +21 -1
  42. package/src/types/DataFormatter.ts +11 -32
  43. package/src/types/DataFormatterGrid.ts +32 -20
  44. package/src/types/DataFormatterMultiGrid.ts +6 -4
  45. package/src/types/DataFormatterMultiValue.ts +3 -0
  46. package/src/types/DataFormatterRelationship.ts +3 -0
  47. package/src/types/DataFormatterSeries.ts +11 -21
  48. package/src/utils/d3Utils.ts +7 -7
  49. package/src/utils/orbchartsUtils.ts +128 -32
@@ -1,149 +1,86 @@
1
1
  import type { DataSeries, DataSeriesDatum } from '../types/DataSeries'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
- import type { ComputedDataSeries, ComputedDatumSeries } from '../types/ComputedDataSeries'
3
+ import type { ComputedDatumSeries } from '../types/ComputedDataSeries'
4
4
  import { formatValueToLabel, createDefaultDatumId, createDefaultSeriesLabel, seriesColorPredicate } from '../utils/orbchartsUtils'
5
5
 
6
- interface SortValue {
7
- rowIndex: number
8
- columnIndex: number
9
- index: number
10
- datum: number | DataSeriesDatum
11
- }
12
-
13
- type GetSortedIndex = (computedDataSeries: ComputedDatumSeries[], rowIndex: number, columnIndex: number) => number
14
-
15
- function createSortedIndexMap (data: DataSeries, sort: (a: number | DataSeriesDatum, b: number | DataSeriesDatum) => number): Map<string, number> {
16
-
17
- const SortedIndexMap: Map<string, number> = new Map() // Map<[rowIndex, columnIndex], sortedIndex>
18
-
19
- let _data = Object.assign([], data) as DataSeries
20
- // 建立排序所需資料的物件
21
- let sortValueData: SortValue[] = []
22
- _data.forEach((d, i) => {
23
- if (Array.isArray(d)) {
24
- d.forEach((_d, _i) => {
25
- sortValueData.push({
26
- rowIndex: i,
27
- columnIndex: _i,
28
- index: -1,
29
- datum: _d
30
- })
31
- })
32
- } else {
33
- sortValueData.push({
34
- rowIndex: i,
35
- columnIndex: 0,
36
- index: -1,
37
- datum: d
38
- })
39
- }
40
- })
41
- // 排序
42
- sortValueData.sort((a, b) => sort(a.datum, b.datum))
43
- // 取得排序後的index
44
- sortValueData = sortValueData.map((d, i) => {
45
- return {
46
- ...d,
47
- index: i
48
- }
49
- })
50
- // 建立SortedIndexMap
51
- sortValueData.forEach(d => {
52
- SortedIndexMap.set(String([d.rowIndex, d.columnIndex]), d.index)
53
- })
54
-
55
- return SortedIndexMap
56
- }
57
-
58
6
  export const computeSeriesData: ComputedDataFn<'series'> = (context) => {
59
7
  const { data = [], dataFormatter, chartParams } = context
60
8
  if (!data.length) {
61
9
  return []
62
10
  }
63
11
 
64
- const computedDataSeries: ComputedDatumSeries[] = []
12
+ let computedDataSeries: ComputedDatumSeries[][] = []
65
13
 
66
14
  try {
67
- // 取得排序後的索引
68
- const getSortedIndex: GetSortedIndex = ((hasSort: boolean) => {
69
- if (hasSort) {
70
- // 資料索引對應排序後的索引 Map<[rowIndex, columnIndex], sortedIndex>
71
- const SortedIndexMap: Map<string, number> = createSortedIndexMap(data, dataFormatter.sort)
72
- return (computedDataSeries: ComputedDatumSeries[], rowIndex: number, columnIndex: number) => {
73
- return SortedIndexMap.get(String([rowIndex, columnIndex]))
74
- }
75
- } else {
76
- return (computedDataSeries: ComputedDatumSeries[], rowIndex: number, columnIndex: number) => {
77
- return computedDataSeries.length
78
- }
79
- }
80
- })(dataFormatter.sort != null)
81
-
82
- // 資料索引對應排序後的索引 Map<[rowIndex, columnIndex], sortedIndex>
83
- // let SortedIndexMap: Map<string, number> = new Map()
84
- // if (dataFormatter.sort) {
85
- // SortedIndexMap = createSortedIndexMap(data, dataFormatter.sort)
86
- // }
87
15
 
88
- const createComputedDatumSeries = (detailData: number | DataSeriesDatum, rowIndex: number, columnIndex: number, currentIndex: number, sortedIndex: number): ComputedDatumSeries => {
89
- const defaultId = createDefaultDatumId(dataFormatter.type, rowIndex, columnIndex)
90
- // const seriesLabel = dataFormatter.mapSeries(detailData, rowIndex, columnIndex, context)
91
- const seriesLabel = dataFormatter.seriesLabels[rowIndex] || createDefaultSeriesLabel('series', rowIndex)
92
- // const color = dataFormatter.colorsPredicate(detailData, rowIndex, columnIndex, context)
93
- const color = seriesColorPredicate(rowIndex, chartParams)
94
- const visible = dataFormatter.visibleFilter(detailData, rowIndex, columnIndex, context)
95
- if (typeof detailData === 'number') {
16
+ const createComputedDatumSeries = (seriesData: number | DataSeriesDatum, seriesIndex: number, itemIndex: number, currentIndex: number): ComputedDatumSeries => {
17
+ const defaultId = createDefaultDatumId(dataFormatter.type, seriesIndex, itemIndex)
18
+ const seriesLabel = dataFormatter.seriesLabels[seriesIndex] || createDefaultSeriesLabel('series', seriesIndex)
19
+ const color = seriesColorPredicate(seriesIndex, chartParams)
20
+ if (typeof seriesData === 'number') {
96
21
  return {
97
22
  id: defaultId,
98
23
  index: currentIndex,
99
- sortedIndex,
24
+ seq: 0, // 先給預設值
100
25
  label: defaultId,
101
26
  description: '',
102
- // tooltipContent: dataFormatter.tooltipContentFormat(detailData, rowIndex, columnIndex, context),
103
27
  data: {},
104
- value: detailData,
105
- // valueLabel: formatValueToLabel(detailData, dataFormatter.valueFormat),
106
- seriesIndex: rowIndex,
28
+ value: seriesData,
29
+ seriesIndex: seriesIndex,
107
30
  seriesLabel,
108
31
  color,
109
- visible
32
+ visible: true // 先給預設值
110
33
  }
111
34
  } else {
112
35
  return {
113
- id: detailData.id ? detailData.id : defaultId,
36
+ id: seriesData.id ? seriesData.id : defaultId,
114
37
  index: currentIndex,
115
- sortedIndex,
116
- label: detailData.label ? detailData.label : defaultId,
117
- description: detailData.description,
118
- // tooltipContent: detailData.tooltipContent ? detailData.tooltipContent : dataFormatter.tooltipContentFormat(detailData, rowIndex, columnIndex, context),
119
- data: detailData.data ?? {},
120
- value: detailData.value,
121
- // valueLabel: formatValueToLabel(detailData.value, dataFormatter.valueFormat),
122
- seriesIndex: rowIndex,
38
+ seq: 0, // 先給預設值
39
+ label: seriesData.label ? seriesData.label : defaultId,
40
+ description: seriesData.description,
41
+ data: seriesData.data ?? {},
42
+ value: seriesData.value,
43
+ seriesIndex: seriesIndex,
123
44
  seriesLabel,
124
45
  color,
125
- visible
46
+ visible: true // 先給預設值
126
47
  }
127
48
  }
128
49
  }
129
50
 
130
- data.forEach((mainData, rowIndex) => {
131
- if (Array.isArray(mainData)) {
132
- mainData.forEach((detailData, columnIndex) => {
133
- const sortedIndex = getSortedIndex(computedDataSeries, rowIndex, columnIndex)
134
- const datum = createComputedDatumSeries(detailData, rowIndex, columnIndex, computedDataSeries.length, sortedIndex)
135
- computedDataSeries.push(datum)
136
- })
137
- } else {
138
- const sortedIndex = getSortedIndex(computedDataSeries, rowIndex, 0)
139
- const datum = createComputedDatumSeries(mainData, rowIndex, 0, computedDataSeries.length, sortedIndex) // 只有一維陣列所以columnIndex為0
140
- computedDataSeries.push(datum)
141
- }
142
- })
51
+ computedDataSeries = data
52
+ .map((seriesData, seriesIndex) => {
53
+ if (Array.isArray(seriesData)) {
54
+ return seriesData.map((item, itemIndex) =>
55
+ createComputedDatumSeries(item, seriesIndex, itemIndex, computedDataSeries.length + itemIndex)
56
+ )
57
+ } else {
58
+ return createComputedDatumSeries(seriesData, seriesIndex, 0, computedDataSeries.length)
59
+ }
60
+ })
61
+ // 攤為一維陣列
62
+ .flat()
63
+ // 排序後給 seq
64
+ .sort(dataFormatter.sort ?? undefined)
65
+ .map((datum, index) => {
66
+ datum.seq = index
67
+ return datum
68
+ })
69
+ .map(datum => {
70
+ datum.visible = dataFormatter.visibleFilter(datum, context)
71
+ return datum
72
+ })
73
+ // 恢復原排序
74
+ .sort((a, b) => a.index - b.index)
75
+ // 依seriesIndex分組(二維陣列)
76
+ .reduce((acc, datum) => {
77
+ if (!acc[datum.seriesIndex]) {
78
+ acc[datum.seriesIndex] = []
79
+ }
80
+ acc[datum.seriesIndex].push(datum)
81
+ return acc
82
+ }, [])
143
83
 
144
- // if (dataFormatter.sort != null) {
145
- // computedDataSeries.sort((a, b) => a.sortedIndex - b.sortedIndex)
146
- // }
147
84
  } catch (e) {
148
85
  // console.error(e)
149
86
  throw Error(e)
@@ -1,26 +1,74 @@
1
- import { shareReplay } from 'rxjs'
1
+ import { map, shareReplay } from 'rxjs'
2
2
  import type { ContextObserverFn } from '../types'
3
3
  import {
4
4
  seriesDataMapObservable,
5
5
  groupDataMapObservable } from '../utils/observables'
6
6
  import { highlightObservable, textSizePxObservable } from '../utils/observables'
7
7
 
8
+ import { separateSeriesObservable, visibleComputedDataObservable, computedLayoutDataObservable, seriesLabelsObservable, seriesContainerPositionObservable, seriesContainerPositionMapObservable } from './seriesObservables'
9
+
8
10
  export const createSeriesContextObserver: ContextObserverFn<'series'> = ({ subject, observer }) => {
9
11
 
10
12
  const textSizePx$ = textSizePxObservable(observer.fullChartParams$).pipe(
11
13
  shareReplay(1)
12
14
  )
13
15
 
16
+ const separateSeries$ = separateSeriesObservable({
17
+ fullDataFormatter$: observer.fullDataFormatter$
18
+ })
19
+
20
+ const visibleComputedData$ = visibleComputedDataObservable({
21
+ computedData$: observer.computedData$,
22
+ })
23
+
24
+ const computedLayoutData$ = computedLayoutDataObservable({
25
+ computedData$: observer.computedData$,
26
+ fullDataFormatter$: observer.fullDataFormatter$
27
+ }).pipe(
28
+ shareReplay(1)
29
+ )
30
+
31
+ const visibleComputedLayoutData$ = visibleComputedDataObservable({
32
+ computedData$: computedLayoutData$,
33
+ })
34
+
35
+ const datumList$ = observer.computedData$.pipe(
36
+ map(d => d.flat())
37
+ ).pipe(
38
+ shareReplay(1)
39
+ )
40
+
14
41
  const seriesHighlight$ = highlightObservable({
15
- datumList$: observer.computedData$,
42
+ datumList$,
16
43
  fullChartParams$: observer.fullChartParams$,
17
44
  event$: subject.event$
18
45
  }).pipe(
19
46
  shareReplay(1)
20
47
  )
21
48
 
49
+ const seriesLabels$ = seriesLabelsObservable({
50
+ computedData$: observer.computedData$,
51
+ })
52
+
53
+
22
54
  const SeriesDataMap$ = seriesDataMapObservable({
23
- datumList$: observer.computedData$
55
+ datumList$
56
+ }).pipe(
57
+ shareReplay(1)
58
+ )
59
+
60
+ const seriesContainerPosition$ = seriesContainerPositionObservable({
61
+ computedData$: observer.computedData$,
62
+ fullDataFormatter$: observer.fullDataFormatter$,
63
+ layout$: observer.layout$,
64
+ }).pipe(
65
+ shareReplay(1)
66
+ )
67
+
68
+ const SeriesContainerPositionMap$ = seriesContainerPositionMapObservable({
69
+ seriesContainerPosition$: seriesContainerPosition$,
70
+ seriesLabels$: seriesLabels$,
71
+ separateSeries$: separateSeries$,
24
72
  }).pipe(
25
73
  shareReplay(1)
26
74
  )
@@ -32,7 +80,14 @@ export const createSeriesContextObserver: ContextObserverFn<'series'> = ({ subje
32
80
  computedData$: observer.computedData$,
33
81
  layout$: observer.layout$,
34
82
  textSizePx$,
83
+ visibleComputedData$,
84
+ visibleComputedLayoutData$,
85
+ separateSeries$,
86
+ computedLayoutData$,
35
87
  seriesHighlight$,
36
- SeriesDataMap$
88
+ seriesLabels$,
89
+ SeriesDataMap$,
90
+ seriesContainerPosition$,
91
+ SeriesContainerPositionMap$,
37
92
  }
38
93
  }
@@ -12,13 +12,165 @@ import {
12
12
  import type {
13
13
  ChartParams,
14
14
  ComputedDatumSeries,
15
- ComputedDataTypeMap } from '../types'
16
- import { highlightObservable } from '../utils/observables'
17
-
18
- // export const seriesHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
19
- // computedData$: Observable<ComputedDataTypeMap<'series'>>
20
- // fullChartParams$: Observable<ChartParams>
21
- // event$: Subject<any>
22
- // }): Observable<string[]> => {
23
- // return highlightObservable ({ datumList$: computedData$, fullChartParams$, event$ })
24
- // }
15
+ ComputedDataTypeMap,
16
+ DataFormatterTypeMap,
17
+ SeriesContainerPosition,
18
+ Layout } from '../types'
19
+ import { calcSeriesContainerLayout } from '../utils/orbchartsUtils'
20
+
21
+ export const separateSeriesObservable = ({ fullDataFormatter$ }: { fullDataFormatter$: Observable<DataFormatterTypeMap<'series'>> }) => {
22
+ return fullDataFormatter$.pipe(
23
+ map(data => data.separateSeries),
24
+ distinctUntilChanged(),
25
+ )
26
+ }
27
+
28
+ export const seriesLabelsObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'series'>> }) => {
29
+ return computedData$.pipe(
30
+ map(data => {
31
+ return data
32
+ .filter(series => series.length)
33
+ .map(series => {
34
+ return series[0].seriesLabel
35
+ })
36
+ }),
37
+ distinctUntilChanged((a, b) => {
38
+ return JSON.stringify(a).length === JSON.stringify(b).length
39
+ }),
40
+ )
41
+ }
42
+
43
+ export const visibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTypeMap<'series'>> }) => {
44
+ return computedData$.pipe(
45
+ map(data => {
46
+ return data.map(series => {
47
+ return series.filter(datum => datum.visible != false)
48
+ })
49
+ })
50
+ )
51
+ }
52
+
53
+ export const computedLayoutDataObservable = ({ computedData$, fullDataFormatter$ }: {
54
+ computedData$: Observable<ComputedDataTypeMap<'series'>>,
55
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'series'>>
56
+ }) => {
57
+ return combineLatest({
58
+ computedData: computedData$,
59
+ fullDataFormatter: fullDataFormatter$
60
+ }).pipe(
61
+ switchMap(async (d) => d),
62
+ map(data => {
63
+ const sumData: ComputedDatumSeries[][] = data.fullDataFormatter.sumSeries == true
64
+ ? data.computedData.map(d => {
65
+ return [
66
+ // 加總為一筆資料
67
+ d.reduce((acc, current) => {
68
+ if (acc == null) {
69
+ return current // 取得第一筆資料
70
+ }
71
+ acc.value = acc.value + current.value
72
+ return acc
73
+ }, null)
74
+ ]
75
+ })
76
+ : data.computedData
77
+
78
+ return data.fullDataFormatter.separateSeries == true
79
+ // 有拆分的話每個series為一組
80
+ ? sumData
81
+ .map(series => {
82
+ return series.sort((a, b) => a.seq - b.seq)
83
+ })
84
+ // 無拆分的話所有資料為一組
85
+ : [
86
+ sumData
87
+ .flat()
88
+ .sort((a, b) => a.seq - b.seq)
89
+ ]
90
+ })
91
+ )
92
+ }
93
+
94
+
95
+ // 所有container位置(對應series)
96
+ export const seriesContainerPositionObservable = ({ computedData$, fullDataFormatter$, layout$ }: {
97
+ computedData$: Observable<ComputedDataTypeMap<'series'>>
98
+ fullDataFormatter$: Observable<DataFormatterTypeMap<'series'>>
99
+ layout$: Observable<Layout>
100
+ }): Observable<SeriesContainerPosition[]> => {
101
+
102
+ const gridContainerPosition$ = combineLatest({
103
+ computedData: computedData$,
104
+ fullDataFormatter: fullDataFormatter$,
105
+ layout: layout$,
106
+ }).pipe(
107
+ switchMap(async (d) => d),
108
+ map(data => {
109
+
110
+ if (data.fullDataFormatter.separateSeries) {
111
+ // -- 依slotIndexes計算 --
112
+ return calcSeriesContainerLayout(data.layout, data.fullDataFormatter.container, data.computedData.length)
113
+ // return data.computedData.map((seriesData, seriesIndex) => {
114
+ // const columnIndex = seriesIndex % data.fullDataFormatter.container.columnAmount
115
+ // const rowIndex = Math.floor(seriesIndex / data.fullDataFormatter.container.columnAmount)
116
+ // const { startX, startY, centerX, centerY, width, height } = calcSeriesContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
117
+ // return {
118
+ // slotIndex: seriesIndex,
119
+ // rowIndex,
120
+ // columnIndex,
121
+ // startX,
122
+ // startY,
123
+ // centerX,
124
+ // centerY,
125
+ // width,
126
+ // height,
127
+ // }
128
+ // })
129
+ } else {
130
+ // -- 無拆分 --
131
+ return calcSeriesContainerLayout(data.layout, data.fullDataFormatter.container, 1)
132
+ // const columnIndex = 0
133
+ // const rowIndex = 0
134
+ // return data.computedData.map((seriesData, seriesIndex) => {
135
+ // const { startX, startY, centerX, centerY, width, height } = calcSeriesContainerPosition(data.layout, data.fullDataFormatter.container, rowIndex, columnIndex)
136
+ // return {
137
+ // slotIndex: 0,
138
+ // rowIndex,
139
+ // columnIndex,
140
+ // startX,
141
+ // startY,
142
+ // centerX,
143
+ // centerY,
144
+ // width,
145
+ // height,
146
+ // }
147
+ // })
148
+ }
149
+ })
150
+ )
151
+
152
+ return gridContainerPosition$
153
+ }
154
+
155
+ export const seriesContainerPositionMapObservable = ({ seriesContainerPosition$, seriesLabels$, separateSeries$ }: {
156
+ seriesContainerPosition$: Observable<SeriesContainerPosition[]>
157
+ seriesLabels$: Observable<string[]>
158
+ separateSeries$: Observable<boolean>
159
+ }) => {
160
+ return combineLatest({
161
+ seriesContainerPosition: seriesContainerPosition$,
162
+ seriesLabels: seriesLabels$,
163
+ separateSeries: separateSeries$,
164
+ }).pipe(
165
+ switchMap(async (d) => d),
166
+ map(data => {
167
+ return data.separateSeries
168
+ ? new Map<string, SeriesContainerPosition>(data.seriesLabels.map((seriesLabel, seriesIndex) => {
169
+ return [seriesLabel, data.seriesContainerPosition[seriesIndex] ?? data.seriesContainerPosition[0]]
170
+ }))
171
+ : new Map<string, SeriesContainerPosition>(data.seriesLabels.map((seriesLabel, seriesIndex) => {
172
+ return [seriesLabel, data.seriesContainerPosition[0]]
173
+ }))
174
+ })
175
+ )
176
+ }
@@ -85,7 +85,6 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
85
85
 
86
86
  const formatBranchData = (branch: DataTreeObj, level: number, seq: number): ComputedDataTree => {
87
87
  const childLayer = level + 1
88
- const visible = dataFormatter.visibleFilter(branch, level, seq, context)
89
88
  const categoryLabel: string | null = branch.categoryLabel ?? null
90
89
  let categoryIndex = 0
91
90
  if (categoryLabel != null) {
@@ -97,7 +96,7 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
97
96
 
98
97
  const currentIndex = index
99
98
  index++
100
- return {
99
+ const formattedBranchData: ComputedDataTree = {
101
100
  id: branch.id,
102
101
  index: currentIndex,
103
102
  level,
@@ -110,12 +109,16 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
110
109
  data: branch.data ?? {},
111
110
  // tooltipContent: branch.tooltipContent ? branch.tooltipContent : dataFormatter.tooltipContentFormat(branch, level, seq, context),
112
111
  value: branch.value,
113
- visible,
112
+ visible: true, // 先給預設值
114
113
  children: (branch.children ?? []).map((d, i) => {
115
114
  // 遞迴
116
115
  return formatBranchData(d, childLayer, i)
117
116
  })
118
117
  }
118
+
119
+ formattedBranchData.visible = dataFormatter.visibleFilter(formattedBranchData, context)
120
+
121
+ return formattedBranchData
119
122
  }
120
123
  computedBranchData = formatBranchData(dataTreeObj, 0, 0)
121
124
  } catch (e) {
@@ -45,6 +45,7 @@ export interface ComputedDatumSeriesValue {
45
45
  color: string
46
46
  seriesIndex: number
47
47
  seriesLabel: string
48
+ seq: number
48
49
  }
49
50
 
50
51
  // datum - 矩陣資料
@@ -6,9 +6,9 @@ export interface ComputedDatumGrid
6
6
  // gridIndex: number
7
7
  // groupIndex: number
8
8
  // groupLabel: string
9
- axisX: number
10
- axisY: number
11
- axisYFromZero: number
9
+ // axisX: number
10
+ // axisY: number
11
+ // axisYFromZero: number
12
12
  }
13
13
 
14
14
  export type ComputedDataGrid = ComputedDatumGrid[][]
@@ -2,7 +2,7 @@ import { ComputedDatumBase, ComputedDatumSeriesValue } from './ComputedData'
2
2
 
3
3
  export interface ComputedDatumSeries
4
4
  extends ComputedDatumBase, ComputedDatumSeriesValue {
5
- sortedIndex: number
5
+
6
6
  }
7
7
 
8
- export type ComputedDataSeries = ComputedDatumSeries[]
8
+ export type ComputedDataSeries = ComputedDatumSeries[][]
@@ -3,29 +3,37 @@ import type { ContextObserverBase } from './ContextObserver'
3
3
  import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
4
4
  import type { TransformData } from './TransformData'
5
5
 
6
- export interface ContextObserverGrid<PluginParams>
7
- extends
8
- ContextObserverBase<'grid', PluginParams>,
9
- ContextObserverGridDetail {
10
- textSizePx$: Observable<number>
11
- }
6
+ export interface ContextObserverGrid<PluginParams> extends
7
+ ContextObserverBase<'grid', PluginParams>, ContextObserverGridDetail {
8
+ textSizePx$: Observable<number>
9
+ }
12
10
 
13
11
  export interface ContextObserverGridDetail {
14
- gridContainer$: Observable<ContainerPosition[]>
12
+ gridContainerPosition$: Observable<GridContainerPosition[]>
15
13
  gridAxesTransform$: Observable<TransformData>
16
14
  gridAxesReverseTransform$: Observable<TransformData>
17
15
  gridGraphicTransform$: Observable<TransformData>
18
16
  gridGraphicReverseScale$: Observable<[number, number][]>
19
17
  gridAxesSize$: Observable<{ width: number; height: number; }>
20
18
  gridHighlight$: Observable<ComputedDatumGrid[]>
21
- existSeriesLabels$: Observable<string[]>
19
+ seriesLabels$: Observable<string[]>
22
20
  SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
23
21
  GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
22
+ computedLayoutData$: Observable<ComputedLayoutDataGrid>
24
23
  visibleComputedData$: Observable<ComputedDataGrid>
25
- isSeriesPositionSeprate$: Observable<boolean>
24
+ visibleComputedLayoutData$: Observable<ComputedLayoutDataGrid>
25
+ // isSeriesSeprate$: Observable<boolean>
26
+ }
27
+
28
+ export type ComputedLayoutDataGrid = ComputedLayoutDatumGrid[][]
29
+
30
+ export interface ComputedLayoutDatumGrid extends ComputedDatumGrid {
31
+ axisX: number
32
+ axisY: number
33
+ axisYFromZero: number
26
34
  }
27
35
 
28
- export interface ContainerPosition {
36
+ export interface GridContainerPosition {
29
37
  slotIndex: number
30
38
  rowIndex: number
31
39
  columnIndex: number
@@ -1,28 +1,16 @@
1
1
  import { Observable } from 'rxjs'
2
2
  import type { ContextObserverBase } from './ContextObserver'
3
3
  import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
4
- import type { ContainerPosition } from './ContextObserverGrid'
5
- import type { TransformData } from './TransformData'
4
+ import type { DataFormatterGrid } from './DataFormatterGrid'
6
5
  import type { ContextObserverGridDetail } from './ContextObserverGrid'
7
6
 
8
7
  export interface ContextObserverMultiGrid<PluginParams> extends ContextObserverBase<'multiGrid', PluginParams> {
9
8
  textSizePx$: Observable<number>
10
- multiGridEachDetail$: Observable<ContextObserverGridDetail[]>
11
- multiGridContainer$: Observable<ContainerPosition[][]>
9
+ multiGridEachDetail$: Observable<ContextObserverMultiGridDetail[]>
12
10
  }
13
11
 
14
- // export interface MultiGridObservableAll {
15
- // isSeriesPositionSeprate$: Observable<boolean>
16
- // gridContainer$: Observable<ContainerPosition[]>
17
- // gridAxesTransform$: Observable<TransformData>
18
- // gridAxesReverseTransform$: Observable<TransformData>
19
- // gridGraphicTransform$: Observable<TransformData>
20
- // gridGraphicReverseScale$: Observable<[number, number][]>
21
- // gridAxesSize$: Observable<{ width: number; height: number; }>
22
- // gridHighlight$: Observable<string[]>
23
- // existSeriesLabels$: Observable<string[]>
24
- // SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
25
- // GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
26
- // visibleComputedData$: Observable<ComputedDataGrid>
27
- // }
28
12
 
13
+ export interface ContextObserverMultiGridDetail extends ContextObserverGridDetail {
14
+ computedData$: Observable<ComputedDataGrid>
15
+ dataFormatter$: Observable<DataFormatterGrid>
16
+ }
@@ -4,6 +4,26 @@ import type { ComputedDatumSeries } from './ComputedDataSeries'
4
4
 
5
5
  export interface ContextObserverSeries<PluginParams> extends ContextObserverBase<'series', PluginParams> {
6
6
  textSizePx$: Observable<number>
7
+ separateSeries$: Observable<boolean>
8
+ visibleComputedData$: Observable<ComputedDatumSeries[][]>
9
+ computedLayoutData$: Observable<ComputedDatumSeries[][]>
10
+ visibleComputedLayoutData$: Observable<ComputedDatumSeries[][]>
7
11
  seriesHighlight$: Observable<ComputedDatumSeries[]>
12
+ seriesLabels$: Observable<string[]>
8
13
  SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
9
- }
14
+ seriesContainerPosition$: Observable<SeriesContainerPosition[]>
15
+ SeriesContainerPositionMap$: Observable<Map<string, SeriesContainerPosition>>
16
+ }
17
+
18
+ export interface SeriesContainerPosition {
19
+ slotIndex: number
20
+ rowIndex: number
21
+ columnIndex: number
22
+ // translate: [number, number]
23
+ startX: number
24
+ startY: number
25
+ centerX: number
26
+ centerY: number
27
+ width: number
28
+ height: number
29
+ }