html
复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>饼图数值固定显示效果</title>
<!-- 引入 ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
body {
padding: 20px;
}
#pieChart {
width: 100%;
height: 500px;
}
</style>
</head>
<body>
<div id="pieChart"></div>
<script>
// 初始化图表
const chartDom = document.getElementById('pieChart');
const myChart = echarts.init(chartDom);
let option;
// 示例数据
const pieData = [
{ value: 335, name: '直接访问' },
{ value: 310, name: '邮件营销' },
{ value: 234, name: '联盟广告' },
{ value: 135, name: '视频广告' },
{ value: 1548, name: '搜索引擎' }
];
// 保存原始颜色和选中状态
const originalColors = [];
let selectedIndex = -1;
const legendNames = pieData.map(item => item.name);
// 颜色变暗函数
function darkenColor(color, percent) {
let hex = color.replace('#', '');
let r = parseInt(hex.substring(0, 2), 16);
let g = parseInt(hex.substring(2, 4), 16);
let b = parseInt(hex.substring(4, 6), 16);
r = Math.floor(r * (1 - percent/100));
g = Math.floor(g * (1 - percent/100));
b = Math.floor(b * (1 - percent/100));
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
// 初始化图表配置
option = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 10,
data: legendNames,
textStyle: {
color: '#666',
fontSize: 14
},
emphasis: {
textStyle: {
color: '#e63946',
fontWeight: 'bold'
}
}
},
series: [
{
name: '访问来源',
type: 'pie',
radius: ['40%', '70%'],
center: ['60%', '50%'],
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
// 关键配置:固定显示标签和数值
label: {
show: true, // 始终显示标签
position: 'outside', // 标签显示在外侧
formatter: '{b}: {c} ({d}%)', // 显示名称、数值和百分比
color: '#666', // 普通状态标签颜色
fontSize: 12,
// 标签线配置
lineStyle: {
color: '#999',
width: 1
}
},
labelLine: {
show: true, // 显示标签连接线
length: 15,
length2: 20
},
// 选中状态的配置
emphasis: {
scale: true,
scaleSize: 20,
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.3)'
},
// 选中时的标签高亮样式
label: {
color: '#e63946', // 高亮颜色
fontSize: 14,
fontWeight: 'bold'
}
},
data: pieData
}
],
animationDuration: 300,
animationEasing: 'elasticOut'
};
// 渲染图表并获取原始颜色
myChart.setOption(option);
const colorList = myChart.getOption().color || echarts.graphic.getDefaultColor();
pieData.forEach((item, index) => {
originalColors[index] = colorList[index % colorList.length];
});
// 处理点击事件
myChart.on('click', function(params) {
if (params.componentType === 'series' && params.seriesType === 'pie') {
// 切换选中状态
selectedIndex = selectedIndex === params.dataIndex ? -1 : params.dataIndex;
updateChartStyle();
} else if (params.componentType === 'legend') {
// 处理图例点击
const index = legendNames.indexOf(params.name);
selectedIndex = selectedIndex === index ? -1 : index;
updateChartStyle();
} else {
// 点击空白处取消选中
selectedIndex = -1;
updateChartStyle();
}
});
// 更新图表样式
function updateChartStyle() {
option.series[0].data.forEach((item, index) => {
if (index === selectedIndex) {
// 选中的扇区
item.itemStyle = {
color: originalColors[index]
};
myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: index });
myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, name: legendNames[index] });
} else {
// 未选中的扇区
item.itemStyle = {
color: darkenColor(originalColors[index], 40)
};
myChart.dispatchAction({ type: 'downplay', seriesIndex: 0, dataIndex: index });
myChart.dispatchAction({ type: 'downplay', seriesIndex: 0, name: legendNames[index] });
}
});
myChart.setOption(option);
}
// 响应窗口大小变化
window.addEventListener('resize', () => {
myChart.resize();
});
</script>
</body>
</html>