在 React 项目中使用 ECharts

在 React 项目中使用 ECharts

说明

重要文件版本

  • “react”: “^16.2.0”
  • “echarts”: “^4.0.2”
  • “redux”: “^3.7.2”,
  • “react-router-dom”: “^4.2.2”
  • “react-router-redux”: “^5.0.0-alpha.9”
  • “react-hot-loader”: “^4.0.0-beta.21”

在 React 项目中使用 ECharts 生成图表,与使用其他第三方库没有太大的区别,只要在 React 的组件 componentDidMount 声明周期中初始化 ECharts 图表,然后在每次更新组件时调用 ECharts 实例的 setOption() 方法更新配置即可,以下记录了使用当中的一些细节

项目模板源码

编写 <Chart/> 图表组件

>

/*
* ECharts 组件基础部分
* */

import React, { PureComponent } from 'react';
import * as echarts from 'echarts';
import 'zrender/lib/svg/svg';
import throttle from '../../utils/throttle'; // 一个节流函数

export default class Chart extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            width: '100%',
            height: '100%'
        };
        this.chart = null;
    }
    /*
        注意:
            虽然在 componentDidMount 中组件已经被装配,
            但是如果设置容器宽高为百分比的值,那么容器的 clientWidth 和 clientHeight 有可能还处于计算中
            这个时候如果在容器中实例化 echarts,echarts 获得的 clientWidth 和 clientHeight 不一定是我们预期的,
            因此这里使用了定时器延迟实例化,也可以提前计算出像素之后 赋值给 width、height,这样不是百分比就没有问题
    */
    async componentDidMount() {
        console.log('did mount');
        // 初始化图表
        await this.initChart(this.el);
        // 将传入的配置(包含数据)注入
        this.setOption(this.props.option);
        // 监听屏幕缩放,重新绘制 echart 图表
        window.addEventListener('resize', throttle(this.resize, 100));
    }
    componentDidUpdate() {
        // 每次更新组件都重置
        this.setOption(this.props.option);
    }
    componentWillUnmount() {
        // 组件卸载前卸载图表
        this.dispose();
    }
    render() {
        const { width, height } = this.state;

        return (
            <div
                className="default-chart"
                ref={el => (this.el = el)}
                style={{ width, height }}
            />
        );
    }
    initChart = el => {
        // renderer 用于配置渲染方式 可以是 svg 或者 canvas
        const renderer = this.props.renderer || 'canvas';
        console.log(renderer);

        return new Promise(resolve => {
            setTimeout(() => {
                this.chart = echarts.init(el, null, {
                    renderer,
                    width: 'auto',
                    height: 'auto'
                });
                resolve();
            }, 0);
        });
    };
    setOption = option => {
        if (!this.chart) {
            return;
        }

        const notMerge = this.props.notMerge;
        const lazyUpdate = this.props.lazyUpdate;

        this.chart.setOption(option, notMerge, lazyUpdate);
    };
    dispose = () => {
        if (!this.chart) {
            return;
        }

        this.chart.dispose();
        this.chart = null;
    };
    resize = () => {
        this.chart && this.chart.resize();
    };
    getInstance = () => {
        return this.chart;
    };
}

其他组件中引用图表组件

/*
   Heatmap 热力图
*/
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/grid';
import 'echarts/lib/chart/heatmap';
import 'echarts/lib/component/visualMap';
import Chart from '../components/Chart/index';
import { getChart } from '../modules/charts/actions';

class HeatmapChart extends Component {
    constructor(props) {
        super(props);
        this.state = {
            renderer: 'canvas'
        };
    }
    async componentWillMount() {
        // 装载前 获取数据
        const path = '/heatmap';
        const key = 'heatmap';

        await this.props.getChart({ path, key });
    }
    render() {
        const renderer = this.state.renderer;
        const option = this.getOption();

        return <Chart renderer={renderer} option={option} />;
    }
    // getOption 这个函数主要用于配置 option,包括将数据配置进去
    // 也可以将其放在 state 中,然后通过 setState 更新
    getOption = () => {
        // 组装数据,返回配置 option
        const currentData = this.props.charts.heatmap;

        return {
            tooltip: {
                position: 'top'
            },
            grid: {
                containLabel: true
            },
            xAxis: {
                type: 'category',
                splitArea: {
                    show: true
                },
                boundaryGap: true
            },
            yAxis: {
                type: 'category',
                splitArea: {
                    show: true
                },
                boundaryGap: true
            },
            visualMap: {
                min: 0,
                max: 20,
                calculable: true,
                left: 'left',
                bottom: 'bottom',
                dimension: 2
            },
            dataset: {
                source: currentData
            },
            series: [
                {
                    name: '热力图',
                    type: 'heatmap',
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    encode: {
                        x: 0,
                        y: 1
                    },
                    tooltip: {
                        formatter(params) {
                            const [x, y, value] = params.data;

                            return [
                                `x: ${x}`,
                                `y: ${y}`,
                                `value: ${value}`
                            ].join('<br/>');
                        }
                    }
                }
            ]
        };
    };
}

export default connect(
    state => ({ charts: state.charts }),
    dispatch => ({
        getChart: bindActionCreators(getChart, dispatch)
    })
)(HeatmapChart);

其他

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值