1. Web Design
  2. HTML/CSS
  3. JavaScript for Designers

Visualizzazione dei dati con DataTables.js e Highcharts.js

In questo tutorial, imparerai come visualizzare i dati sfruttando le librerie JavaScript di DataTables.js e Highcharts.js.
Scroll to top

Italian (Italiano) translation by Mirko Pizii (you can also view the original English article)

In questo tutorial, imparerai come visualizzare i dati sfruttando le librerie JavaScript di DataTables.js e Highcharts.js.

Ecco cosa stiamo costruendo (controlla la versione più grande per una migliore esperienza):

Please accept marketing cookies to load this content.

Librerie richieste

Ai fini di questo esempio, dovremo caricare le seguenti librerie nella nostra penna:

  • jQuery
  • DataTables.js
  • Highcharts.js

A tale proposito, se si guarda sotto la scheda Impostazioni, vedrai che ho incluso un file CSS esterno:

Allo stesso modo, ho incluso anche quattro file JavaScript esterni:

Nota: abbiamo dovuto aggiungere jQuery al nostro progetto perché DataTables.js è un plugin jQuery. Tuttavia, tenere presente che Highcharts.js è una libreria JavaScript pura e quindi non richiede jQuery.

l'HTML

Per calciare le cose definiamo un elemento con la classe del contenitore che contiene due sotto-elementi:

  • Un tavolo con 26 righe. La prima riga si riferisce alle intestazioni di tabella th, mentre le altre 25 righe portano i dettagli del paese. La fonte dei nostri dati per questo esempio è worldometers.info.
  • Un div vuoto che terrà il grafico.

Ecco la struttura HTML:

1
<div class="container">
2
  <table id="dt-table">
3
    <thead>
4
      <tr>
5
        <th>Country</th>
6
        <th>Population (2017)</th>
7
        <th>Density (P/Km²)</th>
8
        <th>Med. Age</th>
9
      </tr>
10
    </thead>
11
    <tbody>
12
      <tr>
13
        <td>China</td>
14
        <td>1,409,517,397</td>
15
        <td>150</td>
16
        <td>37</td>
17
      </tr>
18
    
19
      <!-- 24 more rows here -->
20
   
21
    </tbody 
22
  </table>    
23
  
24
  <div id="chart"></div>
25
</div>

Vale la pena ricordare che, per semplicità, abbiamo specificato i suddetti dati di tabella rigida. In un vero e proprio progetto, tuttavia, la tabella potrebbe essere creata dinamicamente.

Con il markup pronto, e un colore di sfondo aggiunto per chiarezza, il progetto sembra così:

Please accept marketing cookies to load this content.

Il CSS

A questo punto, definiamo alcuni stili di base, come ad esempio:

1
.container {
2
  display: flex;
3
  flex-wrap: wrap;
4
  align-items: center;
5
  padding: 0 10px;
6
}
7
8
#dt-table_wrapper {
9
  width: 35%;
10
  margin-right: 2%;
11
}
12
13
#chart {
14
  width: 63%;
15
}
16
17
table {
18
  text-align: left;
19
}
20
21
@media screen and (max-width: 1200px) {
22
  #dt-table_wrapper,
23
  #chart {
24
    width: 100%;
25
  }
26
27
  #dt-table_wrapper {
28
    margin-right: 0;
29
  }
30
}

È importante capire che:

  • Il #dt-table_wrapper non esiste nel nostro markup. È aggiunto dai DataTables non appena l'abbiamo inizializzato.
  • Mentre definiamo alcune regole di base per piccoli schermi, notate che la demo non sarà completamente reattiva. Ci sono molte cose che possiamo fare per rendere meglio la tabella e il grafico su piccole schermate. Ad esempio, per DataTables è disponibile un'estensione Responsive, ma è al di là dell'ambito di questo tutorial.

Con il CSS in atto, vediamo come appare il progetto. Non vedremo ancora una grande differenza perché non abbiamo inizializzato le biblioteche:

Please accept marketing cookies to load this content.

Il JavaScript

Ora per la finestra JavaScript nella nostra penna. Quando il DOM è pronto, viene eseguita la funzione init; questa funzione attiva altre sotto-funzioni:

1
function init() {
2
  const table = $("#dt-table").DataTable();
3
  const tableData = getTableData(table);
4
  createHighcharts(tableData);
5
  setTableEvents(table);
6
}

Come vedrete, ciascuna di queste sotto-funzioni compie un certo compito.

Inizializzare DataTables

Il primo passo è quello di convertire la nostra tabella in una tabella "DataTables". Possiamo farlo con una sola riga di codice: $ ("# dt-table").DataTable();

Se vediamo ora la tabella, noteremo che ha adottato le funzionalità di una tabella DataTables, vale a dire: possiamo ordinare, ricercarla e così via. Gioca con esso nel seguente demo:

Please accept marketing cookies to load this content.

Ora, come si può vedere, i DataTables applicano un ordinamento predefinito alla tabella. Se necessario, possiamo personalizzare questo comportamento.

Estrazione dei dati della tabella

Il passo successivo è quello di afferrare i dati della tabella e costruire il grafico. Non vogliamo tutti i dati della tabella. Infatti, se si guarda indietro alla versione finita della nostra demo, noterete che il grafico contiene solo i dati delle prime tre colonne (Paese, Popolazione, Densità).

A tal fine, per recuperare i dati richiesti, approfitteremo della API DataTables. La funzione responsabile di questo comportamento è la seguente:

1
function getTableData(table) {
2
  const dataArray = [],
3
    countryArray = [],
4
    populationArray = [],
5
    densityArray = [];
6
7
  // loop table rows

8
  table.rows({ search: "applied" }).every(function() {
9
    const data = this.data();
10
    countryArray.push(data[0]);
11
    populationArray.push(parseInt(data[1].replace(/\,/g, "")));
12
    densityArray.push(parseInt(data[2].replace(/\,/g, "")));
13
  });
14
15
  // store all data in dataArray

16
  dataArray.push(countryArray, populationArray, densityArray);
17
18
  return dataArray;
19
}

All'interno di questa funzione, ripetiamo attraverso le righe di tabella e per ogni riga, afferriamo i dati della colonna di destinazione e li immagazziniamo negli array associati. Infine, tutti quegli array vengono memorizzati all'interno di un altro array.

Ecco una rapida visualizzazione dell'array master (cioè dataArray):

The array which holds the desired table data

Prima di passare, è importante capire una cosa. Per impostazione predefinita, la funzione getTableData dovrebbe raccogliere dati da tutte le righe di tabella. Ma, se cerchiamo la tabella per qualcosa di specifico, solo le righe che corrispondono dovrebbero essere raccolte e elaborate. Per eseguire queste cose, passiamo un argomento alla funzione di righe. In particolare, un oggetto con il valore di ricerca "applicato":

Ricordiamo ancora che se non passeremo questo oggetto, raccogliamo sempre dati da tutte le righe di tabella (prova). Per ulteriori informazioni sulle proprietà che possiamo passare a questo oggetto, assicuratevi di esaminare questa pagina.

Costruire il grafico

Ora che abbiamo i dati desiderati, siamo pronti a costruire il grafico. Questo contiene due grafici nidificati, un grafico a colonna e un grafico a spina.

Ecco la funzione corrispondente:

1
function createHighcharts(data) {
2
  Highcharts.setOptions({
3
    lang: {
4
      thousandsSep: ","
5
    }
6
  });
7
8
  Highcharts.chart("chart", {
9
    title: {
10
      text: "DataTables to Highcharts"
11
    },
12
    subtitle: {
13
      text: "Data from worldometers.info"
14
    },
15
    xAxis: [
16
      {
17
        categories: data[0],
18
        labels: {
19
          rotation: -45
20
        }
21
      }
22
    ],
23
    yAxis: [
24
      {
25
        // first yaxis

26
        title: {
27
          text: "Population (2017)"
28
        }
29
      },
30
      {
31
        // secondary yaxis

32
        title: {
33
          text: "Density (P/Km²)"
34
        },
35
        min: 0,
36
        opposite: true
37
      }
38
    ],
39
    series: [
40
      {
41
        name: "Population (2017)",
42
        color: "#0071A7",
43
        type: "column",
44
        data: data[1],
45
        tooltip: {
46
          valueSuffix: " M"
47
        }
48
      },
49
      {
50
        name: "Density (P/Km²)",
51
        color: "#FF404E",
52
        type: "spline",
53
        data: data[2],
54
        yAxis: 1
55
      }
56
    ],
57
    tooltip: {
58
      shared: true
59
    },
60
    legend: {
61
      backgroundColor: "#ececec",
62
      shadow: true
63
    },
64
    credits: {
65
      enabled: false
66
    },
67
    noData: {
68
      style: {
69
        fontSize: "16px"
70
      }
71
    }
72
  });
73
}

Non essere sopraffatto dal codice qui sopra! Senza dubbio il modo migliore per capire come funziona è provarlo. Inoltre, si dovrebbe sicuramente leggere la documentazione. Ad ogni modo, evidenziamo brevemente i concetti chiave:

  • L'asse x contiene tutti i paesi.
  • Definire due assi y. Il primo contiene tutti i valori della popolazione, mentre la seconda include tutte le densità disponibili.
  • Se il nostro grafico non contiene dati, viene visualizzato un messaggio. Notare che siamo in grado di personalizzare il testo del messaggio tramite l'oggetto lang.

Con i grafici in atto, vediamo di nuovo il nostro progresso:

Please accept marketing cookies to load this content.

Sincronizzazione della tabella e delle tabelle

Nella sezione precedente abbiamo costruito la tabella in base ai dati della tabella, ma non esiste ancora alcuna sincronizzazione completa tra la tabella e il grafico. Per provarlo, torna all'ultima demo e cambia l'ordine (ordinamento) della tabella o cerca qualcosa. Noterete che il grafico non reagisce alle modifiche della tabella.

Per risolvere questo problema, approfitteremo dell'evento draw di DrawTables. Questo evento viene generato ogni volta che la tabella viene aggiornata. Così non appena modifichiamo la tabella dobbiamo ricordare i dati della tabella e ricostruire la tabella.

Ecco la cosa difficile però. L'evento draw si attiva anche durante la paginazione della tabella; non c'è motivo di ricostruire la tabella durante questo processo. Idealmente, dovremmo evitare questo comportamento. Fortunatamente, c'è l'evento pagina che ci aiuta a realizzare questo compito.

Ecco il codice che implementa le funzionalità desiderate:

1
let draw = false;
2
3
function setTableEvents(table) {
4
  // listen for page clicks

5
  table.on("page", () => {
6
    draw = true;
7
  });
8
9
  // listen for updates and adjust the chart accordingly

10
  table.on("draw", () => {
11
    if (draw) {
12
      draw = false;
13
    } else {
14
      const tableData = getTableData(table);
15
      createHighcharts(tableData);
16
    }
17
  });
18
}

Ora che sia tabella che tabella sono sincronizzati, se facciamo una ricerca "cattiva", vedremo i seguenti messaggi:

La versione finale del nostro progetto:

Please accept marketing cookies to load this content.

Supporto del browser

Entrambi i plugin hanno un ottimo supporto per il browser (supporto DataTables, supporto Highcharts), quindi puoi aspettarvi che questa demo funziona bene in tutti i browser più recenti.

Ricorda ancora che questa demo non è ottimizzata per piccole schermate.

Infine, come al solito, usiamo Babel per compilare il codice ES6 fino a ES5.

Conclusione

Ecco gente! Siamo riusciti a visualizzare i nostri dati combinando due popolari e potenti librerie JavaScript.

Ora che hai familiarità con il processo, andare avanti e elaborare la funzionalità del demo finale. Ad esempio, cercare di aggiungere filtri personalizzati alla tabella.

Come sempre, se hai domande o se c'è qualcos'altro che vorresti vedere come un passo successivo a questo tutorial, fatemi sapere nei commenti qui sotto.