function drawNodes(data, svg, nodes, nodeMap, signatures) {
const colorScale = d3.scaleOrdinal(d3.schemeCategory10);
const specialColor = new Map(signatures.map((d, i) => [d, colorScale(i)]));
const signatureSet = new Set(signatures);
const node = svg.append("g")
.style("opacity", .8)
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", d => `translate(${d.x},${d.y})`)
.style("cursor", "pointer")
.on("click", (event, node) => {
handleNodeClick(svg, node, nodeMap, data)
});
node.append("circle")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.attr("fill", d => {
const ancestor = findAncestor(d, nodeMap, signatureSet);
return specialColor.get(ancestor) || "#888";
})
.attr("fill-opacity", 0.8);
setNodeSize(data, nodes.map(n => n.id), svg);
node.append("text")
.text(nodeLabel)
.attr("dy", "0.31em")
.attr("x", 6)
.attr("text-anchor", "start")
.attr("paint-order", "stroke")
.attr("stroke", "white")
.attr("fill", "black");
svg.on("click", (event) => {
if (event.target.tagName === "svg") {
selectedNodes.clear();
selectedPaths.clear();
svg.selectAll("circle").style("opacity", .8);
svg.selectAll("path").style("opacity", .8);
svg.selectAll("text").style("opacity", 1).text(nodeLabel);
setNodeSize(data, nodes.map(n => n.id), svg);
}
});
}