Public
Edited
Oct 27, 2022
1 fork
1 star
Insert cell
# NYC Subway History
Insert cell
d3 = require("d3@6")
Insert cell
function getDistance (x1, y1, x2, y2){
let y = x2 - x1;
let x = y2 - y1;
return Math.sqrt(x * x + y * y);
}
Insert cell
viewof radius = Inputs.range([0.25, 3], {step: .25, label: "Stop Size"})
Insert cell
chart = {
const width = 960,
height = 900;
const svg = d3.create("svg")
.attr("viewBox", [50, 50, width - 250, height - 150]);

// Use Mercator projection
var projection = d3
.geoMercator()
.fitSize([width - 105, height - 80], borough_outline);

var path1 = d3.geoPath().projection(projection);
var path2 = d3.geoPath().projection(projection);
var path3 = d3.geoPath().projection(projection);
var path4 = d3.geoPath().projection(projection);
var path5 = d3.geoPath().projection(projection);
var path6 = d3.geoPath().projection(projection);
var path7 = d3.geoPath().projection(projection);
var path8 = d3.geoPath().projection(projection);
var path9 = d3.geoPath().projection(projection);
var path10 = d3.geoPath().projection(projection);

var g = svg.append("g").attr("id", "paths");

var clicks = []

g.selectAll("path1") //d3 geopath
.data(boroughs.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path1") //d3 geopath
.data(pop5.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', PopColor2020)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

function PopColor2020(d,i) {
var color = 'white'

if(d.properties.NYC2020POP_density >= 70000 && d.properties.NYC2020POP_density <= 109931){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC2020POP_density >= 50000 && d.properties.NYC2020POP_density <= 70000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC2020POP_density >= 35000 && d.properties.NYC2020POP_density <= 50000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC2020POP_density >= 20000 && d.properties.NYC2020POP_density <= 35000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC2020POP_density >= 3000 && d.properties.NYC2020POP_density <= 20000){color = 'rgb(237, 224, 212)'}
return color
}

g.selectAll("path10") //d3 geopath
.data(streetlines.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", 'none')
.style('stroke-opacity','.25')
.style("stroke-width", '.15')
.style("stroke", "gray")
g.selectAll("path9") //d3 geopath
.data(current_lines.features) //CURRENT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path8) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.4')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

var c = svg.selectAll("circle")//current
.data(current_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class','spots')
.attr("cx", function(d) {return path9.centroid(d)[0]})
.attr("cy", function(d) {return path9.centroid(d)[1]})
.attr('r', radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

svg
.on('click', function(event){
var coords = d3.pointer(event)
// console.log(coords[0])

clicks.push(coords)
// console.log(clicks)

c.enter().append("circle") //circle
.data(clicks)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return d[0]})
.attr("cy", function(d) {return d[1]})
.attr('r', radius)
.attr('fill', 'black')
.style('fill-opacity','1')

var distances = []
var sortDistances = []
//loop through clicks array
for(let i = 0; i < clicks.length; i++) {
//measure distance between static and click array point
var dist = getDistance(10, 10, clicks[i][0], clicks[i][1])
//add distance to a new array
distances.push(dist)

var sdist = getDistance(10, 10, clicks[i][0], clicks[i][1])
sortDistances.push(sdist)
}
//sort distance to find the shortest
var sorted = sortDistances.sort(function(a, b){return a - b})
//console.log(sorted[0])

for(let i = 0; i < clicks.length; i++) {
//console.log(distances[i])
//console.log(sorted[0])
if (distances[i] == sorted[0]){
c.enter().append("circle") //circle
.data(clicks)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", clicks[i][0])
.attr("cy", clicks[i][1])
.attr('r', radius)
.attr('fill', 'pink')
.style('fill-opacity','1')
}
}
})

var t = svg.selectAll("text")
.data(Mtime)
.enter()
.append('text')
.attr('x', 116)
.attr('y', function(d,i) {return 115 + 20*i})
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.attr('fill', 'black')
.text(function(d) {return d})


c.enter().append('circle')
.data(Mtime)
.enter()
.append('circle')
.attr('cx', 110)
.attr('cy', function(d,i) {return 112 + 20*i}) //function is for looping data
.attr('r',3)
.attr('fill','black')
.on('click', MtimeClick)

function MtimeClick(event,d){
if(d == 'Current: 2022'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path1") //d3 geopath
.data(boroughs.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', 'white')
// .style('fill-opacity', BoroughPop)
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path1") //d3 geopath
.data(pop5.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', PopColor2020)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path10") //d3 geopath
.data(streetlines.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.25')
.style("stroke-width", '.15')
.style("stroke", "gray")

function PopColor2020(d,i) {
var color = 'white'

if(d.properties.NYC2020POP_density >= 70000 && d.properties.NYC2020POP_density <= 109931){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC2020POP_density >= 50000 && d.properties.NYC2020POP_density <= 70000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC2020POP_density >= 35000 && d.properties.NYC2020POP_density <= 50000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC2020POP_density >= 20000 && d.properties.NYC2020POP_density <= 35000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC2020POP_density >= 3000 && d.properties.NYC2020POP_density <= 20000){color = 'rgb(237, 224, 212)'}
return color
}
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('Current NYC Subway Paths')

g.selectAll("path9") //d3 geopath
.data(current_lines.features) //CURRENT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path9) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.4')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//CURRENT
.data(current_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class','spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'IRT: 1904 - 1906'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path1") //d3 geopath
.data(boroughs.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', 'white')
// .style('fill-opacity', BoroughPop)
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path10") //d3 geopath
.data(streetlines.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", 'none')
.style('stroke-opacity','.25')
.style("stroke-width", '.15')
.style("stroke", "gray")
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('1906 - IRT Subway Paths')

svg.append('text')
.attr('class','history')
.attr('x', '500')
.attr('y','745')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
.text('IRT was a privately operated company for one of the original subway lines in New York City which opened in 1904. The first IRT ran through City Hall and 145th street at Broadway')

g.selectAll("path2") //d3 geopath
.data(irt1906_lines.features) //IRT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path2) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('fill-opacity','.5')
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//IRT
.data(irt1906_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r', radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'IRT: 1939'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop3.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1939)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1939(d,i) {
var color = 'white'
if(d.properties.NYC1940POP_BZO001 >= 15000 && d.properties.NYC1940POP_BZO001 <= 20741){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC1940POP_BZO001 >= 10000 && d.properties.NYC1940POP_BZO001 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC1940POP_BZO001 >= 5000 && d.properties.NYC1940POP_BZO001 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC1940POP_BZO001 >= 2500 && d.properties.NYC1940POP_BZO001 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC1940POP_BZO001 >= 1 && d.properties.NYC1940POP_BZO001 <= 2500){color = 'rgb(237, 224, 212)'}
return color
}
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('1939 - IRT Subway Paths')

svg.append('text')
.attr('class','history')
.attr('x', '500')
.attr('y','745')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
.text('This 1939 IRT map shows the extensive network of IRT subway and elevated lines: East Side and West Side subways, 2nd, 3rd, 6th, and 9th Avenue Elevated lines, and the Flushing Line.')
g.selectAll("path2") //d3 geopath
.data(irt1906_lines.features) //IRT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path2) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('fill-opacity','.5')
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path3") //d3 geopath
.data(irt1939_lines.features) //IRT2
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//IRT
.data(irt1906_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//IRT2
.data(irt1939_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'BRT: 1896 - 1912'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop2.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1910)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1910(d,i) {
var color = 'white'
if(d.properties.nhgis0001_ds40_1910_tract_A64001 >= 15000 && d.properties.nhgis0001_ds40_1910_tract_A64001 <= 44544){color = 'rgb(127, 85, 57)'}
if(d.properties.nhgis0001_ds40_1910_tract_A64001 >= 10000 && d.properties.nhgis0001_ds40_1910_tract_A64001 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.nhgis0001_ds40_1910_tract_A64001 >= 5000 && d.properties.nhgis0001_ds40_1910_tract_A64001 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.nhgis0001_ds40_1910_tract_A64001 >= 3000 && d.properties.nhgis0001_ds40_1910_tract_A64001 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.nhgis0001_ds40_1910_tract_A64001 >= 1 && d.properties.nhgis0001_ds40_1910_tract_A64001 <= 3000){color = 'rgb(237, 224, 212)'}
return color
}
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('1912 - BRT Subway Paths')

svg.append('text')
.attr('class','history')
.attr('x', '500')
.attr('y','745')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
.text('The BRT Compnay began in 1899 and lasted until 1932 when it reorganzed into 1923. This 1912 map takes a look at its train lines that ran in Brooklyn and shows what the train lines looked like before it was became the BMT.')
g.selectAll("path4") //d3 geopath
.data(brt_lines.features) //BRT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path4) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//BRT
.data(brt_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

}

if(d == 'BMT: 1924'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop1.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1920)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1920(d,i) {
var color = 'white'
if(d.properties.nhgis0004_ds48_1920_tract_BBQ002 >= 15000 && d.properties.nhgis0004_ds48_1920_tract_BBQ002 <= 33773){color = 'rgb(127, 85, 57)'}
if(d.properties.nhgis0004_ds48_1920_tract_BBQ002 >= 10000 && d.properties.nhgis0004_ds48_1920_tract_BBQ002 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.nhgis0004_ds48_1920_tract_BBQ002 >= 5000 && d.properties.nhgis0004_ds48_1920_tract_BBQ002 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.nhgis0004_ds48_1920_tract_BBQ002 >= 1000 && d.properties.nhgis0004_ds48_1920_tract_BBQ002 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.nhgis0004_ds48_1920_tract_BBQ002 >= 1 && d.properties.nhgis0004_ds48_1920_tract_BBQ002 <= 1000){color = 'rgb(237, 224, 212)'}
return color
}
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('1924 - BMT Subway Paths')

svg.append('text')
.attr('class','history')
.attr('x', '500')
.attr('y','705')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
.text('BRT Company, now BMT Coorporation signed a Dual Contract in 1913, which bound the BMT to build and operate lines for 49 years. Contract 4 in the Dual Contract indicated that the city would build, rehabilitate and expand certain existing lines and lease them out to private companies for operation. These contracts were made because the city experienced crowding in many forms of transportation and the increasing density in Manhattan encouraged a connection from Brooklyn to Manhattan.')

g.selectAll("path5") //d3 geopath
.data(bmt1924_lines.features) //BMT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path5) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.4')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//BRT
.data(brt_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//BMT
.data(bmt1924_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',1.5)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'BMT: 1940s'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop3.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1940s)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1940s(d,i) {
var color = 'white'
if(d.properties.NYC1940POP_BZO001 >= 15000 && d.properties.NYC1940POP_BZO001 <= 20741){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC1940POP_BZO001 >= 10000 && d.properties.NYC1940POP_BZO001 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC1940POP_BZO001 >= 5000 && d.properties.NYC1940POP_BZO001 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC1940POP_BZO001 >= 2500 && d.properties.NYC1940POP_BZO001 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC1940POP_BZO001 >= 1 && d.properties.NYC1940POP_BZO001 <= 2500){color = 'rgb(237, 224, 212)'}
return color
}
svg.append('text')
.attr('class','history')
.attr('x', '110')
.attr('y','80')
.attr('font-family','Helvetica')
.attr('font-size', '.85em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('1940s - BMT Subway Paths')

svg.append('text')
.attr('class','history')
.attr('x', '500')
.attr('y','745')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
.text('This map shows the BMT lines in the 1940s before it is acquired and combined together with other private companies.')
g.selectAll("path6") //d3 geopath
.data(bmt1940_lines.features) //BMT2
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path6) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.4')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//BMT2
.data(bmt1940_stops2.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'IND: 1939'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop3.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1940)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1940(d,i) {
var color = 'white'
if(d.properties.NYC1940POP_BZO001 >= 15000 && d.properties.NYC1940POP_BZO001 <= 20741){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC1940POP_BZO001 >= 10000 && d.properties.NYC1940POP_BZO001 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC1940POP_BZO001 >= 5000 && d.properties.NYC1940POP_BZO001 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC1940POP_BZO001 >= 2500 && d.properties.NYC1940POP_BZO001 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC1940POP_BZO001 >= 1 && d.properties.NYC1940POP_BZO001 <= 2500){color = 'rgb(237, 224, 212)'}
return color
}

g.selectAll("path7") //d3 geopath
.data(ind_lines.features) //IND
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path7) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//IND
.data(ind_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}

if(d == 'IRT + BMT + IND: 1948'){
d3.selectAll('path.outlines').remove()
d3.selectAll('text.history').remove()
d3.selectAll('circle.spots').remove()

g.selectAll("path10") //d3 geopath
.data(pop4.features) //Current
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path10) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", PopColor1950)
.style('stroke-opacity','.25')
.style("stroke-width", '.5')
.style("stroke", "gray")

function PopColor1950(d,i) {
var color = 'white'
if(d.properties.NYC1950POP_BZ8001 >= 15000 && d.properties.NYC1950POP_BZ8001 <= 38045){color = 'rgb(127, 85, 57)'}
if(d.properties.NYC1950POP_BZ8001 >= 10000 && d.properties.NYC1950POP_BZ8001 <= 15000){color = 'rgb(176, 137, 104)'}
if(d.properties.NYC1950POP_BZ8001 >= 5000 && d.properties.NYC1950POP_BZ8001 <= 10000){color = 'rgb(221, 184, 146)'}
if(d.properties.NYC1950POP_BZ8001 >= 2500 && d.properties.NYC1950POP_BZ8001 <= 5000){color = 'rgb(230, 204, 178)'}
if(d.properties.NYC1950POP_BZ8001 >= 1 && d.properties.NYC1950POP_BZ8001 <= 2500){color = 'rgb(237, 224, 212)'}
return color
}
g.selectAll("path2") //d3 geopath
.data(irt1906_lines.features) //IRT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path2) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('fill-opacity','.5')
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path3") //d3 geopath
.data(irt1939_lines.features) //IRT2
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")
/*
g.selectAll("path4") //d3 geopath
.data(brt_lines.features) //BRT
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path4) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)") */
g.selectAll("path7") //d3 geopath
.data(ind_lines.features) //IND
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path7) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path6") //d3 geopath
.data(bmt1940_lines.features) //BMT2
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path6) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','.2')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

c.enter().append('circle')//IRT
.data(irt1906_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//IRT2
.data(irt1939_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//BRT
.data(brt_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//BMT
.data(bmt1924_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//BMT2
.data(bmt1940_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')

c.enter().append('circle')//IND
.data(ind_stops.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class', 'spots')
.attr("cx", function(d) {return path8.centroid(d)[0]})
.attr("cy", function(d) {return path8.centroid(d)[1]})
.attr('r',radius)
.attr('fill', 'black')//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','gray')
.style('stroke-width','1')
}
var wrap = svg.selectAll("text.history")
.each(function(d, i) { wrap_text(d3.select(this), 250) });//value controls how wide text gets
}





return svg.node();
}
Insert cell
pop2 = FileAttachment("1910 Pop.geojson").json()
Insert cell
ind_stops = FileAttachment("IND_Stops.geojson").json()
Insert cell
streetlines = FileAttachment("Streetlines.geojson").json()
Insert cell
bmt1940_stops2 = FileAttachment("BMT 1940_Stops2.geojson").json()
Insert cell
bmt1924_stops = FileAttachment("BMT 1924_Stops.geojson").json()
Insert cell
bmt1940_stops = FileAttachment("BMT 1940_Stops.geojson").json()
Insert cell
brt_stops = FileAttachment("BRT_Stops.geojson").json()
Insert cell
brt_lines = FileAttachment("BRT_Lines@1.geojson").json()
Insert cell
bmt1924_lines = FileAttachment("BMT 1924_Lines.geojson").json()
Insert cell
bmt1940_lines = FileAttachment("BMT 1940_Lines.geojson").json()
Insert cell
irt1939_lines = FileAttachment("IRT 1939_Lines@1.geojson").json()
Insert cell
irt1906_stops = FileAttachment("IRT 1906_Stops@1.geojson").json()
Insert cell
irt1906_lines = FileAttachment("IRT 1906_Lines@1.geojson").json()
Insert cell
ind_lines = FileAttachment("IND_Lines.geojson").json()
Insert cell
borough_outline = FileAttachment("Borough_Outline.geojson").json()
Insert cell
boroughs = FileAttachment("Boroughs.geojson").json()
Insert cell
current_lines = FileAttachment("Current_Lines.geojson").json()
Insert cell
current_stops = FileAttachment("Current_Stops.geojson").json()
Insert cell
Insert cell
spots = d3.csv(spotsLink, d3.autoType)
Insert cell
Mtime = ['IRT: 1904 - 1906', 'BRT: 1896 - 1912', 'BMT: 1924', 'IRT: 1939', 'BMT: 1940s', 'IND: 1939', 'IRT + BMT + IND: 1948', 'Current: 2022' ]
Insert cell
population = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQrzPJGZlOpOcpVWVSwpUuDi3z5xLfS3joxMklzs-cx4QYv-nOSg45g7CtSCd2KS6xoodpxSfPExGfw/pub?output=csv'
Insert cell
pop = d3.csv(population, d3.autoType)
Insert cell
irt1939_stops = FileAttachment("IRT 1939_Stops@2.geojson").json()
Insert cell
import { wrap_text, wrap_text_nchar } from "@ben-tanen/svg-text-and-tspan-word-wrapping"
Insert cell
pop1 = FileAttachment("1920 Pop.geojson").json()
Insert cell
pop3 = FileAttachment("1940 POP MAP@3.geojson").json()
Insert cell
pop4 = FileAttachment("1950 POP MAP@3.geojson").json()
Insert cell
pop5 = FileAttachment("2020 MAP@3.geojson").json()
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