/******************************* ** By: Jorge Villanueva Sanz ** *******************************/ /** * Referencias utilizadas * Proyectos similares * https://gitlab.inf.uva.es/desi_22-23/icendiossequia * * Otras * - https://d3-graph-gallery.com/graph/choropleth_hover_effect.html */ // Definimos area de dibujo const WIDTH_MAP = 700; const HEIGHT_MAP = 400; // Paleta de colores en formato diccionario const paleta = { "gasolina": [ "rgb( 161, 161, 161)", "rgb( 138, 138, 138)", "rgb( 92, 92, 92)", "rgb( 69, 69, 69)", "rgb( 23, 23, 23)"], "gasoil": [ "rgb( 44, 207, 230)", "rgb( 56, 173, 190)", "rgb( 52, 145, 175)", "rgb( 44, 82, 156)", "rgb( 36, 56, 94)"]}; // Limites de cada grupo const GASOLINA_MIN = 161; const GASOLINA_MEDMIN = 175; const GASOLINA_MEDMAX = 189; const GASOLINA_MAX = 203; const GASOIL_MIN = 148; const GASOIL_MEDMIN = 163; const GASOIL_MEDMAX = 177; const GASOIL_MAX = 192; // La utilizamos para obtener información sobre si es la primera o la segunda pulsación sobre la misma provincia var lastProv; /** * Función principal. * Muestra los datos para el año y variable seleccionada * * @param {int} year Obtenido del slider * @param {String} selectedVar Obtenido de la selectBox */ function plotCyL(mes, selectedVar){ // Eliminamos todo lo que pudiera haber anteriormente d3.select("#mapa").selectAll("svg").remove(); // Abrimos el geoJson d3.json(MAP_DATA).then((mapData)=>{ var svg = d3.select("#mapa") .append("svg") .attr("width", WIDTH_MAP) .attr("height", HEIGHT_MAP); // Proyeccion var projection = d3.geoMercator(); var geoPath = d3.geoPath(projection); // Calculo tamaño original, calculando los valores maximos y minimos de las coordenadas x e y del mapa var Xmax = 0; var Xmin = WIDTH_MAP; var Ymax = 0; var Ymin = HEIGHT_MAP; numPaths = mapData.features.length; mapData.features.forEach(function(data2,i) { var bordeInfX = geoPath.bounds(data2)[0][0]; if (bordeInfX < Xmin) { Xmin = bordeInfX; } var bordeInfY = geoPath.bounds(data2)[0][1]; if (bordeInfY < Ymin) { Ymin = bordeInfY; } var bordeSupX = geoPath.bounds(data2)[1][0]; if (bordeSupX > Xmax) { Xmax = bordeSupX; } var bordeSupY = geoPath.bounds(data2)[1][1]; if (bordeSupY > Ymax) { Ymax = bordeSupY; } }); var porcentajeAjuste = 1.8 // se ajusta el grafico a este porcentaje de la ventana var proporcionX = WIDTH_MAP / (Xmax - Xmin); // se ve cuantas veces puedo aumentar en esta dimension var proporcionY = HEIGHT_MAP / (Ymax - Ymin); // idem para Y if (proporcionX < proporcionY) // ajusto al porcentaje maximo en la dimension X { var escala = Math.floor((WIDTH_MAP*porcentajeAjuste)/(Xmax-Xmin)); } else{ var escala = Math.floor((HEIGHT_MAP*porcentajeAjuste)/(Ymax-Ymin)); } // Multiplicador de escala escala = escala*projection.scale(); projection = d3.geoMercator().scale(escala); geoPath = d3.geoPath(projection); // Se calcula el centro de cada path (Provincia), y con estos el del centro del mapa, // ajustando este al centro del elemento svg var centroX = 0; var centroY = 0; var numPaths = mapData.features.length; mapData.features.forEach(function(data2,i) { centroX = centroX + geoPath.centroid(data2)[0]; centroY = centroY + geoPath.centroid(data2)[1]; }); centroX = centroX / numPaths; centroY = centroY / numPaths; var offsetX = projection.translate()[0]; var offsetY = projection.translate()[1]; var transX = Math.floor((WIDTH_MAP/2)-centroX)+offsetX; var transY = Math.floor((HEIGHT_MAP/2)-centroY)+offsetY; projection = projection.translate([transX,transY]); geoPath = d3.geoPath(projection); d3.csv(mes).then(function(data) { data.forEach(function(data) { /******************************* * AÑADIMOS LOS DATOS AL JSON ** *******************************/ var dataProvincia = data.provincia; var dataGasolina = data.pvpG95; var dataGasoleo = data.pvpGOA; mapData.features.forEach(function(features) { var mapProvincia = features.properties.name; if (dataProvincia == mapProvincia) { // Añadimos los datos a cada provincia del año seleccionado features.properties.pvpG95 = dataGasolina; features.properties.pvpGOA = dataGasoleo; // Colores features.properties.colorGasolina = coloresMapa(dataGasolina, 'gasolina'); features.properties.colorGasoil = coloresMapa(dataGasoleo, 'gasoil'); } }); }); //Dibujamos el mapa svg.selectAll("path") .data(mapData.features) .enter() .append("path") // ATRIBUTOS .attr("d", geoPath) .attr("provincia", function (d) { return d.properties.provincia; }) .attr("pvpG95", function (d) { return d.properties.pvpG95; }) .attr("pvpGOA", function (d) { return d.properties.pvpGOA; }) // STYLE .style("opacity", 0.95) .style("stroke", "gold") .style("fill", function(d) { // Pintamos la variable seleccionada var valor; switch(selectedVar) { case 'gasolina': valor = d.properties.pvpG95; if (valor) { return d.properties.colorGasolina; } else { return "#FFF" /*No hay datos*/; } case 'gasoil': valor = d.properties.pvpGOA; if (valor) { return d.properties.colorGasoil; } else { return "#FFF" /*No hay datos*/; } } }) // EVENTS .on("click", function(d, prov){muestraLineChart(prov);}) .on("mousemove", handlerMouseOver) .on("mouseout", handlerMouseOut); }); }) }; /** * Devuelve el color de la categoría del valor introducido según el indicador * * @param {int} valor * @param {Sring} indicador * @returns */ function coloresMapa(valor, indicador) { var color; console.log("Color") console.log(indicador) switch(indicador) { case 'gasolina': color = paleta['gasolina']; console.log(valor) if(valor < GASOLINA_MIN ){ colorDato = color[0]} else if (valor >= GASOLINA_MIN && valor < GASOLINA_MEDMIN ){ colorDato = color[1]} else if (valor >= GASOLINA_MEDMIN && valor < GASOLINA_MEDMAX ){ colorDato= color[2]} else if (valor >= GASOLINA_MEDMAX && valor < GASOLINA_MAX ){ colorDato= color[3]} else if (valor > GASOLINA_MAX ){ colorDato= color[4]} break; case 'gasoil': color = paleta['gasoil']; console.log(valor) if(valor < GASOIL_MIN ){ colorDato = color[0]} else if (valor >= GASOIL_MIN && valor < GASOIL_MEDMIN ){ colorDato = color[1]} else if (valor >= GASOIL_MEDMIN && valor < GASOIL_MEDMAX ){ colorDato= color[2]} else if (valor >= GASOIL_MEDMAX && valor < GASOIL_MAX ){ colorDato= color[3]} else if (valor > GASOIL_MAX ){ colorDato= color[4]} break; } return colorDato; }; /** * Manejador del ratón cuando se sitúa sobre una provincia. * Muestra la información resumida y resalta la provincia en cuestión. * */ function handlerMouseOver() { // borramos lo que pudiera haber en la etiqueta document.getElementById("infoResumen").innerHTML=""; // Resalta la provincia seleccionada d3.selectAll("path").style("opacity", .1); d3.select(this).style("opacity", 1); // Obtenemos la posición del ratón function position(event) { var x = event.clientX; var y = event.clientY; return{x,y} } // posRaton contiene las coordenadas {x, y} de la posicion del ratón en la pantalla posRaton = position(event); // colocamos la etiqueta en la posicion relativa al raton que queremos posRaton.x = posRaton.x - 205; posRaton.y = posRaton.y - 95; // modificamos la posicion del div que contiene la etiqueta para que aparezca donde hemos establecido d3.select("#infoResumen") .style("display","block") // cambiamos la visibilidad del div que inicialmente estaba oculto .style("left", posRaton.x+"px") .style("top" ,posRaton.y+"px"); // creamos un elemento svg para representar la etiqueta mediante un rectangulo con borde al que introducimos texto var svg = d3.select("#infoResumen") .append("svg") .attr("width", 200) .attr("height", 90); var etiqueta = svg.append("g"); // Obtenemos los datos que vamos a mostrar var provincia = this.__data__.properties.name; var g95 = this.__data__.properties.pvpG95; var goa = this.__data__.properties.pvpGOA; // Nombre de la provincia etiqueta.append("text") .style("font-size", "15px") .style("font-weight", "bold") .attr("x", 10) .attr("y", 20) .text(provincia); // Precio gasolina etiqueta.append("text") .style("font-size", "15px") .attr("x", 10) .attr("y", 40) .text("Gasolina 95: "+g95); // Precio gasoil etiqueta.append("text") .style("font-size", "15px") .attr("x", 10) .attr("y", 60) .text("Gasóleo A: "+goa); } /** * Devuelve el mapa a la situación normal * */ function handlerMouseOut() { // Volvemos recuperar la misma tonalidad d3.selectAll("path").style("opacity", 1); // Vaciamos el contenido del div donde hemos creado la etiqueta y lo ocultamos document.getElementById("infoResumen").innerHTML=""; d3.select("#infoResumen").style("display","none"); }