Public
Edited
May 1, 2023
Insert cell
md`# Amenity Availability by Iowa City Blocks`
Insert cell
//Add d3 library
d3 = require("d3@5")
Insert cell
//import d3 legend library, normal d3 doesn't include this
import {legend} from "@d3/color-legend"
Insert cell
//Add simple-statistics library for statistical analysis of data
simple = require("simple-statistics@7.0.7/dist/simple-statistics.min.js")
Insert cell
format = d => `${d}%`
Insert cell
md`# Data`
Insert cell
//Add topojson-client library
topojson = require("topojson-client@3")
Insert cell
//Add json file
FileAttachment("QCBShpWGSTopo.json").json()
Insert cell
//Assign variable to json file
new_counties = FileAttachment("QCBShpWGSTopo.json").json()
Insert cell
//Extract map features from json file for making map
new_counties_features = topojson.feature(new_counties, new_counties.objects.QCBShpWGS)
Insert cell
//Add csv file
FileAttachment("BlockMeanDivIndex.csv").csv()
Insert cell
//Extract columns of interest from csv data. Manipulate them as you'd like
csv_data = d3.csvParse(await FileAttachment("BlockMeanDivIndex.csv").text(),({GEOID20, MEAN}) => [GEOID20, (MEAN)])
Insert cell
//Create an array from the columns from extracted/manipulated csv columes
VariableArray = Array.from(csv_data.values(), d => d[1])
Insert cell
//Map all of the columns to line up with each other.
new_data = Object.assign(new Map(csv_data), {title: ["Ammenity Diversity"]})
Insert cell
md`# Map`
Insert cell
//Create the color gradient you will use in the map's legend
Purp = [d3.color("#edf8fb"), d3.color("#b3cde3"),d3.color("#8c96c6"), d3.color("#8856a7"), d3.color("#810f7c")]
Insert cell
//Create a classification style for your data. Natural breaks in this case
naturalbreaks = simple.ckmeans(VariableArray, Purp.length).map(v => v.pop())
Insert cell
//more information on sequential scales: https://observablehq.com/@d3/sequential-scales
// color = d3.scaleSequentialQuantile([...data.values()], d3.interpolateBlues)

// color = d3.scaleQuantile()
// .domain(med_age)
// .range()

//This combines the natural breaks calculated and the colors you want to be associated with those groups.
color = d3.scaleThreshold()
.domain(naturalbreaks)
.range(Purp)
Insert cell
width = 975
Insert cell
height = 640
Insert cell
margin = 100
Insert cell
//Rotate the map sets the longitude of origin. Play around with this until it looks nice
projection = d3.geoTransverseMercator().rotate([90,0]).fitExtent([[80, 80], [width, height]], new_counties_features);
//d3 reference for projections: https://github.com/d3/d3-geo/blob/master/README.md

//use the following url for specific projection settings: https://github.com/veltman/d3-stateplane
//Use this code to set up the map projection (if different than geographic projection)

//projection = d3.geoAlbers().fitExtent([[margin, margin], [width - margin, height - margin]], counties)

//projection = d3.geoMercator().fitExtent([[margin, margin], [width - margin, height - margin]], counties)
Insert cell
//Using a path generator to project geometry onto the map
path = d3.geoPath().projection(projection);
Insert cell
choropleth = {
//Creates constant to create an image in an x,y coordinate plane using an SVG graphic.
//SVG is a scalable vector graphic. This image format is useful because it can use vectors within an x,y plan
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
//Creates graphic
svg.append("g")
//Where the graphic begins
.attr("transform", "translate(360,20)")
//What is in the graphic (A LEGEND)
.append(() =>
legend({
color: color,
title: "Diversity of Amenities per Census Block",
width: 260,
tickFormat: "0.01"
})
);
//Creates a scalable vector graphic
svg.append("g")
.selectAll("path")
//USES THIS DATA to make the maps POLYGONS
.data(new_counties_features.features)
.join("path")
//What outlines do you want in the data?
.attr("stroke", "black")
.attr("stroke-linejoin", "round")
.attr("stroke-width", .5)
//Where are you getting your data from to fill your map's polygons? What colors are associated with them?
.attr("fill", d => color(new_data.get(d.properties.GEOID20)))
.attr("d", path)
//Allows you to hover over polygons and find data associated with it
.append("title")
.text(d => "Ammenity Diversity Score: " + new_data.get(d.properties.GEOID20));

return svg.node();
}

// Most places with bigger cities or tourist destinations have a higher percentage of SNAP (food stamp) users.
//It's pretty easy to see when you use just three/four classifications. The darkest-colored counties contain tourist towns or locations that used to have booming auto industries
Insert cell

One platform to build and deploy the best data apps

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