Rotating x labels individually

2,354 views
Skip to first unread message

Alex

unread,
May 25, 2012, 1:49:35 AM5/25/12
to d3-js
Hi

I'm trying to rotate my x labels to -45°, but it looks like they are
anchored on the bottom left of my graph and not on the bottom left of
themselves. I tried to trick the "text-anchor" thing but with no
result. So it is actually rotating my entire x axis labels.

var text = chart.selectAll("text")
.data(d3.range(samples))
.enter().append("svg:text")
.attr("class", "labels")
.attr("text-anchor", "middle" )
.attr("transform", function(d, i) { return " rotate(-45,0,0)
translate(" + x0(i) + ",0)"; })
.attr("x",0)
.attr("y", h+10)
.attr("dy", ".71em")
.text(function(d, i) { return transports[i]; });

Oh and if you know a way to move this anchor point to the right corner
of my labels... well, _o/ \o_

What I am trying to do : http://deuxsingesenhiver.com/graph-dseh.jpg
What I actually get : http://deuxsingesenhiver.com/graph-dseh-d3.png

Thanks

Scott Murray

unread,
May 25, 2012, 11:41:17 AM5/25/12
to d3...@googlegroups.com
Elements are rotated around their points of origin. If you specify both a large x value, and then a rotation value, the net effect will be as you see — your axis labels moving up and to the right, as if taking off from a runway. :-)

An alternative would be to create a <g> element for each individual label, and apply the rotation to the <g>, then position the x/y values on the <text> element (or vice versa).

Can you post the live code somewhere so we can inspect it?

Scott

Alex

unread,
May 25, 2012, 12:51:46 PM5/25/12
to d3...@googlegroups.com
Thanks for your help. I'll try with the <g> containers.

It will be hard for a live example as my chart is inside a Wordpress page running with Mamp on my computer.

I hosted the csv online if you want to take a look at it : http://www.deuxsingesenhiver.com/alexgreg.csv
And here is a look at the future page (i'm working on the first chart) : http://deuxsingesenhiver.com/dseh-datas.jpg
The jQuery slider control the whole page, refresh datas and charts. This part works.

Here is the code (probably a big mess. I'm graphic designer and I find d3 hard to learn ;))

$(document).ready(function(){
var w=440;
var h=320;
var samples = 8;
var defaultDay = 1;
var hash = window.location.hash;
hash = hash.substring(1,hash.length);
if(hash)
{
defaultDay = hash;
}
else
{
defaultDay = 1;
}
var y0 = d3.scale.linear().domain([0, 15000]).range([0,h]);
var x0 = d3.scale.ordinal().domain(d3.range(samples)).rangeBands([0, w], 0.2),
x1 = d3.scale.ordinal().domain(d3.range(2)).rangeBands([0, x0.rangeBand()]);
var chart = d3.select("#chartByTransport").append("svg")
.attr("class", "chart")
.attr("width",w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(0,-30)");

var data = [];
var noms = ["alex","greg"];
var transports = ["Vélo","Bus","Train","Stop","Moto","VéloMoto","Bateau","Avion"];
d3.csv("http://localhost:8888/DSEH/alexgreg.csv", function(csv) {
data = d3.nest()
.map(csv);
var aMaxId = 0;
var gMaxId = 0;
var maxId = 0;
for (var i=0; i<data.length; i++)
{
if(data[i].aLieuArrivee != "")
{
aMaxId++;
}
}
for (var i=0; i<data.length; i++)
{
if(data[i].gLieuArrivee != "")
{
gMaxId++;
}
}
if(aMaxId >= gMaxId)
{
maxId = gMaxId;
}else
{
maxId = aMaxId;
}
$('#sliderControl').slider({
range: "min",
value: 100,
min: 1,
max: maxId,
animate: true,
slide: function( event, ui ) {
$( "#sliderValue" ).text(ui.value );
updateGraphD3(ui.value);
}
});
var alexData = [parseInt(data[defaultDay].aVeloKmTotaux),parseInt(data[defaultDay].aBusKmTotaux),parseInt(data[defaultDay].aTrainKmTotaux),parseInt(data[defaultDay].aStopKmTotaux),parseInt(data[defaultDay].aMotoKmTotaux),parseInt(data[defaultDay].aVelomotoKmTotaux),parseInt(data[defaultDay].aBateauKmTotaux),parseInt(data[defaultDay].aBAvionKmTotaux)];
var gregData = [parseInt(data[defaultDay].gVeloKmTotaux),parseInt(data[defaultDay].gBusKmTotaux),parseInt(data[defaultDay].gTrainKmTotaux),parseInt(data[defaultDay].gStopKmTotaux),parseInt(data[defaultDay].gMotoKmTotaux),parseInt(data[defaultDay].gVelomotoKmTotaux),parseInt(data[defaultDay].gBateauKmTotaux),parseInt(data[defaultDay].gAvionKmTotaux)];
var combinedData = [alexData,gregData];
var g = chart.selectAll("g")
.data(combinedData)
.enter()
.append("svg:g")
.attr("class",function(d,i) {return noms[i]})
.attr("transform", function(d, i) {return "translate(" + x1(i) + ",0)";});
var rect = g.selectAll("rect")
.data(Object)
.enter()
.append("svg:rect")
.attr("transform", function(d, i) {return "translate(" + x0(i) + ",0)";})
.attr("width", x1.rangeBand())
.attr("height", function(d,i) {
return y0(d)+1;
})
.attr("y", function(d,i) {
return h-y0(d)-1;
}
);
var text = chart.selectAll("text")
.data(d3.range(samples))
.enter().append("svg:text")
.attr("class", "labels")
.attr("text-anchor", "middle")
.attr("transform", function(d, i) { return "translate(" + x0(i) + ",0)"; })
.attr("x",0)
.attr("y", h+10)
.attr("dy", ".71em")
.text(function(d, i) { return transports[i]; });
});

function updateGraphD3(jour)
{
window.location.hash = jour;
alexData = [parseInt(data[jour].aVeloKmTotaux),parseInt(data[jour].aBusKmTotaux),parseInt(data[jour].aTrainKmTotaux),parseInt(data[jour].aStopKmTotaux),parseInt(data[jour].aMotoKmTotaux),parseInt(data[jour].aVelomotoKmTotaux),parseInt(data[jour].aBateauKmTotaux),parseInt(data[jour].aAvionKmTotaux)];
var gregData = [parseInt(data[jour].gVeloKmTotaux),parseInt(data[jour].gBusKmTotaux),parseInt(data[jour].gTrainKmTotaux),parseInt(data[jour].gStopKmTotaux),parseInt(data[jour].gMotoKmTotaux),parseInt(data[jour].gVelomotoKmTotaux),parseInt(data[jour].gBateauKmTotaux),parseInt(data[jour].gAvionKmTotaux)];
d3.select(".alex").selectAll("rect")
.data(alexData)
.transition()
.duration(500)
.attr("height", function(d,i,j) {
return y0(d)+1;
})
.attr("y", function(d,i,j) {
return h-y0(d)-1;
}
);
d3.select(".greg").selectAll("rect")
.data(gregData)
.transition()
.duration(500)
.attr("height", function(d,i,j) {
return y0(d)+1;
})
.attr("y", function(d,i,j) {
return h-y0(d)-1;
}
);
}
});

Alex

unread,
May 25, 2012, 3:06:31 PM5/25/12
to d3...@googlegroups.com
It did the trick. The code : 

var gText = chart.selectAll("gText")
.data(d3.range(samples))
.enter().append("svg:g")
.attr("y", h+10)
.attr("transform", function(d, i) {return "translate(" + x0(i) + ",330)";});
gText.append("text")
.text(function(d, i) { return transports[i]; })
.attr("text-anchor","end")
.attr("transform", function(d, i) {return "translate(20,0) rotate(-45,0,0)";});

Thank you for your help !

amarinder thind

unread,
Jan 10, 2017, 9:12:47 AM1/10/17
to d3-js, alexandre...@gmail.com
Dear Alex,

I have similar problem and I want to rotate x axis individually. I want to rotate in following script. if you can help.

var times = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];

var timeLabels = svg.selectAll(".timeLabel")
    .data(times)
    .enter().append("text")
    .text(function(d) { return d; })
    .attr("x", function(d, i) { return i * gridSize; })
    .attr("y", 0)
    .style("text-anchor", "middle")
    .attr("transform", "translate(" + gridSize / 2 + ", -6) ")
    .attr("class", function(d, i) { return ((i >= 8 && i <= 17) ? "timeLabel mono axis axis-worktime" : "timeLabel mono axis"); });

Waiting for your warm reply and thanks.
Regards:
Amarinder

amarinder thind

unread,
Jan 10, 2017, 10:50:11 AM1/10/17
to d3-js, alexandre...@gmail.com
It is working now.
Reply all
Reply to author
Forward
0 new messages