parliament
parliament

Reputation: 22904

d3.js right align nested bar chart

I'm working with this d3.js example and am looking to change the charts entire orientation to go instead from right to left.

I was able to reverse the x-axis scale:

var x = d3.scale.linear().range([width, 0]);

and the placement of the y axis:

svg.append("g").attr("class", "y axis")
               .attr("transform", "translate("+width+", 0)")
               .append("line").attr("y1", "100%");

I believe I have to set the transform on each bar to the chart width - the bar width however applying ANY transform to the containing g has no effect.

 function bar(d) {
    var bar = svg.insert("g", ".y.axis")
                 .attr("class", "enter")
                 .attr("transform", "translate(0,5)")
                 .selectAll("g")
                 .data(d.children)
                 .enter().append("g");
  //DOESNT WORK
  bar.attr("transform", function(n){ return "translate("+ (width - x(n.value)) +", 0)"; })  
     .style("cursor", function(d) { return !d.children ? null : "pointer"; })
     .on("click", down);

  bar.append("text")....

  bar.append("rect")....

  return bar;
} 

No transform is set on bar even if I just do a test with a fixed value, the result is translate(0,0) in the resulting page.

Why doesnt the transform not get applied here and is this even the correct way to make the bars right align? I also need the text to be on the right side of the bar instead of on the left and it seems that changing the order of appending makes no difference in this regard.

Upvotes: 0

Views: 2798

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The problem with this particular example is that the code is a bit confusing -- the positions of the rect elements are set in various non-obvious places. In particular, the transform you are setting is overwritten immediately by other code.

I've modified the example to do what you want here. The key points are that I'm moving the g element containing all bars to the right

var bar = svg.insert("g", ".y.axis")
  .attr("class", "enter")
  .attr("transform", "translate("+width+",5)")
.selectAll("g")
// etc

and setting the x position of the rect elements to be their negative width

bar.append("rect")
  .attr("x", function(d) { return width-x(d.value); })
  .attr("width", function(d) { return x(d.value); })
  .attr("height", barHeight);

The x position needs to be set in a few other places in the code in this way -- there're almost certainly more elegant ways to do this.

Upvotes: 1

Related Questions