D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mbmcpartland
Full window
Github gist
D3 Trellis plot
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>D3: Creating a trellis plot</title> <style type="text/css"> </style> </head> <body> <script src="https://d3js.org/d3.v4.min.js"></script> <script type="text/javascript"> //trellis plot //four global data arrays cancellations1 = []; cancellations2 = []; cancellations3 = []; cancellations4 = []; //helper function for reading in data function alreadyExists(year, name) { if(year >= 2003 && year <= 2006) { for(t = 0 ; t < cancellations1.length ; t++) { if(cancellations1[t].name == name) { return t; } } } if(year >= 2007 && year <= 2009) { for(t = 0 ; t < cancellations2.length ; t++) { if(cancellations2[t].name == name) { return t; } } } if(year >= 2010 && year <= 2012) { for(t = 0 ; t < cancellations3.length ; t++) { if(cancellations3[t].name == name) { return t; } } } if(year >= 2013 && year <= 2016) { for(t = 0 ; t < cancellations4.length ; t++) { if(cancellations4[t].name == name) { return t; } } } return -1; } //helper function for reading in data function addToArr(year, name, index, cancelled) { if(year >= 2003 && year <= 2006) { cancellations1[index].cancelled = cancellations1[index].cancelled + cancelled; } if(year >= 2007 && year <= 2009) { cancellations2[index].cancelled = cancellations2[index].cancelled + cancelled; } if(year >= 2010 && year <= 2012) { cancellations3[index].cancelled = cancellations3[index].cancelled + cancelled; } if(year >= 2013 && year <= 2016) { cancellations4[index].cancelled = cancellations4[index].cancelled + cancelled; } } //helper function for reading in data function bigName(name) { if(name.startsWith("Atlanta, GA")) { return 0; } if(name.startsWith("Boston, MA")) { return 0; } if(name == "Chicago, IL: Chicago O'Hare International") { return 0; } if(name.startsWith("Dallas/Fort")) { return 0; } if(name.startsWith("Los Angeles")) { return 0; } if(name == "New York, NY: LaGuardia") { return 0; } if(name.startsWith("Newark, NJ")) { return 0; } return 1; } //helper function for reading in data function addNew(year, name, cancelled) { if(year >= 2003 && year <= 2006) { var cancel = {name: name, cancelled: cancelled, year: "2003-2006"} cancellations1.push(cancel); } if(year >= 2007 && year <= 2009) { var cancel = {name: name, cancelled: cancelled, year: "2007-2009"} cancellations2.push(cancel); } if(year >= 2010 && year <= 2012) { var cancel = {name: name, cancelled: cancelled, year: "2010-2012"} cancellations3.push(cancel); } if(year >= 2013 && year <= 2016) { var cancel = {name: name, cancelled: cancelled, year: "2013-2016"} cancellations4.push(cancel); } } //debugging function to ensure data is read in correctly function testArr() { console.log("Testing cancellations 1"); for(r = 0 ; r < cancellations1.length ; r++) { console.log(cancellations1[r].name); console.log(cancellations1[r].year); console.log(cancellations1[r].cancelled) } } //helper function for reading in data function convert(which) { var data = []; if(which == 1) { for(t = 0 ; t < cancellations1.length ; t++) { data[t] = cancellations1[t].cancelled; } } if(which == 2) { for(t = 0 ; t < cancellations2.length ; t++) { data[t] = cancellations2[t].cancelled; } } if(which == 3) { for(t = 0 ; t < cancellations3.length ; t++) { data[t] = cancellations3[t].cancelled; } } if(which == 4) { for(t = 0 ; t < cancellations4.length ; t++) { data[t] = cancellations4[t].cancelled; } } return data; } //helper function for reading in data function getNames() { var names = []; for(t = 0 ; t < cancellations1.length ; t++) { index = cancellations1[t].name.indexOf(":"); names[t] = cancellations1[t].name.substring(0, index); } return names; } //setting up the margins var margin = {top: 50, right: 50, bottom: 50, left: 50}, width = 960 - margin.left - margin.right, height = 800 - margin.top - margin.bottom; //adding svg to page var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var parseYear = d3.timeParse("%Y"); //reading in data d3.csv("airlines.csv", function(data) { data.forEach(function(d) { if(bigName(d.Name) == 0) { var look = alreadyExists(d.Year, d.Name); if(look != -1) { addToArr(d.Year, d.Name, look, +d.Cancelled); } else { addNew(d.Year, d.Name, +d.Cancelled); } } }); //making it easier for myself with these four data arrays data1 = convert(1); data2 = convert(2); data3 = convert(3); data4 = convert(4); names = getNames(); //creating separate y-scales for each graph var yScale1 = d3.scaleLinear() .domain([0, d3.max(data1)]) .range([0, height/3]); var yScale2 = d3.scaleLinear() .domain([0, d3.max(data2)]) .range([0, height/3]); var yScale3 = d3.scaleLinear() .domain([0, d3.max(data3)]) .range([0, height/4.5]); var yScale4 = d3.scaleLinear() .domain([0, d3.max(data4)]) .range([0, height/3.5]); //creating separate x-scales for each graph var xScale = d3.scaleBand() .domain(getNames()) .rangeRound([0, width/2.5]) .paddingInner(0.30); var xScale1 = d3.scaleBand() .domain(d3.range(names.length)) .rangeRound([0, width/2.5]) .paddingInner(0.35); var yScale = d3.scaleLinear() .domain([0, d3.max(cancellations1, function(d) { return d.cancelled; })]) .range([height/3, 0]); //drawing bars for first graph svg.selectAll("rect.one") .data(data1) .enter() .append("rect") .attr("class", "one") .attr('transform', "translate(45, -481)") .attr("x", function(d, i) { return xScale1(i); }) .attr("y", function(d) { return height - yScale1(d); }) .attr("width", xScale1.bandwidth()) .attr("height", function(d) { return yScale1(d); }) .attr("fill", function(d) { return "rgb(0, 100, 0)"; }); //adding text to each bar for the first graph svg.selectAll("text.one") .data(data1) .enter() .append("text") .attr("class", "one") .attr('transform', "translate(45, -481)") .text(function(d) { return d; }) .attr("text-anchor", "middle") .attr("x", function(d, i) { return xScale1(i) + xScale1.bandwidth() / 2; }) .attr("y", function(d) { return height - yScale1(d) + 14; }) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white"); //drawing bars for second graph svg.selectAll("rect.two") .data(data2) .enter() .append("rect") .attr("class", "two") .attr('transform', "translate(500, -481)") .attr("x", function(d, i) { return xScale1(i); }) .attr("y", function(d) { return height - yScale2(d); }) .attr("width", xScale1.bandwidth()) .attr("height", function(d) { return yScale2(d); }) .attr("fill", function(d) { return "rgb(0, 100, 0)"; }); //adding text to each bar for the second graph svg.selectAll("text.two") .data(data2) .enter() .append("text") .attr("class", "two") .attr('transform', "translate(500, -481)") .text(function(d) { return d; }) .attr("text-anchor", "middle") .attr("x", function(d, i) { return xScale1(i) + xScale1.bandwidth() / 2; }) .attr("y", function(d) { return height - yScale2(d) + 14; }) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white"); //drawing bars for third graph svg.selectAll("rect.three") .data(data3) .enter() .append("rect") .attr("class", "three") .attr('transform', "translate(45, -116.5)") .attr("x", function(d, i) { return xScale1(i); }) .attr("y", function(d) { return height - yScale3(d); }) .attr("width", xScale1.bandwidth()) .attr("height", function(d) { return yScale3(d); }) .attr("fill", function(d) { return "rgb(0, 100, 0)"; }); //adding text to each bar for the third graph svg.selectAll("text.three") .data(data3) .enter() .append("text") .attr("class", "three") .attr('transform', "translate(45, -116.5)") .text(function(d) { return d; }) .attr("text-anchor", "middle") .attr("x", function(d, i) { return xScale1(i) + xScale1.bandwidth() / 2; }) .attr("y", function(d) { return height - yScale3(d) + 14; }) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white"); //drawing bars for fourth graph svg.selectAll("rect.four") .data(data4) .enter() .append("rect") .attr("class", "four") .attr('transform', "translate(500, -116.5)") .attr("x", function(d, i) { return xScale1(i); }) .attr("y", function(d) { return height - yScale4(d); }) .attr("width", xScale1.bandwidth()) .attr("height", function(d) { return yScale4(d); }) .attr("fill", function(d) { return "rgb(0, 100, 0)"; }); //adding text to each bar for the first graph svg.selectAll("text.four") .data(data4) .enter() .append("text") .attr("class", "four") .attr('transform', "translate(500, -116.5)") .text(function(d) { return d; }) .attr("text-anchor", "middle") .attr("x", function(d, i) { return xScale1(i) + xScale1.bandwidth() / 2; }) .attr("y", function(d) { return height - yScale4(d) + 14; }) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white"); //adding x-axis and y-axis for each graph svg.append("g") .attr("class", "x axis") .attr("transform", "translate(45," + height/3.206 + ")") .call(d3.axisBottom(xScale)) .selectAll("text") .attr("y", 0) .attr("x", 9) .attr("dy", ".35em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(45, -15)") .call(d3.axisLeft(yScale)); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(500," + height/3.206 + ")") .call(d3.axisBottom(xScale)) .selectAll("text") .attr("y", 0) .attr("x", 9) .attr("dy", ".35em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(500, -15)") .call(d3.axisLeft(yScale)); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(45," + height/1.20 + ")") .call(d3.axisBottom(xScale)) .selectAll("text") .attr("y", 0) .attr("x", 9) .attr("dy", ".35em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(45, " + height*0.50 + ")") .call(d3.axisLeft(yScale)); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(500," + height/1.20 + ")") .call(d3.axisBottom(xScale)) .selectAll("text") .attr("y", 0) .attr("x", 9) .attr("dy", ".35em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(500, " + height*0.50 + ")") .call(d3.axisLeft(yScale)); //adding title at the top svg.append("text") .attr("transform", "translate(" + (width/2) + " , -32)") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "22px") .text("Number of Cancelled Flights from Seven Popular Airports (Four Time Periods)"); //adding subtitles for each graph svg.append("text") .attr("transform", "translate(" + (width/4.2) + " , 20)") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "22px") .style("fill", "green") .text("2003 - 2006"); svg.append("text") .attr("transform", "translate(" + (width/1.3) + " , 20)") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "22px") .style("fill", "green") .text("2007 - 2009"); svg.append("text") .attr("transform", "translate(" + (width/4.2) + " , 380)") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "22px") .style("fill", "green") .text("2010 - 2012"); svg.append("text") .attr("transform", "translate(" + (width/1.3) + " , 380)") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "22px") .style("fill", "green") .text("2013 - 2016"); //labeling the axes svg.append("text") .attr("transform", "rotate(-90)") .attr("y", 0 - margin.left + 10) .attr("x",0 - (height / 2)) .attr("dy", "1em") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "18px") .text("Number of Flights Cancelled"); svg.append("text") .attr("transform", "translate(" + (width/2) + " ," + (height - 20) + ")") .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "18px") .text("Airport Locations"); }); </script> </body> </html>
https://d3js.org/d3.v4.min.js