Public
Edited
Mar 19, 2023
Insert cell
# Portland Kidnap Map March 11- Mariam Shared
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


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 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')
g.selectAll("path3") //d3 geopath
.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')
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')
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')
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')
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')
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')
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", "none")
.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(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", '2')
.attr('stroke-opacity', '1')

var p = svg.selectAll('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

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