Ver Mensaje Individual
  #5 (permalink)  
Antiguo 26/08/2005, 13:22
furoya
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años, 1 mes
Puntos: 317
Hola todos :

Leí varias veces preguntas como esta, por eso el asunto me quedó dando vueltas en la cabeza. Me parece más que lógico manejar el gráfico desde el servidor, lo que además permite mejores presentaciones; pero siempre me quedaron ganas de hacelo en forma local -sin usar Flash-, y no se me ocurría cómo.

Lo primero que recordé es que W98 usaba en la carpeta "Mi PC" un objeto que permitía ver en formato circular el porcentaje ocupado de cada disco. Aparcía en el panel izquierdo ... pero cuando se seleccionaba en el panel derecho; lo que me hizo suponer que debía estar integrado al sistema operativo, y no lo podría usar en un HTML. Ni lo intenté.

Después pensé en usar imágenes. Cien porciones de "torta" por cada color, elegidas con JS, no me entusiasmaron mucho.

Hace muy poco redescubrieron en estos foros ( XHTML o CSS ) el VML ( Vectorial Markup Language ), un lenguaje que permite "dibujar" en el documento, y que yo no usaba porque me complico con las fórmulas. Pero quizo el destino que me cruzara con una forma prediseñada -el arc- y cuando lo vi, inmediatamente me evocó a los gráficos circulares.

Busqué en este sitio si había algo parecido y no lo encontré ( yo no lo encontré, no estoy diciendo que no exista; si alguien lo hizo : por favor, ponga un enlace acá ); así que elegí uno de los temas ( éste ) para dejar el primero ( y seguramente único ) borrador.

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html xmlns:v="urn:schemas-microsoft-com:vml">

<head><title>TORTA. </title>
<script language="javascript"> 
var p, g, t, mar, sW;
var acum = 0;
var cadaPorcion = "";

var diametro = 300; //TAMAÑO EN PX

var porciones=new Array()

//[PORCENTAJES DE TORTA, "COLOR FONDO", "COLOR TEXTO"]
porciones[0] = [10, "red", "white"];
porciones[1] = [20, "lime", "black"];
porciones[2] = [30, "blue", "white"];
porciones[3] = [15, "fuchsia", "white"];
porciones[4] = [25, "yellow", "black"];

var totalPorciones = porciones.length;

function sumaPorciones(){
var suma = 0;
var cadaGrado;
grados = new Array(totalPorciones);

for(p=0; p<totalPorciones; p++){
cadaGrado = porciones[p][0]*3.6; 
grados[p] = [cadaGrado]; 
suma += cadaGrado*1;
}

if(suma == 360)escribeTorta();
else alert("La suma de porcentajes no da 100%.")
}


function escribeTorta(){
var Contenedor = document.getElementById("contenedor");
Contenedor.style.width = diametro + "px";
Contenedor.style.height = diametro + "px";

for(g=0; g<totalPorciones; g++){
var sA = (acum*1); 
var eA = (grados[g][0] + acum*1); 
var sC = porciones[g][1];
sW = diametro*0.35;
mar = diametro*0.25;

cadaPorcion += '<v:arc id="arco'+g+'" arcsize="1" strokeweight="'+sW+'px" startangle="'+acum+'" endangle="'+(eA*1+2)+'" strokecolor="'+sC+'" class="porcion" style="width:'+diametro/2+'; height:'+diametro/2+'; margin:'+mar+'px; z-index:-1; " />\r\n'

cadaPorcion += '<span title="'+porciones[g][0]+'%" id="texto'+g+'" class="textos" style="color:'+porciones[g][2]+'">'+porciones[g][0]+'%</span>';

acum = eA; 
}

Contenedor.innerHTML = cadaPorcion;
setTimeout("ubicaTexto()" , 2000);
}

function ubicaTexto(){
for(t=0; t<totalPorciones; t++){

var elArco = document.getElementById("arco"+t);
var elTexto = document.getElementById("texto"+t);

var tTop = Math.floor( elArco.offsetTop - mar*0.25 + elArco.offsetHeight/2); 
var tLeft = Math.floor(elArco.offsetLeft - mar*0.25 + elArco.offsetWidth/2); 
var tSize = Math.floor((elArco.offsetHeight*elArco.offsetWidth)/diametro/4); 

elTexto.style.top = tTop + "px";
elTexto.style.left = tLeft + "px";
elTexto.style.fontSize = tSize + "px";
}
}

</script> 

<style>
v\:* { behavior: url(#default#VML); }
body{background-color:#808080; }
#contenedor{background:transparent; overflow:auto; position:relative;}
.porcion{position:absolute; top:0; left:0; background:transparent; antialias:true; }
.textos{position:absolute; top:-100px; background:transparent; z-index:100; font-weight:bold; }
</style>
</head>

<body onload="sumaPorciones()">
<h2>Crea gr&aacute;fico de torta.</h2>

<div id="contenedor"></div>

<br />
Muestra un gr&aacute;fico de porcentajes. Los valores tienen <tt>title</tt> y se les puede agregar <tt>mouseover</tt>.

</body>
</html>
Dos aclaraciones finales. Como podrán ver, más que una torta o pastel ( pie ), es una rosca o rosquilla ( donut ); no puedo hacer que llegue al centro sin que se deforme mal.
Por último, el VML es soportado hasta el momento sólo por Internet Explorer -seguramente sobre Windows-. Y no me extrañaría nada que alguien agregue aquí que lo hace con su propia versión, sin respetar el estandar.

saludos

furoya.

P.D. : El código está optimizado para IE5.5+; en anteriores, las letras se ven mal.
Si alguien sabe qué puede pasar, acepto sugerencias para que se vea en la mayoría de los IE+W. Gracias.

Última edición por furoya; 01/09/2005 a las 18:07