Cómo crear fantásticas gráficas para tu app con jQuery y xCharts

Las gráficas son una gran ayuda visual en la representación de datos. No puedes desarrollar un panel de administración profesional sin ellas. También son difíciles de configurar. Sin embargo, hay una librería que hace las cosas mucho más fáciles, xCharts. En este artículo, vamos a utilizarla junto con el selector daterange picker de Twitter Bootstrap, para construir una gráfica potenciada por AJAX muy bonita para tu aplicación web, que extraiga los datos de una tabla de MySQL.

El HTML

La estructura HTML de la demo de este artículo es bastante simple, tenemos que añadir elementos en la página para la inicialización de la gráfica, y para el date picker. Comovamos a incluir Twitter Bootstrap, podemos hacer uso de sus habilidades a la hora de dar estilo a los formulario y utilizar sus iconos para que nuestra demo se vea bien.

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Pretty Charts with jQuery and AJAX</title> <link href="assets/css/xcharts.min.css" rel="stylesheet"> <link href="assets/css/style.css" rel="stylesheet"> <!-- Include bootstrap css --> <link href="assets/css/daterangepicker.css" rel="stylesheet"> <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap.min.css" rel="stylesheet" /> </head> <body> <div id="content"> <form class="form-horizontal"> <fieldset> <div class="input-prepend"> <span class="add-on"><i class="icon-calendar"></i></span> <input type="text" name="range" id="range" /> </div> </fieldset> </form> <div id="placeholder"> <figure id="chart"></figure> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <!-- xcharts includes --> <script src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.js"></script> <script src="assets/js/xcharts.min.js"></script> <!-- The daterange picker bootstrap plugin --> <script src="assets/js/sugar.min.js"></script> <script src="assets/js/daterangepicker.js"></script> <!-- Our main script file --> <script src="assets/js/script.js"></script> </body> </html>

Hemos incluido una buena cantidad de recursos externos, como puedes ver. En la sección head, tenemos los archivos CSS para xcharts, el datepicker, bootstrap y nuestro archivo style.css.

Antes de cerrar el tag body, tenemos la librería jQuery, d3.js (obligatoria para xcharts), xcharts, la elegante librería sugar.js (requerida por el plugin date range), el plugin date range y nuestro script.js. En los pasos siguientes verás cómo funcionan todos juntos.

La tabla de MySQL

Como ya he mencionado en la introducción, el script que vamos a implementar obtendrá sus datos de una tabla MySQL y lo mostrará en la gráfica. La tabla tendría esta estructura:

chart_sales
id (INT 11)
date (DATE)
sales_order (INT 11)

Como ves, solo tiene tres campos. El campo date debe ser único, es decir, no puede haber registros duplicados para el mismo día. El campo sales_order albergará el número de ventas del día. Seguramente, tu base de datos será diferente, pero siempre y cuando el script PHP nos devuelva la respuesta JSON correcta, no habrá ningún problema.

El código PHP

En nuestro script PHP, seleccionaremos los registros de la tabla que correspondan a la fecha inicio y fecha fin que se le ha pasado al fichero. Los datos se convertirán en un array, y se devolverán en formato JSON.

ajax.php

header('Content-Type: application/json');

// Set up the ORM library
require_once('setup.php');

if (isset($_GET['start']) AND isset($_GET['end'])) {

    $start = $_GET['start'];
    $end = $_GET['end'];
    $data = array();

    // Select the results with Idiorm
    $results = ORM::for_table('chart_sales')
            ->where_gte('date', $start)
            ->where_lte('date', $end)
            ->order_by_desc('date')
            ->find_array();

    // Build a new array with the data
    foreach ($results as $key => $value) {
        $data[$key]['label'] = $value['date'];
        $data[$key]['value'] = $value['sales_order'];
    }

    echo json_encode($data);
}

Aquí utilizo una de mis librerías favoritas, Idiorm. La he utilizado en tutoriales anteriores (y en muchos proyectos personales). Es sólo un archivo (que se encuentra en el directorio lib) y hace que trabajar con bases de datos sea super sencillo. Todo lo que hago es seleccionar todos los resultados de la base de datos, que tienen un valor de fecha entre las fecha inicio y fecha fin pasados pòr solicitud.

La respuesta JSON resultante debe ser similar a esta:

[{
    "label": "2013-01-07",
    "value": "4"
}, {
    "label": "2013-01-06",
    "value": "65"
}, {
    "label": "2013-01-05",
    "value": "96"
}]

Las propiedades del label contienen los valores del campo fecha para su respectiva fila, y los values, el número de ventas de ese día. Depende de nuestro código JavaScript el manejar correctamente estos datos y convertirlos en un formato adecuado para utilizarlos con el plugin xCharts.

El Javascript

Todo nuestro código JS radica en assets/js/script.js. El código es un poco largo, y para que sea más fácil de seguir voy a explicartelo en trozos.

En primer lugar vamos a declarar algunas variables e inicializar el plugin date range. Observa que el date range que he enlazado es un fork del plugin original. Me decidí a ir con esta versión, como el original depende de date.js, una librería de fechas/horas muy vieja que entra en conflicto con xCharts. El fork, en su lugar, utiliza sugar.js, que es una estupenda librería de utilidades.

assets/js/script.js

$(function() {

    // Set the default dates, uses sugarjs' methods
    var startDate   = Date.create().addDays(-6),    // 6 days ago
        endDate     = Date.create();                // today

    var range = $('#range');

    // Show the dates in the range input
    range.val(startDate.format('{MM}/{dd}/{yyyy}') + ' -
        ' + endDate.format('{MM}/{dd}/{yyyy}'));

    // Load chart
    ajaxLoadChart(startDate,endDate);

    range.daterangepicker({

        startDate: startDate,
        endDate: endDate,

        ranges: {
            'Today': ['today', 'today'],
            'Yesterday': ['yesterday', 'yesterday'],
            'Last 7 Days': [Date.create().addDays(-6), 'today'],
            'Last 30 Days': [Date.create().addDays(-29), 'today']
            // You can add more entries here
        }
    },function(start, end){

        ajaxLoadChart(start, end);

    });

Como puedes ver, hacemos buen uso de los métodos de fechas y horas de la librería sugar.js para definir el inicio y el final del rango. Inicializamos el script con los resultados de los últimos 7 días, y actualizamos el campo del date range.

Ahora, creamos la gráfica:

// The tooltip shown over the chart var tt = $('<div class="ex-tooltip">').appendTo('body'), topOffset = -32; var data = { "xScale" : "time", "yScale" : "linear", "main" : [{ className : ".stats", "data" : [] }] }; var opts = { paddingLeft : 50, paddingTop : 20, paddingRight : 10, axisPaddingLeft : 25, tickHintX: 9, // How many ticks to show horizontally dataFormatX : function(x) { // This turns converts the timestamps coming from // ajax.php into a proper JavaScript Date object return Date.create(x); }, tickFormatX : function(x) { // Provide formatting for the x-axis tick labels. // This uses sugar's format method of the date object.  return x.format('{MM}/{dd}'); }, "mouseover": function (d, i) { var pos = $(this).offset(); tt.text(d.x.format('{Month} {ord}') + ': ' + d.y).css({ top: topOffset + pos.top, left: pos.left }).show(); }, "mouseout": function (x) { tt.hide(); } }; // Create a new xChart instance, passing the type // of chart a data set and the options object var chart = new xChart('line-dotted', data, '#chart' , opts);

En primer lugar defino un objeto de configuración para xCharts, con propiedades y funciones de devolución de llamada. En la propiedad dataFormatX, yo estoy transformando las cadenas aaaa-mm-dd devueltas desde la petición AJAX, en objetos Date de JavaScript, por lo que el plugin puede visualizarlos correctamente y hacer sus cálculos.

También paso un handler de eventos para los eventos mouseover/mouseout del plugin, y los utilizo para mostrar información en un tooltip.

Por último, aquí tienes la función de Javascript que carga los datos mediante AJAX:

// Function for loading data via AJAX and showing it on the chart
    function ajaxLoadChart(startDate,endDate) {

        // If no data is passed (the chart was cleared)

        if(!startDate || !endDate){
            chart.setData({
                "xScale" : "time",
                "yScale" : "linear",
                "main" : [{
                    className : ".stats",
                    data : []
                }]
            });

            return;
        }

        // Otherwise, issue an AJAX request

        $.getJSON('ajax.php', {

            start:  startDate.format('{yyyy}-{MM}-{dd}'),
            end:    endDate.format('{yyyy}-{MM}-{dd}')

        }, function(data) {

            var set = [];
            $.each(data, function() {
                set.push({
                    x : this.label,
                    y : parseInt(this.value, 10)
                });
            });

            chart.setData({
                "xScale" : "time",
                "yScale" : "linear",
                "main" : [{
                    className : ".stats",
                    data : set
                }]
            });

        });
    }
});

xCharts cuenta con el método setData, el cual reemplaza fácilmente los datos que se muestran. El atributo className es importante, ya que esto es lo que utiliza el plugin para identificar la gráfica. Si omites esta propiedad, provocarás un montón de errores.

Con esto, nuestra gráfica estaría completa.

Fuente: tutorialzine.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP