Likert Scale

Statistics
Survey
Bar Chart
Code
chart = {
  const margin = { top: 50, right: 25, bottom: 25, left: 25 };
  const width = fullWidth - margin.left - margin.right,
        height = fullHeight - margin.top - margin.bottom;

  const window = d3.create("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("viewBox", `0 0 ${fullWidth} ${fullHeight}`)
    .attr("preserveAspectRatio", "xMidYMid meet");

  const svg = window.append("g")
    .attr("class", "survey")
    .attr("transform", `translate(${margin.left},${margin.top})`)

  const colors = [
    "#e66101",
    "#fdb863",
    "#f7f7f7",
    "#b2abd2",
    "#5e3c99",
  ];

  const labels = [
    "strongly disagree",
    "disagree",
    "neutral",
    "agree",
    "strongly agree",
  ];

  const data = [
      [0, 1, 8, 15, 12],
      [0, 4, 12, 14, 6],
      [0, 5, 1, 13, 17],
      [1, 8, 8, 15, 4],
      [0, 28, 5, 3, 0],
    ]
    .map(function (d) {
      const N = d3.sum(d);
      let x0 = -(d[0] + d[1] + d[2] / 2) / N;
      return d.map(n => ({ x0: x0, x1: x0 += n / N }));
    });

  const x = d3.scaleLinear()
    .domain([-1 , 1])
    .range([0, width]);

  const y = d3.scaleBand()
    .domain(d3.range(0, data.length))
    .range([0, height])
    .paddingInner(0.2)
    .paddingOuter(0.2);

  const xAxis = d3.axisBottom(x)
    .ticks(5)
    .tickFormat(d => `${100 * Math.abs(d)}%`);

  const yAxis = d3.axisLeft(y)
    .tickValues([]);

  const item = svg.selectAll(".item")
    .data(data)
    .join("g")
      .attr("class", "item")
      .attr("transform", (d, i) => `translate(0,${y(i)})`);

  item.selectAll("rect")
    .data(d => d)
    .join("rect")
      .attr("x", d => x(d.x0))
      .attr("width", d => x(d.x1) - x(d.x0))
      .attr("height", y.bandwidth())
      .style("fill", (d, i) => colors[i]);

  svg.append("g")
    .attr("class", "axis")
    .attr("transform", `translate(0,${height})`)
    .call(xAxis);

  svg.append("g")
    .attr("class", "axis")
    .attr("transform", `translate(${width/2},0)`)
    .call(yAxis);

  function legend(selection) {
    const x = d3.scaleBand()
      .domain(d3.range(colors.length))
      .range([0, fullWidth]);

    const item = selection.selectAll("g")
      .data(x.domain())
      .join("g")
        .attr("transform", (d, i) => `translate(${x(i)},0)`);

    item.append("rect")
      .attr("width", 20)
      .attr("height", 20)
      .style("fill", i => colors[i]);

    item.append("text")
      .attr("alignment-baseline", "middle")
      .attr("x", 20)
      .attr("y", 10)
      .attr("dx", 5)
      .text(i => labels[i]);
  }

  svg.append("g")
    .attr("class", "legend")
    .attr("transform", `translate(0,${-margin.top})`)
    .call(legend);

  return window.node();
}

This chart demonstrates the visualization of survey results on a Likert scale using diverging stacked bar charts.

Resources