Public
Edited
Feb 15, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
asst3_yelp = asst3_yelp1.map(d => {
let coords = d.coordinates.split(',')
d.longitude = parseFloat(coords[0]);
d.latitude = parseFloat(coords[1]);
return d
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// set projection to Albers Equal Area
bayAreaProjection = d3.geoMercator()
.scale(12000)
.center([-122.3, 37.9])
.translate([width/2,height/2]);

Insert cell
// Create GeoPath function that uses built-in D3 functionality to turn
// lat/lon coordinates into screen coordinates
geoPath2 = d3.geoPath()
.projection(bayAreaProjection);
Insert cell
Insert cell
Insert cell
Insert cell
{
let svg = d3.select(DOM.svg(width, height));
let g = svg.append("g");

g.selectAll('path')
.data(bayAreaCounties.features)
.enter()
.append("path")
.attr("fill", "#ccc")
.attr("stroke", "#333")
.attr("d", geoPath2);


// define radius in distance for areas of interest
const radiusInMiles = circleRadius;
const degreesPerMile = 1/69
const radiusInDegrees = radiusInMiles * degreesPerMile;


// Define the drag behavior
let drag = d3.drag()
.on("drag", function(event) {
// Convert the new SVG coordinates to geographic coordinates
let newCoords = bayAreaProjection.invert([event.x, event.y]);
// Update the center of the circle
let center = newCoords;
// Update the path data of the circle
d3.select(this).datum(d3.geoCircle().center(center).radius(radiusInDegrees)())
.attr("d", geoPath2);
});
// draw first circle area of interest
//make this a function that takes in an x and y point for center
//make geocircle a function that takes in a center and returns a pixel path
let geoCircle1 = d3.geoCircle().radius(radiusInDegrees).center([-122.14, 37.44]); // convert radius to km for mercator projection

let circle1Path = svg.append("path")
.datum(geoCircle1)
.attr('id', 'circle1ID')
.attr("d", geoPath2)
.attr("fill", "#3498DB")
.attr('stroke', '#A569BD')
.style("opacity", 0.2)
.attr('stroke-opacity', 0.3)
.call(drag);

// draw second circle area of interest
const geoCircle2 = d3.geoCircle().radius(radiusInDegrees).center([-122.5, 37.6]); // convert radius to km for mercator projection

let circle2Path = svg.append("path")
.datum(geoCircle2)
.attr('id', 'circle2ID')
.attr("d", geoPath2)
.attr("fill", "#3498DB")
.attr('stroke', '#A569BD')
.style("opacity", 0.2)
.attr('stroke-opacity', 0.3)
.call(drag);
const restaurants = svg.append('g')
.attr('id', 'dotIDs')
.selectAll("circle")
.data(dataset)
.join("circle")
.attr('class', 'restaurantDots')
.attr('cx', d => bayAreaProjection([d.latitude, d.longitude])[0])
.attr('cy', d => bayAreaProjection([d.latitude, d.longitude])[1])
.attr("r", 5)
.attr("fill", function(d) {
if (d.longitude < 37.566537 && d.latitude > -122.287134) {return "#3498DB"}
else { return '#616161' }
;})
.attr('opacity', 0.75)
.attr('stroke', '#616161')
.attr('stroke-opacity', 0.75)
/****** show tooltip and border when hovered over ******/
.on("mouseover", function (event, d) { // <-- need to use the regular function definition to have access to "this"
svg.select("#tooltip-text")
.text(`Name: ${d.name}`)
.append("tspan")
.attr("x", 5)
.attr("dy", "1.2em")
.text(`Price: ${d.price}`)
.append("tspan")
.attr("x", 5)
.attr("dy", "1.2em")
.text(`Rating: ${d.rating}`);
let positionOffest = 8;
svg.select("#tooltip")
// move the tooltip to where the cursor is
.attr("transform", `translate(${bayAreaProjection([d.latitude, d.longitude])[0] + positionOffest}, ${bayAreaProjection([d.latitude, d.longitude])[1] + positionOffest})`)
.style("display", "block"); // make tooltip visible
d3.select(this)
.attr("stroke", "#333333")
.attr("stroke-width", 2);
})
.on("mouseout", function (event, d) {
svg.select("#tooltip").style("display", "none"); // hide tooltip
d3.select(this).attr("stroke", "none"); // undo the stroke
});

/****** Tooltip Code ******/
const tooltipGroup = svg.append("g") // the tooltip needs to be added last so that it stays on top of all circles
.attr("id", "tooltip")
.style("display", "none"); // hidden by default
tooltipGroup.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 250)
.attr("height", 60)
.attr("fill", "white")
.attr("fill", "white")
.attr("stroke", "#333")
.attr("stroke-width", 1);

// Adding text to the tooltip
tooltipGroup.append("text")
.attr("id", "tooltip-text")
.attr("x", 5)
.attr("y", 15)
.attr("font-size", "14px")
//.attr("font-weight", "bold")
.attr("fill", "black");

return svg.node();
}
Insert cell
{const circle = d3.geoCircle().center([0, 0]).radius(100);
let svg = d3.select(DOM.svg(width, height));
svg.append("path")
.datum(circle())
.attr("d", geoPath2)
.attr("fill", "steelblue")
.attr("stroke", "white");

svg.each(function() {
console.log(circle.center());
});}
// Output: [0, 0]}
Insert cell
Insert cell
Insert cell
// not working right now

/*

// filtering function
updateRating = function (newRating) {
d3.select("#rating-filter")
.selectAll(".restaurantDots")
.data(dataset.filter(d => d.rating === newRating))
.transition()
.duration(1000)
.ease(d3.easeCubic)
.attr('cx', d => bayAreaProjection([d.latitude, d.longitude])[0])
.attr('cy', d => bayAreaProjection([d.latitude, d.longitude])[1])
.attr("r", 5)
.attr("fill", "red")
.attr('opacity', 0.75)
.attr('stroke', 'black')
.attr('stroke-opacity', 0.75)

}
*/
Insert cell
// Not working right now
// updateRating(ratingFilter)
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