Public
Edited
Jul 18, 2024
Insert cell
Insert cell
chart = {
const width = 900,//pixel size of the map
height = 900;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width-50, height-10]);

// Use Mercator projection
var projection = d3
.geoMercator()//projection system used
.fitSize([width, height], bbbox);//out bounding box is here

var path = d3.geoPath().projection(projection);//need one of these for each line layer from qgis
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.selectAll('g').attr("id", "paths");//qgis lines variable //one variable for each geometry type
var c = svg.selectAll("circle")//for circles
var p = svg.selectAll("polyline")//for polylines from rhino
var t = svg.selectAll("text")


//static lines from qgis
//staticLines(path3, subways.features,"none",1,.5,"rgb(180,180,180)")
staticLines(path3, police_zones.features,"rgb(31,41,56)",1,.75,"white")
staticLines(path4, parks.features,"rgb(9,76,34)",'.25','.1',"rgb(0,255,0)")
staticLines(path5, roadLines.features,"none",'1','.25',"white")

function staticLines(path, data, sfill, sOpac, sW, stroke){

g.enter().append("path")
.data(data) //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", path) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", sfill)
.style('stroke-opacity',sOpac)
.style("stroke-width", sW)
.style("stroke", stroke)
}


//static points from qgis
// staticCircles(restrooms.features,'2','black','1',"0")//
staticCircles(theaters.features,'4','blue','0',"0")
staticCircles(alarm_boxes1.features,'3','rgb(255,120,21)','1',"0")

function staticCircles(data,r,sfill, sOpac, sWidth){

c.enter().append('circle')
.data(data) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('cx',function(d) {return path.centroid(d)[0]})
.attr("cy",function(d) {return path.centroid(d)[1]})
.attr('r', r)
.attr('fill', sfill)
.style('fill-opacity',sOpac)
.style("stroke-width", sWidth)
}


//lines from rhino
polyline(graphic_test,'none','1','0','none')
polyline(base_border,'rgb(186,191,198)','1','0','none')
polyline(headline,'rgb(29,28,31)','1','0','none')
polyline(empty_headlines,'rgb(186,191,198)','1','.0','none')
polyline(drone_outlines,'none','1','.3','rgb(84,92,112)')
function polyline(data, sfill, sOpac, sW, stroke){

g.enter().append("polyline")
.data(data) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr("points", function(d){return d}) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", sfill)
.style('stroke-opacity',sOpac)
.style("stroke-width", sW)
.style("stroke", stroke)
}

//draw icons at spreadsheet location
p.enter().append("polyline")
.data(home) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr("points", icon31) //The d attribute defines a path to be drawn, only applies to appended elements
// .attr('transform',function(d) {return 'translate('+projection([d.Long,d.Lat])[0]+','+projection([d.Long,d.Lat])[1]+')'})//
.attr('transform','translate(60,-190)')
.style("fill", 'rgb(31,41,56)')
.style("stroke-width", '0')
.style("stroke", 'none')
.on("mouseover", addexplodedlines)
.on("mouseout", removeexplodedlines)

p.enter().append("polyline")
.data(home) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr("points", icon4) //The d attribute defines a path to be drawn, only applies to appended elements
// .attr('transform',function(d) {return 'translate('+projection([d.Long,d.Lat])[0]+','+projection([d.Long,d.Lat])[1]+')'})//
.attr('transform','translate(60,-190)')
.style("fill", 'white')
.style("stroke-width", '0')
.style("stroke", 'none')
.on("mouseover", addexplodedlines)
.on("mouseout", removeexplodedlines)
p.enter().append("polyline")
.data(drone_outlines) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr("points", function(d) {return d}) //The d attribute defines a path to be drawn, only applies to appended elements
.style("fill", 'white')
.style('fill-opacity','0')
.style("stroke-width", '.3')
.style("stroke", 'rgb(84,92,112)')
//.style('stroke-dasharray','5 5')//
.on("mouseover", addexplodedlines)
.on("mouseout", removeexplodedlines)

function addexplodedlines(event,d){

p.enter().append("polyline")
.data(exploded_lines) //get data to define path
.enter()
.append('polyline')
.attr('class','wireframe')
.attr("points", function(d) {return d})
.style("fill", 'none')
.style("stroke-width", '.25')
.style("stroke", 'rgb(244,186,3)')

svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',30)
.attr("y",800)
.attr('fill', 'black')
.style('font-family','helvetica')
.style("font-size", "11px")
.text('The yellow line connects the police stations in each area with the alarm boxes located within 1000 meters away')
var wrap = svg.selectAll("text.mText")
.each(function(d, i) { wrap_text(d3.select(this), 100) });
}
function removeexplodedlines(event,d){
svg.selectAll('polyline.wireframe').remove()
svg.selectAll('text.mText').remove()
}


//points from spreadsheet
c.enter().append('circle')
.data(home) //get data to define path
.enter() //there are more data than elements, this selects them
.append("circle") //appends path to data
.attr('class','spots')
.attr('cx',function(d) {return projection([d.Long,d.Lat])[0]})
.attr("cy",function(d) {return projection([d.Long,d.Lat])[1]})
.attr('r', 6)
.attr('fill', 'white')
.style('fill-opacity','1')
.style("stroke-width", "1")
.style("stroke", "Black")
.on("mouseover", addText)
.on("mouseout", removeText)
function addText(event,d){

svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',projection([d.Long,d.Lat])[0]+8)
.attr("y",projection([d.Long,d.Lat])[1])
.attr('fill', 'white')
.style('font-family','helvetica')
.style("font-size", "10px")
.text(d.Name)

svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',30)
.attr("y",800)
.attr('fill', 'black')
.style('font-family','helvetica')
.style("font-size", "10px")
.text(d.Description)
var wrap = svg.selectAll("text.mText")
.each(function(d, i) { wrap_text(d3.select(this), 100) });
}

function addText2(event,d){

svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',projection([d.Long,d.Lat])[0])
.attr("y",projection([d.Long,d.Lat])[1])
.attr('fill', 'black')
.style('font-family','helvetica')
.style("font-size", "15px")
.text('this is some new text')
}
function removeText(){
svg.selectAll('text.mText').remove()
}


return svg.node();
}
Insert cell
icon4 = FileAttachment("icon4.txt").tsv({array:true})
Insert cell
icon31 = FileAttachment("icon3@1.txt").tsv({array:true})
Insert cell
exploded_lines = FileAttachment("exploded_lines.txt").tsv({array:true})
Insert cell
drone_outlines = FileAttachment("drone_outlines.txt").tsv({array:true})
Insert cell
icon2 = FileAttachment("icon2.txt").tsv({array:true})
Insert cell
empty_headlines = FileAttachment("empty_headlines.txt").tsv({array:true})
Insert cell
headline = FileAttachment("headline.txt").tsv({array:true})
Insert cell
base_border = FileAttachment("base_border.txt").tsv({array:true})
Insert cell
alarm_boxes1 = FileAttachment("alarm_boxes1.geojson").json()
Insert cell
police_zones = FileAttachment("police_zones.geojson").json()
Insert cell
roadLines = FileAttachment("road lines.geojson").json()
Insert cell
bbbox = FileAttachment("bbbox.geojson").json()
Insert cell
zone1 = FileAttachment("zone1.txt").tsv({array:true})
Insert cell
wireframe = FileAttachment("wireframe.txt").tsv({array:true})
Insert cell
icon1 = FileAttachment("icon1.txt").tsv({array:true})
Insert cell
Insert cell
Insert cell
mouth = FileAttachment("mouth.txt").tsv({array:true})
Insert cell
eyes = FileAttachment("eyes.txt").tsv({array:true})
Insert cell
face_outline = FileAttachment("face_outline.txt").tsv({array:true})
Insert cell
bbox_new = FileAttachment("bbox_new.geojson").json()
Insert cell
graphic_test = FileAttachment("graphic_test.txt").tsv({array:true})
Insert cell
bbox1 = FileAttachment("bbox@1.geojson").json()
Insert cell
theaters = FileAttachment("theaters.geojson").json()
Insert cell
restrooms = FileAttachment("restrooms.geojson").json()
Insert cell
subways = FileAttachment("subways.geojson").json()
Insert cell
parks = FileAttachment("parks.geojson").json()
Insert cell
dining_lines = FileAttachment("dining_lines.geojson").json()
Insert cell
Insert cell
spots = d3.csv(spotsLink,d3.autoType)
Insert cell
import { wrap_text, wrap_text_nchar } from "@ben-tanen/svg-text-and-tspan-word-wrapping"
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