@orbcharts/core 3.0.0-alpha.21
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/.gitignore +23 -0
- package/LICENSE +201 -0
- package/dist/orbcharts-core.es.js +5096 -0
- package/dist/orbcharts-core.umd.js +3 -0
- package/dist/src/AbstractChart.d.ts +17 -0
- package/dist/src/GridChart.d.ts +6 -0
- package/dist/src/MultiGridChart.d.ts +6 -0
- package/dist/src/MultiValueChart.d.ts +6 -0
- package/dist/src/RelationshipChart.d.ts +6 -0
- package/dist/src/SeriesChart.d.ts +6 -0
- package/dist/src/TreeChart.d.ts +6 -0
- package/dist/src/base/createBaseChart.d.ts +3 -0
- package/dist/src/base/createBasePlugin.d.ts +3 -0
- package/dist/src/defaults.d.ts +37 -0
- package/dist/src/defineGridPlugin.d.ts +1 -0
- package/dist/src/defineMultiGridPlugin.d.ts +1 -0
- package/dist/src/defineMultiValuePlugin.d.ts +1 -0
- package/dist/src/defineNoneDataPlugin.d.ts +1 -0
- package/dist/src/defineRelationshipPlugin.d.ts +1 -0
- package/dist/src/defineSeriesPlugin.d.ts +1 -0
- package/dist/src/defineTreePlugin.d.ts +1 -0
- package/dist/src/grid/computeGridData.d.ts +3 -0
- package/dist/src/grid/createGridContextObserver.d.ts +3 -0
- package/dist/src/grid/gridObservables.d.ts +25 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/multiGrid/computeMultiGridData.d.ts +3 -0
- package/dist/src/multiGrid/createMultiGridContextObserver.d.ts +3 -0
- package/dist/src/multiGrid/multiGridObservables.d.ts +0 -0
- package/dist/src/multiValue/computeMultiValueData.d.ts +3 -0
- package/dist/src/multiValue/createMultiValueContextObserver.d.ts +3 -0
- package/dist/src/multiValue/multiValueObservables.d.ts +0 -0
- package/dist/src/relationship/computeRelationshipData.d.ts +3 -0
- package/dist/src/relationship/createRelationshipContextObserver.d.ts +3 -0
- package/dist/src/relationship/relationshipObservables.d.ts +0 -0
- package/dist/src/series/computeSeriesData.d.ts +3 -0
- package/dist/src/series/createSeriesContextObserver.d.ts +3 -0
- package/dist/src/series/seriesObservables.d.ts +8 -0
- package/dist/src/tree/computeTreeData.d.ts +3 -0
- package/dist/src/tree/createTreeContextObserver.d.ts +3 -0
- package/dist/src/tree/treeObservables.d.ts +0 -0
- package/dist/src/types/Axis.d.ts +1 -0
- package/dist/src/types/Chart.d.ts +41 -0
- package/dist/src/types/ChartParams.d.ts +36 -0
- package/dist/src/types/ComputedData.d.ts +28 -0
- package/dist/src/types/ComputedDataGrid.d.ts +10 -0
- package/dist/src/types/ComputedDataMultiGrid.d.ts +3 -0
- package/dist/src/types/ComputedDataMultiValue.d.ts +6 -0
- package/dist/src/types/ComputedDataRelationship.d.ts +18 -0
- package/dist/src/types/ComputedDataSeries.d.ts +6 -0
- package/dist/src/types/ComputedDataTree.d.ts +7 -0
- package/dist/src/types/ContextObserver.d.ts +28 -0
- package/dist/src/types/ContextObserverGrid.d.ts +18 -0
- package/dist/src/types/ContextObserverMultiGrid.d.ts +4 -0
- package/dist/src/types/ContextObserverMultiValue.d.ts +4 -0
- package/dist/src/types/ContextObserverRelationship.d.ts +4 -0
- package/dist/src/types/ContextObserverSeries.d.ts +8 -0
- package/dist/src/types/ContextObserverTree.d.ts +4 -0
- package/dist/src/types/ContextSubject.d.ts +15 -0
- package/dist/src/types/Data.d.ts +19 -0
- package/dist/src/types/DataFormatter.d.ts +40 -0
- package/dist/src/types/DataFormatterGrid.d.ts +20 -0
- package/dist/src/types/DataFormatterMultiGrid.d.ts +16 -0
- package/dist/src/types/DataFormatterMultiValue.d.ts +13 -0
- package/dist/src/types/DataFormatterRelationship.d.ts +5 -0
- package/dist/src/types/DataFormatterSeries.d.ts +10 -0
- package/dist/src/types/DataFormatterTree.d.ts +5 -0
- package/dist/src/types/DataGrid.d.ts +6 -0
- package/dist/src/types/DataMultiGrid.d.ts +6 -0
- package/dist/src/types/DataMultiValue.d.ts +6 -0
- package/dist/src/types/DataRelationship.d.ts +20 -0
- package/dist/src/types/DataSeries.d.ts +6 -0
- package/dist/src/types/DataTree.d.ts +13 -0
- package/dist/src/types/Event.d.ts +64 -0
- package/dist/src/types/Layout.d.ts +8 -0
- package/dist/src/types/Padding.d.ts +6 -0
- package/dist/src/types/Plugin.d.ts +37 -0
- package/dist/src/types/TransformData.d.ts +8 -0
- package/dist/src/types/index.d.ts +37 -0
- package/dist/src/utils/commonUtils.d.ts +8 -0
- package/dist/src/utils/d3Utils.d.ts +25 -0
- package/dist/src/utils/index.d.ts +4 -0
- package/dist/src/utils/observables.d.ts +14 -0
- package/dist/src/utils/orbchartsUtils.d.ts +20 -0
- package/dist/vite.config.d.ts +2 -0
- package/package.json +40 -0
- package/src/AbstractChart.ts +48 -0
- package/src/GridChart.ts +21 -0
- package/src/MultiGridChart.ts +21 -0
- package/src/MultiValueChart.ts +21 -0
- package/src/RelationshipChart.ts +21 -0
- package/src/SeriesChart.ts +21 -0
- package/src/TreeChart.ts +21 -0
- package/src/base/createBaseChart.ts +329 -0
- package/src/base/createBasePlugin.ts +89 -0
- package/src/defaults.ts +229 -0
- package/src/defineGridPlugin.ts +3 -0
- package/src/defineMultiGridPlugin.ts +3 -0
- package/src/defineMultiValuePlugin.ts +3 -0
- package/src/defineNoneDataPlugin.ts +4 -0
- package/src/defineRelationshipPlugin.ts +3 -0
- package/src/defineSeriesPlugin.ts +3 -0
- package/src/defineTreePlugin.ts +3 -0
- package/src/grid/computeGridData.ts +192 -0
- package/src/grid/createGridContextObserver.ts +91 -0
- package/src/grid/gridObservables.ts +359 -0
- package/src/index.ts +21 -0
- package/src/multiGrid/computeMultiGridData.ts +48 -0
- package/src/multiGrid/createMultiGridContextObserver.ts +12 -0
- package/src/multiGrid/multiGridObservables.ts +0 -0
- package/src/multiValue/computeMultiValueData.ts +127 -0
- package/src/multiValue/createMultiValueContextObserver.ts +12 -0
- package/src/multiValue/multiValueObservables.ts +0 -0
- package/src/relationship/computeRelationshipData.ts +101 -0
- package/src/relationship/createRelationshipContextObserver.ts +12 -0
- package/src/relationship/relationshipObservables.ts +0 -0
- package/src/series/computeSeriesData.ts +154 -0
- package/src/series/createSeriesContextObserver.ts +33 -0
- package/src/series/seriesObservables.ts +23 -0
- package/src/tree/computeTreeData.ts +104 -0
- package/src/tree/createTreeContextObserver.ts +12 -0
- package/src/tree/treeObservables.ts +0 -0
- package/src/types/Axis.ts +1 -0
- package/src/types/Chart.ts +46 -0
- package/src/types/ChartParams.ts +50 -0
- package/src/types/ComputedData.ts +66 -0
- package/src/types/ComputedDataGrid.ts +12 -0
- package/src/types/ComputedDataMultiGrid.ts +3 -0
- package/src/types/ComputedDataMultiValue.ts +10 -0
- package/src/types/ComputedDataRelationship.ts +20 -0
- package/src/types/ComputedDataSeries.ts +8 -0
- package/src/types/ComputedDataTree.ts +20 -0
- package/src/types/ContextObserver.ts +38 -0
- package/src/types/ContextObserverGrid.ts +16 -0
- package/src/types/ContextObserverMultiGrid.ts +5 -0
- package/src/types/ContextObserverMultiValue.ts +5 -0
- package/src/types/ContextObserverRelationship.ts +5 -0
- package/src/types/ContextObserverSeries.ts +8 -0
- package/src/types/ContextObserverTree.ts +5 -0
- package/src/types/ContextSubject.ts +18 -0
- package/src/types/Data.ts +45 -0
- package/src/types/DataFormatter.ts +99 -0
- package/src/types/DataFormatterGrid.ts +40 -0
- package/src/types/DataFormatterMultiGrid.ts +23 -0
- package/src/types/DataFormatterMultiValue.ts +19 -0
- package/src/types/DataFormatterRelationship.ts +23 -0
- package/src/types/DataFormatterSeries.ts +26 -0
- package/src/types/DataFormatterTree.ts +10 -0
- package/src/types/DataGrid.ts +11 -0
- package/src/types/DataMultiGrid.ts +7 -0
- package/src/types/DataMultiValue.ts +11 -0
- package/src/types/DataRelationship.ts +27 -0
- package/src/types/DataSeries.ts +11 -0
- package/src/types/DataTree.ts +18 -0
- package/src/types/Event.ts +114 -0
- package/src/types/Layout.ts +12 -0
- package/src/types/Padding.ts +6 -0
- package/src/types/Plugin.ts +60 -0
- package/src/types/TransformData.ts +8 -0
- package/src/types/index.ts +37 -0
- package/src/utils/commonUtils.ts +50 -0
- package/src/utils/d3Utils.ts +87 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/observables.ts +198 -0
- package/src/utils/orbchartsUtils.ts +150 -0
- package/tsconfig.json +14 -0
- package/vite.config.js +45 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ContextObserverFn } from '../types'
|
|
2
|
+
|
|
3
|
+
export const createRelationshipContextObserver: ContextObserverFn<'relationship'> = ({ subject, observer }) => {
|
|
4
|
+
|
|
5
|
+
return {
|
|
6
|
+
fullParams$: observer.fullParams$,
|
|
7
|
+
fullChartParams$: observer.fullChartParams$,
|
|
8
|
+
fullDataFormatter$: observer.fullDataFormatter$,
|
|
9
|
+
computedData$: observer.computedData$,
|
|
10
|
+
layout$: observer.layout$,
|
|
11
|
+
}
|
|
12
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { DataSeries, DataSeriesDatum } from '../types/DataSeries'
|
|
2
|
+
import type { ComputedDataFn } from '../types/ComputedData'
|
|
3
|
+
import type { ComputedDataSeries, ComputedDatumSeries } from '../types/ComputedDataSeries'
|
|
4
|
+
import { formatValueToLabel, createDefaultDatumId, createDefaultSeriesLabel } from '../utils/orbchartsUtils'
|
|
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
|
+
export const computeSeriesData: ComputedDataFn<'series'> = (context) => {
|
|
59
|
+
const { data = [], dataFormatter, chartParams } = context
|
|
60
|
+
if (!data.length) {
|
|
61
|
+
return []
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const computedDataSeries: ComputedDatumSeries[] = []
|
|
65
|
+
|
|
66
|
+
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
|
+
|
|
88
|
+
// const seriesColors = chartParams.colors[chartParams.colorScheme].series
|
|
89
|
+
|
|
90
|
+
const createComputedDatumSeries = (detailData: number | DataSeriesDatum, rowIndex: number, columnIndex: number, currentIndex: number, sortedIndex: number): ComputedDatumSeries => {
|
|
91
|
+
const defaultId = createDefaultDatumId(dataFormatter.type, rowIndex, columnIndex)
|
|
92
|
+
// const seriesLabel = dataFormatter.mapSeries(detailData, rowIndex, columnIndex, context)
|
|
93
|
+
const seriesLabel = dataFormatter.seriesLabels[rowIndex] || createDefaultSeriesLabel('series', rowIndex)
|
|
94
|
+
// const color = seriesColors[rowIndex]
|
|
95
|
+
const color = dataFormatter.colorsPredicate(detailData, rowIndex, columnIndex, context)
|
|
96
|
+
const visible = dataFormatter.visibleFilter(detailData, rowIndex, columnIndex, context)
|
|
97
|
+
if (typeof detailData === 'number') {
|
|
98
|
+
return {
|
|
99
|
+
id: defaultId,
|
|
100
|
+
index: currentIndex,
|
|
101
|
+
sortedIndex,
|
|
102
|
+
label: defaultId,
|
|
103
|
+
tooltipContent: dataFormatter.tooltipContentFormat(detailData, rowIndex, columnIndex, context),
|
|
104
|
+
data: {},
|
|
105
|
+
value: detailData,
|
|
106
|
+
// valueLabel: formatValueToLabel(detailData, dataFormatter.valueFormat),
|
|
107
|
+
seriesIndex: rowIndex,
|
|
108
|
+
seriesLabel,
|
|
109
|
+
color,
|
|
110
|
+
visible
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
return {
|
|
114
|
+
id: detailData.id ? detailData.id : defaultId,
|
|
115
|
+
index: currentIndex,
|
|
116
|
+
sortedIndex,
|
|
117
|
+
label: detailData.label ? detailData.label : defaultId,
|
|
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,
|
|
123
|
+
seriesLabel,
|
|
124
|
+
color,
|
|
125
|
+
visible
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
data.forEach((mainData, rowIndex) => {
|
|
132
|
+
if (Array.isArray(mainData)) {
|
|
133
|
+
mainData.forEach((detailData, columnIndex) => {
|
|
134
|
+
const sortedIndex = getSortedIndex(computedDataSeries, rowIndex, columnIndex)
|
|
135
|
+
const datum = createComputedDatumSeries(detailData, rowIndex, columnIndex, computedDataSeries.length, sortedIndex)
|
|
136
|
+
computedDataSeries.push(datum)
|
|
137
|
+
})
|
|
138
|
+
} else {
|
|
139
|
+
const sortedIndex = getSortedIndex(computedDataSeries, rowIndex, 0)
|
|
140
|
+
const datum = createComputedDatumSeries(mainData, rowIndex, 0, computedDataSeries.length, sortedIndex) // 只有一維陣列所以columnIndex為0
|
|
141
|
+
computedDataSeries.push(datum)
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// if (dataFormatter.sort != null) {
|
|
146
|
+
// computedDataSeries.sort((a, b) => a.sortedIndex - b.sortedIndex)
|
|
147
|
+
// }
|
|
148
|
+
} catch (e) {
|
|
149
|
+
// console.error(e)
|
|
150
|
+
throw Error(e)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return computedDataSeries
|
|
154
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { shareReplay } from 'rxjs'
|
|
2
|
+
import type { ContextObserverFn } from '../types'
|
|
3
|
+
import {
|
|
4
|
+
highlightObservable,
|
|
5
|
+
seriesDataMapObservable,
|
|
6
|
+
groupDataMapObservable } from '../utils/observables'
|
|
7
|
+
|
|
8
|
+
export const createSeriesContextObserver: ContextObserverFn<'series'> = ({ subject, observer }) => {
|
|
9
|
+
|
|
10
|
+
const seriesHighlight$ = highlightObservable({
|
|
11
|
+
datumList$: observer.computedData$,
|
|
12
|
+
fullChartParams$: observer.fullChartParams$,
|
|
13
|
+
event$: subject.event$
|
|
14
|
+
}).pipe(
|
|
15
|
+
shareReplay(1)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
const SeriesDataMap$ = seriesDataMapObservable({
|
|
19
|
+
datumList$: observer.computedData$
|
|
20
|
+
}).pipe(
|
|
21
|
+
shareReplay(1)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
fullParams$: observer.fullParams$,
|
|
26
|
+
fullChartParams$: observer.fullChartParams$,
|
|
27
|
+
fullDataFormatter$: observer.fullDataFormatter$,
|
|
28
|
+
computedData$: observer.computedData$,
|
|
29
|
+
layout$: observer.layout$,
|
|
30
|
+
seriesHighlight$,
|
|
31
|
+
SeriesDataMap$
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
combineLatest,
|
|
3
|
+
distinctUntilChanged,
|
|
4
|
+
filter,
|
|
5
|
+
map,
|
|
6
|
+
merge,
|
|
7
|
+
takeUntil,
|
|
8
|
+
shareReplay,
|
|
9
|
+
switchMap,
|
|
10
|
+
Subject,
|
|
11
|
+
Observable } from 'rxjs'
|
|
12
|
+
import type {
|
|
13
|
+
ChartParams,
|
|
14
|
+
ComputedDataTypeMap } from '../types'
|
|
15
|
+
import { highlightObservable } from '../utils/observables'
|
|
16
|
+
|
|
17
|
+
export const seriesHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
|
|
18
|
+
computedData$: Observable<ComputedDataTypeMap<'series'>>
|
|
19
|
+
fullChartParams$: Observable<ChartParams>
|
|
20
|
+
event$: Subject<any>
|
|
21
|
+
}): Observable<string[]> => {
|
|
22
|
+
return highlightObservable ({ datumList$: computedData$, fullChartParams$, event$ })
|
|
23
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { DataTree, DataTreeObj, DataTreeDatum } from '../types/DataTree'
|
|
2
|
+
import type { ComputedDataFn } from '../types/ComputedData'
|
|
3
|
+
import type { ComputedDataTree } from '../types/ComputedDataTree'
|
|
4
|
+
import { isObject } from '../utils/commonUtils'
|
|
5
|
+
|
|
6
|
+
export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
|
|
7
|
+
const { data = [], dataFormatter, chartParams } = context
|
|
8
|
+
|
|
9
|
+
let computedBranchData: ComputedDataTree = {
|
|
10
|
+
id: '',
|
|
11
|
+
index: 0,
|
|
12
|
+
label: '',
|
|
13
|
+
visible: true,
|
|
14
|
+
tooltipContent: '',
|
|
15
|
+
data: {},
|
|
16
|
+
value: 0,
|
|
17
|
+
level: 0,
|
|
18
|
+
seq: 0,
|
|
19
|
+
children: []
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// 建立樹狀結構資料
|
|
24
|
+
const dataTreeObj: DataTreeObj = (function () {
|
|
25
|
+
if (isObject(data) === true) {
|
|
26
|
+
// 原本就是樹狀結構則直接複製
|
|
27
|
+
return structuredClone(data) as DataTreeObj
|
|
28
|
+
} else if (Array.isArray(data) === false) {
|
|
29
|
+
return {
|
|
30
|
+
id: ''
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// -- 陣列格式轉物件 --
|
|
34
|
+
// let rootId = ''
|
|
35
|
+
let root: DataTreeDatum | undefined = undefined
|
|
36
|
+
// const DataMap: Map<string, DataTreeDatum> = new Map()
|
|
37
|
+
const ChildrenMap: Map<string, DataTreeDatum[]> = new Map()
|
|
38
|
+
;(data as DataTreeDatum[]).forEach(d => {
|
|
39
|
+
// DataMap.set(d.id, d)
|
|
40
|
+
|
|
41
|
+
if (!d.parent) {
|
|
42
|
+
// rootId = d.id
|
|
43
|
+
root = d
|
|
44
|
+
} else {
|
|
45
|
+
const children: DataTreeDatum[] = ChildrenMap.get(d.parent) ?? []
|
|
46
|
+
children.push(d)
|
|
47
|
+
ChildrenMap.set(d.parent!, children)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const createBranchData = (root: DataTreeDatum): DataTreeObj => {
|
|
52
|
+
return {
|
|
53
|
+
id: root.id,
|
|
54
|
+
label: root.label,
|
|
55
|
+
data: root.data,
|
|
56
|
+
tooltipContent: root.tooltipContent,
|
|
57
|
+
value: root.value,
|
|
58
|
+
children: (ChildrenMap.get(root.id) ?? []).map(d => {
|
|
59
|
+
// 遞迴
|
|
60
|
+
return createBranchData(d)
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (root) {
|
|
65
|
+
return createBranchData(root)
|
|
66
|
+
} else {
|
|
67
|
+
return {
|
|
68
|
+
id: ''
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
})()
|
|
72
|
+
|
|
73
|
+
let index = 0
|
|
74
|
+
|
|
75
|
+
const formatBranchData = (branchRoot: DataTreeObj, level: number, seq: number): ComputedDataTree => {
|
|
76
|
+
const childLayer = level + 1
|
|
77
|
+
const visible = dataFormatter.visibleFilter(branchRoot, level, seq, context)
|
|
78
|
+
const currentIndex = index
|
|
79
|
+
index++
|
|
80
|
+
return {
|
|
81
|
+
id: branchRoot.id,
|
|
82
|
+
index: currentIndex,
|
|
83
|
+
level,
|
|
84
|
+
seq,
|
|
85
|
+
label: branchRoot.label ?? '',
|
|
86
|
+
data: branchRoot.data ?? {},
|
|
87
|
+
tooltipContent: branchRoot.tooltipContent ? branchRoot.tooltipContent : dataFormatter.tooltipContentFormat(branchRoot, level, seq, context),
|
|
88
|
+
value: branchRoot.value,
|
|
89
|
+
visible,
|
|
90
|
+
children: (branchRoot.children ?? []).map((d, i) => {
|
|
91
|
+
// 遞迴
|
|
92
|
+
return formatBranchData(d, childLayer, i)
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
computedBranchData = formatBranchData(dataTreeObj, 0, 0)
|
|
97
|
+
} catch (e) {
|
|
98
|
+
// console.error(e)
|
|
99
|
+
throw Error(e)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return computedBranchData
|
|
103
|
+
|
|
104
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ContextObserverFn } from '../types'
|
|
2
|
+
|
|
3
|
+
export const createTreeContextObserver: ContextObserverFn<'tree'> = ({ subject, observer }) => {
|
|
4
|
+
|
|
5
|
+
return {
|
|
6
|
+
fullParams$: observer.fullParams$,
|
|
7
|
+
fullChartParams$: observer.fullChartParams$,
|
|
8
|
+
fullDataFormatter$: observer.fullDataFormatter$,
|
|
9
|
+
computedData$: observer.computedData$,
|
|
10
|
+
layout$: observer.layout$,
|
|
11
|
+
}
|
|
12
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AxisPosition = 'top' | 'bottom' | 'left' | 'right'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ChartParams, ChartParamsPartial } from './ChartParams'
|
|
2
|
+
import type { ContextSubject } from './ContextSubject'
|
|
3
|
+
import type { ContextObserverFn } from './ContextObserver'
|
|
4
|
+
import type { ComputedDataFn } from './ComputedData'
|
|
5
|
+
import type { DataFormatterTypeMap, DataFormatterPartialTypeMap } from './DataFormatter'
|
|
6
|
+
|
|
7
|
+
export type ChartType = 'series' | 'grid' | 'multiGrid' | 'multiValue' | 'tree' | 'relationship'
|
|
8
|
+
|
|
9
|
+
export interface CreateBaseChart {
|
|
10
|
+
<T extends ChartType>({ defaultDataFormatter, computedDataFn, contextObserverFn }: {
|
|
11
|
+
defaultDataFormatter: DataFormatterTypeMap<T>
|
|
12
|
+
computedDataFn: ComputedDataFn<T>
|
|
13
|
+
contextObserverFn: ContextObserverFn<T>
|
|
14
|
+
}): CreateChart<T>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export interface CreateChart<T extends ChartType> {
|
|
19
|
+
// (element: HTMLElement | Element, pluginParams: any[], chartParams?: Partial<ChartParams>): Chart<T>
|
|
20
|
+
(element: HTMLElement | Element, options?: ChartOptionsPartial<T>): ChartEntity<T>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ChartEntity<T extends ChartType> extends ContextSubject<T> {
|
|
24
|
+
selection: d3.Selection<SVGGElement, unknown, HTMLElement, unknown>
|
|
25
|
+
destroy: () => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ChartOptions<T extends ChartType> {
|
|
29
|
+
preset: Preset<T>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ChartOptionsPartial<T extends ChartType> {
|
|
33
|
+
preset?: PresetPartial<T>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface Preset<T extends ChartType> {
|
|
37
|
+
chartParams: ChartParams
|
|
38
|
+
dataFormatter: DataFormatterTypeMap<T>
|
|
39
|
+
allPluginParams: {[key: string]: any}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PresetPartial<T extends ChartType> {
|
|
43
|
+
chartParams?: ChartParamsPartial
|
|
44
|
+
dataFormatter?: DataFormatterPartialTypeMap<T>
|
|
45
|
+
allPluginParams?: {[key: string]: any}
|
|
46
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Padding } from './Padding'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export interface ChartParams {
|
|
5
|
+
padding: Padding,
|
|
6
|
+
// colors: string[],
|
|
7
|
+
highlightTarget: HighlightTarget
|
|
8
|
+
// highlightDefault: HighlightDefault
|
|
9
|
+
highlightDefault: string | null
|
|
10
|
+
colorScheme: 'dark' | 'light'
|
|
11
|
+
colors: {
|
|
12
|
+
light: ColorScheme
|
|
13
|
+
dark: ColorScheme
|
|
14
|
+
}
|
|
15
|
+
styles: Styles
|
|
16
|
+
transitionDuration: number
|
|
17
|
+
transitionEase: string
|
|
18
|
+
// [key: string]: any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ChartParamsPartial = {
|
|
22
|
+
padding?: Partial<Padding>,
|
|
23
|
+
colors?: {
|
|
24
|
+
light?: Partial<ColorScheme>
|
|
25
|
+
dark?: Partial<ColorScheme>
|
|
26
|
+
}
|
|
27
|
+
styles?: Partial<Styles>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// export interface HighlightDefault {
|
|
31
|
+
// id: string | null
|
|
32
|
+
// label: string | null
|
|
33
|
+
// }
|
|
34
|
+
|
|
35
|
+
export type HighlightTarget = 'series' | 'group' | 'datum' | 'none'
|
|
36
|
+
|
|
37
|
+
export interface Styles {
|
|
38
|
+
textSize: number
|
|
39
|
+
unhighlightedOpacity: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ColorScheme {
|
|
43
|
+
series: string[]
|
|
44
|
+
primary: string
|
|
45
|
+
secondary: string
|
|
46
|
+
white: string
|
|
47
|
+
background: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type ColorType = keyof ColorScheme
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ChartType } from './Chart'
|
|
2
|
+
import type { ComputedDataSeries, ComputedDatumSeries } from './ComputedDataSeries'
|
|
3
|
+
import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
|
|
4
|
+
import type { ComputedDataMultiGrid } from './ComputedDataMultiGrid'
|
|
5
|
+
import type { ComputedDataMultiValue, ComputedDatumMultiValue } from './ComputedDataMultiValue'
|
|
6
|
+
import type { ComputedDataRelationship, ComputedNode } from './ComputedDataRelationship'
|
|
7
|
+
import type { ComputedDataTree } from './ComputedDataTree'
|
|
8
|
+
import type { DataFormatterContext } from './DataFormatter'
|
|
9
|
+
|
|
10
|
+
export interface ComputedDataFn<T extends ChartType> {
|
|
11
|
+
(dataFormatterContext: DataFormatterContext<T>): ComputedDataTypeMap<T>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// datum - 基本型本
|
|
15
|
+
export interface ComputedDatumBase {
|
|
16
|
+
id: string
|
|
17
|
+
index: number
|
|
18
|
+
label: string
|
|
19
|
+
value: number | null
|
|
20
|
+
visible: boolean
|
|
21
|
+
tooltipContent: string
|
|
22
|
+
data: any // 使用者注入的資料
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// datum - 單值
|
|
26
|
+
// export interface ComputedDatumValue {
|
|
27
|
+
// value: number | null
|
|
28
|
+
// // valueLabel: string
|
|
29
|
+
// }
|
|
30
|
+
|
|
31
|
+
// datum - 多值
|
|
32
|
+
// export interface ComputedDatumMultiValue {
|
|
33
|
+
// value: number[]
|
|
34
|
+
// valueLabels: string[]
|
|
35
|
+
// }
|
|
36
|
+
|
|
37
|
+
// datum - 圖軸
|
|
38
|
+
// export interface ComputedDatumWithAxis {
|
|
39
|
+
// axisX: number
|
|
40
|
+
// axisY: number
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
// datum - 序列顏色
|
|
44
|
+
export interface ComputedDatumSeriesValue {
|
|
45
|
+
color: string
|
|
46
|
+
seriesIndex: number
|
|
47
|
+
seriesLabel: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 透過類型選擇ComputedData
|
|
51
|
+
export type ComputedDataTypeMap<T extends ChartType> = T extends 'series' ? ComputedDataSeries
|
|
52
|
+
: T extends 'grid' ? ComputedDataGrid
|
|
53
|
+
: T extends 'multiGrid' ? ComputedDataMultiGrid
|
|
54
|
+
: T extends 'multiValue' ? ComputedDataMultiValue
|
|
55
|
+
: T extends 'relationship' ? ComputedDataRelationship
|
|
56
|
+
: T extends 'tree' ? ComputedDataTree
|
|
57
|
+
: ComputedDatumBase
|
|
58
|
+
|
|
59
|
+
// 透過類型選擇ComputedDatum
|
|
60
|
+
export type ComputedDatumTypeMap<T extends ChartType> = T extends 'series' ? ComputedDatumSeries
|
|
61
|
+
: T extends 'grid' ? ComputedDatumGrid
|
|
62
|
+
: T extends 'multiGrid' ? ComputedDatumGrid
|
|
63
|
+
: T extends 'multiValue' ? ComputedDatumMultiValue
|
|
64
|
+
: T extends 'relationship' ? ComputedNode
|
|
65
|
+
: T extends 'tree' ? ComputedDataTree
|
|
66
|
+
: unknown
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ComputedDatumBase, ComputedDatumSeriesValue } from './ComputedData'
|
|
2
|
+
|
|
3
|
+
export interface ComputedDatumGrid
|
|
4
|
+
extends ComputedDatumBase, ComputedDatumSeriesValue {
|
|
5
|
+
groupIndex: number
|
|
6
|
+
groupLabel: string
|
|
7
|
+
axisX: number
|
|
8
|
+
axisY: number
|
|
9
|
+
axisYFromZero: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type ComputedDataGrid = ComputedDatumGrid[][]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComputedDatumBase } from './ComputedData'
|
|
2
|
+
|
|
3
|
+
export type ComputedDataRelationship = {
|
|
4
|
+
nodes: ComputedNode[]
|
|
5
|
+
edges: ComputedEdge[]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ComputedNode extends ComputedDatumBase {
|
|
9
|
+
startNodes: ComputedNode[]
|
|
10
|
+
startNodeIds: string[]
|
|
11
|
+
endNodes: ComputedNode[]
|
|
12
|
+
endNodeIds: string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ComputedEdge extends ComputedDatumBase {
|
|
16
|
+
startNode: ComputedNode
|
|
17
|
+
startNodeId: string
|
|
18
|
+
endNode: ComputedNode
|
|
19
|
+
endNodeId: string
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComputedDatumBase } from './ComputedData'
|
|
2
|
+
|
|
3
|
+
// export type ComputedDataTree = ComputedDataTreeDatum[]
|
|
4
|
+
|
|
5
|
+
// export interface ComputedDataTreeDatum extends ComputedDatum {
|
|
6
|
+
// // id: string
|
|
7
|
+
// children: ComputedDataTreeDatum[]
|
|
8
|
+
// childrenIds: string[]
|
|
9
|
+
// // ChildrenMap: Map<string, ComputedDataTreeDatum>
|
|
10
|
+
// parent: ComputedDataTreeDatum
|
|
11
|
+
// parentId: string
|
|
12
|
+
// value?: number
|
|
13
|
+
// }
|
|
14
|
+
|
|
15
|
+
// 樹狀結構
|
|
16
|
+
export interface ComputedDataTree extends ComputedDatumBase {
|
|
17
|
+
level: number
|
|
18
|
+
seq: number
|
|
19
|
+
children?: ComputedDataTree[]
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Observable, Subject, BehaviorSubject } from 'rxjs'
|
|
2
|
+
import type { ChartType } from './Chart'
|
|
3
|
+
import type { ChartParams } from './ChartParams'
|
|
4
|
+
import type { DataFormatterTypeMap } from './DataFormatter'
|
|
5
|
+
import type { ComputedDataTypeMap } from './ComputedData'
|
|
6
|
+
import type { Layout } from './Layout'
|
|
7
|
+
import type { ContextObserverGrid } from './ContextObserverGrid'
|
|
8
|
+
import type { ContextObserverMultiGrid } from './ContextObserverMultiGrid'
|
|
9
|
+
import type { ContextObserverMultiValue } from './ContextObserverMultiValue'
|
|
10
|
+
import type { ContextObserverRelationship } from './ContextObserverRelationship'
|
|
11
|
+
import type { ContextObserverSeries } from './ContextObserverSeries'
|
|
12
|
+
import type { ContextObserverTree } from './ContextObserverTree'
|
|
13
|
+
import type { ContextSubject } from './ContextSubject'
|
|
14
|
+
|
|
15
|
+
export interface ContextObserverFn<T extends ChartType> {
|
|
16
|
+
({ subject, observer }: {
|
|
17
|
+
subject: ContextSubject<T>
|
|
18
|
+
observer: ContextObserverBase<T, unknown>
|
|
19
|
+
}): ContextObserverTypeMap<T, unknown>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ContextObserver
|
|
23
|
+
export type ContextObserverTypeMap<T extends ChartType, PluginParams> = T extends 'series' ? ContextObserverSeries<PluginParams>
|
|
24
|
+
: T extends 'grid' ? ContextObserverGrid<PluginParams>
|
|
25
|
+
: T extends 'multiGrid' ? ContextObserverMultiGrid<PluginParams>
|
|
26
|
+
: T extends 'multiValue' ? ContextObserverMultiValue<PluginParams>
|
|
27
|
+
: T extends 'relationship' ? ContextObserverRelationship<PluginParams>
|
|
28
|
+
: T extends 'tree' ? ContextObserverTree<PluginParams>
|
|
29
|
+
: ContextObserverBase<ChartType, PluginParams>
|
|
30
|
+
|
|
31
|
+
export interface ContextObserverBase<T extends ChartType, PluginParams> {
|
|
32
|
+
fullParams$: Observable<PluginParams>
|
|
33
|
+
fullChartParams$: Observable<ChartParams>
|
|
34
|
+
fullDataFormatter$: Observable<DataFormatterTypeMap<T>>
|
|
35
|
+
computedData$: Observable<ComputedDataTypeMap<T>>
|
|
36
|
+
layout$: Observable<Layout>
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Observable } from 'rxjs'
|
|
2
|
+
import type { ContextObserverBase } from './ContextObserver'
|
|
3
|
+
import type { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid'
|
|
4
|
+
import type { TransformData } from './TransformData'
|
|
5
|
+
|
|
6
|
+
export interface ContextObserverGrid<PluginParams> extends ContextObserverBase<'grid', PluginParams> {
|
|
7
|
+
gridAxesTransform$: Observable<TransformData>
|
|
8
|
+
gridGraphicTransform$: Observable<TransformData>
|
|
9
|
+
gridAxesOppositeTransform$: Observable<TransformData>
|
|
10
|
+
gridAxesSize$: Observable<{ width: number; height: number; }>
|
|
11
|
+
gridHighlight$: Observable<string[]>
|
|
12
|
+
SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
|
13
|
+
GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
|
|
14
|
+
visibleComputedData$: Observable<ComputedDataGrid>
|
|
15
|
+
}
|
|
16
|
+
|