Public
Edited
Dec 10, 2022
Insert cell
# Paris Transit Proposed Map (Dec.10.22)
Insert cell
function getDistance(x1, y1, x2, y2){
let y = x2 - x1;
let x = y2 - y1;
return Math.sqrt(x * x + y * y);
}
Insert cell
d3 = require("d3@6")
Insert cell
bbox1 = FileAttachment("bbox.geojson").json()
Insert cell
GreenSpaces = FileAttachment("simplified green spaces.geojson").json()
Insert cell
railSpot = FileAttachment("railLn.geojson").json()
Insert cell
statSpot = FileAttachment("statSpot@1.geojson").json()
Insert cell
distSpot = FileAttachment("distSpot@1.geojson").json()
Insert cell
cSpot = FileAttachment("cSpot@1.geojson").json()
Insert cell
keyText = FileAttachment("keyText@1.geojson").json()
Insert cell
mapKey = FileAttachment("keyOutline.geojson").json()
Insert cell
lines1 = FileAttachment("19001920lines.geojson").json()
Insert cell
lines2 = FileAttachment("19201940lines.geojson").json()
Insert cell
lines3 = FileAttachment("19401960lines.geojson").json()
Insert cell
lines4 = FileAttachment("19601980lines.geojson").json()
Insert cell
lines5 = FileAttachment("19802000lines.geojson").json()
Insert cell
lines6 = FileAttachment("20002020lines.geojson").json()
Insert cell
lines7 = FileAttachment("2020lines.geojson").json()
Insert cell
bikeRoute = FileAttachment("bike route@1.geojson").json()
Insert cell
funSpotsLines = FileAttachment("fun spots lines@1.geojson").json()
Insert cell
outdoorScenicRoutes = FileAttachment("outdoor scenic routes.geojson").json()
Insert cell
existingRoutesForBus = FileAttachment("existing routes for bus and shuttle.geojson").json()
Insert cell
newRoutesForBus = FileAttachment("new routes for bus and shuttle.geojson").json()
Insert cell
rer = FileAttachment("RER.geojson").json()
Insert cell
stations = FileAttachment("stations@1.geojson").json()
Insert cell
stationProximity={
//console.log(stations.features[5].geometry.coordinates)
var isStationClose = 0
var stationOb = 0
var stationObs = []

var from = turf.point(stations.features[0].geometry.coordinates);
var to = turf.point(stations.features[1].geometry.coordinates);
var options = {units: 'kilometers'};

var distance1 = turf.distance(from, to, options);

console.log(distance1*1000)
for (let i = 0; i < stations.features.length; i++) {


for (let k= 0; k < stations.features.length; k++) {
if(i!=k){
//var pt1 = stations[i].geometry.coordinates
//var pt2 = stations[k].geometry.coordinates
var distance = 0

var from = turf.point(stations.features[i].geometry.coordinates);
var to = turf.point(stations.features[k].geometry.coordinates);
var options = {units: 'kilometers'};

distance = turf.distance(from, to, options);
//distance = distance*1000

if(distance*1000<500){
isStationClose = 1
}

}
}
stationOb = {name:stations.features[i].properties.L_STATION, proximity: isStationClose}
stationObs.push(stationOb)
isStationClose=0
}


const person = {
name: 'Mateusz',
lastnme: 'Choma',
sayHello: function (){
console.log('Hello ' + this.name + ' ' + this.lastname)
}
}
return stationObs
}
Insert cell
Streets = FileAttachment("simplified streets.geojson").json()
Insert cell
water = FileAttachment("water@2.geojson").json()
Insert cell
district1 = FileAttachment("1901 district.geojson").json()
Insert cell
district2 = FileAttachment("1921 district.geojson").json()
Insert cell
district3 = FileAttachment("1946 district.geojson").json()
Insert cell
district4 = FileAttachment("1968 district.geojson").json()
Insert cell
district5 = FileAttachment("1990 district.geojson").json()
Insert cell
district6 = FileAttachment("2007 district.geojson").json()
Insert cell
district7 = FileAttachment("2017 district.geojson").json()
Insert cell
suburb1 = FileAttachment("1920-1940 suburb.geojson").json()
Insert cell
suburb2 = FileAttachment("1940-1960 suburb.geojson").json()
Insert cell
suburb3 = FileAttachment("1960-1980 suburb.geojson").json()
Insert cell
suburb4 = FileAttachment("1980-2000 suburb.geojson").json()
Insert cell
Underratedspots = d3.csv(UnderratedSpotsLink, d3.autoType)
Insert cell
Insert cell
Insert cell
spots = d3.csv(SpotsLink, d3.autoType)
Insert cell
Insert cell
districtsCombined = FileAttachment("Districts Combined V4.geojson").json()
Insert cell
turf = require("@turf/turf@5")
Insert cell
round = (n, places) => {
if (!places) return Math.round(n);
const d = places;
return Math.round(d);
}
Insert cell
import { wrap_text, wrap_text_nchar } from "@ben-tanen/svg-text-and-tspan-word-wrapping"
Insert cell
color = d3.scaleQuantize([8500, 100000], d3.schemePurples[9])
Insert cell
viewof uSpots = Inputs.select(Underratedspots, {label: "Cultural Spots", format: x => x.description, value: Underratedspots.find(s => s.description === "Museum")})
Insert cell
chart = {
const width = 960,
height = 900;
const svg = d3.create("svg")
.attr("viewBox", [0, 50, width-100, height-100]);

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

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

var clickYear = 2000
var clicks = []
//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)")
*/


console.log(uSpots)
console.log(uSpots.latitude)


svg
.on('click',function(event){
var coords = d3.pointer(event)
console.log(coords[0],coords[1])

clicks.push(coords)

console.log(clicks)

c.enter().append("circle")
.data(clicks)
.enter()
.append("circle")
.attr("cx", function(d) {return d[0]})
.attr("cy", function(d) {return d[1]})
.attr('r',3)
.attr('fill','cyan')
.style('fill-opacity','1')

var distances = []
//loop through clicks array
for(let i = 0; i <clicks.length;i++){
var dist = getDistance(10,10,clicks[i][0],clicks[i][1])

//measure the distance from static point to clicks array point

//add distances to an array
distances.push(dist)
}
//sort distances to find the shortest
var sorted = distances.sort(function(a, b){return a - b});
console.log(sorted)

var c = document.getElementById("distances");
var ctx = c.getContext("2d");
var cx= coords[0];
var cy= coords[1];
ctx.moveTo(cx,function(d) {return d[0]});
ctx.lineTo(cy,function(d) {return d[1]});
ctx.lineWidth = 1
ctx.stroke("stroke", 'black');

/*
var c = document.getElementById("distances");
var ctx = c.getContext("2d");
var cx= function(dist)
var cy= function(dist)
ctx.moveTo(cx,function(d) {return d[0]});
ctx.lineTo(cy,function(d) {return d[1]});
ctx.lineWidth = 1
ctx.stroke("stroke", 'black');


svg.append('line')
.attr('class','spotLine')
.attr("cx",function(getDistance) {return d[0]})
.attr("cy", function(getDistance) {return d[1]})
.style('stroke-width','.75')
.style('stroke','black')
.style('stroke-dasharray','2 2')

but the function get distance feels like it could work


*/
})

/*
function draw() {
const dist = getDistance.selectAll('line');

if (!canvas.getContext) {
return;
}


function drawLine(ctx, begin, end, stroke = 'black', width = 1) {
if (stroke) {
ctx.strokeStyle = stroke;
}

*/

var t = svg.selectAll('circle')
.data(uSpots)
.enter()
.append('circle')
//.attr('class','spots')
.attr('x','200')
.attr('y',function(d,i){return 200+(i*20)})
.attr('r',8)
.attr('fill','floralwhite')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")
.text(function(d){return d})


g.selectAll("path2")
.data(lines1.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines2.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines3.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines4.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines5.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines6.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines7.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(bikeRoute.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(funSpotsLines.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '1.5')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(outdoorScenicRoutes.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(existingRoutesForBus.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(newRoutesForBus.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(rer.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb1.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.2')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb2.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.3')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb3.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.4')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb4.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "lightsteelblue")
.style('fill-opacity','0.5')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path3")
.data(GreenSpaces.features)
.enter()
.append("path")
.attr('class','greenspaces')
.attr("d", path3)
.style("fill", "rgb(186, 219, 203)")
.style("fill-opacity", ".2")
.style('stroke-opacity','.5')
.style("stroke-width", '.2')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path3")
.data(water.features)
.enter()
.append("path")
.attr('class','water')
.attr("d", path3)
.style("fill", "rgb(193, 219, 224)")
.style("fill-opacity", ".4")
.style('stroke-opacity','.4')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path3")
.data(Streets.features)
.enter()
.append("path")
.attr('class','streets')
.attr("d", path3)
.style("fill", "rgb(200,200,200)")
.style("fill-opacity", "0")
.style('stroke-opacity','.3')
.style("stroke-width", '.1')
.style("stroke", "rgb(0,0,0)")

var c = svg.selectAll("circle")
.data(stations.features)
.enter()
.append("circle")
.attr("cx", function(d) {return path1.centroid(d)[0]})
.attr("cy", function(d) {return path1.centroid(d)[1]})
.attr('r',staRadius)//make a function
.attr('fill','rgb(120,120,120)')
.style('fill-opacity','1')
.style("stroke-width", '0.5')
.style("stroke", "black")
.on('mouseover',growDot)
.on('mouseout', shrinkDot)
.on('click', subClick) //click on subway station, perform a series of operations

function staRadius(){
//get index of this

//use index value to find the station proximity value - stationProximity[index]

//if the station proximity value ==0 then radius = 5 else radius = 2

//return radius

}

function growDot(){
d3.select(this).attr('r','5')
}

function shrinkDot(){
d3.select(this).attr('r','3')
}


var newSubways = [] //list to hold new subway lines
var clickCoords = [] //list to reocrd the start point of our line
var startPtData = []
var latlong = []
var subwayMaxLength = 600

writesubwayMaxLength() //write down initial subway budget
function subClick(event,d) {
//console.log('click')



if(clickCoords.length==1){
var startPt = [latlong[0][0],latlong[0][1]]
var endPt = [d.geometry.coordinates[0],d.geometry.coordinates[1]]
var subLength = turf.distance(startPt,endPt,{units:"meters"});
console.log(round(subLength,600))

console.log("going from " + startPtData[0].properties.name)
console.log("ending at " + d.properties.name)

//connect the points in clickCoords to the current clicks
newSubways.push({x1:clickCoords[0][0], y1:clickCoords[0][1], x2:path1.centroid(d)[0], y2:path1.centroid(d)[1], length:subLength}) //create object w/ new subways
newSubLines() //function that draws new subwayLines

subwayMaxLength = writesubwayMaxLength-subLength
writesubwayMaxLength()
latlong = [] //list that carries lat/long values so we can measure
clickCoords = [] //list that carries pixel values
startPtData = []
}else{
//add the current clicked point to clickCoords
clickCoords.push([path1.centroid(d)[0],path1.centroid(d)[1]])
latlong.push([d.geometry.coordinates[0],d.geometry.coordinates[1]])
startPtData.push(d)
}

//console.log(newSubways)
}

function newSubLines(){
// console.log('im in the function!')
var ln = svg.selectAll("lines") //d3 geopath
.data(newSubways) //get data to define path
.enter() //there are more data than elements, this selects them
.append("line") //appends path to data
.attr('class','newSubwaysClass')
.attr('x1', function(d) {return d.x1})
.attr('x2', function(d) {return d.x2})
.attr('y1', function(d) {return d.y1})
.attr('y2', function(d) {return d.y2})
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "plum")
}


function writesubwayMaxLength(){
d3.selectAll('text.budget').remove()
svg
.append('text')
.attr('class','budget')
.attr('x','800')
.attr('y','800')
.attr('fint-sze','2em')
.attr('font-family','Helvetica')
.text(round(subwayMaxLength,600))
}
var t = svg.selectAll("text")
.data(layers)
.enter()
.append('text')
.attr('x',60)
.attr('y',function(d,i) {return 119+20*i})
.attr('fill','dimgray')
.attr('font-family','Helvetica')
.attr('font-size', '.65em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text(function(d) {return d})


c.enter().append('circle')
.data(layers)
.enter()
.append('circle')
.attr('cx',40)
.attr('cy',function(d,i) {return 115+20*i})
.attr('r',5)
.attr('fill','floralwhite')
.style("stroke-width", '.3')
.style("stroke", "rgb(0,0,0)")
.on('click',layersClick)

function layersClick(event,d){
console.log(d)


if(d=='Full'){

d3.selectAll('path.outlines').remove()
d3.selectAll('text.layersText').remove()
d3.selectAll('path.district').remove()

svg.append('text')
.attr('class','layersText')
.attr('x', '20')
.attr('y','70')
.attr('font-family','Helvetica')
.attr('font-size', '.65em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('Current transportation system')

g.selectAll("path2")
.data(districtsCombined.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.attr("fill", d => color(d.properties.Y2022))
.style('fill-opacity','0.5')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb1.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.2')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb2.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.3')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb3.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "aliceblue")
.style('fill-opacity','0.4')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(suburb4.features)
.enter()
.append("path")
.attr('class','district')
.attr("d", path2)
.style("fill", "lightsteelblue")
.style('fill-opacity','0.5')
.style('stroke-opacity','0.1')
.style("stroke-width", '.6')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path2")
.data(lines1.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path2")
.data(lines2.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path2")
.data(lines3.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines4.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines5.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines6.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

g.selectAll("path2")
.data(lines7.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1')
.style("stroke", "rgb(0,0,0)")

}

if(d=='Proposed'){

d3.selectAll('path.outlines').remove()
d3.selectAll('text.layersText').remove()
d3.selectAll('path.district').remove()

svg.append('text')
.attr('class','layersText')
.attr('x', '20')
.attr('y','70')
.attr('font-family','Helvetica')
.attr('font-size', '.65em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text('Proposed transportation system')

svg.append('text')
.attr('class','layersText')
.attr('x', '20')
.attr('y','85')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.text('Reduced number of lines for easier understanding while also reaching all tourists points.')

svg.append('text')
.attr('class','layersText')
.attr('x', '20')
.attr('y','95')
.attr('font-family','Helvetica')
.attr('font-size', '.55em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.text('Increased bus routes for neighborhoods in outskirts for greater safety.')

g.selectAll("path2")
.data(bikeRoute.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "darkorange")
.style('stroke-dasharray','2 2')

g.selectAll("path2")
.data(funSpotsLines.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '2')
.style("stroke", "darkmagenta")

g.selectAll("path2")
.data(outdoorScenicRoutes.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '2')
.style("stroke", "yellowgreen")

g.selectAll("path2")
.data(existingRoutesForBus.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '1.5')
.style("stroke", "rgb(139, 158, 166)")

g.selectAll("path2")
.data(newRoutesForBus.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '1.5')
.style("stroke", "lightskyblue")
.style('stroke-dasharray','2 2')

g.selectAll("path2")
.data(rer.features)
.enter()
.append("path")
.attr('class','outlines')
.attr("d", path2)
.style("fill", "none")
.style('stroke-opacity','1.5')
.style("stroke-width", '1.5')
.style("stroke", "rgb(0,0,0)")
.style('stroke-dasharray','4 4')


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

c.enter().append('circle')
.data(Underratedspots)
.enter()
.append("circle")
.attr("cx", function(d) {return projection([d.longitude, d.latitude])[0]})
.attr("cy", function(d) {return projection([d.longitude, d.latitude])[1]})
.attr('r',5)
.attr('fill','lightpink')
.style('fill-opacity','1')
.style('stroke','black')
.style('stroke-width','.8')
.on('mouseover', spotText)
.on('mouseout', removespotText)

c.enter().append('circle')
.data(spots)
.enter()
.append("circle")
.attr("cx", function(d) {return projection([d.longitude, d.latitude])[0]})
.attr("cy", function(d) {return projection([d.longitude, d.latitude])[1]})
.attr('r',5)
.attr('fill',colorType)
.style('fill-opacity','1')
.style('stroke','black')
.style('stroke-width','.8')
.on('mouseover', spotText)
.on('mouseout', removespotText)

g.selectAll("path4")
.data(mapKey.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "white")
.style('stroke-opacity','1')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
g.selectAll("path4")
.data(keyText.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "black")
g.selectAll("path4")
.data(cSpot.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "white")
.style('fill-opacity','1')
.style("stroke-width", '1')
.style("stroke", "black")

g.selectAll("path4")
.data(statSpot.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "black")
.style('fill-opacity','.5')
.style("stroke-width", '.15')
.style("stroke", "black")
g.selectAll("path4")
.data(distSpot.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "lavender")
.style('fill-opacity','.75')
.style("stroke-width", '.25')
.style("stroke", "black")

g.selectAll("path4")
.data(railSpot.features)
.enter()
.append("path")
.attr('class','key')
.attr("d", path4)
.style("fill", "none")
.style('fill-opacity','1')
.style("stroke-width", '1.5')
.style("stroke", "black")

function colorType(d,i){
var color = 'black'
if(d.type=='landmark')(color = 'white')
return color

}

/*
c.enter().append('circle')
.data(uSpots)
.enter()
.append('circle')
//.attr('class','spots')
.attr("cx",uSpots.longitude)
.attr("cy", uSpots.latitude)
//.attr("cx", projection([uSpots.longitude, uSpots.latitude])[0])
//.attr("cy", projection([uSpots.longitude, uSpots.latitude])[1])
//.attr("cx", function(d) {return projection([d.longitude, d.latitude])[0]})
//.attr("cy", function(d) {return projection([d.longitude, d.latitude])[1]})
//.attr("cx", d.longitude)
//.attr("cy", d.latitude)
.attr('r',30)
.attr('fill','green')
.style('fill-opacity','1')
.style('stroke','black')
.style('stroke-width','.8')
*/
svg
.append('circle')
.attr("cx", projection([uSpots.longitude, uSpots.latitude])[0])
.attr("cy", projection([uSpots.longitude, uSpots.latitude])[1])
.attr('r',30)
.attr('fill','yellow')
.style('fill-opacity','.5')
.style('stroke','black')
.style('stroke-width','.8')
function spotText(event,d){
d3.select(this).attr('fill','white')
svg.append('text')
.attr('class','spots')
.attr('x', '720')
.attr('y','780')
.attr('font-family','Helvetica')
.attr('font-size', '.7em')
.attr('text.anchor','start')
.attr('font-weight', 'bold')
.text(d.name)

svg.append('text')
.attr('class','spots')
.attr('x', '720')
.attr('y','790')
.attr('font-family','Helvetica')
.attr('font-size', '.65em')
.attr('text.anchor','start')
.attr('font-weight', 'normal')
.text(d.description)

svg.append('line')
.attr('class','spotLine')
.attr('x1', '720')
.attr('y1', '786')
.attr('x2', projection([d.longitude, d.latitude])[0])
.attr('y2', '786')
.style('stroke-width','.5')
.style('stroke','black')
.style('stroke-dasharray','2 2')
svg.append('line')
.attr('class','spotLine')
.attr('x1', projection([d.longitude, d.latitude])[0])
.attr('y1', '786')
.attr('x2', projection([d.longitude, d.latitude])[0])
.attr('y2', projection([d.longitude, d.latitude])[1])
.style('stroke-width','.7')
.style('stroke','black')
.style('stroke-dasharray','2 2')
}
function removespotText(event,d){
d3.select(this).attr('fill',colorType)
d3.selectAll('text.spots').remove()
d3.selectAll('line.spotLine').remove()
}
svg .on('click',function(event){
var culturalspots = d3.pointer(event)
console.log(clicks)

c.enter().append("circle") //circle
.data(clicks)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return d[0]})
.attr("cy", function(d) {return d[1]})
.attr('r',3)
.attr('fill','black')//add function to control color by 'type'
.style('fill-opacity','1')

})
/*
function yearFill(d,i){
var color = 'none'

if(d.year == clickYear){
color = 'white'
}

return color
}

*/
//}
return svg.node();

}

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