//codigo D3.js
// DIMENSIONES
var margin = { top: 10, right:10, bottom: 15, left: 20 },
width = 950 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
//variable para el tolltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("display", "none");
// SVG lo añadimos a la etiqueta html para albergar el grafico
var svg = d3.select('#grafico')
.append('svg')
.attr('width', width + margin.left + margin.right) // width + margin
.attr('height', height + margin.top + margin.bottom) // height + margin
.append('g') // se añade un grupo
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
d3.csv('datosTratados.csv', function(error, csvData) {
if (error) throw error;
//los datos ya están tratados en R, a priori no nos hará falta tratar datos aquí
// pero al preparar la gráfica la primera vez vemos outliers que debemos eliminar en haras de ver patrones
csvData = csvData.filter(function(d) { return d.mean_gdp_capita < 58000; });
//calculamos los máximos valores de las variables
var maxX = d3.max(csvData,function(d){
return parseFloat(d.mean_gdp_capita);
});
var maxY = d3.max(csvData,function(d){
return parseInt(d.mean_life_expentacy);
});
//definir escalas
var xScale = d3.scaleLinear()
//.domain([100,d3.max(csvData,function(d){return d.mean_gdp_capita;})])
.domain([0,maxX+1000])
.range([margin.left, width-margin.right-40]);
var yScale = d3.scaleLinear()
.domain([40,d3.max(csvData,function(d){return d.mean_life_expentacy;})])
.range([height-margin.bottom, margin.top]);
var rScale = d3.scaleSqrt()
.domain(d3.extent(csvData, function(d) { return +d.mean_births_per_woman; }))
.range([5, 30]);
var colorScale = d3.scaleOrdinal()
.domain(['South Asia', 'Europe & Central Asia', 'Middle East & North Africa', 'East Asia & Pacific', 'Sub-Saharan Africa', 'Latin America & Caribbean', 'North America']) // también se pueden sacar de lo datos
.range(['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d']); //colores de color Brewer
// Declara e inserta los ejes aquí!
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisRight(yScale);
//añadimos el eje
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(' + 0 + ',' + (height - margin.bottom) + ')')
.call(xAxis)
.append('text')
.attr('x', margin.left+20)
.attr('y', margin.bottom+12)
.text('GDP per cápita (US$)');
svg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + (width-50) + ',' + 0 + ')')
.call(yAxis)
.append('text')
.attr('x', -70)
.text('Esperanza de vida (años)');
//creamos los circulos para cada país
svg.selectAll('circle')
.data(csvData)
.enter()
.append('circle')
.attr('cx', width/2)
.attr('cy', height/2)
.style("display", 'none')
.attr('r', function(d) {return rScale(d.mean_births_per_woman)})
.style('fill', function(d) {return colorScale(d.region)})
.attr('id', function(d) {return(d.region.substring (0, 3))})
.style('stroke', 'white')
.style('stroke-opacity', 0.5)
.style('opacity', 0.7)
.on('mouseover', function(d){
//definimos funciones al pasar el ratón por encima
d3.select(this)
.style("opacity", 0.9)
.style("stroke","black")
.style("stroke-width",1.5)
.transition()
.duration(400)
.attr('r', parseFloat(d3.select(this).attr('r'))+10);
//mostramos la información añadida
div.style('display', 'inline')
.style("opacity", 0)
.transition()
.duration(500)
.style("opacity", 1);
div.html(
'' + d.country + '
'
+"GDP per cápita: "+ parseFloat(d.mean_gdp_capita).toFixed(0) +"
"
+"Esp media de vida: "+ parseFloat(d.mean_life_expentacy).toFixed(1) +"
"
+"Nacimientos por mujer: "+ parseFloat(d.mean_births_per_woman).toFixed(1) +"
"
+"Población media: "+ parseFloat(d.mean_population).toFixed(1) +""
)
.style('left', width/2.2)
.style('top', height);
})
.on('mouseout', function(d){
//definimos funciones al quitar el ratón
d3.select(this)
.style('stroke', 'white')
.style('stroke-opacity', 0.5)
.style('opacity', 0.7)
.transition()
.duration(400)
.attr('r', function(d) {return rScale(d.mean_births_per_woman)});
//quitamos la información añadida
div.transition().duration(400).style("opacity", 0);
});
//creamos el botón para inciar
svg.append("rect")
.attr('id', 'comienzo')
.attr("width", 150)
.attr("height", 50)
.attr('x', width/2 - 75)
.attr('y', height/2 -25)
.style('fill', 'lightgrey')
.style("cursor", "default")
.style("stroke","black")
.style("stroke-width",1.5)
.style('cursor', 'pointer')
.on('click', comenzar);
svg.append('text')
.text('Comenzar')
.attr('id', 'comienzo')
.attr("x", width/2 - 40)
.attr("y", height/2 +7)
.style('cursor', 'pointer')
.on('click', comenzar);
//Generamos la LEYENDA y la añadimos al svg
var legend = svg.selectAll(".legend")
.data(colorScale.domain())
.enter().append("g")
.attr("class", "legend")
.attr('id', function(d){return(d.substring (0, 3))})
.style('opacity', 1)
.attr("transform", function(d, i) {return "translate("+(width+-200)+","+(170+(i*20)) + ")"; })
.on('click', function(d){
var newOpL = d3.select(this).style('opacity');
var newOp
if(newOpL == 1) {
newOpL = 0.2; newOp = 'none';
}
else {
newOpL = 1; newOp = '';
};
d3.selectAll("#"+d3.select(this).attr('id')).transition()
.duration(500).style("opacity", newOpL-0.3).style("display", newOp);
d3.selectAll(".legend").filter("#"+d3.select(this).attr('id')).transition()
.duration(500).style("opacity", newOpL).style("display", '');
});
// dibujamos cada bullet de la legenda con su color particular
legend.append('rect')
.attr('width', 16)
.attr('height', 17)
.attr("x", -52)
.attr("y", -9)
.style('fill', colorScale)
.style('stroke', colorScale)
.style("cursor", "pointer");
//ponemos el texto correspondiente a la leyenda
legend.append("text")
.attr("x", -33)
.attr("y", 3)
.text(function(d) { return d;})
.style("font-family","arial")
.style("font-size","11")
.style("font-weight","400")
.style('fill', colorScale)
.style("cursor", "pointer");
//función para mover las burbujas a su posición
function comenzar(){
svg.selectAll('#comienzo')
.style("display", 'none');
svg.selectAll('circle')
.style("display", '')
.transition(1200)
.attr('cx', function(d) {return xScale(d.mean_gdp_capita)})
.attr('cy', function(d) {return yScale(d.mean_life_expentacy)})
.attr('r', function(d) {return rScale(d.mean_births_per_woman)})
};
});