Public
Edited
Mar 22, 2023
Insert cell
Insert cell
Insert cell
averageSalaryMap(us)
Insert cell
averageSalaryMap = (us) => {
const svg = d3.create("svg")
.attr("width", chloroplethMapWidth)
.attr("height", chloroplethMapHeight)
.attr("viewBox", [0, 0, 2400, chloroplethMapHeight]);

const averageTeacherSalaryFileType = "Average Teacher Salary By State in ";

const str = averageTeacherSalaryFileType + averageSalaryYearFilter;

// Info Window Text
const infoWindowText = svg.append("text")
.attr("x", 15)
.attr("y", 15)
.attr("transform", "translate(985,110)")
.attr("font-size", 18)

let rank;
let topFiveStates;
let bottomFiveStates;
let notableTeacherStrikesText = "";
let notableTeacherStrikesTextPart2 = "";
let notableTeacherStrikesTextPart3 = "";
let notableTeacherStrikesFacts = "";
let notableTeacherStrikesFactsPart2 = "";
let notableTeacherStrikesFactsPart3 = "";
let notableTeacherStrikesFactsPart4 = "";
let notableTeacherStrikesFactsPart5 = "";
let notableTeacherStrikesFactsPart6 = "";
let notableTeacherStrikesFactsPart7 = "";

if (str === averageTeacherSalaryFileType + "2010") {
rank = avgTeacherSalaryRank2010.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2010.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.reverse()
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2010.entries())
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([state, rank]) => state)
notableTeacherStrikesText = "Arizona, California, Michigan, Pennsylvania";
} else if (str === averageTeacherSalaryFileType + "2011") {
rank = avgTeacherSalaryRank2011.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2011.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2011.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "California, Chicago, New York, Wisconsin";
notableTeacherStrikesFacts = "Wisconsin's Act 10 on Collective Bargaining.";
} else if (str === averageTeacherSalaryFileType + "2012") {
rank = avgTeacherSalaryRank2012.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2012.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2012.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Chicago, Idaho";
notableTeacherStrikesFacts = "- Chicago's 600+ school closure during strikes.";
notableTeacherStrikesFactsPart2 = "- Wisconsin's Recall Governor Elections & Unions.";
notableTeacherStrikesFactsPart3 = "- Michigan's Right to Work (24th state to pass law).";
} else if (str === averageTeacherSalaryFileType + "2013") {
rank = avgTeacherSalaryRank2013.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2013.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2013.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Michigan, Pennsylvania, Washington";
notableTeacherStrikesFacts = "- Chicago's closure of 49 schools in low-income,";
notableTeacherStrikesFactsPart2 = "minority neighborhoods.";
} else if (str === averageTeacherSalaryFileType + "2014") {
rank = avgTeacherSalaryRank2014.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2014.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2014.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Chicago, Oregon, Washington, West Virginia";
notableTeacherStrikesFacts = "- Seattle's 50+ school closure during strikes.";
notableTeacherStrikesFactsPart2 = "- Chicago's 600+ school closure during strikes.";
} else if (str === averageTeacherSalaryFileType + "2015") {
rank = avgTeacherSalaryRank2015.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2015.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2015.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Chicago, Minnesota, Oklahoma, Washington";
} else if (str === averageTeacherSalaryFileType + "2016") {
rank = avgTeacherSalaryRank2016.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2016.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2016.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Massachusetts";
notableTeacherStrikesFacts = "- Supreme Court Friedrichs v. California Teachers";
notableTeacherStrikesFactsPart2 = "Association Case on Union Fees.";
notableTeacherStrikesFactsPart3 = "- Presidential Election & Education Policies.";
notableTeacherStrikesFactsPart4 = "- New Secretary of Education.";
} else if (str === averageTeacherSalaryFileType + "2017") {
rank = avgTeacherSalaryRank2017.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2017.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2017.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Arizona, Colorado, Kansas, Kentucky";
notableTeacherStrikesTextPart2 = "Massachusetts, Michigan, North Carolina,";
notableTeacherStrikesTextPart3 = "Oklahoma, Washington, West Virginia";
} else if (str === averageTeacherSalaryFileType + "2018") {
rank = avgTeacherSalaryRank2018.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2018.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2018.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Arizona, Colorado, Kentucky, North Carolina,";
notableTeacherStrikesTextPart2 = "Oklahoma, West Virginia";
notableTeacherStrikesFacts = "- Arizona: State approves 20% pay raise by 2020";
notableTeacherStrikesFactsPart2 = "(not in effect until following year)."
notableTeacherStrikesFactsPart3 = "- Michigan's 80+ school closure during strikes.";
notableTeacherStrikesFactsPart4 = "- Oklahoma: Approved $6,000 pay raise"
notableTeacherStrikesFactsPart5 = "(not in effect until following year).";
notableTeacherStrikesFactsPart6 = "- West Virginia: Approved 5% pay increase";
notableTeacherStrikesFactsPart7 = "(not in effect until following year).";
} else if (str === averageTeacherSalaryFileType + "2019") {
rank = avgTeacherSalaryRank2019.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2019.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2019.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "California, Colorado, Kentucky, West Virginia";
} else if (str === averageTeacherSalaryFileType + "2020") {
rank = avgTeacherSalaryRank2020.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2020.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2020.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "Arizona, California, Chicago, Colorado, Nevada";
notableTeacherStrikesFacts = "COVID-Related Strikes."
} else if (str === averageTeacherSalaryFileType + "2021") {
rank = avgTeacherSalaryRank2021.get(name);
bottomFiveStates = Array.from(avgTeacherSalaryRank2021.entries())
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 5)
.map(([state, rank]) => state);
topFiveStates = Array.from(avgTeacherSalaryRank2021.entries())
.filter(([key, value]) => value > 0)
.sort((a, b) => a[1] - b[1])
.slice(0, 5)
.map(([key, value]) => key)
notableTeacherStrikesText = "California, Chicago, Minnesota, Oregon, Virginia";
notableTeacherStrikesFacts = "COVID-Related Strikes."
}
infoWindowText.text(name)
.append("tspan")
.attr("x", 0)
.attr("y", 0)
.attr("dy", "1.2em")
.text("TOP 5 STATES");

topFiveStates.forEach((state, index) => {
infoWindowText.append("tspan")
.attr("x", 0)
.attr("dy", "1.2em")
.text(`${index + 1}. ${state}`);
})
infoWindowText.append("tspan")
.attr("x",200)
.attr("y", 0)
.attr("dy", "1.2em")
.text("BOTTOM 5 STATES");
bottomFiveStates.forEach((state, index) => {
infoWindowText.append("tspan")
.attr("x", 200)
.attr("dy", "1.2em")
.text(`${index + 46}. ${state}`);
});

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 180)
.attr("dy", "1.3em")
.text("NOTABLE TEACHER STRIKES");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "2.3em")
.text("States with Most Notable States:");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "3.3em")
.text(notableTeacherStrikesText);

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "4.3em")
.text(notableTeacherStrikesTextPart2 ? notableTeacherStrikesTextPart2 : "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "5.3em")
.text(notableTeacherStrikesTextPart3 ? notableTeacherStrikesTextPart3: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "7.3em")
.text("Comments:");
infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "8.3em")
.text(notableTeacherStrikesFacts ? notableTeacherStrikesFacts: "N/A");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "9.3em")
.text(notableTeacherStrikesFactsPart2 ? notableTeacherStrikesFactsPart2: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "10.3em")
.text(notableTeacherStrikesFactsPart3 ? notableTeacherStrikesFactsPart3: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "11.3em")
.text(notableTeacherStrikesFactsPart4 ? notableTeacherStrikesFactsPart4: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "12.3em")
.text(notableTeacherStrikesFactsPart5 ? notableTeacherStrikesFactsPart5: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "13.3em")
.text(notableTeacherStrikesFactsPart6 ? notableTeacherStrikesFactsPart6: "");

infoWindowText.append("tspan")
.attr("x", 0)
.attr("y", 200)
.attr("dy", "14.3em")
.text(notableTeacherStrikesFactsPart7 ? notableTeacherStrikesFactsPart7: "");
// Chloropleth Map Colors
let color;
// const salaryLegend = [40000, 50000, 60000, 70000];
// color = d3.scaleThreshold()
// .domain(salaryLegend)
// .range(d3.schemeBlues[4]);
// const salaryLegend = [30000, 40000, 50000, 60000, 70000, 80000];
// color = d3.scaleThreshold()
// .domain(salaryLegend)
// .range(d3.schemeGnBu[6]);

const salaryLegend = [40000, 50000, 60000, 70000, 80000];
// const salaryLegend = [30000, 40000, 50000, 60000, 70000];
color = d3.scaleLinear()
.domain(salaryLegend)
.range(d3.schemeBlues[5]);

// Add Color Schema Legend
svg.append("g")
.attr("transform", "translate(1003,30)")
.append(function(d) {
return legend({color, title: `Average Teacher Salary in dollars($)`, width: 350});
})

// Map Title
svg.append("text")
.attr("x", width / 4)
.attr("y", 0)
.attr("text-anchor", "start")
.style("font-size", "30px")
.style("font-weight", "bold")
.text(str);

// Baseline Map of Nations
svg.append("path")
.datum(nations)
.attr("fill", "black")
.attr("stroke", "none")
.attr("d", path);

// Baseline Map of States
svg.append("path")
.datum(states)
.attr("fill", "none")
.attr("stroke", "none")
.attr("d", path);

// SVG Show or Hide State Information
svg.append("g")
.selectAll("path")
.data(states.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", function (d) {
if (str === averageTeacherSalaryFileType + "2010") {
return color(avgTeacherSalary2010.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2011") {
return color(avgTeacherSalary2011.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2012") {
return color(avgTeacherSalary2012.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2013") {
return color(avgTeacherSalary2013.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2014") {
return color(avgTeacherSalary2014.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2015") {
return color(avgTeacherSalary2015.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2016") {
return color(avgTeacherSalary2016.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2017") {
return color(avgTeacherSalary2017.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2018") {
return color(avgTeacherSalary2018.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2019") {
return color(avgTeacherSalary2019.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2020") {
return color(avgTeacherSalary2020.get(d.properties.name));
} else if (str === averageTeacherSalaryFileType + "2021") {
return color(avgTeacherSalary2021.get(d.properties.name));
}
})
.attr("stroke", "white")
.on("mouseover", (event, d) => {
const [x, y] = d3.pointer(event);
const padding = 5;
const lengthOfStateName = d.properties.name.length * 10
const name = d.properties.name;

d3.select(event.currentTarget)
.attr("stroke", "black")
.raise();

let salary;
let rank;
let state_pop;
let num_teachers;

// Color Density Based on Average Teacher Salary Per State Per Year
if (str === averageTeacherSalaryFileType + "2010") {
salary = avgTeacherSalary2010.get(name);
rank = avgTeacherSalaryRank2010.get(name);
state_pop = statePopulation2010.get(name);
num_teachers = fteTeachers2010.get(name);
} else if (str === averageTeacherSalaryFileType + "2011") {
salary = avgTeacherSalary2011.get(name);
rank = avgTeacherSalaryRank2011.get(name);
state_pop = statePopulation2011.get(name);
num_teachers = fteTeachers2011.get(name);
} else if (str === averageTeacherSalaryFileType + "2012") {
salary = avgTeacherSalary2012.get(name);
rank = avgTeacherSalaryRank2012.get(name);
state_pop = statePopulation2012.get(name);
num_teachers = fteTeachers2012.get(name);
} else if (str === averageTeacherSalaryFileType + "2013") {
salary = avgTeacherSalary2013.get(name);
rank = avgTeacherSalaryRank2013.get(name);
state_pop = statePopulation2013.get(name);
num_teachers = fteTeachers2013.get(name);
} else if (str === averageTeacherSalaryFileType + "2014") {
salary = avgTeacherSalary2014.get(name);
rank = avgTeacherSalaryRank2014.get(name);
state_pop = statePopulation2014.get(name);
num_teachers = fteTeachers2014.get(name);
} else if (str === averageTeacherSalaryFileType + "2015") {
salary = avgTeacherSalary2015.get(name);
rank = avgTeacherSalaryRank2015.get(name);
state_pop = statePopulation2015.get(name);
num_teachers = fteTeachers2015.get(name);
} else if (str === averageTeacherSalaryFileType + "2016") {
salary = avgTeacherSalary2016.get(name);
rank = avgTeacherSalaryRank2016.get(name);
state_pop = statePopulation2016.get(name);
num_teachers = fteTeachers2016.get(name);
} else if (str === averageTeacherSalaryFileType + "2017") {
salary = avgTeacherSalary2017.get(name);
rank = avgTeacherSalaryRank2017.get(name);
state_pop = statePopulation2017.get(name);
num_teachers = fteTeachers2017.get(name);
} else if (str === averageTeacherSalaryFileType + "2018") {
salary = avgTeacherSalary2018.get(name);
rank = avgTeacherSalaryRank2018.get(name);
state_pop = statePopulation2018.get(name);
num_teachers = fteTeachers2018.get(name);
} else if (str === averageTeacherSalaryFileType + "2019") {
salary = avgTeacherSalary2019.get(name);
rank = avgTeacherSalaryRank2019.get(name);
state_pop = statePopulation2019.get(name);
num_teachers = fteTeachers2019.get(name);
} else if (str === averageTeacherSalaryFileType + "2020") {
salary = avgTeacherSalary2020.get(name);
rank = avgTeacherSalaryRank2020.get(name);
state_pop = statePopulation2020.get(name);
num_teachers = fteTeachers2020.get(name);
} else if (str === averageTeacherSalaryFileType + "2021") {
salary = avgTeacherSalary2021.get(name);
rank = avgTeacherSalaryRank2021.get(name);
state_pop = statePopulation2021.get(name);
num_teachers = fteTeachers2021.get(name);
}
tooltip.select("text")
.text(null)
.append("tspan")
.text(name)
.attr("font-size", "25px")

.append("tspan")
.attr("dy", "1.2em")
.attr("font-size", "20px")
.attr("x", 20)
.attr("y", 25)
.attr("text-anchor", "start")
.text(num_teachers ? `# FTE Teachers: ${commaSeparated(num_teachers)} teachers` : "")

.append("tspan")
.attr("dy", "2.2em")
.attr("font-size", "20px")
.attr("x", 20)
.attr("y", 25)
.attr("text-anchor", "start")
.text(state_pop ? `State Population: ${commaSeparated(state_pop)} people` : "")

.append("tspan")
.attr("dy", "4.4em")
.attr("font-size", "20px")
.attr("x", 20)
.attr("y", 25)
.attr("text-anchor", "start")
.text(salary ? `Average Teacher Salary: $${commaSeparated(salary)}` : "No 2010 Average Teacher Salary Available")

.append("tspan")
.attr("dy", "5.5em")
.attr("font-size", "20px")
.attr("x", 20)
.attr("y", 25)
.attr("text-anchor", "start")
.text(rank ? `Average Teacher Salary Rank: ${rank}` : "")

const textLength = tooltip.select('text').node().getComputedTextLength();

tooltip.select("rect")
.attr("width", textLength / 3)
.attr("height", 150)
.attr("x")
tooltip.attr("transform", `translate(${x},${y})`);
tooltip.style("display", "block");
})
.on("mouseout", (event, d) => {
tooltip.style("display", "none")

d3.select(event.currentTarget)
.attr("stroke", "white")
.lower();
});

// Right Side Info Window
const infoWindow = svg
.append("rect")
.attr("transform", "translate(970,100)")
.attr("width", 420)
.attr("height", 500)
.attr("fill", "none")
.attr("stroke", "black")
.raise();

// Tooltip
const rect = svg
.append("rect")
.attr("id", "tooltip-box")
.attr("height", 100)

const stateName = svg.append("text")
.attr("y", 20)
.attr("stroke", "black")
.attr("alignment-baseline", "middle");

const tooltip = svg
.append("g")
.attr("class", "tooltip")
.style("display", "none");

tooltip.append("rect")
.attr("width", 100)
.attr("height", 80)
.attr("fill", "white")
.attr("stroke", "black")
tooltip.append("text")
.attr("y", 25)
.attr("x", 20)
.attr("text-anchor", "start")
.text("");
return svg.node();
}
Insert cell
Insert cell
chloroplethMapWidth = 2000
Insert cell
chloroplethMapHeight = 700
Insert cell
// TopoJSON Map Data for the United States
us = FileAttachment("states-albers-10m.json").json()
Insert cell
Insert cell
statePopulation2010 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2010.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2010"})
Insert cell
statePopulation2011 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2011.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2011"})
Insert cell
statePopulation2012 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2012.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2012"})
Insert cell
statePopulation2013 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2013.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2013"})
Insert cell
statePopulation2014 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2014.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2014"})
Insert cell
statePopulation2015 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2015.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2015"})
Insert cell
statePopulation2016 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2016.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2016"})
Insert cell
statePopulation2017 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2017@1.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2017"})
Insert cell
statePopulation2018 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2018@1.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2018"})
Insert cell
statePopulation2019 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2019@1.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2019"})
Insert cell
statePopulation2020 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2020@1.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2020"})
Insert cell
statePopulation2021 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2021@1.csv").text(), ({state, state_population}) => [state, +state_population])), {title: "State Population Per State in 2021"})
Insert cell
Insert cell
fteTeachers2010 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2010.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2010"})
Insert cell
fteTeachers2011 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2011.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2011"})
Insert cell
fteTeachers2012 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2012.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2012"})
Insert cell
fteTeachers2013 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2013.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2013"})
Insert cell
fteTeachers2014 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2014.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2014"})
Insert cell
fteTeachers2015 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2015.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2015"})
Insert cell
fteTeachers2016 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2016.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2016"})
Insert cell
fteTeachers2017 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2017@1.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2017"})
Insert cell
fteTeachers2018 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2018@1.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2018"})
Insert cell
fteTeachers2019 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2019@1.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2019"})
Insert cell
fteTeachers2020 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2020@1.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2020"})
Insert cell
fteTeachers2021 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2021@1.csv").text(), ({state, num_fte_teachers}) => [state, +num_fte_teachers])), {title: "Number of FTE Teachers By State in 2021"})
Insert cell
Insert cell
avgTeacherSalaryRank2010 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2010.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2010"})
Insert cell
avgTeacherSalaryRank2011 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2011.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2011"})
Insert cell
avgTeacherSalaryRank2012 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2012.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2012"})
Insert cell
avgTeacherSalaryRank2013 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2013.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2013"})
Insert cell
avgTeacherSalaryRank2014 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2014.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2014"})
Insert cell
avgTeacherSalaryRank2015 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2015.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2015"})
Insert cell
avgTeacherSalaryRank2016 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2016.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2016"})
Insert cell
avgTeacherSalaryRank2017 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2017@1.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2017"})
Insert cell
avgTeacherSalaryRank2018 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2018@1.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2018"})
Insert cell
avgTeacherSalaryRank2019 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2019@1.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2019"})
Insert cell
avgTeacherSalaryRank2020 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2020@1.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2020"})
Insert cell
avgTeacherSalaryRank2021 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2021@1.csv").text(), ({state, rank}) => [state, +rank])), {title: "Average Teacher Salary Rank By State in 2021"})
Insert cell
Insert cell
avgTeacherSalary2010 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2010.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2010"})
Insert cell
avgTeacherSalary2011 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2011.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2011"})
Insert cell
avgTeacherSalary2012 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2012.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2012"})
Insert cell
avgTeacherSalary2013 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2013.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2013"})
Insert cell
avgTeacherSalary2014 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2014.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2014"})
Insert cell
avgTeacherSalary2015 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2015.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2015"})
Insert cell
avgTeacherSalary2016 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2016.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2016"})
Insert cell
avgTeacherSalary2017 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2017@1.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2017"})
Insert cell
avgTeacherSalary2018 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2018@1.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2018"})
Insert cell
avgTeacherSalary2019 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2019@1.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2019"})
Insert cell
avgTeacherSalary2020 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2020@1.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2020"})
Insert cell
avgTeacherSalary2021 = Object.assign(new Map(d3.csvParse(await FileAttachment("teacherData2021@1.csv").text(), ({state, avg_teacher_salary}) => [state, +avg_teacher_salary])), {title: "Average Teacher Salary By State in 2021"})
Insert cell
Insert cell
d3 = require('d3@7', 'd3-geo@2', 'd3-dsv', 'd3-selection');
Insert cell
d3_annotation = require("https://cdnjs.cloudflare.com/ajax/libs/d3-annotation/2.3.0/d3-annotation.min.js")
Insert cell
projection = d3.geoAlbersUsa().scale(1300).translate([487.5, 305])
Insert cell
path = d3.geoPath()
Insert cell
states = topojson.feature(us, us.objects.states, (a, b) => a !== b);
Insert cell
nations = topojson.feature(us, us.objects.nation);
Insert cell
topojson = require("topojson-client@3")
Insert cell
import {legend} from "@d3/color-legend"
Insert cell
import {select} from "@jashkenas/inputs"
Insert cell
import {Scrubber} from "@mbostock/scrubber"
Insert cell
commaSeparated = d3.format(",")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more