Public
Edited
Jan 19, 2023
Insert cell
Insert cell
function getDistance(x1, y1, x2, y2){
let y = x2 - x1;
let x = y2 - y1;
return Math.sqrt(x * x + y * y);
}
Insert cell
fruit = ['apples','peaches','watermelon','dragonfruit']
Insert cell
Insert cell
transportation
Insert cell
viewof transportation = Inputs.checkbox(["subway", "taxi", "citibike", "revel", "bus"], {label: "NYC Transport"})
Insert cell
index = [{name: 'saigonshack', cost:10, happiness: 2},
{name: 'hellosaigon', cost:8, happiness: 1},
{name: 'bluenotejazz', cost:13, happiness: 3},
{name: 'comedycellar', cost:15, happiness: 5},
{name: 'lpr', cost:15, happiness: 1},
{name: 'ifccenter', cost:12, happiness: 4},
{name: 'filmforum', cost:12, happiness: 2},
{name: 'arthurstavern', cost:10, happiness: 2},
]
Insert cell
ind = {
var totalcost = 0
totalcost = totalcost +(index[0].cost*shack)
totalcost = totalcost +(index[1].cost*saigon)
totalcost = totalcost +(index[2].cost*jazz)
totalcost = totalcost +(index[3].cost*cellar)
totalcost = totalcost +(index[4].cost*lpr)
totalcost = totalcost +(index[5].cost*center)
totalcost = totalcost +(index[6].cost*forum)
totalcost = totalcost +(index[7].cost*tavern)

var totalhappiness = 0
totalhappiness = totalhappiness+(index[0].happiness*shack)
totalhappiness = totalhappiness+(index[1].happiness*saigon)
totalhappiness = totalhappiness+(index[2].happiness*jazz)
totalhappiness = totalhappiness+(index[3].happiness*cellar)
totalhappiness = totalhappiness+(index[4].happiness*lpr)
totalhappiness = totalhappiness+(index[5].happiness*center)
totalhappiness = totalhappiness+(index[6].happiness*forum)
totalhappiness = totalhappiness+(index[7].happiness*tavern)

return [totalcost,totalhappiness]
}
Insert cell
viewof xrad = Inputs.range([0,10],{value:5,step:.1})
Insert cell
viewof xcolor = Inputs.range([0,255],{value:0,step:5})
Insert cell
viewof cellar = Inputs.range([0,10],{value:5,step:1,label:'Comedy Cellar'})
Insert cell
viewof forum = Inputs.range([0,10],{value:5,step:1,label:'Film Forum'})
Insert cell
viewof shack = Inputs.range([0,10],{value:5,step:1,label:'Saigon Shack'})
Insert cell
viewof saigon = Inputs.range([0,10],{value:5,step:1,label:'Hello Saigon'})
Insert cell
viewof jazz = Inputs.range([0,10],{value:5,step:1,label:'Blue Note Jazz'})
Insert cell
viewof lpr = Inputs.range([0,10],{value:5,step:1,label:'LPR'})
Insert cell
viewof center = Inputs.range([0,10],{value:5,step:1,label:'IFC Center'})
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const width = 960,
height = 900;
const svg = d3.create("svg")
.attr("viewBox", [50, 50, width-100, height-100]);

// Use Mercator projection
var projection = d3
.geoAlbersUsa()
.fitSize([width - 50, height - 50], gbox);

var path1 = d3.geoPath().projection(projection);//use different path variable for each set of line data
var path2 = d3.geoPath().projection(projection);
var path3 = d3.geoPath().projection(projection);
var path4 = d3.geoPath().projection(projection);
var path5 = d3.geoPath().projection(projection);
var path6 = d3.geoPath().projection(projection);

var g = svg.append("g").attr("id", "paths");

var clicks =[]

//i'm not using the boundary lines, so I'm going to comment them out
/*
g.selectAll("path1") //d3 geopath
.data(boundary.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
*/

g.selectAll("path2") //d3 geopath
.data(streets.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path2) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.75')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path3") //d3 geopath
.data(gbldgs.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "rgb(240,240,240)")
.style("fill-opacity", ".5")
.style('stroke-opacity','.4')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

var c = svg.selectAll("circle") //circle
.data(spots)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return projection([d.long,d.lat])[0]})
.attr("cy", function(d) {return projection([d.long,d.lat])[1]})
.attr('r',3)
.attr('fill',colorType)//add function to control color by 'type'
.style('fill-opacity','1')
.style('stroke','black')
.style('stroke-width','1')
.on('mouseover', spotText)
.on('mouseout', removeSpotText)

function colorType(d,i){
var color = 'black'

if(d.type=='food'){color = 'cyan',d3.select(this).attr('r',xrad)}
if(d.type=='live'){color = 'yellow'}
if(d.type=='film'){color = 'rgb('+xcolor+',0,'+xcolor+')'}
return color
}



var t = svg.selectAll('text')
.data(transportation)
.enter()
.append('text')
.attr('x','200')
.attr('y',function(d,i){return 200+(i*20)})
.attr('font-family','Helvetica')
.attr('font-size','.6em')
.attr('text-anchor','start')
.attr('font-weight','bold')
.text(function(d) {return d})

function spotText(event,d){
d3.select(this).attr('fill','yellow')

svg.append('text')
.attr('class','spots')
.attr('x','525')
.attr('y','385')
.attr('font-family','Helvetica')
.attr('font-size','.6em')
.attr('text-anchor','start')
.attr('font-weight','bold')
.text(d.name)

svg.append('text')
.attr('class','spots')
.attr('x','525')
.attr('y','395')
.attr('font-family','Helvetica')
.attr('font-size','.5em')
.attr('text-anchor','start')
.attr('font-weight','normal')
.text(d.description)

svg.append('line')
.attr('class','spotLine')
.attr('x1','522')
.attr('y1','381')
.attr('x2',projection([d.long,d.lat])[0])
.attr('y2','381')
.style('stroke-width','1')
.style('stroke','black')
.style('stroke-dasharray','4 4')

svg.append('line')
.attr('class','spotLine')
.attr('x1',projection([d.long,d.lat])[0])
.attr('y1','381')
.attr('x2',projection([d.long,d.lat])[0])
.attr('y2',projection([d.long,d.lat])[1])
.style('stroke-width','1')
.style('stroke','black')
.style('stroke-dasharray','4 4')
}
function removeSpotText(event,d){
d3.select(this).attr('fill',colorType)
d3.selectAll('text.spots').remove()
d3.selectAll('line.spotLine').remove()
}
svg.append('text')
.attr('class','spots')
.attr('x','100')
.attr('y','100')
.attr('font-family','Helvetica')
.attr('font-size','.8em')
.attr('text-anchor','start')
.attr('font-weight','bold')
.text('Monthly Cost ='+ind[0])

svg.append('text')
.attr('class','spots')
.attr('x','100')
.attr('y','130')
.attr('font-family','Helvetica')
.attr('font-size','.8em')
.attr('text-anchor','start')
.attr('font-weight','bold')
.text('Happiness Index ='+ind[1])

if(ind[0]>300){
svg.append('text')
.attr('class','spots')
.attr('x','480')
.attr('y','450')
.attr('font-family','Helvetica')
.attr('font-size','5.8em')
.attr('text-anchor','middle')
.attr('font-weight','bold')
.text('OVER BUDGET')
}

if(ind[0]<300 && ind[1]>79){
svg.append('text')
.attr('class','spots')
.attr('x','480')
.attr('y','450')
.attr('font-family','Helvetica')
.attr('font-size','5.8em')
.attr('text-anchor','middle')
.attr('font-weight','bold')
.text('HAPPY CAMPER')
}
/*
c.enter.append('circle')//format to add additional circles
.data(trees)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return projection([d.long,d.lat])[0]})
.attr("cy", function(d) {return projection([d.long,d.lat])[1]})
.attr('r',3)
.attr('fill','black')
.style('fill-opacity','1')
*/



return svg.node();
}
Insert cell
gbldgs = FileAttachment("gbldgs.geojson").json()
Insert cell
gbox = FileAttachment("greenwich_bb.geojson").json()
Insert cell
streets = FileAttachment("greenwich_streets.geojson").json()
Insert cell
Insert cell
spots = d3.csv(spotsLink,d3.autoType)
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more