Public
Edited
May 10
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
height = 525
Insert cell
width = 850
Insert cell
path_points = d3.geoPath().projection(newprojection)
Insert cell
path_basemap = d3.geoPath().projection(newprojection)
Insert cell
format = d3.format("1")
Insert cell
//proportional symbols
//radius = d3.scaleSqrt([0, d3.max(attribute)], [0, 30])
Insert cell
radius = d3.scaleThreshold()
.domain(naturalbreaks)
.range(radiusArray)
Insert cell
sizeArrayForLegend = Array.from(radiusArray, d=>Math.PI*Math.pow(d, 2))
Insert cell
radiusArray = [5, 7, 12, 17, 22]
Insert cell
circleLabels = Array.from(naturalbreaks.slice(1), d => format(Math.pow(d, 2)))
Insert cell
colors = d3.scaleThreshold()
.domain(naturalbreaks)
.range(Greens)
Insert cell
Greens = ['#','#','#','#','#','#']
Insert cell
naturalbreaks = simple.ckmeans(attribute, 6).map(v => v.pop())
Insert cell
d3.max(attribute)
Insert cell
attribute = Array.from(points.features, d=>Math.sqrt(d.properties[FDept_ResptoWildfire]))
Insert cell
filteredPoints = {
return {
...points,
features: points.features.filter(d => d.properties.states_sim !== "District of Columbia")
};
}
Insert cell
csv_data = d3.csvParse(await FileAttachment("StateF2Pexport@1.csv").text(),({Firedepart, Firedepa_2}) => [Firedepart, +Firedepa_2])
Insert cell
FDept_ResptoWildfire = "Firedepa_2"
Insert cell
idName = "Firedepart"
Insert cell
//import the point data (geojson)
points = FileAttachment("StateF2Pexport.json").json()
Insert cell
//import the polygon base map data
basepolygons = FileAttachment("states_simple.json").json()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
newd3 = require("d3@5")
Insert cell
import {legend} from "@d3/color-legend"
Insert cell
newsimple = require("simple-statistics@7.0.7/dist/simple-statistics.min.js")
Insert cell
newformat = d => `${d}%`
Insert cell
States = FileAttachment("states_simple.json").json()
Insert cell
State_Features = topojson.feature(States, States.objects.states_simple)
Insert cell
newcsv_data = newd3.csvParse(await FileAttachment("StateF2Pexport@1.csv").text(),({states_sim, Total_FireDepartments}) => [states_sim, +Total_FireDepartments])
Insert cell
data = Object.assign(new Map(newcsv_data), {title: "Total Fire Departments per State"})
Insert cell
data.get("Washington")
Insert cell
FireDepartmentChoro = Array.from(newcsv_data.values(), d => d[1])
Insert cell
PuRd = [newd3.color("#f1eef6"), newd3.color("#d7b5d8"), newd3.color("#df65b0"), newd3.color("#dd1c77"),newd3.color("#980043")]
Insert cell
newnaturalbreaks = newsimple.ckmeans(FireDepartmentChoro, PuRd.length).map(v => v.pop())
Insert cell
//more information on sequential scales: https://observablehq.com/@d3/sequential-scales
// color = newd3.scaleSequentialQuantile([...data.values()], newd3.interpolateBlues)

// color = newd3.scaleQuantile()
// .domain(PctWhite)
// .range()

color = newd3.scaleThreshold()
.domain(newnaturalbreaks)
.range(PuRd)
Insert cell
newwidth = 850
Insert cell
newheight = 525
Insert cell
margin = 100
Insert cell
//Rotate the map sets the longitude of origin for our UTM Zone 15N projection.
//projection = newd3.geoTransverseMercator().rotate([100,0]).fitExtent([[80, 80], [newwidth, newheight]], State_Features);
//d3 reference for projections: https://d3js.org/d3-geo

//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)

newprojection = newd3.geoAlbers().fitExtent([[margin, margin], [newwidth, newheight]], State_Features)

//projection = d3.geoMercator().fitExtent([[margin, margin], [width - margin, height - margin]], Counties)
Insert cell
//Using a path generator to project geometry onto the map
newpath = newd3.geoPath().projection(newprojection);
Insert cell
choropleth = {
const svg = newd3.create("svg")
.attr("viewBox", [45, 20, width, height])
.style("background-color", "#ed914e");
svg.append("g")
.attr("transform", "translate(550,41)")
.append(() =>
legend({
color: color,
title: data.title,
width: 250,
tickFormat: ".1f"
})
);
svg.append("g")
.selectAll("path")
.data(State_Features.features)
.join("path")
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 0.5)
.attr("fill", d => color(data.get(d.properties.STATE_NAME)))
.attr("d", newpath)
.append("title")
.text(d => "Total Fire Departments : " + data.get(d.properties.STATE_NAME));

svg.append("g")
svg.append("g")
.selectAll("circle")
.data(filteredPoints.features
.map(d => (d.value = Math.sqrt(d.properties[FDept_ResptoWildfire]), d))
.sort((a, b) => b.value - a.value))
.join("circle")
.attr("transform", d => `translate(${path_points.centroid(d)})`)
.attr("r", d => radius(d.value))
.attr("fill", d => colors(d.value))
.attr("fill-opacity", 0)
.attr("stroke", "black")
.attr("stroke-width", 0.5)
.append("title")
.text(d => `${d.properties[idName]} : ${format(d.properties[FDept_ResptoWildfire])}`);

const symLegendNode = symbolLegend.cloneNode(true); // clone Plot SVG
const symLegendGroup = newd3.select(symLegendNode).select("g");

svg.append("g")
.attr("transform", "translate(160,45)") // adjust position as needed
.node()
.appendChild(symLegendGroup.node());

return svg.node();
}
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