Public
Edited
Apr 29, 2024
1 fork
Insert cell
# Ticket to Ride - Japan
Insert cell
d3 = require("d3@6")
Insert cell
mutable wallet= 20
Insert cell
mutable customerSatisfaction= 10
Insert cell
mutable clickID = 0
Insert cell
startmoney= 150
Insert cell
border11 = FileAttachment("border@1.txt").tsv({array:true})
Insert cell
chart = {
const width = 1060,
height = 1000;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

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

function NoninteractablePolylines(svg, data, classType, strokeWidth, strokeColor,fillColorX) {
//console.log(data)
const polylines = svg.selectAll("polyline." + classType)
.data(data)
.enter()
.append("polyline")
.attr("class", classType)
.attr("points", d => d)
.style("stroke", strokeColor)
.style("stroke-width", strokeWidth)
// .attr('transform', 'translate(0,50)')
.style("fill", fillColorX);
}

NoninteractablePolylines(svg, bg_dashboard, "outline", "4px","peru", "peru")


//mutable variables - wallet and customer satisfaction
svg.append("text")//DESTINATION TOKYO
.attr("x", "200")
.attr("y", "200")
//.attr("class", "body")
.style("font-size", '24px')
.style('font-weight','bold')
.style("fill", 'red')
.style('fill-opacity','1')
.style('font-family',"century gothic")
.text(wallet)

svg.append("text")//DESTINATION TOKYO
.attr("x", "200")
.attr("y", "250")
//.attr("class", "body")
.style("font-size", '24px')
.style('font-weight','bold')
.style("fill", 'red')
.style('fill-opacity','1')
.style('font-family',"century gothic")
.text(customerSatisfaction)



var p = svg.selectAll("polyline")
var t = svg.selectAll('text')

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 g = svg.append("g").attr("id", "paths");

let gameState = {
hasStarted: false,
startPopupInitiated: false // Step 1: Add a flag to track if startPopup has been initiated
}
// Remember to call initializeGame where appropriate, for example, within a user action like clicking a start button.
//svg.select("rect.st_Rect").on('click', () => {
//startPopup();
//initializeGame(); // You may need to adjust this call depending on your application flow
//})
//svg.select("rect.st_Rect").on('click', () => {
//startPopup();
// You may need to adjust this call depending on your application flow
//})

function initializeGame() {
//console.log('initialize game')
if (gameState.startPopupInitiated == true) { // Step 3: Check the flag before setting hasStarted to true
gameState.hasStarted = true
enableGameInteractions()

//what do we do?! where do we go?
}
}

// Function to enable game interactions
function enableGameInteractions() {
if (gameState.hasStarted == true) {
//console.log("hellllo")
svg.append("text")//DESTINATION TOKYO
.attr("x", "750")
.attr("y", "520")
.attr("class", "body")
.style("font-size", '24px')
.style('font-weight','bold')
.style("fill", 'red')
.style('fill-opacity','1')
.style('font-family',"century gothic")
.text('First Stop: Tokyo')

}
}

function reset() {
d3.selectAll('rect').remove()
d3.selectAll('text.start_txt').remove()
d3.selectAll('text.body').remove()
d3.selectAll('text.label').remove()
d3.selectAll('path.stationLines').remove()
d3.selectAll('text.destinations').remove()
d3.selectAll('text.confirm').remove()
d3.selectAll('text.currentText').remove()
d3.selectAll('text.welcome').remove()
d3.selectAll('text.missionText').remove()
d3.selectAll('text.hintText').remove()
}

function createText(svg, x, y, fontSize, textContent, fontWeight, textFill, txtOpacity, fontFamily) {
svg.append("text")
.attr("x", x)
.attr("y", y)
.attr("class", "Header")
.style("font-size", fontSize)
.style('font-weight',fontWeight)
.style("fill", textFill)
.style('fill-opacity',txtOpacity)
.style('font-family',fontFamily)
.text(textContent)
}

createText(svg, 202, 52, "60px", "A Ticket to Ride: Japan", "bold", 'saddlebrown', "0.5", 'century gothic')
createText(svg, 200, 50, "60px", "A Ticket to Ride: Japan", "bold", "saddlebrown", "1", "century gothic")

p.enter().append("polyline")
.data(start_button_bg)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','startButtonBG')
.attr('points', function(d){return d})
.attr('transform', 'translate(-90,-150)')
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill','ivory')
.style('fill-opacity','1')
.on('click',startPopup)

p.enter().append("polyline")
.data(resetClick)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','resetButton')
.attr('points', function(d){return d})
//.attr('transform', 'translate(-90,-150)')
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill','ivory')
.style('fill-opacity','1')
.on('click',reset)

NoninteractablePolylines(svg, reset_lns, "resetLns", "1px","peru", "peru")
p.enter().append("polyline")
.data(startButton)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','startButton')
.attr('points', function(d){return d})
.attr('transform', 'translate(-90,-150)')
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill','peru')
.style('fill-opacity','1')
.on('click',startPopup)

function startPopup(event,d){

gameState.hasStarted = true;
gameState.startPopupInitiated = true; // Step 2: Set the flag to true when startPopup is called
console.log(gameState.startPopupInitiated)

d3.selectAll('rect.pop_Rect').remove()
d3.selectAll('text.start_txt').remove()

initializeGame()

svg.append("rect")
.attr("class","pop_Rect")
.attr("x","144")
.attr("y","158")
.attr("rx","20")
.attr("ry","20")
.attr("height","240")
.attr("width","360")
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","5")
.style("stroke","peru")

svg
.append("text")
.attr("class","start_txt")
.attr('x','145')
.attr('y','420')
.style('font-family','monospace')
.style('font-size','18px')
.style('font-weight','bold')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('Instructions')

svg
.append("text")
.attr("class","start_txt")
.attr('x','155')
.attr('y','180')
.style('font-family','monospace')
.style('font-size','13px')
.style('font-weight','regular')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('Welcome to A Ticket to Ride: Japan! The rules are pretty simple. You are a XX picking up very important guests at different rail and bullet train stations. Each Round you will receive a train station destination; use the network of different bullet train and rail routes to get there in the most efficient way. If you dont get there in time XXXX. Oh, Also! watch your food and that wallet. If you need to refuel, there are plenty of vending machines around japan. Lastly, time is money, as they say, so if you start to run low on cash, you will need to lose some time to make some money. Anyways, Good Luck and Welcome to a Ticket to Ride: Japan!')

var wrap = svg.selectAll('text.start_txt')
.each(function(d,i) {wrap_text(d3.select(this),190)})

}
/*
//RANDOM Starting Postion and Destination
function getRandomStationNames(stations) {
// Ensure there are at least two different stations to choose from
if (stations.length < 2) {
console.error("Not enough stations to choose from.");
return null;
}

// Select a random index for the starting station
let startIndex = Math.floor(Math.random() * stations.length);
let startStation = stations[startIndex];

// Select a random index for the destination station
let destIndex;
do {
destIndex = Math.floor(Math.random() * stations.length);
} while (destIndex === startIndex); // Ensure destination is not the same as the start
let destinationStation = stations[destIndex];

return {
startStation: startStation.Name,
destinationStation: destinationStation.Name
};
}

// Example usage with your station data
let stations = [
{ Name: "Tokyo" },
{ Name: "Kyoto" },
{ Name: "Osaka" },
{ Name: "Hokkaido" }
];

let gameStations = getRandomStationNames(stations);
console.log("Start at:", gameStations.startStation);
console.log("Destination:", gameStations.destinationStation);

*/

//MAP DATA
const borderLines = g.selectAll(".borderLine") // Use a class to identify the elements
.data(border11)
.enter()
.append("polyline")
.attr("class", "borderLine")
.attr("points", d => d.pts) // Assuming each 'd' has a 'pts' property with the polyline points
.style("stroke", "black")
.style("stroke-width", "2px")
.style("fill", "none");

/* p.enter().append("polyline")
.data(vend_list)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon')
.attr('points',function(d){return d.geo})//not supposed to be points
//.attr('transform',function(d){return 'translate('+projection([d.data.Long,d.data.Lat])[0]+','+projection([d.data.Long,d.data.Lat])[1]+')'})
.style('stroke-opacity','1')
.style("stroke-width", '.2')
.style("stroke", "peru")
.style('fill',"peru")
.style('fill-opacity','1')
*/



g.selectAll("path3") //d3 geopath
.data(outline.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outline1')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "ivory")
.style("fill-opacity", ".9")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "sienna")

g.selectAll("path1") //d3 geopath
.data(sbs_lines.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')
//.attr('stroke-dasharray','0.5 1 0.5 1')
.style("stroke-width", '1.5')
.style("stroke", lineType)

function lineType(d,i){
var color = "salmon"

if(d.properties.Layer=="rail"){color = "lightsalmon"}

return color

}

/*g.selectAll("path1") //d3 geopath
.data(jpRail.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('fill-opacity','.4')
.style("stroke-width", '1')
.style("stroke", "red")
*/
// TRAIN STATION POINTS
p.enter().append("polyline")
.data(train_list)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon')
.attr('points',function(d){return d.pts})
.attr('transform',function(d){return 'translate('+projection([d.data.Long,d.data.Lat])[0]+','+projection([d.data.Long,d.data.Lat])[1]+')'})
.style('stroke-opacity','1')
.style("stroke-width", '.2')
.style("stroke", "peru")
.style('fill',fillColor)
.style('fill-opacity','1')
.on('mouseover',spotsInfo)
.on('mouseout',spotsInfoOut)
.on('click',polyClickStation)



//STATION CLICK
function polyClickStation(event,d) {

d3.selectAll('text.start_txt').remove()
d3.selectAll('text.destinations').remove()
d3.selectAll('rect.pop_Rect').remove()
d3.selectAll('path.stationLines').remove()
d3.selectAll('text.confirm').remove()
d3.selectAll('text.currentText').remove()
d3.selectAll('text.welcome').remove()
d3.selectAll('text.body').remove()
d3.selectAll('text.missionText').remove()
d3.selectAll('text.hintText').remove()

//have text for name of station
//text for numbers ofr bullet trains you can go to
// text for number of japanraisl you can go to

/* svg
.append("text")
.attr('x','200')
.attr('y','450')
.attr('class','label')
.style('font-family','julee')
.style('font-size','8px')
.style('font-weight','light')//use 'fill' to change font color
.attr('fill','peru')
.attr('text-anchor','left')
.text("bullet:" + d.data.bulletDestination)
*/
var bulletOptions = String(d.data.bulletDestination)
// console.log(bulletOptions)
if(bulletOptions!=null && bulletOptions.includes(",")){
bulletOptions = bulletOptions.split(",")
//console.log(bulletOptions)
}
var bulletDests = []
for (let i = 0; i < bulletOptions.length; i++) {
var index = Number(bulletOptions[i])
//console.log(index)
for (let n = 0; n < train_list.length; n++) {
//console.log(Number(train_list[n].data.indexID))
if(index==Number(train_list[n].data.indexID)){

console.log(train_list[n].data.Name)
bulletDests.push(train_list[n].data)
}
}
}

var lnsToDraw = []

for (let i = 0; i < sbs_lines.features.length; i++) {//loop through dataset of lines

var sbsLine = sbs_lines.features[i].properties.indexID//pull out id of lines
sbsLine = sbsLine.split(',');//split ids by ','
//console.log(sbsLine)

for (let n = 0; n < sbsLine.length; n++) {//loop through ids of lines
if (d.data.indexID==Number(sbsLine[n])){//compare icon clicked on to ids of numbers
// console.log('match')
// console.log(sbsLine[n])

//d3.select(sbs_lines.features[i].geometry).style('stroke-width','10')
lnsToDraw.push(sbs_lines.features[i])
}
}
}
//console.log(lnsToDraw)

g.selectAll("path1") //d3 geopath
.data(lnsToDraw) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','stationLines')
.attr("d", path2) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
//.attr('stroke-dasharray','0.5 1 0.5 1')
.style("stroke-width", '4')
.style("stroke", stationType)//

function stationType(d,i){
var color = "orange"

if(d.properties.Layer=="rail"){color = "orangered"}

return color

}

svg.append("rect")//pops up to click on for train destinations
.attr("class","vendRect")
.attr("x","760")
.attr("y",function(d,i){return 910+(i*30)})
.attr("rx","5")
.attr("ry","5")
.attr("height","30")
.attr("width","145")//can we make this adjustable to the length of the name and repeat with each name?
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","1")
.style("stroke","brown")
.style('stroke-opacity','.5')
.on('click',polyClickVend)

svg.append("text")//DESTINATION TOKYO
.attr("x", "767")
.attr("y", "930")
.attr("class", "confirm")
.style("font-size", '15px')
.style('font-weight','regular')
.style("fill", 'brown')
.style('fill-opacity','1')
.style('font-family',"century gothic")
.text('Vending Machine')



//STATION CLICK
function polyClickVend(event,d) {

d3.selectAll('text.start_txt').remove()
d3.selectAll('text.destinations').remove()
d3.selectAll('text.currentText').remove()
d3.selectAll('text.missionText').remove()
d3.selectAll('text.hintText').remove()
d3.selectAll('text.welcome').remove()
d3.selectAll('rect.pop_Rect').remove()
d3.selectAll('rect.trainRect').remove()
d3.selectAll('rect.vendRect').remove()
d3.selectAll('path.stationLines').remove()
d3.selectAll('text.confirm').remove()


p.enter().append("polyline")//VENDING MACHINE STUFF
.data(vendingLines)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','vendClick')
.attr('points', function(d){return d.geo})
//.attr('transform', 'translate(1,10)')
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill','ivory')
.style('fill-opacity','1')
.on('click',vendMacClick)

function vendMacClick (event, d) {

svg.append("rect")
.attr("class", "pop_vend_Rect")
.attr("x", 144)
.attr("y", 158)
.attr("rx", 10)
.attr("ry", 10)
.attr("height", 35)
.attr("width", 270)
.style("fill", "ivory")
.style('fill-opacity', '1')
.style("stroke-width", 1)
.style("stroke", "saddlebrown")
.on('click',confrimVend)
svg.append("text")//DESTINATION TOKYO
.attr("x", "160")
.attr("y", "180")
.attr("class", "confirm")
.style("font-size", '16px')
.style('font-weight','bold')
.style("fill", 'salmon')
.style('fill-opacity','1')
.style('font-family',"century gothic")
.text('Click here to Confirm Purchase')

function confrimVend (event, d) {
d3.selectAll('rect.pop_Rect').remove()
d3.selectAll('rect.pop_vend_Rect').remove()
d3.selectAll('rect.trainRect').remove()
d3.selectAll('rect.vendRect').remove()
d3.selectAll('text.confirm').remove()
d3.selectAll('polyline.vendClick').remove()
d3.selectAll('polyline.vmachinecol').remove()
d3.selectAll('polyline.vmachine').remove()
d3.selectAll('polyline.vmachinebg').remove()
}
}

NoninteractablePolylines(svg, bg_vending_color, "vmachinecol", "1.5px","none", "ivory")
NoninteractablePolylines(svg, vendingMachineOutlines, "vmachine", "0.5px","peru", "peru")
NoninteractablePolylines(svg, vend_bg_lns, "vmachinebg", "2px","peru", "none")
}
/* svg.append("rect")//pops up to click on for train destinations
.attr("class","trainRect")
.attr("x","690")
.attr("y",function(d,i){return 810+(i*30)})
.attr("rx","5")
.attr("ry","5")
.attr("height","30")
.attr("width","125")//can we make this adjustable to the length of the name and repeat with each name?
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","1")
.style("stroke","brown")
.style('stroke-opacity','.5')
*/

svg.append("text")
.attr("x", "830")
.attr("y", "450")
.attr("class", "welcome")
.style("font-size", '22px')
.style('font-weight','bold')
.style("fill", 'salmon')
.style('fill-opacity','1')
.attr('text-anchor','middle')
.style('font-family',"century gothic")
.text('Hi there! Welcome to:')
svg.append('text')
.attr('class','currentText')
.attr('x','830')
.attr('y','500')
.style('font-family','julee')
.attr('font-size','2em')
.attr('fill','brown')
.attr('text-anchor','middle')
.style('font-weight','bold')
.text(d.data.Name)

svg.append("text")
.attr("x", "830")
.attr("y", "560")
.attr("class", "welcome")
.style("font-size", '22px')
.style('font-weight','bold')
.style("fill", 'salmon')
.style('fill-opacity','1')
.attr('text-anchor','middle')
.style('font-family',"century gothic")
.text('Your Potential Next Stops are:')

svg.append("text")
.attr("x", "830")
.attr("y", "810")
.attr("class", "hintText")
.style("font-size", '12px')
.style('font-weight','regular')
.style("fill", 'salmon')
.style('fill-opacity','1')
.attr('text-anchor','middle')
.style('font-family',"century gothic")
.text('A little hint to help you choose the best next station:')
var wrap = svg.selectAll('text.hintText')
.each(function(d,i) {wrap_text(d3.select(this),130)})

svg.append('text')
.attr('class','missionText')
.attr('x','830')
.attr('y','850')
.style('font-family','julee')
.attr('font-size','1.2em')
.attr('fill','brown')
.attr('text-anchor','middle')
.style('font-weight','light')
.text(d.data.Mission)

var wrap = svg.selectAll('text.missionText')
.each(function(d,i) {wrap_text(d3.select(this),150)})
t.enter().append("text")
.data(bulletDests)
.enter() //there are more data than elements, this selects them
.append("text")
.attr('class','destinations')
.attr('points',function(d){return d})
.attr('x','830')
.attr('y',function(d,i){return 700+(i*30)})
.style('font-family','century gothic')
.style('font-size','24px')
.style('font-weight','bold')//use 'fill' to change font color
.attr('fill','orangered')
.attr('text-anchor','middle')
.text( function(d){return d.Name})



/*svg
.append("text")
.attr('x','200')
.attr('y','440')
.style('font-family','julee')
.style('font-size','13px')
.style('font-weight','light')//use 'fill' to change font color
.attr('fill','peru')
.attr('text-anchor','left')
.text("train:" + d.data.trainDestination)
*/


var railOptions = String(d.data.trainDestination)
if(railOptions!= null && railOptions.includes(",")){
railOptions = railOptions.split(",")
// console.log(railOptions)
}

var trainDests = []

for (let i = 0; i < railOptions.length; i++) {
var index = Number(railOptions[i])

for (let n = 0; n < train_list.length; n++){

if(index==Number(train_list[n].data.indexID)){
// console.log(train_list[n].data.Name)
trainDests.push(train_list[n].data)
}
}
}

p.enter().append("text")
.data(trainDests)
.enter() //there are more data than elements, this selects them
.append("text")
.attr('class','destinations')
//.attr('class','icon_rating')
.attr('points',function(d){return d})
.attr('x','830')
.attr('y',function(d,i){return 600+(i*20)})
.style('font-family','century gothic')
.style('font-size','13px')
.style('font-weight','bold')//use 'fill' to change font color
.attr('fill','orange')
.attr('text-anchor','middle')
.text(function(d){return d.Name})

}

function fillColor(d,i){
var color = 'peru'
if(d.data.transportType=='rail'){color = 'orangered'
console.log("match")}
if(d.data.transportType=='bullet'){color = 'tomato'}
return color
}

function spotsInfo(event,d){
d3.select(this).style('fill','brown')


svg.append('line')
.attr('class','spotLine')
.attr('x1','225')
.attr('y1','435')
.attr('x2','225')
.attr('y2',projection([d.data.Long,d.data.Lat])[1])
.attr('stroke-width','2')
.style('stroke-opacity','.5')
.attr('stroke','brown')

svg.append('line')
.attr('class','spotLine')
.attr('x1',projection([d.data.Long,d.data.Lat])[0])
.attr('y1',projection([d.data.Long,d.data.Lat])[1])
.attr('x2','225')
.attr('y2',projection([d.data.Long,d.data.Lat])[1])
.attr('stroke-width','2')
.style('stroke-opacity','.5')
.attr('stroke','brown')
svg.append("rect")
.attr("class","dRect")
.attr("x","145")
.attr("y","435")
.attr("rx","5")
.attr("ry","5")
.attr("height","65")
.attr("width","175")
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","1")
.style("stroke","brown")
.style('stroke-opacity','.5')

svg
.append('text')
.attr('class','spotsText')
.attr('x','230')
.attr('y','452')
.style('font-family','julee')
.attr('font-size','1em')
.attr('fill','brown')
.attr('text-anchor','middle ')
.style('font-weight','bold')
.text(d.data.Name)

var wrap = svg.selectAll('text.spotsText')
.each(function(d,i) {wrap_text(d3.select(this),135)})

svg
.append('text')
.attr('class','spotsDes')
.attr('x','230')
.attr('y','470')
.attr('font-family','century gothic')
.attr('font-size','.65em')
.attr('fill','saddlebrown')
.attr('text-anchor','middle ')
.text(d.data.funFact)

var wrap = svg.selectAll('text.spotsDes')
.each(function(d,i) {wrap_text(d3.select(this),150)})

}

function spotsInfoOut(event,d){
d3.selectAll('polyline.icon').style('fill',fillColor)
d3.selectAll('text.spotsText').remove()
d3.selectAll('text.spotsDes').remove()
d3.selectAll('text.spotsRate').remove()
d3.selectAll('rect.dRect').remove()
d3.selectAll('line.spotLine').remove()
d3.selectAll('polyline.icon_rating').remove()
}


//POLYCLICK FOR FIRST MOVE
function polyClick(event, d) {
var p = svg.selectAll("outlines")

d3.selectAll('text.menuText').remove()
d3.selectAll('image.dogImage').remove()

//Kagoshima Chou

if(d.Name =='KKagoshima'){

mutable clickID = 1
//PROMPT BOX
svg
.append('rect')
.attr("class","optionsPrompt")
.attr("x","403")
.attr("y","400")
.attr("rx","10")
.attr("ry","10")
.attr("height","200")
.attr("width","200")
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","5")
.style("stroke","saddlebrown")

svg
.append('text')
.attr("class","fareOptions")
.attr('x','400')
.attr('y','430')
.style('font-family','monospace')
.style('font-size','24px')
.style('font-weight','regular')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('Which transport would you like to take?"')

//CREATE BOXES AND CLICKS FOR EACH OPTION

//on sheets, for each station, iclude potential stops, add index values, show destiantions using javascript split commannd, have NESTED FOR LOOP that finds matches and prints them all out
//when i = 1 then, find destinations that match
// click on icon, click, have vairable that = to the split of destination id, loop thorugh ID, for each ID loop thorugh google sheet, and find maytch destination ID = to matching indx ids, then those index ID that corrosponf iwth the stations gets put into a temp list (a variable), add timer
// make vending machine graphic, simple game
// player is against the clock, energy, and money
//by end of spring break, on tecnhical side, click on icon and be able to run though destination ID and balc black blac
// make vending machine icon, popup that it interactive




if(d.trainFare){
function spendMoney(event,d){

mutable wallet = mutable wallet -d.price

}
}

//Nagasaki
if(d.Name =='Nagasaki'){

mutable clickID = 2

}

//Takeo-Onsen

if(d.Name =='Takeo-Onsen'){

mutable clickID = 3
//PROMPT BOX
}

// TRAINFARE OPTION
/* if(trainfareoptionselcted){
}

//CABFARE OPTION
//if(cabfareoptionselcted){

}
//WALK OPTION
// if(walkoptionselcted){

}*/

}

//Shin-Tosu

if(d.Name =='Tosu'){

mutable clickID = 4

}

//Hakata
if(d.Name =='Hakata'){

mutable clickID = 5

}

//Hiroshima
if(d.Name =='Hiroshima'){

mutable clickID = 6

}

//Kyoto
if(d.Name =='Kyoto'){

mutable clickID = 7

}


//Shin-Osaka
if(d.Name =='Shin-Osaka'){

mutable clickID = 8

}

//Nagoya
if(d.Name =='Shin-Osaka'){

mutable clickID = 9

}

//Tsuruga
if(d.Name =='Tsuruga'){

mutable clickID = 10

}

//Kanazawa
if(d.Name =='Kanazawa'){

mutable clickID = 11

}

//Nagano
if(d.Name =='Nagano'){

mutable clickID = 12

}

//Shin-Yokohama
if(d.Name =='Shin-Yokohama'){

mutable clickID = 13

}

//Tokyo
if(d.Name =='Tokyo'){

mutable clickID = 14

}

//ÅŒmiya
if(d.Name =='ÅŒmiya'){

mutable clickID = 15

}

//Takasaki
if(d.Name =='Takasaki'){

mutable clickID = 16

}

//Niigata
if(d.Name =='Niigata'){

mutable clickID = 17

}

//Fukushima
if(d.Name =='Fukushima'){

mutable clickID = 18

}

//Sendai
if(d.Name =='Sendai'){

mutable clickID = 19

}

//Yamagata
if(d.Name =='Yamagata'){

mutable clickID = 20

}

//ShinjÅ
if(d.Name =='ShinjÅ'){

mutable clickID = 21

}

//Akita
if(d.Name =='Akita'){

mutable clickID = 22

}

//Morioka
if(d.Name =='Morioka'){
mutable clickID = 23
}

//Shin-Aomori
if(d.Name =='Shin-Aomori'){

mutable clickID = 24

}

//Shin-Hakodate-Hokuto
if(d.Name =='Shin-Hakodate-Hokuto'){

mutable clickID = 25

}

//Sapporo

if(d.Name =='Shin-Hakodate-Hokuto'){

mutable clickID = 26

}

}





return svg.node();
}
Insert cell
start_button_bg = FileAttachment("start_button_bg@1.txt").tsv({array:true})
Insert cell
reset_lns = FileAttachment("reset_lns.txt").tsv({array:true})
Insert cell
resetClick = FileAttachment("reset_bg.txt").tsv({array:true})
Insert cell
vendingClicks = FileAttachment("vending machine clicks3.txt").tsv({array:true})
Insert cell
vendingLines = {

var list = []
for (let i = 0; i < vendingClicks.length; i=i+2) {
list.push({geo:vendingClicks[i],id:Number(vendingClicks[i+1])})
}
return list
}
Insert cell
vend_bg_lns = FileAttachment("vend_bg_lns@1.txt").tsv({array:true})
Insert cell
vendingMachineOutlines = FileAttachment("vending_macLines@1.txt").tsv({array:true})
Insert cell
bg_vending_color = FileAttachment("bg_vending_color.txt").tsv({array:true})
Insert cell
bg_dashboard = FileAttachment("bg_dashboard.txt").tsv({array:true})
Insert cell
border11
X*
Y*
Color
Size
Facet X
Facet Y
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
resetButton1 = FileAttachment("reset button@1.txt").tsv({array:true})
Insert cell
startButton3 = FileAttachment("start button@3.txt").tsv({array:true})
Insert cell
twm1 = FileAttachment("twm@1.txt").text()
Insert cell
btm_circs = FileAttachment("btm_circs.txt").text()
Insert cell
starIcon = {

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

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

return svg.node();
}
Insert cell
staricon2 = FileAttachment("staricon-2.txt").tsv({array:true})
Insert cell
/*thereWillBeLineWorkEventually = {

var list = lines
var spreadsheet = trainPRices
var cleanLines = []
for (let i = 0; i < list.length-1; i=i+2) {
var id = list[i+1][0]
var idNum = String(id) //use this line if your ids are words
//idNum = Number(id) use this line if your ids are numbers

//spreadsheet variables
var Name
var trainFare
var cabFare
var Walk
//looping through spreadsheet
for (let k = 0; k < spreadsheet.length;k++) {
if(idNum==spreadsheet[k].Name){
console.log("match!!!!!!")
Name=spreadsheet[k].Name
trainFare=spreadsheet[k].trainFare
cabFare=spreadsheet[k].cabFare
Walk=spreadsheet[k].Walk

}
}
//tying spreadsheet data to var
cleanLines.push({pts:list[i], Name:Name, trainFare:trainFare, cabFare:cabFare, Walk:Walk})//add features to our final list of objects
}


return cleanLines
}*/
Insert cell
lantern1 = FileAttachment("lantern1@2.txt").tsv({array:true})
Insert cell
train_list = {

///create empty list
var list = []

///loop through google sheets list
for (let i = 0; i < trainPrices.length; i++) {
//function to add item to a list
list.push({data:trainPrices[i],pts:train_icon})
}
//add icon points to each google sheet item
////addd combined data to empty list


//return new list
return list
}
Insert cell
vend_list = {

///create empty list
var list = []

///loop through google sheets list
for (let i = 0; i < vendPrices.length; i++) {
//function to add item to a list
list.push({data:vendPrices[i],pts:vendingClicks})
}
//add icon points to each google sheet item
////addd combined data to empty list


//return new list
return list
}
Insert cell
jpBboxSm = FileAttachment("JP bbox sm.geojson").json()
Insert cell
train_icon = FileAttachment("train_icon3@1.txt").tsv({array:true})
Insert cell
startButton = FileAttachment("start button@2.txt").tsv({array:true})
Insert cell
yinyang = FileAttachment("yinyang_lg@1.txt").tsv({array:true})
Insert cell
jpRail = FileAttachment("jp rail.geojson").json()
Insert cell
sbs_lines = FileAttachment("sbs_lines.geojson").json()
Insert cell
sbs_line_1 = FileAttachment("sbs_line_1.geojson").json()
Insert cell
sbs_line_2 = FileAttachment("sbs_line_2.geojson").json()
Insert cell
jpRoads = FileAttachment("jp roads.geojson").json()
Insert cell
outline = FileAttachment("jp coastline 2.geojson").json()
Insert cell
subSts = FileAttachment("sbs_stations.geojson").json()
Insert cell
Insert cell
bbox = FileAttachment("start button@1.txt").json()
Insert cell
subLns = FileAttachment("subway_lines.geojson").json()
Insert cell
jpBbox = FileAttachment("JP bbox.geojson").json()
Insert cell
vendingPrices_list = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTfD7shp-toV4RzZ_GvIf0fwuRMCFtrwwcws3ISI1GXHWTv91NpNgUyg0FMfb7FC7BP3S1HJU4iPq6A/pub?output=csv"
Insert cell
vendPrices= d3.csv(vendingPrices_list,d3.autoType)
Insert cell
Insert cell
trainPrices= d3.csv(trainPrices_link,d3.autoType)
Insert cell
Insert cell
spots = d3.csv(spots_link,d3.autoType)
Insert cell
Insert cell
stations = d3.csv(stations_link,d3.autoType)
Insert cell
import { wrap_text, wrap_text_nchar } from "@ben-tanen/svg-text-and-tspan-word-wrapping"
Insert cell
Insert cell
Insert cell
GFontToDataURI(
// "https://fonts.googleapis.com/css2?family=Julee&display=swap"
"https://fonts.googleapis.com/css2?family=Julee&display=swap"
)
.then((cssRules) => {
let fontRules = cssRules.join("\n");
svg
.append("defs")
.append("style")
.attr("type", "text/css")
.text(fontRules);
console.log("Added Font");
})
.catch((reason) => console.log(reason));
Insert cell
Insert cell
Insert cell
Insert cell
test_dash = FileAttachment("test_dash@1.txt").tsv({array:true})
Insert cell
border1 = FileAttachment("dashboard-border1.txt").tsv({array:true})
Insert cell
vending_click = FileAttachment("vending_click_3.txt").tsv({array:true})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more