|
|
<template> <div ref="chartRef" :style="{ height: height, width: width }" /></template>
<script>import * as echarts from 'echarts'import resize from '@/views/dashboard/mixins/resize'
export default { name: 'CatePie', mixins: [resize], props: { cateData: { type: Array, required: true, default: () => [] }, width: { type: String, default: '100%' }, height: { type: String, default: '100%' }, refreshtime: { type: Number, default: null } }, data() { return { chart: null, timer: null // 新增:定时器统一管理
} }, watch: { cateData: { handler() { this.$nextTick(() => { this.drawChart() }) }, immediate: true, deep: true } }, mounted() { this.refreshEchart() }, beforeDestroy() { clearInterval(this.timer) // 新增:清除定时器
if (this.chart) { this.chart.dispose() this.chart = null } }, methods: { refreshEchart() { if (this.refreshtime) { this.timer = setInterval(() => { this.drawChart() // 优化:直接重绘而非重新初始化
}, this.refreshtime) } else { this.initChart() } }, initChart() { if (this.chart) return const chartDom = this.$refs.chartRef if (!chartDom) return
this.chart = echarts.init(chartDom) this.drawChart() }, drawChart() { if (!this.chart) this.initChart() if (!this.chart) return
// 处理无数据情况
const chartData = this.cateData.length ? this.cateData : [{ name: '无告警数据', value: 1, itemStyle: { color: '#666666' }}]
// ========== 核心修改:0值项分配极小占比,实现视觉分离 ==========
const processedData = chartData.map(item => { // 0值替换为极小值(0.01),非0值保持原样
const displayValue = item.value === 0 ? 0.01 : item.value return { ...item, value: displayValue, // 新增:存储原始值,用于tooltip/label显示
rawValue: item.value } })
const option = { backgroundColor: 'transparent', tooltip: { trigger: 'item', textStyle: { fontSize: 12 }, // 优化:显示原始0值,而非极小值
formatter: (params) => `${params.name}: ${params.data.rawValue} 次 (0%)` }, legend: { bottom: 10, left: 'center', icon: 'circle', itemHeight: 8, itemWidth: 8, itemGap: 15, textStyle: { color: '#ffffff', fontSize: 11 }, formatter: function(name) { if (name.length > 6) { return name.substring(0, 6) + '\n' + name.substring(6) } return name } }, series: [ { name: '当日告警统计', type: 'pie', radius: ['30%', '60%'], center: ['50%', '44%'], avoidLabelOverlap: true, // 优化:开启标签防重叠
// 优化:调整标签线样式,强制分开0值项标签
labelLine: { show: true, length: 10, // 增加基础长度
length2: 15, // 增加二级长度
smooth: 0.2, // 轻微平滑,避免线条重叠
lineStyle: (params) => ({ color: params.data.rawValue === 0 ? 'rgba(255,255,255,0.3)' : '#ffffff', width: 1 }) }, label: { show: true, fontSize: 11, color: '#ffffff', // 优化:显示原始0值
formatter: (params) => `${params.data.rawValue} 次`, // 新增:调整标签位置,强制分开
position: 'outer', distance: 20 // 标签离饼图的距离
}, emphasis: { label: { show: true, fontSize: 12, fontWeight: 'bold' }, itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } }, data: processedData, animationDuration: 1000, animationEasing: 'cubicOut', // 新增:饼图扇区之间增加间隙,进一步分开
itemStyle: { borderColor: 'transparent', borderWidth: 1 } } ] }
this.chart.setOption(option, true) }, resize() { if (this.chart) { this.chart.resize() } } }}</script>
<style lang="scss" scoped>:deep(.ec-legend) { padding-bottom: 5px !important;}:deep(.ec-tooltip) { background: rgba(0, 20, 53, 0.9) !important; border: 1px solid #339cff !important; border-radius: 4px !important;}
// 0值项标签半透明区分
:deep(.ec-label) { &[style*="0 次"] { fill: rgba(255,255,255,0.5) !important; }}
// 新增:给饼图扇区加间隙,视觉上更易区分
:deep(.ec-pie) { g > path { stroke: transparent !important; stroke-width: 1px !important; }}</style>
|