Public
Edited
Dec 24, 2024
Insert cell
Insert cell
geoData = {
return {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {
city: "San Francisco",
company: "Cruise",
start_date: "2024-12-01"
},
geometry: {
type: "Polygon",
coordinates: [
[
[-122.51593, 37.70813],
[-122.35699, 37.70813],
[-122.35699, 37.83239],
[-122.51593, 37.83239],
[-122.51593, 37.70813]
]
]
}
},
{
type: "Feature",
properties: {
city: "Phoenix",
company: "Waymo",
start_date: "2023-10-15"
},
geometry: {
type: "Polygon",
coordinates: [
[
[-112.32391, 33.29026],
[-111.97972, 33.29026],
[-111.97972, 33.73106],
[-112.32391, 33.73106],
[-112.32391, 33.29026]
]
]
}
},
{
type: "Feature",
properties: {
city: "Austin",
company: "Tesla",
start_date: "2025-01-01"
},
geometry: {
type: "Polygon",
coordinates: [
[
[-97.92028, 30.09808],
[-97.55671, 30.09808],
[-97.55671, 30.55333],
[-97.92028, 30.55333],
[-97.92028, 30.09808]
]
]
}
}
]
};
}
Insert cell
import { geoPath, geoMercator, select } from "d3";

// Dimensions for our map
const width = 800;
const height = 500;

// Create an SVG
const svg = select(DOM.svg(width, height))
.attr("viewBox", [0, 0, width, height])
.style("border", "1px solid black");

// Create a projection (choose the projection type that fits your need)
const projection = geoMercator()
.scale(1000) // Adjust scale to fit your area of interest
.translate([width / 2, height / 2]); // Center the map in the svg

// Create a geoPath generator
const pathGenerator = geoPath().projection(projection);

// Define color scale by company (simple example)
const colorMap = {
"Cruise": "#ff0000",
"Waymo": "#0000ff",
"Tesla": "#008000"
};

// Draw the polygons
svg.selectAll("path")
.data(geoData.features)
.join("path")
.attr("d", pathGenerator)
.attr("fill", d => colorMap[d.properties.company] || "#888888")
.attr("stroke", "#000")
.attr("stroke-width", 1);

// Add labels
svg.selectAll("text")
.data(geoData.features)
.join("text")
.attr("x", d => {
const centroid = pathGenerator.centroid(d);
return centroid[0];
})
.attr("y", d => {
const centroid = pathGenerator.centroid(d);
return centroid[1];
})
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "#000")
.text(d => `${d.properties.city} - ${d.properties.company}`);

// Return the SVG
svg.node();

Insert cell
{
const { geoPath, geoMercator, select } = d3;

// Dimensions for our map
const width = 800;
const height = 500;

// Create an SVG
const svg = select(DOM.svg(width, height))
.attr("viewBox", [0, 0, width, height])
.style("border", "1px solid black");

// Create a projection (choose the projection type that fits your need)
const projection = geoMercator()
.scale(1000) // Adjust scale to fit your area of interest
.translate([width / 2, height / 2]); // Center the map in the svg

// Create a geoPath generator
const pathGenerator = geoPath().projection(projection);

// Define color scale by company (simple example)
const colorMap = {
Cruise: "#ff0000",
Waymo: "#0000ff",
Tesla: "#008000"
};

// Draw the polygons
svg
.selectAll("path")
.data(geoData.features)
.join("path")
.attr("d", pathGenerator)
.attr("fill", (d) => colorMap[d.properties.company] || "#888888")
.attr("stroke", "#000")
.attr("stroke-width", 1);

// Add labels
svg
.selectAll("text")
.data(geoData.features)
.join("text")
.attr("x", (d) => {
const centroid = pathGenerator.centroid(d);
return centroid[0];
})
.attr("y", (d) => {
const centroid = pathGenerator.centroid(d);
return centroid[1];
})
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "#000")
.text((d) => `${d.properties.city} - ${d.properties.company}`);

// Return the SVG
return svg.node();
}
Insert cell
// import { geoPath, geoMercator, select } from "d3"
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