Public
Edited
Feb 20, 2024
Insert cell
# base map - UD Spring 2024 - Alec's Version V4
Insert cell
d3 = require("d3@6")
Insert cell
chart = {
const width = 1200,
height = 960;
const svg = d3.create("svg")
.attr("viewBox", [50, 50, width-100, height-100]);

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

var path1 = d3.geoPath().projection(projection);
var path2 = d3.geoPath().projection(projection);
var path3 = d3.geoPath().projection(projection);
var path4 = d3.geoPath().projection(projection);

var g = svg.append("g").attr("id", "paths");
g.selectAll("trails") //d3 geopath
.data(trails.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','0.6')
.style("stroke-width", '0.4')
.style("stroke", "rgb(0,0,0)")


g.selectAll("boundaries") //d3 geopath
.data(boundaries.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(153,255,153)")
.style("fill-opacity", ".05")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")

g.selectAll("waterBoundaries") //d3 geopath
.data(waterBoundaries.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(102,102,255)")
.style("fill-opacity", ".1")
.style('stroke-opacity','.4')
.style("stroke-width", '0.5')
.style("stroke", "rgb(68,85,200)")

//Title and Text......................................................................................................................................
svg
.append('text')
.attr('x','65')
.attr('y','120')
.attr("font-family", "arial")
.attr('font-size','35')
//.attr('text-anchor','end')
.style("font-weight","bold")
.style("fill","rgb(0,0,0)")
.text("Wyoming's")

svg
.append('text')
.attr('x','65')
.attr('y','160')
.attr("font-family", "arial")
.attr('font-size','35')
//.attr('text-anchor','end')
.style("font-weight","bold")
.style("fill","rgb(0,0,0)")
.text("Natural")

svg
.append('text')
.attr('class','station')
.attr('x','65')
.attr('y','200')
.attr("font-family", "arial")
.attr('font-size','35')
//.attr('text-anchor','end')
.style("font-weight","bold")
.style("fill","rgb(0,0,0)")
.text("Wonders")
svg
.append('line')
.attr('class','sbLn')
.attr('x1',50)
.attr('y1',210)
.attr('x2',250)
.attr('y2',210)
.attr('stroke-width','2')
.attr('stroke-opacity','0.75')
.style('stroke','rgb(0,0,0)')


//Start of park interactive info..................................................................................................................



var p = svg.selectAll("polyline")
.data(treeicon1)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('points', function(d){return d})
.attr('transform', 'translate(80,250)')
.style('fill', 'grey')
.style('stroke','black')
.style('stroke-width','0.9')
.style('stroke-fill', '4,4,8,8')

p.enter().append("polyline")
.data(icon_list)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon2')
.attr('points', function(d){return d.pts})
.attr('transform',function(d){return 'translate('+projection([d.data.Long,d.data.Lat])[0]+','+projection([d.data.Long,d.data.Lat])[1]+')'})
.style('fill', fillcolor)
.style('stroke','black')
.style('stroke-width','0.9')
.style('stroke-fill', '4,4,8,8')
.on('mouseover',parkInfo)//listens for a mousover, and calls function
.on('mouseout', parkInfoOut)
function fillcolor(d,i){

var color = 'rgb(0,255,0)'

if(d.data.Rating==5){color='rgb(0,255,0)'}
if(d.data.Rating==4){color='rgb(102,204,0)'}
if(d.data.Rating==3){color='rgb(153,255,153)'}
if(d.data.Rating==2){color='rgb(204,255,204)'}
if(d.data.Rating==1){color='rgb(255,255,255)'}
return color
}
function parkInfo(event,d){
d3.select(this).style('fill','white')

svg
.append('text')
.attr('class','parkText')
.attr('x','75')
.attr('y','845')
.style("font-family", "Helvetica")
.style('font-size','1em')
.style('font-weight','10')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Name)

svg
.append('text')
.attr('class','parkText')
.attr('x','75')
.attr('y','860')
.style("font-family", "Helvetica")
.style('font-size','.60em')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Description)

svg
.append('text')
.attr('class','parkText')
.attr('x','75')
.attr('y','875')
.style("font-family", "Helvetica")
.style('font-size','.60em')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Rating)

svg
.append('line')
.attr('class','parkLine')
.attr('x1','75')
.attr('y1','880')
.attr('x2','800')
.attr('y2','880')
.style('stroke','black')
.style('stroke-width','1')


var ratingList= []

if(d.data.Rating==1){ratingList = [treeicon1]}
if(d.data.Rating==2){ratingList = [treeicon1,treeicon1]}
if(d.data.Rating==3){ratingList = [treeicon1,treeicon1,treeicon1]}
if(d.data.Rating==4){ratingList = [treeicon1,treeicon1,treeicon1,treeicon1]}
if(d.data.Rating==5){ratingList = [treeicon1,treeicon1,treeicon1,treeicon1,treeicon1]}
p.enter().append("polyline")
.data(ratingList)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon_rating2')
.attr('points', function(d){return d})
.attr('transform',function(d,i){return 'translate('+(75+(i*25))+',805)'})
.style('fill', 'white')
.style('stroke','black')
.style('stroke-width','0.25')
.style('stroke-fill', '4')
}

function parkInfoOut(event, d){
d3.selectAll('text.parkText').remove()
d3.selectAll('line.parkLine').remove()
d3.selectAll('polyline.icon_rating2').remove()
d3.selectAll('polyline.icon2').style('fill',fillcolor)
}



//mountain data................................................................................................................................

var p = svg.selectAll("polyline")
.data(mountainicon)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('points', function(d){return d})
.attr('transform', 'translate(75,300)')
.style('fill', 'grey')
.style('stroke','black')
.style('stroke-width','0.9')
.style('stroke-fill', '4,4,8,8')

p.enter().append("polyline")
.data(icon_list2)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon1')
.attr('points', function(d){return d.pts})
.attr('transform',function(d){return 'translate('+projection([d.data.Long,d.data.Lat])[0]+','+projection([d.data.Long,d.data.Lat])[1]+')'})
.style('fill', fillcolor1)
.style('stroke','black')
.style('stroke-width','0.9')
.style('stroke-fill', '4,4,8,8')
.on('mouseover',mountainsInfo)//listens for a mousover, and calls function
.on('mouseout', mountainsInfoOut)

function fillcolor1(d,i){

var color = 'rgb(0,255,0)'

if(d.data.Rating==5){color='rgb(0,255,0)'}
if(d.data.Rating==4){color='rgb(102,204,0)'}
if(d.data.Rating==3){color='rgb(153,255,153)'}
if(d.data.Rating==2){color='rgb(204,255,204)'}
if(d.data.Rating==1){color='rgb(235,255,235)'}
return color
}


function mountainsInfo(event,d){
d3.select(this).style('fill','white')

svg
.append('text')
.attr('class','mountainsText')
.attr('x','75')
.attr('y','845')
.style("font-family", "Helvetica")
.style('font-size','1em')
.style('font-weight','10')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Name)

svg
.append('text')
.attr('class','mountainsText')
.attr('x','75')
.attr('y','860')
.style("font-family", "Helvetica")
.style('font-size','.60em')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Description)

svg
.append('text')
.attr('class','mountainsText')
.attr('x','75')
.attr('y','875')
.style("font-family", "Helvetica")
.style('font-size','.60em')
.style('fill','rgb(0,0,0)')
.style('text-anchor','start')
.text(d.data.Rating)

svg
.append('line')
.attr('class','mountainsLine')
.attr('x1','75')
.attr('y1','880')
.attr('x2','800')
.attr('y2','880')
.style('stroke','black')
.style('stroke-width','1')
var ratingList= []

if(d.data.Rating==1){ratingList = [mountainicon]}
if(d.data.Rating==2){ratingList = [mountainicon,mountainicon]}
if(d.data.Rating==3){ratingList = [mountainicon,mountainicon,mountainicon]}
if(d.data.Rating==4){ratingList = [mountainicon,mountainicon,mountainicon,mountainicon]}
if(d.data.Rating==5){ratingList = [mountainicon,mountainicon,mountainicon,mountainicon,mountainicon]}
p.enter().append("polyline")
.data(ratingList)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon_rating1')
.attr('points', function(d){return d})
.attr('transform',function(d,i){return 'translate('+(90+(i*50))+',805)'})
.style('fill', 'white')
.style('stroke','black')
.style('stroke-width','0.25')
.style('stroke-fill', '4')
}

function mountainsInfoOut(event, d){
d3.selectAll('text.mountainsText').remove()
d3.selectAll('line.mountainsLine').remove()
d3.selectAll('polyline.icon_rating1').remove()
d3.selectAll('polyline.icon1').style('fill',fillcolor1)

}

return svg.node();
}


Insert cell
subSts = FileAttachment("sub_stops.geojson").json()
Insert cell
bldgs = FileAttachment("bldgs.geojson").json()
Insert cell
bbox = FileAttachment("site_boundary.geojson").json()
Insert cell
subLns = FileAttachment("subway_lines.geojson").json()
Insert cell
trails = FileAttachment("trails.geojson").json()
Insert cell
water = FileAttachment("water.geojson")
Insert cell
bbox1 = FileAttachment("bbox.geojson").json()
Insert cell
boundaries = FileAttachment("Boundaries.geojson").json()
Insert cell
waterBoundaries = FileAttachment("water boundaries.geojson").json()
Insert cell
Insert cell
park = d3.csv(parks_link,d3.autotype)
Insert cell
Insert cell
mountains = d3.csv(mountains_link,d3.autotype)
Insert cell
treeicon1 = FileAttachment("TreeIcon@2.txt").text()
Insert cell
mountainicon = FileAttachment("mountainicon.txt").text()
Insert cell
icon_list = {

////create empty list
var list = []

//// loop through google sheets list
for (let i = 0; i < park.length; i++) {
park[i]

//function to add items to a list
list.push({data:park[i],pts:treeicon1})
}


////return list
return list
}
Insert cell
icon_list2 = {

////create empty list
var list2 = []

//// loop through google sheets list
for (let i = 0; i < mountains.length; i++) {
mountains[i]

//function to add items to a list
list2.push({data:mountains[i],pts:mountainicon})
}


////return list
return list2
}
Insert cell
waterIcon = FileAttachment("water icon.txt").tsv({array:true})
Insert cell
dashboard = FileAttachment("dashborrd@8.txt").tsv({array:true})
Insert cell
dashboard_graphics = {

const width = 1250,
height = 2000;

const svg = d3.create("svg")
.attr("viewBox",[82,300,width,height]);

var p = svg.selectAll("polyline")
.data(dashboard)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('points', function(d){return d})
.attr('transform', 'translate(75,300)')
.style("fill-opacity", ".05")
.style('fill', 'tan')
.style('stroke','brown')
.style('stroke-width','0.9')
.style('stroke-fill', '4,4,8,8')
.style("stroke-opacity", ".5")

return svg.node();

}
Insert cell
dashboard1 =

html`

<div class='dashboardOuter' style='height:1010px;width:1250px'>
<div class='dashboard_graphics' style='position:absolute;width:1000px;top:0px;left:0px'>
${dashboard_graphics}
</div>

<div class='dashboardOuter' style='height:1010px;width:1250px'>
<div class='dashboard_graphics' style='position:absolute;width:1000px;top:22px;left:0px'>
${chart}
<div class='inputs' style='position:absolute;width:1000px;top:800px;left:20px'>
${viewof CM}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:850px;left:20px'>
${viewof GT}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:885px;left:20px'>
${viewof NB}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:800px;left:290px'>
${viewof WR}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:835px;left:290px'>
${viewof TP}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:870px;left:290px'>
${viewof MW}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:800px;left:550px'>
${viewof PP}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:840px;left:550px'>
${viewof SNF}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:890px;left:550px'>
${viewof BTF}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:800px;left:820px'>
${viewof GTP}
</div>
<div class='inputs' style='position:absolute;width:1000px;top:850px;left:820px'>
${viewof YNP}
</div>

<div class='text' style='position:absolute;top:930px;left:0px;font-family:helvetica;font-size:12px'>
${md`Anticipated Excitment (in stars): **${calculatedValues[0]}** `}
</div>

<div class='text' style='position:absolute;top:945px;left:0px;font-family:helvetica;font-size:12px'>
${md`Anticipated Hike Time (in hours): **${calculatedValues[1]}** `}
</div>

<div class='star' style='position:absolute;width:200px;top:890px;left:150px'>
${DrawStar}
</div>
</div>
`
Insert cell
DrawStar = {
var icon = ' '
if(calculatedValues[0]>60 && calculatedValues[1]>150){icon = staricon}


return icon
}
Insert cell
viewof CM = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Carter Mountain"})
Insert cell
viewof GT = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Grant Teton"})
Insert cell
viewof NB = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at North Breccia"})
Insert cell
viewof WR = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Wapiti Ridge"})
Insert cell
viewof TP = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Trout Peak"})
Insert cell
viewof MW = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Mt. Washburn"})
Insert cell
viewof PP = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Pilot Peak"})
Insert cell
viewof SNF = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Shoshone National Forest"})
Insert cell
viewof BTF = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Bridger-Teton National Forest"})
Insert cell
viewof GTP = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Grand Teton National Park"})
Insert cell
viewof YNP = Inputs.radio(["1", "2", "3"], {label: "Amount of trails to hike at Yellowstone National Park"})
Insert cell
GT
Insert cell
MountainDataset = [
{name:"CM",rating: 1,time:3},
{name:"GT",rating: 3,time:17},
{name:"NB",rating: 3,time:3},
{name:"WR",rating: 4,time:12},
{name:"TP",rating: 3,time:24},
{name:"MW",rating: 5,time:4},
{name:"PP",rating: 5,time:8},




]
Insert cell
ParkDataset = [
{name:"SNF",rating: 4,time:3},
{name:"BTF",rating: 3,time:3},
{name:"GTP",rating: 2,time:3},
{name:"YNP",rating: 5,time:3},




]
Insert cell
calculatedValues = {

var totalrating = 0
var totaldifficulty = 0
totalrating = totalrating+MountainDataset[0].rating*CM
totalrating = totalrating+MountainDataset[1].rating*GT
totalrating = totalrating+MountainDataset[2].rating*NB
totalrating = totalrating+MountainDataset[3].rating*WR
totalrating = totalrating+MountainDataset[4].rating*TP
totalrating = totalrating+MountainDataset[5].rating*MW
totalrating = totalrating+MountainDataset[6].rating*PP
totalrating = totalrating+ParkDataset[0].rating*SNF
totalrating = totalrating+ParkDataset[1].rating*BTF
totalrating = totalrating+ParkDataset[2].rating*GTP
totalrating = totalrating+ParkDataset[3].rating*YNP

totaldifficulty = totaldifficulty+MountainDataset[0].time*CM
totaldifficulty = totaldifficulty+MountainDataset[1].time*GT
totaldifficulty = totaldifficulty+MountainDataset[2].time*NB
totaldifficulty = totaldifficulty+MountainDataset[3].time*WR
totaldifficulty = totaldifficulty+MountainDataset[4].time*TP
totaldifficulty = totaldifficulty+MountainDataset[5].time*MW
totaldifficulty = totaldifficulty+MountainDataset[6].time*PP
totaldifficulty = totaldifficulty+ParkDataset[0].time*SNF
totaldifficulty = totaldifficulty+ParkDataset[1].time*BTF
totaldifficulty = totaldifficulty+ParkDataset[2].time*GTP
totaldifficulty = totaldifficulty+ParkDataset[3].time*YNP
return [totalrating,totaldifficulty]
}
Insert cell
calculatedValues[0]
Insert cell
staricon = {

const width = 90,
height = 60;
const svg = d3.create("svg")
.attr("viewBox", [-40, -30, width, height]);

var p = svg.selectAll("polyline")
.data(star)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('points',function(d){return d})
.style('fill','yellow')
.style('stroke','black')
.style('stroke-width','0.5')

return svg.node();
}
Insert cell
star = FileAttachment("star.txt").tsv({array:true})
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