Gráficos circulares (2)

facebook-svg gplus-svg twitter-svg

Ir a Gráficos circulares (1)

Añadir una amimación con <set>

Además de dibujar los sectores circulares, 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 círculo del mismo color, pero con una opacidad de 40%.
Para esto dibujamos un trazado <path id="sombra". . . cuyos atributos stroke-opacity="0.4" y  stroke-width="0".

<path id="sombra" d="M119, 54 A100,100 0 0, 1250,150" fill="none" stroke="#FCCA03" 
 	stroke-opacity="0.4" 
 	stroke-width="0" ></path>

Ya que la grosor de línea stroke-width="0", el trazado será prácticamente invisible.

Importante: tanto el trazado que dibuja el "gajo" como el trazado que dibuja la "sombra" tienen una identificación ( id ) para poder referenciarlos después, utilizando los atributos begin y end de <set> .

<path id= "gajo" d="M150, 150 L119,54 A100,100 0 0, 1 250,150 z". . .
<path id= "sombra"         d="M119,54 A100,100 0 0, 1 250,150". . .      

Dentro del elemento <path id="sombra" aparece anidado un elemento <set> que hace que la grosor de línea ( attributeName = "stroke-width" ) cambie a 15px ( to="15" ) cada vez que pasamos con el ratón por encima ( mouseenter ). La animación acaba cuando el ratón se sale ( mouseleave ) fuera del gajo o de la sombra.

begin= "gajo.mouseenter; sombra.mouseenter;"
end= "gajo.mouseleave; sombra.mouseleave;" >


   
   
      
   
   Por favor, pase por encima con el ratón
Por favor, pase por encima con el ratón

A continuación escribiremos las funciones necesarias para conseguir este efecto.

La función dSombra

Muy parecida a la función dGajo, la función dSombra calcula el parámetro d de <path> para dibujar un arco de círculo entre los puntos ap y af.

function dSombra(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" + Xap + ", " + Yap+
                       " A"+r+","+r+" 0 0, 1"+Xaf+","+Yaf;
    return parametro_d;
}

La función nuevaSombra

Crea un nuevo elemento <path> y establece los atributos necesarios para dibujar la "sombra". En el caso de id utiliza la variable i del bucle for para atribuir una identificación única a cada arco de círculo que dibujamos:

nuevaSombra.setAttributeNS( null, "id", "sombra"+i ).

Después de adjuntar ( append ) el nuevo elemento al DOM  como hijo del lienzo SVG.

lienzoSVG.appendChild( nuevaSombra );

creamos un nuevo elemento <set> y lo dotamos con los atributos necesarios.
Finalmente adjuntamos ( append ) el nuevo elemento al DOM, como hijo de nuevaSombra.

function nuevaSombra(ap,af,color, i ){
   
var nuevaSombra=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");
nuevaSombra.setAttributeNS(null,"id", "sombra"+i); 		
nuevaSombra.setAttributeNS(null,"d", dSombra(ap,af));
nuevaSombra.setAttributeNS(null,"fill", "none"); 
nuevaSombra.setAttributeNS(null,"stroke", color);
nuevaSombra.setAttributeNS(null,"stroke-opacity", .4); 
nuevaSombra.setAttributeNS(null,"stroke-width", 0);
  
lienzoSVG.appendChild(nuevaSombra);
  
var sombraSet = document.createElementNS("http:\/\/www.w3.org/2000/svg","set");
sombraSet.setAttributeNS(null,"attributeName", "stroke-width");
sombraSet.setAttributeNS(null,"attributeType", "XML");
sombraSet.setAttributeNS(null,"to", 15);
sombraSet.setAttributeNS(null,"begin", "gajo"+i+".mouseover; sombra"+i+".mouseover");
sombraSet.setAttributeNS(null,"end", "gajo"+i+".mouseleave; sombra"+i+".mouseleave");
  
nuevaSombra.appendChild(sombraSet);
}

La función nuevoGajo

Modificamos ligeramente la función nuevoGajo añadiendo otro atributo: id, que exactamente como en el caso de nuevaSombra utiliza la variable i del bucle for para generar una identificación única.

function nuevoGajo (ap,af,color,i){
var nuevoGajo=document.createElementNS ("http:\/\/www.w3.org/2000/svg","path");
nuevoGajo.setAttributeNS (null,"id", "gajo"+i);
nuevoGajo.setAttributeNS (null,"d", dGajo (ap,af));
. . . . . 
}

Veamos como queda

Ahora cada vez que pasamos con el ratón por encima de uno de los sectores circulares ( "gajo"+i+".mouseover; ),o por encima de la "sombra" ( sombra"+i+".mouseover; ) aparece, como una sombra, un arco de círculo del mismo color, pero con una opacidad de 40%.

<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 dSombra(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" + Xap + ", " + Yap+
	               " A"+r+","+r+" 0 0, 1"+Xaf+","+Yaf;
	return parametro_d;
	}
 
function nuevaSombra(ap,af,color,i){
 
var nuevaSombra=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");
nuevaSombra.setAttributeNS(null,"id", "sombra"+i); 		
nuevaSombra.setAttributeNS(null,"d", dSombra(ap,af));
nuevaSombra.setAttributeNS(null,"fill", "none"); 
nuevaSombra.setAttributeNS(null,"stroke", color);
nuevaSombra.setAttributeNS(null,"stroke-opacity", .4); 
nuevaSombra.setAttributeNS(null,"stroke-width", 0);
 
lienzoSVG.appendChild(nuevaSombra);
 
var sombraSet = document.createElementNS("http:\/\/www.w3.org/2000/svg","set");
sombraSet.setAttributeNS(null,"attributeName", "stroke-width");
sombraSet.setAttributeNS(null,"attributeType", "XML");
sombraSet.setAttributeNS(null,"to", 15);
sombraSet.setAttributeNS(null,"begin", "gajo"+i+".mouseover; sombra"+i+".mouseover");
sombraSet.setAttributeNS(null,"end", "gajo"+i+".mouseleave; sombra"+i+".mouseleave");
 
nuevaSombra.appendChild(sombraSet);
}
 
function nuevoGajo(ap,af,color,i){
var nuevoGajo=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");
nuevoGajo.setAttributeNS(null,"id", "gajo"+i); 			
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
   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,i);
   nuevaSombra(ap[ i ],af[ i ],color,i);
}

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.

A continuación añadiremos una leyenda.