Public
Edited
Mar 29, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
symbolLegendDef = {
return {
type: "symbol",
title: attributeName, // Sets the title of our legend
fill: "symbolColor", // Sets the colors
size: "symbolSize", // Sets the size
direction: 'Horizontal', // Sets the orientation
columns: undefined,
rowPadding: 5, // Defines spacing between rows
columnPadding: 5, // Defines spacing between columns
clipHeight: undefined,
titleOrient: 'top', // Sets the legend title position
symbolStrokeColor: '#000', // Sets the stroke color for the circles in the legend
symbolStrokeWidth: 0.5 // Sets the width of the strokes
};
}
// This function will create our legend
Insert cell
height = 610
Insert cell
width = 975
Insert cell
path_points = d3.geoPath().projection(projection)
Insert cell
path_basemap = d3.geoPath().projection(projection)
Insert cell
projection = d3.geoAlbers()
// Projects our data utilizing our datum (WGS 1984). this projection is the preferred for the lower 48 States
Insert cell
format = d3.format(".2s")
// This function will format our data in a more understandable way. It does this by turning something like 2026.2564 into 2k or 3002513.2254 into 3M
Insert cell
radius = d3.scaleThreshold()
.domain(naturalbreaks)
.range(radiusArray)
// Similar to our "colors" function, this combines two arrays but instead of assigning a color it will be assigning a circle size.
Insert cell
sizeArrayForLegend = Array.from(radiusArray, d=>Math.PI*Math.pow(d, 2))
// This function creates an array to calculate the area to be used in a circle
Insert cell
radiusArray = [3, 9, 18, 27]
// This function creates an array of the sizes to be used for the circles displayed above. (map and legend) The order is important.
Insert cell
circleLabels = Array.from(naturalbreaks, d=> format(Math.pow(d, 2)))
// This function creates an array of labels to be used based upon the statistics function we created. The order of the array is case sensitive.
Insert cell
colors = d3.scaleThreshold()
.domain(naturalbreaks)
.range(LtBlu)
// Uses our color array and our class array below to assign a color to each class. This is done similar to an appending method through the combination of the arrays.
Insert cell
LtBlu = ["#eff3ff", "#bdd7e7", "#6baed6", "#2171b5"]
// This function creates an array of the colors we wish to use for our circles. The colors are chosen from ColorBrewer.com
Insert cell
naturalbreaks = simple.ckmeans(attribute, 4).map(v => v.pop())
// Funtion that classifys our data into four classes that are then used to map our data
Insert cell
d3.max(attribute)
// Finds max number in the array
Insert cell
attribute = Array.from(points.features, d=>Math.sqrt(d.properties[attributeName]))
// uses the attributeName function to retrieve the attribute data from our points function to build an array
Insert cell
attributeName = "NEVERMARRY"
// Defines the attribute we wish to map. This function will be used throughout the code
Insert cell
idName = "STATE_NAME"
// Used later in display functions
Insert cell
points = FileAttachment("Lower_STATES_points.geojson").json()
// This creates the points on our map that are displayed as the circles. The data must be formatted to properly work. The steps are as follows:
// First - Ensure you have QGIS downloaded as well as data that has usable attributes (ie. median age)
// Upload your data into QGIS and then select the area you wish to exame using the "select features" button and export the selected features as a GeoJSON format. While you are doing this, ensure your CRS is in the correct coordinate system.
// Using your new layer - utilize the vector tool "Centroids" (found in: Vector > Geometry Tools) and use the default settings
// When you run the centroid tool it creates a temporary file so you will need to export the layer and save it
// When this is done you can attach the file to your notebook
Insert cell
basepolygons = FileAttachment("STATES.json").json()
// This created the base polygons for the map that are displayed as States. This data was formatted into a Topojson file using mapshaper and the corrosponding files (dbf, shp, prj, shx)
Insert cell
simple = require("simple-statistics@7.0.7/dist/simple-statistics.min.js")
// Imports a library useful for doing statistical calculations
Insert cell
topojson = require("topojson-client@3")
// Imports the topojson library. Very important
Insert cell
import {plot} from '@vega/vega-plot'
// Imports a library that is required for vega plot
Insert cell
d3 = require("d3@5")
// This imports the d3 library which allows us to use a number of functions such as "format: f(t)" which is used later. If we were using a .csv file we would need the d3 library as well.
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