Skip to content

Commit 53b06c3

Browse files
Merge pull request #138 from vue-pivottable/feature/useProvidePivotData-ts
feat(composables): useProvidePivotData TypeScript 마이그레이션
2 parents fa0a3db + 7f3b396 commit 53b06c3

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { Ref, ref, provide, inject, computed, ComputedRef } from 'vue'
2+
import type { PivotData } from '@/helper/utilities'
3+
import { PivotData as PivotDataClass } from '@/helper/utilities'
4+
5+
const PIVOT_DATA_KEY = Symbol('pivotData')
6+
7+
interface ProvidePivotDataProps { [key: string]: any }
8+
9+
export interface PivotDataContext {
10+
pivotData: ComputedRef<PivotData | null>
11+
rowKeys: ComputedRef<any[][]>
12+
colKeys: ComputedRef<any[][]>
13+
colAttrs: ComputedRef<string[]>
14+
rowAttrs: ComputedRef<string[]>
15+
getAggregator: (rowKey: any[], colKey: any[]) => any
16+
grandTotalAggregator: ComputedRef<any>
17+
spanSize: (arr: any[][], i: number, j: number) => number
18+
valueCellColors: (rowKey: any[], colKey: any[], value: any) => any
19+
rowTotalColors: (value: any) => any
20+
colTotalColors: (value: any) => any
21+
error: Ref<string | null>
22+
}
23+
24+
export function providePivotData (props: ProvidePivotDataProps): PivotDataContext {
25+
const error = ref<string | null>(null)
26+
27+
const pivotData = computed<PivotData | null>(() => {
28+
try {
29+
return new PivotDataClass(props) as PivotData
30+
} catch (err: any) {
31+
console.error(err.stack)
32+
error.value = 'An error occurred computing the PivotTable results.'
33+
return null
34+
}
35+
})
36+
37+
const rowKeys = computed<any[][]>(() => pivotData.value?.getRowKeys() || [])
38+
const colKeys = computed<any[][]>(() => pivotData.value?.getColKeys() || [])
39+
const colAttrs = computed<string[]>(() => pivotData.value?.props.cols || [])
40+
const rowAttrs = computed<string[]>(() => pivotData.value?.props.rows || [])
41+
const colorScaleGenerator = props.tableColorScaleGenerator
42+
const getAggregator = (rowKey: any[], colKey: any[]) =>
43+
pivotData.value?.getAggregator(rowKey, colKey) || {
44+
value: () => null,
45+
format: () => ''
46+
}
47+
48+
const grandTotalAggregator = computed(() => {
49+
return pivotData.value
50+
? getAggregator([], [])
51+
: {
52+
value: () => null,
53+
format: () => ''
54+
}
55+
})
56+
57+
const allColorScales = computed(() => {
58+
const values = rowKeys.value.reduce((acc: any[], r: any[]) => acc.concat(colKeys.value.map((c: any[]) => getAggregator(r, c).value())), [])
59+
return colorScaleGenerator(values)
60+
})
61+
const rowColorScales = computed(() =>
62+
rowKeys.value.reduce((scales: Record<string, any>, r: any[]) => {
63+
const key = JSON.stringify(r)
64+
scales[key] = colorScaleGenerator(
65+
colKeys.value.map((x: any[]) => getAggregator(r, x).value())
66+
)
67+
return scales
68+
}, {} as Record<string, any>)
69+
)
70+
const colColorScales = computed(() =>
71+
colKeys.value.reduce((scales: Record<string, any>, c: any[]) => {
72+
const key = JSON.stringify(c)
73+
scales[key] = colorScaleGenerator(
74+
rowKeys.value.map((x: any[]) => getAggregator(x, c).value())
75+
)
76+
return scales
77+
}, {} as Record<string, any>)
78+
)
79+
80+
const valueCellColors = (rowKey: any[], colKey: any[], value: any) => {
81+
if (props.heatmapMode === 'full') {
82+
return allColorScales.value(value)
83+
} else if (props.heatmapMode === 'row') {
84+
return rowColorScales.value[JSON.stringify(rowKey)]?.(value)
85+
} else if (props.heatmapMode === 'col') {
86+
return colColorScales.value[JSON.stringify(colKey)]?.(value)
87+
}
88+
return {}
89+
}
90+
const rowTotalValues = computed(() => colKeys.value.map((x: any[]) => getAggregator([], x).value()))
91+
const rowTotalColors = (value: any) => {
92+
if (!props.heatmapMode) return {}
93+
return colorScaleGenerator(rowTotalValues.value)(value)
94+
}
95+
const colTotalValues = computed(() => rowKeys.value.map((x: any[]) => getAggregator(x, []).value()))
96+
const colTotalColors = (value: any) => {
97+
if (!props.heatmapMode) return {}
98+
return colorScaleGenerator(colTotalValues.value)(value)
99+
}
100+
101+
const spanSize = (arr: any[][], i: number, j: number): number => {
102+
let x
103+
if (i !== 0) {
104+
let noDraw = true
105+
for (x = 0; x <= j; x++) {
106+
if (arr[i - 1][x] !== arr[i][x]) {
107+
noDraw = false
108+
}
109+
}
110+
if (noDraw) {
111+
return -1
112+
}
113+
}
114+
115+
let len = 0
116+
while (i + len < arr.length) {
117+
let stop = false
118+
for (x = 0; x <= j; x++) {
119+
if (arr[i][x] !== arr[i + len][x]) {
120+
stop = true
121+
}
122+
}
123+
if (stop) {
124+
break
125+
}
126+
len++
127+
}
128+
return len
129+
}
130+
131+
const pivotDataContext: PivotDataContext = {
132+
pivotData,
133+
rowKeys,
134+
colKeys,
135+
colAttrs,
136+
rowAttrs,
137+
getAggregator,
138+
grandTotalAggregator,
139+
spanSize,
140+
valueCellColors,
141+
rowTotalColors,
142+
colTotalColors,
143+
error
144+
}
145+
146+
provide(PIVOT_DATA_KEY, pivotDataContext)
147+
return pivotDataContext
148+
}
149+
150+
export function useProvidePivotData (): PivotDataContext | undefined {
151+
return inject<PivotDataContext>(PIVOT_DATA_KEY)
152+
}

0 commit comments

Comments
 (0)