chart = {
const width = 1100, height = 960;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width-50, height-50]);
var projection = d3
.geoMercator()
.fitSize([width - 50, height - 50], border);
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 path6 = d3.geoPath().projection(projection);
var path7 = d3.geoPath().projection(projection);
var geopaths = svg.append("g").attr("id", "paths");
var spots = svg.selectAll("circle")
var polyline = svg.selectAll("polyline").enter().append("polyline")
geopaths.selectAll("path1")
.data(region.features)
.enter()
.append("path")
.attr('class', 'outlines')
.attr("d", path1)
.style("fill", "rgb(255,239,224)")
.style("fill-opacity", "1")
geopaths.selectAll("path2")
.data(districts.features)
.enter() // there are more data than elements, this selects them
.append("path") // appends path to data
.attr('class', 'outlines')
.attr("d", path2) // defines a path to be drawn and only applies it to appended elements
.style("fill", "rgb(255,249,244)")
.style("fill-opacity", "1")
// .style('stroke-opacity','.1')
// .style("stroke-width", '.5')
// .style("stroke", "rgb(0,0,0)")
geopaths.selectAll("path3")
.data(water.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", path3) // defines a path to be drawn and only applies it to appended elements
.style("fill", "rgb(185,222,285)")
.style("fill-opacity", "1")
// .style('stroke-opacity','.1')
// .style("stroke-width", '.5')
// .style("stroke", "rgb(0,0,0)")
geopaths.selectAll("path4")
.data(buildings.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) // defines a path to be drawn and only applies it to appended elements
.style("fill", "rgb(255,218,185)")
.style("fill-opacity", "1")
// .style('stroke-opacity','.1')
// .style("stroke-width", '.5')
// .style("stroke", "rgb(0,0,0)")
geopaths.selectAll("path6")
.data(railwayLines.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", path6) // defines a path to be drawn and only applies it to appended elements
.style("fill", "none")
.style('stroke-opacity','1')
.style("stroke-width", '.25')
.style("stroke", "rgb(0,0,0)")
// any way to separate data based on properties?
// change size of point on QGIS and reexport file
geopaths.selectAll("path7")
.data(transitStations.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", path7) // defines a path to be drawn and only applies it to appended elements
.style("fill", "rgb(0,0,0)")
.style("fill-opacity", ".1")
// .style('stroke-opacity','1')
// .style("stroke-width", '.25')
// .style("stroke", "rgb(0,0,0)")
spots.data(places) // get data
.enter() // there are more data than elements, this selects them
.append("circle") //appends path to data
.attr("cx", function(d) {return projection([d.long,d.lat])[0]})
.attr("cy", function(d) {return projection([d.long,d.lat])[1]})
.attr('r',3)
.style('stroke','black')
.style('stroke-width','1')
.style('fill','rgb(255,185,187)')
.style('fill-opacity','1')
.on('mouseover',placeText)
.on('mouseout',removePlaceText)
function placeText(event,d) {
// console.log(d)
svg.append("text")
.attr('x', width-225)
.attr('y', 100)
.attr('class','place_position')
.style('font-family','roboto+slab')
.style('font-size','16px')
.style('font-weight','regular')
.text(d.name)
// control how many pixels wide our text block can be
var wrap = svg.selectAll("text.place_position")
.each(function(d, i) {
wrap_text(d3.select(this), 100)
});
svg.append("line")
.attr('x1', width-230)
.attr('y1', 100)
.attr('x2', projection([d.long,d.lat])[0])
.attr('y2', projection([d.long,d.lat])[1])
.attr('class','fLine')
.style('stroke-width', '1')
.style("stroke", "rgb(0,0,0)")
.style('stroke-dasharray', '6 4')
// polyline.data(name)
// .enter() // there are more data than elements, this selects them
// .append("polyline") // appends path to data
// .attr("points", function(d) {return d}) // we use a function to loop through the points
// .attr("class", 'place')
// .style('fill','black')
// .style('stroke','none')
// .style('stroke-width','.5')
}
function removePlaceText() {
d3.selectAll('text.place_position').remove() // geometry type, then class name
d3.selectAll('line.fLine').remove()
// d3.selectAll('polyline.place').remove()
}
// how do you order text so it's above the geopaths?
svg.append("text")
.attr('x','100')
.attr('y','100')
.style('font-family','roboto+slab')
.style('font-size','32px')
.style('font-weight','bold')
// .style('fill','purple') // text color
.text('Journey in Rome')
svg.append("text")
.attr('x','100')
.attr('y','130')
.style('font-family','roboto+slab')
.style('font-size','24px')
.style('font-weight','regular')
.text('Urban Data F23')
return svg.node();
}