//globals
var projection, path, graticule, svg, div, tooltip, borders, impacts, attributeArray = [], currentAttribute = 0, playing = false;
var width = 1000,
height = 650;
projection = d3.geo.eckert5() // define our projection with parameters
.center([5, 25]) // x, y natural position of the map when loading
.scale(215) //mapscale (natural zoom-in/out when loading page)
.rotate([-1,0]) //slides the map on a x-axis in its SVG box
.precision(.50);
path = d3.geo.path() // create path generator function
.projection(projection); // add our define projection to it
//graticule = d3.geo.graticule(); // create a graticule
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.scaleExtent([height*.33, 15 * height]) // manage zoom strength [out, in]
.on("zoom", zoom);
svg = d3.select("#map").append("svg") // append a svg to our html div to hold our map
.attr("width", width)
.attr("height", height)
.call(zoom);
function zoom() {
projection.translate(d3.event.translate).scale(d3.event.scale);
svg.selectAll("path").attr("d", path);
circles
.attr("cx", function(d){return proj([d.long, d.lat])[0];})
.attr("cy", function(d){return proj([d.long, d.lat])[1];});
}
svg.append("defs").append("path") // prepare some svg for outer container of svg elements
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
svg.append("use") // use that svg to style with css
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("path") // use path generator to draw a graticule
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
div = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0.1)
.style("background", "");
borders = svg.append("g");
impacts = svg.append("g");
queue() // queue function loads all external data files asynchronously
.defer(d3.json, "data/world-topo.json") // our geometries
.defer(d3.tsv, "data/countriesRandom.txt") // and associated data in csv file
.await(processData); // once all files are loaded, call the processData function passing
// the loaded objects as arguments
var metors;
function processData(error,world,countryData) {
// function accepts any errors from the queue function as first argument, then
// each data object in the order of chained defer() methods above
var countries = world.objects.countries.geometries; // store the path in variable for ease
for (var i in countries) { // for each geometry object
for (var j in countryData) { // for each row in the CSV
if(countries[i].properties.id == countryData[j].id) { // if they match
for(var k in countryData[i]) { // for each column in the a row within the CSV
if(k != 'name' && k != 'id') { // let's not add the name or id as props since we already have them
if(attributeArray.indexOf(k) == -1) {
attributeArray.push(k); // add new column headings to our array for later
}
countries[i].properties[k] = Number(countryData[j][k]) // add each CSV column key/value to geometry object
}
}
break; // stop looking through the CSV since we made our match
}
}
}
rawMetors = countryData;
metors = [];
rawMetors.forEach(function(d){
d.degree = +d.id;
d.popu = +d.pop;
metors.push(d);
});
metors.sort(function(a, b){return a.degree - b.degree;})
console.log(metors)
svg.selectAll(".country") // select country objects (which don't exist yet)
.data(topojson.feature(world, world.objects.countries).features) // bind data to these non-existent objects
.enter().append("path") // prepare data to be appended to paths
.attr("class", "country") // give them a class for styling and access later
.attr("id", function(d) { return "code_" + d.properties.id; }, true) // give each a unique id for access later
.attr("d", path) // create them using the svg path generator defined above
.on("mouseover", function(d){
div.transition()
.duration(100)
.style("opacity", .9)
tooltip
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 5) + "px")
.transition().duration(300)
.style("opacity", 100)
.style("display", "block")
updateDetails(d);
})
.on("mouseout", function(d){
div.transition()
.attr("stroke", "")
.attr("fill-opacity", function(d){return 1;})
.duration(500)
.style("opacity", .001)
tooltip.transition().duration(200).style("opacity", 0);
})
var dataRange = getDataRange(); // get the min/max values from the current year's range of data values
d3.selectAll('.country') // select all the countries
.attr('fill-opacity', function(d) {
return getColor(d.properties[attributeArray[currentAttribute]], dataRange); // give them an opacity value based on their current value
});
}
function getColor(valueIn, valuesIn) {
var color = d3.scale.linear() // create a linear scale
.domain([valuesIn[0],valuesIn[1]]) // input uses min and max values
.range([.3,1]); // output for opacity between .3 and 1 %
return color(valueIn); // return that number to the caller
}
function getDataRange() {
// function loops through all the data values from the current data attribute
// and returns the min and max values
var min = Infinity, max = -Infinity;
d3.selectAll('.country')
.each(function(d,i) {
var currentValue = d.properties[attributeArray[currentAttribute]];
if(currentValue <= min && currentValue != -99 && currentValue != 'undefined') {
min = currentValue;
}
if(currentValue >= max && currentValue != -99 && currentValue != 'undefined') {
max = currentValue;
}
});
return [min,max]; //boomsauce
}
var printDetails = [{'var': 'id', 'print': 'Entity'},
{'var': 'pop', 'print': 'Population'},
{'var': 'cartodb_id', 'print': 'ID de carte'}];
function updateDetails(metor){
// this section is unecessary if we don't want the image
//var image = new Image();
//image.onload = function(){
//document.getElementById("tooltipImg").src = 'pictures/' + metor.cartodb_id + '.jpg';}
//image.src = 'pictures/' + metor.cartodb_id + '.jpg';
tooltip.selectAll("div").remove();
tooltip.selectAll("div").data(printDetails).enter()
.append("div")
.append('span')
.text(function(d){return d.print + ": ";})
.attr("class", "boldDetail")
.insert('span')
.text(function(d){return metor[d.var];})
.attr("class", "normalDetail");
}
de ici...