chart = {
const width = 1060,
height = 1000;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
var projection = d3
.geoMercator()
.fitSize([width - 100, height], jpBbox);
function NoninteractablePolylines(svg, data, classType, strokeWidth, strokeColor,fillColorX) {
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)
.style("fill", fillColorX);
}
NoninteractablePolylines(svg, bg_dashboard, "outline", "4px","peru", "peru")
svg.append("text")
.attr("x", "200")
.attr("y", "200")
.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")
.attr("x", "200")
.attr("y", "250")
.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
}
function initializeGame() {
if (gameState.startPopupInitiated == true) {
gameState.hasStarted = true
enableGameInteractions()
}
}
function enableGameInteractions() {
if (gameState.hasStarted == true) {
svg.append("text")
.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()
.append("polyline")
.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()
.append("polyline")
.attr('class','resetButton')
.attr('points', function(d){return d})
.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()
.append("polyline")
.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;
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')
.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')
.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)})
}
const borderLines = g.selectAll(".borderLine")
.data(border11)
.enter()
.append("polyline")
.attr("class", "borderLine")
.attr("points", d => d.pts)
.style("stroke", "black")
.style("stroke-width", "2px")
.style("fill", "none");
g.selectAll("path3")
.data(outline.features)
.enter()
.append("path")
.attr('class','outline1')
.attr("d", path3)
.style("fill", "ivory")
.style("fill-opacity", ".9")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "sienna")
g.selectAll("path1")
.data(sbs_lines.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','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
}
p.enter().append("polyline")
.data(train_list)
.enter()
.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)
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()
var bulletOptions = String(d.data.bulletDestination)
if(bulletOptions!=null && bulletOptions.includes(",")){
bulletOptions = bulletOptions.split(",")
}
var bulletDests = []
for (let i = 0; i < bulletOptions.length; i++) {
var index = Number(bulletOptions[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)
bulletDests.push(train_list[n].data)
}
}
}
var lnsToDraw = []
for (let i = 0; i < sbs_lines.features.length; i++) {
var sbsLine = sbs_lines.features[i].properties.indexID
sbsLine = sbsLine.split(',');
for (let n = 0; n < sbsLine.length; n++) {
if (d.data.indexID==Number(sbsLine[n])){
lnsToDraw.push(sbs_lines.features[i])
}
}
}
g.selectAll("path1")
.data(lnsToDraw)
.enter()
.append("path")
.attr('class','stationLines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','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")
.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")
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","1")
.style("stroke","brown")
.style('stroke-opacity','.5')
.on('click',polyClickVend)
svg.append("text")
.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')
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")
.data(vendingLines)
.enter()
.append("polyline")
.attr('class','vendClick')
.attr('points', function(d){return d.geo})
.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")
.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("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()
.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')
.attr('fill','orangered')
.attr('text-anchor','middle')
.text( function(d){return d.Name})
var railOptions = String(d.data.trainDestination)
if(railOptions!= null && railOptions.includes(",")){
railOptions = railOptions.split(",")
}
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)){
trainDests.push(train_list[n].data)
}
}
}
p.enter().append("text")
.data(trainDests)
.enter()
.append("text")
.attr('class','destinations')
.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')
.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()
}
function polyClick(event, d) {
var p = svg.selectAll("outlines")
d3.selectAll('text.menuText').remove()
d3.selectAll('image.dogImage').remove()
if(d.Name =='KKagoshima'){
mutable clickID = 1
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')
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('Which transport would you like to take?"')
if(d.trainFare){
function spendMoney(event,d){
mutable wallet = mutable wallet -d.price
}
}
if(d.Name =='Nagasaki'){
mutable clickID = 2
}
if(d.Name =='Takeo-Onsen'){
mutable clickID = 3
}
}
if(d.Name =='Tosu'){
mutable clickID = 4
}
if(d.Name =='Hakata'){
mutable clickID = 5
}
if(d.Name =='Hiroshima'){
mutable clickID = 6
}
if(d.Name =='Kyoto'){
mutable clickID = 7
}
if(d.Name =='Shin-Osaka'){
mutable clickID = 8
}
if(d.Name =='Shin-Osaka'){
mutable clickID = 9
}
if(d.Name =='Tsuruga'){
mutable clickID = 10
}
if(d.Name =='Kanazawa'){
mutable clickID = 11
}
if(d.Name =='Nagano'){
mutable clickID = 12
}
if(d.Name =='Shin-Yokohama'){
mutable clickID = 13
}
if(d.Name =='Tokyo'){
mutable clickID = 14
}
if(d.Name =='ÅŒmiya'){
mutable clickID = 15
}
if(d.Name =='Takasaki'){
mutable clickID = 16
}
if(d.Name =='Niigata'){
mutable clickID = 17
}
if(d.Name =='Fukushima'){
mutable clickID = 18
}
if(d.Name =='Sendai'){
mutable clickID = 19
}
if(d.Name =='Yamagata'){
mutable clickID = 20
}
•![]()
if(d.Name =='ShinjÅ'){
mutable clickID = 21
}
if(d.Name =='Akita'){
mutable clickID = 22
}
if(d.Name =='Morioka'){
mutable clickID = 23
}
if(d.Name =='Shin-Aomori'){
mutable clickID = 24
}
if(d.Name =='Shin-Hakodate-Hokuto'){
mutable clickID = 25
}
if(d.Name =='Shin-Hakodate-Hokuto'){
mutable clickID = 26
}
}
return svg.node();
}