Mr B
Mr B

Reputation: 4130

How to ensure D3 horizontal bar chart fits in div?

I am working on creating a horizontal bar chart using D3 in a ReactJS application. The issue I'm having is that the bars are too long and get cut off. How can I scale the bars down proportionally?

Appreciate any advice.

Upvotes: 0

Views: 917

Answers (1)

dmytroy
dmytroy

Reputation: 2397

If you want to fit your chart then you need to change width/height of container where your chart is rendered (see <svg> in code below). Usually bars maximum height or width must not exceed correspondent container's dimension size, so probably you have an error somewhere in code. It would be helpful if you could share your code.

Here I provide an example of horizontal bar chart that scales correctly (original: https://bl.ocks.org/caravinden/eb0e5a2b38c8815919290fa838c6b63b):

var data = [{"salesperson":"Bob","sales":33},{"salesperson":"Robin","sales":12},{"salesperson":"Anne","sales":41},{"salesperson":"Mark","sales":16},{"salesperson":"Joe","sales":159},{"salesperson":"Eve","sales":38},{"salesperson":"Karen","sales":21},{"salesperson":"Kirsty","sales":25},{"salesperson":"Chris","sales":30},{"salesperson":"Lisa","sales":47},{"salesperson":"Tom","sales":5},{"salesperson":"Stacy","sales":20},{"salesperson":"Charles","sales":13},{"salesperson":"Mary","sales":29}];

// set the dimensions and margins of the graph
var 
    svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 60},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

// set the ranges
var y = d3.scaleBand()
          .range([height, 0])
          .padding(0.1);

var x = d3.scaleLinear()
          .range([0, width]);
          
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
svg = svg
    .append("g")
    .attr("transform", 
          "translate(" + margin.left + "," + margin.top + ")");

  // format the data
  data.forEach(function(d) {
    d.sales = +d.sales;
  });

  // Scale the range of the data in the domains
  x.domain([0, d3.max(data, function(d){ return d.sales; })])
  y.domain(data.map(function(d) { return d.salesperson; }));
  //y.domain([0, d3.max(data, function(d) { return d.sales; })]);

  // append the rectangles for the bar chart
  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      //.attr("x", function(d) { return x(d.sales); })
      .attr("width", function(d) {return x(d.sales); } )
      .attr("y", function(d) { return y(d.salesperson); })
      .attr("height", y.bandwidth());

  // add the x Axis
  svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

  // add the y Axis
  svg.append("g")
      .call(d3.axisLeft(y));
.bar {
  fill: steelblue;
}

.bar:hover {
  fill: brown;
}

.axis--x path {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>
<svg width="300" height="500"></svg>

Upvotes: 1

Related Questions