| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- <script setup lang="ts">
- import { provide, ref } from 'vue';
- import VChart, { type EChartsOption, theme } from './echart';
- const { dataset = [] } = defineProps<{ dataset?: any[][] }>();
- const snapshot = defineModel('snapshot', { default: '' });
- provide(...theme);
- const option = ref<EChartsOption>({
- backgroundColor: 'transparent',
- legend: { top: 10, right: 10, },
- grid: {
- containLabel: true,
- top: 50,
- bottom: 10,
- left: 10,
- right: 10,
- },
- xAxis: {
- type: 'category',
- splitLine: { show: false },
- axisTick: { show: false },
- },
- yAxis: {
- type: 'value', min: 0, max: 100, splitNumber: 5,
- axisLine: { show: false },
- axisLabel: { show: false },
- },
- series: [],
- });
- const defaultSetting = [
- { label: '平和体质(正常体质)', color: '#38ff6e' },
- { label: '所属体质', color: '#ff8917' },
- { label: '倾向体质', color: '#ffbc5b' },
- { label: '推断体质', color: '#34a76b' },
- { label: '体质', color: '#b2b4ab' },
- ];
- watchEffect(() => {
- const ref = new Set<number>(dataset.map((item) => item[2]));
- const legend: EChartsOption['legend'] & {} = { data: [] };
- const series: EChartsOption['series'][] = [];
- for (const key of ref) {
- const { label: name, color } = defaultSetting[key] ?? {};
- series.push({
- name, type: 'bar',
- barMaxWidth: 30, barGap: '-100%',
- data: dataset.filter((item) => item[2] === key), itemStyle: { color },
- });
- if (name !== '体质') legend.data?.push({ name, itemStyle: { color } });
- }
- option.value.legend = { ...option.value.legend, ...legend };
- option.value.series = series as any;
- });
- const chart = useTemplateRef<InstanceType<typeof VChart>>('chart');
- let loaded = false;
- function onFinished() {
- if (loaded || snapshot.value && snapshot.value.startsWith(`data:image/`)) return;
- snapshot.value = chart.value?.getDataURL() ?? '';
- loaded = true;
- }
- </script>
- <template>
- <div class="mx-auto">
- <div class="chart-container">
- <v-chart ref="chart" class="chart" :option="option" @finished="onFinished" />
- </div>
- </div>
- </template>
- <style scoped lang="scss">
- .chart-container {
- position: relative;
- padding-bottom: 50%;
- > .chart {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- }
- }
- </style>
|