简体   繁体   English

如何在d3图表中定位图例

[英]How to position the legend in a d3 chart

How do I position the legend above and out of the chart? 如何将图例放置在图表的上方和外部?

I am working in this d3 example Grouped Bar Chart 我正在使用这个d3示例Grouped Bar Chart

Here is my PLUNKER but the legend can overlap the graph. 这是我的PLUNKER,但图例可以与图形重叠。 Ideally I would like the legend above and out of the chart. 理想情况下,我想要图表上方和外部的图例。

This is my code that I have to change. 这是我必须改变的代码。 I don't understand why the 0 refers to the current position. 我不明白为什么0指的是当前的位置。

  var legend = svg.selectAll(".legend")
      .data(ageNames.slice().reverse())
    .enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

I can move the legend as follows: PLUNKER .attr("transform", function(d, i) { return "translate(" + "-500," + i * 20 + ")"; }); 我可以按如下方式移动图例: PLUNKER .attr("transform", function(d, i) { return "translate(" + "-500," + i * 20 + ")"; }); which moves imore to the center. 这移动到中心。

I can then have the legend read from left to right as follows: .attr("transform", function(d, i) { return "translate(" + (-700+i*100) + "," + 0 + ")"; }); 然后我可以从左到右读取图例如下: .attr("transform", function(d, i) { return "translate(" + (-700+i*100) + "," + 0 + ")"; }); I would be great if I could move this above and outside the chart as it still overlaps some of the graph. 如果我能在图表的上方和外部移动它,我会很棒,因为它仍然会覆盖一些图形。


EDIT1 PLUNKER EDIT1 PLUNKER

tks to an answer belwo. 请回答一下这个问题。 This is my attempt, which is above the chart as I would expect, but I would like the different series in the legend to appear closer together (there is too much white space). 这是我的尝试,正如我所期望的那样高于图表,但我希望图例中的不同系列看起来更接近(白色空间太多)。 So how do I have the coloured rect and then the text beside it, but without the whitespace? 那么我如何使用彩色矩形然后旁边的文本,但没有空白?

## the below is close but I am just guessing 
var legendHolder = svg.append('g')
  // translate the holder to the right side of the graph
  .attr('transform', "translate(" + (-width) + "," + (-margin.top) + ")")
  .attr('class','legendHolder')

  var legend = legendHolder.selectAll(".legend")
                .data(ageNames.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")

  legend.append("rect")
      .attr("x", function(d,i){return (width +(150*i))})
      .attr("width", 36)
      .attr("height", 18)
      //.style("text-anchor", "end")
      .style("fill", color);

  legend.append("text")
      //.attr("x", width - 24)
      .attr("x", function(d,i){return (width +(140*i))})
      .attr("y", 9)
      .attr("dy", ".35em")
      //.style("text-anchor", "end")
      .text(function(d) { return d; });

EDIT2 PLUNKER EDIT2 PLUNKER

This is the best I can do, but I fell I am jsut guessing, maybe I will revisit but in the meant time if anyone can beautifully explain it to me that would be greatly appreciated 这是我能做的最好的,但是我感到很沮丧,也许我会重新思考,但是在意味着时间,如果有人可以精美地向我解释,那将非常感激

var legendHolder = svg.append('g')
  // translate the holder to the right side of the graph
  .attr('transform', "translate(" + (-width) + "," + (-margin.top) + ")")
  .attr('class','legendHolder')

  var legend = legendHolder.selectAll(".legend")
                .data(ageNames.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")
                .attr('transform', function(d, i) { return "translate(" + -40*i + "," + 0 + ")"; })
                .attr("width", 36)

  legend.append("rect")
      .attr("x", function(d,i){return (width +(150*i))})
      .attr("width", 18)
      .attr("height", 18)
      //.style("text-anchor", "end") //"startOffset"="100%
      //.style("startOffset","100%") //"startOffset"="100%
      .style("fill", color);

  legend.append("text")
      //.attr("x", width - 24)
      .attr("x", function(d,i){return (width +(150*i)+20)})
      .attr("y", 9)
      .attr("dy", ".35em")
      //.style("text-anchor", "end")
      .text(function(d) { return d; });

If you want the legend to be located outside of the graph, you just need to increase the size of the margin where you want it to be placed and translate it into position. 如果您希望图例位于图形之外,则只需增加要放置的边距的大小并将其转换为位置。

Right now you are positioning the individual parts of your legend based on the size of the <svg> . 现在,您将根据<svg>的大小定位图例的各个部分。 You can simplify this by creating a <g> that contains all of your legend elements and translating that to its desired position in the graph. 您可以通过创建包含所有图例元素并将其转换为图形中所需位置的<g>来简化此操作。

You'll need to play around with the values to get exactly what you want, but below are the values that would allow you to place the legend in the right margin. 您需要使用这些值来获得您想要的内容,但下面是允许您将图例放在右边距中的值。

var margin = {top: 20, right: 100, bottom: 30, left: 40};

var legendHolder = svg.append('g')
  // translate the holder to the right side of the graph
  .attr('transform', "translate(" + (margin.left + width) + ",0)")

var legend = legendHolder.selectAll(".legend")
    .data(ageNames.slice().reverse())
  .enter().append("g")
    .attr("class", "legend")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
  .attr("x", 0)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", color);

legend.append("text")
  .attr("x", 0)
  .attr("y", 9)
  .attr("dy", ".35em")
  .style("text-anchor", "end")
  .text(function(d) { return d; });

The legend in the example appears on the right hand side, despite a transform of zero because the elements in the group have an x attribute of nearly the width of the frame (minus a small offset), pushing them to the right: 示例中的图例显示在右侧,尽管变换为零,因为组中的元素具有接近帧宽度的x属性(减去小偏移量),将它们推向右侧:

 legend.append("rect")
  .attr("x", width - 18)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", color);

  legend.append("text")
  .attr("x", width - 24)
  .attr("y", 9)
  .attr("dy", ".35em")
  .style("text-anchor", "end")
  .text(function(d) { return d; });

So an x transform of -500, about half your width, pulls it to the middle, as noted. 因此,如上所述,x变换为-500,大约是宽度的一半,将其拉到中间。 Using a smaller x attribute for the legend elements might help make it clearer for setting up your legend (this is seen in the other answer), though as your comment notes, it isn't too hard to make it work as it is (just more confusing than needed). 对图例元素使用较小的x属性可能有助于更清楚地设置图例(这在另一个答案中可以看到),尽管如您的评论所述,但它并不难以使其工作(只是比需要更混乱)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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