Public
Edited
Apr 10
Fork of base map
1 fork
Insert cell
# fleet's interesting base map
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
line = d3.line()
Insert cell
//clicks = []
Insert cell
viewof message = Inputs.text({placeholder: "Say hello"})
Insert cell
viewof colorInput = Inputs.select(["red", "orange", "yellow", "green", "blue", "violet"], {value: "green"})
Insert cell
d3 = require("d3@6")
Insert cell
chart = {
const width = 960, //size of map on screen
height = 900;
//const svg = d3.create("svg")
//.attr("viewBox", [50, 50, width-100, height-100]); // adjusting position of the view box
//.on("click", reset);

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

var clicks = []
viewof colorInput
var g = svg.append("g")
//.attr("class", "circle");

const zoom = d3.zoom()
.extent([[0, 0], [width, height]])
.scaleExtent([1, 8])
.on("zoom", zoomed);
// Use Mercator projection
var projection = d3
.geoMercator()
.fitSize([width - 50, height - 50], bb_test);

var path1 = d3.geoPath().projection(projection);//path variable for each use of d3.geopath
var path2 = d3.geoPath().projection(projection);
var path3 = d3.geoPath().projection(projection);
var path4 = d3.geoPath().projection(projection);

svg.call(zoom);
//var g = svg.append("g").attr("id", "circles");

svg
.on('mousemove',function(event) {
var coords = d3.pointer(event)
console.log(coords)
}
)
svg
.on('click', function(event) {
var coords = d3.pointer(event);
//console.log( coords[0], coords[1] ) // log the mouse x,y position
clicks.push(coords)
//var x = d3.mouse(this)[0];
console.log(clicks)

//add circle to click
c.enter().append("circle") //d3 geopath
.data(clicks)
.enter()
.append("circle") //appends path to data
.attr('class','newClicks')
.attr("cx", function(d) {return (d)[0]})
.attr("cy", function(d) {return (d)[1]})
.attr('r',6)
.attr('fill','black')
.style('fill-opacity','1')

var newPath = line(clicks)

/*
svg.append('path')
.data(newPath)
.enter()
.append('path')
.attr('stroke','black')
.attr('stroke-weight','1')
*/

var ln2 = svg.selectAll('polyline')
.data(clicks)
.enter()
.append('polyline')
//.attr('class','ln2')
//.attr('points',function(d) {return d})
.attr('points', function(d) { return (d)[0][1]})
.attr('stroke','rgb(180,180,180)')
.attr('stroke-width','1')
.attr('fill','none')
.attr('stroke-dasharray','4,4')


//closest dist
//console.log(clicks)
var dists = []
for (let i = 0; i < clicks.length; i++) {
var dist = getDistance(10,10,clicks[i][0],clicks[i][1])
dists.push(dist)
//console.log(dist)
}

var pt1 = projection.invert([0,0])
var pt2 = projection.invert([coords[0],coords[1]])
const distance = d3.geoDistance(pt1, pt2);
console.log(distance*6378100)


var sorted = dists.sort(function(a, b){return b - a});
console.log(sorted[sorted.length-1])
});


//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", '.3')
.style("stroke", "rgb(100,100,100)")

g.selectAll("path2") //d3 geopath
.data(sub_test.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','.6')
.style("stroke-width", '.75')
.style("stroke", "rgb(0,0,0)")


const zoomParks = g.append("g")
.selectAll("path4") //d3 geopath
.data(class_parks.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("path") //appends path to data
.attr('class','outlines')
.attr("d", path4) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", "rgb(0,200,0)")
.style("fill-opacity", ".3")
.style('stroke-opacity','.4')
.style("stroke-width", '.5')
.style("stroke", "rgb(0,0,0)")
.on('click',clicked)

function clicked(event, d) {
//console.log('hello')
const [[x0, y0], [x1, y1]] = path4.bounds(d);
event.stopPropagation();//stops other zooms from happening
//zoomParks.transition().style("fill", null);
//d3.select(this).transition().style("fill", "red");
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity
.translate(width / 2, height / 2)
.scale(Math.min(8, 0.3 / Math.max((x1 - x0) / width, (y1 - y0) / height)))
.translate(-(x0 + x1) / 2, -(y0 + y1) / 2),
d3.pointer(event, svg.node())
);
}

function reset() {
//states.transition().style("fill", null);
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity,
d3.zoomTransform(svg.node()).invert([width / 2, height / 2])
);
}


var c = svg.selectAll("circle") //d3 geopath
.data(class_subs.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class','circs')
.attr("cx", function(d) {return path1.centroid(d)[0]})
.attr("cy", function(d) {return path1.centroid(d)[1]})
.attr('r',2)
.attr('fill','black')
.style('fill-opacity','1')
.on('mouseover',subText)
.on('mouseout',textOut)


function subText(event,d,i){
console.log(class_subs.features.indexOf(d))
svg.append('text')
.attr('class','keyText')
.attr('x','100')
.attr('y','100')
.attr("font-family","Helvetica")
.attr('font-size','.45em')
.attr('font-weight','600')
.attr('fill','rgb(0,0,0)')
.attr('text-anchor','start')
.text(d.properties.name)

}

function textOut(){
d3.selectAll('text.keyText').remove()
}

function zoomed({transform}) {
g.attr("transform", transform);
}

/*
c.enter().append('circle') //d3 geopath
.data(class_subs.features)
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return path1.centroid(d)[0]})
.attr("cy", function(d) {return path1.centroid(d)[1]})
.attr('r',3)
.attr('fill','black')
.style('fill-opacity','1')
*/


//c.enter().append('circle')





return svg.node();
}
Insert cell
class_subs = FileAttachment("class_subs.geojson").json()
Insert cell
class_parks = FileAttachment("class_parks.geojson").json()
Insert cell
subSts = FileAttachment("sub_stops.geojson").json()
Insert cell
bldgs = FileAttachment("bldgs.geojson").json()
Insert cell
bbox = FileAttachment("site_boundary.geojson").json()
Insert cell
subLns = FileAttachment("subway_lines.geojson").json()
Insert cell
boundary = FileAttachment("nyc_boundary.geojson").json()
Insert cell
bb_test = FileAttachment("bounding_box_test.geojson").json()
Insert cell
sub_test = FileAttachment("sub_test.geojson").json()
Insert cell
/*
chartCopy = html`

<div class="map-embed" style='width:400px;'>
${chart}
</div>
<div class="input" style='width:100px;'>
${viewof colorInput}
${viewof message}
</div>

`*/
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