Public
Edited
May 3, 2023
Insert cell
Insert cell
canvas = {
const context = DOM.context2d(width, height);

const projection = d3.geoMercator().fitSize([width, height], mapData);

const path = d3.geoPath().projection(projection).context(context);

// Draw map paths
mapData.features.forEach((feature) => {
context.beginPath();
path(feature);
context.strokeStyle = "#ddd";
context.lineWidth = 1;
context.stroke();
});

// Draw tree coordinates as circles
treesCoords.forEach((d) => {
const [x, y] = projection(d);
context.beginPath();
context.arc(x, y, 1, 0, 2 * Math.PI);
context.fillStyle = "green";
context.fill();
});

return context.canvas
}
Insert cell
rawData = FileAttachment("SFTrees.csv").csv({typed: true})
Insert cell
treeData = rawData.map( d => ({
Latitude: d.Latitude,
Longitude: d.Longitude
}))
Insert cell
trees = treeData.filter(d => d.Latitude !== null)
Insert cell
treesCoords = trees.map( function (d) {
return [+d.Longitude,+d.Latitude]
})
Insert cell
mapData = d3.json("https://gist.githubusercontent.com/caseylabrack/aa9d0ca1b50290b21e6f743be2f56001/raw/2759f8cfb683ae3ad2ab2b35fb9cc52d3c78723c/Streets%2520of%2520San%2520Francisco.geojson")
Insert cell
speciesNames = rawData.map( d => ({
species : d.qSpecies.split("::")[0].trim()
}))
Insert cell
summary_species = speciesNames.reduce((accumulator, obj) => {
const species = obj.species;
if (accumulator.hasOwnProperty(species)) {
accumulator[species]++;
} else {
accumulator[species] = 1;
}
return accumulator;
}, {});
Insert cell
Insert cell
numkeys = Object.keys(sf_plant_species).length
Insert cell
height = 960;
Insert cell
width = 999
Insert cell
projection = d3.geoMercator().fitSize([width,height], mapData)
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