Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a chart legend in D3

Tags:

legend

d3.js

I am having trouble adding a chart legend to my d3js chart. Here is my current approach:

var legend = svg.append("g")   .attr("class", "legend")   .attr("x", w - 65)   .attr("y", 25)   .attr("height", 100)   .attr("width", 100);  legend.append("rect")   .attr("x", w - 65)   .attr("y", 25)   .attr("width", 10)   .attr("height", 10)   .style("fill", function(d) { return color_hash[dataset.indexOf(d)][1] });  legend.append("text")   .attr("x", w - 65)   .attr("y", 25)   .text(function(d) { return color_hash[dataset.indexOf(d)][0] + ": " + d; }); 

Then I am attempting to style the .legend class:

.legend {             padding: 5px;             font: 10px sans-serif;             background: yellow;             box-shadow: 2px 2px 1px #888;         } 

But I'm not having much luck.

Is anyone familiar with adding legends to charts able to provide the best way to do so? I am not finding many resources for this online.

Here is my entire graph: http://jsbin.com/ewiwag/2/edit

like image 369
darko Avatar asked Nov 26 '12 21:11

darko


People also ask

How do you add a title to a D3 graph?

Use append("text") to append a title to the graph: svg. append("text") . attr("x", w/2) .


1 Answers

You need to bind data to the nodes (rectangles and text elements) that make up the legend.

Currently you get an error when trying to style rectangles:

Uncaught TypeError: Cannot read property '1' of undefined  

The reason: there's no bound data

legend.append("rect")       /*...*/       .style("fill", function(d) {           // d <---- is undefined          return color_hash[dataset.indexOf(d)][1]        }); 

Notice that D3 focuses on data transformation and operates on selections. So, first select a set of nodes and then bind data

legend.selectAll('rect')       .data(dataset)       .enter() 

Once you enter the selection with enter, you can add nodes and apply properties dynamically. Notice that to avoid creating rectangles on top of others, when setting the y property pass the i counter and multiply it by an integer.

  /*.....*/       .append("rect")       .attr("x", w - 65)       .attr("y", function(d, i){ return i *  20;})       .attr("width", 10)       .attr("height", 10)       .style("fill", function(d) {           var color = color_hash[dataset.indexOf(d)][1];          return color;       }); 

Here's the fixed example: http://jsbin.com/ubafur/3

like image 83
jaime Avatar answered Sep 17 '22 20:09

jaime