D3 Graph Examples
Force layouts and bar charts both show up under D3 graph examples. They are not the same thing. Here are both, live.
Search D3 graph examples and you get a pile of unrelated pictures. Half are force-directed networks. Half are bar charts someone titled “graph” because English is sloppy. D3 will draw both. They don't share a layout function.
Below is one of each: a network you can drag, a bar chart, a line chart. The D3.js page has the same bar/line/pie in a tighter demo. Maps live in the map visualization example.
Two meanings of graph
-
Node-link. People, servers, citations.
forceSimulation. If you needed this in React, I'd look at vis.js or Cytoscape.js (examples) before wrapping D3 myself. - Chart. Time series, categories. Scales and axes. That's the D3 everyone meets in the first tutorial.
Force-directed graph
Eight boxes, some edges, a charge that pushes them apart. Drag a node. The simulation writes x and y every tick; you copy those onto the SVG. That's the whole trick.
Preview
Code
const nodes = [{ id: "API" }, { id: "App" }, { id: "DB" }];
const links = [
{ source: "App", target: "API" },
{ source: "API", target: "DB" },
];
const sim = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id((d) => d.id).distance(70))
.force("charge", d3.forceManyBody().strength(-180))
.force("center", d3.forceCenter(width / 2, height / 2));
const link = svg.selectAll("line").data(links).join("line");
const node = svg.selectAll("circle").data(nodes).join("circle").attr("r", 16);
sim.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);
});
Bar chart
scaleBand for the categories, scaleLinear for
the height. I still write this from scratch when the page is already D3
and adding Chart.js would be a second religion.
Preview
Code
const data = [
{ label: "Mon", value: 12 },
{ label: "Tue", value: 19 },
{ label: "Wed", value: 8 },
];
const x = d3.scaleBand().domain(data.map((d) => d.label)).range([40, 620]).padding(0.3);
const y = d3.scaleLinear().domain([0, d3.max(data, (d) => d.value)]).range([200, 16]);
svg.selectAll("rect").data(data).join("rect")
.attr("x", (d) => x(d.label))
.attr("y", (d) => y(d.value))
.attr("width", x.bandwidth())
.attr("height", (d) => 200 - y(d.value))
.attr("fill", "#e8b84a");
Line chart
d3.line() plus a monotone curve so it doesn't look like a
seismograph. Circles on the points are optional. I put them in because
otherwise people ask if the line is decorative.
Preview
Flows between steps are a different animal again: D3 sankey chart. A natal wheel is polar D3, not a line.
Questions I get
What are D3 graph examples usually showing?
Two different things. A force-directed graph is nodes and links. A bar or line is a chart. Search results mix them. D3 does both; they are not the same layout.
How do I make a force-directed graph in D3?
forceSimulation with forceLink, forceManyBody, and forceCenter. On each tick, write the new x/y onto the SVG circles and lines. Drag is optional but it makes the example feel alive.
Is D3 still worth it for a bar chart?
For one bar chart, Chart.js or Recharts is faster to ship. D3 is the right call when the visual is custom, or when the same page already uses D3 for a network or a map.