Public
Edited
Apr 6, 2023
Insert cell
# 230405_Punk The Stasi overhaul - fleet edit + new fixes
Insert cell
d3 = require("d3@6")
Insert cell
concertSTOPS = FileAttachment("concertnight_003.csv").csv()
Insert cell
ampelmann = FileAttachment("ampelmaennchen.txt").tsv({array:true})
Insert cell
viewof stops2 = Inputs.radio(["0", "1", "2", "3"], {value:"0"})
Insert cell
border_01 = FileAttachment("border_01.png").url()
Insert cell
border_02 = FileAttachment("border_02@1.png").url()
Insert cell
border_03 = FileAttachment("border_03.png").url()
Insert cell
border_04 = FileAttachment("border_04.png").url()
Insert cell
stops
Insert cell
dashboard =

html`
<div class='outer' style='width:650px;height:750px'>

<div class='chart' style='position:absolute;top:55px;left:280px;width:860px'>
${chart}
</div>


<img src="${border_02}" style="position:absolute;top:0px;left:0px;width: 1200px"/>
<img src="${border_04}" style="position:absolute;top:624px;left:0px;width: 1200px"/>
<img src="${border_03}" style="position:absolute;top:0px;left:1065px;height: 750px"/>
<img src="${border_01}" style="position:absolute;top:0px;left:0px;height: 750px"/>


<div class='pageDisplay' style='position:absolute;width:800px;top:665px;left:250px;font-family:helvetica;font-size:16px;font-weight:400'>
${pageDisplay}
</div>



<div class='time' style='position:absolute;width:200px;top:630px;left:60px;font-family:helvetica;font-size:16px;font-weight:500'>
${time}
${viewof startTimerButton}
</div>



</div>


`
Insert cell
pageDisplay = {

//this cell controls the content that goes into the dashboard depending on my 'stops' radio button
var currentPage
if(stops == "0"){//this is the initial step of the gam
currentPage = html`

${concertSTOPS[stops].message}
${viewof gobutton}
`
set(viewof eyesOnly,"i don't know what that means")
}

if(stops == "1"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof initial}
`
set(viewof caughtresponse,"I've had enough of the daredevil life")
}

/*
if(stops == "BR"){
//have the br question, or some question on the way to br
}
*/

/*
if(stops == "BH"){
//have the berghaim question, or some question on the way to br
}


if(stops == "2"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof parkStop}
`
set(viewof initial,"thinking...")
}



if(stops == "3"){
currentPage = html`
${concertSTOPS[stops].prompt}//question from sheets file
${viewof eyesOnly}//this is the input, it contains the answers to the question
`
set(viewof parkStop,"thinking.....")// reset the previous input to a neutral value(you don't want the input to remain on the correct value)
}

*/


if(stops == "2"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof hotel}
`
set(viewof infoRV,"Who cares?")
}

if(stops == "3"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof golf}
`
set(viewof infoSUP,"Who cares?")
}

if(stops == "4"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof charlie}
`
set(viewof infoBERG,"Who cares?")
}

if(stops == "5"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof delta}
`
set(viewof infoSCHOKO,"Who cares?")
}


if(stops == "6"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof hotel}
`
set(viewof infoDUN,"Who cares?")
}


if(stops == "7"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof echo}
`
set(viewof infoFRANNZ,"Who cares?")
}

if(stops == "8"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof bravo}
`
set(viewof infoRR,"Who cares?")
}

if(stops == "9"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoBERG}
`
set(viewof initial,"thinking...")
}

if(stops == "10"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoSUP}
`
set(viewof charlie,"Hmmm...")
}
if(stops == "11"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoRV}
`
set(viewof charlie,"Hmmm...")
}


if(stops == "12"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoRVSP}
`
set(viewof foxtrot,"Hmmm...")
}


if(stops == "13"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoRR}
`
set(viewof initial,"Hmmm...")
}


if(stops == "14"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoSCHOKO}
`
set(viewof bravo,"Hmmm...")
}


if(stops == "15"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoFRANNZ}
`
set(viewof bravo,"Hmmm...")
}


if(stops == "16"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof infoDUN}
`
set(viewof echo,"Hmmm...")
}


if(stops == "17"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof caughtresponse}
`
set(viewof juliet,"Hmmm...")
}

if(stops == "18"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof caughtresponse}
`
set(viewof delta,"Hmmm...")
}

if(stops == "19"){
currentPage = html`
${concertSTOPS[stops].message}
${viewof caughtresponse}
`
set(viewof hotel,"Hmmm...")
}








return currentPage
}
Insert cell
viewof gobutton = Inputs.button("Let the night begin!")
Insert cell
viewof initial = Inputs.radio(["How about Berghain?", "To Roadrunner's Paradise!","Hmmm..."], {})
Insert cell
viewof preBerghain = Inputs.radio(["Super excited for Berghain!", "Nervous...?"], {})
Insert cell
viewof choiceresponse = Inputs.radio(["The first one!", "Perhaps the second one?"], {})
Insert cell
viewof bravo = Inputs.radio(["Let's go to Schokoladen", "FRANNZ Club!", "Hmmm..."], {})
Insert cell
viewof charlie = Inputs.radio(["Rock & Viking Bar!", "Supamolly sounds good...", "Hmmm..."], {})
Insert cell
viewof delta = Inputs.radio(["Party's not over...to FRANNZ Club!", "Let's try to escape to the West", "Hmmm..."], {})
Insert cell
viewof echo = Inputs.radio(["Dunckerclub sounds like a plan", "Maybe we call it a night?", "Hmmm..."], {})
Insert cell
viewof foxtrot = Inputs.radio(["To Rock & Viking we go!", "I don't know...maybe we should head back?", "Hmmm..."], {})
Insert cell
viewof golf = Inputs.radio(["Let's go to Supamolly", "Shall we escape to West Berlin?", "Hmmm..."], {})
Insert cell
viewof hotel = Inputs.radio(["On to Rock & Viking!", "Let's head back to West Berlin","Let's hide out and think for a minute", "Hmmm..."], {})
Insert cell
viewof india = Inputs.radio(["Time to head back to West Berlin!", "Hmmm..."], {})
Insert cell
viewof juliet = Inputs.radio(["Let's try to hit up Dunckerclub", "I don't know, maybe we head back...", "Hmmm..."], {})
Insert cell
viewof infoBERG = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoSUP = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoRV = Inputs.radio(["Cool, good to know!", "who cares"], {})
Insert cell
viewof infoRVSP = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoRR = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoSCHOKO = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoFRANNZ = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof infoDUN = Inputs.radio(["Cool, good to know!", "Who cares?"], {})
Insert cell
viewof caughtresponse = Inputs.radio(["Damn, that's too bad... guess I'll try again?","I've had enough of the daredevil life"], {})
Insert cell
viewof okresponse = Inputs.radio(["Let's see if we can hit 3 concerts this time!","I've had enough of the daredevil life"], {})
Insert cell
viewof successresponse = Inputs.radio(["See you tomorrow night for another round?","I've had enough of the daredevil life"], {})
Insert cell
viewof eyesOnly = Inputs.select(responses, {})
Insert cell
responses = ["Sure, let's give it a go","Do you see a Stasi officer?","I am lost in Berlin"]
Insert cell
mutable stops = 0
Insert cell
viewof i = Inputs.input(100)
Insert cell
Inputs.bind(Inputs.radio([0, 100]), viewof i)
Insert cell
Inputs.bind(Inputs.radio([0, 100]), viewof i)
Insert cell
i
Insert cell
//set(i,0)
Insert cell
{

//this cell looks for correct answers from the input, and progresses to the next step when appropriate
if(gobutton==1){
mutable stops = 1 //change to next stop on the map3
set(viewof gobutton,0)//reset button
set(viewof initial,null)
}

if(initial == "How about Berghain?"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "9"
}

if(initial == "To Roadrunner's Paradise!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "13"
}


if(bravo == "Let's go to Schokoladen"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "14"
}
if(bravo == "FRANNZ Club!"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "15"
}



if(charlie == "Rock & Viking Bar!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "11"
}
if(charlie == "Supamolly sounds good..."){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "10"
}

if(delta == "Party's not over...to FRANNZ Club!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "18"
}
if(delta == "Let's try to escape to the West"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "21"
}

if(echo == "Dunckerclub sounds like a plan"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "16"
}
if(echo == "Maybe we call it a night?"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "20"
}

if(foxtrot == "To Rock & Viking we go!"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "12"
}

if(foxtrot == "I don't know...maybe we should head back?"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "24"
}


if(golf == "Let's go to Supamolly"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "12"
}

if(golf == "Shall we escape to West Berlin?"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "24"
}

if(hotel == "On to Rock & Viking!"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "19"
}

if(hotel == "Let's head back to West Berlin"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "20"
}

if(india == "Time to head back to West Berlin!"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "24"
}


if(juliet == "Let's try to hit up Dunckerclub"){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "17"
}

if(juliet == "I don't know, maybe we head back..."){//these if statements allow us to continue the game
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "24"
}













if(infoBERG == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "4"
}

if(infoSUP == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "3"
}

if(infoRV == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "2"
}

if(infoRVSP == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "19" // THIS IS WRONG - NEED TO SEPARATE THIS INTO SEPARATE MOVES FOR R&V AND SUPAMOLLY
}


if(infoRR == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "8"
}

if(infoSCHOKO == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "5"
}


if(infoFRANNZ == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "7"
}


if(infoDUN == "Cool, good to know!"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "6"
}

if(caughtresponse == "Damn, that's too bad... guess I'll try again?"){//these if statements allow us to move the game to the next location
//mutable stops = "BR" //if correct answer = bandito rosso, move to stop BR
mutable stops = "1"
}



/*
if(initial == "berghaim"){
//mutable stops = "BH"
}
*/

/*
if(postBerghaim == "prenzlauerberg"){
//mutable stops = "PB"
}
*/

/*
if(postBerghaim == "kreuzberg"){
//mutable stops = "KB"
}


if(parkStop == "I'm not so sure about this..."){
mutable stops = 3
}


*/
if(eyesOnly == "Do you see a Stasi officer?"){
mutable stops = 0
}





if(stops == "0"){
//viewof initial = Inputs.input("nice walk")
//set(viewof initial,null)
//set(viewof parkStop,null)
//set(viewof eyesOnly,null)
}

}
Insert cell
function set(input, value) {
input.value = value;
input.dispatchEvent(new Event("input", {bubbles: true}));
}
Insert cell
viewof seconds = Inputs.range([0, 59], {value: 0, step:1, label: "seconds"})
Insert cell
viewof minutes = Inputs.range([0, 59], {value: 2, step:1, 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: 40px;font-family:helvetica;font-weight:800 }
</style>
<span class="countdown">${result}</span>
`
}
Insert cell
viewof startTimerButton = Inputs.button([
["Start", value => value + 1],
["Reset", value => 0]
], {value: 0})
Insert cell
_berUpdatedDash3 = FileAttachment("230220_BER Updated Dash@3.png").image()
Insert cell
viewof choices = Inputs.radio(["Bandito Rosso", "SO36", "Dunckerclub"], {label: "Select a venue:", value: 0})
Insert cell
_berConcertChoice = FileAttachment("concert choice dash-04.png").image()
Insert cell
chart = {
const width = 400,
height = 350;
const svg = d3.create("svg")
.attr("viewBox", [5, 30, width-50, height-105]);

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

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 path5 = d3.geoPath().projection(projection);
var path6 = d3.geoPath().projection(projection);
var path7 = d3.geoPath().projection(projection);
var path8 = d3.geoPath().projection(projection);
var path9 = d3.geoPath().projection(projection);
var g = svg.append("g").attr("id", "paths");
//i'm not using the boundary lines, so I'm going to comment them out
/*
g.selectAll("path1") //d3 geopath
.data(boundary.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path1) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
*/


if(stops=="0"){
//then draw the first stop line segment
}
if(stops=="1"){
//then draw the first stop line segment
}


g.selectAll("path4") //d3 geopath
.data(BERwater.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", path4) //The d attribute defines a path to be drawn, only applies to appended elements
.style('fill', 'maroon')
.style("fill-opacity", ".3")
.style('stroke-opacity','.7')
.style("stroke-width", '.1')
.style('stroke', 'rosybrown')

g.selectAll("path6") //d3 geopath
.data(BERwall.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", path4) //The d attribute defines a path to be drawn, only applies to appended elements
.style('stroke-opacity','.7')
.style("stroke-width", '.5')
.style('stroke', 'firebrick')
.style('fill', 'lightblue')
.style("fill-opacity", "0")



g.selectAll("path7") //d3 geopath
.data(BERbuildings.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', 'tan')
.style("fill-opacity", ".5")
.style('stroke-opacity','.5')
.style("stroke-width", '.1')
.style('stroke', 'darkred')


/*
g.selectAll("path5") //d3 geopath
.data(BERroads.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','.4')
.style("stroke-width", '.3')
.style('stroke', 'dodgerblue')

*/


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


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

if(d.Sector=='east'){color = 'maroon'}
if(d.Sector=='west'){color = 'lightslategrey'}

return color
}

function spotText(event,d){
d3.select(this)
.attr('fill',colorType)
.attr('r', 5)
.style('stroke', 'pink')
.style("stroke-opacity",'.65')
.style("stroke-width", '.3')



svg.append("rect")
.attr('class','whitebox')
.attr("x", 65)
.attr("y", 127)
.attr("height", 21)
.attr("width", 59)
.attr('stroke','black')
.attr("stroke-width", '.5')
.attr('stroke-opacity', '.4')
.style("fill", 'white');

svg.append('text')
.attr('class','spots')
.attr('x','70')
.attr('y','135')
.attr('font-family','Helvetica')
.attr('font-size','.22em')
.attr('text-anchor','start')
.attr('font-weight','bold')
.text(d.Name)

svg.append('text')
.attr('class','spots')
.attr('x','70')
.attr('y','140')
.attr('font-family','Helvetica')
.attr('font-size','.15em')
.attr('text-anchor','start')
.attr('font-weight','normal')
.attr('font-style','italic')
.text(d.Neighborhood)

svg.append('text')
.attr('class','spots')
.attr('x','70')
.attr('y','143')
.attr('font-family','Helvetica')
.attr('font-size','.15em')
.attr('text-anchor','start')
.attr('font-weight','normal')
.attr('font-style','italic')
.text(d.ActivityType)

svg.append('line')
.attr('class','spotLine')
.attr('x1','124')
.attr('y1','137')
.attr('x2',projection([d.Long,d.Lat])[0])
.attr('y2','137')
.style('stroke-width','.3')
.style('stroke','black')
.style('stroke-dasharray','1 1')

svg.append('line')
.attr('class','spotLine')
.attr('x1',projection([d.Long,d.Lat])[0])
.attr('y1','137')
.attr('x2',projection([d.Long,d.Lat])[0])
.attr('y2',projection([d.Long,d.Lat])[1])
.style('stroke-width','.3')
.style('stroke','black')
.style('stroke-dasharray','1 1')





}
function removeSpotText(event,d) {
d3.select(this).attr('fill', colorType)
d3.select(this).attr('r', 3)
d3.select(this).style('stroke', 'pink')
d3.select(this).style('fill-opacity','1')
d3.select(this).style('stroke-opacity','.65')
d3.select(this).style('stroke-width', '.2')
d3.selectAll('text.spots').remove()
d3.selectAll('line.spotLine').remove()
d3.selectAll('rect.whitebox').remove()




var wrap = svg.selectAll("text.spots")
.each(function(d,i) {wrap_text(d3.select(this), 100) } );




}

/*

c.enter.append('circle')// format to add additional circles
.data(spots)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return projection([d.longitude,d.latitude])[0]})
.attr("cy", function(d) {return projection([d.longitude,d.latitude])[1]})
.attr('r',3)
.attr('fill','black')
.style('fill-opacity','1')

*/




function walkText(event,d){
d3.select(this).style("stroke-width", '3');
d3.select(this).style("stroke-dasharray", '4 0');

svg
.append('text')
.attr('class','walkText')
.attr('x','370')
.attr('y','385')
.attr("font-family", "Helvetica")
.attr('font-size','.75em')
.attr('fill','rgb(0,0,0)')
.attr('text-anchor','end')
//.attr('background-color', 'rgba(255, 0, 0)')
.text(d.properties.Text)

var wrap = svg.selectAll("text.walkText")
.each(function(d, i) { wrap_text(d3.select(this), 100) });
}

function walkErase(event,d){
d3.selectAll('path.walks').style('stroke-width','1')
d3.selectAll('path.walks').style('stroke-dasharray','4 2')
d3.selectAll('text.walkText').remove()
}

var p = svg.selectAll("polyline")
.data(ampelmann) //get data to define path
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('points', function(d){return d})
.style("fill", "black")
.style('stroke-opacity','0')
.style("stroke-width", '0')
.style("stroke", "rgb(0,0,0)")
.attr('transform',iconLocation)
function iconLocation(){
var xVal = projection([concertSTOPS[stops].Long,concertSTOPS[stops].Lat])[0]
var yVal = projection([concertSTOPS[stops].Long,concertSTOPS[stops].Lat])[1]

//console.log(xVal)
return "translate("+(xVal-5)+" "+(yVal+5)+")"
}

/*
svg
.append("image")
attr('x','0')
.attr('y','0')
.attr('width','100')
.attr('height','100')
.attr('href',tunnel)
*/

//if(showTunnels=="yes"){
var i = svg.selectAll("image")
.data(tunnelPng)//the key is that this dataset has both the image url and the lat/long
.enter()
.append("image")
.attr('x','0')
.attr('y','0')
.attr('width','14')
.attr('height','14')
.attr('href',function(d){return d.image})
.attr("transform", movePng)

function movePng(d,i){
var xVal = projection([d.Long, d.Lat])[0]-7
var yVal = projection([d.Long, d.Lat])[1]-7

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

}
//}

return svg.node();


}
Insert cell
paperDash = FileAttachment("230220_BER Updated Dash@1.png").image()
Insert cell
margin = ({top: 30, right: 20, bottom: 30, left: 40})
Insert cell
BERbuildings = FileAttachment("BER_buildingscropped_V2.geojson").json()
Insert cell
BERbox = FileAttachment("BER_bb.geojson").json()
Insert cell
BERwater = FileAttachment("BER_waterhatches_V1.geojson").json()
Insert cell
BERwall = FileAttachment("BER_wall.geojson").json()
Insert cell
Insert cell
Insert cell
tunnelPng = {//this cell combines the locations of the tunnels with the tunnel png.

var tunnelList = []
for (let i = 0; i < tunnelLoc.length; i++) {

tunnelList.push({Lat:tunnelLoc[i].Lat,Long:tunnelLoc[i].Long,type:"unclear",image:tunnel})
}


return tunnelList
}
Insert cell
import { wrap_text, wrap_text_nchar } from "@ben-tanen/svg-text-and-tspan-word-wrapping"
Insert cell
tooltip = d3
.select('body')
.append('div')
.attr('class', 'tooltip')
.style('position', 'absolute')
.style('z-index', '10')
.style('visibility', 'hidden')
.style('padding', '10px')
.style('background-color', 'white')
.style('border-radius', '4px')
.style('-webkit-border-radius', '10px')
.style('-moz-border-radius', '10px')
.style('-webkit-box-shadow', '4px 4px 10px rgba(0, 0, 0, 0.4)')
.style('-moz-box-shadow', '4px 4px 10px rgba(0, 0, 0, 0.4)')
.style('box-shadow', '4px 4px 10px rgba(0, 0, 0, 0.4)')
.style('color', 'white')
.style('font-family','sans-serif')
.text('a simple tooltip');
Insert cell
tunnel = FileAttachment("tunnel.png").url()
Insert cell
Insert cell
tunnelLoc = d3.csv(tunnelLink,d3.autoType)
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