Public
Edited
Mar 19, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const monthCounted = Object.values(counts_by_month)[month_counted];

let fc = {
type: "FeatureCollection",
features: monthCounted
}
if (map.value._loaded) {
// Update our source
if (!map.value.getSource("intersections")) {
map.value.addSource("intersections", {
type: "geojson",
data: fc
});
} else {
map.value.getSource("intersections").setData(fc)
}

// Update our layer
if (map.value.getLayer(intersectionsLayer.id)) {
map.value.removeLayer(intersectionsLayer.id);
}
map.value.addLayer(intersectionsLayer);

// Add tooltips on hover
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});

// TODO: Need to update contents of tooltip when scrubber updates
map.value.on("mouseenter", "intersections", function(e) {
console.log('mouse on enter intersection', e);
map.value.getCanvas().style.cursor = "default";

const coordinates = e.features[0].geometry.coordinates.slice();
const properties = e.features[0].properties;
const description = `${properties.location}\n
${properties.total} riders`;

while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}

popup
.setLngLat(coordinates)
.setHTML(description)
.addTo(map.value);
});

map.value.on("mouseleave", "intersections", function() {
map.value.getCanvas().style.cursor = "";
popup.remove();
});
}
}
Insert cell
Insert cell
Insert cell
intersectionsLayer = {
return {
id: "intersections",
type: "circle",
source: "intersections",
paint: {
"circle-stroke-width": 0,
"circle-color": "#80BC3D",
"circle-radius": ["get", "size"],
"circle-opacity": 0.75
}
}
}
Insert cell
counts_by_month = _.groupBy(counts_as_geojson, "properties.start_time")
Insert cell
counts_as_geojson = counts.map((d,i) => {
return {
id: i,
properties: {
...d,
color: color(d.total),
size: size(d.total),
},
geometry: { type: "Point", coordinates: [d.lng, d.lat] },
type: "Feature"
}
})
Insert cell
color = d3.scaleSequentialSqrt([0, max_count], d3.interpolatePlasma);
Insert cell
size = d3.scaleLinear([0, max_count], [5, 25]);
Insert cell
max_count = {
const max = _.max(_.map(counts, "total"));
return max + (max * 0.2);
}
Insert cell
counts = raw_data_files.map((rawData) => parse(rawData, { flatten: true }));
Insert cell
raw_data_files = await Promise.all([
FileAttachment("int_27_Feb1-7_2023.csv").text(),
FileAttachment("int_27_Jan1-7_2023.csv").text(),
FileAttachment("int_27_Dec1-7_2022.csv").text(),
FileAttachment("int_27_Nov1-7_2022.csv").text(),
FileAttachment("int_27_Oct1-7_2022.csv").text(),
FileAttachment("int_27_Sept1-7_2022.csv").text(),

FileAttachment("int_43_Feb1-7_2023.csv").text(),
FileAttachment("int_43_Jan1-7_2023.csv").text(),
FileAttachment("int_43_Dec1-7_2022.csv").text(),
FileAttachment("int_43_Nov1-7_2022.csv").text(),
FileAttachment("int_43_Oct1-7_2022.csv").text(),
FileAttachment("int_43_Sept1-7_2022.csv").text(),

FileAttachment("int_44_Feb1-7_2023.csv").text(),
FileAttachment("int_44_Jan1-7_2023.csv").text(),
FileAttachment("int_44_Dec1-7_2022.csv").text(),
FileAttachment("int_44_Nov1-7_2022.csv").text(),
FileAttachment("int_44_Oct1-7_2022.csv").text(),
FileAttachment("int_44_Sept1-7_2022.csv").text(),

FileAttachment("int_45_Feb1-7_2023.csv").text(),
FileAttachment("int_45_Jan1-7_2023.csv").text(),
FileAttachment("int_45_Dec1-7_2022.csv").text(),
FileAttachment("int_45_Nov1-7_2022.csv").text(),
FileAttachment("int_45_Oct1-7_2022.csv").text(),
FileAttachment("int_45_Sept1-7_2022.csv").text(),
]);
Insert cell
import {renderMap, mapboxgl} from "@jketcham/tempe-az-map-mapbox"
Insert cell
import { parse } from "@jketcham/parse-intersection-bicycle-counts"
Insert cell
import {Scrubber} from "@mbostock/scrubber"
Insert cell
d3legend = require('d3-svg-legend@2.25.6/indexRollup.js')
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