Public
Edited
Feb 15, 2023
1 fork
Insert cell
Insert cell
Insert cell
asst3_yelp.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
attachment = FileAttachment("asst3_yelp.csv").csv()
Insert cell
restaurantData = attachment.map((res) => {
return {id: res.id,
name:res.name,
img: res.image_url,
category:res.categories,
rating:res.rating,
coordinates:[parseFloat(res.coordinates.split(',')[1]),parseFloat(res.coordinates.split(',')[0])],
price:res.price,
selected:0,
x: projection1([parseFloat(res.coordinates.split(',')[1]),parseFloat(res.coordinates.split(',')[0])])[0],
y: projection1([parseFloat(res.coordinates.split(',')[1]),parseFloat(res.coordinates.split(',')[0])])[1] }
});//.slice(1, 2);
Insert cell
bayArea = FileAttachment("counties.geojson").json()
Insert cell
markers = [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.354344,37.820594
]
}
}
]
Insert cell
data = {
let data = Object.assign({}, bayArea);
data.features = bayArea.features;
return data;
}
Insert cell
projection1 = d3.geoMercator()
.scale([17000])
.center(markers[0].geometry.coordinates)
.translate([width / 2, 400]);

Insert cell
Insert cell
Insert cell
hi = {
const newData = overlapData;
const chartWidth = width;
const chartHeight = 800;
const backgroundColor = "#ADD8E6";
const landColor = "#09A573";
const landStroke = "#FCF5E9";
const markerColor = "#E26F99";
const projection = d3.geoMercator()
.scale([17000])
.center(markers[0].geometry.coordinates)
.translate([chartWidth / 2, chartHeight / 2]);
const pathGenerator = d3.geoPath(projection);
const svg = d3.create('svg')
.attr("id","map")
.attr("title", "Map")
.attr('width', chartWidth)
.attr('height', chartHeight)
.attr("stroke-width", 0);
svg.append("rect")
.attr("width", chartWidth)
.attr("height", chartHeight)
.attr('fill', backgroundColor);

svg.selectAll('path')
.attr("class","unique")
.data(bayArea.features)
.join('path')
.attr('d', pathGenerator)
.attr('fill', landColor)
.attr('stroke', landStroke)
.attr('stroke-width', 1);
const circles = d3.range(2).map(i => ({
// x: Math.random() * (width - 32 * 2) + 32,
// y: Math.random() * (chartHeight - 32 * 2) + 32,
x: 100,
y: [100,300],
r: [size1,size2]
}));

svg.selectAll("circle")
.data(circlesData)
.attr("id","circle1")
.join("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", (d,i) => d.r[i])
.attr('fill-opacity', 0.5)
.attr("fill", (d, i) => d3.schemeCategory10[i % 10])
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
//.call(drag)
//.call(d3.drag().on('drag', (event,d)=>{console.log("dragging")}))
// console.log("drag end", d.x)

// var id = d.id

// circlesData[id].x = d.x
// circlesData[id].y = d.y
// update();}))
//.call(drag)
// .on("drag",(d,event)=> {
// d3.select(this).attr("cx", d.x = event.x).attr("cy", d.y = event.y);
// console.log("drag end", d.x)

// var id = d.id

// circlesData[id].x = d.x
// circlesData[id].y = d.y
// update();
// })
.call(contains);

console.log("Main",overlapData)


// svg.selectAll("circle").enter()
// .attr("id", "restaurantMarker")
// .data(overlapData)
// .call(d=>console.log("data,",overlapData))
// .join(
// enter => enter.append("circle")//.filter(d=>d.selected == 1)
// .attr("cx", d => projection(d.coordinates)[0])
// .attr("cy", d => projection(d.coordinates)[1])
// .attr("r", 4)
// .attr("fill-opacity", 0.5)
// .attr("fill", d => d.selected === 0 ? "#cccccc":"#E26F99")
// .attr("stroke", markerColor)
// .attr('stroke-width', 1).selection())
//update => update.data(overlapData).attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99").selection(),
//exit => exit.remove()).filter(d=>d.selected ==0)

svg.selectAll("circle").enter()
.attr("id", "restaurantMarker")
.data(overlapData)
.join("circle")
.attr("cx", d => projection(d.coordinates)[0])
.attr("cy", d => projection(d.coordinates)[1])
.attr("r", 4)
.attr("fill-opacity", 0.5)
.attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99")
.attr("stroke", markerColor)
.attr('stroke-width', 1)
.on("mouseover", function (event, d) {
svg.select("#tooltip-text")
.append("text").text(d.name + " (" + d.price + ")");

let positionOffest = 8;
svg.select("#tooltip")
// move the tooltip to where the cursor is
.attr("transform", `translate(${projection(d.coordinates)[0] + positionOffest}, ${projection(d.coordinates)[1] + positionOffest})`)
.style("display", "block"); // make tooltip visible
d3.select(this)
.attr("stroke", "#333333")
.attr("stroke-width", 2);


const path = tooltip.append("path")
.attr("fill", "white")
.attr("stroke", "black");


})
.on("mouseout", function (event, d) {
svg.select("#tooltip").style("display", "none"); // hide tooltip
svg.select("#tooltip-text").text(" ");
d3.select(this).attr("stroke", "none"); // undo the stroke
});


var path = d3.path();

//const hi = svg.selectAll(".restaurantMarker").filter(d=>console.log("tokyo"))


svg.append("path")
.attr("fill", "none")
.attr("stroke", "#FFF")
.attr("d",path)

const tooltip = 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
.append("g")
.attr("id", "tooltip-text")
.attr("x", 5)
.attr("y", 15)
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "black")

tooltip.append("text")
.attr("id", "tooltip-text1")
.attr("x", 5)
.attr("y", 30)
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "black")




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);
console.log("drag end", d.x)

var id = d.id

circlesData[id].x = d.x
circlesData[id].y = d.y

console.log("before",overlapData)

//update();
overlapData.forEach(function(d,i) {
var a = projection1(d.coordinates)
var x = a[0]
var y = a[1]

if (overlaps(x,y)){
overlapData[i].selected = 1
d.selected = 1
console.log("overlaps")
} else {
overlapData[i].selected = 0
d.selected = 0
}
})


overlapData.filter(function(d,i) {
var a = projection1(d.coordinates)
var x = a[0]
var y = a[1]

if (overlaps(x,y)){
overlapData[i].selected = 1
d.selected = 1
console.log("dont return null")
return d
} else {
overlapData[i].selected = 0
d.selected = 0
console.log("return null")
return null
}
})


const svg = d3.select("#map")
//svg.selectAll("circle").filter(d=>d.selected ==1)
// UNCOMMENT FOR HELP
const marker = svg.select("#restaurantMarker")
console.log("Marker",marker)
d3.selectAll("circle").attr("fill", d => d.selected === 0 ? "#cccccc":"#E26F99").filter(d=>d.selected === 1)
console.log("Circle Node",svg.selectAll("circle"))

// d3.selectAll("#restaurantMarker").data(overlapData).append("circle").attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99")
// console.log("MEE",d3.selectAll("circle"))
//d3.selectAll("circle")

// svg.selectAll("circle").filter(function(d){
// if ('name' in d){
// console.log("Yoo bitch",d)
// if (d.selected == 0){
// d.attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99")
// console.log(d)
// } else {
// return null
// }
// } else {
// console.log(d)
// return d
// }
// })

// console.log("Heyoo",d3.select("#map"))
// console.log("too too",svg.select("#restaurantMarker"))
// d3.selectAll("#restaurantMarker").filter(d=>console.log("d",d))
console.log("after",overlapData)

//console.log("morocco",d3.select("#restaurantMarker"))

}

function dragended(event, d) {
d3.select(this).attr("stroke", null);
}


return svg.node()
}
Insert cell
circlesData = d3.range(2).map(i => ({
id: i,
x: 100,
y: 100+200*i,
r: [size1,size2]
}));
Insert cell
viewof size2 = Inputs.range([0, 100], {step: 1, label: "Circle Size 1"})

Insert cell
viewof size1 = Inputs.range([0, 100], {step: 1, label: "Circle Size 1"})

Insert cell
// drag = {

// 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);
// console.log("drag end", d.x)

// var id = d.id

// circlesData[id].x = d.x
// circlesData[id].y = d.y

// console.log("before",overlapData)

// //update();
// overlapData.forEach(function(d,i) {
// var a = projection1(d.coordinates)
// var x = a[0]
// var y = a[1]

// if (overlaps(x,y)){
// overlapData[i].selected = 1
// d.selected = 1
// console.log("overlaps")
// } else {
// overlapData[i].selected = 0
// d.selected = 0
// }
// })


// overlapData.filter(function(d,i) {
// var a = projection1(d.coordinates)
// var x = a[0]
// var y = a[1]

// if (overlaps(x,y)){
// overlapData[i].selected = 1
// d.selected = 1
// console.log("dont return null")
// return d
// } else {
// overlapData[i].selected = 0
// d.selected = 0
// console.log("return null")
// return null
// }
// })


// const svg = d3.select("#map")
// //svg.selectAll("circle").filter(d=>d.selected ==1)
// // UNCOMMENT FOR HELP
// const marker = svg.select("#restaurantMarker")
// console.log("Marker",marker)
// //d3.selectAll("circle").attr("fill", d => d.selected === 0 ? "#cccccc":"#E26F99").filter(d=>d.selected === 1)
// console.log("Circle Node",svg.selectAll("circle"))

// // d3.selectAll("#restaurantMarker").data(overlapData).append("circle").attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99")
// // console.log("MEE",d3.selectAll("circle"))
// //d3.selectAll("circle")

// // svg.selectAll("circle").filter(function(d){
// // if ('name' in d){
// // console.log("Yoo bitch",d)
// // if (d.selected == 0){
// // d.attr("fill", d => d.selected == 0 ? "#cccccc":"#E26F99")
// // console.log(d)
// // } else {
// // return null
// // }
// // } else {
// // console.log(d)
// // return d
// // }
// // })

// // console.log("Heyoo",d3.select("#map"))
// // console.log("too too",svg.select("#restaurantMarker"))
// // d3.selectAll("#restaurantMarker").filter(d=>console.log("d",d))
// console.log("after",overlapData)

// //console.log("morocco",d3.select("#restaurantMarker"))

// }

// function dragended(event, d) {
// d3.select(this).attr("stroke", null);
// }

// return d3.drag()
// .on("start", dragstarted)
// .on("drag", dragged)
// .on("end", dragended);
// }
Insert cell
function contains(event,d){
console.log(event)
// console.log("HELLOOOO",d._groups[0]);
// var data = d._groups[0]
// var circle1 = data[0].__data__
// var circle2 = data[1].__data__
// console.log("heyy",circle1)
// return circle1

}
Insert cell
Insert cell
price
Insert cell
viewof sizes = Inputs.checkbox(new Map([["$", 1], ["$$", 2], ["$$$", 3]]), {value: [12], label: "Size"})
Insert cell
sizes
Insert cell
filtered = restaurantData.filter(function(d) {
if (sizes.length == 0){
return d
} else {
return d.price.length == sizes[0] || d.price.length == sizes[1] || d.price.length == sizes[2] ? d : null
}
})

Insert cell
overlapData = filtered.map(function(d) {
var a = projection1(d.coordinates)
var x = a[0]
var y = a[1]

if (overlaps(x,y)){
console.log("YOOO aaa")
d.selected = 1
} else {
d.selected = 0
}
return d
})

Insert cell
Insert cell
topGenresOther = [
"Action",
"Comedy",
"Animation",
"Drama",
]
Insert cell
viewof colors = Inputs.checkbox(["red", "green", "blue"], {label: "color"})
Insert cell
colors
Insert cell
function overlaps(x,y){
var circle1 = 0
var circle2 = 0
if ((x - circlesData[0].x)**2 + (y - circlesData[0].y)**2 < circlesData[0].r[0]**2){
circle1 = 1
}
if ((x - circlesData[1].x)**2 + (y - circlesData[1].y)**2 < circlesData[0].r[1]**2){
circle2 = 1
}
if (circle1 == 1 && circle2 == 1){
return true
}
return false
}
Insert cell
function update(){
overlapData.forEach(function(d,i) {
var a = projection1(d.coordinates)
var x = a[0]
var y = a[1]

if (overlaps(x,y)){
overlapData[i].selected = 1
d.selected = 1
console.log("overlaps")
} else {
overlapData[i].selected = 0
}
})
}
Insert cell
overlapData
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