Public
Edited
Feb 17, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof categoryFilter = Inputs.checkbox(filterOptions.keys(),
{label: html`<h3>Dining Options:</h2>`,
value: filterOptions.keys()
})
Insert cell
Insert cell
Insert cell
Insert cell
drag = {
function isInBothCircles(x, y) {
const distFromCircleA =
Math.sqrt(Math.pow((x - d3.select("#circle0").attr("cx")),2) + Math.pow((y - d3.select("#circle0").attr("cy")),2));
const distFromCircleB =
Math.sqrt(Math.pow((x - d3.select("#circle1").attr("cx")),2) + Math.pow((y - d3.select("#circle1").attr("cy")),2));
return distFromCircleA <= d3.select("#circle0").attr("r") && distFromCircleB <= d3.select("#circle1").attr("r")
}
function dragstarted(event, d) {
d3.select(this).raise().attr("stroke", "black");
}

function dragged(event, d) {
d3.select(this).attr("cx", d.x = event.x).attr("cy", d.y = event.y);
}

function dragended(event, d) {
d3.select(this).attr("stroke", null);
d3.selectAll(".bobaShop").attr("fill", d => isInBothCircles(path.centroid(d)[0], path.centroid(d)[1]) ? "green" : "gray")
d3.selectAll(".bobaShop").attr("opacity", d => isInBothCircles(path.centroid(d)[0], path.centroid(d)[1]) ? 1 : .5)
}

return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
}
Insert cell
updateRadius = function(currRVal, i) {
const circles =
d3.select("#map")
.select("#" + circlesData[i].id)
.data(circlesData, d => d.id)
circles.transition()
.duration(1000)
.ease(d3.easeCubic)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", currRVal)
.attr("opacity", 0.5)
}
Insert cell
filterHelper = function (d, currFilters) {
for (const filter of currFilters) {
if (d[filterOptions.get(filter)] === "False") {
return false
}
}
return true
}
Insert cell
updateFilters = function (currFilters) {
const curr_boba_shops = d3.select("#map")
.select("#bobaShopsGroup")
.selectAll(".bobaShop")
.data(boba_shop_features.features.filter((d) => filterHelper(d.properties, categoryFilter)))
.join(
enter =>
enter
.append("circle")
.attr("class","bobaShop")
.attr("cx", d => path.centroid(d)[0])
.attr("cy", d => path.centroid(d)[1])
.attr('opacity', 1)
.attr('r', d => 0)
.attr("fill", "grey")
.attr("stroke", greys[5])
.attr("stroke-width", 0.5),
update => update,
exit =>
exit
.transition()
.duration(1000)
.attr('opacity', 0)
.attr('r', d => 0)
.remove()
)
curr_boba_shops.transition() // <-- akin to a D3 selection, but interpolates values
.duration(1000) // <-- 1000 ms === 1 sec
.ease(d3.easeCubic) // <-- sets pacing; cubic is the default, try some others!
.attr("cx", d => path.centroid(d)[0])
.attr("cy", d => path.centroid(d)[1])
.attr("r", d => 3)
.attr('opacity', .5)
}
Insert cell
updateRadius(radiusSliderA, 0)
Insert cell
updateRadius(radiusSliderB, 1)
Insert cell
updateFilters(categoryFilter)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
circlesData =
d3.range(2).map(i => ({
x: Math.random() * 500,
y: Math.random() * 500,
r: 32,
id: "circle" + i
}));
Insert cell
filterOptions = new Map([
["Offers dine in", "dine_in"],
["Offers curbside pick up", "curbside_pickup"],
["Offers delivery", "delivery"],
["Offers take-out", "takeout"],
["Offers reservations", "reservable"],
["Vegetarian", "serves_vegetarian_food"]
]);
Insert cell
boba_shop_data = FileAttachment("asst3_google.csv").csv()
Insert cell
Insert cell
asst3_google.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
mapFrameSpec = {
const spec = {
width: 334,
height: 432,
upperLeft: [403, 561]
}
spec.bottomRight = [spec.upperLeft[0] + spec.width, spec.upperLeft[1] + spec.height]

spec.colors = {
'ocean': '#9bbff4',
'land-neutral': '#FFF2AF',
'text': '#000000',
'land-city': '#E8E8E8',
'land-forest': '#C3ECB2',
'highway': '#F6CF65'
}

spec.icons = {
'pin': 'https://upload.wikimedia.org/wikipedia/commons/d/d1/Google_Maps_pin.svg'
}
return spec
}
Insert cell
mapFrameCoords = [
projection.invert(mapFrameSpec.upperLeft),
projection.invert(mapFrameSpec.bottomRight)
]
Insert cell
mapFrameGeoJSON = JSON.parse(`{"type":"Feature","geometry":{"type":"LineString","coordinates":[[-122.54644297642132,37.989209933976475],[-121.74157680240731,37.19360698897229]]}}`)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// california state plane 3 | https://github.com/veltman/d3-stateplane
projection = d3.geoConicConformal()
.parallels([37 + 4 / 60, 38 + 26 / 60])
.rotate([120 + 30 / 60], 0)
.fitSize([width, height], mapFrameGeoJSON)

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

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