Public
Edited
Feb 28, 2024
Insert cell
# Ticket to Ride - Japan
Insert cell
d3 = require("d3@6")
Insert cell
chart = {
const width = 860,
height = 800;
const svg = d3.create("svg")
.attr("viewBox", [50, 50, width-100, height-100]);

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

var p = svg.selectAll("polyline")
/* .data(yinyang)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','iconTest')
.attr('points', function(d){return d})
.attr('transform', 'translate(200,200)')
//.attr('transform', 'scale(1)') //not working right now
.style('stroke','orangered')
.style('stroke-width','1')
.style('stroke-opacity','.1')
.style('fill','orangered')
.style('fill-opacity','.15')
*/


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");



svg
.append("text")
.attr('x','260')
.attr('y','165')
.style('font-family','monospace')
.style('font-size','48px')
.style('font-weight','bold')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','middle ')
.text('TICKET TO RIDE')
svg.append("rect")
.attr("class","st_Rect")
.attr("x","130")
.attr("y","180")
.attr("rx","5")
.attr("ry","5")
.attr("height","60")
.attr("width","130")
.style("fill","ivory")
.style('fill-opacity','1')
// .style("stroke-width","1")
.style("stroke","brown")
.on('click',reset)

function reset() {
d3.selectAll('rect.pop_Rect').remove()
d3.selectAll('text.start_txt').remove()
}

p.enter().append("polyline")
.data(startButton)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','iconTest')
.attr('points', function(d){return d})
.attr('transform', 'translate(-5,-10)')
//.attr('transform', 'scale(1)') //not working right now
.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){

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

svg.append("rect")
.attr("class","pop_Rect")
.attr("x","75")
.attr("y","247")
.attr("rx","20")
.attr("ry","20")
.attr("height","450")
.attr("width","700")
.style("fill","ivory")
.style('fill-opacity','1')
.style("stroke-width","5")
.style("stroke","saddlebrown")
//.style('stroke-opacity','.5')

svg
.append("text")
.attr("class","start_txt")
.attr('x','130')
.attr('y','330')
.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','150')
.attr('y','360')
.style('font-family','monospace')
.style('font-size','14px')
.style('font-weight','regular')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('Body of text explaining the instructions/rules of the game. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Posuere morbi leo urna molestie at. Scelerisque viverra mauris in aliquam sem fringilla ut morbi tincidunt. Elementum integer enim neque volutpat ac tincidunt vitae semper. Morbi tincidunt augue interdum velit.')

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

svg
.append("text")
.attr("class","start_txt")
.attr('x','150')
.attr('y','500')
.style('font-family','monospace')
.style('font-size','14px')
.style('font-weight','regular')//use 'fill' to change font color
.attr('fill','saddlebrown')
.attr('text-anchor','left')
.text('How to create a bulleted or numerical list...? Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Posuere morbi leo urna molestie at. Scelerisque viverra mauris in aliquam sem fringilla ut morbi tincidunt. Elementum integer enim neque volutpat ac tincidunt vitae semper. Morbi tincidunt augue interdum velit.')

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



/*svg
.append("text")
.attr('x','280')
.attr('y','175')
.style('font-family','julee')
.style('font-size','24px')
.style('font-weight','light')//use 'fill' to change font color
.attr('fill','peru')
.attr('text-anchor','middle ')
.text('Art, Culture, & Food Tour')

g.selectAll("path5") //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','outlinesshadow')
.attr('transform', 'translate(2,1)')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "black")
.style("fill-opacity", ".5")
g.selectAll("path5") //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','outlinesshadow')
.attr("d", path3) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "white")
.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("path2") //d3 geopath
.data(jpRoads.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','.35')
.style("stroke-width", '.1')
.style("stroke", "rgb(0,0,0)")
*/
g.selectAll("path1") //d3 geopath
.data(sbs_line_1.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')
//.attr('stroke-dasharray','0.5 1 0.5 1')
.style("stroke-width", '2')
.style("stroke", "orange")

g.selectAll("path1") //d3 geopath
.data(sbs_line_2.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')
.attr('stroke-dasharray','2 2 4 2')
.style("stroke-width", '2')
.style("stroke", "orange")


var c = svg.selectAll("circle") //d3 geopath
/* .data(subSts.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class','stsPts')
.attr("cx", function(d) {return path1.centroid(d)[0]})
.attr("cy", function(d) {return path1.centroid(d)[1]})
.attr('r',4.5)
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "sienna")
.style('fill','peru')
.style('fill-opacity','1')


p.enter().append("polyline")
.data(icon_test)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','iconTest')
.attr('points', function(d){return d})
.attr('transform', 'translate(125,200)')
//.attr('transform', 'scale(1)') //not working right now
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill','peru')
.style('fill-opacity','.8')


//NOT RELEVANT CODE p.enter().append("polyline") //d3 geopath
.data(icon_list)
.enter() //there are more data than elements, this selects them
.append("polyline") //appends path to data
.attr('class','iconTest')
.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]+')'})
//.attr('transform', 'scale(1,0.5)') //not working right now
.style('stroke-opacity','.9')
.style("stroke-width", '.3')
.style("stroke", "peru")
.style('fill',fillColor)
.style('fill-opacity','.8')
*/
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", '.4')
.style("stroke", "peru")
.style('fill',fillColor)
.style('fill-opacity','1')
.on('mouseover',spotsInfo)
.on('mouseout',spotsInfoOut)

function fillColor(d,i){

var color = 'peru'
if(d.data.Rated==5){color = 'orangered'
console.log("match")}
if(d.data.Rated==4){color = 'tomato'}
if(d.data.Rated==3){color = 'coral'}
if(d.data.Rated==2){color = 'salmon'}
if(d.data.Rated==1){color = 'lightsalmon'}

return color
}



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


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

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','650')
.attr('y2',projection([d.data.Long,d.data.Lat])[1])
.attr('stroke-width','2')
.style('stroke-opacity','.5')
.attr('stroke','brown')
//.attr('stroke-dasharray','2 2 4 2')

svg.append("rect")
.attr("class","dRect")
.attr("x","550")
.attr("y","635")
.attr("rx","5")
.attr("ry","5")
.attr("height","55")
.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','spotsDes')
.attr('x','710')
.attr('y','698')
.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('Info')
svg
.append('text')
.attr('class','spotsText')
.attr('x','635')
.attr('y','650')
.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),150)})

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

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

svg
.append('text')
.attr('class','spotsRate')
.attr('x','570')
.attr('y','670')
.attr('font-family','julee')
.attr('font-size','1.2em')
.attr('fill','saddlebrown')
.style('fill-opacity','.4')
.attr('text-anchor','middle ')
.text(d.data.Rating)

var ratingList = []
if(d.data.Rated==1){ratingList = [shrine]}
if(d.data.Rated==2){ratingList = [shrine,shrine]}
if(d.data.Rated==3){ratingList = [shrine,shrine,shrine]}
if(d.data.Rated==4){ratingList = [shrine,shrine,shrine,shrine]}
if(d.data.Rated==5){ratingList = [shrine,shrine,shrine,shrine,shrine]}

p.enter().append("polyline")
.data(ratingList)
.enter() //there are more data than elements, this selects them
.append("polyline")
.attr('class','icon_rating')
.attr('points',function(d){return d})
.attr('transform',function(d,i){return 'translate('+(180+(i*25))+',205)'})
.style('stroke-opacity','.9')
.style("stroke-width", '.05')
.style("stroke", "saddlebrown")
.style('fill','saddlebrown')
.style('fill-opacity','.8')


}

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()
}

return svg.node();
}
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 < stations.length; i++) {
//function to add item to a list
list.push({data:stations[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
icon_list = {

///create empty list
var list = []

///loop through google sheets list
for (let i = 0; i < spots.length; i++) {
//function to add item to a list
list.push({data:spots[i],pts:lantern1})
}
//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
icon_test = FileAttachment("lantern2@1.txt").tsv({array:true})
Insert cell
train_icon = FileAttachment("train_icon@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
shrine = FileAttachment("shrine5@1.txt").tsv({array:true})
Insert cell
jpRail = FileAttachment("jp rail.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
bldgs = FileAttachment("bldgs.geojson").json()
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
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
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
dashboardGraphics = {

const width = 1060,
height = 1000;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

var p = svg.selectAll("polyline")
.data(border1)
.enter()
.append("polyline")
.attr('points',function(d){return d})
.attr('transform', 'translate(2,1)')
.attr('fill','grey')
.style('fill-opacity','.15')

p.enter().append("polyline")
.data(border1)
.enter()
.append("polyline")
.attr('points',function(d){return d})
.attr('fill','white')
.style('fill-opacity','1')

p.enter().append("polyline")
.data(border1)
.enter()
.append("polyline")
.attr('points',function(d){return d})
.attr('fill','orangered')
.style('fill-opacity','.1')
.style('stroke-opacity','.5')
.style("stroke-width", '.3')
.style('stroke','peru')


return svg.node();
}
Insert cell
dashboard =

html`
<div class='dashboardOuter' style='height:1000px;width:1060px'>


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

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

<div class='text' style='position:absolute;top:790px;left:350px;font-family:helvetica;font-size:18px'>
${viewof gm}
${viewof sd}
${viewof is}
</div>
<div class='text' style='position:absolute;top:775px;left:290px;color:peru;font-family:julee;font-size:16px'>
${md`Art`}
</div>

<div class='text' style='position:absolute;top:800px;left:290px;color:peru;font-family:julee;font-size:16px'>
${md`Culture`}
</div>

<div class='text' style='position:absolute;top:824px;left:290px;color:peru;font-family:julee;font-size:16px'>
${md`Food`}
</div>

<div class='text' style='position:absolute;top:855px;left:290px;color:saddlebrown;font-family:century gothic;font-size:18px'>
${md`Anticipated Enjoyment: **${calculatedValues[0]}**`}
</div>

<div class='text' style='position:absolute;top:880px;left:290px;color:saddlebrown;font-family:century gothic;font-size:18px'>
${md`Anticipated Cost: **${calculatedValues[1]}**`}
</div>

<div class='shrineIcon' style='position:absolute;width:200px;top:760px;left:740px'>
${drawTotoro}
</div>

</div>

`

Insert cell
drawTotoro = {
var icon = ' '
if(calculatedValues[0]>10 && calculatedValues[1]<200){icon = totoroIcon}


return icon
}
Insert cell
viewof gm = Inputs.radio(["0", "1", "2"],)
Insert cell
viewof sd = Inputs.radio(["0", "1", "2"],)
Insert cell
viewof is = Inputs.radio(["0", "1", "2"],)
Insert cell
spotsDataset = [
{name:'gm',rating:4,cost:15},
{name:'sd',rating:3,cost:10},
{name:'is',rating:2,cost:20}
]
Insert cell
calculatedValues = {

var totalRating = 0
var totalCost = 0

totalRating = totalRating+spotsDataset[0].rating*gm
totalRating = totalRating+spotsDataset[1].rating*sd
totalRating = totalRating+spotsDataset[2].rating*is

totalCost = totalCost+spotsDataset[0].cost*gm
totalCost = totalCost+spotsDataset[1].cost*sd
totalCost = totalCost+spotsDataset[2].cost*is

return [totalRating,totalCost]
}
Insert cell
calculatedValues[0]
Insert cell
totoroIcon = {

const width = 100,
height = 100;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

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

return svg.node();
}
Insert cell
shrine_icon = FileAttachment("shrine_icon.txt").tsv({array:true})
Insert cell
totoro = FileAttachment("totoro.txt").tsv({array:true})
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more