Thursday, November 8, 2018

Adding legend to D3 chart

D3 is very powerful free JavaScript library that allows to do many things such as DOM manipulations, working with data and shapes, smoth transitions between UI states etc. I show just a simple example how I adedd a legend into a coloured barchart.

4.744.682.331.322
SydneyMelbourneBrisbaneAdelaidePerth

HTML and CSS:

  1. <style>
  2. #barchart {
  3. float: left;
  4. }
  5. #legend svg {
  6. height: 300px;
  7. }
  8. </style>
  9. <div id="barchart"></div>
  10. <div id="legend"></div>
<style>
   #barchart {
      float: left;
   }
   #legend svg {
      height: 300px; 
   }
</style>

<div id="barchart"></div>
<div id="legend"></div>

Javascript:

  1. //Initialize data
  2. var chartData = [
  3. {name: "Sydney", value: 4.74, color: "#2ea4ea"},
  4. {name: "Melbourne", value: 4.68, color: "#eb1560"},
  5. {name: "Brisbane", value: 2.33, color: "#f78f12"},
  6. {name: "Adelaide", value: 1.32, color: "#20c02d"},
  7. {name: "Perth", value: 2.00, color: "#8031eb"}
  8. ];
  9. //Select top container and create svg parent node
  10. var barWidth = 50;
  11. var heightScale = 60;
  12. var barchart = d3
  13. .select('#barchart')
  14. .append('svg')
  15. .style('height', '330px')
  16. .selectAll('.bar')
  17. .data(chartData);
  18. //Create bar rectangles
  19. barchart
  20. .enter()
  21. .append('rect')
  22. .attr('class', 'bar')
  23. .attr('width', barWidth)
  24. .attr('height', d => {
  25. return d.value * heightScale;
  26. })
  27. .style('fill', d => d.color)
  28. .attr('transform',
  29. (d, i) => {
  30. var x = barWidth * i + 10;
  31. var y = 310 - d.value * heightScale;
  32. return `translate(${x}, ${y})`;
  33. });
  34. //Add bar values
  35. barchart
  36. .enter()
  37. .append('text')
  38. .attr('x', (d, i) => barWidth * i + 20)
  39. .attr('y', d => 300 - d.value * heightScale)
  40. .text(d => d.value);
  41. //Initialize legend
  42. var legendItemSize = 12;
  43. var legendSpacing = 4;
  44. var xOffset = 150;
  45. var yOffset = 100;
  46. var legend = d3
  47. .select('#legend')
  48. .append('svg')
  49. .selectAll('.legendItem')
  50. .data(chartData);
  51. //Create legend items
  52. legend
  53. .enter()
  54. .append('rect')
  55. .attr('class', 'legendItem')
  56. .attr('width', legendItemSize)
  57. .attr('height', legendItemSize)
  58. .style('fill', d => d.color)
  59. .attr('transform',
  60. (d, i) => {
  61. var x = xOffset;
  62. var y = yOffset + (legendItemSize + legendSpacing) * i;
  63. return `translate(${x}, ${y})`;
  64. });
  65. //Create legend labels
  66. legend
  67. .enter()
  68. .append('text')
  69. .attr('x', xOffset + legendItemSize + 5)
  70. .attr('y', (d, i) => yOffset + (legendItemSize + legendSpacing) * i + 12)
  71. .text(d => d.name);
//Initialize data
  var chartData = [
   {name: "Sydney", value: 4.74, color: "#2ea4ea"},
   {name: "Melbourne", value: 4.68, color: "#eb1560"},
   {name: "Brisbane", value: 2.33, color: "#f78f12"},
   {name: "Adelaide", value: 1.32, color: "#20c02d"},
   {name: "Perth", value: 2.00, color: "#8031eb"}
  ];
  
  //Select top container and create svg parent node
  var barWidth = 50;
  var heightScale = 60;
  var barchart = d3
   .select('#barchart')
   .append('svg')
   .style('height', '330px')
   .selectAll('.bar')
   .data(chartData);
   
  //Create bar rectangles
  barchart
   .enter()
   .append('rect')
   .attr('class', 'bar')
   .attr('width', barWidth)
   .attr('height', d => {
    return d.value * heightScale;
   })
   .style('fill', d => d.color)
   .attr('transform',
                (d, i) => {
                    var x = barWidth * i + 10;
                    var y = 310 - d.value * heightScale;
                    return `translate(${x}, ${y})`;
                });
  
  //Add bar values
  barchart
   .enter()
   .append('text')
   .attr('x', (d, i) => barWidth * i + 20)
   .attr('y', d => 300 - d.value * heightScale)
   .text(d => d.value);  
   

  //Initialize legend
  var legendItemSize = 12;
        var legendSpacing = 4;
  var xOffset = 150;
  var yOffset = 100;
        var legend = d3
   .select('#legend')
   .append('svg')
            .selectAll('.legendItem')
            .data(chartData);
   
  //Create legend items
  legend
   .enter()
   .append('rect')
   .attr('class', 'legendItem')
   .attr('width', legendItemSize)
   .attr('height', legendItemSize)
   .style('fill', d => d.color)
   .attr('transform',
                (d, i) => {
                    var x = xOffset;
                    var y = yOffset + (legendItemSize + legendSpacing) * i;
                    return `translate(${x}, ${y})`;
                });
  
  //Create legend labels
  legend
   .enter()
   .append('text')
   .attr('x', xOffset + legendItemSize + 5)
   .attr('y', (d, i) => yOffset + (legendItemSize + legendSpacing) * i + 12)
   .text(d => d.name);  

You can try it on the JSFiddler:
https://jsfiddle.net/AndrewBuntsev/usk73eoa

For more information about D3 read this
https://d3indepth.com/

No comments:

Post a Comment