viewof chart = {
let data = {
nodes: [{id: 2, x: width/2, y: height/2}, {id: 3, x: width/2+50, y: height/2}],
links: [{source: {id: 2, x: width/2, y: height/2}, target: {id: 3, x: width/2+50, y: height/2}}]
}
const svg = d3.select(DOM.svg(width, height))
.property("value", data);
console.log(svg.property('value'))
const simulation = d3.forceSimulation(svg.property("value").nodes)
.force("link", d3.forceLink(svg.property("value").links).id(d => d.id))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("charge", d3.forceManyBody())
.alphaDecay(0.0002).restart()
.on("tick", ticked);
let g = svg.append("g").attr("class", "outer-g")
let nodes = g.selectAll("g").data(svg.property("value").nodes, d => d.id);
let edges = g.selectAll("line").data(svg.property("value").nodes);
function update() {
nodes = g.selectAll("g").data(svg.property("value").nodes, d => d.id);
edges = g.selectAll("line").data(svg.property("value").nodes);
nodes.exit().remove()
edges.exit().remove()
const enterEdges = edges.enter().append("line").lower()
.attr("stroke", "gray")
.attr("stroke-opacity", 0.3)
.attr("stroke-width", 1)
const enterNodes = nodes.enter().append("g")
.attr('transform', d => `translate(${d.x},${d.y})`)
.call(drag())
enterNodes.append('circle')
.attr("class", "node");
enterNodes.append('text')
.attr("pointer-events", "none")
.style("pointer-events", "none")
.style("-webkit-touch-callout", "none")
.style("-webkit-user-select", "none")
.style("-khtml-user-select", "none")
.style("-moz-user-select", "none")
.style("-ms-user-select", "none")
.style("-o-user-select", "none")
.style("user-select", "none")
.attr('fill', 'black')
enterNodes.append('title')
.text(d => d.desc)
nodes = nodes.merge(enterNodes);
nodes.selectAll('.node')
.attr("stroke", "#FFF")
.attr("stroke-width", 0.2)
.attr("r", 6)
.attr("fill", d => d.explored ? 'steelblue' : 'gray')
edges = edges.merge(enterEdges);
simulation.nodes(data.nodes)
.force("link", d3.forceLink(data.links).id(d => d.id))
.alphaTarget(0.0002).alpha(1).restart()
}
var zoom_handler = d3.zoom()
.on("zoom", () => {g.attr("transform", d3.event.transform)})
.scaleExtent([0.1, 100]);
zoom_handler(svg);
function ticked() {
console.log(nodes.data())
update()
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);
nodes
.attr("transform", d => `translate(${d.x},${d.y})`);
svg.property("value", data).dispatch("input")
};
const drag = () => {
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.0002).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
return svg.node()
}