hur*_*rtz 6 d3.js ecmascript-6 reactjs
我试图在当前版本 4 中了解 d3。具体来说:我试图在 react 和 es6 中为简单的折线图创建 x 轴。
我看过 Mike Bostock 的例子以及他是如何做到的:
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
Run Code Online (Sandbox Code Playgroud)
但这既不是 react 也不是 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>
}
Run Code Online (Sandbox Code Playgroud)
这是 React 和 ES6,但不是版本 4 中的 d3。
我可以尝试将第 3 版代码用于 d3 的第 4 版,但是: d3.select 非常困扰我。当我使用 react(或其中的其他库,如 d3)时,我不想进行 DOM 调用。React 应该用于以最有效的方式渲染到 DOM 中,而不是让我获取 DOM 节点。
所以,我的问题是:创建一个简单的 x 轴的反应方式是什么?或者,如果还没有这样的答案:采用 Mike Bostock 引用的代码的反应方式是什么?
经过几年试图在 React 中找出 d3 之后,这是我和我的团队发现的最好的处理轴的方法:
const Axis = props => {
const axisRef = axis => {
axis && props.axisCreator(select(axis));
};
return <g className={props.className} ref={axisRef} />;
};
Run Code Online (Sandbox Code Playgroud)
笔记
axisCreator
是由axisBottom
、axisLeft
等返回的函数。它是在组件外部创建的,目的是向用户展示 d3 轴库的全部功能。className
允许用户随意设置轴的样式。select
麻烦是可以理解的,但是如果你想让 d3 操作 DOM,它是必需的,如果你不让 d3 操作 DOM,你就失去了 d3 的所有功能(这是一个非常 酷的 库))。小智 5
如果您正在使用 React,那么您几乎可以控制 DOM 的工作方式,因为它是内部工作的。React 将在虚拟 DOM 树中渲染你的组件,然后找出页面中的 DOM 树在你插入根组件时和前者之间的区别。它将应用两棵树之间的差异,以便页面中的树看起来像虚拟树。
混合 d3 和 React 需要一些技巧。你使用 d3 的所有元素(节点或属性)不应该归 React 所有。否则会发生奇怪的事情。假设您transform
的g.axis
节点属性由 d3 设置,这意味着您不在 React 中渲染它。你让你的 d3 逻辑拥有它的独占所有权。
现在是下一步。如果您想使用其他工具来描述 DOM 节点,那么您必须将该逻辑放在componentWillMount
和 中componentDidUpdate
。基本上你只在Reactg
的render()
方法中渲染元素,然后在这两个 React 生命周期句柄中你可以改变g
元素的属性和里面的内容。
我将向您指出这篇文章,该文章更详细地介绍了方法,但我也想给我两分钱。从我对这两个函数的角度和经验来看,最好只将 d3 用于它的辅助函数(通用数学函数)。让渲染逻辑(DOM 组合)完全在 React 中完成,即使会出现代码重复。维护一致且没有两种不同渲染方法混合在一起的代码更容易。
TL; 博士; 将属性或节点所有权赋予 React 或 d3,以便它们一起工作;或者我的建议,在 React 中制作您自己的轴组件,输出与 d3 相同的 DOM 元素(或者如果您需要其他功能或样式,则不同)并且不要使用 d3 进行渲染。
希望我有所帮助。