效果图:

echartsLinkStyle.gif

代码实现:

import React, { Component } from 'react';
import * as echarts from 'echarts';
import moment from 'moment'
const { registerReactDom, logoutReactDom } = scriptUtil;

let style = document.createElement('style');
style.innerHTML = `
    .echarts-container {
        width: 100%;
        height: calc(100% - 80px);
        display: flex;
        justify-content: flex-start;
        flex-wrap: wrap;
        overflow: auto;
        // background:rgb(80, 202, 117);
    }
    .echarts-container li {
        list-style: none;
        margin-right: 20px;
        margin-bottom: 20px;
        border: 1px solid #000;
    }
    .echarts-container li:nth-child(3n){
        margin-right: 0;
    }
    .echarts-container li:last-child{
        margin-bottom: 0;
    }
    .no-data{
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 20px;
        color: #000;
    }
`;
document.head.appendChild(style);



class CustomComp extends Component {
    state = {
        data: {},
        xData: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
        chartInstances: {},
        currentHighlightIndex: null,
        chartType: 'bar' // 图表类型状态
    }
    componentDidMount = () => {
        registerReactDom(this, this.props);
    }
    componentWillUnmount() {
        logoutReactDom(this, this.props);
    }
    componentDidUpdate(prevProps, prevState) {
        if (prevState.currentHighlightIndex !== this.state.currentHighlightIndex) {
            this.highlightCharts(this.state.currentHighlightIndex);
        }
        if (prevState.chartType !== this.state.chartType) {
            this.updateAllCharts();
        }
    }
    // 数据初始化
    init = (data) => {
        let newData = _.groupBy(data, 'pn'); // 按pn分组
        /* 示例数据:
        {"B80005210603181143": [{dataDate:"2025-01", valSUM: 124829},...], 
         "B80005210603195057": [{dataDate:"2025-01", valSUM: 124829},...]}
        */
        // console.log(newData, 'newData');
        this.setState({
            data: newData
        })
        Object.keys(newData).forEach((key) => {
            let obj = newData[key];
            let yData = [];
            obj.forEach((item) => {
                yData.push(item.valSUM);
            })
            this.chartInit('analysis' + key, yData, obj[0].deviceName, key);

        })
    }
    // 图表初始化
    chartInit = (id, yData, name, key) => {
        let { xData, chartType } = this.state;
        let myChart = echarts.init(document.getElementById(id));
        var option = {
            backgroundColor: 'transparent',
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'cross',
                    // type: 'none',
                    crossStyle: {
                        color: '#000'
                    }
                },
                // 添加事件监听器
                showContent: true,
                formatter: params => {
                    let index = params[0].dataIndex;
                    let month = xData[index];
                    let value = params[0].value.toFixed(2);
                    let seriesName = params[0].seriesName;
                    this.setState({ currentHighlightIndex: index });

                    // return params[0].seriesName + '<br/>' + xData[index] + '月: ' + params[0].value.toFixed(2) + 'kw';
                    return `
                        <div style="background-color: #37586d; color: #fff; padding: 5px 15px; border-radius: 2px; line-height: 1.5;">
                            <strong style="color: #fff; font-size: 14px;">${seriesName}</strong><br/>
                        </div>
                        <div style="background-color: #fff; color: #000; padding: 5px 15px; border-radius: 2px; line-height: 1.5;">
                            <span style="color: #000;">${month}月 </span><span style="color: green;">&nbsp; ${value}</span> kw
                        </div>
                    `;
                },
                // 允许使用 HTML 内容
                useHTML: true,
                // 可选:设置 tooltip 的样式
                extraCssText: 'background-color: #37586d; color: #fff; padding: 0px 0px; border-radius: 2px; line-height: 1.5;border:none;'

            },
            grid: {
                top: '10%',
                right: '3%',
                left: '12%',
                bottom: '8%'
            },
            // 工具配置
            toolbox: {
                feature: {
                    dataView: { show: false, readOnly: false },
                    magicType: { show: true, type: ['line', 'bar'] },
                    restore: { show: false },
                    saveAsImage: { show: false }
                },
                iconStyle: {
                    borderColor: "#000",  // 图标默认颜色
                },
                emphasis: {
                    iconStyle: {
                        borderColor: "#000",  // 图标hover颜色
                    },
                },
            },
            legend: {
                data: [name],
                type: 'scroll',
                icon: 'circle',
                top: 5,
                right: 150,
                textStyle: {
                    color: '#000',
                    margin: '10',
                },
            },
            xAxis: [
                {
                    type: 'category',
                    data: xData,
                    axisPointer: {
                        type: 'shadow'
                    },
                    axisLabel: {
                        margin: 10,
                        color: '#000',
                        textStyle: {
                            fontSize: 16
                        },
                    },
                }
            ],
            yAxis: [
                {
                    type: 'value',
                    name: "kw",
                    nameTextStyle: {//y轴上方单位的颜色
                        color: '#000'
                    },
                    splitLine: { show: false },
                    axisLabel: {
                        formatter: '{value}',
                        color: '#000',
                        fontSize: 16
                    },
                    axisLine: { // 添加y轴轴线
                        show: true,
                        lineStyle: {
                            color: '#000' // 轴线颜色
                        }
                    },
                    axisTick: { // 添加y轴刻度
                        show: true,
                        lineStyle: {
                            color: '#000' // 刻度颜色
                        }
                    }
                }
            ],
            series: [
                {
                    name: name,
                    type: chartType,
                    // barWidth: '15%',
                    // itemStyle:{
                    //     color: '#DAC8A3'
                    // },
                    data: yData
                },
            ]
        };
        myChart.setOption(option, true)
        // 保存图表实例
        this.setState(prevState => ({
            chartInstances: {
                ...prevState.chartInstances,
                [key]: myChart
            }
        }));
        // 添加事件监听器
        myChart.on('mouseover', (params) => {
            this.setState({ currentHighlightIndex: params.dataIndex });
        });
        myChart.on('mouseout', () => {
            this.setState({ currentHighlightIndex: null });
        });
        // 图表类型切换
        myChart.on('magictypechanged', (params) => {
            this.setState({ chartType: params.currentType });
        });
    }

    // 高亮图表
    highlightCharts(index) {
        const { chartInstances } = this.state;
        Object.keys(chartInstances).forEach(key => {
            let chart = chartInstances[key];
            // 隐藏所有tooltip
            // chart.dispatchAction({
            //     type: 'hideTip'
            // });
            // // 取消高亮所有柱子
            // chart.dispatchAction({
            //     type: 'downplay'
            // });
            // 包含清除tooltip、柱子高亮、坐标轴指示器
            chart.dispatchAction({
                type: 'updateAxisPointer',
                xAxisIndex: 0,   // 对应你的 x 轴索引
                yAxisIndex: 0,   // 对应你的 y 轴索引
                tooltip: {
                    show: false  // 强制隐藏指示器
                }
            });

            // 完全重置图表状态,如果有图表类型切换,会被重置
            // chart.dispatchAction({
            //     type: 'restore'
            // });
        });
        // 高亮图表
        if (index !== null) {
            Object.keys(chartInstances).forEach(key => {
                let chart = chartInstances[key];
                // 触发tooltip显示
                chart.dispatchAction({
                    type: 'showTip',
                    seriesIndex: 0,
                    dataIndex: index
                });
                // 高亮柱子
                chart.dispatchAction({
                    type: 'highlight',
                    seriesIndex: 0,
                    dataIndex: index
                });

            });
        }
    }
    // 切换图表类型
    updateAllCharts = () => {
        const { chartInstances, chartType } = this.state;
        Object.keys(chartInstances).forEach(key => {
            let chart = chartInstances[key];
            let option = chart.getOption();
            option.series[0].type = chartType;
            chart.setOption(option);
        });
    };

    render() {
        const { data } = this.state;
        return (
            <ul className='echarts-container'>
                {Object.keys(data).length > 0 ?
                    Object.keys(data).map((key) => {
                        return (
                            <li id={'analysis' + key} style={{ width: '31%', height: '400px', backgroundColor: 'transparent' }} > </li>
                        )
                    }) :
                    <div className='no-data'>未查询到数据</div>
                }
            </ul>

        );
    }
}

export default CustomComp;
最后修改:2025 年 06 月 24 日
如果觉得我的文章对你有用,请随意赞赏