1

I am using D3 to create a basic bar graph

For my x-axis, I want to position each label above their respective bar. The text should also be rotated 90 degrees

To see the code that does this, start at line 51. https://codepen.io/Fallenstedt/pen/xdYooE

//This is where I attempt to create an x Axis label
//create a container to hold the text element
var textContainer = svg.append('g')
  .selectAll('g')
  .data(data).enter()
  .append('g')
  .attr('class', 'x-axis')
  .attr('x', function(d, i) {
    return i * (width/data.length)
  })
  .attr('y', function(d, i) {
    return height - (d.value) + 15;
  })
  .attr("transform", function(d, i) {return "translate(" + (i * (width/data.length)) + ",330)";});


//now that a container is made, I can append a text element to it so I can rotate the text 90 degrees.
textContainer.append('text')
  .text(function(d) {
    return d.type
  })
  .attr('font-size', '34px')
  .attr('fill', 'white')
  .attr("text-anchor","end")
  .attr("transform", function(d, i) {return "translate(40,0) rotate(-90,0,0)";});

The labels appear and they are rotated 90 degrees, however I cannot position them to be above their respective rectangle. How can I position each x-axis label to be directly above their rectangle? I feel that my approach to this is overly complicated.

davcs86
  • 3,926
  • 2
  • 18
  • 30
Alex Fallenstedt
  • 2,040
  • 1
  • 18
  • 34

1 Answers1

1

You can create the rect and text elements inside the same container, e.g.

var rContainer = svg
  .selectAll(".bar")
  .data(data)
  .enter()
  .append("g");

//append rectangles for the bar chart
rContainer
  .append("rect")
  .attr("class", "bar")
  .style("fill", function(d, i) { return color(i); })
  .attr("x", function(d) { return x(d.type); })
  .attr("y", 0)
  .attr("width", x.bandwidth())
  .attr("height", 0)
  .transition()
  .duration(500) //length of animation
  .delay(function(d, i) { return i * 100; }) //delay must be less than duration
  .attr("y", function(d) { return y(d.value); })
  .attr("height", function(d) { return height - y(d.value); });

//append a text element to it so I can rotate the text 270 degrees.
rContainer
  .append("text")
  .text(function(d) { return d.type; })
  .attr("width", x.bandwidth())
  .attr("font-size", "34px")
  .attr("fill", "white")
  .attr("text-anchor", "start")
  .attr("transform", function(d, i) {
    // http://stackoverflow.com/questions/11252753/rotate-x-axis-text-in-d3
    var yVal = y(d.value) - 6;
    var xVal = x(d.type) + x.bandwidth() / 1.6;
    return "translate(" + xVal + "," + yVal + ") rotate(270)";
  });

You can check this working demo // starts in line 40

davcs86
  • 3,926
  • 2
  • 18
  • 30
  • This makes so much more sense now. I didn't think about using the `x.bandwidth()` to translate each piece of text. Thank you! I'll be sure to poke around this a bit more. :) – Alex Fallenstedt May 10 '17 at 23:56