Published
Edited
May 5, 2022
3 forks
2 stars
Insert cell
# Los Angeles Inglewood
Insert cell
zips = FileAttachment("LA Boundary.geojson").json()
Insert cell
stations = FileAttachment("Metro Stations.geojson").json()
Insert cell
locations = FileAttachment("Key Locations 1.geojson").json()
Insert cell
CDL = FileAttachment("community_dash_lines.geojson").json()
Insert cell
CD = FileAttachment("community_dash.geojson").json()
Insert cell
CEL = FileAttachment("commuter_express_lines.geojson").json()
Insert cell
CE = FileAttachment("commuter_express.geojson").json()
Insert cell
DDL = FileAttachment("downtown_dash_lines.geojson").json()
Insert cell
DD = FileAttachment("downtown_dash.geojson").json()
Insert cell
BL1 = FileAttachment("bikelanes_1.geojson").json()
Insert cell
BL2 = FileAttachment("bikelanes_2.geojson").json()
Insert cell
BL3 = FileAttachment("bikelanes_3.geojson").json()
Insert cell
inglewood = FileAttachment("Inglewood 2.geojson").json()
Insert cell
cali = FileAttachment("California.geojson").json()
Insert cell
streets = FileAttachment("Streets.geojson").json()
Insert cell
rivers = FileAttachment("Rivers.geojson").json()
Insert cell
LAHighways = FileAttachment("InglewoodHighways.dxf.geojson").json()
Insert cell
LAMainRoads = FileAttachment("InglewoodMainRoads.dxf.geojson").json()
Insert cell
Pacific =
FileAttachment("LAPacificOcean.geojson").json()
Insert cell
FootPrints = FileAttachment("Inglewood_Buildings.geojson").json()
Insert cell
Buildings = FileAttachment("Simp_Buildings.geojson").json()
Insert cell
olympics = FileAttachment("OlympicLocationsAttr..geojson").json()
Insert cell
parks3 = FileAttachment("parks i.geojson").json()
Insert cell
roads = FileAttachment("roads_Inglewood.geojson").json()
Insert cell
BusStops = FileAttachment("Bus Stops Simplified.geojson").json()
Insert cell
NewStations = FileAttachment("AddStations.geojson").json()
Insert cell
NewLine = FileAttachment("NewLineLAX@1.geojson").json()
Insert cell
NewMetro = FileAttachment("2028MetroAdditions.geojson").json()
Insert cell
MetroC = FileAttachment("Metro_C.geojson").json()
Insert cell
DTIW = FileAttachment("Downtown Inglewood West.geojson").json()
Insert cell
EHardy = FileAttachment("E Hardy.geojson").json()
Insert cell
Arbor = FileAttachment("Arbor Park Northwest.geojson").json()
Insert cell
PeopleMover = FileAttachment("PeopleMoverLine.geojson").json()
Insert cell
PMStops = FileAttachment("3PMStops.geojson").json()
Insert cell
d3 = require("d3@7", "d3-geo-scale-bar@1.2", "d3-tile@1")
Insert cell
projection = d3.geoMercator()
.fitSize([width - 50, innerHeight - 5], inglewood);
Insert cell
d32 = require("d3@7", "d3-geo-scale-bar@1.2", "d3-tile@1")
Insert cell
scaleBar = d32.geoScaleBar()
.projection(projection)
.size([-50, -5])
.left(.02)
.top(0.95)
.tickFormat(d3.format(","));
Insert cell
Cemetary = FileAttachment("Cemetary.geojson").json()
Insert cell
chart = {
const width = 600,
height = 725;
const svg = d3.create("svg")
.attr("viewBox", [-20, 10, width, height]);

// Use Mercator projection
var projection = d3
.geoMercator()
.fitSize([width - 50, height - 5], inglewood);

var path = d3.geoPath().projection(projection);
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 c = svg.selectAll("circle"); //d3 geopath
var g = svg.append("g").attr("id", "paths");
g.selectAll("path") //d3 geopath
//svg
//.selectAll('path')
.data(zips.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "rgb(225,225,225)")
.style('fill-opacity','.75')
.style("stroke-width", "0")
.style("stroke", "#ccc")

// Pacific Ocean
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(Pacific.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "rgb(135,206,250)")
.style('fill-opacity','0.9')
.style("stroke-width", "1.5")
.style("stroke", "rgb(135,206,250)")
.style('stroke-opacity','0.9')

// Parks
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(parks3.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "green")
.style('fill-opacity','0.15')
.style("stroke-width", "0.2")
.style("stroke", "black")

// Cemetary
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(Cemetary.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "green")
.style('fill-opacity','0.15')
.style("stroke-width", "0.2")
.style("stroke", "black")

// Highways
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(LAHighways.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", "2")
.style("stroke", "rgb(225,165,0)")
.style('stroke-opacity','0.5')

// Main Roads
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(LAMainRoads.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", "1")
.style("stroke", "white")
.style('stroke-opacity','0.9')

// Streets
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(streets.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", "0.5")
.style("stroke", "white")
.style('stroke-opacity','0.9')

// Rivers
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(rivers.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
// .style("fill", "blue")
.style('fill-opacity','0')
.style("stroke-width", "3")
.style("stroke", "rgb(135,206,250)")
.style('stroke-opacity','0.9')

// FootPrints
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(Buildings.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "rgb(200,200,200)")
.style('fill-opacity','0.75')
.style("stroke-width", "0.15")
.style("stroke", "black")

// Station text
var t = svg.selectAll("text")//creating a variable t and adding all text objects to it
.data(stations.features)
.enter() //there are more data than elements, this selects them
.append("text") //appends path to data
.attr("x", function(d) {return path1.centroid(d)[0]})
.attr("y", function(d) {return path1.centroid(d)[1]-5})
.attr('font-family','helvetica')
.attr('font-size','.45em')
.attr('font-weight','550')
.style("fill", "rgb(50,50,50)")
.attr('text-anchor','left')
.text(function(d) {return d.properties.Name})

// 2028 Metro
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(NewLine.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", ".75")
.style("stroke", "rgb(255,20,147)")
.style('stroke-opacity','0.75')
.attr('stroke-dasharray', 3.5)

// Metro C
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(MetroC.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", ".5")
.style("stroke", "rgb(50,205,50)")
.style('stroke-opacity','0.75')

// Rail Stations
//g.selectAll("circle") //d3 geopath
var c = svg.selectAll('circle')
c.enter().append('circle')
//svg
//.selectAll('path')
.data(stations.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy", function(d) {return path.centroid(d)[1]})
.attr('r',2.5)
.attr("fill", "rgb(128,128,128)")
.style('fill-opacity','1')

//Olympic key points
//g.selectAll("circle2") //d3 geopath
c.enter().append('circle')
//svg
//.selectAll('path')
.data(olympics.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy", function(d) {return path.centroid(d)[1]})
.attr('r',3)
.attr("fill", "rgb(148,0,211)")
.style('fill-opacity','1')
.style("stroke-width", ".5")
.style("stroke", "rgb(0,0,0)")
.on('mouseover', addOlympic)
.on('mouseout', removeOlympic)

// add Olympic tool tip
var tooltip = svg.append("g");
function addOlympic(event, d) {
var centroid = path.centroid(d);
tooltip.call(
callout,
`2028 Summer Olympics
Location: ${d.properties.name}
Events: ${d.properties.description} `
);
tooltip.attr("transform", "translate(" + centroid + ")");
}

// // remove Olympic tool tip
function removeOlympic(event, d)
{tooltip.call(callout,null)
}

// Arbor Park Northwest
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(Arbor.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','.5')
.style('fill','white')
.style("stroke-width", ".5")
.style("stroke", "rgb(0,0,139)")
.style('stroke-opacity','0.75')

svg
.append("text")
.attr('class','title')
.attr('x','45')
.attr('y','300')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','500')
.style("fill", "rgb(0,0,0)")
.text('Arbor Park Northwest')

// Downtown Inglewood West
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(DTIW.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','.5')
.style('fill','white')
.style("stroke-width", ".5")
.style("stroke", "rgb(0,0,255)")
.style('stroke-opacity','0.75')

svg
.append("text")
.attr('class','title')
.attr('x','155')
.attr('y','290')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','500')
.style("fill", "rgb(0,0,0)")
.text('Downtown')
svg
.append("text")
.attr('class','title')
.attr('x','155')
.attr('y','295')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','500')
.style("fill", "rgb(0,0,0)")
.text('Inglewood West')

// E Hardy St/S Myrtle Ave
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(EHardy.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','.5')
.style('fill','white')
.style("stroke-width", ".5")
.style("stroke", "rgb(65,105,225)")
.style('stroke-opacity','0.75')

svg
.append("text")
.attr('class','title')
.attr('x','245')
.attr('y','400')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','500')
.style("fill", "rgb(0,0,0)")
.text('E Hardy St/S Myrtle Ave')

// People Mover
g.selectAll("path3") //d3 geopath
//svg
//.selectAll('path')
.data(PeopleMover.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path) //The d attribute defines a path to be drawn, only applies to appended elements
//.style("fill", "green")
.style('fill-opacity','0')
.style("stroke-width", "1")
.style("stroke", "rgb(100,149,237)")
.style('stroke-opacity','1')
.attr('stroke-dasharray', '2,1')

svg
.append("text")
.attr('class','title')
.attr('x','325')
.attr('y','350')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','550')
.style("fill", "rgb(0,0,0)")
.text('Proposed')

svg
.append("text")
.attr('class','title')
.attr('x','325')
.attr('y','356')
.attr('font-family','helvetica')
.attr('font-size','.35em')
.attr('font-weight','550')
.style("fill", "rgb(0,0,0)")
.text('People Mover')

svg
.append("line")
.attr('x1','316')
.attr('y1','348')
.attr('x2','323')
.attr('y2','348')
.attr('stroke-width','.65')
.attr('stroke','rgb(0,0,0)')

//Bus Stops
//g.selectAll("circle2") //d3 geopath
c.enter().append('circle')
//svg
//.selectAll('path')
.data(BusStops.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy", function(d) {return path.centroid(d)[1]})
.attr('r',1.5)
.attr("fill", "rgb(255,255,255)")
.style('fill-opacity','1')
.style("stroke-width", ".25")
.style("stroke", "rgb(0,0,0)")
.on('mouseover', addBus)
.on('mouseout', removeBus)

// add Bus tool tip
var tooltip = svg.append("g");
function addBus(event, d) {
var centroid = path.centroid(d);
tooltip.call(
callout,
`Bus Stop: ${d.properties.STOPNAME} `
);
tooltip.attr("transform", "translate(" + centroid + ")");
}

// // remove Bus tool tip
function removeBus(event, d)
{tooltip.call(callout,null)
}

//People Mover Stops
//g.selectAll("circle") //d3 geopath
c.enter().append('circle')
//svg
//.selectAll('path')
.data(PMStops.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy", function(d) {return path.centroid(d)[1]})
.attr('r',2)
.attr("fill", "rgb(100,149,237)")
.style('fill-opacity','1')
.style("stroke-width", ".5")
.style("stroke", "rgb(0,0,0)")
.on('mouseover', addStops)
.on('mouseout', removeStops)

// add Stops tool tip
var tooltip = svg.append("g");
function addStops(event, d) {
var centroid = path.centroid(d);
tooltip.call(
callout,
`People Mover Stop: ${d.properties.name} `
);
tooltip.attr("transform", "translate(" + centroid + ")");
}

// // remove Stops tool tip
function removeStops(event, d)
{tooltip.call(callout,null)
}

// New Rail Stations
//g.selectAll("circle") //d3 geopath
c.enter().append('circle')
//svg
//.selectAll('path')
.data(NewStations.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy", function(d) {return path.centroid(d)[1]})
.attr('r',2.5)
.attr("fill", "rgb(255,20,147)")
.style('fill-opacity','1')
.style("stroke-width", ".5")
.style("stroke", "rgb(0,0,0)")
.on('mouseover', addNew)
.on('mouseout', removeNew)

// add New tool tip
var tooltip = svg.append("g");
function addNew(event, d) {
var centroid = path.centroid(d);
tooltip.call(
callout,
`Metro Station: ${d.properties.Layer} `
);
tooltip.attr("transform", "translate(" + centroid + ")");
}

// // remove New tool tip
function removeNew(event, d)
{tooltip.call(callout,null)
}

//Olympic text
var t = svg.selectAll("text")
.data(olympics.features)
.enter() //there are more data than elements, this selects them
.append("text") //appends path to data
.attr("x", function(d) {return path1.centroid(d)[0]})
.attr("y", function(d) {return path1.centroid(d)[1]-5})
.attr('font-family','helvetica')
.attr('font-size','.4em')
.attr('font-weight','450')
.style("fill", "rgb(0,0,0)")
.attr('text-anchor','middle')
.text(function(d) {return d.properties.name})

//add labels to site line
svg
.append("text")
.attr('class','title')
.attr('x','45')
.attr('y','550')
.attr('font-family','helvetica')
.attr('font-size','.7em')
.attr('font-weight','400')
.style("fill", "rgb(0,0,0)")
.text('2028 Addition')

svg
.append("text")
.attr('class','title')
.attr('x','45')
.attr('y','560')
.attr('font-family','helvetica')
.attr('font-size','.5em')
.attr('font-weight','400')
.style("fill", "rgb(0,0,0)")
.text('Crenshaw/LAX')

svg
.append("line")
.attr('x1','15')
.attr('y1','545')
.attr('x2','40')
.attr('y2','545')
.attr('stroke-width','.75')
.attr('stroke','rgb(0,0,0)')
scaleBar
.projection(projection)
.size([width, height]);

svg.append("g")
.call(scaleBar);
return svg.node();
}
Insert cell
callout = (g, value) => {
if (!value) return g.style("display", "none");

g
.style("display", null)
.style("pointer-events", "none")
.style("font", "8px sans-serif");

const path = g.selectAll("path")
.data([null])
.join("path")
.attr("fill", "white")
.attr("stroke", "black");

const text = g.selectAll("text")
.data([null])
.join("text")
.call(text => text
.selectAll("tspan")
.data((value + "").split(/\n/))
.join("tspan")
.attr("x", 0)
.attr("y", (d, i) => `${i * 1.1}em`)
.style("font-weight", (_, i) => i ? null : "bold")
.text(d => d));

const {x, y, width: w, height: h} = text.node().getBBox();

text.attr("transform", `translate(${-w / 2},${15 - y})`);
path.attr("d", `M${-w / 2 - 10},5H-5l5,-5l5,5H${w / 2 + 10}v${h + 20}h-${w + 20}z`);
}
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