Public
Edited
Dec 12, 2023
Insert cell
Insert cell
import {Plot} from "@observablehq/plot"
Insert cell
import {Inputs} from "@observablehq/inputs"
Insert cell
Insert cell
Insert cell
Insert cell
path = d3.geoPath()
Insert cell
states = topojson.mesh(us, us.objects.states, (a, b) => a !== b)
Insert cell
nation = topojson.feature(us, us.objects.nation)
Insert cell
counties = topojson.mesh(us, us.objects.counties, (a, b) => a !== b && (a.id / 1000 | 0) === (b.id / 1000 | 0))
Insert cell
us = FileAttachment("counties-albers-10m.json").json() // Already projected to Albers-USA!
Insert cell
geojsonData = FileAttachment("simplified_updated_climate_divisions (1).geojson").json()
Insert cell
d3 = require("d3@7")
Insert cell
// airports_jsonData = d3.json("https://raw.githubusercontent.com/e9d8v/cs448b/main/airports.json").then(function(airports_jsonData) {
// // Assuming jsonData is already in the correct format
// return airports_jsonData;
// });
Insert cell
// delays_jsonData = d3.json("https://raw.githubusercontent.com/e9d8v/cs448b/main/airports_delays.json").then(function(delays_jsonData) {
// // Assuming jsonData is already in the correct format
// return delays_jsonData;
// });
Insert cell
// routes_jsonData = d3.json("https://raw.githubusercontent.com/e9d8v/cs448b/main/routes.json").then(function(routes_jsonData) {
// return routes_jsonData;
// });
Insert cell
// airportsData = airports_jsonData

Insert cell
// delayData = delays_jsonData
Insert cell
// routesData = routes_jsonData
Insert cell
// projectedPoints = Object.values(airportsData).map(d => {
// const projectedPoint = projection([+d.longitude, +d.latitude]);
// if (!projectedPoint) return null;

// const [x, y] = projectedPoint;
// return {
// x, y,
// 'IataCode': d.iata_code,
// 'Airport': d.airport,
// 'DelayRate': d.delay_rate,
// 'FlightsCount': d.flights_count
// };
// }).filter(d => d);
Insert cell
// routesByAirport = d3.group(routesData, d => d.origin_airport);
Insert cell
// delayData.forEach(delay => {
// if (airportsData[delay.origin_airport]) {
// airportsData[delay.origin_airport].delay_rate = delay.delay_rate;
// airportsData[delay.origin_airport].flights_count = delay.flights_count;
// }
// });
Insert cell
// function showRoutes(svg, projection, airportsData, iataCode) {
// const routes = routesByAirport.get(iataCode) || [];
// routes.forEach(route => {
// const origin = airportsData[iataCode];
// const destination = airportsData[route.destination_airport];
// if (destination) {
// // Calculate start and end points
// const startPoint = projection([+origin.longitude, +origin.latitude]);
// const endPoint = projection([+destination.longitude, +destination.latitude]);

// // Group for line and text
// const routeGroup = svg.append("g").classed("route-group", true);

// // Draw the line
// routeGroup.append("line")
// .attr("x1", startPoint[0])
// .attr("y1", startPoint[1])
// .attr("x2", endPoint[0])
// .attr("y2", endPoint[1])
// .attr("stroke", "gray")
// .attr("stroke-width", 2)
// .attr("stroke-dasharray", "5, 5");

// // Calculate midpoint for the text
// const midX = (startPoint[0] + endPoint[0]) / 2;
// const midY = (startPoint[1] + endPoint[1]) / 2;

// // Text settings
// const text = routeGroup.append("text")
// .attr("x", midX)
// .attr("y", midY)
// .attr("dy", "0.3em") // Adjust vertical position
// .attr("text-anchor", "middle")
// .style("font-family", "Arial")
// .text(route.count);

// // Get the size of the text element for the background box
// const textSize = text.node().getBBox();

// // Add a background box behind the text
// routeGroup.insert("rect", "text")
// .attr("x", textSize.x - 2)
// .attr("y", textSize.y - 2)
// .attr("width", textSize.width + 4)
// .attr("height", textSize.height + 4)
// .attr("fill", "lightgray")
// .attr("rx", 3); // Rounded corners

// // Ensure the text is on top of the box
// text.raise();
// }
// });
// }

Insert cell
// function hideRoutes(svg) {
// svg.selectAll(".route-group").remove();
// }

Insert cell
// projection = d3.geoAlbersUsa().scale(1300).translate([487.5, 305]);
Insert cell
// radiusScale = d3.scaleSqrt()
// .domain(d3.extent(projectedPoints, d => d.DelayRate))
// .range([2, 20]); // Min and max radius of circles
Insert cell
Insert cell
// {
// const svg = d3.select(map);
// const circles = svg.selectAll("circle.airport")
// .data(projectedPoints)
// .join("circle")
// .attr("class", "airport")
// .attr("cx", d => d.x)
// .attr("cy", d => d.y)
// .attr("r", d => radiusScale(d.DelayRate))
// .attr("fill", "steelblue")
// .attr("fill-opacity", 0.6)
// .on("mouseover", (event, d) => showRoutes(svg, projection, airportsData, d.IataCode))
// .on("mouseout", () => hideRoutes(svg));

// // Append titles (tooltips) to each circle
// circles.append("title")
// .text(d => `IATA Code: ${d.IataCode}\nAirport: ${d.Airport}\nDelay Rate: ${d.DelayRate}\nFlights Count: ${d.FlightsCount}`);

// addLegendToSVG(svg, radiusScale);


// return svg.node();
// }
Insert cell
Insert cell
// d3.csv('https://raw.githubusercontent.com/fbottazzini/448B/main/Flight%20Delays%202015/airlines.csv').then(data => {
// console.log(data);
// });
Insert cell
// airlinesData = d3.csv("https://raw.githubusercontent.com/e9d8v/cs448b/main/airlines.csv", function(d) {
// return {
// // We parse the data into an array of csv objects. We could for example change the names of fields.
// Code: d.IATA_CODE,
// Airline: d.AIRLINE
// };
// }).then(function(airlinesData) {
// //Outside of Observable notebooks you would put all code to draw the graph here.
// return airlinesData;
// });
Insert cell
// width = 2000
Insert cell
// height = 200
Insert cell
// jsonData = d3.json("https://raw.githubusercontent.com/e9d8v/cs448b/main/months.json").then(function(jsonData) {
// // Assuming jsonData is already in the correct format
// return jsonData;
// });
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