2016-02-02 79 views
1

所有:混淆有關反應,D3之間的重疊和衝突

我非常新的反應,我所要做的是把一個D3的數據可視化圖表到陣營組件,但有一個困惑:

我不太明白作出反應的virtualDOM,但有一點我相信是D3不能直接做就可以操作(唯一真正的DOM可以通過D3進行操作,對吧?),那麼問題是:

哪有我們充分利用了React?如果這是不正確的,任何人都可以給我一些代碼,同時使用D3和virtualDOM使數據更新操作和動畫化的圖表

感謝

回答

1

你是正確的,D3不上反應的虛擬操作DOM,因此D3與反應不直接兼容。這是不幸的,但基本上有兩種方法。

1)讓它在虛擬dom上運行。 react-faux-dom在這方面做得很好,並且在反應的背景下使很多D3的工作變得有意義。 https://github.com/Olical/react-faux-dom

2)使用逃生艙口,並直接操縱dom。本質上,截取componentWillReceiveProps中的新道具並將shouldComponentUpdate設置爲始終返回false。從那裏,從componentWillRecieveProps採取數據,並做你想要的dom參考D3的元素。

兩種情況都不是特別美麗。目前還沒有一個完美的解決方案來完成D3內部的反應應用程序。

+0

謝謝,所以說,如果我們忘記了D3 DOM操作,只是離開它的數學部分,你能告訴我如何操作像D3那樣的過渡動畫的虛擬DOM? – Kuan

+0

如果您使用'react-faux-dom',那麼使用['react-motion'](https://github.com/chenglou/react-motion)可能會帶來一些好運。如果你正在使用逃生艙口,那麼所有的東西都應該像在反應之外那樣工作,這樣你就可以做你會做的事情,就好像你不在反應中一樣。你只需要小心。 –

1

有一種方法,其中React處理真正的SVG元素和D3只是做數學。從互聯網例如:

class Line extends React.Component { 
    static contextTypes = { 
     xScale: React.PropTypes.func, 
     yScale: React.PropTypes.func 
    }; 

    render() { 
     let path = d3.svg.line() 
         .interpolate("linear") 
         .x(d => this.context.xScale(d.x)) 
         .y(d => this.context.yScale(d.y)); 

     return (
      <path d={path(this.props.data)} 
        stroke="#0077CC" 
        strokeWidth="3" 
        fill="none" /> 
     ); 
    } 
} 

class Chart extends React.Component { 
    static propTypes = { 
     width: React.PropTypes.number, 
     height: React.PropTypes.number, 
     data: React.PropTypes.shape({ 
      x: React.PropTypes.number.isRequired, 
      y: React.PropTypes.number.isRequired 
     }).isRequired 
    }; 

    static defaultProps = { 
     width: 400, 
     height: 200 
    }; 

    static childContextTypes = { 
     xScale: React.PropTypes.func, 
     yScale: React.PropTypes.func 
    }; 

    getChildContext() { 
     return { 
      xScale: this.getXScale(), 
      yScale: this.getYScale() 
     } 
    } 

    getXScale() { 
     return d3.scale.linear() 
       .domain(d3.extent(this.props.data, d => d.x)) 
       .range([0, this.props.width]); 
    } 

    getYScale() { 
     return d3.scale.linear() 
       .domain(d3.extent(this.props.data, d => d.y)) 
       .range([this.props.height, 0]); 
    } 

    render() { 
     return (
      <svg style={{ width: this.props.width, height: this.props.height }}> 
       <Line data={this.props.data} /> 
      </svg> 
     ); 
    } 
} 
2

,我覺得這樣做最簡單的事情是加載一個陣營組件內D3可視化componentDidMount()。然後您可以(在d3代碼中)訪問React屬性和狀態,在它們之間來回傳遞數據。 Here is an example.