Published
Edited
May 15, 2019
Fork of Project Code
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
dataGeneral = d3.csv("https://gist.githubusercontent.com/nbailey/95ad116b50e7b7cbe02a8e2dac626922/raw/e3d08f6b6c829885d997231988a27aa272f117cb/sevis_gen_201808")
Insert cell
dataStem = d3.csv("https://gist.githubusercontent.com/nbailey/95ad116b50e7b7cbe02a8e2dac626922/raw/e3d08f6b6c829885d997231988a27aa272f117cb/sevis_stem_201808")
Insert cell
Insert cell
Insert cell
dataStem.columns
Insert cell
stemCountries = z.unique(z.getCol("CoC", dataStem)).sort();
Insert cell
allCountries = z.unique(z.getCol("Country of Citizenship", dataGeneral)).sort();
Insert cell
states = z.unique(z.getCol("State", dataStem)).sort();
Insert cell
stateAbbrevs = dataGeneral.columns.slice(17,72);
Insert cell
stemByCountry = z.groupBy(d => d["CoC"], dataStem)
Insert cell
countryStem = {
let output = {};
z.gbSum("Count of Active STEM Students", stemByCountry).forEach(row => (output[row.group] = row.sum));
return output;
}
Insert cell
countryTotal = {
let countryStudents = {};
dataGeneral.forEach(row => (countryStudents[row["Country of Citizenship"]] = +row["# of Active Students"]));
return countryStudents
}
Insert cell
countryPctStem = {
let output = {};
for (var i in allCountries) {
let country = allCountries[i];
if (!stemCountries.includes(country)) {
output[country] = 0;
} else {
output[country] = countryStem[country] / countryTotal[country];
}
}
return output;
}
Insert cell
countryStateStem = {
let output = [];
for (var i in stemCountries) {
let country = stemCountries[i];
let countryStem = stemByCountry[country];
// output[country] = z.groupBy(d => d["Abbreviation"], countryStem);
output[country] = z.gbSum("Count of Active STEM Students", z.groupBy(d => d["Abbrv"], countryStem));
}
return output;
}
Insert cell
z.filter(d => (d.group == "TX"),countryStateStem["CHINA"])[0].sum
Insert cell
countryStateTotals = {
let output = {};
for (var i in allCountries) {
let country = allCountries[i];
let countryData = z.filter(d => (d["Country of Citizenship"] == country), dataGeneral);
// Keep columns 17:72, the data of how many students from that country are in each state
output[country] = z.pickCols(Object.keys(countryData[0]).slice(17,72), countryData)[0];
}
return output;
}
Insert cell
countryStateStemPct = {
let output = {};
for (var i in allCountries) {
let country = allCountries[i];
let stemPct = {};
let countryHasStem = stemCountries.includes(country);
let countryStemData = undefined;
let countryStemStates = undefined;
if (countryHasStem) {
countryStemData = countryStateStem[country];
countryStemStates = z.getCol("group", countryStemData)
}
let countryGenData = countryStateTotals[country];
let countryGenStates = Object.keys(countryGenData);
for (var j in stateAbbrevs) {
let state = stateAbbrevs[j];
if (countryHasStem) {
if (countryStemStates.includes(state)) {
let numStem = +z.filter(d => d.group == state, countryStemData)[0].sum;
let numStudents = +countryGenData[state];
// Assuming that STEM is a subset of the number of students
if (numStudents > 0) {
stemPct[state] = numStem / numStudents;
} else {
stemPct[state] = NaN;
}
// stemPct[state] = numStem / (numStem + numStudents);
} else {
stemPct[state] = 0;
}
} else {
stemPct[state] = 0;
}
}
output[country] = stemPct;
}
return output;
}
Insert cell
countryStateStemNumbers = {
let output = {};
for (var i in allCountries) {
let country = allCountries[i];
let stateStem = {};
let countryHasStem = stemCountries.includes(country);
let countryStemData = undefined;
let countryStemStates = undefined;
if (countryHasStem) {
countryStemData = countryStateStem[country];
countryStemStates = z.getCol("group", countryStemData)
}
let countryGenData = countryStateTotals[country];
let countryGenStates = Object.keys(countryGenData);
for (var j in stateAbbrevs) {
let state = stateAbbrevs[j];
if (countryHasStem) {
if (countryStemStates.includes(state)) {
let numStem = +z.filter(d => d.group == state, countryStemData)[0].sum;
stateStem[stateIDMap[state]] = numStem;
} else {
stateStem[stateIDMap[state]] = 0;
}
} else {
stateStem[stateIDMap[state]] = 0;
}
}
output[country] = stateStem;
}
return output;
}
Insert cell
countryStateStudentNumbers[countryOfInterest][11]
Insert cell
countryStateStudentNumbers = {
let output = {};
for (var i in allCountries) {
let country = allCountries[i];
let stateStudents = {};

let countryHasStem = stemCountries.includes(country);
let countryStemData = undefined;
let countryStemStates = undefined;
if (countryHasStem) {
countryStemData = countryStateStem[country];
countryStemStates = z.getCol("group", countryStemData)
}
let countryGenData = countryStateTotals[country];
let countryGenStates = Object.keys(countryGenData);
for (var j in stateAbbrevs) {
let state = stateAbbrevs[j];
if (countryHasStem) {
if (countryGenStates.includes(state)) {
let numStudents = +countryGenData[state];
stateStudents[stateIDMap[state]] = numStudents;
} else {
stateStudents[stateIDMap[state]] = 0;
}
} else {
stateStudents[stateIDMap[state]] = 0;
}
}
output[country] = stateStudents;
}
return output;
}
Insert cell
countrySelector = html`<select id="countrySelect"></select>`
Insert cell
countryOfInterest = country_dropdown
Insert cell
// Will use this when not on Observable: https://www.electrictoolbox.com/javascript-add-options-html-select/
countrySelector.options[0] = new Option("test", 0)
Insert cell
stemPctByID = {
let output = {};
Object.keys(countryStateStemPct[country_dropdown]).forEach(function(d) {
output[stateIDMap[d]] = countryStateStemPct[country_dropdown][d];
})
return output;
}
Insert cell
// your code here
stemPctByState = {
let width = 960;
let height = 600;
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
// Bind TopoJSON data
g.selectAll("path")
.data(topojson.feature(us, us.objects.states).features) // Bind TopoJSON data elements
.enter().append("path")
.attr("d", path)
.style("fill", d => pctColorScale(stemPctByID[d.id]))
.style("stroke", "black")
.on("mouseover", d => tooltip.style("visibility", "visible").text(d.id))
.on("mousemove", d => tooltip.style("top", (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").html(stateNameMap[d.id] + ": <br/>" + (100 * stemPctByID[d.id]).toFixed(1) + "% STEM <br/>(" + countryStateStemNumbers[countryOfInterest][d.id] + " STEM students out of " + countryStateStudentNumbers[countryOfInterest][d.id] + " total)"))
.on("mouseout", d => tooltip.style("visibility", "hidden"));

return svg.node();
}
Insert cell
Insert cell
// your code here
{
let width = 960;
let height = 600;
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
// Bind TopoJSON data
g.selectAll("path")
.data(topojson.feature(us, us.objects.states).features) // Bind TopoJSON data elements
.enter().append("path")
.attr("d", path)
.style("fill", d => numColorScale(countryStateStudentNumbers[countryOfInterest][d.id]))
.style("stroke", "black")
.on("mouseover", d => tooltip.style("visibility", "visible").text(d.id))
.on("mousemove", d => tooltip.style("top", (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").text(stateNameMap[d.id] + ": " + countryStateStudentNumbers[countryOfInterest][d.id] + " students from " + countryOfInterest))
.on("mouseout", d => tooltip.style("visibility", "hidden"));

return svg.node();
}
Insert cell
path = d3.geoPath();
Insert cell
tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("font-family", "'Open Sans', sans-serif")
.style("font-size", "12px")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "white")
.style("padding", "5px")
.style("width", "100px")
Insert cell
pctColorScale = d3.scaleQuantize()
.domain([0, 1])
.range(d3.schemePurples[9]);
Insert cell
numColorScale = d3.scaleQuantize()
.domain([0, d3.max(Object.values(countryStateStudentNumbers[countryOfInterest]))])
.range(d3.schemePurples[9]);
Insert cell
Insert cell
Insert cell
stateIDMap = {
let output = {};
for (let i in onlyStates) {
let state = onlyStates[i];
let abbreviation = z.unique(z.getCol("Abbrv", z.filter(row => row["State"] == state, dataStem)))[0]
output[abbreviation] = stateIDs[i];
}
return output;
}
Insert cell
stateNameMap = {
let output = {};
for (let i in onlyStates) {
let state = onlyStates[i];
output[stateIDs[i]] = state;
}
return output;
}
Insert cell
topojson.mesh(us, us.objects.states, (a, b) => a !== b)
Insert cell
md` ## Degree Level by Country`
Insert cell
dataGeneral.columns
Insert cell
vocational = z.deriveCol(row => +row["FLIGHT TRAINING"] + +row["LANGUAGE TRAINING"] + +row["OTHER VOCATIONAL SCHOOL"], dataGeneral);
Insert cell
newData = z.addCol("VOCATIONAL", vocational, dataGeneral)
Insert cell
series = d3.stack().keys(["ASSOCIATE", "BACHELOR'S", "MASTER'S", "DOCTORATE", "VOCATIONAL"])(degreesByCountry)
Insert cell
degreesByCountry = z.filter(r => r["Country of Citizenship"] == country_dropdown, newData);
Insert cell
margin = ({top: 10, right: 10, bottom: 20, left: 40})
Insert cell
Insert cell
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickSizeOuter(0)) //feeding function 'x' as a function
.call(g => g.selectAll(".domain").remove())
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const svg1 = d3.select(DOM.svg(width, height)); //pointing it to the DOM object

svg1.append("g")
.selectAll("g")
.data(series)
.join("g")
.attr("fill", d => color(d.key))
.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", (d, i) => x(d.data.year))
.attr("y", d => y(d[1])) //feeding y the data at index [1]
.attr("height", d => y(d[0]) - y(d[1]))
.attr("width", x.bandwidth());

svg1.append("g")
.call(xAxis);

svg1.append("g")
.call(yAxis);

svg1.append("g")
.call(legend);

return svg1.node();
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more