Gráficos Estadísticos con jqPlot

En aplicaciones en los que introducimos una gran cantidad de datos, lo más lógico será posteriormente explotar esos datos y obtener estadísticas e informes. En este post presento jqPlot, una librería jQuery para generar gráficos estadísticos interactivos.

En aplicaciones en los que introducimos una gran cantidad de datos, lo más lógico será posteriormente explotar esos datos y obtener estadísticas e informes. En estos casos los datos obtenidos se visualizan de una manera óptima en gráficas que nos ayudan representar visualmente la gran cantidad de datos que en muchos casos hemos obtenido. Una manera fácil de generar gráficos estadísticos en aplicaciones web es utilizar javascript para mostrarlas en tiempo de ejecución.

La opción que utilizo para generar gráficas pasa por jQuery junto con jqPlot. Se trata de un plugin jQuery que genera gráficos estadísticos en el navegador dentro de tus páginas web. Soporta gráficas lineales, de barras y circulares (en forma de tarta). Tiene numerosas opciones de configuración como la inclusión de sombras y la interacción con eventos drag&drop. jqPlot ha sido probado en IE7, IE8 o superior, Firefox, Chrome, Safari y Opera. La licencia de uso es MIT y GPL versión 2, por lo que podemos utilizarlo libremente de forma gratuita en nuestros proyectos. Requiere jQuery (1.4.3 o superior para algunas características), la cual está incluida en la distribución.

Uso de la librería

Antes de nada debemos descargar jqPlot y lo podemos hacer desde la sección de descargas de la página del proyecto: http://www.bitbucket.org/cleonello/jqplot/

Para usar jqPlot debes incluir en tu página web: jquery, jqPlot, el fichero css de jqPlot y opcionalmente, el script excanvas para que tu página soporte canvas en Internet Explorer (esta característica HTML5 no la soportan las versiones de IE anteriores a la versión 9. Si es superior no es necesario incluir excanvas):

<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
<link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />

Lo siguiente es añadir el contenedor de la gráfica. Se trata de una capa a la que podemos darle si deseamos un ancho y un alto. Lo que es obligatorio es indicar un id.

<div id="chartdiv" style="height:400px;width:300px; "></div>

Creamos la gráfica llamando a la función jqplot, con dos parámetros obligatorios, el id de la capa contenedora y un array con los datos, normalmente enviados por el servidor y obtenidos desde base de datos. La invocación al método suele realizarse cuando la página está preparada:

<script type="text/javascript">
  <!--
  $(document).ready(function() {
    $.jqplot('chartdiv',  [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]);
  });
  -->
</script>

Esto generará una gráfica como la siguiente:

Gráfica lineal

Opciones de jqPlot

Podemos personalizar la gráfica pasando parámetros a la función como tercer parámetro, de la forma:

$.jqplot('chartdiv',  [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]],
{ title:'Exponential Line',
  axes:{yaxis:{min:-10, max:240}},
  series:[{color:'#5FAB78'}]
});

Todas las opciones disponibles están descritas en el fichero jqPlotOptions.txt de la distribución.

Dependiendo de las características y de lo complejo que queramos que sea nuestra gráfica es posible que necesitemos incluir en nuestra página enlaces a otros plugins que se incluyen el la distribución jqPlot. Hay plugins para personalizar el renderizado de gráficas de barras con varias series, para personalizar la leyenda, las etiquetas en los ejes, etc:

<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="js/jqplot/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="js/jqplot/jquery.jqplot.min.js"></script>

<script type="text/javascript" src="js/jqplot/jqplot.pieRenderer.min.js"></script>    
<script type="text/javascript" src="js/jqplot/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot/jqplot.pointLabels.min.js"></script>
<script type="text/javascript" src="js/jqplot/jqplot.enhancedLegendRenderer.min.js"></script>

<link rel="stylesheet" type="text/css" href="css/jqplot/jquery.jqplot.css" />

Ejemplos

En el siguiente enlace se puede ver la librería en funcionamiento con varios ejemplos. A continuación algunas imágenes con diferentes tipos de gráficas:

Gráficas lineales: http://www.jqplot.com/tests/line-charts.php Gráfica lineal

Gráficas circulares: http://www.jqplot.com/tests/pie-donut-charts.phppiechart

Gráficas de barras: http://www.jqplot.com/tests/bar-charts.phpbarchart

Ni que decir tiene que jqPlot no es la única librería jQuery para la generación de gráficos estadísticos. A continuación os dejo dos enlaces a páginas dónde se enumeran varias alternativas:

 

JScrollPane, Barras de Scroll en Divs

¿Necesitas incluir barras de scroll a una o más capas dentro de tu página? En este post encontraréis una posible solución utilizando un plugin jQuery llamado jScrollPane.

¿Necesitas incluir barras de scroll a una o más capas dentro de tu página? En este post encontraréis una posible solución utilizando un plugin jQuery llamado jScrollPane.

En ocasiones llenamos nuestras páginas de de mucho contenido dentro de uno o varios divs. Más tarde nos damos cuenta de que el área reservada en un div para mostrar ciertos elementos o texto se ha quedado pequeño, y al crecer la página la página deja de verse correctamente. Tanto si este es tu problema como si únicamente quieres incluir scroll a una capa este plugin de jQuery te ayudará.

Lo primero que debemos hacer es descargarlo desde http://jscrollpane.kelvinluck.com/#download, necesitaremos lo siguiente:

  • jquery.jscrollpane.css. Estilos básicos CSS necesarios para hacerlo funcionar
  • jquery.jscrollpane.min.js. Es la versión reducida del fichero javascript de jScrollPane. Podemos usar el fichero sin minimizar, de manera que nos permita ver el código y los comentarios sobre el mismo.
  • Obviamente, la librería jQuery.
  • jquery.mousewheel.js. Opcional. Es el plugin mousewheel, para hacer scroll con la rueda que incorporan la mayoría de los ratones.
  • mwheelIntent.js. Opcional. Es el plugin mWheelIntent para mejorar la usabilidad usando la rueda del ratón.

El uso es muy sencillo, después de descargar los ficheros necesarios los incluimos en el head de nuestro código html:

<!-- estilos jScrollPane -->
<link type="text/css" href="jquery.jscrollpane.css" rel="stylesheet"/>

<!-- versión de jQuery  -->
<script type="text/javascript" src="jquery.min.js"></script>

<!-- El plugin mousewheel plugin - opcional - provee soporte para la rueda del ratón -->
<script type="text/javascript" src="jquery.mousewheel.js"></script>

<!-- Fichero javascript de jScrollPane -->
<script type="text/javascript" src="jquery.jscrollpane.min.js"></script>

Ahora tenemos que inicializar jScrollPane al cargar la página de la forma:

<script type="text/javascript">
	$(document).ready(function($){
		var pane = $("#cajafechas")
		pane.jScrollPane();
		var api = pane.data('jsp');
		api.scrollToBottom();
	});
</script>

En el ejemplo tenemos una capa con el id cajafechas, a la que aplicamos el plugin. Esta capa se va completando con fechas de forma dinámica, cuando el número de fechas sea muy grande, aparecerán las barras de scroll. Bastaría con poner la línea $("#cajafechas").jScrollPane();, pero necesitamos que al iniciar la página el scroll se desplace al final. Para ello llamamos a un método del API, scrollToBottom().

Hay muchas formas de usar jScrollPane (animaciones, estilos de barra, etc), bien a través de parámetros de configuración o bien a través del API. En la página del desarrollador se pueden encontrar multitud de ejemplos.

 

Deshabilitar el botón Submit manteniendo el nombre/valor en el formulario

Cuando desarrollamos aplicaciones web en las que se muestra uno o varios formularios, en ocasiones nos encontramos con que al enviar éstos, el tiempo de proceso o consulta a la Base de Datos es mayor de lo deseable. Cómo todavía no conozco un usuario paciente, lo más probable es que mientras espera haya pulsado el botón enviar el formulario varias veces más, saturando el servidor con más peticiones y haciendo que el tiempo de proceso sea aún mayor.

Lo primero que se nos ocurre es deshabilitar el botón Submit para que el usuario no vuelva a pulsar y de esa manera evitamos recibir en el servidor varias peticiones idénticas. Esta solución funciona en la mayoría de los casos pero puede darse el caso en el que tengamos varios botones de tipo Submit dentro del mismo formulario (buscar, imprimir, ordenar, completar desplegable), y nos interese consultar en el servidor cuál de ellos ha pulsado mediante una sentencia similar a:

if (request.getParameter("nombre_del_input_submit_pulsado") != null) {     ... }

En el caso de que hayamos deshabilitado el botón no es posible recuperar si ha pulsado dicho botón puesto que los elementos deshabilitados de un formulario no se envían en la petición.

Existe un plugin en jQuery llamado Lock Submit que deshabilita el botón submit después de su pulsación manteniendo el par nombre / valor pasado en el formulario. Como dice en el título de la página del plugin:

Stop Double Clicks on form submits… without losing the submits name/value

Para usarlo necesitas tener jQuery, del que ya os he hablado en más de una ocasión y seguir estos pasos:

  1. Descarga el plugin
  2. Incluye tanto jQuery como el plugin en tu página
  3. Incluye el siguiente código adaptándolo al selector de tu botón:
<script type="text/javascript"> jQuery(document).ready(function() { jQuery('id_boton_submit').lockSubmit({ submitText: "Please wait" }); }); </script>

Internamente no deshabilita el botón, realmente el botón original se encuentra oculto y el que se muestra en la página deshabilitado es una copia del primero. La propiedad submitText permite modificar y personalizar el texto que se muestra dentro del botón. También tiene propiedades para modificar el estilo css.

Visor de Imágenes con jQuery y el plugin iViewer

Anteriormente ya he publicado varios posts hablando sobre la librería jQuery, en concreto como resaltar una búsqueda con jQuery y cómo actualizar tablas displaytag con ajax y jQuery. Gracias a esta librería y el plugin iViewer podemos cargar una imagen, visualizarla en pantalla dentro de un contenedor con la posibilidad de realizar zoom de la imagen con el ratón dentro del contenedor.

Puedes ver una demo pulsando sobre el enlace: http://joseantoniosaiz.es/samples/iviewer

¿Cómo se usa? Obviamente debemos de partir de una página que posea un contenedor en el que cargar la imagen, y al que daremos un ancho y un alto.

<html>
<head>
<style>
.viewer
{
width: 768px;
height: 573px;
border: 1px solid black;
position: relative;
}
.wrapper
{
overflow: hidden;
}
</style>
</head>
<body>
<h1>jQuery Zoom</h1>
<br/>
<div id="viewer"></div>
</body>
</html>

También debemos incluir las referencias a las librerías javascript de jQuery y del plugin iViewer, así como el enlace al fichero de estilos del plugin (yo lo inserté entre los tags head de la página)

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" ></script>
<script type="text/javascript" src="jquery.iviewer.js" ></script>
<link rel="stylesheet" href="jquery.iviewer.css" />

Para terminar debemos añadir el código javascript para invocar al plugin y cargue la imagen con los parámetros que deseemos. Al insertar el código dentro de la función ready nos aseguramos que se ejecutará cuando el documento HTML esté listo para visualizarse.

<script type="text/javascript">
var $ = jQuery;
$(document).ready(function(){
var iviewer = {};
$("#viewer").iviewer(
{
src: "CIMG0498.JPG",
initCallback: function()
{
iviewer = this;
}
});
});
</script>

En este ejemplo únicamente hemos añadido el parámetro src con la ruta a la imagen. Para ver más parámetros podemos consultar la página oficial del plugin. También he probado a cargar una imagen añadiendo una URL de una imagen publicada en cualquier web en vez de una ruta al fichero y funciona correctamente.

Una vez que se ha cargado la imagen, aparecerá una barra con un enlace para ampliar el zoom de la imagen, otro para reducirlo, otro para ver la imagen a tamaño real y otro para ajustarla al área de visión. También se ofrece el porcentaje de zoom. Pulsando el botón izquierdo del ratón podemos arrastrar la imagen para desplazarnos por ella. Si deseamos realizar zoom con la rueda del ratón podemos insertar el plugin mouse wheel extension:

<script type="text/javascript" src="jquery.mousewheel.min.js" ></script>

Resaltar una búsqueda con jQuery

Después de algunos meses sin publicar ningún post, y ya pasadas las vacaciones de verano, vuelvo con un tema que seguro que a los que trabajamos diseñando / desarrollando aplicaciones web nos han pedido los usuarios en más de alguna ocasión: Resaltar en la pantalla las palabras introducidas en una búsqueda.

En nuestro caso tenemos una página con un formulario de búsqueda con diferentes campos: una caja de texto (búsqueda por texto), dos campos de fechas (búsqueda por fechas) y una lista desplegable de países. Todos ellos se combinan en una consulta a la Base de datos y muestra un listado con los resultados. Dichos resultados se pueden ampliar en otra página pulsando sobre el registro correspondiente. Cómo os imagináis es en esta página de detalle donde se nos requirió que se resaltaran las palabras introducidas en la búsqueda.

Después de manejar varias opciones (resaltar en BBDD o en la propia aplicación, de manera que al navegador le llegaba el trabajo hecho), me decanté por hacerlo mediante javascript una vez que haya cargado todo el documento en la página. Para ello hemos incluido dentro del proyecto la librería jQuery (de la que ya os he hablado anteriormente) y de un plugin para ella que podéis consultar en http://bartaz.github.com/sandbox.js/jquery.highlight.html.

Básicamente esta librería contiene una función que se encarga de recorrer todas las palabras del contenedor (documento, div, table, etc.) que le especifiquemos y si encuentra alguna de las palabras utilizadas en la búsqueda y que le pasamos como parámetro la envuelve en una etiqueta <span class=”highlight”>:

<script type="text/javascript" src="/js/jquery-1.4.2.js"></script>
<script type="text/javascript" src="/js/jquery-highlight.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("html").highlight(divide_string("<c:out value='${modelo.form.textoLibre}'/>"),{ wordsOnly: true });
});
</script>

Este código se ejecuta una vez que se ha cargado el documento y llama a la función highlight para que resalte las palabras dentro del elemento HTML del DOM. Asímismo le pasamos la opción wordsOnly:true para que resalte palabras completas (si en la búsqueda se introdujo ‘este’, que no resalte parcialmente Esteban). La función divide_string recibe el texto introducido en la caja de búsqueda y retorna un array de palabras, obviando palabras comunes como artículos y preposiciones. Aquí os paso el código:

function divide_string(cadena)
{
var pattern =                       "\\b(Sr|Sra|Sres|Sta|...más_palabras_comunes...|vuestro|vuestros|y|yo|él|en)\\b";
var re = new RegExp(pattern, "gi");
cadena = cadena.replace(re,"");
var mytool_array = cadena.split(" ");
return mytool_array;
}

Por último indicar que fue necesario realizar modificaciones del plugin ya que no resaltaba las palabras que tenían acento si en la caja de texto buscabas sin acento. Justo antes de crear la expresión regular a evaluar, modificamos el patrón para incluir las vocales acentuadas:

pattern = pattern.replace(/a/gi,"[a|á]");pattern = pattern.replace(/e/gi,"[e|é]");pattern = pattern.replace(/i/gi,"[i|í]");pattern = pattern.replace(/o/gi,"[o|ó]");pattern = pattern.replace(/u/gi,"[u|ú]");
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}
var re = new RegExp(pattern, flag);

Seguro que alguna vez os resulta útil.