Published
Edited
Sep 5, 2019
3 stars
Insert cell
Insert cell
chart = {
const nodes = nodesData.map(d => Object.create(d));

const forceX = d3.forceX((d) => {
const position = d.group === "user" ? -100 : 100;
return position;
}).strength(0.15)
const forceY = d3.forceY(height/2).strength(0.015)

const simulation = d3.forceSimulation(nodes)
.force("x", forceX)
.force("y", forceY)
.force("collide", d3.forceCollide().radius(circleRadius).iterations(5))
.force("center", d3.forceCenter(width / 2, height / 2));
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const node = svg.append("g")
.selectAll(".node")
.data(nodes)
.join("g")
.attr('class', 'node')
.call(drag(simulation));

node.append('circle')
.attr("r", circleRadius)
.style("fill", (d, i) => {
return color(d.group);
});
simulation.on("tick", () => {
node
.attr("transform", d => `translate(${d.x}, ${d.y})`);
});

invalidation.then(() => simulation.stop());

return svg.node();
}
Insert cell
nodesData = [
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "user"},
{group: "IP"},
{group: "IP"},
{group: "IP"},
{group: "IP"}
]
Insert cell
height = 600
Insert cell
circleRadius = 25
Insert cell
arcStrokeWidth = 3;
Insert cell
arc = d3.arc()
.innerRadius(circleRadius - arcStrokeWidth)
.outerRadius(circleRadius)
Insert cell
drag = simulation => {
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).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);
}
Insert cell
color = d3.scaleOrdinal()
.domain(["user", "IP"])
.range(["#5688F0", "#ff6074"]);
Insert cell
d3 = require("d3@5")
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