chart = {
const nodes = data.nodes.map(d => Object.create(d));
const index = new Map(nodes.map(d => [d.id, d]));
const links = data.links.map(d => Object.assign(Object.create(d), {
source: index.get(d.source),
target: index.get(d.target)
}));
const membership = new Map(nodes.map((d,i) => [i,d.group]));
const container = d3.select(
html`<div style="position:relative;">${groupSelection}</div>`
);
const svg = container.append("svg").attr("viewBox", `0 0 ${width} ${height}`);
const layout = cola.d3adaptor(d3)
.size([width, height])
.nodes(nodes)
.links(links)
.jaccardLinkLengths(40, 0.7)
.start(30);
const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("line")
.attr("class", d => `_${membership.get(d.source.index)} _${membership.get(d.target.index)}`)
.attr("stroke-width", d => Math.sqrt(d.value));
const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("class", d => `_${d.group}`)
.attr("r", 5)
.attr("fill", d => color(d.group))
.text(d => d.id)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.call(layout.drag);
// node.append("title")
// .text(d => d.id);
layout.on("tick", () => {
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);
});
invalidation.then(() => layout.stop());
function mouseover(e, d) {
d3.select(this).attr("stroke", "#000");
tooltip.style("display", null);
tooltip.attr("transform", `translate(${e.x},${e.y})`);
console.log(d3.select(this).text());
const path = tooltip.selectAll("path")
.data([,])
.join("path")
.attr("fill", "white")
.attr("stroke", "black");
const text = tooltip.selectAll("text")
.data([,])
.join("text")
.call(text => text
.selectAll("tspan")
.data(`${d3.select(this).text()}`.split(/\n/))
.join("tspan")
.attr("x", 0)
.attr("y", (_, i) => `${i * 1.1}em`)
.attr("font-weight", (_, i) => i ? null : "bold")
.text(d => d));
const {x, y, width: w, height: h} = text.node().getBBox();
text.attr("transform", `translate(${-w / 2},${15 - y})`);
path.attr("d", `M${-w / 2 - 10},5H-5l5,-5l5,5H${w / 2 + 10}v${h + 20}h-${w + 20}z`);
}
const tooltip = svg.append("g")
.style("pointer-events", "none")
function mouseout() {
d3.select(this).attr("stroke", null);
tooltip.style("display", "none");
}
function update(){
container.selectAll("input").each(function(d){
const cb = d3.select(this);
const grp = cb.property("value")
if(cb.property("checked")) {
svg.selectAll("._"+grp).style("opacity",1)
} else {
svg.selectAll("._"+grp).style("opacity",0.1)
}
})
}
container.selectAll("input").on("change",update);
return container.node();
}