chart = {
const links = data.links.map(d => Object.create(d));
const nodes = data.nodes.map(d => Object.create(d));
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(200))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 3, height / 3))
.on("tick", ticked);
const svg = d3.select(DOM.svg(width, height));
const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.2)
.attr("marker-end", "url(#arrow)")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke-width", 0.5);
const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", .5)
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", color)
node.append("title")
.text(d => d.id);
node.on("mouseover", (d) => {
link.style('stroke-opacity', function(l) {
if (d === l.source) return 1;
else return 0;
});
link.style('stroke-width', function(l) {
if (d === l.source) return 1;
else return 0;
})
})
.on("mouseout", (d) => {
link.style("stroke-opacity", 0.2);
link.style("stroke-width", 0.5)
});
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 20)
.attr("refY", 0)
.attr("opacity", 0.2)
.attr("markerWidth", 8)
.attr("markerHeight", 8)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
function ticked() {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
}
return svg.node();
}