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>
相关推荐
小小愿望21 小时前
ECharts 实战技巧:揭秘 X 轴末项标签 “莫名加粗” 之谜及破解之道
前端·echarts
じòぴé南冸じょうげん1 天前
解决ECharts图表上显示的最小刻度不是设置的min值的问题
前端·javascript·echarts
我在北国不背锅2 天前
基于Java的Markdown转Word工具(标题、段落、表格、Echarts图等)
java·word·echarts·markdown
码界筑梦坊2 天前
135-基于Spark的抖音数据分析热度预测系统
大数据·python·数据分析·spark·毕业设计·echarts
安卓开发者2 天前
RxJava 核心概念解析:构建响应式Android应用的基石
android·echarts·rxjava
码界筑梦坊5 天前
105-基于Flask的珍爱网相亲数据可视化分析系统
python·ai·信息可视化·flask·毕业设计·echarts
安卓开发者5 天前
深入理解Android Kotlin Flow:响应式编程的现代实践
android·kotlin·echarts
别来无恙1498 天前
Spring Boot + ECharts 极简整合指南:从零实现动态数据可视化大屏
spring boot·信息可视化·echarts
莲青见卿8 天前
react+echarts实现变化趋势缩略图
javascript·react.js·echarts
爱吃香菇的小白菜9 天前
echarts、antv图表类 y轴范围 计算方法
前端·echarts