I'm trying to create a graph with D3, where the data needs to be loaded from a REST controller. Here is the code for the nodes I'm having problems with:
async function request(partNumber) {
var response = await fetch(restURL + partNumber)
var grafic = await response.text()
return grafic
}
nodes.selectAll("nodeSvg")
.data(d => [d])
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + [offsetX + d.x * scale + svgOffsetX, offsetY + d.y * scale + svgOffsetY] + ") scale(0.1 0.1)"; })
.html(async (d) => {
if (d.partNumber === "") {
return "";
}
return await request(d.partNumber);
});
As you can see I create to stream for the data. Each of the data entrys has a partNumber which I need to get an HTML string from the RestApi. This string is an SVG string which if hard coded produces a picture as node. But if I don't hardcode it and request it (which actually gives me a string if I set a breakpoint) the nodes are not created. How can I resolve this?
Thanks in advance!
EDIT: I'm using D3v5 which added Promises, but I'm not sure if and how this can help me
EDIT2: Made the question more clear
EDIT3: I found a solution which alows me to add the svgs after loading the rest of the graph, which is better if there are a lot of svgs to load from the REST Api. Here si how I did it:
async function request(partNumber) {
if (partNumber !== "") {
var response = await fetch(restURL + partNumber)
return await response.text()
}
}
drawing.nodes.forEach((d) => {
if (d.partNumber === "") {
d.graphic = "";
}
request(d.partNumber).then((e) => {
d.graphic = e;
nodes.selectAll("nodeSvg")
.data(d => [d])
.enter()
.append("g")
.attr("transform", function(d) {
return translateNode(d); })
.html((d) => {
return d.graphic
});
});
})
I just moved the part that creates the nodes into the ".then()" part. As it turns out D3 just updates changed values instead of redrawing it again and again as it is in a loop.
Anyways: Thank you Mikkel for your answer!