Browse Source

饼图需求

master
xuhuajiao 9 months ago
parent
commit
33b5fcd52b
  1. 13
      src/views/environmentalScreen/index.vue
  2. 88
      src/views/environmentalScreen/module/catePie.vue

13
src/views/environmentalScreen/index.vue

@ -574,11 +574,11 @@ export default {
}, },
formatAlarmChartData() { formatAlarmChartData() {
const allZero = this.alarmStatisticsRaw.every(item => item.num === 0)
if (allZero) {
this.alarmChartData = [{ name: '无告警', value: 1, itemStyle: { color: '#666666' }}]
return
}
// const allZero = this.alarmStatisticsRaw.every(item => item.num === 0)
// if (allZero) {
// this.alarmChartData = [{ name: '无告警', value: 1, itemStyle: { color: '#666666' }}]
// return
// }
const alarmColorMap = { const alarmColorMap = {
'门禁告警': '#F65164', '门禁告警': '#F65164',
'消防告警': '#FFB800', '消防告警': '#FFB800',
@ -589,7 +589,7 @@ export default {
const colorList = ['#F65164', '#339CFF', '#FFB800', '#1CADAB', '#9B6BCC', '#FF7D00'] const colorList = ['#F65164', '#339CFF', '#FFB800', '#1CADAB', '#9B6BCC', '#FF7D00']
this.alarmChartData = this.alarmStatisticsRaw.map((item, index) => { this.alarmChartData = this.alarmStatisticsRaw.map((item, index) => {
const alarmName = item.alarmValue || '未知告警'
const alarmName = item.alarmValue
// 优先使用配置的颜色,没有则使用备用颜色 // 优先使用配置的颜色,没有则使用备用颜色
const color = alarmColorMap[alarmName] || colorList[index % colorList.length] || '#666666' const color = alarmColorMap[alarmName] || colorList[index % colorList.length] || '#666666'
@ -599,7 +599,6 @@ export default {
itemStyle: { itemStyle: {
color: color color: color
}, },
// 可选:为0值添加特殊样式(比如半透明)
...(item.num === 0 ? { itemStyle: { color: color, opacity: 0.5 }} : {}) ...(item.num === 0 ? { itemStyle: { color: color, opacity: 0.5 }} : {})
} }
}) })

88
src/views/environmentalScreen/module/catePie.vue

@ -31,7 +31,7 @@ export default {
data() { data() {
return { return {
chart: null, chart: null,
timer: null // 新增:定时器统一管理
timer: null
} }
}, },
watch: { watch: {
@ -49,7 +49,7 @@ export default {
this.refreshEchart() this.refreshEchart()
}, },
beforeDestroy() { beforeDestroy() {
clearInterval(this.timer) // 新增:清除定时器
clearInterval(this.timer)
if (this.chart) { if (this.chart) {
this.chart.dispose() this.chart.dispose()
this.chart = null this.chart = null
@ -59,7 +59,7 @@ export default {
refreshEchart() { refreshEchart() {
if (this.refreshtime) { if (this.refreshtime) {
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.drawChart() // 优化:直接重绘而非重新初始化
this.drawChart()
}, this.refreshtime) }, this.refreshtime)
} else { } else {
this.initChart() this.initChart()
@ -77,30 +77,48 @@ export default {
if (!this.chart) this.initChart() if (!this.chart) this.initChart()
if (!this.chart) return if (!this.chart) return
// 处理无数据情况
// 处理无数据(空数组)情况
const chartData = this.cateData.length const chartData = this.cateData.length
? this.cateData ? this.cateData
: [{ name: '无告警数据', value: 1, itemStyle: { color: '#666666' }}] : [{ 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
// ========== 核心调整1:判断是否全为0 ==========
const isAllZero = chartData.every(item => item.value === 0)
// 全0时:给每个项分配均等的极小值(保证每个项占比相同,分开显示)
// 非全0时:0值项分配0.01,非0值保持原样
const processedData = chartData.map((item, index, arr) => {
let displayValue
if (isAllZero) {
// 全0场景:每个项分配相同的极小值(1/总项数,保证占比均等)
displayValue = 1 / arr.length
} else {
// 非全0场景:0值项分配极小值,非0值保持原样
displayValue = item.value === 0 ? 0.01 : item.value
}
return { return {
...item, ...item,
value: displayValue, value: displayValue,
// 新增:存储原始值,用于tooltip/label显示
rawValue: item.value
rawValue: item.value // 保留原始0值
} }
}) })
// ========== 核心调整2:优化tooltip格式化(区分全0/非全0的百分比) ==========
const tooltipFormatter = (params) => {
const rawValue = params.data.rawValue
let percent = '0%'
// 非全0场景下,非0值计算真实百分比
if (!isAllZero && rawValue !== 0) {
percent = `${params.percent.toFixed(1)}%`
}
return `${params.name}: ${rawValue} 次 (${percent})`
}
const option = { const option = {
backgroundColor: 'transparent', backgroundColor: 'transparent',
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
textStyle: { fontSize: 12 }, textStyle: { fontSize: 12 },
// 优化:显示原始0值,而非极小值
formatter: (params) => `${params.name}: ${params.data.rawValue} 次 (0%)`
formatter: tooltipFormatter
}, },
legend: { legend: {
bottom: 10, bottom: 10,
@ -126,13 +144,17 @@ export default {
type: 'pie', type: 'pie',
radius: ['30%', '60%'], radius: ['30%', '60%'],
center: ['50%', '44%'], center: ['50%', '44%'],
avoidLabelOverlap: true, // 优化:开启标签防重叠
// 优化:调整标签线样式,强制分开0值项标签
avoidLabelOverlap: true,
// 优化:全0场景下强制标签不重叠
labelLayout: {
hideOverlap: false, // 关闭标签重叠隐藏
moveOverlap: 'shiftY' // 重叠时上下偏移
},
labelLine: { labelLine: {
show: true, show: true,
length: 10, // 增加基础长度
length2: 15, // 增加二级长度
smooth: 0.2, // 轻微平滑,避免线条重叠
length: 10,
length2: 15,
smooth: 0.2,
lineStyle: (params) => ({ lineStyle: (params) => ({
color: params.data.rawValue === 0 color: params.data.rawValue === 0
? 'rgba(255,255,255,0.3)' ? 'rgba(255,255,255,0.3)'
@ -144,11 +166,11 @@ export default {
show: true, show: true,
fontSize: 11, fontSize: 11,
color: '#ffffff', color: '#ffffff',
// 优化:显示原始0值
formatter: (params) => `${params.data.rawValue} 次`, formatter: (params) => `${params.data.rawValue} 次`,
// 新增:调整标签位置,强制分开
position: 'outer', position: 'outer',
distance: 20 // 标签离饼图的距离
distance: 20,
// 全0场景下调整标签位置,避免重叠
...(isAllZero ? { rotate: 0 } : {})
}, },
emphasis: { emphasis: {
label: { label: {
@ -165,10 +187,10 @@ export default {
data: processedData, data: processedData,
animationDuration: 1000, animationDuration: 1000,
animationEasing: 'cubicOut', animationEasing: 'cubicOut',
// 新增:饼图扇区之间增加间隙,进一步分开
// 增强:扇区间隙加大,全0时更易区分
itemStyle: { itemStyle: {
borderColor: 'transparent',
borderWidth: 1
borderColor: 'rgba(0,0,0,0.1)', // 浅灰色边框,增强分隔
borderWidth: 2 // 加大边框宽度
} }
} }
] ]
@ -186,27 +208,33 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.ec-legend) {
::v-deep(.ec-legend) {
padding-bottom: 5px !important; padding-bottom: 5px !important;
} }
:deep(.ec-tooltip) {
::v-deep(.ec-tooltip) {
background: rgba(0, 20, 53, 0.9) !important; background: rgba(0, 20, 53, 0.9) !important;
border: 1px solid #339cff !important; border: 1px solid #339cff !important;
border-radius: 4px !important; border-radius: 4px !important;
} }
// 0值项标签半透明区分 // 0值项标签半透明区分
:deep(.ec-label) {
::v-deep(.ec-label) {
&[style*="0 次"] { &[style*="0 次"] {
fill: rgba(255,255,255,0.5) !important; fill: rgba(255,255,255,0.5) !important;
} }
} }
// 新增:给饼图扇区加间隙,视觉上更易区分
:deep(.ec-pie) {
// 增强:扇区间隙样式(兼容全0场景)
::v-deep(.ec-pie) {
g > path { g > path {
stroke: transparent !important;
stroke-width: 1px !important;
stroke: rgba(0,0,0,0.1) !important;
stroke-width: 2px !important;
stroke-linejoin: 'round' !important;
} }
} }
// 全0场景下优化图例可读性
::v-deep(.ec-legend-text) {
opacity: 1 !important;
}
</style> </style>
Loading…
Cancel
Save