2013-02-08 91 views
10

如何将图例添加到多行系列图表中?我试过,但没有得到任何图例显示。d3.js将图例添加到多行系列图表

的这里块:

http://bl.ocks.org/3884955

有一个缺陷,当各种系列汇聚到同一点,像零。所有的标签都会叠加在一起。传统的传说将非常有用,而不是去寻找这些标签。

我尝试添加该

var legend = svg.append("g") 
.attr("class", "legend") 
.attr("height", 100) 
.attr("width", 100) 
.attr('transform', 'translate(-20,50)');  

legend.selectAll('rect') 
    .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 
    .append("rect") 
    .attr("x", width) 
    .attr("y", function(d, i){ return i * 20;}) 
    .attr("width", 10) 
    .attr("height", 10) 
    .style("fill", function(d) { 
    return color.domain(d3.keys(d[0]).filter(function(key) { return key !== "day"; })); 
    }); 

legend.selectAll('text') 
    .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 
    .append("text") 
    .attr("x", width) 
    .attr("y", function(d, i){ return i * 20 + 9;}) 
    .text(function(d) { 
    return d.name; 
    }); 

到代码的末尾,我的数据是如何格式化的键值名(d.name)匹配,但它并不显示。在一个点上它显示全黑盒子到图形的右侧,这样意味着我接近,但我缺少一些重要的东西

任何见解赞赏

回答

13

Here是你的代码的固定&重构版本。

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

    legend.append('rect') 
     .attr('x', width - 20) 
     .attr('y', function(d, i){ return i * 20;}) 
     .attr('width', 10) 
     .attr('height', 10) 
     .style('fill', function(d) { 
      return color(d.name); 
     }); 

    legend.append('text') 
     .attr('x', width - 8) 
     .attr('y', function(d, i){ return (i * 20) + 9;}) 
     .text(function(d){ return d.name; }); 

您需要使用enter(),但enter()exit()方法不能datum()使用。从d3 wiki

selection.datum引用([值])

获取或设置绑定的数据为每个选定的元素。与selection.data方法不同,此方法不计算连接(因此不计算进入和退出选择)。

+1

我添加了一个点,并且您的代码适用于我。 var legend = svg.selectAll('。g') – theIrishUser 2014-03-05 14:22:13

0

你似乎缺少.datum后。进入() ()函数调用。

legend.selectAll('rect') 

    .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 

    .enter() // <====== 

    .append("rect") 

    .attr("x", width) 

    .attr("y", function(d, i){ return i * 20;}) 

    .attr("width", 10) 

    .attr("height", 10) 

    .style("fill", function(d) { 

    return color.domain(d3.keys(d[0]).filter(function(key) { return key !== "day"; })); 

追加“矩形”之前,你必须使用输入()函数见链接,确切的解释Click Here

+0

hm,我发现一些与逻辑有差异的地方,在一些地方的'city'变量以'.append(“text”)''开头,然后是'.datum(...)'之后输入(),但只是属性修改。此外,当我添加'输入()'我的控制台说,对象没有'输入()',并给了一个错误 – CQM 2013-02-08 20:36:37

+0

我可能是错的,但我认为混淆来自事实(如果我正确阅读).datum ()将值添加/更改为选择中的现有元素。在您的代码中,您声明“legend.selectAll('rect')”不存在,并且要创建初始连接,您需要使用“.data(data).enter()”创建新的“rect”元素。 – 2013-02-08 22:27:42

+0

这里是一个很好的答案关于.data和.datum的问题http://stackoverflow.com/questions/13181194/when-do-i-need-to-use-or-not-use-datum-when-appending- an-svg-element – 2013-02-08 22:30:55