Public
Edited
Apr 22, 2023
Insert cell
Insert cell
d3=require("d3@5")
Insert cell
Insert cell
topojson=require("topojson-client@3")
Insert cell
Insert cell
BasePolygons = FileAttachment("iowa_borderWGS84.json").json()
Insert cell
Insert cell
points = FileAttachment("City_Park_Locations.json").json()
Insert cell
Insert cell
csv_data = d3.csvParse(await FileAttachment("City_Park_Locations.csv").text(),({NAME, Shape__Are}) => [NAME, +Shape__Are])
Insert cell
data = Object.assign(new Map(csv_data))
Insert cell
data.get("Ashby Park")
Insert cell
Insert cell
radius = d3.scaleSqrt([0, d3.max([...data.values()])], [0, 20])
Insert cell
Insert cell
radius(5363075.53259277)
Insert cell
d3.max([...data.values()])
Insert cell
format = d3.format(",.0f")
Insert cell
Insert cell
projection = d3.geoTransverseMercator().rotate([94,0]).fitExtent([[150, 150], [width, height]], points)
Insert cell
path_basemap = d3.geoPath().projection(projection)
Insert cell
path_points = d3.geoPath().projection(projection)
Insert cell
Insert cell
proportionalsymbols = {
const svg = d3.create("svg")
.attr("viewBox", [70, 70, width, height]);

svg.append("path")
.datum(topojson.feature(BasePolygons, BasePolygons.objects.iowa_borderWGS84))
.attr("fill", "#f0f0f0")
.attr("stroke", "black")
.attr("d", path_basemap);

svg.append("path")
.datum(topojson.mesh(BasePolygons, BasePolygons.objects.iowa_borderWGS84, (a, b) => a !== b))
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("d", path_basemap);
const legend = svg.append("g")
.attr("fill", "black")
.attr("transform", "translate(950,600)")
//this is the x y coordinates of the legend
.attr("text-anchor", "middle")
.style("font", "12px sans-serif")
.selectAll("g")
//you can also add more circles here if you want
.data([1.4e7, d3.max([...data.values()])])
//this is your legends max and minimum value, we will have to change it
.join("g");

legend.append("circle")
.attr("fill", "none")
.attr("stroke", "black")
.attr("cy", d => -radius(d))
.attr("r", radius);

legend.append("text")
.attr("y", d => -3.2 * radius(d))
.attr("dy", "1.4cm")
.text(d3.format(".2s"));

svg.append("g")
.attr("fill", "#99d8c9")
.attr("fill-opacity", 0.35)
.attr("stroke", "#00441b")
.attr("stroke-width", 0.25)
.selectAll("circle")
.data(points.features
.map(d => (d.value = data.get(d.properties.NAME), d))
.sort((a, b) => b.value - a.value))
//displays larger circles in the back
.join("circle")
.attr("transform", d => `translate(${path_points.centroid(d)})`)
.attr("r", d => radius(data.get(d.properties.NAME)))
.append("title")
.text(d => `${d.properties.NAME} : ${format(d.value)}`);
return svg.node();
}
Insert cell
Insert cell
width = 975
Insert cell
height = 610
Insert cell
margin = 0
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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