@orbcharts/core 3.0.0-alpha.35 → 3.0.0-alpha.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. package/dist/orbcharts-core.es.js +1754 -1666
  2. package/dist/orbcharts-core.umd.js +2 -2
  3. package/dist/src/series/seriesObservables.d.ts +1 -8
  4. package/dist/src/tree/treeObservables.d.ts +13 -0
  5. package/dist/src/types/ChartParams.d.ts +1 -1
  6. package/dist/src/types/ComputedData.d.ts +13 -0
  7. package/dist/src/types/ComputedDataGrid.d.ts +2 -5
  8. package/dist/src/types/ComputedDataMultiValue.d.ts +2 -2
  9. package/dist/src/types/ComputedDataRelationship.d.ts +2 -2
  10. package/dist/src/types/ComputedDataTree.d.ts +2 -2
  11. package/dist/src/types/ContextObserverTree.d.ts +6 -0
  12. package/dist/src/types/DataFormatterMultiGrid.d.ts +1 -3
  13. package/dist/src/types/DataFormatterMultiValue.d.ts +0 -1
  14. package/dist/src/types/DataFormatterSeries.d.ts +0 -2
  15. package/dist/src/types/DataFormatterTree.d.ts +1 -0
  16. package/dist/src/types/DataMultiValue.d.ts +1 -0
  17. package/dist/src/types/DataRelationship.d.ts +1 -0
  18. package/dist/src/types/DataTree.d.ts +2 -0
  19. package/dist/src/types/Event.d.ts +9 -1
  20. package/dist/src/utils/observables.d.ts +7 -4
  21. package/package.json +1 -1
  22. package/src/base/createBaseChart.ts +0 -1
  23. package/src/defaults.ts +5 -3
  24. package/src/multiValue/computeMultiValueData.ts +7 -2
  25. package/src/relationship/computeRelationshipData.ts +3 -0
  26. package/src/series/createSeriesContextObserver.ts +1 -1
  27. package/src/series/seriesObservables.ts +8 -7
  28. package/src/tree/computeTreeData.ts +31 -9
  29. package/src/tree/createTreeContextObserver.ts +44 -0
  30. package/src/tree/treeObservables.ts +95 -0
  31. package/src/types/ChartParams.ts +1 -1
  32. package/src/types/ComputedData.ts +18 -1
  33. package/src/types/ComputedDataGrid.ts +5 -5
  34. package/src/types/ComputedDataMultiValue.ts +2 -3
  35. package/src/types/ComputedDataRelationship.ts +2 -2
  36. package/src/types/ComputedDataTree.ts +2 -2
  37. package/src/types/ContextObserverTree.ts +6 -1
  38. package/src/types/DataFormatterMultiGrid.ts +2 -2
  39. package/src/types/DataFormatterMultiValue.ts +1 -1
  40. package/src/types/DataFormatterSeries.ts +2 -2
  41. package/src/types/DataFormatterTree.ts +1 -0
  42. package/src/types/DataMultiValue.ts +1 -0
  43. package/src/types/DataRelationship.ts +1 -0
  44. package/src/types/DataTree.ts +2 -0
  45. package/src/types/Event.ts +9 -1
  46. package/src/utils/d3Utils.ts +16 -13
  47. package/src/utils/observables.ts +60 -77
@@ -1,11 +1,11 @@
1
- import type { ComputedDatumBase } from './ComputedData'
1
+ import type { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData'
2
2
 
3
3
  export type ComputedDataRelationship = {
4
4
  nodes: ComputedNode[]
5
5
  edges: ComputedEdge[]
6
6
  }
7
7
 
8
- export interface ComputedNode extends ComputedDatumBase {
8
+ export interface ComputedNode extends ComputedDatumBase, ComputedDatumCategoryValue {
9
9
  startNodes: ComputedNode[]
10
10
  startNodeIds: string[]
11
11
  endNodes: ComputedNode[]
@@ -1,4 +1,4 @@
1
- import type { ComputedDatumBase } from './ComputedData'
1
+ import type { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData'
2
2
 
3
3
  // export type ComputedDataTree = ComputedDataTreeDatum[]
4
4
 
@@ -13,7 +13,7 @@ import type { ComputedDatumBase } from './ComputedData'
13
13
  // }
14
14
 
15
15
  // 樹狀結構
16
- export interface ComputedDataTree extends ComputedDatumBase {
16
+ export interface ComputedDataTree extends ComputedDatumBase, ComputedDatumCategoryValue {
17
17
  level: number
18
18
  seq: number
19
19
  children?: ComputedDataTree[]
@@ -1,5 +1,10 @@
1
+ import { Observable } from 'rxjs'
1
2
  import type { ContextObserverBase } from './ContextObserver'
3
+ import type { ComputedDataTree } from './ComputedDataTree'
2
4
 
3
5
  export interface ContextObserverTree<PluginParams> extends ContextObserverBase<'tree', PluginParams> {
4
-
6
+ treeHighlight$: Observable<string[]>
7
+ existCategoryLabels$: Observable<string[]>
8
+ CategoryDataMap$: Observable<Map<string, ComputedDataTree[]>>
9
+ visibleComputedData$: Observable<ComputedDataTree>
5
10
  }
@@ -9,13 +9,13 @@ import type {
9
9
  import type { AxisPosition } from './Axis'
10
10
 
11
11
  export interface DataFormatterMultiGrid extends DataFormatterBase<'multiGrid'> {
12
- visibleFilter: VisibleFilter<'multiGrid'>
12
+ // visibleFilter: VisibleFilter<'multiGrid'>
13
13
  gridList: Array<DataFormatterGridGrid>
14
14
  container: DataFormatterMultiGridContainer
15
15
  }
16
16
 
17
17
  export interface DataFormatterMultiGridPartial extends DataFormatterBasePartial<'multiGrid'> {
18
- visibleFilter?: VisibleFilter<'multiGrid'>
18
+ // visibleFilter?: VisibleFilter<'multiGrid'>
19
19
  gridList?: Array<DataFormatterGridGridPartial>
20
20
  container?: Partial<DataFormatterMultiGridContainer>
21
21
  }
@@ -17,5 +17,5 @@ export interface DataFormatterMultiValuePartial extends DataFormatterBasePartial
17
17
 
18
18
  // multiValue欄位
19
19
  export interface DataFormatterMultiValueMultiValue {
20
- unitLabel: string
20
+ // unitLabel: string
21
21
  }
@@ -5,7 +5,7 @@ import { DataFormatterBase, DataFormatterBasePartial, VisibleFilter } from './Da
5
5
  export interface DataFormatterSeries extends DataFormatterBase<'series'> {
6
6
  visibleFilter: VisibleFilter<'series'>
7
7
  // series: DataFormatterSeriesSeries
8
- unitLabel: string
8
+ // unitLabel: string
9
9
  seriesLabels: string[]
10
10
  // labelFormat: (datum: DataSeriesDatum) => string
11
11
  // mapSeries: (datum: DataSeriesDatum | DataSeriesValue, rowIndex: number, columnIndex: number, context: DataFormatterContext<'series'>) => string
@@ -16,7 +16,7 @@ export interface DataFormatterSeries extends DataFormatterBase<'series'> {
16
16
 
17
17
  export interface DataFormatterSeriesPartial extends DataFormatterBasePartial<'series'> {
18
18
  // series: Partial<DataFormatterSeriesSeries>
19
- unitLabel?: string
19
+ // unitLabel?: string
20
20
  seriesLabels?: string[]
21
21
  // colorsPredicate?: (datum: DataSeriesDatum | DataSeriesValue, rowIndex: number, columnIndex: number, context: DataFormatterContext<'series'>) => string
22
22
  sort?: ((a: DataSeriesDatum | DataSeriesValue, b: DataSeriesDatum | number) => number) | null
@@ -6,6 +6,7 @@ export interface DataFormatterTree
6
6
  visibleFilter: VisibleFilter<'tree'>
7
7
  // labelFormat: (datum: unknown) => string
8
8
  // descriptionFormat: (datum: unknown) => string
9
+ categoryLabels: string[]
9
10
  }
10
11
 
11
12
  export type DataFormatterTreePartial = Partial<DataFormatterTree>
@@ -6,6 +6,7 @@ export type DataMultiValue = (DataMultiValueDatum | DataMultiValueValue)[][]
6
6
  export type DataMultiValueValue = number
7
7
 
8
8
  export interface DataMultiValueDatum extends DatumBase, DatumValue {
9
+ categoryLabel?: string
9
10
  }
10
11
 
11
12
 
@@ -18,6 +18,7 @@ export type DataRelationshipList = [
18
18
  export interface Node extends DatumBase {
19
19
  id: string
20
20
  value?: number
21
+ categoryLabel?: string
21
22
  }
22
23
 
23
24
  export interface Edge extends DatumBase {
@@ -7,6 +7,7 @@ export interface DataTreeObj extends DatumBase {
7
7
  id: string
8
8
  value?: number
9
9
  children?: DataTreeObj[]
10
+ categoryLabel?: string
10
11
  }
11
12
 
12
13
  // 陣列資料
@@ -14,5 +15,6 @@ export interface DataTreeDatum extends DatumBase {
14
15
  id: string
15
16
  value?: number
16
17
  parent?: string
18
+ categoryLabel?: string
17
19
  }
18
20
 
@@ -5,7 +5,7 @@ import type { ComputedDataSeries, ComputedDatumSeries } from './ComputedDataSeri
5
5
  import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
6
6
  import type { ComputedDataMultiGrid } from './ComputedDataMultiGrid'
7
7
  import type { ComputedDataMultiValue, ComputedDatumMultiValue } from './ComputedDataMultiValue'
8
- import type { ComputedNode } from './ComputedDataRelationship'
8
+ import type { ComputedDataRelationship, ComputedNode } from './ComputedDataRelationship'
9
9
  import type { ComputedDataTree } from './ComputedDataTree'
10
10
  import type { HighlightTarget } from './ChartParams'
11
11
 
@@ -104,11 +104,19 @@ export interface EventMultiValue extends EventBase {
104
104
 
105
105
  export interface EventRelationship extends EventBase {
106
106
  type: 'relationship'
107
+ data: ComputedDataRelationship
108
+ category: ComputedNode[]
109
+ categoryIndex: number
110
+ categoryLabel: string
107
111
  datum: ComputedNode | null
108
112
  }
109
113
 
110
114
  export interface EventTree extends EventBase {
111
115
  type: 'tree'
116
+ data: ComputedDataTree
117
+ category: ComputedDataTree[]
118
+ categoryIndex: number
119
+ categoryLabel: string
112
120
  datum: ComputedDataTree | null
113
121
  }
114
122
 
@@ -16,24 +16,20 @@ export const createAxisLinearScale = ({
16
16
  scaleRange: [number, number] // 0-1
17
17
  }) => {
18
18
 
19
+ // -- 無值補上預設值 --
19
20
  const domainMin: number | 'auto' = scaleDomain[0] ?? DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
20
21
  const domainMax: number | 'auto' = scaleDomain[1] ?? DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
21
22
  const rangeMin: number = scaleRange[0] ?? DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
22
23
  const rangeMax: number = scaleRange[1] ?? DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
23
24
 
24
- // const _minValue = domainMin === 'auto' ? minValue : domainMin
25
- // const domainMinValue: number = maxValue - (maxValue - _minValue) / (1 - rangeMin)
26
- // const _maxValue = domainMax === 'auto' ? maxValue : domainMax
27
- // const domainMaxValue: number = _maxValue / rangeMax
28
-
29
- // return d3.scaleLinear()
30
- // .domain([domainMinValue, domainMaxValue])
31
- // .range([0, axisWidth])
32
-
25
+ // -- 'auto'提換成實際值 --
33
26
  const domainMinValue = domainMin === 'auto' ? minValue : domainMin
34
27
  const domainMaxValue = domainMax === 'auto' ? maxValue : domainMax
35
- let rangeMinValue = axisWidth * rangeMin
36
- let rangeMaxValue = axisWidth * rangeMax
28
+
29
+ // let rangeMinValue = axisWidth * rangeMin
30
+ // let rangeMaxValue = axisWidth * rangeMax
31
+
32
+ // -- 計算padding --
37
33
  // if (padding > 0) {
38
34
  // const stepAmount = maxValue - minValue + (padding * 2)
39
35
  // const eachStepWidth = axisWidth / stepAmount
@@ -41,10 +37,17 @@ export const createAxisLinearScale = ({
41
37
  // rangeMinValue += paddingWidth
42
38
  // rangeMaxValue -= paddingWidth
43
39
  // }
40
+
41
+ // -- 依場景大小換算 --
42
+ const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
43
+ const axisDomainMaxValue = domainMaxValue / rangeMax
44
44
 
45
+ // return d3.scaleLinear()
46
+ // .domain([domainMinValue, domainMaxValue])
47
+ // .range([rangeMinValue, rangeMaxValue])
45
48
  return d3.scaleLinear()
46
- .domain([domainMinValue, domainMaxValue])
47
- .range([rangeMinValue, rangeMaxValue])
49
+ .domain([axisDomainMinValue, axisDomainMaxValue])
50
+ .range([0, axisWidth])
48
51
  }
49
52
 
50
53
  // scalePoint - 非連續資料對應到比例尺座標上
@@ -27,8 +27,9 @@ import type {
27
27
  // groupLabel?: string // 要符合每一種computedData所以不一定會有groupLabel
28
28
  // }
29
29
 
30
+ // 通用 highlight Observable
30
31
  export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
31
- datumList$: Observable<ComputedDatumTypeMap<'series' | 'grid'>[]>
32
+ datumList$: Observable<ComputedDatumTypeMap<'series' | 'grid' | 'multiValue' | 'relationship' | 'tree'>[]>
32
33
  fullChartParams$: Observable<ChartParams>
33
34
  event$: Subject<any>
34
35
  }): Observable<string[]> => {
@@ -42,6 +43,7 @@ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
42
43
  id: null,
43
44
  seriesLabel: null,
44
45
  groupLabel: null,
46
+ categoryLabel: null,
45
47
  highlightDefault: d.highlightDefault
46
48
  }
47
49
  }),
@@ -59,12 +61,14 @@ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
59
61
  id: (d.datum as any).id,
60
62
  seriesLabel: (d.datum as any).seriesLabel,
61
63
  groupLabel: (d.datum as any).groupLabel,
64
+ categoryLabel: (d.datum as any).categoryLabel,
62
65
  highlightDefault: null
63
66
  }
64
67
  : {
65
68
  id: null,
66
69
  seriesLabel: null,
67
70
  groupLabel: null,
71
+ categoryLabel: null,
68
72
  highlightDefault: null
69
73
  }
70
74
  })
@@ -79,68 +83,28 @@ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
79
83
  switchMap(d => highlightDefault$)
80
84
  )
81
85
 
82
- const getHighlightIds = ({ data, id, seriesLabel, groupLabel, highlightDefault, target }: {
83
- data: ComputedDatumTypeMap<'series' | 'grid'>[]
84
- id: string | null
85
- seriesLabel: string | null
86
- groupLabel: string | null
87
- highlightDefault: string | null
88
- target: HighlightTarget
89
- }) => {
90
- let ids: string[] = []
91
- // if (id) {
92
- // ids.push(id)
93
- // }
94
- // if (label) {
95
- // if (target === 'group') {
96
- // const _ids = data.flat()
97
- // .filter(d => {
98
- // return d.groupLabel === label
99
- // || d.label === label
100
- // })
101
- // .map(d => d.id)
102
- // ids = ids.concat(_ids)
103
- // } else if (target === 'series') {
104
- // const _ids = data.flat()
105
- // .filter(d => {
106
- // return d.seriesLabel === label
107
- // || d.label === label
108
- // })
109
- // .map(d => d.id)
110
- // ids = ids.concat(_ids)
111
- // }
112
- // }
113
- // 依highlightDefault找到id/seriesLabel/groupLabel
114
- if (highlightDefault != null && highlightDefault != '') {
115
- if (target === 'datum') {
116
- id = highlightDefault
117
- } else if (target === 'series') {
118
- const datum = data.flat().find(d => d.id === highlightDefault || d.seriesLabel === highlightDefault)
119
- seriesLabel = (datum && datum.seriesLabel) ? datum.seriesLabel : null
120
- } else if (target === 'group') {
121
- const datum = data.flat().find(d => d.id === highlightDefault || (d as ComputedDatumTypeMap<"grid">).groupLabel === highlightDefault)
122
- groupLabel = (datum && (datum as ComputedDatumTypeMap<"grid">).groupLabel) ? (datum as ComputedDatumTypeMap<"grid">).groupLabel : null
123
- }
124
- }
125
- if (target === 'datum' && id != null && id != '') {
126
- ids.push(id)
127
- } else if (target === 'series' && seriesLabel != null && seriesLabel != '') {
128
- const _ids = data.flat()
129
- .filter(d => {
130
- return d.seriesLabel === seriesLabel
131
- })
132
- .map(d => d.id)
133
- ids = ids.concat(_ids)
134
- } else if (target === 'group' && groupLabel != null && groupLabel != '') {
135
- const _ids = data.flat()
136
- .filter(d => {
137
- return (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel
138
- })
139
- .map(d => d.id)
140
- ids = ids.concat(_ids)
141
- }
86
+ function getDatumIds (datumList: ComputedDatumTypeMap<'series' | 'grid' | 'multiValue' | 'relationship' | 'tree'>[], id: string | null) {
87
+ return id == null
88
+ ? []
89
+ : datumList.find(d => d.id === id) ? [id] : []
90
+ }
142
91
 
143
- return ids
92
+ function getSeriesIds (datumList: ComputedDatumTypeMap<'series' | 'grid'>[], seriesLabel: string | null) {
93
+ return seriesLabel == null
94
+ ? datumList.filter(d => d.seriesLabel === seriesLabel).map(d => d.id)
95
+ : []
96
+ }
97
+
98
+ function getGroupIds (datumList: ComputedDatumTypeMap<'grid'>[], groupLabel: string | null) {
99
+ return groupLabel == null
100
+ ? datumList.filter(d => (d as ComputedDatumTypeMap<"grid">).groupLabel === groupLabel).map(d => d.id)
101
+ : []
102
+ }
103
+
104
+ function getCategoryIds (datumList: ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>[], categoryLabel: string | null) {
105
+ return categoryLabel == null
106
+ ? []
107
+ : datumList.filter(d => (d as ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">).categoryLabel === categoryLabel).map(d => d.id)
144
108
  }
145
109
 
146
110
  return new Observable<string[]>(subscriber => {
@@ -149,16 +113,19 @@ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
149
113
  datumList: datumList$,
150
114
  fullChartParams: fullChartParams$,
151
115
  }).pipe(
152
- takeUntil(destroy$)
116
+ takeUntil(destroy$),
117
+ switchMap(async d => d)
153
118
  ).subscribe(data => {
154
- const ids = getHighlightIds({
155
- data: data.datumList,
156
- id: data.target.id,
157
- seriesLabel: data.target.seriesLabel,
158
- groupLabel: data.target.groupLabel,
159
- highlightDefault: data.target.highlightDefault,
160
- target: data.fullChartParams.highlightTarget,
161
- })
119
+ let ids: string[] = []
120
+ if (data.fullChartParams.highlightTarget === 'datum') {
121
+ ids = getDatumIds(data.datumList, data.target.id)
122
+ } else if (data.fullChartParams.highlightTarget === 'series') {
123
+ ids = getSeriesIds(data.datumList as ComputedDatumTypeMap<'series' | 'grid'>[], data.target.seriesLabel)
124
+ } else if (data.fullChartParams.highlightTarget === 'group') {
125
+ ids = getGroupIds(data.datumList as ComputedDatumTypeMap<'grid'>[], data.target.groupLabel)
126
+ } else if (data.fullChartParams.highlightTarget === 'category') {
127
+ ids = getCategoryIds(data.datumList as ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>[], data.target.categoryLabel)
128
+ }
162
129
  subscriber.next(ids)
163
130
  })
164
131
 
@@ -168,31 +135,47 @@ export const highlightObservable = ({ datumList$, fullChartParams$, event$ }: {
168
135
  })
169
136
  }
170
137
 
171
- export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<ChartType>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
138
+ export const seriesDataMapObservable = <DatumType extends ComputedDatumTypeMap<'series' | 'grid'>>({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
172
139
  return datumList$.pipe(
173
140
  map(data => {
174
141
  const SeriesDataMap: Map<string, DatumType[]> = new Map()
175
142
  data.forEach(d => {
176
- const seriesData = SeriesDataMap.get((d as ComputedDatumTypeMap<'series' | 'grid'>).seriesLabel) ?? []
143
+ const seriesData = SeriesDataMap.get(d.seriesLabel) ?? []
177
144
  seriesData.push(d)
178
- SeriesDataMap.set((d as ComputedDatumTypeMap<'series' | 'grid'>).seriesLabel, seriesData)
145
+ SeriesDataMap.set(d.seriesLabel, seriesData)
179
146
  })
180
147
  return SeriesDataMap
181
148
  })
182
149
  )
183
150
  }
184
151
 
185
- export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<ChartType>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
152
+ export const groupDataMapObservable = <DatumType extends ComputedDatumTypeMap<'grid'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
186
153
  return datumList$.pipe(
187
154
  map(data => {
188
155
  const GroupDataMap: Map<string, DatumType[]> = new Map()
189
156
  data.forEach(d => {
190
- const groupData = GroupDataMap.get((d as ComputedDatumTypeMap<'grid'>).groupLabel) ?? []
157
+ const groupData = GroupDataMap.get(d.groupLabel) ?? []
191
158
  groupData.push(d)
192
- GroupDataMap.set((d as ComputedDatumTypeMap<'grid'>).groupLabel, groupData)
159
+ GroupDataMap.set(d.groupLabel, groupData)
193
160
  })
194
161
  return GroupDataMap
195
162
  })
196
163
  )
197
164
  }
198
165
 
166
+ export const categoryDataMapObservable = <DatumType extends ComputedDatumTypeMap<'multiValue' | 'relationship' | 'tree'>> ({ datumList$ }: { datumList$: Observable<DatumType[]> }) => {
167
+ return datumList$.pipe(
168
+ map(data => {
169
+ const GroupDataMap: Map<string, DatumType[]> = new Map()
170
+ data
171
+ .filter(d => d.categoryLabel != null)
172
+ .forEach(d => {
173
+ const groupData = GroupDataMap.get(d.categoryLabel) ?? []
174
+ groupData.push(d)
175
+ GroupDataMap.set(d.categoryLabel, groupData)
176
+ })
177
+ return GroupDataMap
178
+ })
179
+ )
180
+ }
181
+