我试图在当前版本4中绕过d3。具体来说:我试图为react和es6中的简单折线图创建x轴。
我已经看过Mike Bostock的例子以及他是如何做到的:
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
但这既不是反应也不是ES6。
在另一个网站上,我看到了以下变体:
renderAxis() {
var node = this.refs.axis;
var axis = d3.svg.axis().orient(this.props.orient).ticks(5).scale(this.props.scale);
d3.select(node).call(axis);
}
render() {
return <g className="axis" ref="axis" transform={this.props.translate}></g>
}
这是反应和ES6,但不是版本4中的d3。
我可以尝试将版本3代码应用到d3的第4版但是:d3.select非常困扰我。当我使用react(或者其他一些库,比如d3)时,我不想进行DOM调用。应该使用React以最有效的方式呈现到DOM中,而不是让我获得DOM节点。
所以,我的问题是: 创建一个简单的x轴的反应方式是什么?或者,如果还没有这样的答案:采用Mike Bostock引用代码的反应方式是什么?
答案 0 :(得分:3)
如果您正在使用React,那么您几乎可以控制DOM如何工作到React,因为它的内部工作原理。 React会将您的组件呈现在虚拟DOM树中,然后在插入根组件和前者时,找出页面中DOM树之间的差异。它将应用两棵树之间的差异,以便页面中的树看起来像虚拟树。
混合d3和React需要一些技巧。您使用d3(节点或属性)的所有元素都不应归React所有。否则会发生奇怪的事情。假设transform
节点的g.axis
属性由d3设置,这意味着您不在React中渲染它。你让你的d3逻辑拥有它的独家所有权。
现在进入下一步。如果您想使用其他工具来描述DOM节点,那么您必须将该逻辑放在componentWillMount
and componentDidUpdate
中。基本上,您只在React的g
方法中呈现render()
元素,然后在这两个React生命周期句柄中,您可以更改g
元素的属性以及内部的内容。
我会指向你post that goes a bit more in detail about the hows,但我也想给我两分钱。根据我对这两者的看法和经验,最好只使用d3作为辅助函数(通用数学函数)。让渲染逻辑(DOM组合)完全在React中完成,即使出现了代码重复。维护代码是一致的,并且没有两种不同的方法来混合在一起,这样更容易。
TL; DR;将属性或节点所有权赋予React或d3以使它们一起工作;或者我的建议,在React中创建自己的轴组件,输出与d3相同的DOM元素(如果需要其他功能或样式,则输出不同),不要使用d3进行渲染。
希望我帮助过。
答案 1 :(得分:1)
经过几年尝试在React中找出d3的方法,这是我团队和我发现做轴的最好方法:
const Axis = props => {
const axisRef = axis => {
axis && props.axisCreator(select(axis));
};
return <g className={props.className} ref={axisRef} />;
};
注释
axisCreator
是axisBottom
,axisLeft
等返回的函数。它是在组件外部创建的,以向用户展示d3轴库的全部功能。className
允许用户根据自己的需要来设置轴的样式。select
会打扰您,但是如果您想让d3操纵DOM是必需的,并且如果您不让d3操纵DOM,那么您将失去所有的功能d3(这是incredibly cool library)。答案 2 :(得分:0)
直接使用React而不是d3的select API渲染轴的代码实际上并不那么复杂。 react-d3-axis提供了一个非常简单的~100 loc实现。使用这种方法,您可以使用d3进行数据转换和比例插值之类的操作,并使用React进行渲染。