如何解决如何通过D3从ReactJS中删除先前的实例?
我想每次更改数据(数据是基于用户交互(例如按钮单击)生成的数据)时绘制的树状图。每次更改数据时,都会创建一个新的树形图,但它会在前一个树形图的上方绘制-这意味着我可以在屏幕上看到两个树形图。不知何故,前一个实例并未删除。
我查看了this和this,并应用了remove()
函数通过d3删除了先前的实例。但是,它不起作用。我可能在生命周期中没有正确使用remove
函数。
d3.select("treemap").remove();
用于第二种useEffect
方法。
export function Treemap({ width,height,data }) {
const ref = useRef();
useEffect(() => {
const svg = d3
.select(ref.current)
.attr("id","treemap")
.attr("width",width)
.attr("height",height);
},[]);
useEffect(() => {
//THIS IS WHERE I USE REMOVE FUNCTION;
d3.select("treemap").remove();
draw();
},[data]);
const draw = () => {
const svg = d3.select(ref.current);
// Give the data to this cluster layout:
var root = d3.hierarchy(data).sum(function (d) {
return d.value;
});
// initialize treemap
d3
.treemap()
.size([width,height])
.paddingTop(28)
.paddingLeft(0)
.paddingRight(0)
.paddingBottom(7)
.paddingInner(3)(root);
const color = d3
.scaleOrdinal()
.domain(["Diary","Sweetner","Fruit"])
.range(["#8FD175","#402D54","#E67E22"]);
const opacity = d3.scaleLinear().domain([10,30]).range([0.5,1]);
// Select the nodes
var nodes = svg.selectAll("rect").data(root.leaves());
// draw rectangles
nodes
.enter()
.append("rect")
.attr("x",function (d) {
return d.x0;
})
.attr("y",function (d) {
return d.y0;
})
.attr("width",function (d) {
return d.x1 - d.x0;
})
.attr("height",function (d) {
return d.y1 - d.y0;
})
.style("stroke","black")
.style("fill",function (d) {
return color(d.parent.data.name);
})
.style("opacity",function (d) {
return opacity(d.data.value);
});
nodes.exit().remove();
// select node titles
var nodeText = svg.selectAll("text").data(root.leaves());
// add the text
nodeText
.enter()
.append("text")
.attr("x",function (d) {
return d.x0 + 5;
}) // +10 to adjust position (more right)
.attr("y",function (d) {
return d.y0 + 20;
}) // +20 to adjust position (lower)
.text(function (d) {
return d.data.name;
})
.attr("font-size","19px")
.attr("fill","white");
// select node titles
var nodeVals = svg.selectAll("vals").data(root.leaves());
// add the values
nodeVals
.enter()
.append("text")
.attr("x",function (d) {
return d.y0 + 35;
}) // +20 to adjust position (lower)
.text(function (d) {
return d.data.value;
})
.attr("font-size","11px")
.attr("fill","white");
// add the parent node titles
svg
.selectAll("titles")
.data(
root.descendants().filter(function (d) {
return d.depth == 1;
})
)
.enter()
.append("text")
.attr("x",function (d) {
return d.y0 + 21;
})
.text(function (d) {
return d.data.name;
})
.attr("font-size",function (d) {
return color(d.data.name);
});
};
return (
<div className="chart">
<svg ref={ref}></svg>
</div>
);
}
解决方法
通常,对于d3,您永远不会删除已经绘制的节点。 (从计算上来说)便宜得多,并且只需重新调整用途即可!
如果您确实要删除所有节点,d3.select("treemap")
不会执行任何操作,因为“ treemap”不是有效的选择器。尝试使用#treemap
。
或者,如果要重新利用已绘制的位,请考虑以下事项:
function Treemap({
width,height
}) {
const ref = React.useRef();
const [data,setData] = React.useState(`
{
"name": "Fruit","children": [
{ "name": "Apples","value": 1 },{ "name": "Oranges",{ "name": "Bananas","value": 1 }
]
}
`);
React.useEffect(() => {
const svg = d3
.select(ref.current)
.attr("id","treemap")
.attr("width",width)
.attr("height",height);
},[]);
React.useEffect(() => {
draw();
},[data]);
const draw = () => {
const svg = d3.select(ref.current);
let parsedData
try {
parsedData = JSON.parse(data);
} catch (e) {
console.log(e);
return;
}
// Give the data to this cluster layout:
var root = d3.hierarchy(parsedData).sum(function(d) {
return d.value;
});
// initialize treemap
d3
.treemap()
.size([width,height])
.paddingTop(28)
.paddingLeft(0)
.paddingRight(0)
.paddingBottom(7)
.paddingInner(3)(root);
const color = d3
.scaleOrdinal()
.domain(["Diary","Sweetner","Fruit"])
.range(["#8FD175","#402D54","#E67E22"]);
const opacity = d3.scaleLinear().domain([10,30]).range([0.5,1]);
// Select the nodes
var nodes = svg.selectAll("rect").data(root.leaves());
// draw rectangles
var newNodes = nodes
.enter()
.append("rect")
.style("stroke","black");
nodes.merge(newNodes)
.attr("x",function(d) {
return d.x0;
})
.attr("y",function(d) {
return d.y0;
})
.attr("width",function(d) {
return d.x1 - d.x0;
})
.attr("height",function(d) {
return d.y1 - d.y0;
})
.style("fill",function(d) {
return color(d.parent.data.name);
})
.style("opacity",function(d) {
return opacity(d.data.value);
});
nodes.exit().remove();
// select node titles
var nodeVals = svg.selectAll(".val").data(root.leaves());
nodeVals.exit().remove();
// add the values
var newNodeVals = nodeVals
.enter()
.append("text")
.classed("val",true)
.attr("font-size","11px")
.attr("fill","white");
nodeVals.merge(newNodeVals)
.attr("x",function(d) {
return d.x0 + 5;
}) // +10 to adjust position (more right)
.attr("y",function(d) {
return d.y0 + 35;
}) // +20 to adjust position (lower)
.text(function(d) {
return d.data.value;
});
// add the parent node titles
var titles = svg
.selectAll(".title")
.data(
root.descendants().filter(function(d) {
return d.depth == 1;
})
);
titles.exit().remove();
var newTitles = titles
.enter()
.append("text")
.classed("title","19px");
titles.merge(newTitles)
.attr("x",function(d) {
return d.x0 + 5;
})
.attr("y",function(d) {
return d.y0 + 21;
})
.text(function(d) {
return d.data.name;
})
.attr("fill",function(d) {
return color(d.data.name);
});
};
return ( <
div className = "chart" >
<
textarea onChange = {
(el) => setData(el.target.value)
}
value = {
data
}
rows = "20"
cols = "50" / >
<
svg ref = {
ref
} > < /svg> <
/div>
);
}
ReactDOM.render( <
Treemap width = "600"
height = "300" / >,document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.js"></script>
<div id="root"></div>
无论如何,所有选择器都缺少.
类前缀。我建议您阅读选择器以及enter(),exit(),merge()
生命周期。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。