{
const networkWidth = 300;
const networkHeight = 300;
const nodeRadius = 10;
const svg = d3.create('svg')
.attr('width', networkWidth)
.attr('height', networkHeight);
const nodesForce = nodes.map(d => ({...d}));
const linksForce = links.map(d => ({...d}));
const simulation = d3.forceSimulation(nodesForce)
.force('link', d3.forceLink(linksForce).id(d => d.id))
.force('center', d3.forceCenter(networkWidth / 2, networkHeight / 2))
.force('manyBody', d3.forceManyBody().strength(-100))
.force('collision', d3.forceCollide(nodeRadius));
const edges = svg.append('g')
.selectAll('line')
.data(linksForce)
.join('line')
.attr('stroke', '#d3d3d3')
.attr('fill', 'none')
.attr('stroke-width', 1)
const vertices = svg.append('g')
.selectAll('g')
.data(nodesForce)
.join('g');
vertices.append('circle')
.attr('r', nodeRadius)
.attr('fill', 'steelblue');
vertices.append('text')
.attr('fill', 'white')
.attr('dominant-baseline', 'middle')
.attr('text-anchor', 'middle')
.attr('font-family', 'sans-serif')
.attr('font-size', '16')
.attr('pointer-events', 'none')
.text(d => d.id);
simulation.on('tick', () => {
vertices.attr('transform', d => `translate(${d.x},${d.y})`);
edges.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
})
vertices.call(networkDrag(simulation));
invalidation.then(() => simulation.stop());
return svg.node();
}