Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3 与 React #63

Open
hsipeng opened this issue Aug 3, 2018 · 0 comments
Open

D3 与 React #63

hsipeng opened this issue Aug 3, 2018 · 0 comments
Labels

Comments

@hsipeng
Copy link
Owner

hsipeng commented Aug 3, 2018

D3 与 React

React render D3 图表

d3.csv('data.csv', (err, data) => {
    if (err) {
        console.log(err)
        return
    }
    ReactDOM.render(
        <App width={960} height={640} data={data} />,
        document.getElementById('root'),
    )
})

function App({width, height, data}) {
    return (
        <svg width={width} height={height}>
            <Bubbles data={data} />
        </svg>
    )
}

function Bubbles({data}) {
    const bubbles = data.map( ({id,x,y,r}) => <Bubble key={id} x={x} y={y} r={r} />)
    return (
        <g className="bubbles">
            {
                bubbles
            }
        </g>
    )
}

function Bubble({x,y,r}) {
    return (
        <circle cx={x} cy={y} r={r} />
    )
}
  • 优点
    • 结构化
    • 可读性强
  • 缺点
    • 没有用到d3.transition
    • 渲染比 D3 慢

D3 render 图表

shouldComponentUpdate(){ return false}
export class App extends React.Component {
    state = {
        g: null,
    }

    onRef = (ref) => {
        this.setState({ g: d3.select(ref) }, () => this.renderBubbles(this.props.data))
    }

    renderBubbles(data) {
        const bubbles = this.state.g.selectAll('.bubble').data(data, d => d.id)

        // Exit
        bubbles.exit().remove()

        // Enter
        const bubblesE = bubbles.enter().append('circle')
            .classed('bubble', true)
            .attr('r', 0)
            .attr('cx', d => d.x)
            .attr('cy', d => d.y)

        // Update
        // ...

        // can use animations like this now
        bubblesE.transition().duration(2000).attr('r', d => d.radius)
    }

    componentWillReceiveProps(nextProps) {
        // we have to handle the DOM ourselves now
        if (nextProps.data !== this.props.data) {
            this.renderBubbles(nextProps.data)
        }
    }

    shouldComponentUpdate() { return false }

    render() {
        const { width, height } = this.props
        return (
            <svg width={width} height={height}>
                <g ref={this.onRef} className="bubbles" />
            </svg>
        )
    }
}
  • 优点
    • D3 渲染
  • 缺点
    • 可读性不强
    • 结构性不强

D3 与 React 融合

React 渲染 (大部分)静态的组件(Container 、Title 、 Axis 、 Legend)

D3 渲染需要动效也就是数据部分(Data Series)

export default class App extends React.Component {
  state = {
    data: [],
    grouping: 'all',
  }

  onGroupingChanged = (newGrouping) => {
    this.setState({
      grouping: newGrouping,
    })
  }

  render() {
    const { data, grouping } = this.state
    return (
      <div className="App">
        <GroupingPicker onChanged={this.onGroupingChanged} active={grouping} />
        <BubbleChart width={width} height={height}>
          <Bubbles data={data} forceStrength={0.03} center={center} yearCenters={yearCenters} groupByYear={grouping === 'year'} />
          {
            grouping === 'year' &&
            <YearsTitles width={width} yearCenters={yearCenters} />
          }
        </BubbleChart>
      </div>
    )
  }
}
  • 优点
    • 良好的文件结构,可读性强
    • 直接引用了D3 动态渲染

参考

How to use D3.js in React | cmichel

@hsipeng hsipeng added react react D3 labels Aug 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant