Flask + D3.js - Data Dashboard - Part 3

In Part-2 of this series, we created pie-chart to render data representing the distribution of Survivors of Titanic, based on their cabin classes. In this part of the tutorial, we want to show further age-distribution of survivors for selected cabin class.

You can get the whole project code at this github link.

6. Creating bar-chart Open barchcart.js in your editor, and add following code:

    
    var group = "All";
      
    function datasetBarChosen(group, datasetBarChart) {
           var ds = [];
           for (x in datasetBarChart) {
                if(datasetBarChart[x].group==group){
                    ds.push(datasetBarChart[x]);
                }
               }
           return ds;
    }
    
    function d3BarChartBase() {
    
       var margin = {top: 30, right: 5, bottom: 20, left: 50},
       width = 600 - margin.left - margin.right,
       height = 350 - margin.top - margin.bottom,
       colorBar = d3.scaleOrdinal(d3.schemeCategory10),
       barPadding = 1,
       misc = {ylabel: 7, xlabelH: 5, title:11};
      
       return {
           margin : margin,
           width : width,
           height : height,
           colorBar : colorBar,
           barPadding : barPadding,
           misc: misc
       };
    }
    function d3BarChart(datasetBarChart) {
    }
    
    

The key value pair in our dataset are, “group”: class, “category”: age-group, “measure”: percentage

  • First we define “All” as default group. What we mean here is, when page is loaded and no specific class is selected, we show age-group distribution for all classes
  • Next, we create a function datasetBarChosen(group, datasetBarChart) , which returns array of percentage values for a specific selected group from the whole dataset.
  • Then, we create d3BarChartBase function, which returns the dimensions and color attributes of bar-chart.
  • Finally, we create d3BarChart function, which accepts dataset and renders a bar-chart

In d3BarChart function, add following code:

    
    var firstDatasetBarChart = datasetBarChosen(group, datasetBarChart);           
    var basics = d3BarChartBase();
        var margin = basics.margin,
            width = basics.width,
           height = basics.height,
            colorBar = basics.colorBar,
           barPadding = basics.barPadding,
           misc = basics.misc
            ;
                        
        var xScale = d3.scaleLinear()
                            .domain([0, firstDatasetBarChart.length])
                            .range([0, width])
                            ;
    var yScale = d3.scaleLinear()
          .domain([0, d3.max(firstDatasetBarChart, function(d) { return d.measure; })])
                  .range([height, 0]);
    
    var svg = d3.select("#barChart")
       .append("svg")
       .attr("width", width + margin.left + margin.right)
       .attr("height", height  + margin.top + margin.bottom)
       .attr("id","barChartPlot")
       ;
    
    
  • firstDatasetBarChart variable stores array of percentage values for a group. Initially it has value for ‘all’ classes
  • basics variable stores dimension of bar-chart
  • Next we set xScale and yScale for our bar-chart. They are the X and Y axis scales. We have to make sure that however large the data values are, the bar should fit into the SVG area. To make sure that bar should not get higher than the SVG area itself, we use d3.max() to fit.
  • Then, in svg variable, we append bar-chart to #barChart ID with pre-defined dimensions.

Now that we have our SVG set, we will add elements like chart title, bar-chart, x and y axis labels to it. Add following code :

    
    svg.append("text")
       .attr("x", (width + margin.left + margin.right)/2)
       .attr("y", misc.title)
       .attr("class","title")              
       .attr("text-anchor", "middle")
       .text("Age-group Breakdown of all Survivors");
    
       var plot = svg
           .append("g")
           .attr("transform", "translate(" + margin.left + "," + (margin.top + misc.ylabel) + ")");
              
       plot.selectAll("rect")
       .data(firstDatasetBarChart)
       .enter()
       .append("rect")
           .attr("x", function(d, i) {
               return xScale(i);
           })
       .attr("width", width / firstDatasetBarChart.length - barPadding)  
           .attr("y", function(d) {
               return yScale(d.measure);
           }) 
           .attr("height", function(d) {
               return height-yScale(d.measure);
           })
           .attr("fill", "#6B6B6B");
    
    
  • We append title to our chart and add a default text to it. We will be updating this title, whenever user makes a class selection from pie-chart.
  • Next, we add g or group element, to group together other elements of the chart
  • Now, we finally plot each bar based on firstDatasetBarChart that holds numeric values we want to plot. Based on these values, we set the height of each bar. At the end, we add fill attribute to give a default color to all the bars.

Now that we have plotted the bars, we also want to show the actual percentage value each bar height represents, and the group it belongs to. Add following code to do so:

        
        plot.selectAll("text")
        .data(firstDatasetBarChart)
        .enter()
        .append("text")
        .text(function(d) {
                return formatAsInteger(d.measure)+"%";
        })
        .attr("text-anchor", "middle")
        .attr("x", function(d, i) {
                return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2);
        })
        .attr("y", function(d) {
                return (yScale(d.measure) - misc.ylabel);
        })
        .attr("class", "yAxis")
       ;
      
           // Add x labels to chart    
        
       var xLabels = svg
       .append("g")
       .attr("transform", "translate(" + margin.left + "," + (margin.top + height + misc.xlabelH)  + ")");
    
       xLabels.selectAll("text.xAxis")
       .data(firstDatasetBarChart)
       .enter()
       .append("text")
       .text(function(d) { return d.category;})
       .attr("text-anchor", "middle")
       .attr("x", function(d, i) {
           return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2);
       })
       .attr("y", 15)
       .attr("class", "xAxis")
       ;
    
    
  • We begin with adding y-label to each bar, which is a percentage value. We also define it’s x and y positions. We set this value using d.measure, which is measure key in our JSON data.
  • Then we add x-label to each bar. X-label represents age-group. We set the age-group values using d.category, which is category key in our JSON data.



Takeaways

With that, we have plotted bar- chart too. However, this is a default bar-chart, which appears when page loads initially. We need to update the bar-chart with new values, whenever user clicks on a cabin class from pie-chart.

In part-4, we will work on updating bar-chart whenever a user selection is made on pie-chart slice.


Note, References & Links: