Ir al contenido principal

Tablas y gráficas estadísticas dinámicas con JavaScript, highcharts, HTML y JSON



Después de tener mucho tiempo sin entradas, quiero retomar  el blog  con un poco más de desarrollo códigos ejemplos y más cosas interesantes que he podido realizar en mi día a día.
En esta ocasión quiero realizar un ejemplo para el cual pueda  graficar tablas, gráficas estadísticas  utilizando la librería de highcharts (https://www.highcharts.com/), esta librería tiene muchas aplicaciones se puede  usar en diferentes campos y es realmente interesante para realizar todo tipo de tratamiento de data.
Este ejemplo se va a trabajar sobre un proyecto realizado en visual studio 2015, pero se debe tener en cuenta que se puede aplicar a cualquier tipo de proyecto en el cual se use javascript y objetos JSON.

La idea con este código es poder generar la cantidad de objetos JSON que sean necesarios desde  el code behind usado y este sea procesado para que se genere a nivel del cliente todas las gráficas requeridas.

Ejemplo:

1- Se debe crear el proyecto con el cual se va a trabajar, pra este caso un proyecto de webforms con aspx
2- En la pagina se importan las librerias que se se requiere para poder crear las graficas y todos los componentes visuales.
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/highcharts-3d.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/App/TablayGraficas.js"></script>
3- En la pagina crear el contenedor principal de todo el proyecto
    <div id="contenedor">
    </div> 
 4- Crear el archivo js en el cual se va a tener todo el código necesario.
5- para este ejemplo se ha creado una variable que contiene la informacion que vamos a mostrar del lado del cliente; para este ejemplo hemos creado dos objetos JSON separados por *.
var objetocompleto = '[{"Manzana": "John","data": [5,3,4,7,2]},{"Manzana": "Pedro","data": [1,2,3,4,5]},{"Manzana": "Pablo","data": [0,10,3,9,15]},{"Manzana": "Andres","data": [3,4,3,9,12]},{"Manzana": "Ana","data": [3,4,3,9,12]}]*[{"Pera": "Juan","data": [2, 6, 8, 3, 1]},{"Pera": "Carlos","data": [10, 9, 8, 5, 2]}]*';
6- Crear las funciones para realizar el tratamiento de la información y crear la cantidad de objetos necesarios a graficar, para este ejemplo se ha utilizado gráficas en 3D, gráficas en 2D, y pie.

7- Aquí dejo el código completo del js que se encarga de realizar todo el trabajo, al final del post dejo el enlace para donde se puede descargar el proyecto completo.
//variable para el grafico
var charter;
var objetocompleto = '[{"Manzana": "John","data": [5,3,4,7,2]},{"Manzana": "Pedro","data": [1,2,3,4,5]},{"Manzana": "Pablo","data": [0,10,3,9,15]},{"Manzana": "Andres","data": [3,4,3,9,12]},{"Manzana": "Ana","data": [3,4,3,9,12]}]*[{"Pera": "Juan","data": [2, 6, 8, 3, 1]},{"Pera": "Carlos","data": [10, 9, 8, 5, 2]}]*';
var valorgrafica = 1
$(document).ready(function () {
    jscompleto(objetocompleto, valorgrafica);
});
//***********************************************************************************************************//
//** Función:     recibe la data completa sin importar cuantos datatables reciba el c#, recibe un valor adicional para saber si la consulta lleva grafica o solo tablas
//** Parametros:  objeto json con toda la data a graficar
//** Observacion:
//***********************************************************************************************************//
function jscompleto(objetocompleto, valorgrafica) {
    var ultimo = objetocompleto.substring(0, objetocompleto.length - 1);
    var arreglo = [];
    var otroarreglo=[];
    arreglo.push(ultimo.split("*"));
    otroarreglo = arreglo[0];
    var tamano = otroarreglo.length;
    createtablecontent(tamano, valorgrafica);
    for (var t = 0; t < otroarreglo.length; t++) {
        var d = JSON.parse(otroarreglo[t]);
        var contenedortabla = "#divTablaContainer" + t;
        var contenedor = "container" + t;
        var dataset = new Array();
        if (valorgrafica == 0) {
            buildHtmlTable(JSON.stringify(d), contenedortabla);
        } else {
            grafica(dataset, contenedor, contenedortabla, JSON.stringify(d));
         
        }
    }
}
//***********************************************************************************************************//
//** Función:     Recibe los parametros necesarios para crear las tablas y las graficas por cada objeto JSON
//** Parametros:  Recibe 4 parametro
//**              - dataset: arreglo en el cual se guarda la data de cada grafica
//**              - Contenedor: id del div donde se pinta la grafica
//**              - contendortabla: id del div donde se debe pintar la tabla de cada grafica
//*               - dat objeto json con la data que se debe procesar
//** Observacion:
//***********************************************************************************************************//
function grafica(dataset, contenedor,contenedortabla, data) {
    var key = [];
    key = GetKey(data);
    var serie = [];
    var nombreserie = [];
    serie = series(dataset,data, key);
    var arreglo = [];
    for (var a = 0; a < dataset.length; a++) {
        arreglo.push(dataset[a].toString().split(','));
    }
    var tmp = "";
    var arr = [];
    var longitud = arreglo[0].length;
    for (var b = 0; b < arreglo.length; b++) {
        tmp = "";
        for (var a = 0; a < longitud; a++) {
            tmp = tmp + arreglo[b][a].toString() + ",";
        }
        tmp = tmp.substring(0, tmp.length - 1);
        arr.push(tmp);
    }
    // se genera el json con los nombres de las series
    for (var j = 0; j < dataset.length; j++) {
        nombreserie.push({ name: serie[j], data: [dataset[j].slice(0, -1)] });
    }
    var js = seriecompleta(nombreserie);
    buildHtmlTable(data, contenedortabla);
    var categorias = armarcategorias(key);
    var Titulo = creartitulografico(key[0]);
    //se debe llamar a la funcion que se quiera graficar
    //creargraficogeneral(contenedor, Titulo, categorias, js);
    graficadimensiones(contenedor, Titulo, categorias, js);
    //pie();
    }
//***********************************************************************************************************//
//** Función:     funcion que crea las series en objetos JSON de acuerdo a las categorias requeridas
//** Parametros:  Recibe 3 parametro
//**              - dataset: arreglo en el cual se guarda la data de cada grafica
//**              - key: array con el nombre de las categorias
//*               - data objeto json con la data que se debe procesar
//** Observacion:
//***********************************************************************************************************//
function series(dataset,data, key) {
    var series = [];
    var NombreSeries = [];
    series = JSON.parse(data);
    var dato = [];
    for (var i = 0; i < series.length; i++) {
        NombreSeries.push(series[i][key[0]]);
    }
    for (var i = 0; i < series.length; i++) {
        dato = "";
        for (var j = 1; j < key.length; j++) {
            dato = dato + series[i][key[j]] + ",";
        }
        dataset.push(dato);
    }
    var columnas = data.toString();
    var temp = new Array();
    temp = columnas.split(',');
    var NombresEncabezado = [];
    for (var i = 1; i < NombreSeries.length; i++) {
        NombresEncabezado.push({ "data": NombreSeries[i] });
    }
    return NombreSeries;
}
//***********************************************************************************************************//
//** Función:     Funcion para instanciar la creacion de la tabla de cada grafica dinamicamente
//** Parametros:  Recibe 2 parametro
//**              - myList: arreglo con la data que se debe mostrar en la tabla
//**              - contenedortabla: id del div donde  pintar la tabla
//** Observacion:
//***********************************************************************************************************//
function buildHtmlTable(myList, contenedortabla) {
    var listas = JSON.parse(myList);
    CreateTable(listas, contenedortabla);
}
//***********************************************************************************************************//
//** Función:     Recibe los parametros necesarios para crear las tablas y las graficas por cada objeto JSON la ata debe ser parseada antes de iniciar la creacion de la tabla
//** Parametros:  Recibe 2 parametro
//**              - myList: arreglo con la data que se debe mostrar en la tabla
//**              - contenedortabla: id del div donde se pintar la tabla
//** Observacion:
//***********************************************************************************************************//
function CreateTable(myList, Contenedor) {
    var series = myList;
    // Se extraen los valores para los encabezados
    var col = [];
    for (var i = 0; i < myList.length; i++) {
        for (var key in myList[i]) {
            if (col.indexOf(key) === -1) {
                col.push(key);
            }
        }
    }
    //se crea la tlabla
    var tabla = document.createElement("table");
    //crear encabezado dinamico
    $(Contenedor).empty();
    $(Contenedor).append(tabla);
    $(Contenedor).append("<thead>");
    $(Contenedor).append("<tr>");
    //$(Contenedor).append("<th style='width:200px;'></th>");
    var array = Array.from(col);
    for (var i = 0; i < array.length; i++) {
        $(Contenedor).append("<th style='width:200px;text-align:center; vertical-align:middle;'>" + array[i].replace(/_/g, " ") + "</th>");
    }
    //se crea el contenido de la tabla
    for (var j = 0; j < series.length; j++) {
        $(Contenedor).append("<tr style='border:1px solid;'>");
        for (var i = 0; i < col.length; i++) {
            if (i == 0) {
                $(Contenedor).append("<td style='border:1px solid;vertical-align:middle;'>" + series[j][col[i]] + "</td>");
            } else {
                $(Contenedor).append("<td style='border:1px solid;vertical-align:middle;text-align: center;'>" + series[j][col[i]] + "</td>");
            }
        }
        $(Contenedor).append("</tr>");
    }
    $(Contenedor).append("</tr>");
    $(Contenedor).append(" </thead>");
    $(Contenedor).append("<tbody>");
    $(Contenedor).append("</tbody>");
    $(Contenedor).append("</table>");
    $(Contenedor).show();
}
//***********************************************************************************************************//
//** Función:     Se realiza la cracion del html necesario para mostrar las graficas y las tablas de acuerdo a la cantidad de datatables que se reciban del c#
//** Parametros:  Recibe 1 parametro
//**              - tamano: cantidad de los tr a crear en el html para la visualizacion de los informes
//** Observacion:
//***********************************************************************************************************//
function createtablecontent(tamano, valorgrafica) {
    var Contenedor = "#contenedor";
    var tabla = document.createElement("table");
    $(Contenedor).append(tabla);
    //se crea el contenido de la tabla
    for (var j = 0; j < tamano; j++) {
        $(Contenedor).append('<tr>');
        $(Contenedor).append('<td >');
        if (valorgrafica == 1) {
            $(Contenedor).append('<div  style="min-width: 550px; height: 400px; margin: 0 auto; display: block;" id="' + "container" + j + '">');
            $(Contenedor).append('</div>');
            $(Contenedor).append('<br/>');
            $(Contenedor).append('<div  class="dataTable" style="width: 100%; font-size: 8pt; vert-align: middle; display: block;" id="' + "divTablaContainer" + j + '">');
            $(Contenedor).append('</td>');
            $(Contenedor).append('</tr>');
            $(Contenedor).append('<br/>');
        }
        else {
            $(Contenedor).append('<div  class="dataTable" style="width: 100%; font-size: 8pt; vert-align: middle; display: block;" id="' + "divTablaContainer" + j + '">');
            $(Contenedor).append('</td>');
            $(Contenedor).append('</tr>');
            $(Contenedor).append('<br/>');
        }
    }
    $(Contenedor).append('<tbody>');
    $(Contenedor).append('</tbody>');
    $(Contenedor).append('</table>');
    $(Contenedor).show();
}
//***********************************************************************************************************//
//** Función:     se sacan las llaves necesarias del objeto para crear las series y los encabezados necesarios para tablas y graficas
//** Parametros:  Recibe 1 parametro
//**              - data: objeto JSON  a graficar
//** Observacion:
//***********************************************************************************************************//
function GetKey(data) {
    var parseJSONResultado = jQuery.parseJSON(data);
    var l = [];
    var j = [];
    l = parseJSONResultado[0];
    for (var key in l) {
        if (key === 'length' || !l.hasOwnProperty(key)) continue;
        j.push(key);
    }
    return j;
}
//***********************************************************************************************************//
//** Función:     se crean las series con los datos que se deben grqficar por categoria
//** Parametros:  Recibe 1 parametro
//**              - nombreserie: arreglo con las series a crear
//** Observacion:
//***********************************************************************************************************//
function seriecompleta(nombreserie) {
    var prueba = JSON.stringify(nombreserie);
    while (prueba.toString().indexOf('["') != -1)
        prueba = prueba.toString().replace('["', '[');
    while (prueba.toString().indexOf('"]') != -1)
        prueba = prueba.toString().replace('"]', ']');
    var js = jQuery.parseJSON(prueba);
    return js;
}
//***********************************************************************************************************//
//** Función:     se crean las categorias que debe tener cada grafica
//** Parametros:  Recibe  parametro
//**              - key: arreglo con los nombres de cada categoria por cada objeto JSON
//** Observacion:
//***********************************************************************************************************//
function armarcategorias(key) {
    var categorias = [];
    for (var i = 1; i < key.length; i++) {
        categorias.push(key[i]);
    }
    for (var a = 0; a < categorias.length; a++) {
        categorias[a] = categorias[a].toString().replace('_', ' ');
        categorias[a] = categorias[a].toString().replace('_', ' ');
    }
    return categorias;
}
//***********************************************************************************************************//
//** Función:     se crea el titulo que se coloca al inicio de cada grafica
//** Parametros:  Recibe 4 parametro
//**              - key: arreglo con las llaves de los titulos
//** Observacion:
//***********************************************************************************************************//
function creartitulografico(key) {
    var Titulo = key;
    while (Titulo.toString().indexOf('_') != -1)
        Titulo = Titulo.toString().replace('_', ' ');
    return Titulo;
}
//***********************************************************************************************************//
//** Función:     Funcion que se instancia para crear el grafico
//** Parametros:  Recibe 4 parametro
//**              - contenedor: el ID del div en el cual se va a graficar
//**              - Titulo: titulo que se le va a cada colocar a la grafica
//**              - categorias: las categorias que va a tener cada  grafica
//*               - js: la data que se va a graficar
//** Observacion:
//***********************************************************************************************************//
function creargraficogeneral(contenedor, Titulo, categorias, js) {
    charter =  $(function () {
        Highcharts.chart(contenedor, {
            chart: {
                type: 'column'
            },
            title: {
                text: Titulo
            },
            subtitle: {
                text: ''
            },
            legend: {
                enabled: false
            },
            xAxis: {
                categories: categorias,
                crosshair: true,
                scrollbar: {
                    enabled: true
                }
            },
            yAxis: {
                min: 0,
                title: {
                    text: 'Frutas'
                }
            },
            tooltip: {
                headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                    '<td style="padding:0">{point.y:.1f} Fruta</td></tr>',
                footerFormat: '</table>',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderWidth: 0
                },
                series: {
                    enableMouseTracking: true
                }
            },
            series: js
        });
    });
}
function graficadimensiones(contenedor, Titulo, categorias, js) {
    Highcharts.chart(contenedor, {
        chart: {
            type: 'column',
            options3d: {
                enabled: true,
                alpha: 15,
                beta: 15,
                viewDistance: 25,
                depth: 40
            }
        },
        title: {
            text: Titulo
        },
        xAxis: {
            categories: categorias
        },
        yAxis: {
            allowDecimals: false,
            min: 0,
            title: {
                text: Titulo
            }
        },
        tooltip: {
            headerFormat: '{point.key}<br>',
            pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
        },
        plotOptions: {
            column: {
                stacking: 'normal',
                depth: 40
            }
        },
        series: js
    });
}
function pie() {
    Highcharts.chart('contenedor', {
        chart: {
            plotBackgroundColor: null,
            plotBorderWidth: null,
            plotShadow: false,
            type: 'pie'
        },
        title: {
            text: 'Browser market shares January, 2015 to May, 2015'
        },
        tooltip: {
            pointFormat: '{series.name}: {point.percentage:.1f}%'
        },
        plotOptions: {
            pie: {
                allowPointSelect: true,
                cursor: 'pointer',
                dataLabels: {
                    enabled: true,
                    format: '{point.name}: {point.percentage:.1f} %',
                    style: {
                        color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
                    }
                }
            }
        },
        series: [{
            name: 'Brands',
            colorByPoint: true,
            data: [{
                name: 'Microsoft Internet Explorer',
                y: 56.33
            }, {
                name: 'Chrome',
                y: 24.03,
                sliced: true,
                selected: true
            }, {
                name: 'Firefox',
                y: 10.38
            }, {
                name: 'Safari',
                y: 4.77
            }, {
                name: 'Opera',
                y: 0.91
            }, {
                name: 'Proprietary or Undetectable',
                y: 0.2
            }]
        }]
    });
}


8- Imágenes con el resultado





Comentarios

Entradas populares de este blog

Exportar Archivos en C# con NPOI

Siempre que se tiene que exportar un archivo, se tienen varias opciones; se puede pensar en usar reporting services, se puede usar librerías que se encuentran en la red, se pueden usar librerías especificas de .NET, pero hoy vamos a ver como usar la librería NPOI. La librería NPOI es una librería de código abierto que se usa para parsear data en archivos de excel, en este caso vamos a usar  un data set  para realizar toda la operación. Se va a crear un libro de excel con extensión xlsx, en el cual se va a crear la plantilla que se requiere para poder visualizar la data y la gráfica correspondiente. se crea el método dentro del cual se tendrá la lógica         public void ejemplonpoi()           { } Se crean la variables necesarias para realizar la conversión del archivo             var extension = "xlsx";             string result = Path.GetTempPath();             DataSet dt = new DataSet();             dt = (DataSet)Session["ListData"