It’s easier to start with an example and modify the code. Yesterday, we used this Observable example to visualize the main characters in the four houses in Harry Potter. We can start by copying & pasting them to our main.js file. Of course, always give credit to the examples and cite the original place for the examples. 🙂
To a beginner like me, many lines of code at the beginning do not make much sense to me. I think they are defining some values and some rules for the events.
Then I found d3-force documentation. From there I saw d3.forceSimulation() is the first function. Let’s forget about the codes in the beginning and start with the bare minimum. I started to copy & paste the following codes to the main.js file. And see if it works. Since I did not copy the values defined at the beginning, I also deleted the codes in the red circle.

Here is what I end up with in the main.js file. First, we have the forceSimulation, then we bind the data to our link and node. For our node, we defined three events, “start”, “drag” and “end”. I also added the first name and last name to the node. It will be displayed when you hover the node.

const force = d3.forceSimulation()
.nodes(dataset.nodes)
.force("link", d3.forceLink().id(d => d.id).links(dataset.links))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
const link = svg.selectAll(".link")
.data(dataset.links)
.enter().append("line")
.attr("class", "link")
const node = svg.selectAll(".node")
.data(dataset.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
node.append("title")
.text(d => d.first_name )
force.on("tick", function() {
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)
});
function dragstarted(event, d) {
if (!event.active) force.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event, d) {
if (!event.active) force.alphaTarget(0);
d.fx = null;
d.fy = null;
}
The files can be found here.