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>
相关推荐
Smile_ping2 天前
tooltip在真机上出现图形阴影?
echarts·tooltip图形阴影设置
金融小白数据分析之路2 天前
绍兴市镇街echarts 制作
前端·数据库·echarts
shmily麻瓜小菜鸡3 天前
浏览器在请求外部图片(403 Forbidden)问题
vue.js·vscode·echarts·angular.js
paopaokaka_luck3 天前
基于Springboot3+Vue3的高校选课系统(AI选课助手、协同过滤算法、分享到微博、扣扣、Echarts图形化分析)
网络·spring boot·网络协议·echarts
张人玉3 天前
基于 Vue 3 + ECharts + Express + SQLite 构建的新能源汽车销量数据分析与可视化平台——新能源汽车销量数据分析系统
数据库·vue.js·sqlite·echarts
想你依然心痛3 天前
让数据会说话,Vue 结合 ECharts 打造电力可视化大屏
echarts·vue3·数据大屏·电力可视化
张人玉4 天前
基于 Vue 3 + ECharts + Express + SQLite 构—— LDA 模型的新闻舆论主题识别与情感分析系统
vue.js·echarts·express
shmily麻瓜小菜鸡5 天前
前端“伪防盗链”方案
前端·javascript·vue.js·bootstrap·echarts
张人玉6 天前
基于 Vue 3 + ECharts + Express + SQLite 的可视化大屏与业务管理系统——YOLOv8 高精度车辆行人检测与计数系统
数据库·vue.js·yolo·sqlite·echarts·express
张人玉7 天前
基于 Vue 3 + ECharts + Express + SQLite 构建的鞋类零售数据分析与毛利预测平台——基于深度学习的鞋类销售数据分析系统
vue.js·sqlite·echarts·express