/* ================================================ AUTHOR: JÉRÉMIE JACQUES (http://jeremiejacques.be — @jeremiejacques) TITLE: HDI BY COUNTRY IN 2012 AND 2013 - DATAVISUALISATION DESC : Datavisualisation with JSON, D3.js and jQuery for the course of jQuery at school VERSION: 1.1 LAST MODIFIED: Sun 6th Dec 2015 SOURCE AND HELP : - https://github.com/mbostock/d3/wiki/API-Reference - https://github.com/mbostock/topojson - http://www.tnoda.com/blog/2013-12-07 - http://bl.ocks.org/d3noob/5d621a60e2d1d02086bf - https://github.com/cristiroma/countries - http://bost.ocks.org/mike/map/ DATA SOURCE : https://data.undp.org/ -> http://data.undp.org/resource/myer-egms.json ================================================*/ $(document).ready(function(){ var hdiValue2012 = new Array, // create Array to push the value from JSON country2012 = new Array, hdiValue2013 = new Array, country2013 = new Array, year = "2013"; // to save the map that is show var BaseURL="http://tfa.jeremiejacques.be/json/assets/_js/myer-egms.json?accessType=DOWNLOAD"; $.getJSON(BaseURL, function(data){ for (var i = 1; i < data.human_development_index.length; i++) { // var i = 1 because first country is "Very high human development" if(typeof data.human_development_index[i] !== "undefined"){ country2012.push(data.human_development_index[i].country); // push the value from json to the array hdiValue2012.push(data.human_development_index[i]._2012); }; }; for (var i = 1; i < data.human_development_index.length; i++) { // var i = 1 because first country is "Very high human development" if(typeof data.human_development_index[i] !== "undefined"){ // verifie that there is a value before to push into array country2013.push(data.human_development_index[i].country); hdiValue2013.push(data.human_development_index[i]._2013); }; }; }).done(function(){ // when json is loaded and array completed by data var m_width = $(".svgContainer").width(), width = 938, height = 500; var projection = d3.geo.mercator() // create the map, function and informations from api .scale(150) .translate([width / 2, height / 1.5]); var path = d3.geo.path().projection(projection); // create the map, function and informations from api var svg = d3.select(".svgContainer").append("svg") // create svg and all attributes necessary to make it "responsive" .attr("preserveAspectRatio", "xMidYMid") .attr("viewBox", "0 0 " + width + " " + height) .attr("width", m_width) .attr("height", m_width * height / width); /* create the map */ d3.json("http://tfa.jeremiejacques.be/json/assets/_js/_lib/countries.topo.json?accessType=DOWNLOAD", function(error, world){ // get the json with all coordonate for the map svg.append("g") // create a group of path for the first map and append to svg .attr("id", "map2012") .style({ display : "none" // display none to show the map of 2013 on load }) .selectAll("path") .data(topojson.feature(world, world.objects.countries).features) // create the element of the map, function and informations from api .enter() // enter the data to create the path .append("path") .attr("class", function(d) { return d.properties.name; }) // add class with the name of the country for each path .attr("data-flag", function(d) { return d.id; }) // this is to get the image of flag for the tooltip .attr("data-hdi", function(d, i){ for (var i = 0; i < country2012.length; i++){ if(d.id === country2012[i]){ // compare if we have the data for each country and create attr with it return hdiValue2012[i]; }; }; }) .attr("d", path) .on("mousemove", mouseMove) .on("mouseout", mouseOut) .on("click", clickOn); svg.append("g") // create a group of path for the second map and append to svg .attr("id", "map2013") .style({ display : "block" // display on load }) .selectAll("path") .data(topojson.feature(world, world.objects.countries).features) .enter() .append("path") .attr("class", function(d) { return d.properties.name; }) // add class with the name of the country for each path .attr("data-flag", function(d) { return d.id; }) // this is to get the image of flag for the tooltip .attr("data-hdi", function(d, i){ for (var j = 0; j < country2013.length; j++){ // compare if we have the data for each country and create attr with it if(d.id == country2013[j]){ return hdiValue2013[j]; }; }; }) .attr("d", path) .on("mousemove", mouseMove) .on("mouseout", mouseOut) .on("click", clickOn); /* create the label */ svg.append("text") .attr("x", 0) // posisition x .attr("y", 500) // position y .attr("class", "legend") .attr("id", "legend2012") .text("2012") .style({ fill : "rgb(200, 200, 200)", cursor: "pointer" }) .on("click", function(){ if($(this).attr("click") != "isClicked"){ // verifie if the label is active or not $("#map2012").toggle(); // change the map and the comparator $(".comparative-2012").toggle(); $("#map2013").toggle(); $(".comparative-2013").toggle(); $("#legend2013").attr("click", ""); year = "2013" ? "2012" : "2013"; // to know which year is active if($(this).css("fill") == "rgb(200, 200, 200)"){ $(this).css("fill", "rgb(152, 119, 27)"); d3.select("#legend2013").style("fill", "rgb(200, 200, 200)"); }else{ $(this).css("fill", "rgb(200, 200, 200)"); d3.select("#legend2013").style("fill", "rgb(21, 106, 223)"); }; $(this).attr("click", "isClicked") }; }); svg.append("text") .attr("x", 70) .attr("y", 500) .attr("class", "legend") .attr("id", "legend2013") .attr("click", "isClicked") // isClicked because the 2013 map is active on load .text("2013") .style({ fill : "rgb(21, 106, 223)", cursor: "pointer" }) .on("click", function(){ if($(this).attr("click") != "isClicked"){ // verifie if the label is active or not $("#map2012").toggle(); // change the map and the comparator $(".comparative-2012").toggle(); $("#map2013").toggle(); $(".comparative-2013").toggle(); $("#legend2012").attr("click", ""); $(this).attr("click", ""); year = "2012" ? "2013" : "2012"; if($(this).css("fill") == "rgb(21, 106, 223)"){ $(this).css("fill", "rgb(200, 200, 200)"); d3.select("#legend2012").style("fill", "rgb(152, 119, 27)"); }else{ $(this).css("fill", "rgb(21, 106, 223)"); d3.select("#legend2012").style("fill", "rgb(200, 200, 200)"); }; $(this).attr("click", "isClicked"); }; }); /* Give the opacity value to all path */ d3.selectAll("#map2012 path").each(function(d, i){ for (var i = 0; i < country2012.length; i++){ if(d.id == country2012[i]){ // compare if we have the data for each country $(this).attr("style", "opacity : " + parseFloat(hdiValue2012[i]).toFixed(1) + "; fill : #98771B; cursor: pointer;").attr("data-color", "#98771B"); // add an attr style with opacity, opacity value correspond to the HDI value of this country }; }; }); d3.selectAll("#map2013 path").each(function(d, i) { // the same for 2013 for (var i = 0; i < country2013.length; i++){ if(d.id == country2012[i]){ $(this).attr("style", "opacity : " + parseFloat(hdiValue2013[i]).toFixed(1) + "; fill : #005DDE; cursor: pointer;").attr("data-color", "#005DDE"); }; }; }); }); /* function for the mouse event */ function mouseMove(){ var dataHdi = $(this).attr("data-hdi"), // get the infos of the country that is hover country = $(this).attr("class"), dataFlag = $(this).attr("data-flag"), flagURL; if(typeof dataHdi == "undefined"){ dataHdi = "HDI Indéfini"; // if there's no data for this country write this }else{ dataHdi = dataHdi + " HDI"; }; var html = $("<span/>").html(country + " : " + dataHdi); $(".tooltip").css({ // show the tooltip and position it under the mouse opacity: "1", borderColor: $(this).css("fill"), top: d3.event.pageY + 20 + "px", left: d3.event.pageX + 10 + "px" }); if(typeof dataFlag != "undefined"){ $.getJSON("http://tfa.jeremiejacques.be/json/assets/_js/_lib/countries-flag.json?accessType=DOWNLOAD", function(data){ for (var i = 0; i < data.length; i++) { if(data[i].code3l == dataFlag){ flagURL = data[i].flag_32; // get the url for the flag with the country code }; }; }).done(function(){ if(typeof flagURL != "undefined"){ flagURL = "http://tfa.jeremiejacques.be/json/assets/_img/flags/" + flagURL; // get the flag and display it in the tooltip if(flagURL != $(".tooltipFlag").attr("src")){ var flag = $("<img/>").attr("src", flagURL).height("16px").width("32px").attr("class", "tooltipFlag"); $(".tooltip").html("").append(flag, html); }; }else{ $(".tooltip").html("").append(html); }; }); }; }; function mouseOut(){ // when mouse is out of a country hide it $(".tooltip").css("opacity", "0"); }; function clickOn(){ var dataHdi = $(this).attr("data-hdi"), country = $(this).attr("class"); if(typeof dataHdi != "undefined" && $(this).attr("click") != "isClicked"){ var that = $(this); var a = $("<a/>").attr("href", "#") .on("mouseover", function(event){ navOver(event, that, $(this)); }) .on("mouseout", function(event){ navOut(event, that, $(this)); }) .on("click", function(event){ navClick(event, that, $(this)); }) .attr("class", "comparative-list-country").attr("data-country", country) .html(country + "<span class='comparative-list-country-hdi'>"+ dataHdi +"</span>"); $("<li/>").append(a).appendTo(".comparative-list-" + year); d3.select(this).style("fill", "rgb(128, 25, 62)").attr("click", "isClicked"); }else if($(this).attr("click") == "isClicked"){ d3.select(this).style("fill", d3.select(this).attr("data-color")).attr("click", ""); $(".comparative-"+ year +" .comparative-list-country[data-country='"+ country +"']").remove(); }; }; function navClick(event, elem, $this){ event.preventDefault(); $this.parent().remove(); d3.select(elem.context).style("fill", d3.select(elem.context).attr("data-color")).attr("click", ""); d3.selectAll("path").style("fill-opacity", "1"); return false; }; function navOver(event, elem, $this){ event.preventDefault(); d3.selectAll("path").style("fill-opacity", ".1"); d3.select(elem.context).style("fill-opacity", "1"); return false; }; function navOut(event, elem, $this){ event.preventDefault(); d3.selectAll("path").style("fill-opacity", "1"); return false; }; /* add the possibility to move the comparator */ $(".comparative").draggable({ cursor: "move", opacity: 0.7 }); /* on resize, change the size of svg */ $(window).resize(function() { var w = $(".svgContainer").width(); svg.attr("width", w); svg.attr("height", w * height / width); }); }); });//end of $(document).ready
<h1>Indice de développement humain par pays en 2012 et 2013</h1> <div class="tooltip"></div> <div class="svgContainer"></div> <div class="comparative"> <div class="comparative-2012"> <h2>Comparer : </h2> <p>(cliquer sur les pays que vous souhaitez comparer)</p> <ul class="comparative-list-2012 clearfix"></ul> </div> <div class="comparative-2013"> <h2>Comparer : </h2> <p>(cliquer sur les pays que vous souhaitez comparer)</p> <ul class="comparative-list-2013 clearfix"></ul> </div> </div>
@import url("http://tfa.jeremiejacques.be/json/assets/_styles/jquery-ui.css"); @import url(http://fonts.googleapis.com/css?family=Roboto+Condensed:300italic,400italic,700italic,400,300,700); html, body{ padding: 0; margin: 0; background: #D5D7E0; font-family: 'Roboto Condensed', sans-serif; } h1{ text-align: center; font-family: 'Roboto Condensed', sans-serif; font-size: 30px; } p{ text-align: center; } .tooltip{ height: auto; padding: 10px 20px; text-align: center; line-height: 50px; background: #E7E5CC; position: absolute; opacity: 0; border: solid 4px; } .tooltip img{ display: inline-block; margin-right: 10px; position: relative; top: 2px; } .legend{ font-size: 20px; } .comparative{ width: 80%; height: auto !important; max-width: 330px; top: 30px; left: 30px; position: absolute; -webkit-box-shadow: 0px 0px 20px 0px rgba(50, 50, 50, 0.4); -moz-box-shadow: 0px 0px 20px 0px rgba(50, 50, 50, 0.4); box-shadow: 0px 0px 20px 0px rgba(50, 50, 50, 0.4); cursor: move; } .comparative-2013{background-color: #A9C4E7; padding: 30px;} .comparative-2012{ background : #E4D096; padding: 30px; display: none; } .comparative-2013 ul, .comparative-2012 ul{ margin: 0; padding: 0; } .comparative-2013 li, .comparative-2012 li{ background-color: #FFFFFF; list-style: none; } .comparative-list-country:hover{ cursor: url(http://jeremiejacques.be/json/assets/_img/cross.svg) 16 12, pointer; } .comparative-list-country{ display: block; padding: 10px; margin: 10px 0; color: #666666; text-decoration: none; } span.comparative-list-country-hdi{ float: right; } .comparative-2013 h2, .comparative-2012 h2{ margin-bottom: 0; margin-top: 0; text-align: center; } .comparative-2013 p, .comparative-2012 p{ line-height: 2em; margin-top: 0; text-align: center; font-size: 10px; } .svgContainer{ width: 80%; max-width: 1200px; margin: 0 auto; margin-top: 20px; } path{ fill: #333030; stroke: rgb(255, 255, 255); stroke-width: .5px; -webkit-transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); -moz-transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); -ms-transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); -o-transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1); } .clearfix:after { content: " "; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }