konrad konrad - 8 months ago 65
Javascript Question

creating a legend with d3.js

I feel like I am being inefficient here. I am trying to create a legend from an array and it seems like i am writing too much to do this. Can someone tell me if it can be optimized?


var data = [
{name: "AnotherLong"},
{name: "BigData"},
{name: "What"},
{name: "Something"},
{name: "Smalls"}

var margin = {top: 10, right: 10, bottom: 10, left: 10};

var color = d3.scale.category20c();

var svg = d3.select("body").append("svg")
.attr("width", 400 - margin.left - margin.right)
.attr("height", 1000 - margin.top - margin.bottom)

var g = svg.selectAll(".row")

var rectangles = g.selectAll(".cell")
.attr("width", 19)
.attr("height", 19)
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
.style("fill", function(d, i){return color(i);})

var text = g.selectAll(".text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
.text(function(d){return d.name;})


Another thing that bothers me. It seems like my styling is all BOLD for some reason. I haven't defined any styles. Is that default behavior?


First, move all the measurements and values to the top of the file and reference them (this just makes things more readable)

var legend_row_height = 50;

You don't need to create the g elements. Just position the rectangles and text with x,y attributes instead of translations:

.attr("y", function(d,i){return legend_row_height * i;})

And move your styling into CSS. This is most easily achieved by setting classes on the objects:

.classed("squares", 1)

then adding CSS :

.squares {
   stroke: white;