Public
Edited
Mar 11, 2023
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
//This workbook is based off the same data as forked. The reason for that is the lack of ability to find suitable attribute data to fit the states as a base line. I did hours of research but either files were too big or they did not contain the correct geographic information. The comments provided however will allow for seemless transition of data if I can get assistance finding data.

//Initially to create the baseline of maps the use of states_simple.json as a base layer is critical. The next layer which contains the point is added using QGIS. We press on vector -> Geometry Tools -> Centroids. Then clicking run will allow centroids to be created as a layer on the states to which we can later assign values as attributes.
Insert cell
height = 610
// the next two cells denote the height and width of the map projection in Observable
Insert cell
width = 975
Insert cell
path_points = d3.geoPath().projection(projection)
//This path_points equation creates a link between our points that we get from our states48_points.geojson and the map projected.
Insert cell
path_basemap = d3.geoPath().projection(projection)
//This path_basemap equation creates a link between our states baseline that we get from our states_simple.json and the map projected.
Insert cell
projection = d3.geoAlbers()
Insert cell
format = d3.format(".1s")
Insert cell
//proportional symbols
//radius = d3.scaleSqrt([0, d3.max(attribute)], [0, 30])
Insert cell
radius = d3.scaleThreshold()
.domain(naturalbreaks)
.range(radiusArray)
//This piece of code creates the radius of the points. In this instance it's going to represent the 1999 population for each state. The classification method used is naturalbreaks. Hence the circles will be visualized in 4 different sizes, each of which represent one natural break. The radius implies that the shape of the points will be a circle.
Insert cell
sizeArrayForLegend = Array.from(radiusArray, d=>Math.PI*Math.pow(d, 2))
//This function uses a math package to calcuate the area of each one of the circles. This is used for the sizes of the centroids in the map.
Insert cell
radiusArray = [3, 10, 23, 34]
//This piece of code shows an array of radiuses of 4 circles. I adjusted the sizes to be proportional to the naturalbreaks created below (2M, 7M, ... etc).
Insert cell
circleLabels = Array.from(naturalbreaks, d=> format(Math.pow(d, 2)))
//This creates correct labels in the legend for the circles based off the areas.
Insert cell
colors = d3.scaleThreshold()
.domain(naturalbreaks)
.range(GnBu)
//As above in the "radius" expression, this "colors" expression uses natural breaks and the GnBu color scheme defined below to assign color to classes.
Insert cell
GnBu = ["#f0f9e8", "#bae4bc", "#7bccc4", "#2b8cbe"]
//This cell sets the colour scheme for the circles. Using colorbrewer.org, I chose a sequential Green Blue.
Insert cell
naturalbreaks = simple.ckmeans(attribute, 4).map(v => v.pop())
//This equation creates the natural breaks between the attributes. The 4 denotes that we want four classes.
Insert cell
d3.max(attribute)
//This is a check for the maximum value in attribute.
Insert cell
attribute = Array.from(points.features, d=>Math.sqrt(d.properties[attributeName]))
//After using this formula, each attribute will contain the square root of the value of the specified attribute for each feature in the points object. The square root is used to not only normalize the data but also because it makes the data easier to visualize.
Insert cell
attributeName = ("POP1999")
//This cell is where the column or variable we want to analyze is defined. In this instance we are looking at the population from 1999 for each state.
Insert cell
idName = "STATE_NAME"
//This defines the id we are using to analyze the attribute. In this instance State_Name is the primary key.
Insert cell
points = FileAttachment("states48_points.geojson").json()
//This imports the points data as attributes in form of a geojson. This includes the centroids.
Insert cell
basepolygons = FileAttachment("states_simple.json").json()
//Imports the polygon base map data. This is for the outlines of the states.
Insert cell
Insert cell
Insert cell
Insert cell
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