最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - d3.js adding legend to multiline series chart - Stack Overflow

programmeradmin8浏览0评论

How would one add a legend to the multiline series chart? I tried but am not getting any legend to display.

The block here:

has a flaw when the various series converge to the same point, like zero. All the labels will be overlayed on each other. Instead of going for these labels, a traditional legend would be useful.

I tried adding this

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

to the end of the code, the key names (d.name) match how my data is formatted, but it does not display. At one point it showed all black boxes to the right of the graph so that means I am close but I am missing something important

any insight appreciated

How would one add a legend to the multiline series chart? I tried but am not getting any legend to display.

The block here:

http://bl.ocks.org/3884955

has a flaw when the various series converge to the same point, like zero. All the labels will be overlayed on each other. Instead of going for these labels, a traditional legend would be useful.

I tried adding this

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

to the end of the code, the key names (d.name) match how my data is formatted, but it does not display. At one point it showed all black boxes to the right of the graph so that means I am close but I am missing something important

any insight appreciated

Share Improve this question edited Jul 12, 2013 at 20:26 Darryl Hein 145k96 gold badges223 silver badges263 bronze badges asked Feb 8, 2013 at 15:32 CQMCQM 44.2k77 gold badges229 silver badges370 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 13

Here is a fixed & refactored version of your code.

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

You need to use enter(), but enter() and exit() methods cannot be used with datum(). Quoting from the d3 wiki

selection.datum([value])

Gets or sets the bound data for each selected element. Unlike the selection.data method, this method does not compute a join (and thus does not compute enter and exit selections).

You seem to be missing the .enter() after .datum() function call.

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

Before appending the "rect" you must use the enter() function see link for exact explanation Click Here

发布评论

评论列表(0)

  1. 暂无评论