chart = {
const width = 850,
height = 560
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width-50, height-10]);
var projection = d3
.geoMercator()
.fitSize([width, height], bbox_new);
var path = 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 g = svg.selectAll('g').attr("id", "paths");
var c = svg.selectAll("circle")
var p = svg.selectAll("polyline")
var t = svg.selectAll("text")
var l = svg.selectAll("line")
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','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 d.x})
.attr("cy",function(d) {return d.y})
.attr('r', r)
.attr('fill', sfill)
.style('fill-opacity',sOpac)
.style("stroke-width", sWidth)
}
*/
//lines from rhino
//polyline(graphic_test,'red','1','0','none','angles')
//polyline(face_outline,'rgb(255,255,0)','1','2','black','zzz')
polyline(ground,'rgb(221,221,221)','1','1','rgb(221,221,221)','zzz','5 0')
polyline(greenery,'rgb(117,130,115)','1','.6','rgb(137,150,135)','zzz','5 0')
polyline(water,'rgb(197,213,216)','1','1','rgb(197,213,216)','zzz','5 0')
polyline(roads1,'none','1','.1','black','zzz','5 0')
polyline(border,'none','1','2','rgb(122,64,64)','zzz','5 2')
polyline(yellowBorderLine,'none','1','10','yellow','zzz')
polyline(blackBorderFill,'black','1','1','black','zzz')
polyline(buildingiconblack,'black','1','1','black','zzz')
polyline(buildingiconwhite,'rgb(221,221,221)','1','1','rgb(221,221,221)','zzz')
function polyline(data, sfill, sOpac, sW, stroke,classVar,sd){
g.enter().append("polyline")
.data(data) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr('class',classVar)
.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)
.style('stroke-dasharray',sd)
}
/* //draw icons at spreadsheet location
p.enter().append("polyline")
.data(neighborhood) //get data to define path
.enter() //there are more data than elements, this selects them
.append('polyline')
.attr('class','bunny')
.attr("points", icon1) //The d attribute defines a path to be drawn, only applies to appended elements
.attr('transform', function(d) { return 'translate(' + d.x + ', ' + d.y + ')'; }) //new transform system that works with x and y
.style("fill", 'red')
.style("stroke-width", '1')
.style("stroke", 'black')
// .on("mouseover", addWireframe)
// .on("mouseout", removeWireframe)
/*
p.enter().append("polyline")
.data(zone1) //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", '2')
.style("stroke", 'black')
.style('stroke-dasharray','5 5')
.on("mouseover", addWireframe)
.on("mouseout", removeWireframe)
*/
/*
function addWireframe(event,d){
p.enter().append("polyline")
.data(wireframe) //get data to define path
.enter()
.append('polyline')
.attr('class','wireframe')
.attr("points", function(d) {return d})
.style("fill", 'none')
.style("stroke-width", '.5')
.style("stroke", 'black')
svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',50)
.attr("y",600)
.attr('fill', 'black')
.style('font-family','helvetica')
.style("font-size", "11px")
.text('this is a detail')
}
function removeWireframe(event,d){
svg.selectAll('polyline.wireframe').remove()
svg.selectAll('text.mText').remove()
}
*/
//display names from spreadsheet - use this format for points from SPREADSHEET
// t.enter().append('text')
// .data(neighborhood) //get data to define path
// .enter() //there are more data than elements, this selects them
// .append("text") //appends path to data
//.attr('class','spots')
// .attr('x',140)
// .attr("y",function(d,i){return 780 +(i*16)})
// .attr('fill', 'black')
// .style('font-family','helvetica')
/// .style("font-size", "9px")
// .style("text-anchor", "end")
// .text(function(d){return d.Name})
// .on("mouseover",musText)
// .on("mouseout",removeMusText)
/*
function removeMusText(event,d){
svg.selectAll("line.museumLine").remove()
svg.selectAll('polyline.bunny').style('fill','red')
svg.selectAll('polyline.angles').style('fill','red')
}
function musText(event,d){
svg.selectAll('polyline.bunny').style('fill','yellow')
svg.selectAll('polyline.angles').style('fill','yellow')
//THESE ARE LINES FOR ANNOTATION
l.enter().append('line')
.data(museums) //get data to define path
.enter() //there are more data than elements, this selects them
.append("line") //appends path to data
.attr('class','museumLine')
.attr('x1',145)
.attr("y1",780)
.attr('x2',projection([d.Long,d.Lat])[0])
.attr("y2",projection([d.Long,d.Lat])[1])
.attr('stroke', 'black')
.attr('stroke-width', '1.25')
.style('stroke-dasharray', '3 2')
//THESE ARE LINES FOR ANNOTATION
l.enter().append('line')
.data(museums) //get data to define path
.enter() //there are more data than elements, this selects them
.append("line") //appends path to data
.attr('class','museumLine')
.attr('x1',145)
.attr("y1",function(d,i){return 780 +(i*16)})
.attr('x2',function(d) {return projection([d.Long,d.Lat])[0]-5})
.attr("y2",function(d,i){return 780 +(i*16)})
.attr('stroke', 'black')
.attr('stroke-width', '.25')
.style('stroke-dasharray', '3 2')
l.enter().append('line')
.data(museums) //get data to define path
.enter() //there are more data than elements, this selects them
.append("line") //appends path to data
.attr('class','museumLine')
.attr('x1',function(d) {return projection([d.Long,d.Lat])[0]-5})
.attr("y1",function(d,i){return 780 +(i*16)})
.attr('x2',function(d) {return projection([d.Long,d.Lat])[0]-5})
.attr("y2",function(d) {return projection([d.Long,d.Lat])[1]+10})
.attr('stroke', 'black')
.attr('stroke-width', '.25')
.style('stroke-dasharray', '3 2')
}
*/
/*
t.enter().append('text')//theater names from QGIS - use this format for points from QGIS
.data(theaters.features) //get data to define path
.enter() //there are more data than elements, this selects them
.append("text") //appends path to data
//.attr('class','spots')
.attr('x',function(d) {return path.centroid(d)[0]})
.attr("y",function(d) {return path.centroid(d)[1]-8})
.attr('fill', 'black')
.style('font-family','helvetica')
.style('text-anchor','middle')
.style("font-size", "6px")
.text(function(d){return d.properties.NAME})
*/
//points from spreadsheet use for google sheet circles
svg.selectAll("circle")
.data(neighborhood)
.enter()
.append("circle")
.attr('class', 'spots')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('r', 5)
.attr('fill', 'yellow')
.style('fill-opacity', '2')
.style("stroke-width", "1")
.style("stroke", "black")
.on("mouseover", addText)
.on("mouseout", removeText);
function addText(event, d) {
var text1 = svg.append("text")
.attr('class', 'mText')
.attr('x', '10')
.attr('y', '500')
.attr('fill', 'black')
.style('font-family', 'Helvetica')
.style("font-size", "9px")
.text(d.Description);
var wrap1 = svg.selectAll("text.mText")
.each(function(d, i) { wrap_text(d3.select(this), 200); });
var text2 = svg.append("text")
.attr('class', 'mText')
.attr('x', '10')
.attr('y', '480')
.attr('fill', 'blue')
.style('font-family', 'Helvetica')
.style("font-size", "12px")
.text(d.Date);
var wrap2 = svg.selectAll("text.mText")
.each(function(d, i) { wrap_text(d3.select(this), 200); });
d3.select(this).datum().textElement = { text1, text2 };
}
function removeText(event, d) {
if (d.textElement) {
d.textElement.text1.remove();
d.textElement.text2.remove();
}
d3.select(this).style('fill', 'yellow');
}
//NEW STUFF PAST THIS POINT
svg//Yopougon Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '340')
.attr('y', '260')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://www.koaci.com/assets/news/thumbnails/1000/2024/10/photo_1728587834.jpg')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
/* svg//draw text
.append("text") //appends path to data
.attr('class','mText')
.attr('x',50)
.attr("y",300)
.attr('fill', 'black')
.style('font-family','helvetica')
.style("font-size", "8px")
.text('Illegal construction in Yopougon in Niangon Adjame district and the removing of the formwork of a slab caused the collapse')
*/
});
svg//Cocody Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '520')
.attr('y', '230')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://www.sabcnews.com/sabcnews/wp-content/uploads/2023/09/ivory-edited.jpg')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Cocody Collapse 2
.append('image')
.attr('class', 'picture')
.attr('x', '500')
.attr('y', '130')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://th.bing.com/th/id/OIP.oildNc6AARno2uLhVgF6NQHaD5?w=316&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Treichville Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '460')
.attr('y', '300')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://beninwebtv.com/wp-content/uploads/2022/02/Capture-web_27-2-2022_134614_afrik-plus.com_-1.jpeg')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Yopougon Bridge Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '280')
.attr('y', '180')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://media-files.abidjan.net/photo/yopougon-drame-effondrement-dun-pilier-de-lechangeur-en-construction-a-gesc_0i21a1gamk1a.jpg')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Anyama Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '370')
.attr('y', '0')
.attr('width', '100')
//.attr('height', '725')
.attr('href', 'https://www.aljazeera.com/wp-content/uploads/2020/06/339c8d8ee57944a0b4d337054aa504aa_18.jpeg?resize=770%2C513&quality=80')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Yopougon Collapse 2
.append('image')
.attr('class', 'picture')
.attr('x', '340')
.attr('y', '165')
.attr('width', '50')
//.attr('height', '725')
.attr('href', 'https://pbs.twimg.com/media/EGNWGUsWoAYQGsi?format=jpg&name=medium')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Port Bouet Accident
.append('image')
.attr('class', 'picture')
.attr('x', '490')
.attr('y', '390')
.attr('width', '70')
//.attr('height', '725')
.attr('href', 'https://cdn.punchng.com/wp-content/uploads/2017/05/31204606/Helicopter-crash.jpg')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Abodo Fire
.append('image')
.attr('class', 'picture')
.attr('x', '390')
.attr('y', '70')
.attr('width', '70')
//.attr('height', '725')
.attr('href', 'https://th.bing.com/th/id/OIP.B2DsAqYFq-u6SHcb0myRFQAAAA?w=316&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
svg//Attecoube Collapse
.append('image')
.attr('class', 'picture')
.attr('x', '410')
.attr('y', '167')
.attr('width', '70')
//.attr('height', '725')
.attr('href', 'https://www.bing.com/th?id=OIP.qym-sKLwKKmUMV4A0YPZ3QHaES&w=176&h=185&c=8&rs=1&qlt=90&o=6&dpr=1.1&pid=3.1&rm=2')
.on('mouseover', function() {
d3.select(this)
.style('opacity', 1); // Visible
})
.on('mouseout', function() {
d3.select(this)
.style('opacity', 0); // Invisible
});
return svg.node();
}