D3的问题是它用于改变正常工作的DOM。
这是一个很好的article with workaround for this problem。这是一个有点混乱的解决方案,但最终你会收到可以很好地处理反应的组件,并且你可以在其中编写本地D3代码。关键想法是:
反应句柄进入和退出元素,以及D3处理更新 属性。
例如,考虑这个(很简单)地区,我使用我的项目的图表:我已经简化代码,尽可能到仅剩下小的演示
const d3Visualization = {
enter(data) {
const width = this.props.width;
const height = this.props.height;
const x = d3.time.scale.utc().range([0, width]);
const y = d3.scale.linear().range([height, 0]);
const xAxis = d3.svg.axis()./* ... axis code */
const yAxis = d3.svg.axis()./* ... axis code */
const area = d3.svg.area()
.x(d => x(new Date(d.dateTime)))
.y0(height)
.y1(d => y(d.usage));
x.domain(d3.extent(data, d => new Date(d.dateTime)));
y.domain([0, d3.max(data, d => d.usage)]);
this.d3Path
.datum(data)
.transition(100)
.attr("d", area);
this.d3XAxis
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
this.d3YAxis
.call(yAxis)
}
};
class Area extends React.Component {
componentDidMount() {
this.d3Node = d3.select(ReactDOM.findDOMNode(this));
this.d3Path = this.d3Node.select("path.area");
this.d3XAxis = this.d3Node.select("g.x.axis");
this.d3YAxis = this.d3Node.select("g.y.axis");
}
componentDidUpdate() {
d3Visualization.enter.call(this, this.props.data)
}
render() {
return (
<svg width={this.props.width} height={this.props.height}>
<g transform="translate(20,10)">
<path className="area"/>
<g className="x axis"></g>
<g className="y axis">
<text></text>
</g>
</g>
</svg>
);
}
}
。在上面的文章中,您可以找到最常见问题的描述以及更复杂的演示组件。
下面是一个例子:https://github.com/EcutDavid/D3In20Days d3 with react。 –