Public
Edited
Mar 28, 2023
1 star
Insert cell
# Portland Kidnap Map March 11- Mariam Shared - fleet updated
Insert cell
stein_outline1 = FileAttachment("icon_test.txt").text()
Insert cell
portlandBoundary = FileAttachment("Portland Boundary.geojson").json()
Insert cell
sideWater = FileAttachment("side water.geojson").json()
Insert cell
water = FileAttachment("water@1.geojson").json()
Insert cell
d3 = require("d3@6")
Insert cell
viewof pages = Inputs.radio(['Home', 'Profile', 'First Clue','Main Game'], {label: "", value:'Home'})
Insert cell
iconLocations = {

var combined = []
//var scaleFac = .5

for (let i = 0; i < locs.length; i++) {


combined.push({lat:locs[i].latitude,long:locs[i].longitude,outline:stein_outline1})
}
return combined

}
Insert cell


chart = {
const width = 700,
height = 600;
const svg = d3.create("svg")
.attr("viewBox", [50, 50, width-120, height-100]);

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

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

var g = svg.append("g").attr("id", "paths");
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','.5')
.style("stroke-width", '.2')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2") //d3 geopath
.data(highwaylines.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", '2')
.style("stroke", "palevioletred")

g.selectAll("path3") //d3 geopath
.data(portlandBoundary.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", "floralwhite")
.style("fill-opacity", '.2')
.style('stroke-opacity','.6')
.style("stroke-width", '1')
.style("stroke", "rgb(119,94,148)")

g.selectAll("path3") //d3 geopath
.data(parks.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", "mediumvioletred")
.style("fill-opacity", ".5")
.style('stroke-opacity','1')
.style("stroke-width", '.6')
.style("stroke", "lightslategrey")

g.selectAll("path3") //d3 geopath
.data(water.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", "teal")
.style("fill-opacity", ".5")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "lightslategrey")

g.selectAll("path3") //d3 geopath
.data(sideWater.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", "slategrey")
.style("fill-opacity", ".05")
.style('stroke-opacity','.1')
.style("stroke-width", '.1')
.style("stroke", "black")

g.selectAll("path2") //d3 geopath
.data(ferryline.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", '2')
.style("stroke", "blueviolet")
.style('stroke-dasharray','2 2')


var p = svg.selectAll('polyline')
.data(iconLocations) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d.outline})
.style("fill", "teal")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "deeppink")
.attr("transform", moveIcons)

//this function to be used to move each polyline into place
function moveIcons(d,i){
var xVal = projection([d.long, d.lat])[0]
var yVal = projection([d.long, d.lat])[1]

return "translate("+xVal+" "+yVal+")"
}

/*
var c = svg.selectAll("circle") //d3 geopath
.data(locs)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return projection([d.longitude, d.latitude])[0]})
.attr("cy", function(d) {return projection([d.longitude, d.latitude])[1]})
.attr('r',4)
.attr('fill',colorType)
.style('fill-opacity','2')
.style('stroke','darkviolet')
.style('stroke-width','1')
.on('mouseover', spotText)
.on('mouseout', removespotText)
*/
function colorType(d,i){
var color = 'gold'
if(d.type=='morgue'){color = 'gold'}
if(d.type=='house'){color = 'gold'}
if(d.type=='house'){color = 'gold'}
if(d.type=='house'){color = 'gold'}
if(d.type=='saloon'){color = 'gold'}
if(d.type=='scow'){color = 'gold'}
return color

}
function spotText(event,d){
d3.select(this).attr('fill','mediumslateblue')
.attr('r', 6)
.style('stroke', 'mediumslateblue')
.style("stroke-opacity",'.5')
.style("stroke-width", '5')
svg.append('text')
.attr('class','spots')
.attr('x', '340')
.attr('y','320')
.attr('font-family','Helvetica')
.attr('font-size', '.7em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text(d.name)

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

svg.append('line')
.attr('class','spotLine')
.attr('x1', '340')
.attr('y1', '318')
.attr('x2', projection([d.longitude, d.latitude])[0])
.attr('y2', '318')
.style('stroke-width','.5')
.style('stroke','black')
.style('stroke-dasharray','2 2')
svg.append('line')
.attr('class','spotLine')
.attr('x1', projection([d.longitude, d.latitude])[0])
.attr('y1', '318')
.attr('x2', projection([d.longitude, d.latitude])[0])
.attr('y2', projection([d.longitude, d.latitude])[1])
.style('stroke-width','.7')
.style('stroke','darkblue')
.style('stroke-dasharray','2 2')
}
function removespotText(event,d){
d3.select(this).attr('fill',colorType)
d3.select(this).attr('r', 4)
d3.select(this).style('stroke-opacity','.65')
d3.select(this).style('stroke-width', '1')
d3.selectAll('text.spots').remove()
d3.selectAll('line.spotLine').remove()
}



return svg.node();
}


Insert cell
villains = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


var g = svg.append("g").attr("id", "paths");
svg.append('image')
.attr('href',jamesTurk)
.attr('class','spotImage')
.attr('x', '510')
.attr('y','90')
.attr('width', 90)
.attr('height', 140)
.on('mouseover', spotProfile1)
.on('mouseout', removespotProfile)

svg.append('image')
.attr('href',bridgetGrant)
.attr('class','spotImage')
.attr('x', '610')
.attr('y','90')
.attr('width', 90)
.attr('height', 140)
.on('mouseover', spotProfile2)
.on('mouseout', removespotProfile)

svg.append('image')
.attr('href',larrySullivan)
.attr('class','spotImage')
.attr('x', '710')
.attr('y','90')
.attr('width', 90)
.attr('height', 140)
.on('mouseover', spotProfile3)
.on('mouseout', removespotProfile)

svg.append('image')
.attr('href',buncoKelly)
.attr('class','spotImage')
.attr('x', '820')
.attr('y','90')
.attr('width', 90)
.attr('height', 140)
.on('mouseover', spotProfile)
.on('mouseout', removespotProfile)

function spotProfile(i,d){
d3.select(this).attr('fill','lavenderblush')

svg.append("rect")
.attr('class','whitebox')
.attr("x", 150)
.attr("y", 100)
.attr("height", 154)
.attr("width", 300)
.attr('stroke','gold')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')
.style("fill", 'white');

svg.append('image')
.attr('href',joeBuncoKelly)
.attr('class','spotProfile')
.attr('x', '1150')
.attr('y','103')
.attr('width', 300)
.attr('height', 150)
}



function spotProfile1(i,d){
d3.select(this).attr('fill','lavenderblush')

svg.append("rect")
.attr('class','whitebox')
.attr("x", 150)
.attr("y", 100)
.attr("height", 154)
.attr("width", 2500)
.attr('stroke','gold')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')
.style("fill", 'white');

svg.append('image')
.attr('href',jamesTurkProfile)
.attr('class','spotProfile1')
.attr('x', '155')
.attr('y','103')
.attr('width', 295)
.attr('height', 145)
}
/*
function removespotProfile1(event,d){
d3.select(this).attr('fill',colorType)
d3.selectAll('image.spotProfile1').remove()
d3.selectAll('rect.whitebox').remove()
}
*/
function spotProfile2(event,d){
d3.select(this).attr('fill','lavenderblush')

svg.append("rect")
.attr('class','whitebox')
.attr("x", 150)
.attr("y", 100)
.attr("height", 154)
.attr("width", 300)
.attr('stroke','gold')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')
.style("fill", 'white');

svg.append('image')
.attr('href',grantProfile)
.attr('class','spotProfile2')
.attr('x', '155')
.attr('y','103')
.attr('width', 295)
.attr('height', 145)
}
/*
function removespotProfile2(event,d){
d3.select(this).attr('fill',colorType)
d3.selectAll('image.spotProfile2').remove()
d3.selectAll('rect.whitebox').remove()
}
*/
function spotProfile3(event,d){
d3.select(this).attr('fill','lavenderblush')

svg.append("rect")
.attr('class','whitebox')
.attr("x", 150)
.attr("y", 100)
.attr("height", 154)
.attr("width", 300)
.attr('stroke','gold')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')
.style("fill", 'white');

svg.append('image')
.attr('href',larryProfile)
.attr('class','spotProfile3')
.attr('x', '155')
.attr('y','103')
.attr('width', 295)
.attr('height', 145)
}
/*
function removespotProfile3(event,d){
d3.select(this).attr('fill',colorType)
d3.selectAll('image.spotProfile3').remove()
d3.selectAll('rect.whitebox').remove()
}
*/

function removespotProfile(i,d){

d3.selectAll('image.spotProfile').remove()
d3.selectAll('image.spotProfile1').remove()
d3.selectAll('image.spotProfile2').remove()
d3.selectAll('image.spotProfile3').remove()
d3.selectAll('rect.whitebox').remove()
}



return svg.node();
}
Insert cell
frame = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


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

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(footstepsBorder1) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "deeppink")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(footstepsBorder2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "deeppink")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(footstepsBorder3) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "deeppink")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(timerBorder) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '3')
.style("stroke", "deeppink")

return svg.node();
}
Insert cell
Insert cell
rectangle = {
const svg = d4.create("svg")
svg.append("rect")
.attr('class','whitebox')
.attr("height", 350)
.attr("width", 200)
.style("fill", "snow")
.attr('fill-opacity', '1')
.attr('stroke','rosybrown')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')


return svg.node();
}
Insert cell
bool = {
var page = homepage1

if (pages == 'Profile') {page = profilepage}
else if (pages == 'First Clue') {page = intropage}
else if (pages == 'Main Game') {page = maingamepage}

return page
}
Insert cell
dashboard =
html`

<!-- This sets the page. Because of the number of elements on the main game page it makes more sense to have that as a single cell that can be chosen by the boolean above, put main game things in the maingamepage html -->


<div class='dashboardOuter' style='height:800px;width:1200px'>
<div class='border' style='position:absolute;width:1160px;top:0px;left:0px'>
${bool}
</div>



<!-- This is the place for persistent elements, ones that show on every page-->




<div class='pages' style='position:absolute;width:400px;top:40px;left:40px'>
${viewof pages}
</div>




`
Insert cell
maingamepage =
html`



<div class='dashboardOuter' style='height:800px;width:1200px'>
<div class='border' style='position:absolute;width:1160px;top:0px;left:0px'>
${border}
</div>

<div class='whole' style='position:absolute;width:1160px;top:0px;left:0px'>
${frame}
</div>

<div class='profile' style='position:absolute;top:175px;left:85px;font-family:Helvetica;font-size:12px;font-weight:bold'>
${md`The Investigator`}
</div>
<div class='map' style='position:absolute;width:685px;top:95px;left:238px'>
${chart}
</div>

<div class='map' style='position:absolute;width:200px;height:350px;top:490px;left:700px'>
${rectangle}
</div>

<div class='border' style='position:absolute;width:200px;top:500px;left:700px'>
${smallmap}
</div>




<div class='starttime Button' style='position:absolute;width:200px;top:35px;left:535px'>
${viewof startTimerButton}
</div>
<div class='time' style='position:absolute; width:200px;top:3px;left:547px'>
${time}
</div>

<div class='villains' style='position:absolute; width:400px;top:55px;left:790px'>
${villains}
</div>

<div class='clue' style='position:absolute;width:50px;top:205px;left:129px;font-family:Helvetica;font-size:12px;font-weight:bold;color:deeppink'>
${md`Clue #1`}
</div>
<div class='clue' style='position:absolute;width:50px;top:225px;left:85px;font-family:TimesNewRoman;font-size:12px;font-weight:bold'>
${md`“Bars, food, and shows; oh the fun you could have! Along this popular strip, now referred to as 2nd Ave.”`}
</div>

<div class='clue' style='position:absolute;top:324px;left:99px;font-family:Helvetica;font-size:12px;font-weight:bold;color:deeppink'>
${md`Clue #2`}
</div>
<div class='clue' style='position:absolute;top:344px;left:57px;font-family:TimesNewRoman;font-size:12px;font-weight:bold'>
${md`“The owner himself may have a month for a name. Beyond these walls you’ll find many a drinking game.”`}
</div>

<div class='clue' style='position:absolute;top:450px;left:129px;font-family:Helvetica;font-size:12px;font-weight:bold;color:deeppink'>
${md`Clue #3`}
</div>


<div class='clue' style='position:absolute;top:600px;left:98px;font-family:Helvetica;font-size:12px;font-weight:bold;color:deeppink'>
${md`Clue #4`}
</div>


`



Insert cell
Insert cell
Insert cell
border = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


var g = svg.append("g").attr("id", "paths");
var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(colorUnderlay) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "peachpuff")
.style("fill-opacity", '.4')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(mapFrame1) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "rbg(87,52,11)")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "rosybrown")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(mapFrame2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "rbg(87,52,11)")
.style("fill-opacity", '1')
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "rosybrown")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(portlandtittle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1.2')
.style("stroke", "teal")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(kidnapstitle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "mediumvioletred")
var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(lTitle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "darkturquoise")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(paTitle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "orange")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(onTitle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "dodgerblue")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(rdTitle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "deeppink")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(rectCharacter) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "snow")
.style('stroke-opacity','1')
.style("stroke-width", '2.5')
.style("stroke", "teal")

/* var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(targetCircle) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "firebrick")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(peopleBorder) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "deeppink")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(clueBorder) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "teal")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(targetLine1) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "firebrick")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(targetLine2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "firebrick")
*/

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(profileBorder) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "black")

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(footsteps) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '.5')



return svg.node();
}
Insert cell
Insert cell
mutable stops = 0
Insert cell
viewof seconds = Inputs.range([0, 59], {value: 0, step:1, label: "seconds"})
Insert cell
viewof minutes = Inputs.range([0, 59], {value: 0, step:15, label: "minutes", value:2})
Insert cell
hours = 0
Insert cell
function* timer(i = 0) {
yield i;
while (true) {
yield Promises.tick(1000).then(() => i++);
}
}
Insert cell
currentTime = {
if(startTimerButton>0){
return timer();
}else{mutable stops = 0}
}
Insert cell
countdownTime = {
return minutes*60 + seconds;
}
Insert cell
//mutable timesup = 0
Insert cell
time = {
let result = countdownTime - currentTime;
if (currentTime == undefined){result = 0}
if ( result < 0 )
result = "Time Up!";
else {
const remainHours = ""+parseInt(result/3600);
result = result - remainHours*3600;
const remainMinutes = ""+parseInt(result/60);
const remainSeconds = ""+parseInt(result%60);
result = remainMinutes.padStart(2,"0") + ":" +
remainSeconds.padStart(2,"0") ;
}

return html`
<style>
.countdown{ font-size: 23px;font-family:helvetica;font-weight:600; color: teal }
</style>
<span class="countdown">${result}</span>
`
}
Insert cell
viewof startTimerButton = Inputs.button([
["Start", value => value + 1],
["Reset", value => 0]
], {value: 0})

Insert cell
Insert cell
homepage1 = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


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

svg.append('text')
.attr('class','spots')
.attr('x', '390')
.attr('y','660')
.attr('font-family','Helvetica')
.attr('font-size', '.6em')
.attr('text.anchor','middle')
.attr('font-weight', 'bold')
.text('Learn More Here!')
.on('click', Learnmore)
function Learnmore(event,d){
window.open("https://www.oregonencyclopedia.org/articles/shanghai_tunnels_myth/#.Y_XqE3bMJD8");
}


svg.append('image')
.attr('href',buncoVillain)
.attr('class','spotImage')
.attr('x', '760')
.attr('y','450')
.attr('width', 140)
.attr('height', 290)

svg.append('image')
.attr('href',turkVillain)
.attr('class','spotImage')
.attr('x', '750')
.attr('y','140')
.attr('width', 160)
.attr('height', 320)

svg.append('image')
.attr('href',KidnapNews)
.attr('class','spotImage')
.attr('x', '295')
.attr('y','220')
.attr('width', 290)
.attr('height', 430)

svg.append('image')
.attr('href',kidnapBoatpic)
.attr('class','spotImage')
.attr('x', '590')
.attr('y','453')
.attr('width', 160)
.attr('height', 310)

svg.append('image')
.attr('href',kidnapPic)
.attr('class','spotImage')
.attr('x', '623')
.attr('y','217')
.attr('width', 80)
.attr('height', 160)

svg.append('image')
.attr('href',tunnelPic)
.attr('class','spotImage')
.attr('x', '740')
.attr('y','355')
.attr('width', 140)
.attr('height', 170)
var p = svg.selectAll('polyline')

g.selectAll("path3") //d3 geopath
.data(homepageRect) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "cadetblue")
.style("fill-opacity", '1')
.attr('stroke','rosybrown')
.attr("stroke-width", '4')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
//svg.append("polyline")
.data(welcomeRect) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','deeppink')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(welcome) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','snow')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(welcomeO) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','snow')
.attr("stroke-width", '2FileAttachment("image@1.png").image()')
.attr('stroke-opacity', '1')


//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(missingclue) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "linen")
.style("fill-opacity", '1')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')


//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(questionMark2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "none")
.style("fill-opacity", '1')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(questionMark1) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','teal')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(pins) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "Deeppink")
.style("fill-opacity", '.35')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')


//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(targetX) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','maroon')
.attr("stroke-width", '4')
.attr('stroke-opacity', '1')

//var p = svg.selectAll('polyline')
p.enter().append("polyline")
//g.selectAll("path3") //d3 geopath
.data(tape) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "beige")
.style("fill-opacity", '1')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')



return svg.node();
}
Insert cell
buncoVillain = FileAttachment("image@1.png").url()
Insert cell
turkVillain = FileAttachment("image@2.png").url()
Insert cell
tunnelPic = FileAttachment("image@3.png").url()
Insert cell
KidnapNews = FileAttachment("image@4.png").url()
Insert cell
kidnapPic = FileAttachment("image@5.png").url()
Insert cell
kidnapBoatpic = FileAttachment("image@6.png").url()
Insert cell
targetX = FileAttachment("target X.txt").tsv({array:true})
Insert cell
pins = FileAttachment("pins.txt").tsv({array:true})
Insert cell
questionMark1 = FileAttachment("question mark 1.txt").tsv({array:true})
Insert cell
questionMark2 = FileAttachment("question mark 2.txt").tsv({array:true})
Insert cell
missingclue = FileAttachment("missingclue.txt").tsv({array:true})
Insert cell
tape = FileAttachment("Tape.txt").tsv({array:true})
Insert cell
welcomeO = FileAttachment("welcome O.txt").tsv({array:true})
Insert cell
welcomeRect = FileAttachment("Welcome Rect.txt").tsv({array:true})
Insert cell
welcome = FileAttachment("welcome.txt").tsv({array:true})
Insert cell
homepageRect = FileAttachment("Homepage rect.txt").tsv({array:true})
Insert cell
Insert cell
profilepage = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


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

/*
var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(combinedData) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "cadetblue")
.style("fill-opacity", '1')
.attr('stroke','rosybrown')
.attr("stroke-width", '4')
.attr('stroke-opacity', '1')
*/

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(profilePageRect) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "cadetblue")
.style("fill-opacity", '1')
.attr('stroke','rosybrown')
.attr("stroke-width", '4')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(profileTextframe) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','deeppink')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')


var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorText) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorText2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','black')
.attr("stroke-width", '1')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorProfile) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','snow')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorProfile2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','snow')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorQuestionmark) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','snow')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

svg.append('text')
.attr('class','layersText')
.attr('x', '540')
.attr('y','560')
.attr('font-family','Helvetica')
.attr('font-size', '.7em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.style("fill", "mistyrose")
.text('Portlands finest inspector')

svg.append('text')
.attr('class','layersText')
.attr('x', '540')
.attr('y','575')
.attr('font-family','Helvetica')
.attr('font-size', '.7em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.style("fill", "mistyrose")
.text('is set out to take down the')

svg.append('text')
.attr('class','layersText')
.attr('x', '540')
.attr('y','590')
.attr('font-family','Helvetica')
.attr('font-size', '.7em')
.attr('text.anchor','start')
.attr('font-weight', 'light')
//.style('width', '15px')
.style("fill", "mistyrose")
.text('toughest abductors in town')

svg.append('text')
.attr('class','layersText')
.attr('x', '530')
.attr('y','155')
.attr('font-family','Helvetica')
.attr('font-size', '1em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.style("fill", "pink")
.text('Player Profile')

return svg.node();
}
Insert cell
combinedData={
var locations = []

for(let i=0;i<locs.length;i++){

locations.push({lat:locs[i].latitude,long:locs[i].longitude, shape:investigatorProfile})
}
return locations
}
//loop through spreadsheet
//create a new object

//eachtime we loop through, we will add an object w/ a lat, long, and investigator profile
Insert cell
investigatorProfile = FileAttachment("Investigator profile.txt").tsv({array:true})
Insert cell
investigatorProfile2 = FileAttachment("Investigator profile 2.txt").tsv({array:true})
Insert cell
investigatorText2 = FileAttachment("Investigator text 2.txt").tsv({array:true})
Insert cell
investigatorText = FileAttachment("Investigator text.txt").tsv({array:true})
Insert cell
profilePageRect = FileAttachment("Profile page rect.txt").tsv({array:true})
Insert cell
investigatorQuestionmark = FileAttachment("investigator questionmark.txt").tsv({array:true})
Insert cell
profileTextframe2 = FileAttachment("profile textframe 2.txt").tsv({array:true})
Insert cell
profileTextframe = FileAttachment("profile textframe.txt").tsv({array:true})
Insert cell
Insert cell
intropage = {
const width = 1200,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);


var g = svg.append("g").attr("id", "paths");
var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(introClueRect) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "cadetblue")
.style("fill-opacity", '1')
.attr('stroke','rosybrown')
.attr("stroke-width", '4')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(profileTextframe2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','deeppink')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(investigatorTinyprofile) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '.8')
.attr('stroke','teal')
.attr("stroke-width", '1')
.attr('stroke-opacity', '.5')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(magnifyingGlass1) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "teal")
.style("fill-opacity", '1')
.attr('stroke','deeppink')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

var p = svg.selectAll('polyline')
g.selectAll("path3") //d3 geopath
.data(magnifyingGlass2) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline') //appends path to data
.attr('class','outlines')
.attr('points', function(d) {return d})
.style("fill", "deeppink")
.style("fill-opacity", '1')
.attr('stroke','cadetblue')
.attr("stroke-width", '2')
.attr('stroke-opacity', '1')

svg.append('text')
.attr('class','layersText')
.attr('x', '440')
.attr('y','360')
.attr('font-family','Helvetica')
.attr('font-size', '1em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.style("fill", "mistyrose")
.text('Insert intro clue here')

svg.append('text')
.attr('class','layersText')
.attr('x', '440')
.attr('y','215')
.attr('font-family','Helvetica')
.attr('font-size', '1em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.style("fill", "mistyrose")
.text('Catch the abductor before time runs out!')

svg.append('text')
.attr('class','layersText')
.attr('x', '390')
.attr('y','215')
.attr('font-family','Helvetica')
.attr('font-size', '1em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.style("fill", "pink")
.text('Goal:')
svg.append('text')
.attr('class','layersText')
.attr('x', '390')
.attr('y','255')
.attr('font-family','Helvetica')
.attr('font-size', '1em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.style("fill", "pink")
.text('Here is Your 1st Clue...')


return svg.node();
}
Insert cell
magnifyingGlass2 = FileAttachment("magnifying glass 2.txt").tsv({array:true})
Insert cell
magnifyingGlass1 = FileAttachment("magnifying glass 1.txt").tsv({array:true})
Insert cell
introClueRect = FileAttachment("Intro clue rect.txt").tsv({array:true})
Insert cell
investigatorTinyprofile = FileAttachment("investigator tinyprofile.txt").tsv({array:true})
Insert cell
Insert cell
buttons = {

function layersClick(event,d){
console.log(d)

var currentPage
if(buttons == 'Home'){
currentPage = html`
<div class='homepage' style='padding-top:25px'>
${homepage1}
</div>
`
}
if(buttons == 'Profile'){
currentPage = html`
<div class='profile' style='padding-top:25px'>
${profilepage}
</div>
`
}

if(buttons == 'First Clue'){
currentPage = html`
<div class='intropage' style='padding-top:25px'>
${intropage}
</div>
`
}

if(buttons == 'Main Game'){
currentPage = html`
<div class='chart' style='padding-top:25px'>
${chart}
</div>
`
}

return currentPage
}
Insert cell
Insert cell
*/ svg_embed = svg`<svg width=300 height=200 xmlns="http://www.w3.org/2000/svg">
<style>
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: url(${await toDataURL('https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6M-Bp0u-.woff')}) format('woff'), url(${await toDataURL('https://rawcdn.githack.com/google/fonts/e9c0bd/ofl/pacifico/Pacifico-Regular.ttf')}) format('truetype');
}
rect { fill: lightsalmon }
text {
font-size: 40px;
font-family: Pacifico;
fill: black;
}
</style>
<rect x=0 y=0 width=300 height=200 />
<text x=35 y=100>Well, hello!</text>
</svg> /*
Insert cell
whitebox = FileAttachment("1280px-White_box_55x90.png").image()
Insert cell
test = FileAttachment("test.txt").tsv({array:true})
Insert cell
footsteps = FileAttachment("Footsteps@1.txt").tsv({array:true})
Insert cell
targetLine1 = FileAttachment("target line1.txt").tsv({array:true})
Insert cell
targetLine2 = FileAttachment("target line2.txt").tsv({array:true})
Insert cell
profileBorder = FileAttachment("profile border@1.txt").tsv({array:true})
Insert cell
clueBorder = FileAttachment("clue border.txt").tsv({array:true})
Insert cell
peopleBorder = FileAttachment("people border.txt").tsv({array:true})
Insert cell
rectCharacter = FileAttachment("rect character.txt").tsv({array:true})
Insert cell
targetCircle = FileAttachment("target circle@1.txt").tsv({array:true})
Insert cell
footstepsBorder3 = FileAttachment("Footsteps border3.txt").tsv({array:true})
Insert cell
timerBorder = FileAttachment("timer border.txt").tsv({array:true})
Insert cell
rectBorder = FileAttachment("rect border.txt").tsv({array:true})
Insert cell
footstepsBorder1 = FileAttachment("Footsteps border1.txt").tsv({array:true})
Insert cell
footstepsBorder2 = FileAttachment("Footsteps border2.txt").tsv({array:true})
Insert cell
highwaylines = FileAttachment("HighwayLines.geojson").json()
Insert cell
kidnapstitle = FileAttachment("kidnapstitle.txt").tsv({array:true})
Insert cell
lTitle = FileAttachment("L title.txt").tsv({array:true})
Insert cell
onTitle = FileAttachment("ON title.txt").tsv({array:true})
Insert cell
paTitle = FileAttachment("PA title.txt").tsv({array:true})
Insert cell
rdTitle = FileAttachment("RD title.txt").tsv({array:true})
Insert cell
portlandtittle = FileAttachment("PortlandTittle@1.txt").tsv({array:true})
Insert cell
mapFrame2 = FileAttachment("Map Frame2.txt").tsv({array:true})
Insert cell
mapFrame1 = FileAttachment("Map Frame1@1.txt").tsv({array:true})
Insert cell
colorUnderlay = FileAttachment("Color underlay.txt").tsv({array:true})
Insert cell
mapFrame = FileAttachment("Map Frame.txt").tsv({array:true})
Insert cell
image = FileAttachment("image.png").url()
Insert cell
allRoutes = FileAttachment("all routes@4.geojson").json()
Insert cell
bridgetGrant = FileAttachment("Bridget Grant PNG 2.png").url()
Insert cell
buncoKelly = FileAttachment("Bunco Kelly PNG 2.png").url()
Insert cell
jamesTurk = FileAttachment("James Turk png 2.png").url()
Insert cell
larrySullivan = FileAttachment("Larry Sullivan PNG 2.png").url()
Insert cell
larryProfile = FileAttachment("Larry profile.png").url()
Insert cell
grantProfile = FileAttachment("Grant profile.png").url()
Insert cell
jamesTurkProfile = FileAttachment("James Turk profile.png").url()
Insert cell
joeBuncoKelly = FileAttachment("Joe Bunco kelly@1.png").url()
Insert cell
buncoEstablishment = FileAttachment("Bunco-s establishment.PNG").url()
Insert cell
sailorBoardinghouses = FileAttachment("Sailor-s boardinghouses.PNG").url()
Insert cell
turkSailorsBoardinghouses = FileAttachment("Turk-s sailors boardinghouses.PNG").url()
Insert cell
import {skullTest} from "@mariamth/shanghai"
Insert cell
Insert cell
locs = d3.csv(locslink, d3.autoType)
Insert cell
bbox = FileAttachment("BBox@2.geojson").json()
Insert cell
streets = FileAttachment("Streets@1.geojson").json()
Insert cell
parks = FileAttachment("parks@2.geojson").json()
Insert cell
pdcBase = FileAttachment("pdc base.geojson").json()
Insert cell
ferryline = FileAttachment("Ferryline.geojson").json()
Insert cell
import {map} with {projection, outline} from "@d3/world-map"
Insert cell
d4 = require("d3@6", "d3-geo-projection@3")
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