Public
Edited
Oct 30, 2022
25 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
us = FileAttachment("output-topo20.json").json()
Insert cell
states = topojson.feature(us, us.objects.statestl20).features
Insert cell
counties_water = FileAttachment("counties_water.json").json()
Insert cell
counties = topojson.feature(counties_water, counties_water.objects.counties).features
Insert cell
Insert cell
Insert cell
Insert cell
//define aspect ratio for your shape
aspectRatioUSA = 0.6
Insert cell
//Observable provides a built-in width variable that you can use to set your canvas width
height = width * aspectRatioUSA
Insert cell
projection = d3
.geoAlbers() //use Albers as a base projection type
.fitSize([width, height], us) //fit the size of the map to a predefined width and height of the window, and to our us file
.scale(1280) //zoom of map
.translate([480, 300]) //shift map in window
Insert cell
Insert cell
//the path variable will be used to tell D3 how to manipulate your input data
path = d3.geoPath(projection)
Insert cell
Insert cell
map = {
//A basic D3 map requires creating a new "svg" element and defining a window in which to draw the map
const svg = d3.create("svg")
.attr("width", width + 100)
.attr("height", height);

// this block will display the states
svg
.append("g") //add a G element, which is basiscally a group that holds elements
.selectAll("path") //tells d3 to select path elements to modify
.data(states) //defines the data we'll use to show
.enter() //joins the data above to DOM elements
.append("path") //for each data element, add a path
.attr("d", path) //defines coordinates
.attr("fill","lightgray")
.attr("fill-opacity",0.5)
.attr("stroke", "gray")
.attr("stroke-opacity",0.3)
.attr("stroke-width",0.75)

//if we want to add counties, we can duplicate our code above and *only* change the data and styling
svg
.append("g")
.selectAll("path")
.data(counties)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "none")
.attr("fill-opacity",0.3)
.attr("stroke", "gray")
.attr("stroke-opacity",0.2)
.attr("stroke-width",0.4);

return svg.node();
}
Insert cell
Insert cell
counties.map(county => {
county.properties.water_sq_mile = county.properties.AWATER/2590000 //convert to square miles
county.properties.land_sq_mile = county.properties.ALAND/2590000 //convert to square miles
return county
})
Insert cell
county_select = counties.filter(d => d.properties.STATEFP == 27)
Insert cell
county_select_geo = {
const obj = {}
obj['type'] = "FeatureCollection";
obj['features'] = county_select;
return obj
}
Insert cell
Insert cell
projection_mn = d3.geoConicConformal()
.parallels([45 + 37 / 60, 47 + 3 / 60])
.rotate([94 + 15 / 60, 0])
.fitSize([widthMN, heightMN], county_select_geo);
//.fitSize([width, height-50], county_select_geo);
Insert cell
path_state = d3.geoPath(projection_mn)
Insert cell
map_state = {
const svg = d3.create("svg")
.attr("width", widthMN)
.attr("height", heightMN);
svg
.append("g")
.selectAll("path")
.data(county_select)
.enter()
.append("path")
.attr("fill", "lightgray")
.attr("fill-opacity",0.3)
.attr("stroke", "gray")
.attr("stroke-opacity",0.2)
.attr("stroke-width",0.4)
.attr("d", path_state);


return svg.node();
}
Insert cell
Insert cell
lakes = FileAttachment("dnr_hydro_features_lakes_acres_100_plus_unprojected.json").json()
Insert cell
lakesGeo = topojson.feature(lakes, lakes.objects["dnr_hydro_features_all"]).features
Insert cell
aspectRatioMN = 1.15
Insert cell
widthMN = width > 500 ? 500 : width
Insert cell
heightMN = widthMN * aspectRatioMN
Insert cell
Insert cell
map_lakes_100 = {
const svg = d3.create("svg").attr("width", widthMN)
.attr("height", heightMN);

svg
.append("g")
.selectAll("path")
.data(lakesGeo)
.enter()
.append("path")
//color
.attr("fill", "blue")
.attr("fill-opacity",0.7)
.attr("stroke", "none")
.attr("d", path_state);

return svg.node();
}
Insert cell
Insert cell
color = d3.scaleLinear()
.domain([1,100])
.range(['#f1eef6','#d0d1e6','#a6bddb','#74a9cf','#2b8cbe','#045a8d'])
Insert cell
map_lakes = {
const svg = d3.create("svg")
.attr("width", widthMN)
.attr("height", heightMN);

svg
.append("g")
.selectAll("path")
.data(county_select) //source: social explorer county dataset
.enter()
.append("path")
//color
.attr("fill",d=>color(d.properties.water_sq_mile))
.attr("fill-opacity",1)
.attr("stroke", "gray")
.attr("stroke-opacity",1)
.attr("stroke-width",0.2)
.attr("d", path_state);

return svg.node();
}
Insert cell
Insert cell
propSymbols = d3.scaleLinear().domain([5,200]).range([3,10])
Insert cell
map_lakes_circles = {
const svg = d3.create("svg")
.attr("width", widthMN)
.attr("height", heightMN);

svg
.append("g")
.selectAll("path")
.data(county_select)
.enter()
.append("path")
.attr("fill","white")
.attr("fill-opacity",1)
.attr("stroke", "gray")
.attr("stroke-opacity",1)
.attr("stroke-width",0.2)
.attr("d", path_state);

svg
.append("g")
.selectAll("path")
.data(county_select)
.enter()
.append("circle") //APPEND CIRCLE†
.attr("cx",d=> path_state.centroid(d)[0])
.attr("cy",d=> path_state.centroid(d)[1])
.attr("r",d=> propSymbols(d.properties.water_sq_mile))
.attr("fill","black")
.attr("fill-opacity",0.25)
.attr("stroke", "gray")
.attr("stroke-opacity",1)
.attr("stroke-width",0.2)
.attr("d", path_state);

return svg.node();
}
Insert cell
Insert cell
dotRadius = 3;
Insert cell
outputPointData = {
let pointData = [];
county_select_geo.features.forEach(d => {
let sq_miles = d.properties.water_sq_mile
for (let i = 0, len = sq_miles/50; i < len; i++) {
let obj = {}
obj['TOTAL_SQ_MILES'] = sq_miles;
obj['COUNTY'] = d.properties.NAME
obj['CENTROID'] = path_state.centroid(d)
pointData.push(obj)
}
})
return pointData;
}
Insert cell
Insert cell
force = applySimulation(outputPointData)
Insert cell
map_lakes_dots = {
const svg = d3.create("svg").attr("viewBox", [0, 0, 975, 610]);

svg
.append("g")
.selectAll("path")
.data(county_select)
.enter()
.append("path")
//color
.attr("fill","white")
.attr("fill-opacity",1)
.attr("stroke", "gray")
.attr("stroke-opacity",1)
.attr("stroke-width",0.2)
.attr("d", path_state);

svg
.append("g")
.attr('class','data')
.selectAll('circle')
.data(force)
.enter()
.append("circle")
.attr("class", "circle-symbol")
.attr("r", dotRadius)
.attr("cx", function(d) { // define the x position
return d.x;
})
.attr("cy", function(d) { // define the y positio
return d.y;
})
.attr("fill","black")
.attr("fill-opacity",1)

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { fastestGrowingRace } from "@adrianblanco/americas-demographics-are-changing"
Insert cell
import { campaignEventsMap } from "@adrianblanco/2020-presidential-campaign-events"
Insert cell
import { globe } from "@adrianblanco/designing-patterns-for-vintage-maps"
Insert cell
immigration_map = FileAttachment("Screen Shot 2022-10-17 at 9.19.19 PM.png")
Insert cell
afghanistan_map = FileAttachment("Screen Shot 2022-10-17 at 9.25.01 PM.png")
Insert cell
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