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

最终效果

代码实现

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>
相关推荐
码界筑梦坊11 小时前
240-基于Python的医疗疾病数据可视化分析系统
开发语言·python·信息可视化·数据分析·毕业设计·echarts
码界筑梦坊13 小时前
243-基于Django与VUE的笔记本电脑数据可视化分析系统
vue.js·python·信息可视化·数据分析·django·毕业设计·echarts
xiaohe06013 天前
🥳 Uni ECharts 2.1 发布:正式支持鸿蒙,零成本迁移、全平台兼容、跨端开发零负担!
vue.js·uni-app·echarts
前端_Danny3 天前
使用 ECharts + ECharts-GL 生成 3D 环形图
3d·信息可视化·echarts
景早4 天前
小黑记账清单案例(axios,echarts,vue)
前端·vue.js·echarts
uuai4 天前
echarts不同版本显示不一致问题
前端·javascript·echarts
马卫斌 前端工程师5 天前
vue3 实现echarts 3D 地图
前端·javascript·echarts
盼哥PyAI实验室7 天前
纯前端打造个人成长网站:零后端、零部署、零服务器的实践分享
运维·服务器·前端·javascript·echarts·个人开发
Lsx_7 天前
详解ECharts中的convertToPixel和convertFromPixel
前端·javascript·echarts
java水泥工8 天前
基于Echarts+HTML5可视化数据大屏展示-工厂信息监控台
echarts·html5·可视化大屏·大屏模版