我一直在探索如何在绘图中添加图例,并在绘制新类型的过渡后更新图例。我遇到了两个问题,我无法解决这个问题。
该块位于http://bl.ocks.org/natemiller/df4b96809580fe7d00a6
示例JSON数据集包括几个不同的变量(temp,pH,name,y等),我想要开发的是一个图表,它改变了哪个变量在x轴上绘制,哪个变量决定了填充单击按钮时的数据点数。到目前为止,我的x轴发生了变化,点移动得恰到好处,并且图例颜色也正常变化。但是,我有两个问题。
我错过了图例文字(标签)。我不清楚为什么他们没有被展示,但我认为它缺少一个小细节。我很感激任何帮助。
正如您在数据集中看到的,有几个来自同一地点的“样本”,或具有相同的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个矩形(如果设置了填充,则设置为2个)由temp)给定一些值是重复的。有办法做到这一点吗?我考虑过d3.nest,但是当我开始转换时,我不再希望数据嵌套在名称上,而是由pH值(因此填充由d.pH设置)。我对此表示感谢。我是以太复杂的方式做这件事的吗?我是否应该考虑更简单的方法来实现同样的目标?
谢谢你的时间和帮助, 内特
答案 0 :(得分:2)
2 - 当您提供.data值时,您还可以提供返回唯一标识值的函数。像这样:
varlegend = svg.selectAll('rect')
.data(data, function(d) { return d.name })
//...
从selection.data的文档:“为了控制数据如何连接到元素,可以指定一个关键函数。这将替换默认的索引行为”
1 - 关于未显示的文本,我认为问题是缺少“笔画”属性。你可能白了白。但是,另一种需要考虑的方法是使用'g'标记来保存rect和text。像这样:
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");
答案 1 :(得分:1)
问题1:文本未显示,因为您无法在SVG中将文本附加到矩形。也就是说,一个矩形不能像一个容器。您的问题是您指定了legend = svg.selectAll('rect')
,这意味着在legend.append("text")
下面说不起作用。因此,解决方案是explunit建议:将数据加入g
(组),然后分别将rect和text附加到该组。
问题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或temp过滤图例数据,然后将新创建的数组传递到重绘功能,图例将转换,同时删除旧/不需要的元素。有关如何布置重绘功能的信息,请参阅General Update Pattern上的Mike Bostock的帖子。