<div class="container"></div>
html, body {
  height: 100%;
}

.container {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.axis {
  color: #676767;
}
console.clear();

const data = [
  { name: "Richards", value: 40},
  { name: "Sue",      value: 25 },
  { name: "Johnny",   value: 15 },
  { name: "Ben",      value: 10}
];

const margin = { top: 20, right: 20, bottom: 40, left: 45 }
const svgWidth = 350;
const svgHeight = 200;
const width = svgWidth - margin.left - margin.right
const height = svgHeight - margin.top - margin.bottom

const svg = d3
  .select('.container')
  .append('svg')
  .attr('width', svgWidth)
  .attr('height', svgHeight);

const graphArea = svg
  .append('g')
  .attr('transform', `translate(${margin.left}, ${margin.top})`);

const x = d3.scaleBand()
  .rangeRound([0, width])
  .domain(data.map(d => d.name))
  .padding(0.4);

const y = d3.scaleLinear()
  .range([height, 0])
  .domain([
    d3.min(data, d => d.value) - 5,
    d3.max(data, d => d.value) + 5
  ])
  .nice();

const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y).ticks(5);;

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

graphArea
  .append('g')
  .attr('class', 'axis')
  .call(yAxis);

const rx = 12;
const ry = 12;

graphArea
   .selectAll("bar")
   .data(data)
   .enter().append("path")
      .style("fill", "#c51b8a") 
      .attr("d", item => `
        M${x(item.name)},${y(item.value) + ry}
        a${rx},${ry} 0 0 1 ${rx},${-ry}
        h${x.bandwidth() - 2 * rx}
        a${rx},${ry} 0 0 1 ${rx},${ry}
        v${height - y(item.value) - ry}
        h${-(x.bandwidth())}Z
      `);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js