如何在 D3 图表中定位图例?

问题描述 投票:0回答:2

如何将图例放置在图表之上和之外?

我正在研究这个 D3 示例分组条形图。这是我的PLUNKER,但图例可以与图表重叠。理想情况下,我希望上面和图表之外的图例。

这是我必须更改的代码。我不明白为什么 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 + ")"; });

我可以按如下方式移动图例:PLUNKER

.attr("transform", function(d, i) { return "translate(" + "-500," + i * 20 + ")"; });
imore
移动到中心。

然后我可以让图例从左到右读取,如下所示:

.attr("transform", function(d, i) { return "translate(" + (-700+i*100) + "," + 0 + ")"; });

如果我可以将其移至图表上方和外部,那就太好了,因为它仍然与某些图表重叠。


编辑1 PLUNKER

感谢下面的答案,这是我的尝试,正如我所期望的那样,它位于图表上方,但我希望图例中的不同系列看起来更接近(有太多空白)。那么我如何拥有彩色矩形,然后是它旁边的文本,但没有空格?

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

编辑2PLUNKER

这是我能做的最好的事情,但我觉得我只是猜测。也许我会重新访问,但与此同时,如果有人可以向我完美地解释它,我将不胜感激。

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; });
javascript d3.js
2个回答
4
投票

如果您希望图例位于图表之外,您只需增加想要放置图例的边距大小并将其平移到位置即可。

现在,您正在根据

<svg>
的大小定位图例的各个部分。您可以通过创建一个包含所有图例元素的
<g>
并将其转换到图表中所需的位置来简化此过程。

您需要尝试使用这些值才能准确获得您想要的内容,但以下是允许您将图例放置在右边距中的值。

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

4
投票

示例中的图例出现在右侧,尽管变换为零,因为组中的元素具有接近框架宽度(减去小偏移)的 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; });

因此,-500 的 x 变换(大约宽度的一半)将其拉到中间,如前所述。对图例元素使用较小的 x 属性可能有助于更清晰地设置图例(这在其他答案中可以看到),尽管正如您的评论所指出的那样,使其按原样工作并不难(只是比需要的更令人困惑)。

© www.soinside.com 2019 - 2024. All rights reserved.