收到新道具后,D3组件不会重新绘制

时间:2018-04-12 03:48:17

标签: reactjs d3.js

我正在React.js上构建一个小应用程序,我正在使用D3绘制与其收到的道具相对应的多维数据集。

class Visual extends React.Component {

renderD3 = (records, selector) => {
    const data = records;
    console.log('inside renderD3', data);
    // It logs out most updated props every time it receives new props

    const visual = this.props.connectFauxDOM('div', selector);
    d3
        .select(visual)
        .attr('class', 'visual-wrapper')
        .selectAll('div')
        .data(data) // bind data
        .enter()
        .selectAll('div') 
        .data(d => d3.range(d.duration / 5).map(() => d)) 
        .enter()
        .append('div')
        .attr('class', 'block')
        .style('background-color', d => d.color);
}

componentDidMount() {
// it is just for generating gray grids for background setting, please ignore 
    this.renderD3([{duration: 300, color: '#e6e6e6'}], 'defaultBox')
}
render() {
    this.renderD3(this.props.records, 'box')
    return (
        <div>
            <div className="line-container">{this.props.defaultBox}</div>
            <div className="line-container">{this.props.box}</div>
        </div>
    );
}

}

我想要实现的是,一旦visual组件接收到新道具,D3就会重新绘制新颜色(新道具有不同的颜色)。

到目前为止,在renderD3函数内,它接收新的道具,在控制台上,它会正确记录新的道具,但立方体仍然具有相同的颜色。问题是,如果我进行哈希刷新,那么颜色会随着D3中的颜色变化而使用新道具绘制立方体。

我想象一旦Visual组件在每次收到新道具时重新渲染,D3立方体将自动重绘(或更新)立方体。但是在renderD3函数内部思考,它会在每次重新渲染时接收新道具并记录新道具,D3立方体不会改变。

我对反应很满意但对D3没什么了解。 我正在使用react-faux-dom将d3与反应结合起来。

我很欣赏任何见解。

提前谢谢你。

2 个答案:

答案 0 :(得分:1)

let divs = d3
    .select(visual)
    .attr('class', 'visual-wrapper')
    .selectAll('div')
    .data(data) // bind data
    .enter()
    .selectAll('div') 
    .data(d => d3.range(d.duration / 5).map(() => d));

    divs.enter()
    .append('div')
    .attr('class', 'block')

    //update
    divs.style('background-color', d => d.color);

对于更新,您需要在渲染方法中破坏这样的代码。

参考:here

答案 1 :(得分:1)

因此,您可以使用const ReactFauxDOM = require('react-faux-dom'); class Visual extends React.Component { renderD3 = (data) => { console.log('inside renderD3', data); // It logs out most updated props every time it receives new props const el = ReactFauxDOM.createElement('div'); d3.select(el) .attr('class', 'visual-wrapper') .selectAll('div') .data(data) // bind data .enter() .selectAll('div') .data(d => d3.range(d.duration / 5).map(() => d)) .enter() .append('div') .attr('class', 'block') .style('background-color', d => d.color); return el.toReact(); } render() { return ( <div> <div className="line-container">{this.renderD3(this.props.records)}</div> </div> ); } } 工具,根据我的需要,这些工具在您不需要动画的时候真的可以保留吗? (我可能在这里错了......)

文档中存在已知问题,您不清楚是否需要使用此工具。您应该只能使用普通的无状态API:

connectFauxDOM

如果您打算使用动画,则需要createElement。如果您不需要执行此类操作,那么正常的toReactcreate table2 as select *, 1 as count, case when a=1 and tx="A_L" then "L" when a=1 and tx="A_L" then "L" when a=1 and tx="B_A" then "A" when a=1 and tx="C_E" then "E" when a=1 and tx in ("E_V","D_M","H_O","I_D") then "Other" when a=1 and tx="F_S" then "S" when a=1 and tx="G_L" then "L" when b=1 and tx="A_L" then "L" when b=1 and tx="B_A" then "A" when b=1 and tx="C_E" then "E" when a!=1 and b!=1 and tx="A_L" then "L" when a!=1 and b!=1 and tx="B_A" then "A" when a!=1 and b!=1 and tx="C_E" then "E" when a!=1 and b!=1 and tx in ("D_M","E_V","F_S","H_O","I_D") then "Other" when a!=1 and b!=1 and tx="G_L" then "L" end as tx1 from table1 流程应该更容易使用。我希望这有帮助!