更新React中的d3元素



我正试图根据我在输入栏中的搜索输入来编辑这个bubblechart。现在,我把所有的d3代码放在Bubble.js中,然后在我的app.js中,我有一个searchinput元素,它将过滤我要显示的数据,然后在Bubble的状态下,我将其数据设置为过滤后的数据(名为RoadmapData)。然而,我的气泡图没有更新实际上,每次我键入内容时,都会呈现另一个气泡图,所以如果我键入3个字母,则会有三个相同且未经过滤的气泡图

这是我现在的代码:

import React, { Component } from "react";
import * as d3 from "d3";
class Bubble extends Component {
constructor(props) {
super(props);
this.state = {
dataset: { children: this.props.RoadmapData }
};
}
componentWillReceiveProps(nextProps) {
var diameter = 600;
var color = d3.scaleOrdinal(d3.schemeCategory10);
var bubble = d3
.pack(this.state.dataset)
.size([diameter, diameter])
.padding(1.5);
var svg = d3
.select("body")
.append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");
var nodes = d3.hierarchy(this.state.dataset).sum(function(d) {
return d.Count;
});
var node = svg
.selectAll(".node")
.data(bubble(nodes).descendants())
.enter()
.filter(function(d) {
return !d.children;
})
.append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
node.append("title").text(function(d) {
return d.Name + ": " + d.Count;
});
node
.append("circle")
.attr("r", function(d) {
return d.r;
})
.style("fill", function(d, i) {
return color(i);
});
node
.append("text")
.attr("dy", ".2em")
.style("text-anchor", "middle")
.text(function(d) {
return d.data.Name.substring(0, d.r / 3);
})
.attr("font-family", "sans-serif")
.attr("font-size", function(d) {
return d.r / 5;
})
.attr("fill", "white");
node
.append("text")
.attr("dy", "1.3em")
.style("text-anchor", "middle")
.text(function(d) {
return d.data.Count;
})
.attr("font-family", "Gill Sans", "Gill Sans MT")
.attr("font-size", function(d) {
return d.r / 5;
})
.attr("fill", "white");
}
render() {
return <div>{this.node}</div>;
}
}
export default Bubble;

我是d3的初学者,但我觉得问题要么是我使用了错误的生命周期方法(我在这里使用了componentWillReceiveProps,当我使用componentMount()并在搜索栏中键入时,没有任何变化。或者也许我不应该回这个?提前谢谢。

每次重新渲染组件时,componentWillReceiveProps函数都会创建一个新的可视化实例,并通过对node.append的调用将其添加到React创建的<div>节点中。您可以通过d3remove()函数删除以前创建的实例来避免这种情况。

如果你愿意引入另一个库,有一个名为React Faux Dom的库,它可以让你避免所有React生命周期的东西,只做render()函数中的所有事情。这可能会简化一些事情。

您还提到,图表每次都是未过滤的——这是因为您只在构造函数中将数据道具分配给state——这只在首次创建组件时运行一次。在这种情况下,看起来您可以安全地删除它,并每次从this.props.RoadmapData读取数据(似乎您没有对组件内部的状态进行任何更改)。

您只需要在render()的开头添加一行,就可以将数据转换为d3的正确格式,比如:

var roadmapDataForD3 = { children: this.props.RoadmapData };

最新更新