Pratyush
Pratyush

Reputation: 1

Add space between the stacks in d3v4 stacked bar chart?

d3.json("data2.json", function(error, data) {
  data.forEach(function(d) {
    d.Total = +d.Total;
  });

  var width = 200,
    height = 50;

  var margin = {
    top: 10,
    right: 10,
    bottom: 30,
    left: 10
  };

  var svg = d3.select('body')
    .append('svg')
    .attr('width', '20%')
    .attr('height', '20%')
    .attr('viewBox', '0 0 ' + width + ' ' + height)
    .append('g');

  width = width - margin.left - margin.right,
    height = height - margin.top - margin.bottom;

  svg.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');


  var xScale = d3.scaleLinear()
    .range([0, width])

  var yScale = d3.scaleBand()
    .range([0, height])
    .padding(0.1);

  xScale.domain([0, d3.sum(data, function(d) {
    return d.Total;
  })]);

  var x_axis = svg.append('g')
    .attr('class', 'axis')
    .attr('padding', 1)
    .attr('transform', 'translate(' + 0 + ',' + height + ')');

  var keys = data.map(function(d) {
    return d.Type;
  });

  var newData = [{}];

  data.forEach(function(d) {
    newData[0][d.Type] = d.Total
  });

  var stack = d3.stack()
    .keys(keys);

  var series = stack(newData);

  var colorScale = d3.scaleOrdinal()
    .domain([0, 12])
    .range(d3.schemeCategory10);

  var bars = svg.selectAll()
    .data(series)
    .enter()
    .append('g')
    .attr('fill', function(d) {
      return colorScale(d.key);
    })
    .selectAll('rect')
    .data(function(d) {
      return d;
    })
    .enter()
    .append('rect')
    .attr('x', function(d, i) {
      return xScale(d[0]) ;
    })
    .attr('width', function(d, i) {
      return xScale(d[1]) - xScale(d[0]);
    })
    .attr("height", yScale.bandwidth());

});

This is the code I tried. I tried adding padding to g as well as x. It does not seem to be working. I just need a horizontal single stacked bar chart along with a tooltip. I can add the tooltip later but I just need somebody to help me figure this out. I have been struggling for far too long on this. Below is the data I am using.

[
  {
    "Type": "Pending Review",
    "Total": 3209,
    "Percent": "23.90%"
  },
  {
    "Type": "Audit Finding",
    "Total": 2715,
    "Percent": "20.22%"
  },
  {
    "Type": "No Issues",
    "Total": 1675,
    "Percent": "12.50%"
  }
]

Upvotes: 0

Views: 765

Answers (1)

Bemipefe
Bemipefe

Reputation: 1537

The easiest way that I found is to subtract few pixels from the width of the bar obtained with the x-axis mapping object (xScale in your case). You can keep the positioning (x and y values) as they are. So you can just change this line:

.attr('width', function(d, i) {
  return xScale(d[1]) - xScale(d[0]);
})

like this:

.attr('width', function(d, i) {
  return xScale(d[1]) - xScale(d[0]) - 2;
})

The -2 do the trick.

https://codepen.io/bemipefe/pen/ExyWeYm

Upvotes: 1

Related Questions