block by denisemauldin fa24eef2855d730def4a00caa9a0a717

d3v4 Multi-Line Chart, Nested Data, and 2 Dropdown Menus

Full Screen

forked from ProQuestionAsker‘s block: d3v4 Multi-Line Chart, Nested Data, and 2 Dropdown Menus

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3 Page Template</title>
        <script src="https://d3js.org/d3.v4.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>
  
  <body>
    <div id = "fruitDropdown"></div>
    <div id= "yearDropdown"></div>
    <div id="graph"></div>
    <script src="Exploration7.js"></script>
  </body>
  
</html>

Example5.csv

Month,Sales,Fruit,Year
Jan,87,strawberry,2016
Feb,3,strawberry,2016
Mar,89,strawberry,2016
Apr,56,strawberry,2016
May,1,strawberry,2016
Jun,17,strawberry,2016
Jul,59,strawberry,2016
Aug,43,strawberry,2016
Sep,16,strawberry,2016
Oct,94,strawberry,2016
Nov,99,strawberry,2016
Dec,53,strawberry,2016
Jan,93,grape,2016
Feb,8,grape,2016
Mar,95,grape,2016
Apr,62,grape,2016
May,5,grape,2016
Jun,24,grape,2016
Jul,62,grape,2016
Aug,49,grape,2016
Sep,18,grape,2016
Oct,101,grape,2016
Nov,103,grape,2016
Dec,53,grape,2016
Jan,94,blueberry,2016
Feb,15,blueberry,2016
Mar,95,blueberry,2016
Apr,64,blueberry,2016
May,11,blueberry,2016
Jun,33,blueberry,2016
Jul,64,blueberry,2016
Aug,53,blueberry,2016
Sep,27,blueberry,2016
Oct,103,blueberry,2016
Nov,108,blueberry,2016
Dec,62,blueberry,2016
Jan,80,strawberry,2015
Feb,0,strawberry,2015
Mar,71,strawberry,2015
Apr,51,strawberry,2015
May,3,strawberry,2015
Jun,11,strawberry,2015
Jul,56,strawberry,2015
Aug,34,strawberry,2015
Sep,12,strawberry,2015
Oct,75,strawberry,2015
Nov,94,strawberry,2015
Dec,46,strawberry,2015
Jan,76,grape,2015
Feb,0,grape,2015
Mar,78,grape,2015
Apr,58,grape,2015
May,10,grape,2015
Jun,22,grape,2015
Jul,47,grape,2015
Aug,36,grape,2015
Sep,18,grape,2015
Oct,86,grape,2015
Nov,98,grape,2015
Dec,40,grape,2015
Jan,79,blueberry,2015
Feb,0,blueberry,2015
Mar,78,blueberry,2015
Apr,49,blueberry,2015
May,5,blueberry,2015
Jun,31,blueberry,2015
Jul,62,blueberry,2015
Aug,49,blueberry,2015
Sep,7,blueberry,2015
Oct,86,blueberry,2015
Nov,100,blueberry,2015
Dec,46,blueberry,2015
Jan,89,strawberry,2014
Feb,97,strawberry,2014
Mar,46,strawberry,2014
Apr,89,strawberry,2014
May,80,strawberry,2014
Jun,29,strawberry,2014
Jul,84,strawberry,2014
Aug,18,strawberry,2014
Sep,36,strawberry,2014
Oct,3,strawberry,2014
Nov,48,strawberry,2014
Dec,63,strawberry,2014
Jan,212,grape,2014
Feb,78,grape,2014
Mar,234,grape,2014
Apr,37,grape,2014
May,98,grape,2014
Jun,3,grape,2014
Jul,148,grape,2014
Aug,207,grape,2014
Sep,102,grape,2014
Oct,221,grape,2014
Nov,15,grape,2014
Dec,188,grape,2014
Jan,59,blueberry,2014
Feb,73,blueberry,2014
Mar,141,blueberry,2014
Apr,217,blueberry,2014
May,104,blueberry,2014
Jun,109,blueberry,2014
Jul,248,blueberry,2014
Aug,28,blueberry,2014
Sep,111,blueberry,2014
Oct,87,blueberry,2014
Nov,81,blueberry,2014
Dec,14,blueberry,2014
Jan,96,strawberry,2013
Feb,46,strawberry,2013
Mar,99,strawberry,2013
Apr,92,strawberry,2013
May,70,strawberry,2013
Jun,21,strawberry,2013
Jul,93,strawberry,2013
Aug,20,strawberry,2013
Sep,72,strawberry,2013
Oct,42,strawberry,2013
Nov,37,strawberry,2013
Dec,65,strawberry,2013
Jan,227,grape,2013
Feb,120,grape,2013
Mar,185,grape,2013
Apr,144,grape,2013
May,104,grape,2013
Jun,163,grape,2013
Jul,202,grape,2013
Aug,86,grape,2013
Sep,139,grape,2013
Oct,127,grape,2013
Nov,153,grape,2013
Dec,144,grape,2013
Jan,206,blueberry,2013
Feb,73,blueberry,2013
Mar,126,blueberry,2013
Apr,20,blueberry,2013
May,60,blueberry,2013
Jun,24,blueberry,2013
Jul,248,blueberry,2013
Aug,188,blueberry,2013
Sep,27,blueberry,2013
Oct,181,blueberry,2013
Nov,18,blueberry,2013
Dec,234,blueberry,2013

Exploration7.js

// Set the margins
var margin = {top: 60, right: 100, bottom: 20, left: 80},
  width = 850 - margin.left - margin.right,
  height = 370 - margin.top - margin.bottom;

// Parse the month variable
var parseMonth = d3.timeParse("%b");
var formatMonth = d3.timeFormat("%b");

var formatYear = d3.timeFormat("%Y");
var parseYear = d3.timeParse("%Y");


// Set the ranges
var x = d3.scaleTime().domain([parseMonth("Jan"), parseMonth("Dec")]).range([0, width]);
var y = d3.scaleLinear().range([height, 0]);


// Define the line
var valueLine = d3.line()
    .x(function(d) { return x(d.Month); })
    .y(function(d) { return y(+d.Sales); })

// Create the svg canvas in the "graph" div
var svg = d3.select("#graph")
        .append("svg")
        .style("width", width + margin.left + margin.right + "px")
        .style("height", height + margin.top + margin.bottom + "px")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform","translate(" + margin.left + "," + margin.top + ")")
        .attr("class", "svg");

// Import the CSV data
d3.csv("Example5.csv", function(error, data) {
  if (error) throw error;
  
   // Format the data
  data.forEach(function(d) {
      d.Month = parseMonth(d.Month);
      d.Sales = +d.Sales;
      d.Fruit = d.Fruit;
      d.Year = formatYear(parseYear(+d.Year));
  });

  var nest = d3.nest()
	    .key(function(d){
	    	return d.Fruit;
	    })
		.rollup(function(leaves){
            var max = d3.max(leaves, function(d){
            	return d.Sales
            })
            var year = d3.nest().key(function(d){
            	return d.Year
            })
            .entries(leaves);
            return {max:max, year:year};
            })
	  .entries(data)

  // Scale the range of the data
  x.domain(d3.extent(data, function(d) { return d.Month; }));
  //y.domain([0, d3.max(data, function(d) { return d.Sales; })]);
  
  // Set up the x axis
  var xaxis = svg.append("g")
       .attr("transform", "translate(0," + height + ")")
       .attr("class", "x axis")
       .call(d3.axisBottom(x)
          .ticks(d3.timeMonth)
          .tickSize(0, 0)
          .tickFormat(d3.timeFormat("%B"))
          .tickSizeInner(0)
          .tickPadding(10));



  // Create 1st dropdown
    var fruitMenu = d3.select("#fruitDropdown")

    fruitMenu
		.append("select")
		.selectAll("option")
        .data(nest)
        .enter()
        .append("option")
        .attr("value", function(d){
            return d.key;
        })
        .text(function(d){
            return d.key;
        })

    // Create 2nd dropdown
    var yearMenu = d3.select("#yearDropdown")

    yearMenu
    	.data(nest)
		.append("select")
		.selectAll("option")
        .data(function(d) { return d.value.year; })
       	.enter()
        .append("option")
        .attr("value", function(d){
            return d.key;
        })
        .text(function(d){
            return d.key;
        })

 
 	// Function to create the initial graph
 	var initialGraph = function(fruit){

 		// Filter the data to include only fruit of interest
 		var selectFruit = nest.filter(function(d){
                return d.key == fruit;
              })

	    var selectFruitGroups = svg.selectAll(".fruitGroups")
		    .data(selectFruit, function(d){
		      return d ? d.key : this.key;
		    })
		    .enter()
		    .append("g")
		    .attr("class", "fruitGroups")
		    .each(function(d){
                y.domain([0, d.value.max])
            });

		var initialPath = selectFruitGroups.selectAll(".line")
			.data(function(d) { return d.value.year; })
			.enter()
			.append("path")

		initialPath
			.attr("d", function(d){
				return valueLine(d.values)
			})
			.attr("class", "line")

		  // Add the Y Axis
		   var yaxis = svg.append("g")
		       .attr("class", "y axis")
		       .call(d3.axisLeft(y)
		          .ticks(5)
		          .tickSizeInner(0)
		          .tickPadding(6)
		          .tickSize(0, 0));
		  
		  // Add a label to the y axis
		  svg.append("text")
		        .attr("transform", "rotate(-90)")
		        .attr("y", 0 - 60)
		        .attr("x", 0 - (height / 2))
		        .attr("dy", "1em")
		        .style("text-anchor", "middle")
		        .text("Monthly Sales")
		        .attr("class", "y axis label");

 	}

 	// Create initial graph
 	initialGraph("strawberry")


 	// Update the data
 	var updateGraph = function(fruit){

 		// Filter the data to include only fruit of interest
 		var selectFruit = nest.filter(function(d){
                return d.key == fruit;
              })

 		// Select all of the grouped elements and update the data
	    var selectFruitGroups = svg.selectAll(".fruitGroups")
		    .data(selectFruit)
		    .each(function(d){
                y.domain([0, d.value.max])
            });

		    // Select all the lines and transition to new positions
            selectFruitGroups.selectAll("path.line")
               .data(function(d) { return d.value.year; }, 
               		function(d){ return d.key; })
               .transition()
                  .duration(1000)
                  .attr("d", function(d){
                    return valueLine(d.values)
                  })

        // Update the Y-axis
            d3.select(".y")
                    .transition()
                    .duration(1500)
                    .call(d3.axisLeft(y)
                      .ticks(5)
                      .tickSizeInner(0)
                      .tickPadding(6)
                      .tickSize(0, 0));


 	}


 	// Run update function when dropdown selection changes
 	fruitMenu.on('change', function(){

 		// Find which fruit was selected from the dropdown
 		var selectedFruit = d3.select(this)
            .select("select")
            .property("value")

        // Run update function with the selected fruit
        updateGraph(selectedFruit)


    });


    // Change color of selected line when year dropdown changes
    yearMenu.on('change', function(){

    	// Find which year was selected
    	var selectedYear = d3.select(this)
    		.select("select")
    		.property("value")

    	// Change the class of the matching line to "selected"
    	var selLine = svg.selectAll(".line")
              // de-select all the lines
              .classed("selected", false)
              .filter(function(d) {
                  return +d.key === +selectedYear
              })
              // Set class to selected for matching line
              .classed("selected", true)
              .raise()
    })


  
})

style.css

.line {
  fill: none;
  stroke: #999999;
  stroke-width: 2px;
}

.selected{
  stroke: #EF5285;
}