1

我一直在探索如何在绘图中添加图例并在绘制新类型的转换后更新图例。我遇到了两个我无法解决的问题。

该块在这里 http://bl.ocks.org/natemiller/df4b96809580fe7d00a6

示例 JSON 数据集包括几个不同的变量(温度、pH、名称、y 等),我试图开发的是一个图,它改变了在 x 轴上绘制的变量以及确定数据填充的变量单击按钮时的点。到目前为止,我的 x 轴发生了变化,点移动得当,图例颜色也发生了变化。但是,我有两个问题。

  1. 我缺少图例文本(标签)。我不清楚为什么没有显示它们,但我认为这是我遗漏的一个小细节。我将不胜感激任何帮助。

  2. 正如您在数据集中看到的那样,有几个“样本”来自同一站点,或者具有相同的 pH 值(7.2、8.0、7.2、7.2、8.0、8.0、7.6),或者具有相同的温度(30、25、25 , 30, 30, 25, 25)。因此,当我在此处的代码中生成图例时...

    varlegend = svg.selectAll('rect')
       .data(data)
       .enter().append("rect")
       .attr('x', width-50)
       .attr('y', function(d,i) {return i*20;})
       .attr('width', 10)
       .attr('height', 10)
       .style('fill', function(d) { 
         return color(d.name);
       }); 
    

...并使用 d.name 设置颜色我得到 7 个矩形(每个值一个),当填充颜色由站点或 pH 设置时,我宁愿有 3 个矩形(如果填充由 temp 设置,则有两个)给定一些值是重复的。有没有办法做到这一点?我考虑过 d3.nest,但是当我开始转换时,我不再希望数据按名称嵌套,而是按 pH 值嵌套(因此填充由 d.pH 设置)。我很感激对此的任何评论。我这样做是不是太复杂了?有没有更简单的方法我应该考虑实现同样的目标?

谢谢你的时间和帮助,内特

4

2 回答 2

2

2 - 当您提供 .data 值时,您还可以提供一个返回唯一标识值的函数。像这样的东西:

varlegend = svg.selectAll('rect')
   .data(data, function(d) { return d.name })
//...

selection.data的文档中:“要控制数据如何连接到元素,可以指定一个键函数。这取代了默认的按索引行为”

1 - 关于未显示的文本,我认为问题是缺少“stroke”属性。你可能已经得到了白底白字。但是,要考虑的另一种方法是使用“g”标签来保存矩形和文本。像这样的东西:

var legend = svg.selectAll('.legend')
      .data(data, function(d) { return d.name; })
      .enter().append('g')
      .attr('class', 'legend')
      .attr('ID', function(d) { return d.name })
      .attr("transform", function(d,i) {
        return "translate(" + 800 + "," + i*20 + ")";
      });

legend.append("rect")
      .attr('width', 10).attr('height', 10)
      .style('fill', function(d) { 
        return color(d.name);
      });

legend.append("text")
      .attr('x', 25).attr('y', 10)
      .text(function(d) { return d.name; })
      .attr("font-family","sans-serif")
      .attr("font-size","11px")
      .attr("stroke","black");
于 2013-03-05T23:52:23.207 回答
1

问题 1:文本未显示,因为您无法将文本附加到 SVG 中的矩形。也就是说,一个矩形不能像一个容器。你的问题是你已经指定了legend = svg.selectAll('rect'),这意味着下面的说法是legend.append("text")行不通的。因此,解决方案正如 explunit 建议的那样:将数据加入g(组),然后分别将矩形和文本附加到该组。

问题 2:一种方法是首先创建一个删除重复条目的数组,然后将该数组用于您的图例数据连接。这是一个例子:

var legendData = d3.values(data.map(function (d) { return d.temp; }))

var unique = legendData.filter(function (elem, pos) {
   return legendData.indexOf(elem) == pos; })

这是您的unique数组,其中包含:[30, 25].

为了缓解头痛,我建议您将所有 .enter() 和 .transition() 放在一个可以传递数据的重绘函数中。因此,您可以首先按 pH 或温度过滤图例数据,然后将新创建的数组传递给重绘函数,图例将转换,同时删除旧的/不需要的元素。有关如何布置重绘功能的信息,请参阅 Mike Bostock 关于通用更新模式的帖子。

于 2013-03-06T04:21:31.340 回答