Es sorprendente la cantidad de alternativas para crear gráficos en un sitio web. Cuando empecé a investigar sobre el tema no esperaba encontrar tanto, pero la verdad es que hay opciones para todos los gustos:
Luego de probar Google Chart API (la unica opción de la lista que no requiere JavaScript) y gRaphael decidí quedarme con Flot, una librearía gráfica para jQuery. Gráficos atractivos, sintaxis intuitiva (es como usar cualquier otro plugin de jQuery), soporte para eventos y la posibilidad de ser extendida a través de plugins, son varias de las características que hicieron de esta librería mi elección para crear gráficos para la web.
El siguiente ejemplo muestra como crear un gráfico de líneas usando Flot. El resultado es un gráfico como el que aparece aquí.
Primero prepararemos una página HTML donde dibujar el gráfico. Debemos incluir jQuery, Flot, Navigate (un plugin para Flot) y un archivo con nuestro código JavaScript. El contenido de la página será un elemento DIV donde se va a renderizar el gráfico.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Flot - Una librería gráfica para jQuery - Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
body {
font-family: Arial,Helvetica,"Liberation Sans","DejaVu Sans",sans-serif;
font-size: 12px;
}
#graph {
margin: 50px auto 0;
width: 960px;
height: 600px;
}
#tooltip {
position: absolute;
padding: 4px;
opacity: 0;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
</style>
</head>
<body>
<div id="graph"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.flot.min.js"></script>
<script src="jquery.flot.navigate.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Ahora debemos generar los datos del gráfico en un formato apropiado para Flot. Flot acepta multiples series de datos, cada una como un objeto con atributos label
y data
. label
es la etiqueta de la serie y data
un array de parejas[x,y]
:
var series = [{
'label': 'Serie 1',
'data': [[1264377041075, 447], [1264428833413, 1524], [1264455973422, 375]]
}];
Usaremos la siguiente función para generar los datos que se utilizarán en el ejemplo. Los valores en el eje x
serán timestamps y los valores en el eje y
serán numeros enteros entre 0 y 600.
/* @series: cantidad de series
* @n: cantidad de datos por serie */
function generateInputData(series, n) {
var start = (new Date()).getTime(),
data = [], date, dots, dot,
maxx = 0, miny = 0, maxy = 0, j;
for (var i = 0; i < series; i++) {
date = start; dots = [], j = 0;
do {
j++;
// cantidad aleatoria de milisegundos entre
// 86400000 (1 día) y 259200000 (3 dias)
dot = Math.round(Math.random() * 600);
date += Math.round((Math.random() * 172800) + 86400) * 1000;
dots.push([date, dot]);
// guarda los valores extremos
if (dot > maxy) {
maxy = dot;
} else if (dot < miny) {
miny = dot;
}
} while (j < n);
// guarda el mayor timestamp
if (date > maxx) { maxx = date; }
data.push({'label': 'Serie ' + i, 'data': dots});
}
return {'data': data, 'minx': start, 'miny': miny, 'maxx': maxx, 'maxy': maxy};
}
El siguiente paso es usar Flot para convertir nuestros datos en un gráfico de lineas interactivo. Primero creamos el gráfico:
var container = $('#graph'),
tooltip = $('<div id="tooltip"/>').appendTo($('body')),
series = generateInputData(3, 9),
plot, point = null,
// opciones para Flot
options = {
series: {
lines: { show: true },
points: { show: true },
sahdowSize: 0
},
grid: { hoverable: true, clickable: true },
legend: {
show: true,
position: 'nw'
},
xaxis: {
mode: 'time',
min: series.minx,
max: series.maxx,
zoomRange: [1, series.maxx - series.minx],
panRange: [series.minx, series.maxx]
},
yaxis: {
min: series.miny,
max: series.maxy,
zoomRange: [1, series.maxy - series.miny],
panRange: [series.miny, series.maxy] },
zoom: { interactive: true },
pan: { interactive: true }
};
// usa Flot para crear el gráfico dentro de #graph
plot = $.plot(container, series.data, options);
La parte importante del fragmento de código anterior es el objeto options
y la última linea, donde se crea el gráfico. Es importante notar que ninguna de las opciones definidas es obligatoria, Flot es capaz de generar el gráfico aun si se omite el parametro options
. Sin embargo, para lograr el resultado que esperamos en esta ocasión se configuró el plugin como sigue:
series
indica que se debe mostrar las lineas y los puntos de las series y que no si dibujará sombra.grid
habilita los eventosplothover
yplotclick
que se pueden escuchar en el contenedor del gráfico.xaxis
yyaxis
permiten configurar parametros de los ejes del gráfico. en este caso se definieron los valores máximos y mínimos, dos parametros para el plugin de navegación y el parametromode=time
para indicar que los valores en el ejex
son timestamps.zoomRange
ypanRange
restringen la profundidad del zoom y el area que se puede explorar del gráfico, respectivametne.zoom
ypan
activan estas opciones del plugin de navegación.
La documentación para el API de Flot (texto en inglés) ofrece mucho mas detalle sobre estas y otras opciones de configuración. Se recomienda leerlas.
Para finalizar, utilizamos el evento plothover
para mostrar un tooltip cuando el cursor pasa por alguno de los puntos del gráfico. Así:
// agregar tooltips
container.bind('plothover', function(event, pos, item) {
// si el cursor está sobre uno de los puntos
if (item) {
// comprueba que se trate de un punto diferente al que se le generó
// tooltip la última vez
if (point === null || point[0] != item.datapoint[0] || point[1] != item.datapoint[1]) {
// guarda el punto para evitar generar el mismo tooltip dos
// veces consecutivas
point = item.datapoint;
// Flot permite conocer información sobre el punto para el cual
// estamos generando el tooltip:
// - item.series contiene información sobre la serie a la q pertenece
// el punto. la etiqueta y el color son dos buenos ejemplos.
// - item.pageX e item.pageY son las coordenadas el punto respecto
// al documento (coordenadas globales).
// - pos.pageX y pos.pageY son las coordenadas globales del cursor.
tooltip.html(item.series.label + ': ' + parseInt(point[1].toFixed(2)))
.css('background-color', item.series.color);
// centra el tooltip sobre el punto
var x = item.pageX - (tooltip.width() / 2),
y = item.pageY - tooltip.height() - 18;
// animación para el tooltip
if (tooltip.css('opacity') < 0.2) {
tooltip.stop().css({top: y, left: x}).animate({ opacity: 1}, 400);
} else {
tooltip.stop().animate({ opacity: 1, top: y, left: x}, 600);
}
}
} else {
// si el cursor no está sobre uno de los puntos escondemos el tooltip
tooltip.stop().animate({opacity: 0}, 400);
point = null;
}
});
pos
e item
, parametros del callback para el evento plothover
, ofrecen mas información que la descrita en el código anterior. Se recomienda usar console.log
de Firebug para descubrir los secretos que esconde :P.
¿Qué librerias usan ustedes para generar gráficos en la web?
Lea acerca de otras librerías en Graphing/Charting Data on Web Pages: JavaScript Solutions y Using various javascript libraries to create pie chart.
Comments
es genial esta libreria grafica. muchisimas gracias.
solo tengo una duda. estoy intentando hacer una grafica de una clasificacion, por lo que el punto mas alto corresponde al numero/dato mas bajo. He estado metiendo mano pero no consigo nada….
hay alguna manera de que la numeracion de los ejes quede acorde a este tipo de grafico???
1 saludo y de nuevo muchas gracias por el aporte.
Hola, yo estoy haciendo esactamente lo mismo pero con tiempos, asique me sucede los mismo que a ti, facil su solucion.
Lo que debes de hacer es insertar numeros negativos, asi el menor valor sera el mas alto, y asi te queda tu menor valor como el mejor en la grafica 🙂
Luego tu puedes modificar el archivo de como muestra los labels de la grafica, asique le pides que muestre el opuesto al que grafica, osea si te grafica -30, le pides que a la hora de mostrar muestre 30
Saludos!
aporte al blog en cuanto a Internet Explorer 8 para que te funciones necesitas de la siguiente linea de código :
“”
se que funciona con explorer 8 no e probado con inferiores a este, espero a alguien le sirva esta información
No veo el código. Podrás incluirlo nuevamente y aclarar un poco donde va la línea..
gracias
Gracias, yo tambien comence a utilizar flot