Moving the Y position of a legend in D3

2019-09-08 15:45发布

问题:

I've made a legend for my choropleth map inspired off of this: http://bl.ocks.org/KoGor/5685876

The challenge is, I want to change the legend's location within my canvas/svg.

var legend = svg.selectAll("g.legend")
.data(ext_color_domain)
.enter().append("g")
.attr("class", "legend");

var ls_w = 20, ls_h = 20;

legend.append("rect")
.attr("x", 20)
.attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;})
.attr("width", ls_w)
.attr("height", ls_h)
.style("fill", function(d, i) { return color(d); })
.style("opacity", 0.8);

legend.append("text")
.attr("x", 50)
.attr("y", function(d, i){ return height - (i*ls_h) - ls_h - 4;})
.text(function(d, i){ return legend_labels[i]; });

Changing the "x" location is easy, but the "y" location is the one I'm having trouble with. Why can't I just go .attr("y", 100, function/*..*/?

visual: click here

回答1:

I don't like the way your example code sets the position of the legend. He is setting each piece of the legend (both rect and text) independently across the whole svg. What should be done is that each rect and text is positioned within the g and then the g is moved as a group using a transform:

var legend = svg.selectAll("g.legend")
  .data(ext_color_domain)
  .enter().append("g")
  .attr("class", "legend")
  .attr('transform', 'translate(0,0)'); //<-- where does the group go

var ls_w = 20,
  ls_h = 20;

legend.append("rect")
  .attr("x", 20)
  .attr("y", function(d, i) {
    return (i * ls_h) - 2 * ls_h; //<-- position in group
  })
  .attr("width", ls_w)
  .attr("height", ls_h)
  .style("fill", function(d, i) {
    return color(d);
  })
  .style("opacity", 0.8);

legend.append("text")
  .attr("x", 50)
  .attr("y", function(d, i) {
    return (i * ls_h) - ls_h - 4; /<-- position in group
  })
  .text(function(d, i) {
    return legend_labels[i];
  });

Full example here.



标签: d3.js svg legend