Cree bonitos gráficos para su aplicación con jQuery y xCharts

Los gráficos son una gran ayuda visual cuando se presentan datos. No puede crear un panel de administración profesional sin ellos. También son difíciles de configurar. Sin embargo, hay una nueva biblioteca que facilita las cosas:xCharts. Hoy, lo usaremos junto con el selector de rango de fechas para Twitter Bootstrap, para crear un gráfico bonito con tecnología AJAX para su aplicación web que obtiene datos de una tabla MySQL.

El HTML

La estructura HTML de la demostración es bastante simple:tenemos que agregar elementos en la página para la inicialización del gráfico y para el selector de fecha. Como estamos incluyendo bootstrap en la página de todos modos, podemos hacer uso de sus habilidades de diseño de formularios e íconos para que se vea bien.

index.php

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <title>Pretty Charts with jQuery and AJAX | Tutorialzine Demo</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="https://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>

Estamos incluyendo una buena cantidad de recursos externos aquí. En la sección principal, tenemos los archivos css para xcharts , el seleccionador de fechas , arranque (incluido desde el cdn súper rápido de cloudflare) y nuestro style.css archivo.

Antes de la etiqueta del cuerpo de cierre, tenemos jQuery biblioteca, d3.js (requerido por xcharts), xcharts , la elegante biblioteca sugar.js (requerida por el complemento de intervalo de fechas), el complemento de intervalo de fechas y nuestro script.js . En los siguientes pasos, verá cómo funcionan todos juntos.

La tabla MySQL

Como mencioné en la introducción, el script que estamos escribiendo obtendrá sus datos de una tabla MySQL y los mostrará en el gráfico. Puede encontrar el código SQL que creará la tabla en schema.sql en el archivo zip, disponible para descargar desde los botones de arriba. Así es como se ve la tabla:

Tiene solo tres campos. Al campo de fecha se le asigna un índice único, lo que significa que no puede haber registros duplicados para el mismo día. El campo sales_ord contiene el número de ventas del día. Su base de datos seguramente será diferente, pero siempre que devuelva la respuesta JSON correcta de su secuencia de comandos PHP, no habrá ningún problema (más sobre eso en la siguiente sección).

El código PHP

En nuestro script PHP, seleccionaremos los registros de la tabla que correspondan a la fecha de inicio y finalización pasada, ensamblaremos una matriz y la generaremos como un 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í estoy usando una de mis bibliotecas favoritas:Idiorm. Lo he usado antes en tutoriales en el sitio (y en muchos proyectos personales). Es solo un archivo (ubicado en la carpeta lib/) y hace que trabajar con bases de datos sea un verdadero placer. Todo lo que estoy haciendo es seleccionar todos los resultados de la base de datos, que tienen un valor de fecha entre las marcas de tiempo de inicio y finalización pasadas con la solicitud.

La respuesta JSON resultante se parece a esto:

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

La etiqueta properties contienen los valores de fecha de MySQL para la fila respectiva y los valores - el número de ventas de ese día. Depende de nuestro código JavaScript manejar correctamente estos datos y convertirlos en un formato adecuado para usar con el complemento xCharts.

JavaScript

Todo nuestro código JS se encuentra en assets/js/script.js . El código es un poco largo y, para que sea más fácil de seguir, se lo presentaré en fragmentos.

Primero declararemos algunas variables e inicializaremos el complemento del selector de rango de fechas. Tenga en cuenta que el rango de fechas al que me vinculé es una bifurcación del complemento original. Decidí optar por esta versión, ya que la original depende de date.js, una biblioteca de fecha/hora muy antigua que entra en conflicto con xCharts. En cambio, la bifurcación usa sugar.js, que es una buena biblioteca de utilidades con un potente soporte de fecha y hora.

activos/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 puede ver, estamos haciendo un buen uso de los métodos de fecha y hora de sugar.js para definir el punto inicial y final del rango. Estoy inicializando el script con los resultados de los últimos 7 días y actualizando el campo de entrada de rango.

Ahora vamos a crear el gráfico:

    // 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);

Primero defino un objeto de configuración para xCharts, con propiedades y funciones de devolución de llamada. En el formato de datosX propiedad, estoy transformando las cadenas aaaa-mm-dd devueltas de la solicitud AJAX, en objetos de fecha de JavaScript adecuados, para que el complemento pueda mostrarlos correctamente y hacer sus cálculos.

También estoy pasando un controlador de eventos para los eventos del complemento mouseover/mouseout, y los uso para mostrar una información sobre herramientas (el complemento no viene con uno listo para usar).

Por último, aquí está la función de JavaScript para cargar datos con 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 expone el setData método para que pueda reemplazar fácilmente los datos mostrados. El atributo className es importante, ya que esto es lo que usa el complemento para identificar su gráfico. Si omite esta propiedad, se producirán todo tipo de errores extraños (créame, lo sé).

¡Con esto, nuestros bonitos gráficos están completos!

¡Hemos terminado!

Puede usar este ejemplo para mejorar sus áreas de administración y visualizar datos estadísticos en una hermosa interfaz.