Skip to content

Instantly share code, notes, and snippets.

@SHewitt95
Created February 29, 2016 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SHewitt95/dbc08c4a141ad3b6783d to your computer and use it in GitHub Desktop.
Save SHewitt95/dbc08c4a141ad3b6783d to your computer and use it in GitHub Desktop.
Transition Plot
<!DOCTYPE html>
<!-- Modification of an example by Scott Murray from Knight D3 course -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Line Chart with Multiple Data Sets, Transitions</title>
<!-- this is the cdn link to bootstrap's css -->
<!--link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"-->
<style type="text/css">
body {
background-color: white;
font-family: Helvetica, Arial, sans-serif;
}
h1 {
font-size: 24px;
margin: 0;
}
p {
font-size: 14px;
margin: 10px 0 10px 0;
}
.selected {
background-color: pink;
}
svg {
background-color: white;
}
.axis path,
.axis line {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
.line {
fill: none;
stroke: black;
stroke-width: 1px;
stroke-opacity: 80%;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
line-height: 1em;
}
.map_note {
padding-top: 120px;
padding-left: 30px;
}
.tooltip {
position: absolute;
z-index: 10;
}
.tooltip p {
background-color: white;
border: none;
padding: 2px;
}
/* this is an adjustment to bootstrap's row for my page */
.row {
padding-top: 0px;
}
/* this is an adjustment to bootstrap for my page */
.btn-group {
padding-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="">
<h1>College Enrollment Percentages, based on race/ethnicity and gender</h1>
<p>Source: Data.gov, U.S. Department of Commerce, Census Bureau, Current Population Survey</p>
<p>The data portrays the changing percentages of 18 to 24-year-olds per race/ethnicity who attend 2 or 4-year colleges. In addition, the data separates the races by gender. For example, in 2000, 18.5 percent of Hispanic males between age 18 and 24 attended college. By 2012, that percentage increased by 15 percent to 33.5 percent.</p>
<p>Click the buttons below to cycle through the different data points.</p>
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default" id="Male">Male</button>
<button type="button" class="btn btn-default" id="Female">Female</button>
<br />
<button type="button" class="btn btn-default" id="Asian">Asian</button>
<button type="button" class="btn btn-default" id="Black">Black</button>
<button type="button" class="btn btn-default" id="Hispanic">Hispanic</button>
<button type="button" class="btn btn-default" id="White">White</button>
</div>
<br />
<h2 id="graph_title"></h2>
<div id="svg"></div>
</div>
</div>
</div>
<!--
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<!--script type="text/javascript" src="d3.min.js"></script-->
<script type="text/javascript">
//Dimensions and padding
var fullwidth = 950;
var fullheight = 500;
var margin = {top: 20, right: 20, bottom: 40, left: 50};
var width = fullwidth - margin.left - margin.right;
var height = fullheight - margin.top - margin.bottom;
//Set up date formatting and years
var dateFormat = d3.time.format("%Y");
var outputFormat = d3.time.format("%Y");
//Set up scales - I already know the start and end years, not using data for it.
var xScale = d3.time.scale()
.range([ 0, width ]);
// don't know the yScale domain yet. Will set it with the data.
var yScale = d3.scale.linear()
.range([ 0, height ]);
//Configure axis generators
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10)
.tickFormat(function(d) {
return outputFormat(d);
})
.innerTickSize([6])
.outerTickSize([0]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.innerTickSize([6])
.outerTickSize([0]);
//Configure line generator
// each line dataset must have an x and y for this to work.
var line = d3.svg.line()
.x(function(d) {
return xScale(dateFormat.parse(d.year));
})
.y(function(d) {
return yScale(+d.percent);
});
// add a tooltip to the page - not to the svg itself!
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip");
//Create the empty SVG image
var svg = d3.select("#svg")
.append("svg")
.attr("width", fullwidth)
.attr("height", fullheight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var selectedGender = "Female",
selectedRace = "Asian, non-Hispanic";
d3.select("#graph_title")
//.append("h1")
.html(selectedGender + ", " + selectedRace);
//Load data
d3.csv("Race_Education_Data_Male_Female.csv", function(error, data) {
var dataset = [];
//var simpleRace = ["Asian", "Black", "Hispanic", "White"];
var years = d3.keys(data[0]).slice(0, 13);
//console.log(dataset);
//console.log(years);
//Loop once for each row in data
data.forEach(function(d, i) {
var eduPerYear = [];
//Loop through all the years
years.forEach(function(y) {
if (d[y]) {
//Add a new object to the new eduPerYear data array - for year, percent
eduPerYear.push({
race: d["Race_Ethnicity"],
year: y,
gender: d["Gender"],
percent: d[y]
});
}
})
//Create new object with this race's name and empty array
// d is the current data row... from data.forEach above.
dataset.push({
race: d["Race_Ethnicity"],
gender: d["Gender"],
data: eduPerYear
});
}) // End of data.forEach loop.
//console.log(dataset);
/*var males = [],
females = [];
// Creates two separate arrays: one for males, one for females.
dataset.forEach(function(d,i) {
if (d["gender"] === "Male") {
males.push(d);
} else {
females.push(d);
}
})
//console.log(males);
//console.log(females);
function getGenderData(gender) {
if (gender === "Male") {
return males;
} else {
return females;
}
}*/
xScale.domain(
d3.extent(years, function(d) {
return dateFormat.parse(d);
}));
// max of percentages to 0 (reversed, remember) - [max, 0] for y scale
yScale.domain([
d3.max(dataset, function(d) {
return d3.max(d.data, function(d) {
return +d.percent;
});
}),
0
]);
//console.log(dataset[0]);
//Make a group for each race/ethnicity for males as a start - just for the data binding
var groups = svg.selectAll("g.lines")
.data([dataset[0]])
.enter()
.append("g")
//.attr("class", "lines")
.attr("class", function(d) {
return("lines " + d["gender"]);
});
//Within each group, create a new line/path,
//binding just the percentage data to each one
//var colors = d3.scale.category10();
groups.selectAll("path")
.data(function(d) { // because there's a group with data per race already...
return [ d.data ]; // it has to be an array for the line function
})
.enter()
.append("path")
.attr("class", "line")
.attr("d", line); // calls the line function you defined above, using that array
//Axes
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// Returns new data based on selected race and gender.
function get_gender_race_data(selection) {
if (selection === "Male" || selection === "Female") {
selectedGender = selection;
} else {
selectedRace = fix_race_selection(selection);
}
var newdata = dataset.filter(function(d) {
return (d["gender"] == selectedGender && d["race"] == selectedRace);
});
//console.log(newdata);
return newdata;
}
// Converts id into the label used in the CSV file.
function fix_race_selection(race) {
var fixedSelection;
switch(race) {
case "Asian":
fixedSelection = "Asian, non-Hispanic";
break;
case "Black":
fixedSelection = "Black, non-Hispanic ";
break;
case "White":
fixedSelection = "White, non-Hispanic";
break;
default:
fixedSelection = "Hispanic";
break;
}
return fixedSelection;
}
d3.selectAll("button").on("click", function() {
// Handle the button click to change the data set.
var selectedline = d3.select("path.line");
var thisButton = d3.select(this);
// current attr "id" is returned if you don't set it to anything!
var newdata = get_gender_race_data(thisButton.attr("id")); // the id has to match the country name for this to work.
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
//console.log(newdata[0].data);
selectedline.transition().attr("d", line(newdata[0].data));
d3.select("#graph_title")
//.append("h1")
.html(selectedGender + ", " + selectedRace);
});
}); // end of data csv
</script>
<!-- Latest compiled and minified JavaScript -->
</body>
</html>
Gender Race_Ethnicity 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
Female Asian, non-Hispanic 52.8 58.9 61.9 60.4 57.7 58.8 58.3 56.8 63 65.2 65.8 60.3 60.4
Male Asian, non-Hispanic 59.0 63.7 59.9 62.2 63.5 63.1 58.4 57.7 55.3 65.2 61.3 59.9 59.3
Female Black, non-Hispanic 35.2 35.5 36.9 36 36.6 37.6 36.9 34 34.2 41.9 41.4 39.9 38.7
Male Black, non-Hispanic 25.1 26.7 26.3 28.2 26.5 28.2 28.1 32.2 29.7 33.2 35.2 34.0 33.9
Female Hispanic 25.4 26.1 24.4 29.4 28.2 29.5 27.6 33 28.9 31 36.1 39.4 41.7
Male Hispanic 18.5 17.4 16.2 18.3 21.7 20.7 20.0 20.7 23.0 24.2 27.9 31.0 33.5
Female White, non-Hispanic 41.3 41.9 42.8 44.5 45 46.1 44.1 45.7 46.9 47.7 46.1 47.1 46
Male White, non-Hispanic 36.2 37.2 38.9 38.5 38.4 39.4 37.9 39.6 41.7 42.3 40.6 42.4 38.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment