Published
Edited
Oct 15, 2019
8 stars
Insert cell
Insert cell
Insert cell
chart = {
const nodes = layoutedData.nodes;
const links = layoutedData.links;

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("line")
.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("r", 5)
.attr("fill", color)
.attr("cursor", "pointer");

node.append("title")
.text(d => d.id);

let hoveredNode = undefined;
let clickedNode = undefined;
const update = () => {
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)
.attr("stroke-dasharray", d => {
const activeNode = clickedNode || hoveredNode;
if (activeNode && (d.__proto__.source === activeNode.id || d.__proto__.target === activeNode.id)) {
return "";
}
const lineLengthCoveredByNode = 5;
const lineLength = Math.sqrt((d.source.x - d.target.x) ** 2 + (d.source.y - d.target.y) ** 2) - lineLengthCoveredByNode * 2;
const lineStubLength = config.stubDrawingType === 'relative' ? lineLength * config.relativeStubLength : config.absoluteStubLength;
if (lineLength < lineStubLength * 2) {
return "";
}
return `${lineLengthCoveredByNode + lineStubLength} ${lineLength - lineStubLength * 2}`;
});

node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
};

node
.on("mouseover", d => {
hoveredNode = d;
update();
})
.on("mouseout", d => {
if (hoveredNode === d) {
hoveredNode = undefined;
update();
}
})
.on("mousedown", d => {
clickedNode = d;
update();
})
.on("mouseup", d => {
clickedNode = undefined;
update();
});
document.addEventListener("mousemove", event => {
if (event.buttons === 0) {
clickedNode = undefined;
update();
}
});
node.call(d3.drag().on("drag", d => {
d.x = d3.event.x;
d.y = d3.event.y;
update();
}));

update();

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more