Skip to content

Instantly share code, notes, and snippets.

@Andrew-Reid
Created January 26, 2018 22:28
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Andrew-Reid/c1db394cca3d312703c0fe1b807f20fd to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
<style>
path {
fill: none;
stroke: black;
stroke-width: .7px;
}
#tooltip {
position: absolute;
display: block;
z-index: 100;
max-width: 200px;
max-height: 400px;
padding: 15px;
background-color: white;
overflow: auto;
}
.showing {
opacity: 1;
}
.notShowing {
opacity: 0;
}
span {
clear: both;
display: inline-block;
font-style: italic;
font-size: .8em;
}
</style>
<body>
</body>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>
var width = 960;
var height = 600;
var margin = {top: 0, bottom: 0, left: 0, right: 0}
var bigCities = new Map();
var icon = 8;
var cirSize = 5;
d3.queue()
.defer(d3.json, "world.json")
.defer(d3.csv, "storyList.csv")
.await(ready)
function ready(error, world, cities) {
// IF WE WANTED TO USE A MAP INSTEAD
/*
cities.forEach(function(d){
bigCities.set(d.city, {"lat": +d.lat, "lon": +d.lng, "url": d.url, "exLink": d.exLink})
// console.log(bigCities.get(d.city)) <-- Data is storied in bigCities.get(d.city)
})
// Define Data variable for binding.
var data = Array.from(bigCities.values())
console.log(data) // Create an array of key-value pairs for mapping (can also access them with bigCities.entries())
// console.log(Array.from(bigCities.values())) // Create an array of just values
// console.log(Array.from(bigCities.keys())) // Create an array of just values
*/
// Create Generator
var projection = d3.geoMercator()
var path = d3.geoPath().projection(projection) // Geopath generator
var zoomExtent = d3.zoom().scaleExtent([1, 20]);
function zoom() {
var iconMove = icon/d3.event.transform.k;
g.attr("transform", d3.event.transform)
d3.selectAll(".storyImages")
.attr("width", `${iconMove}px`)
.attr("height", `${iconMove}px`)
.attr("x", (d) => projection([d.lng,d.lat])[0] - iconMove/2)
.attr("y", (d) => projection([d.lng,d.lat])[1] - iconMove/2)
d3.selectAll("circle")
.attr("r", function(){
return cirSize/d3.event.transform.k
})
}
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.style("background-color","lightgrey")
.call(zoomExtent
.on("zoom", zoom))
var g = svg.append("g")
.attr("class", "mapInformation")
.attr("transform",`translate(8,${margin.top})`)
var paths = g.selectAll("path")
.data(world.geometries)
.enter()
.append("path")
.attr("d", path)
.attr("transform","translate(0,0)")
var tooltip = d3.select("body")
.append("div")
.attr("id","tooltip")
.style("pointer-events", "none")
.style("top", height/2 + "px") // iniital x and y coordinates of tooltip
.style("left",width/2 + "px")
.style("opacity", 0)
var stories = g.selectAll("g.story")
.data(cities) // this could also be our data.values() Map
.enter()
.append("g")
.attr("class","story")
/* var icons = stories.append("image")
.attr("xlink:href", d => d.pubIcon)
.attr("class","storyImg")
.attr("width", "15px")
.attr("height", "15px")
.attr("x", (d) => projection([d.lat,d.lon])[0])
.attr("y", (d) => projection([d.lon,d.lat])[1])
*/
var circles = stories.append("circle")
.attr("cx", (d) => projection([d.lng,d.lat])[0])
.attr("cy", (d) => projection([d.lng,d.lat])[1])
.attr("r", cirSize)
.attr("fill","red")
var icons = stories.append("image")
.attr("xlink:href",(d)=> d.pubIcon)
.attr("class","storyImages")
.attr("x", (d) => projection([d.lng,d.lat])[0] - icon/2)
.attr("y", (d) => projection([d.lng,d.lat])[1] - icon/2)
.attr("width", `${icon}px`)
.attr("height", `${icon}px`)
.on("mouseover", showStory)
.on("mouseleave",hideStory)
.on("click", function(d){
window.open(d.exLink, "_blank")
})
function showStory(d){
$.ajax({
type: 'GET',
url: d.url,
success: function(result){
d3.select("#tooltip").html(result)
}
})
d3.select("#tooltip")
.transition()
.style("opacity",1)
.style("left", ()=> d3.event.x - (icon/2) + "px")
.style("top", ()=> d3.event.y - (icon/2) + "px")
}
function hideStory(){
console.log("OUT")
d3.select("#tooltip")
.transition()
.style("opacity",0)
}
}
</script>
city lat lng url exLink pubIcon
Zareh Sharan 39.9334 32.8597 samplePage1.txt https://www.nytimes.com/2016/12/19/world/europe/russia-ambassador-shot-ankara-turkey.html https://image.freepik.com/free-icon/news_318-32311.jpg
Taloqan 36.72999904 69.54000364 samplePage2.txt https://www.washingtonpost.com/world/middle_east/turkeys-erdogan-vows-to-press-offensive-on-us-backed-kurds-in-syria/2018/01/22/04be5bae-ff7c-11e7-86b9-8908743c79dd_story.html?utm_term=.a7edc1892abf https://image.freepik.com/free-icon/news_318-32311.jpg
Boston 42.3601 71.0589 samplePage3.txt http://www.wbur.org/artery/2018/01/22/womens-march-poster-archive https://image.flaticon.com/icons/svg/34/34099.svg
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment