echarts点击选中操作(react)

本文介绍了一个React应用中使用Echarts实现柱状图点击选中并变色的需求。允许最多选中五个柱子,每个柱子对应不同颜色且不重复。关键在于利用Echarts的itemStyle.normal.color属性及lodash的_.xor函数处理颜色数组,确保颜色不重复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近的一个需求,做出来之后觉得很简单的一个操作,分享出来

需求是这样的:echarts的柱状图,点击可以选中变色,最多可以选中五个柱子,五个柱子五个颜色,不能重复。

先看个效果:

在这里插入图片描述

然后上代码:

import React, { Component } from 'react';
import * as echarts from 'echarts';
import ReactEcharts from 'echarts-for-react';
import styles from '../details.less';
import _ from 'lodash'

const colorLists = {
    "0" : "#6bd6fc",
    "1": "#3beaab",
    "2": "#fd9087",
    "3": "#adc6ff",
    "4": "#fed856",
}
let unused = [1];
let initialCid = [0,1,2,3,4]
class Bar extends Component {
    render() {
        const textColor = "#464c5b";
        const axisColor = "#657180";
        const handleChartClick = params => {
            const platform = params.data;
            const quota = this.props.articleDetails[showType];
            const { show } = this.props.articleDetails;
            if (show[showType]) {
                const { current } = quota;
                let existed = false;
                for (let i = 0; i < current.length; i++) {
                    const plat = current[i];
                    if (Number(plat.id) === Number(platform.id)) {
                        if (current.length > 1) {
                            current.splice(i, 1);
                        }
                        existed = true;
                        break;
                    }
                }
                if (!existed) {
                    let cid = 0;
                    if (current.length > 4) {
                        cid = unused[0];
                        current.shift();
                    } else {
                        cid = unused[0];
                    }
                    current.push({ ...platform , "cid": cid});
                }
            } else {
                quota.current = [{...platform, "cid": 0 }];
                show[showType] = !!!show[showType];
                this.props.dispatch({ type: 'articleDetails/setState', payload: { show } });
            }
            const colorIdArr = quota.current.map(i =>{return i.cid})
            if (quota.current.length > 4) {
                unused[0] = colorIdArr[0]
            } else {
                unused = (_.xor(initialCid, colorIdArr)).sort((a, b) => {return a - b} );
            }
            this.props.dispatch({ type: 'articleDetails/setQuota', payload: quota });
        }
        const handleColorClick = (param) => {
            const quota = this.props.articleDetails[showType];
            if(Array.isArray(hightlight) && hightlight.indexOf(param['name']) !== -1) {
                const cid = quota.current.filter((item) => { return item.id === param.data.id});
                return colorLists[cid[0].cid];
            } else {
                return '#66aaff';
            }
        }
        const option = {
            animation: false,
            grid: {
                top: 60,
                bottom: 60,
                left: 60,
                right: 60,
            },
            color: color,
            title: {
                text: title,
                textStyle: {
                    color: textColor,
                    fontWeight: 'normal',
                    fontSize: 12
                },
                top: 0
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow',
                    shadowStyle: {
                        color: '#3ba1ff',
                        opacity: .1
                    }
                }
            },
            xAxis: {
                type: 'category',
                data: Object.keys(data).length > 0 && data.map(item => item.name),
                axisLine: {
                    lineStyle: {
                        color: "rgba(158,167,180,1)",
                        width: 2,
                    }
                },
                axisTick: { show: false },
                axisLabel: {
                    fontSize: 12,
                    color: axisColor,
                    padding: [16, 0, 0, 0],
                    interval: 0,
                }
            },
            yAxis: {
                type: 'value',
                minInterval: 1,
                axisLine: { show: false },
                axisTick: { show: false },
                axisLabel: {
                    fontSize: 12,
                    color: axisColor,
                },
                splitLine: {
                    lineStyle: {
                        type: "dashed"
                    }
                }
            },

            series: [{
                data: data,
                type: 'bar',
                barWidth: 38,
                itemStyle: {
                    normal: {
                        color: handleColorClick,//操纵点击后的颜色
                        borderColor: '#3ba1ff',
                        borderWidth: 0,
                    }
                },

            }]
        };
        
        return (
            <div className={styles.chart} style={{ height: height }}>
                <ReactEcharts
                    onEvents={{
                        click: handleChartClick
                    }}
                    notMerge={true}
                    lazyUpdate={true}
                    option={option}
                    style={{ width: '100%', height: '100%' }} />
            </div>
        );
    }
}

export default Bar;


变色操作参考echarts官网
series > itemStyle > normal > color 的用法自行搜索 = =
在这里插入图片描述

主要代码是在两个函数里

大概就是仨个数组,一个已使用数组,一个待使用数组,一个需使用数组
点击后把当前点击的数据存到一个数组 点到第六个的时候 shift()
loadash函数_.xor用来筛选非重复的元素,代表此颜色id还没有用过,可以放到待使用数组中
其实就是对数据的操作
完毕

<think>嗯,用户问的是ECharts中饼图的点击事件。我需要先回忆一下ECharts的相关知识,确保自己理解正确。饼图是常用的数据可视化图表,点击事件应该涉及用户与图表的交互部分。首先,ECharts的事件处理机制是怎样的?记得ECharts支持多种事件,比如点击、鼠标悬停等,而饼图的点击事件可能和其他图表有所不同,因为饼图有扇形区域,可能需要区分点击的是整个饼图还是某个具体的扇形。 接下来,用户可能需要知道如何绑定点击事件。在ECharts中,通常使用on方法来绑定事件。比如,chart.on('click', function(params) { ... });。这里要注意事件类型是否正确,饼图的点击事件是否属于普通的click事件,还是有特定的事件名称。需要确认文档中的事件部分,尤其是饼图相关的事件是否有特殊处理。 另外,饼图的每个扇形可能对应不同的数据,点击事件触发时,如何获取被点击扇形的数据信息?回调函数中的params参数应该包含相关信息,比如params.name、params.value等。可能需要详细说明params对象的结构,以及如何利用这些数据做后续处理,比如更新其他图表或显示详细信息。 还有,用户可能想知道点击事件的一些应用场景。比如,点击某个扇形后,可以下钻显示更详细的数据,或者联动其他图表进行筛选。这时候需要举一些实际的例子,说明如何通过事件处理函数实现这些功能。 此外,需要注意ECharts的版本差异。不同版本的ECharts可能在事件处理上有细微差别,是否需要提醒用户检查版本?或者是否有常见的兼容性问题需要提及? 还有,用户可能会遇到事件不触发的情况,这时候应该检查是否正确绑定了事件,是否正确引用了ECharts库,以及DOM元素是否存在等问题。可以简要提到一些排查步骤,帮助用户解决潜在问题。 最后,是否需要提供完整的代码示例?比如初始化图表、绑定点击事件的具体代码,以及如何处理参数。这样用户可以直接参考示例代码进行实现,提高回答的实用性。 总结一下,回答需要包括:饼图点击事件的基本概念、绑定方法、参数获取、应用示例以及常见问题处理。结构要清晰,分步骤讲解,确保用户能逐步理解和实现功能。</think>在 ECharts 中,饼图的点击事件是实现交互功能的重要机制。以下是逐步说明: --- ### **1. 事件绑定原理** ECharts 通过 `on` 方法绑定事件,语法为: ```javascript myChart.on('事件类型', function(params) { // 事件处理逻辑 }); ``` 对于饼图,常用 `'click'` 类型触发点击事件。 --- ### **2. 获取点击数据** 回调函数参数 `params` 包含以下关键信息: ```javascript { componentType: 'series', seriesType: 'pie', // 表明是饼图系列 name: '类别名称', // 如"电子产品" value: 数值, // 如5000 data: 原始数据项 // 包含name/value等完整数据 } ``` --- ### **3. 基础代码示例** ```javascript // 初始化图表 const myChart = echarts.init(document.getElementById('chart')); // 配置项 const option = { series: [{ type: 'pie', data: [ { name: '电子产品', value: 5000 }, { name: '服装', value: 3000 } ] }] }; // 绑定点击事件 myChart.on('click', function(params) { console.log('点击的类别:', params.name); console.log('对应的数值:', params.value); }); // 渲染图表 myChart.setOption(option); ``` --- ### **4. 典型应用场景** #### **场景1:联动更新其他图表** ```javascript myChart.on('click', params => { // 根据点击的类别过滤其他图表数据 otherChart.setOption({ dataset: { source: getFilteredData(params.name) } }); }); ``` #### **场景2:显示详细信息弹窗** ```javascript myChart.on('click', params => { const detail = `销售额:$${params.value}`; document.getElementById('tooltip').innerHTML = detail; }); ``` --- ### **5. 高级:阻止默认行为** 若需禁用自动高亮效果,在事件中返回 `false`: ```javascript myChart.on('click', params => { // 自定义逻辑... return false; // 阻止默认的选中动画 }); ``` --- ### **6. 常见问题排查** - **事件未触发**:检查 DOM 容器尺寸是否有效,确认 `myChart` 已正确初始化 - **参数未获取**:确保事件类型为 `'click'`,且数据格式符合饼图要求 - **异步问题**:在 Vue/React 中注意事件绑定时机,需在图表渲染后执行 通过合理利用点击事件,可以实现数据钻取、图表联动等复杂交互功能。建议结合官方文档中的 [events](https://echarts.apache.org/zh/api.html#events) 部分进行扩展学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值