adminforth 2.22.0-next.29 → 2.22.0-next.30
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.
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="afcl-treemap -mb-2" ref="chart"></div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import ApexCharts, { type ApexOptions } from 'apexcharts';
|
|
7
|
+
import { ref, type Ref, watch, computed, onUnmounted } from 'vue';
|
|
8
|
+
|
|
9
|
+
const chart: Ref<HTMLDivElement | null> = ref(null);
|
|
10
|
+
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
data: {
|
|
13
|
+
x: string,
|
|
14
|
+
[key: string]: any,
|
|
15
|
+
}[],
|
|
16
|
+
series: {
|
|
17
|
+
name: string,
|
|
18
|
+
fieldName: string,
|
|
19
|
+
}[],
|
|
20
|
+
options?: ApexOptions,
|
|
21
|
+
}>();
|
|
22
|
+
|
|
23
|
+
const optionsBase: ApexOptions = {
|
|
24
|
+
chart: {
|
|
25
|
+
height: 350,
|
|
26
|
+
type: 'treemap',
|
|
27
|
+
fontFamily: 'Inter, sans-serif',
|
|
28
|
+
toolbar: {
|
|
29
|
+
show: false,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
legend: {
|
|
33
|
+
show: false,
|
|
34
|
+
},
|
|
35
|
+
dataLabels: {
|
|
36
|
+
enabled: true,
|
|
37
|
+
style: {
|
|
38
|
+
fontFamily: 'Inter, sans-serif',
|
|
39
|
+
colors: ['#FFFFFF'],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
plotOptions: {
|
|
43
|
+
treemap: {
|
|
44
|
+
distributed: true,
|
|
45
|
+
enableShades: false,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const options = computed(() => {
|
|
51
|
+
if (props.data?.length > 0) {
|
|
52
|
+
props.series.forEach((s) => {
|
|
53
|
+
if (props.data[0][s.fieldName] === undefined) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Field ${s.fieldName} not found even in first data point ${JSON.stringify(props.data[0])}, something is wrong`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const nextOptions: ApexOptions = {
|
|
62
|
+
...optionsBase,
|
|
63
|
+
series: props.series.map((s) => ({
|
|
64
|
+
name: s.name,
|
|
65
|
+
data: (props.data ?? []).map((item: any) => {
|
|
66
|
+
const { x, y: _ignoredY, ...rest } = item ?? {};
|
|
67
|
+
return {
|
|
68
|
+
x,
|
|
69
|
+
y: item?.[s.fieldName],
|
|
70
|
+
...rest,
|
|
71
|
+
};
|
|
72
|
+
}),
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function mergeOptions(target: any, source: any) {
|
|
77
|
+
if (!source) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const key in source) {
|
|
81
|
+
if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
82
|
+
if (!target[key]) {
|
|
83
|
+
target[key] = {};
|
|
84
|
+
}
|
|
85
|
+
mergeOptions(target[key], source[key]);
|
|
86
|
+
} else {
|
|
87
|
+
target[key] = source[key];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
mergeOptions(nextOptions, props.options);
|
|
93
|
+
return nextOptions;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
let apexChart: ApexCharts | null = null;
|
|
97
|
+
|
|
98
|
+
watch(() => [options.value, chart.value], (value) => {
|
|
99
|
+
if (!value || !chart.value) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (apexChart) {
|
|
104
|
+
apexChart.updateOptions(options.value);
|
|
105
|
+
} else {
|
|
106
|
+
apexChart = new ApexCharts(chart.value, options.value);
|
|
107
|
+
apexChart.render();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
onUnmounted(() => {
|
|
112
|
+
if (apexChart) {
|
|
113
|
+
apexChart.destroy();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<style lang="scss">
|
|
119
|
+
:root {
|
|
120
|
+
--afcl-treemap-text: #FFFFFF;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
[data-theme='dark'] {
|
|
124
|
+
--afcl-treemap-text: #FFFFFF;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.afcl-treemap {
|
|
128
|
+
.apexcharts-datalabel {
|
|
129
|
+
fill: var(--afcl-treemap-text);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.apexcharts-legend-text {
|
|
133
|
+
color: var(--afcl-treemap-text) !important;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
</style>
|
|
@@ -12,6 +12,7 @@ export { default as Dropzone } from './Dropzone.vue';
|
|
|
12
12
|
export { default as AreaChart } from './AreaChart.vue';
|
|
13
13
|
export { default as BarChart } from './BarChart.vue';
|
|
14
14
|
export { default as PieChart } from './PieChart.vue';
|
|
15
|
+
export { default as TreeMapChart } from './TreeMapChart.vue';
|
|
15
16
|
export { default as Table } from './Table.vue';
|
|
16
17
|
export { default as ProgressBar } from './ProgressBar.vue';
|
|
17
18
|
export { default as Spinner } from './Spinner.vue';
|