D3.js charts - Show legend in two rows

d3.js, svg

Solution

My solution: put everything into the "enter" method, and compute the offsets.

legend = svg.selectAll(".legend").data(data).enter().append("g")
   .attr("class", "legend")
   .attr( "transform", function(d,i) { 
        xOff = (i % 4) * 50
        yOff = Math.floor(i  / 4) * 10
        return "translate(" + xOff + "," + yOff + ")" 
} );

Consequently, you can delete the entire "selectAll" and "each" portion at the bottom.

Updated Fiddle: http://jsfiddle.net/v7mkg/1/

Side-effect; this particular implementation could create many rows, but that's not at the heart of the issue.

Problem

I have 10 legend elements that I want to show in two rows on top of my D3.js chart. I have tried the following ``` legend.append("rect").attr("width", 20).attr("height", 15).style("fill", function(d) { return color(d.packageName); }); legend.append("text").attr("dx", +25).attr("dy", "0.8em").style("text-anchor","front").style("fill", "#666").text(function(d) { return d.packageName; }); var margin = { top: 30, right: 20, bottom: 30, left: 40 }; d3.selectAll(".legend").each(function(d, i) { return d3.selectAll(".legend").attr("transform", i < 6 ? function(d, i) { return "translate(" + ((i * 100) + (diameter / 10) - 25) + "," + (+margin.top * 2) +")"; } : function(d, i) { return "translate(" + ((i * 100) + (diameter / 10) - 25) + "," + (+margin.top * 4) +")"; }); }); ``` My goal was to change the y coordinate if the "i" counter went over 5 so that the legend elements appear in 2 rows of 5. But the above code shows all legend elements in the second row. I'm sure I'm missing something very simple here!

Original source