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:

 

Menú Contextual en tu Aplicación Web

Si necesitas incluir un menú contextual en tu página web, puedes hacerlo de una forma sencilla con el siguiente plugin jQuery

¿Quieres incluir un menú contextual en tu página web? Puedes hacerlo de una forma sencilla incorporando el plugin ContextMenu de jQuery. Se trata de un plugin ligero que te permite sobrescribir selectivamente el menú contextual del navegador al pulsar sobre el botón derecho del ratón. También comentaré la forma de que responda tanto a la pulsación sobre el botón derecho como al izquierdo.

Sus características son las siguientes:

  • Uso de múltiples menús diferentes en un página
  • Un menú puede ser asociado para que responda a varios elementos de la página
  • Los estilos de los menús son totalmente personalizables
  • Permite opciones de menú con iconos
  • Acciones asociadas a callbacks sensibles al contexto.

El único requisito es haber incluido en la aplicación el framework jQuery. Funciona en todos los navegadores, por lo que no tendremos problemas con compatibilidades. Puedes descargarlo desde aquí: jquery.contextmenu.r2.js para incluirlo en tus páginas o aplicaciones web

Uso

La estructura del menú se construye con HTML, incluyendo cada opción de menú en una lista no ordenada dentro de una capa, con la clase “contextMenu” y con el id que prefieras y que utilizarás para referenciarlo. Dentro de la página esta capa puede ir en cualquier posición.

Puedes definir tantos menús como necesites. Cada elemento <li> de la lista de la capa actuará como una opción de menú. Dando a cada <li> un id único las acciones pueden ser ligadas a ese menú.

A continuación se muestra un ejemplo. En la página HTML incluiremos el código del div del menú con las opciones que necesitamos:

    <div id="myMenu1" class="contextMenu" style="display: none">

      <ul>

        <li id="open"><img src="folder.png" /> Open</li>

        <li id="email"><img src="email.png" /> Email</li>

        <li id="save"><img src="disk.png" /> Save</li>

        <li id="close"><img src="cross.png" /> Close</li>

      </ul>

    </div>

El código javascript para enlazar cada opción con el código a ejecutar es el siguiente:

    $('span.demo1').contextMenu('myMenu1', {
      bindings: {

        'open': function(t) {
          alert('Trigger was '+t.id+'\nAction was Open');
        },

        'email': function(t) {
          alert('Trigger was '+t.id+'\nAction was Email');
        },

        'save': function(t) {
          alert('Trigger was '+t.id+'\nAction was Save');
        },

        'delete': function(t) {
          alert('Trigger was '+t.id+'\nAction was Delete');
        }
      }

    });

Menú de ejemplo

Parámetros

menu_id: Puedes asociar uno o más elementos de la página a un menú. Por ejemplo si invocamos al context menú de esta forma $("table td").contextMenu("myMenu1"), todas las celdas de una tabla mostrarán el menú al pulsar sobre ellas el botón derecho.

Configuración: Podemos usar la configuración por defecto o bien podemos opcionalmente  modificarla. En el ejemplo de arriba hemos visto cómo asociar la acción que se va a ejecutar para cada id del menú. Para añadir más deben ir separados por comas. El elemento que dispara el menú actual es pasado como parámetro.

  • menuStyle: Contiene pares nombre-valor para aplicar estilos al tag <ul> del menú.
  • itemStyle: Contiene pares nombre-valor para aplicar estilos a los elementos <li> del menú
  • itemHoverStyle: Idéntico al anterior pero aplica cuando se pasa el ratón sobre el elemento <li>, para resaltarlo, etc.
  • shadow: Boolean que identifica si se quiere mostrar la sombra del menú. Por defecto es true.

Puedes ver más en la página oficial del plugin. También es posible ampliar las opciones por defecto de todos los menús invocando al método defaults. Cualquier configuración excepto bindings puede ser usado como por defecto:

  $.contextMenu.defaults({
    menuStyle : {
      border : "2px solid green"
    },

    shadow: false,
    onContextMenu: function(e) {
      alert('Did someone asked for a context menu?!');
    }
  });

Menú contextual pulsando el botón izquierdo del ratón

Por defecto, este plugin funciona pulsando sobre el elemento que queremos que muestre el menú, con el botón derecho del ratón. Para modificar este comportamiento, y que se muestre igualmente al pulsar sobre el botón izquierdo, debemos abrir el fichero descargado del plugin (jquery.contextmenu.r2.js) y abrirlo para editar. Necesitamos modificar la línea:

return $(this).bind('contextmenu', function(e) {

por esta otra:

return $(this).bind('click', function(e) {

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.

 

Refresco Automático de un Div Cada X Segundos con jQuery

Tanto si desarrollas una aplicación web en la que se muestra una colección de datos dinámica, que se actualiza cada poco tiempo, como si quieres que el contenido de una parte de tu web se actualice o refresque periódicamente, aquí tienes una solución a tu problema utilizando jQuery.

Tanto si desarrollas una aplicación web en la que se muestra una colección de datos dinámica, que se actualiza cada poco tiempo, como si quieres que el contenido de una parte de tu web se actualice o refresque periódicamente, aquí tienes una solución a tu problema utilizando jQuery.

En las antiguas webs, sobre todo en la de noticias o periódicos, cada cierto tiempo se refrescaba todo su contenido, actualizando la página completa. Para eso utilizamos el tag Meta refresh de HTML. Lo que hace es refrescar la página o frame cada cierto tiempo. Para ello, entre los tags <HEAD></HEAD> de la página incluíamos el siguiente código:

<meta http-equiv="refresh" content="5">

Lo que hace es refrescar todo el contenido de la página cada 5 segundos. Este comportamiento está desaconsejado por el World Wide Web Consortium (W3C) ya que puede desorientar al usuario.

Durante el desarrollo de una aplicación web, necesitábamos que una tabla de datos (utilizábamos displaytag, de la que ya os he hablado anteriormente) se actualizara cada cierto tiempo, definido por el usuario), debido a que el estado de los datos mostrados en esta displaytag tenían un comportamiento bastante dinámico y cambiante.

Para ello me creé en la página un div con id  salastatus y éste contenía otro div con id resulttable que contenía la displaytag y algún control más que deseaba actualizar, a continuación introduje el siguiente código que se ejecuta tras la carga de la página:

 $(document).ready(function(){
   var refreshId = setInterval(refrescarTablaEstadoSala, 30000);
   $.ajaxSetup({ cache: false });
 });

Lo que hace el código es, cada 30 segundos (el valor del parámetro va en milisegundos), se ejecuta la función javascript refrescarTablaEstadoSala. Comentaros que aquí para simplificar he indicado el número de milisegundos de forma directa, pero realmente lo enviaba el servidor, a partir de los datos de configuración del usuario.

A continuación muestro el contenido de la función refrescarTablaEstadoSala:

function refrescarTablaEstadoSala() {
  $("#rolling").toggle();
  $("#salastatus").css('opacity', 0.4);
  $("#salastatus").load('estadoSala.do?randval='+ Math.random() + " #resulttable", function(){
      //aquí puedes meter más código si necesitas;
      $("#salastatus").css('opacity', 1);
      $("#rolling").toggle();
  });
}

Lo primero que hago es mostrar un icono de cargando cuyo id es “rolling” ( $(“#rolling”).toggle(); ) y pongo la capa que quiero actualizar transparente ( $(“salastatus”).css(‘opacity’, 0.4); ), totalmente operativa, pero el usuario ya detecta que ha comenzado una actualización. A continuación mediante el método load, de la que ya os hablé en esta publicación anterior, realizo una petición de la página con un número aleatorio como parámetro (para que el navegador no me devuelva la página de caché) seguido de un espacio y el div que quiero cargar en salastatus precedido de un #. Tras la carga, oculto el icono cargando y quito la transparecia a la capa. Antes de esto puedes completar la función con el código que necesites o el tratamiento de errores que desees.

No olvides incluir el enlace al fichero js de jquery o no te funcionará. Cómo ves una solución bastante elegante de resolver el problema ocasionado con el meta refresh y su manera, mucho más intrusiva de refrescar la página.

Placeholder en Internet Explorer

Placeholder es un atributo HTML5 utilizado como una pequeña pista o descripción corta del valor esperado en un campo de texto dentro de un formulario. Funciona en los campos input de tipo: text, search, url, tel, email y password. Es soportado por todos los navegadores (Firefox, Opera, Chrome, Safari, etc.), pero existe un problema si quieres utilizarlo con Internet Explorer (de momento ninguna versión lo soporta).

Placeholder es un atributo HTML5 utilizado como una pequeña pista o descripción corta del valor esperado en un campo de texto dentro de un formulario, como por ejemplo “Buscar”, “Introduzca su e-mail”, etc. Esta descripción se muestra dentro de la caja de texto cuando éste se encuentra vacío y desaparece cuando el elemento obtiene el foco.

Cómo hemos dicho se encuentra disponible desde la versión de HTML5 y su uso se encuentra bastante extendido en aplicaciones y páginas a lo largo y ancho de Internet. Funciona en los campos input de tipo: text, search, url, tel, email y password. Es soportado por todos los navegadores (Firefox, Opera, Chrome, Safari, etc.), pero existe un problema si quieres utilizarlo con Internet Explorer (de momento ninguna versión lo soporta).

Navegando por la web en busca de una solución para aplicar a uno de los proyectos en los que trabajo, cuya interfaz debe ser similar en todos los navegadores, encontré ésta que usa jQuery. jQuery es una librería javascript, que siempre es aplicable a multitud de problemas y usos, para alterar el comportamiento y visualización de los documentos web en navegadores, así como realizar peticiones asíncronas (ajax), y de la que ya os he hablado en otros artículos.

Podemos usar el siguiente código:

$(function() {
    if(!$.support.placeholder) {

            var active = document.activeElement;

            $(':text').focus(function () {
                    if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) {
                            $(this).val('').removeClass('hasPlaceholder');
                    }

            }).blur(function () {
                    if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) {
                            $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
                    }
            });

            $(':text').blur();
            $(active).focus();

            $('form').submit(function () {
                    $(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
            });

    }
});

Y este podría ser el css con el estilo, ya que el color de la letra del placeholder aparecería en un tono más grisáceo, como difuminado:

.hasPlaceholder { color: #777; } 

Lo que hace el código es sobreescribir el evento focus (posicionas el foco) y blur (el foco abandona el elemento) para elementos de tipo texto, en aquellos navegadores que no soportan el atributo placeholder, vamos en IE. Cuando se producen dichos eventos, leen el texto del atributo placeholder y lo muestran como valor del elemento (blur) aplicando la clase hasplaceholder, o bien borran el valor del campo (focus) y eliminan la clase hasplaceholder del campo de texto.

También se sobreescribe el evento submit, para borrar todos los valores de los campos de texto que muestran el texto placeholder, justo antes de enviar el formulario al servidor evitando que esos campos tengan valores incorrectos.

Se trata de una solución bastante elegante y nada intrusiva, porque sólo se aplica si el navegador no soporta el atributo. En caso de utilizar placeholder con Firefox, Safari, Chrome… el código jQuery no tiene efecto.