echarts【实战】饼状图点击高亮,其他区域变暗

发布于:2025-07-25 ⋅ 阅读:(20) ⋅ 点赞:(0)

最终效果

在这里插入图片描述

代码实现

<!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>

网站公告

今日签到

点亮在社区的每一天
去签到