Jacob Johnson
Jacob Johnson

Reputation: 581

D3 - rotating rect text elements individually instead of as group

I have a bar vertical bar graph with text at the bottom describing the meaning of each bar; however, I need to rotate this text between 45-65 degrees to allow it to be readable with my limited space.

I've come across the problem that using "transform","rotate(-65)" is simply rotating the center of the who group of text. I understand its an issue of not selecting individual text elements to base my rotation on but I'm unsure how to select them individually.

This is the javascript for the graph below using D3:

var color = d3.scale.ordinal().range(["#004467","#005481","#00659c","#0076b7","#5480ba","#a17b8b","#cf735c","#f36925"]);

var ed1_data = [867,674,901,401,127,234,608,866,153,93,701,111,813];
var ed1_dataKey = [
  "Humanities",
  "Social sciences",
  "Life sciences",
  "Physical sciences",
  "Computer sciences",
  "Engineering",
  "Education",
  "Business management",
  "Health",
  "Law",
  "Vocational training",
  "Undeclared",
  "Other"
];
var ed1_width = 800;
var ed1_height = 600;
var ed1_scale = d3.scale.linear()
  .domain([0,1000])
  .range([ed1_height-100,0]);

var ed1_canvas = d3.select("#ed1-graph")
  .append("svg")
  .attr("width",ed1_width)
  .attr("height",ed1_height)
  .append("g");

var ed1_bars = ed1_canvas.selectAll("rect")
  .data(ed1_data)
  .enter()
    .append("g")
    .append("rect")
    .attr("width",40)
    .attr("fill",function(d){return color(d);})
    .attr("x",function(d,i){return 20+(i*60);})
    .attr("height",function(d){return (ed1_scale(0)-ed1_scale(d));})
    .attr("y",function(d){return ed1_scale(d)-10});

var ed1_numbers = ed1_canvas.selectAll(".ed1numbers")
  .data(ed1_data)
  .enter()
    .append("text")
    .attr("class","ed1numbers")
    .text(function(d){return d;})
    .attr("width",20)
    .attr("fill","#292215")
    .attr("text-anchor","middle")
    .attr("font-family","Franklin Gothic")
    .attr("x",function(d,i){return 40+(i*60);})
    .attr("height",function(d){return (ed1_scale(0)-ed1_scale(d));})
    .attr("y",function(d){return ed1_scale(d)-18})
    .attr("font-size","1em");

ed1_canvas.selectAll("g")
  .append("text")
  .attr("font-size","1em")
  .attr("fill","#292215")
  .attr("y",510)
  .attr("text-anchor","end")
  // .attr("transform","rotate(-65)") THIS IS THE ERROR LINE THAT ISN't DOING WHAT I WANT
  .attr("x",function(d,i){return 40+(i*60);})
  .text(function(d,i){return ed1_dataKey[i];});

And the CodePen for ease of assistance: http://codepen.io/jacob_johnson/pen/mRepoG?editors=1010

This is is in the last code block and is currently commented out.

Thank you. Any help is appreciated.

Upvotes: 1

Views: 859

Answers (2)

Stu
Stu

Reputation: 324

By passing the optional x & y parameters to the rotation function you can set a point around which your elements will rotate. Without these parameters the rotation point will default to the current user coordinate system.

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Rotate

The Pen below demonstrates how to set the rotation of each text element relative to itself.

https://codepen.io/stw/pen/vVgBmm?editors=1010

.attr("transform", function (d) {
             var xRot = d3.select(this).attr("x");
             var yRot = d3.select(this).attr("y");       
     return `rotate(-65, ${xRot},  ${yRot} )` //ES6 template literal to set x and y rotation points
}) 

Upvotes: 1

Aurelius
Aurelius

Reputation: 151

Add the rotation and the translate to one transform.

.attr("transform",function(d,i){ 
    return "translate(" + (40+(i*60)) + ", 510) " + "rotate(-65)"})

http://codepen.io/Aure1ius/pen/BporJZ?editors=1010

Upvotes: 2

Related Questions