简体   繁体   中英

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?

http://jsbin.com/foqesivice/edit?js,console,output

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")
  .data(data)
  .enter().append("svg:g")

var rectangles = g.selectAll(".cell")
  .data(data)
  .enter().append("svg:rect")
  .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")
  .data(data)
  .enter().append("svg: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;})

EDIT:

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;
}

@MatthewWilcoxson's answer is good, but here's a more d3 specific re-write. Essentially, don't double-bind the data, keep the g , bind on it, position that and add the rect and text to it:

 <!DOCTYPE html> <html> <head> <script data-require="d3@4.0.0" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> </head> <body> <script> 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(), cellDim = 19; 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") .data(data) .enter().append("svg:g") .attr("transform", function(d, i) { return "translate(" + (0) + "," + ((cellDim + 1) * i) + ")" }); g.append("svg:rect") .attr("width", cellDim) .attr("height", cellDim) .style("fill", function(d, i) { return color(i); }); g.append("text") .attr("dy", "1em") .attr("dx", cellDim + 2) .text(function(d) { return d.name; }); </script> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM