I have the following function:
export async function drawTechTree(techData, svgElement) {
let graphDef = "digraph TechTree {\n";
graphDef += 'node [style="filled", color="black", fontcolor="white", fillcolor="black", fontname="Arial"];\n';
for (const [key, value] of Object.entries(techData)) {
const price = value.price || "Unknown";
const label = `<b>${key}</b><br/>Price: ${price}`;
graphDef += `${key} [label=<${label}> shape="box"];\n`;
}
for (const [key, value] of Object.entries(techData)) {
const appearsAt = value.appearsAt || [];
if (appearsAt.length > 1) {
for (let i = 1; i < appearsAt.length; i++) {
const prereq = appearsAt[i];
if (prereq) {
graphDef += `${prereq} -> ${key};\n`;
}
}
}
}
graphDef += "}";
console.log("Graph definition:", graphDef);
try {
console.log("Rendering graph...");
await new Promise((resolve, reject) => {
d3.select(svgElement)
.graphviz()
.zoom(false)
.renderDot(graphDef)
.on("end", () => {
console.log("Graph rendered successfully");
resolve();
})
.on("error", (err) => {
console.error("Error while rendering the graph:", err);
reject(err);
});
});
} catch (error) {
console.error("An error occurred during graph rendering:", error);
}
}
I am passing in:
fetch('./resources/techData.json')
.then((response) => response.json())
.then((techData) => {
drawTechTree(techData, '#techTreeSvg');
})
.catch((error) => console.error('Error loading tech data:', error));
This gives graphDef
have a perfectly formed DOT string that I can render in other online services that render these in svg's.
However that is where it all goes wrong.
.renderDot(graphDef)
- if I debug through this it gives no clues as to what is happening, but it is not rendering in the specified element that is for sure.
The only console output in this function is related to web workers and I dont think this will affect the render. In fact I tried passing in 'digraph {a -> b}'
and that didn't render neither. The svg is in the DOM and it is with the correct id and I can see it in my web page.
So have you got any advice for me, anything missing from the code? Thanks for reading.
Just to mention I have tried with and without the Promise
I included in this snippet. None of the .on()
provide anything useful and the .on("end"...)
never triggers.