Inicio
Artículos
Categorias
Etiquetas
Visualización de gráficas y tablas con javascript
publicado el: 2022-3-26   actualizado el: 2022-3-26   incluido en: Gráficas y tablas , Linux
palabras totales: 1777   tiempo de lectura: 9 mins  

Existen multitud de formas de representar en la web colecciones de datos visualizándolos como gráficas o como tablas.

En este post quiero exponer una sencilla forma de hacerlo, utilizando varias librerías de javascript, datatables ( pluging para la librería JQuery) para representar las tablas y la librería chart.js para las gráficas.

La forma más adecuada para almacenar los datos a representar en todas ellas es usar bases de datos por todas las ventajas y posibilidades que nos proporcionarían. Pero como sólo necesito representar varios centenares de datos que no van a ser modificados una vez escritos y realmente no tienen mayor valor que el sentimental, los voy a almacenar en un archivo txt para la tabla y en sencillos arrays dentro del código javascript para las gráficas. Esto me facilita su publicación web no teniendo que recurrir a lenguajes de backend ni BBDD.

Para poder utilizar las librerías una de las formas es importarlas dentro de mi proyecto.

Importo la siguiente librería para representar las gráficas usando Chart.js:

1
2
 <!-- Librería Chart.min.js -->
	<script src="https://cdn.jsdelivr.net/npm/chart.js@latest/dist/Chart.min.js"></script>

Y para la tabla con datatables importo estas otras.

1
2
3
4
5
6
7
8
    <!-- Librería JQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <!-- Para la tabla con ajax -->
    <script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/2.2.9/js/responsive.bootstrap5.min.js"></script>
    <script src="assets/js/tabla.js"></script>

Además para formatear la tabla con CSS debo importar otras librerías.

1
2
3
4
    <!-- CSS para dataTables -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.bootstrap5.min.css">

Con todo esto el archivo index.html de mi proyecto se vería así.

index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="es">

  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">

      <!-- CSS para dataTables -->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.min.css">
      <link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
      <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.bootstrap5.min.css">
      
      <title>Gráficas y tablas con JavaScritp</title>
  </head>

  <body>
      <h2>Ejemplo 1 - Gráfica de líneas</h2>

      <canvas id="grafica_lineas"></canvas>
      
      <!-- Librería JQuery -->
      <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        
      <!-- Para representar las gráficas con la librería Chart.min.js -->
      <script src="https://cdn.jsdelivr.net/npm/chart.js@latest/dist/Chart.min.js"></script>
      <script src="assets/js/gráficas.js"></script>
      
      <!-- Para la tabla con datatables y ajax -->
      <script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
      <script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
      <script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script>
      <script src="https://cdn.datatables.net/responsive/2.2.9/js/responsive.bootstrap5.min.js"></script>
      <script src="assets/js/tabla.js"></script>
  </body>

</html>

En el código html anterior he añadido una etiqueta canvas con id="grafica_lineas" donde dibujaré una gráfica multilinea que represente por ejemplo el numero de inmersiones que realice un buceador cada año a una determinada profundidad. Para poder dibujarla utilizo el siguiente código javascript.

graficas.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
$(function () {

    /*
     * Gráfica que representa las inmersiones por profundidades y año 
     */
    
    // Datos de la gráfica profundidades
    const datosInmersionProfundidad = {
        // Estas etiquetas aparecen en la leyenda y en la información del eje x
        labels: ["2003", "2004", "2005", "2006", "2007", "2008", "2009"],
        datasets: [
            {
                label: "-10m", // Nombre de la línea
                backgroundColor: "rgba(255, 159, 64, 0.2)",// Color de fondo
                borderColor:"rgba(255, 159, 64, 1)",// Color del borde
                borderWidth: 1,// Ancho del borde
                data: [7, 9, 3, 3, 19, 7, 12]// Datos
            },
            {
                label: "-20m",
                backgroundColor: "rgba(75, 192, 192, 0.2)",
                borderColor:"rgba(75, 192, 192, 1)",
                borderWidth: 1,
                data: [9, 20, 52, 35, 15, 16, 18]
            },
            {
                label: "-30m",
                backgroundColor: "rgba(153, 102, 255, 0.5)",
                borderColor: "rgba(153, 102, 255, 1)",
                borderWidth: 1,// Ancho del borde
                data: [8, 9, 5, 7, 0, 7, 4]
            },
            {
                label: "-40m",
                backgroundColor: "rgba(159, 255, 64, 0.5)",
                borderColor: "rgba(159, 255, 64, 1)",
                borderWidth: 1,
                data: [0, 2, 4, 11, 0, 2, 1]
            }
        ]
    };
    
    // Opciones de representación de los datos
    const opciones = {
        responsive: true,
        transitions: {
            show: {
              animations: {
                x: {
                  from: 0
                },
                y: {
                  from: 0
                }
              }
            },
            hide: {
              animations: {
                x: {
                  to: 0
                },
                y: {
                  to: 0
                }
              }
            }
          },
        scales: {
            y: {
                beginAtZero: true
            }
        }
    };
   
    // Obtengo la referencia al elemento canvas que quiero seleccionar
    const ctx = document.getElementById("profundidades").getContext('2d');

    // Represento la gráfica
    const profundidades = new Chart(ctx, {
        type: "line", // Tipo de gráfica
        data: datosInmersionProfundidad,
        options: opciones
      });

});

El script anterior lo importo al archivo index.html del proyecto incluyendo la siguiente línea.

1
<script src="assets/js/gráficas.js"></script>

Si quiero añadir más gráficas a mi proyecto debo de crear nuevas etiquetas canvas en donde dibujarlas. Cada una de ellas identificada por su id único al que vincularé una gráfica.

1
2
<canvas id="lugares"></canvas>
<canvas id="anualidades"></canvas>

Añado el código javascript para las otras dos gráficas al archivo graficas.js.

graficas.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    /*
     * Gráfica que representa inmersiones por lugares de inmersión 
     */

    // Datos de las inmersiones por lugares de inmersión
    const datosInmersionLugar = {
      datasets: [{
            data: [294, 2, 7, 2, 9],
            backgroundColor: [
                'rgba(255, 99, 132, 0.5)',
                'rgba(255, 159, 64, 0.5)',
                'rgba(255, 205, 86, 0.5)',
                'rgba(75, 192, 192, 0.5)',
                'rgba(54, 162, 235, 0.5)'
                ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(255, 159, 64, 1)',
                'rgba(255, 205, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(54, 162, 235, 1)'
                ],
            borderWidth: 1
        }],

        // Estas etiquetas aparecen en la leyenda y en la información del eje x
        labels: [
            'I. de Mouro',
            'Tablas de Daimiel',
            'P. Riomiera',
            'Niño Reef',
            'I. Mauricio'
        ]
    };

    // Represento la gráfica de las inmersiones por lugares de inmersión
    const myPieChart = new Chart("lugares",{
        type: 'pie',// Grafica tipo tarta
        data: datosInmersionLugar,
        options: opciones
    });


    /*
     * Gráfica que representa inmersiones por anualidades 
     */

    // Datos de inmersiones por año para la gráfica
    const datosInmersionAnualidad = {
        datasets: [{
            label: "Inmersiones totales por año",
            data: [ 24, 40, 63, 71, 34],
            backgroundColor: [
                'rgba(255, 99, 132, 0.5)',
                'rgba(255, 159, 64, 0.5)',
                'rgba(255, 205, 86, 0.5)',
                'rgba(75, 192, 192, 0.5)',
                'rgba(54, 162, 235, 0.5)'
                ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(255, 159, 64, 1)',
                'rgba(255, 205, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(54, 162, 235, 1)'
                ],
            borderWidth: 1
        }],

        // Estas etiquetas aparecen en la leyenda y en la información del eje x
        labels: ['2003', '2004', '2005', '2006', '2007']
    };

    // Represento la gráfica de las inmersiones por año
    const diagramaBarras = new Chart("anualidades", {
        type: 'bar', // tipo de gráfica de barras
        data: datosInmersionAnualidad,
        options: opciones
        });

Con esto ya tengo representadas las gráficas. Lo siguiente que quiero es crear un tabla que por ejemplo muestre el detalle de cada una de las inmersiones de dicho buceador.

Para ello añado el código html que representará la tabla a mi archivo index.html del proyecto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<table id="tabla" class="display table table-striped table-sm" style="width:100%">
  <thead class=" text-primario">
      <tr>
         <th></th>
         <th>Lugar</th>
         <th>Fecha</th>
         <th>Prof.</th>
         <th>Tiempo</th>
         <th>%O2</th>
         <th></th>
         <th>Inicio</th>
         <th>Fin</th>
         <th>Int sup</th>
         <th>CNS o2</th>
         <th>Prof. media</th>
         <th>Cons. Bares</th>
         <th>Botella</th>
         <th>Cons. litros</th>
         <th>l/min</th>
         <th>Observaciones</th>
      </tr>
  </thead>
</table>

Utilizo el siguiente scritp que llama a la librería Datatable para construir la tabla.

tabla.js

1
2
3
4
5
6
7
8
9
$(document).ready(function() {
    $('#tabla').DataTable( {
        "ajax": '/diario_de_inmersiones/assets/ajax/data/buceo.txt',
        "language": {
            "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
        },
        "scrollY": "300px",
    } );
} );   

Este a su vez llama al archivo buceo.txt donde he almacenado en un array los datos de cada inmersión.

buceo.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
  "data": [
    [
      "462",
      "Isla de Mouro",
      "02/09/2021",
      "14,7",
      "47",
      "21",
      "14",
      "17:58:00",
      "18:45:00",
      "0",
      "0",
      "7,9",
      "112",
      "12",
      "1342",
      "28,60",
      "Zona de la Corvera, el agua estaba muy fría y bastante sucia. Fuimos todos en grupo. Lo mejor una docena de lubinas de las gordas gordas que descubrió pepe en una grieta. !!Espectacular!! "
    ],
    [
      "461",
      "Isla de Mouro",
      "17/08/2021",
      "11,1",
      "65",
      "21",
      "20",
      "17:44:00",
      "18:49:00",
      "0",
      "0",
      "6,2",
      "125",
      "12",
      "1500",
      "23,08",
      ""
    ],
    [
      "460",
      "Laredo",
      "08/08/2020",
      "24,3",
      "37",
      "21",
      "14",
      "09:10:00",
      "10:27:00",
      "0",
      "0",
      "18,1",
      "115",
      "12",
      "1380",
      "37,30",
      "Aquí el agua estaba muy fría"
    ]
  ]
 }

El archivo index.html que representa a las tres gráficas y la tabla quedaría así:

index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- CSS para dataTables -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.bootstrap5.min.css">
    
    <title>Gráficas y tablas con JavaScritp</title>
</head>

<body>
    <h2>Ejemplo 1 - Gráfica de líneas</h2>
    <canvas id="grafica_lineas"></canvas>
    <h2>Ejemplo 2 - Gráfica de porciones</h2>
    <canvas id="lugares"></canvas>
    <h2>Ejemplo 3 - Gráfica de barras</h2>
	<canvas id="anualidades"></canvas>
    
    <h2>Ejemplo 4 - Tabla</h2>
    <table id="tabla" class="display table table-striped table-sm" style="width:100%">
      <thead class=" text-primario">
          <tr>
             <th></th>
             <th>Lugar</th>
             <th>Fecha</th>
             <th>Prof.</th>
             <th>Tiempo</th>
             <th>%O2</th>
             <th></th>
             <th>Inicio</th>
             <th>Fin</th>
             <th>Int sup</th>
             <th>CNS o2</th>
             <th>Prof. media</th>
             <th>Cons. Bares</th>
             <th>Botella</th>
             <th>Cons. litros</th>
             <th>l/min</th>
             <th>Observaciones</th>
          </tr>
      </thead>
    </table>
    
    <!-- Librería JQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
      
    <!-- Para representar las gráficas con la librería Chart.min.js -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js@latest/dist/Chart.min.js"></script>
    <script src="assets/js/gráficas.js"></script>
    
    <!-- Para la tabla con datatables y ajax -->
    <script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script>
    <script src="https://cdn.datatables.net/responsive/2.2.9/js/responsive.bootstrap5.min.js"></script>
    <script src="assets/js/tabla.js"></script>

</body>

</html>

Con esto es suficiente para representar las tres gráficas y la tabla de inmersiones. Ya solo queda ponerlo un poco mas bonito con un poco de html y css, pero eso sería contenido para otro árticulo. Se pude ver el resultado aquí, y el código del proyecto aquí.

Fuentes

https://www.chartjs.org/

https://cdnjs.com/libraries/Chart.js

https://www.datatables.net/