Gráficos circulares (1)

facebook-svg gplus-svg twitter-svg

Ir a Dibujar un sector circular

Los gráficos circulares ( pie chart ), también llamados gráficos de pastel, gráficos de torta o gráficas de 360°, son recursos estadísticos que se utilizan para representar porcentajes y proporciones.  Ya que sabemos como dibujar un sector circular, dibujar un gráfico circular será coser y cantar. Pero antes de ver como pongamos un poco de orden en el código.

La función coords

Vamos a escribir una función: coords() que calcula las coordenadas de un punto en la circunferencia de un círculo. La función toma como argumento el ángulo ( a ) en grados sexagesimales, lo transforma en radianes ( arad ), calcula las coordenadas x e y del punto en la circunferencia, y devuelve un objeto que almacena las dichas coordenadas.

function coords( a ){
   var arad = ( Math.PI / 180 ) * a;
   var coords = {
   "x" : cx + r * Math.cos( arad ),
   "y" : cy + r * Math.sin( arad )
   };
   return coords;
}

La función dGajo

Modificamos ligeramente la funcción dGajo() que calcula el parámetro d de <path>. Ahorra dGajo() utiliza la función coords() para calcular las coordenadas Xap, Yap, Xaf y Yaf de los dos puntos, de partida ( ap ) y final ( af ) entre los cuales dibujamos el arco circular.

function dGajo(ap,af){
var Xap = coords(ap).x;
var Yap = coords(ap).y;
var Xaf = coords(af).x;
var Yaf = coords(af).y;
            
var parametro_d =
"M" + cx + ", " + cy+
" L"+Xap+","+Yap+
" A"+r+","+r+" 0 0, 1 "+Xaf+","+Yaf+
" z";
return parametro_d;
}');

La función nuevoGajo

Como queremos dibujar varios gajos , cada uno de otro color, la función nuevoGajo(),la que dibuja un nuevo "gajo" en el lienzo SVG, toma ahora 3 argumentos: los dos ángulos af, ap  y el color de relleno.  También establecemos dos nuevos atributos de <path>: un borde ( stroke ) blanco con una grosor del borde ( stroke-width ) de 2px.

function nuevoGajo(ap,af,color){
var nuevoGajo=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");		
nuevoGajo.setAttributeNS(null,"d", dGajo(ap,af));
nuevoGajo.setAttributeNS(null,"fill", color); 
nuevoGajo.setAttributeNS(null,"stroke", "#fff"); 
nuevoGajo.setAttributeNS(null,"stroke-width", "2");
lienzoSVG.appendChild(nuevoGajo);
} 

El objeto oGrafico

Además de var lienzoSVG  ( el lienzo SVG ), var cx y cy ( las coordenadas del centro del gráfico ) y var r ( el radio del círculo ) necesitamos un objeto, oGrafico, que almacene todas las características de los sectores de círculo que componen el gráfico: el nombre, el porcentaje, y el color.

var oGrafico = [
{nombre:"vitamina A", porcentaje:"40",color:"0140CA"},
{nombre:"vitamina B", porcentaje:"12",color:"DD1812"},
{nombre:"vitamina C", porcentaje:"6",color:"16A6FE"},
{nombre:"vitamina D", porcentaje:"18",color:"6ab150"},
{nombre:"vitamina E", porcentaje:"25",color:"FCCA03"}
];

Lea este interesante articulo: Trabajando con objetos ( en JavaScript )

El bucle for ( for loop )

Utilizamos  el objeto oGrafico para crear el gráfico circular. Un bucle for ( for loop ) recorre cada elemento del array oGrafico, recupera el porcentaje y el color de cada elemento del gráfico, y lo construye, gajo por gajo. Veamos como.

1.Iniciamos dos array :

  var ap = Array(); // el array de los angulos de partida
  var af = Array(); // el array de los angulos finales
  

2. Un bucle for recorre cada elemento del array oGrafico:

for( var i=0; i < oGrafico.length; i++ ){ . . .

3. Recupera el porcentaje y el color de cada elemento del gráfico:

var porcentaje = oGrafico[i].porcentaje;
var color = oGrafico[i].color;

3. Calcula el valor del ángulo en grados sexagesimales: si un círculo entero ( 100% ) tiene 360° , ¿cuantos grados tiene el tanto%?

af[i] = ((porcentaje*360)/100);

4. Si no se trata del primer elemento del array oGrafico

if( i>0 ){

Calculamos el valor de los dos ángulos. Equiparamos el ángulo de partida al ángulo final anterior. Calculamos el nuevo ángulo final, y lo sumamos al anterior.

ap[i] = af[i-1];
af[i] += af[i-1];
}else{ap[i] = 0};
nuevoGajo(ap[i],af[i],color);

5. Cerramos el bucle.

Lo ponemos todo junto

No te olvides: siempre que sea posible, pon el JavaScript dentro del <body>, justo antes de su cierre: los estilos arriba, los scripts al fondo.

<svg id = "lienzoSVG" width="260" height="250"></svg>

var lienzoSVG = document.getElementById("lienzoSVG");
var cx = 130;
var cy = 120;
var r = 100;

var oGrafico = [
{nombre:"vitamina A", porcentaje:"40",color:"#0140CA"},
{nombre:"vitamina B", porcentaje:"12",color:"#DD1812"},
{nombre:"vitamina C", porcentaje:"6",color:"#16A6FE"},
{nombre:"vitamina D", porcentaje:"17",color:"#6ab150"},
{nombre:"vitamina E", porcentaje:"25",color:"#FCCA03"}
];

function coords(a){
	var arad = (Math.PI / 180) * a;
	var coords = {
	"x" : cx+r * Math.cos(arad),
	"y" : cy+r * Math.sin(arad)
	};
	return coords;
}

function dGajo(ap,af){
var Xap = coords(ap).x;
var Yap = coords(ap).y;
var Xaf = coords(af).x;
var Yaf = coords(af).y;

var parametro_d  = 
"M" + cx + ", " + cy+
" L"+Xap+","+Yap+ 
" A"+r+","+r+" 0 0, 1 "+Xaf+","+Yaf+ 
" z";
return parametro_d;
}

function nuevoGajo(ap,af,color){
var nuevoGajo=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");		
nuevoGajo.setAttributeNS(null,"d", dGajo(ap,af));
nuevoGajo.setAttributeNS(null,"fill", color); 
nuevoGajo.setAttributeNS(null,"stroke", "#fff"); 
nuevoGajo.setAttributeNS(null,"stroke-width", "2"); 
lienzoSVG.appendChild(nuevoGajo);
} 

var ap = Array(); // angulos de partida
var af = Array(); // angulos finales
	

for( var i=0; i < oGrafico.length; i++ ){
	var porcentaje = oGrafico[ i ].porcentaje;
	var color = oGrafico[ i ].color;
	// calcula el valor del ángulo en radianes
	af[i] = ((porcentaje*360)/100);
	
	if( i>0 ){
		af[ i ] += af[ i-1 ]
		ap[ i ] = af[ i-1 ];
	    } else { ap[ i ] = 0; }
	nuevoGajo(ap[ i ],af[ i ],color);
}

A continuación queremos añadir una animación muy sencilla: cada vez que pasamos con el ratón por encima de uno de los sectores circulares, queremos que aparezca, como una sombra, un arco de circulo del mismo color, pero con una opacidad de 40%.