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.

D3 Examples Networks
← All posts
D3 Graph Examples

Search D3 graph examples and you get a pile of results that don't agree with each other. Half are force-directed networks — nodes, edges, a simulation. The other half are bar charts someone labeled “graph” because English is genuinely ambiguous about this. D3 handles both, but they don't share a layout function or much else.

Below is one of each: a network you can drag around, a bar chart, and a line chart. The D3.js page has the bar/line/pie in a more compact demo. If you need a map, that's 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 nodes, some edges, a charge that pushes them apart. Drag one of them around. The simulation is running the whole time — it recalculates x and y on each tick, and you just copy those numbers onto the SVG elements. That's genuinely all there is to it once you get past the setup.

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 pretty different things, actually. Half the results you'll find are force-directed networks — nodes and links, people or servers or citations. The other half are bar charts or line charts that someone titled 'graph' because the word is ambiguous. D3 draws both, but they don't share a layout function or really any code. It helps to know which one you need before you start.

How do I make a force-directed graph in D3?

Set up a forceSimulation with forceLink, forceManyBody (for repulsion), and forceCenter. On each tick, the simulation writes updated x and y coordinates onto your nodes — you just copy those values onto your SVG circles and lines. Drag is optional but makes the result feel much more usable. The live preview on this page is exactly that.

Is D3 still worth it for a bar chart?

Honestly, for a single standalone bar chart, Chart.js or Recharts will get you there faster with less setup. D3 earns its place when the visual is non-standard, or when you're already using D3 elsewhere on the page for a network or a map and you don't want to pull in a second library just for a bar.

Latest posts

All posts