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.


HTML and CSS:




Javascript:

//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