我一直关注Shirley Wu's post about using React with D3并将问题分成单独的文件。我们的想法是visualisation
文件夹中的模块处理D3属性。
在我的示例中,文件visualisation/node.js
负责设置表示数据集的循环节点的属性。它们的位置应该基于它们的value属性和一个变量比例,它的域设置为数据值的范围。
比例本身是在加载数据的父组件中创建的,因此我没有看到任何传递方式。这到nodeViz.create
,其中设置了节点属性(包括它们的位置)。我也不相信该功能/模块对数据集有任何意识,允许在node.js
文件中重新创建比例。
使用比例尺来定位元素时,有没有办法实现这种分离?感觉我必须遗漏一些东西......
您可以see a version of this in codesandbox.io,但代码也在下面:
chart.js之
import React from "react";
import { extent, scaleLinear, select } from "d3";
import nodeViz from "./visualisation/node";
const width = 800;
const height = 500;
class Chart extends React.Component {
data = [
{ id: 0, value: 4 },
{ id: 1, value: 0 },
{ id: 2, value: 7 },
{ id: 3, value: 5 },
{ id: 4, value: 2 }
];
xScale = scaleLinear()
.range([0, width])
.domain(extent(this.data.map(d => d.value)));
createChart = () => {
// The following would normally happen on componentDidUpdate
// when we have some new data via the props, but in this
// case we're not async so the data will already exist.
const svg = select(this.node);
const nodes = svg.selectAll("circle").data(this.data, d => d.id);
nodes.enter().call(nodeViz.create);
nodes.exit().remove();
};
componentDidMount() {
this.createChart();
}
render() {
return (
<svg ref={node => (this.node = node)} width={width} height={height}>
<g />
</svg>
);
}
}
export default Chart;
可视化/ node.js的
const create = selection => {
return selection
.append("circle")
.attr("r", 3)
.merge(selection)
.attr("fill", "red")
.attr("cx", d => d.value) // Should be xScale(d.value)
.attr("cy", 150);
};
export default {
create
};
答案 0 :(得分:2)
我说实话,自从我写了这篇文章以来,我实际上有了一些新意见(尽管核心概念保持不变)已经这么多年了。在这种情况下,属性设置被分离出来,以便能够使用d3执行诸如转换/动画之类的操作(bc d3需要直接操作DOM,因此我们不想做出反应来跟踪它) 。你在秤中所拥有的是数据计算和渲染的分离,在这种情况下,我在渲染阶段之前完成数据计算。因此,在该示例中,数据计算happens in _onChange
和呈现happens in render
和GraphVisualization.update
。
如果我现在要这样做,我可能只是让React渲染所有东西(包括属性)或者让D3渲染所有东西(所以输入 - 更新 - 退出所有东西)。我在this talk中谈到了这一点。