在 React 中使用 D3

2018-03-04

React 和 D3 都是十分出色的框架, 如何在 React 中使用 D3? 若有 D3 相助, React 应用的表现力将会更上一个台阶.

本文是对 Interactive Applications with React & D3 的学习笔记.

安装

通过以下命令安装:

yarn add d3

结合的难点

在 React 中结合 D3 的难点在于, 两个框架都是操作 DOM 的框架, 两者各有各的操纵方法, 两者之间是不兼容的.

解决这一问题的结合方法是, React 负责应用的结构, 在需要可视化的地方, 创建一个 svg, 传给 D3, D3 在 svg 内部施展操作.

示例

编写一个 React 结合 D3 的柱状图组件, 实现代码如下:

import React, { Component } from 'react';
import { scaleLinear } from 'd3';
import { max } from 'd3';
import { select } from 'd3';

class BarChart extends Component {
    constructor(props){
        super(props);
        this.createBarChart = this.createBarChart.bind(this)
    }

    componentDidMount() {
        this.createBarChart()
    }

    componentDidUpdate() {
        this.createBarChart()
    }

    createBarChart() {
        const node = this.node;
        const dataMax = max(this.props.data);

        const yScale = scaleLinear()
            .domain([0, dataMax])
            .range([0, this.props.size[1]]);

        select(node)
            .selectAll('rect')
            .data(this.props.data)
            .enter()
            .append('rect');

        select(node)
            .selectAll('rect')
            .data(this.props.data)
            .exit()
            .remove();

        select(node)
            .selectAll('rect')
            .data(this.props.data)
            .style('fill', '#fe9922')
            .attr('x', (d,i) => i * 25)
            .attr('y', d => this.props.size[1] - yScale(d))
            .attr('height', d => yScale(d))
            .attr('width', 25)
    }
    render() {
        return <svg ref={node => this.node = node}
                    width={this.props.width}
                    height={this.props.height}>
        </svg>
    }
}

调用方法:

<BarChart
    data={[1,2,3,4]}
    size={[500, 200]} />

总结

至此, 就完成了 React 与 D3 的结合.