You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.5 KiB
212 lines
5.5 KiB
<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>
|