function drawNetworkGraph(graphData, options = {}) {
options = addDefaults(options, { height: 1000, width: 1000 });
const div = html`<div style='max-width: 1000px; overflow-x: auto; padding: 0px; margin: 0px;'></div>`;
const MARGIN = 0;
const svg = d3
.select(div)
.append("svg")
.attr("width", options.width + MARGIN + MARGIN)
.attr("height", options.height + MARGIN + MARGIN)
.append("g")
.attr("transform", `translate(${MARGIN},${MARGIN})`);
const simulation = d3
.forceSimulation()
.force("link", d3.forceLink().id(d => d.id))
.force("charge", d3.forceManyBody().strength(-10))
.force("center", d3.forceCenter(options.width / 2, options.height / 2));
const link = svg
.append("g")
.attr("class", "links")
.selectAll("line")
.data(graphData.links)
.enter()
.append("line")
.attr('stroke', 'blue');
const node = svg
.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graphData.nodes)
.enter()
.append("circle")
.attr('fill', 'gray')
.attr("r", 20);
const text = svg
.append("g")
.attr("class", "text")
.selectAll("text")
.data(graphData.nodes)
.enter()
.append("text")
.text(d => d.id);
simulation.nodes(graphData.nodes).on("tick", ticked);
simulation.force("link").links(graphData.links);
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);
text
.attr("x", d => d.x - 5)
.attr("y", d => d.y + 5);
}
return div;
}