对于上下文:我在 React 应用程序中运行 D3,并将 D3 更新模式绑定到 React 生命周期方法。
问题: 当我const selection = select(".svg-circle-node-class").data(nodeArray)
运行该函数时,D3 总是为我提供数组中的每个节点,无论新节点是否已添加到数组中。我希望该函数selection.enter()
为我提供新的节点,并selection.exit()
为我提供不存在的节点以供删除,并且对于直接在此选择上完成的任何操作而不使用,enter()
应该为我提供所有剩余的节点,如下所示:
这个问题导致我无法区分新旧项目,这导致我总是重新附加新的 SVG 元素,因此每次状态发生变化时都会复制所有内容。我只想更新这些元素的值。
我的具体情况如下:我有一个图的实现,其结构如下:
class Graph {
nodes: Node[];
}
class DirectedEdge {
from: Node;
to: Node;
}
class Node {
x: number;
y: number;
edges: DirectedEdge[];
id: string; // unique for each node
}
在我的反应组件中,我通过在组件状态中保存图形的实例来跟踪图形的状态,如下所示:
const n1, n2: Node = ...;
interface IState {
g: Graph = new Graph(n1, n2), // constructor connects two graphs with an edge
degree: number // a parameter to change some shapes
}
我将图表的初始化与componentDidMount生命周期方法联系起来,这是执行此操作的函数:
/** Once HTML elements have loaded, this method is run to initialize the SVG elements using D3. */
private initializeGraph(): void {
const mainGroup = select(this.svgElement.current)
.append("g")
.attr("id", "main");
// append nodes svg group
this.nodeElements = mainGroup.append("g")
.attr("id", "nodes")
.selectAll<SVGCircleElement, Node>(".directed-graph-node")
.data<Node>(this.state.g.nodes, _ => _.id);
// append edges svg group
this.edgeElements = mainGroup.append("g")
.attr("id", "edges")
.selectAll<SVGPathElement, DirectedEdge>(".directed-graph-edge")
.data<DirectedEdge>(this.state.g.nodes.flatMap(_ => _.edges), _ => _.id);
}
我将一个updateGraph函数与componentDidUpdate生命周期函数绑定在一起,导致每次状态发生变化时都会调用它(即,在本例中,是由参数“ Degree”变化引起的。但我希望能够更新(x ,y) 每次更新时每个节点的位置)。
阿晨1998
相关分类