ai-agent-m/src/pages/overview/_components/pie-chart.vue
2025-03-20 18:06:23 +08:00

128 lines
3.0 KiB
Vue

<template>
<div ref="chartEl" :style="{ width, height }" class="chart-container"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
title: {
type: String,
default: 'Pie Chart'
},
data: {
type: Array,
required: true,
validator: (val) => val.every(i => i.name && typeof i.value === 'number')
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '600px'
}
})
const chartEl = ref(null)
let chartInstance = null
// 确保ECharts正确初始化
const initChart = () => {
if (!chartEl.value) return
// 先销毁已有实例
if (chartInstance) {
chartInstance.dispose()
}
chartInstance = echarts.init(chartEl.value)
chartInstance.setOption({
title: {
text: props.title,
left: 'center',
top: '5%',
},
tooltip: {
trigger: 'item'
},
legend: {
top: '15%',
left: 'center',
selectedMode: true,
},
selectedMode: 'single',
series: [
{
name: '部门使用次数',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
top: '20%',
itemStyle: {
borderRadius: 10
},
label: {
show: true,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: true
},
hoverOffset: 15, // 增加悬停偏移量
still: false, // 允许悬浮动画
silent: true, // 启用交互
// 添加响应阈值配置
hoverAnimationThreshold: 1, // 无论多小的区块都可交互
selectedOffset: 10, // 选中项偏移量
data: props.data
}
]
})
}
onMounted(() => {
// 延迟初始化确保DOM就绪
setTimeout(initChart, 0)
window.addEventListener('resize', initChart)
})
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose()
chartInstance = null
}
window.removeEventListener('resize', initChart)
})
// 数据变化时更新
watch(() => props.data, () => {
if (chartInstance) {
chartInstance.setOption({
series: [{
data: props.data
}]
})
}
}, { deep: true })
</script>
<style scoped>
.chart-container {
touch-action: manipulation;
/* 优化移动端触控 */
-webkit-tap-highlight-color: transparent;
/* 移除点击高光 */
}
</style>