HTMLDrop.

D3.js starter

D3.js v7: a data-driven bar chart with scales, axes, and transitions.

Open in editor Free. No install, no sign-up.
  • d3

The code

Three files, exactly what you get in the editor.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>D3 starter</title>
  </head>
  <body>
    <main class="page">
      <header>
        <a href="https://d3js.org" target="_blank"
          ><svg class="logo" role="img" viewBox="0 0 128 128">
            <linearGradient
              id="d3js-original-a"
              gradientUnits="userSpaceOnUse"
              x1="-201.009"
              y1="376.844"
              x2="-200.098"
              y2="375.873"
              gradientTransform="matrix(82.4907 0 0 -81.4303 16634.416 30700.326)"
            >
              <stop offset="0" stop-color="#f9a03c" />
              <stop offset="1" stop-color="#f7974e" />
            </linearGradient>
            <path
              fill="url(#d3js-original-a)"
              d="M126.334 90.59a37.18 37.18 0 00.128-1.647C126.5 88.288 87.094 50.9 87.094 50.9h-.942s39.94 42.13 40.182 39.69z"
            />
            <linearGradient
              id="d3js-original-b"
              gradientUnits="userSpaceOnUse"
              x1="-199.257"
              y1="373.615"
              x2="-197.514"
              y2="371.916"
              gradientTransform="matrix(40.2105 0 0 -40.4122 8003.203 15127)"
            >
              <stop offset="0" stop-color="#f9a03c" />
              <stop offset="1" stop-color="#f7974e" />
            </linearGradient>
            <path
              fill="url(#d3js-original-b)"
              d="M42.26 77.62a26.282 26.282 0 01-.328.702c-1.256 2.62 17.585 21.038 19.1 18.8.07-.098.14-.202.208-.3.077-.118.152-.23.228-.348 1.213-1.84-18.67-20.05-19.207-18.854z"
            />
            <linearGradient
              id="d3js-original-c"
              gradientUnits="userSpaceOnUse"
              x1="-199.836"
              y1="374.252"
              x2="-198.286"
              y2="372.475"
              gradientTransform="matrix(41.0403 0 0 -39.9333 8224.5 14997.683)"
            >
              <stop offset="0" stop-color="#f9a03c" />
              <stop offset="1" stop-color="#f7974e" />
            </linearGradient>
            <path
              fill="url(#d3js-original-c)"
              d="M68.886 103.52c-.053.118-.433.76-.78 1.098-.058.117 18.394 18.417 18.394 18.417h1.66c.002 0-17.32-18.74-19.274-19.514z"
            />
            <linearGradient
              id="d3js-original-d"
              gradientUnits="userSpaceOnUse"
              x1="-201.143"
              y1="379.263"
              x2="-200.795"
              y2="378.804"
              gradientTransform="matrix(255.8347 0 0 -242.016 51476.605 91789.102)"
            >
              <stop offset="0" stop-color="#f26d58" />
              <stop offset="1" stop-color="#f9a03c" />
            </linearGradient>
            <path
              fill="url(#d3js-original-d)"
              d="M126.488 88.61c-.863 19.13-16.69 34.425-36.024 34.425H87.85l-19.31-19.022a69.313 69.313 0 004.38-6.98h17.544c5.55 0 10.064-4.514 10.064-10.065 0-5.55-4.515-10.064-10.064-10.064H80.082A69.373 69.373 0 0081.306 64c0-4.48-.44-8.852-1.26-13.1h6.45l39.88 39.295a48.62 48.62 0 00.112-1.585zM11.962 4.772H1.472v26.003h10.49c18.32 0 33.23 14.903 33.23 33.225 0 4.984-1.113 9.716-3.088 13.964L61.24 96.82A58.882 58.882 0 0071.2 64c0-32.658-26.574-59.228-59.236-59.228z"
            />
            <linearGradient
              id="d3js-original-e"
              gradientUnits="userSpaceOnUse"
              x1="-200.962"
              y1="378.553"
              x2="-200.452"
              y2="378.218"
              gradientTransform="matrix(160.7307 0 0 -174.8133 32360.78 66184.883)"
            >
              <stop offset="0" stop-color="#b84e51" />
              <stop offset="1" stop-color="#f68e48" />
            </linearGradient>
            <path
              fill="url(#d3js-original-e)"
              d="M90.464 4.772H47.986a69.81 69.81 0 0124.82 26.003h17.658c5.55 0 10.064 4.513 10.064 10.064 0 5.55-4.515 10.06-10.064 10.06h-3.968l39.88 39.296a36.65 36.65 0 00.152-3.228c0-8.766-3.146-16.807-8.368-23.066 5.223-6.256 8.368-14.3 8.368-23.063 0-19.887-16.177-36.068-36.064-36.068z"
            />
            <linearGradient
              id="d3js-original-f"
              gradientUnits="userSpaceOnUse"
              x1="-200.619"
              y1="377.137"
              x2="-200.595"
              y2="376.532"
              gradientTransform="matrix(176.7653 0 0 -92.6293 35504.598 35022.56)"
            >
              <stop offset="0" stop-color="#f9a03c" />
              <stop offset="1" stop-color="#f7974e" />
            </linearGradient>
            <path
              fill="url(#d3js-original-f)"
              d="M87.85 123.035H48.29a69.95 69.95 0 0020.25-19.022l19.31 19.022zM61.24 96.82L42.106 77.965c-5.287 11.362-16.807 19.264-30.143 19.264H1.472v26h10.49c20.53 0 38.648-10.5 49.28-26.407z"
            /></svg
        ></a>
        <div>
          <h1>Letter frequency</h1>
          <p>
            How often each letter appears in English text.
            <button id="sort">Sort by frequency</button>
          </p>
        </div>
      </header>
      <figure id="chart"></figure>
    </main>
  </body>
</html>
body {
  margin: 0;
  font-family: system-ui, sans-serif;
  background: #fff;
  color: #1f2328;
}
.page {
  max-width: 880px;
  margin: 0 auto;
  padding: 32px 24px;
}
header {
  display: flex;
  align-items: center;
  gap: 16px;
}
.logo {
  width: 56px;
  height: 56px;
}
h1 {
  margin: 0;
  font-size: 24px;
}
header p {
  margin: 4px 0 0;
  color: #57606a;
}
button {
  margin-left: 8px;
  font: inherit;
  font-size: 13px;
  padding: 4px 10px;
  border: 1px solid #d0d7de;
  border-radius: 6px;
  background: #f6f8fa;
  cursor: pointer;
}
figure {
  margin: 24px 0 0;
}
.bar {
  fill: #f68e1f;
}
.bar:hover {
  fill: #bd4b20;
}
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";

const data = Object.entries({
  A: 8.17,
  B: 1.49,
  C: 2.78,
  D: 4.25,
  E: 12.7,
  F: 2.23,
  G: 2.02,
  H: 6.09,
  I: 6.97,
  J: 0.15,
  K: 0.77,
  L: 4.03,
  M: 2.41,
  N: 6.75,
  O: 7.51,
  P: 1.93,
  Q: 0.1,
  R: 5.99,
  S: 6.33,
  T: 9.06,
  U: 2.76,
  V: 0.98,
  W: 2.36,
  X: 0.15,
  Y: 1.97,
  Z: 0.07,
}).map(([letter, frequency]) => ({ letter, frequency: frequency / 100 }));

const width = 840,
  height = 420;
const margin = { top: 20, right: 0, bottom: 30, left: 44 };
const x = d3
  .scaleBand()
  .domain(data.map((d) => d.letter))
  .range([margin.left, width - margin.right])
  .padding(0.1);
const y = d3
  .scaleLinear()
  .domain([0, d3.max(data, (d) => d.frequency)])
  .nice()
  .range([height - margin.bottom, margin.top]);

const svg = d3
  .select("#chart")
  .append("svg")
  .attr("viewBox", [0, 0, width, height])
  .attr("width", "100%");
const bars = svg
  .append("g")
  .selectAll("rect")
  .data(data)
  .join("rect")
  .attr("class", "bar")
  .attr("x", (d) => x(d.letter))
  .attr("width", x.bandwidth())
  .attr("y", y(0))
  .attr("height", 0);
bars.append("title").text((d) => `${d.letter}: ${d3.format(".1%")(d.frequency)}`);
bars
  .transition()
  .duration(800)
  .delay((d, i) => i * 20)
  .attr("y", (d) => y(d.frequency))
  .attr("height", (d) => y(0) - y(d.frequency));

const xAxis = svg
  .append("g")
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(x).tickSizeOuter(0));
svg
  .append("g")
  .attr("transform", `translate(${margin.left},0)`)
  .call(d3.axisLeft(y).tickFormat(d3.format(".0%")));

// Re-order the bars with a transition.
let sorted = false;
d3.select("#sort").on("click", function () {
  sorted = !sorted;
  this.textContent = sorted ? "Sort alphabetically" : "Sort by frequency";
  x.domain(
    data
      .slice()
      .sort(
        sorted ? (a, b) => b.frequency - a.frequency : (a, b) => d3.ascending(a.letter, b.letter),
      )
      .map((d) => d.letter),
  );
  const t = svg.transition().duration(750);
  bars
    .transition(t)
    .delay((d, i) => i * 20)
    .attr("x", (d) => x(d.letter));
  xAxis.transition(t).call(d3.axisBottom(x).tickSizeOuter(0));
});

Questions

Can I use D3.js without a build step?

Yes. This starter loads D3.js straight from a CDN, so it runs in the browser with no npm install, bundler, or config.

How do I start a D3.js project online?

Click Open in editor. HTMLDrop copies this starter into a new drop with index.html, style.css, and script.js, and the preview updates as you edit.

Is it free?

Yes. Public drops, live collaboration, versions, and embeds are free, and you do not need an account to start.

Can I share or embed my D3.js demo?

Yes. Every drop gets a public link and an embed code, and you can invite others to edit it with you in real time.

More starter kits