{"id":7001004,"date":"2018-12-28T09:28:07","date_gmt":"2018-12-28T09:28:07","guid":{"rendered":"https:\/\/alistapart.com\/it\/?post_type=article&#038;p=7001004"},"modified":"2019-08-30T10:03:32","modified_gmt":"2019-08-30T10:03:32","slug":"gestire-i-dati-con-javascript","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/gestire-i-dati-con-javascript\/","title":{"rendered":"Gestire i dati con JavaScript"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Amo i dati. Adoro anche JavaScript. Tuttavia, i dati e il codice JavaScript lato client sono spesso considerati mutualmente esclusivi. In genere, il settore considera l&#8217;elaborazione e l&#8217;aggregazione dei dati come una funzione di back-end, mentre JavaScript \u00e8 solo per la visualizzazione dei dati pre-aggregati. La larghezza di banda e il tempo di elaborazione sono visti come enormi colli di bottiglia per gestire i dati sul lato client. E, per la maggior parte, sono d&#8217;accordo. Ma ci sono situazioni in cui l&#8217;elaborazione dei dati nel browser ha perfettamente senso. In quei casi d&#8217;uso, come possiamo avere successo?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pensare ai dati<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lavorare con i dati in JavaScript richiede sia dati completi sia una comprensione degli strumenti che abbiamo a disposizione senza dover effettuare inutili chiamate server. Facciamo un&#8217;utile distinzione tra dati trilaterali e dati riepilogati.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>I dati trilaterali<\/em> sono costituiti da dati transazionali raw (ossia dati ricavati direttamente da una transazione, non elaborati). Si tratta del dettaglio di basso livello che, di per s\u00e9, \u00e8 quasi impossibile da analizzare. Dall&#8217;altra parte dello spettro abbiamo i <em>dati riepilogati<\/em>. Si tratta di dati che possono essere presentati in un modo significativo e ragionato. Chiameremo questi i nostri <em>dati composti<\/em>. La cosa pi\u00f9 importante per gli sviluppatori sono le strutture dati che risiedono tra i nostri dettagli transazionali e i nostri dati completamente composti. Questo \u00e8 il nostro &#8220;punto giusto&#8221;. Tali set di dati sono aggregati ma contengono pi\u00f9 di quello che ci serve per la presentazione finale. Sono multidimensionali in quanto hanno due o pi\u00f9 dimensioni diverse (e pi\u00f9 misure) che offrono flessibilit\u00e0 per la presentazione dei dati. Questi set di dati consentono agli utenti finali di modellare i dati ed estrarre le informazioni per ulteriori analisi. Sono piccoli e performanti, ma offrono abbastanza dettagli per consentire approfondimenti che voi, come autori, potreste non aver previsto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Non \u00e8 necessario che l&#8217;obiettivo sia di avere i dati in forma perfetta per evitare tutte le manipolazioni nel front end. Al contrario, fate s\u00ec che i dati siano ridotti a un dataset multidimensionale. Definite diverse dimensioni chiave (es., persone, prodotti, luoghi e tempo) e misure (ad es. somma, conteggio, media, minimo e massimo) a cui potrebbe essere interessato il vostro cliente. Infine, presentate i dati sulla pagina con elementi di form che possano suddividere i dati in un modo che permetta un&#8217;analisi pi\u00f9 approfondita.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nella creazione dei dataset abbiamo a che fare con un equilibrio delicato. Dovrete avere sufficienti dati per rendere le vostre statistiche significative senza mettere troppo sotto stress la macchina client. Questo significa trovare dei requisiti chiari e concisi. A seconda di quanto \u00e8 grande il dataset, potreste aver bisogno di includere molte dimensioni e metodi di misura differenti. Alcune cose da tenere a mente:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>La variet\u00e0 del contenuto \u00e8 un caso limite o qualcosa di frequente? Seguite la regola 80\/20: generalmente, all&#8217;80% degli utenti serve il 20% di ci\u00f2 che \u00e8 disponibile.<\/li><li>Ogni dimensione \u00e8 finita? Le dimensioni dovrebbero sempre avere un insieme predeterminato di valori. Per esempio, un inventario di prodotti sempre in aumento potrebbe essere travolgente, mentre le categorie di prodotto potrebbero funzionare bene.<\/li><li>Quando \u00e8 possibile, aggregate i dati, specialmente le date. Se potete cavarvela aggregando per anni, fatelo. Se dovete scendere al trimestre o al mese, potete farlo, ma evitate qualunque cosa al di sotto di questo.<\/li><li>Less is more. Una dimensione che ha meno valori \u00e8 migliore per la performance. Per esempio, prendete un dataset con 200 righe. Se aggiungete un&#8217;altra dimensione che ha quattro possibili valori, crescer\u00e0 al massimo di 200 * 4 = 800 righe. Se aggiungete una dimensione che ha 50 valori, crescer\u00e0 di 200 * 50 = 10.000 righe. Ci\u00f2 sar\u00e0 aggravato da ogni dimensione che aggiungete.<\/li><li>Nei set di dati multidimensionali, evitare di riepilogare le misure che devono essere ricalcolate ogni volta che cambia il set di dati. Per esempio, se pianificate di mostrare le medie, dovreste includere il totale e la somma. Calcolate le medie dinamicamente. In questo modo, se riepilogate i dati, potete ricalcolare le medie usando i valori riassunti.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Assicuratevi di comprendere i dati con cui state lavorando prima di cercare di fare una qualsiasi delle cose elencate sopra. Potreste formulare delle ipotesi sbagliate che portano a decisioni malinformate. La qualit\u00e0 dei dati \u00e8 sempre una priorit\u00e0 assoluta. Questo vale per i dati che state interrogando e producendo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Non prendete mai un dataset e formulate ipotesi su una dimensione o una misura. Non esitare a chiedere i <a href=\"http:\/\/library.ucmerced.edu\/node\/10249\"> data dictionaries<\/a> o altra documentazione sui dati per aiutarvi a capire che cosa state guardando. L&#8217;analisi dei dati non \u00e8 qualcosa che si indovina. Potrebbero essere state applicate regole aziendali oppure i dati potrebbero essere filtrati preventivamente. Se non avete davanti a voi queste informazioni, potreste facilmente finire per comporre set di dati e visualizzazioni che sono prive di significato o, peggio ancora, completamente fuorvianti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il seguente esempio di codice vi aiuter\u00e0 a spiegare ci\u00f2 ulteriormente. <a href=\"https:\/\/github.com\/ignoreintuition\/tamingData\">Il codice completo per questo esempio pu\u00f2 essere trovato su GitHub.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Il nostro use case<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Per il nostro esempio useremo il <a href=\"https:\/\/github.com\/BuzzFeedNews\/2015-11-refugees-in-the-united-states\">dataset di BuzzFeed<\/a> da \u201cWhere U.S. Refugees Come From\u2014and Go\u2014in Charts\u201d. Creeremo una piccola app che ci mostrer\u00e0 il numero di rifugiati arrivati in uno stato selezionato in un anno selezionato. Nello specifico mostreremo uno dei seguenti casi a seconda della richiesta dell&#8217;utente:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>arrivi totali per uno stato in un dato anno;<\/li><li>arrivi totali per tutti gli anni per un dato stato;<\/li><li>arrivi totali per tutti gli stati in un dato anno.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La UI per selezionare stato e anno sar\u00e0 una semplice form:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1154\" height=\"788\" src=\"https:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2019\/08\/fig1.png?fit=960%2C655\" alt=\"\" class=\"wp-image-7001007\" \/><figcaption>La UI per l&#8217;input dei nostri dati<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Il codice:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Mander\u00e0 una richiesta per i dati.<\/li><li>Convertir\u00e0 i risultati in JSON.<\/li><li>Processer\u00e0 i dati.<\/li><li>Far\u00e0 il log di qualsiasi errore nella console. (<i>Nota: per essere sicuri che lo step 3 non venga eseguito fino a che non sar\u00e0 completamente recuperato il dataset, useremo il metodo then e faremo tutto il processing dei dati all&#8217;interno di quel blocco.<\/i>)<\/li><li>Mostrer\u00e0 i risultati all&#8217;utente.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Non vogliamo passare dei dataset eccessivamente larghi ai browser per due ragioni principali: ampiezza di banda e CPU. Al contrario, aggregheremo i dati sul server con Node.js.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Dati sorgente:<\/b><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[{\"year\":2005,\"origin\":\"Afghanistan\",\"dest_state\":\"Alabama\",\"dest_city\":\"Mobile\",\"arrivals\":0},\n{\"year\":2006,\"origin\":\"Afghanistan\",\"dest_state\":\"Alabama\",\"dest_city\":\"Mobile\",\"arrivals\":0},\n... ]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Dati multidimensionali:<\/b><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[{\"year\": 2005, \"state\": \"Alabama\",\"total\": 1386}, \n {\"year\": 2005, \"state\": \"Alaska\", \"total\": 989}, \n... ]<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1296\" height=\"562\" src=\"https:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2019\/08\/fig2.png?fit=960%2C416\" alt=\"\" class=\"wp-image-7001008\" \/><figcaption>Transactional Details mostra molti item con Year, Origin, Destination, City e Arrivals. Questo viene filtrato attraverso i dati semi-aggregati: By Year, By State e  Total. Nella colonna finale, vediamo una tabella con i dati completamente composti risultanti dal passaggio di Transactional Details attraverso i dati semi-aggregati.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Come sistemare la struttura dati<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">AJAX e la Fetch API<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">C&#8217;\u00e8 una serie di modi in JavaScript per raccogliere dati da una sorgente esterna. Storicamente, avreste usato una <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/XMLHttpRequest\">XHR request<\/a>. XHR \u00e8 ampiamente supportata, ma \u00e8 anche piuttosto complessa e richiede molti metodi differenti. Ci sono anche librerie come <a href=\"https:\/\/github.com\/axios\/axios\">Axios<\/a> o <a href=\"https:\/\/api.jquery.com\/jquery.ajax\/\">la AJAX API di jQuery<\/a>. Queste possono essere utili per ridurre la complessit\u00e0 e forniscono il supporto cross-browser. Potrebbero essere un&#8217;opzione se state gi\u00f9 usando queste librerie, ma noi vogliamo optare per una soluzione nativa ovunque sia possibile. Infine, c&#8217;\u00e8 la pi\u00f9 recente <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Fetch_API\">Fetch API<\/a>. \u00c8 <a href=\"https:\/\/caniuse.com\/#search=fetch\">meno supportata<\/a>, ma \u00e8 semplice e concatenabile. E se state usando un transpiler (es., <a href=\"https:\/\/babeljs.io\/\">Babel<\/a>), convertir\u00e0 il vostro codice in un equivalente molto pi\u00f9 supportato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per il nostro use case, useremo la Fetch API per mettere i dati nella nostra applicazione:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>window.fetchData = window.fetchData || {};\n  fetch('.\/data\/aggregate.json')\n  .then(response =&gt; {\n      \/\/ when the fetch executes we will convert the response\n      \/\/ to json format and pass it to .then()\n      return response.json();\n  }).then(jsonData =&gt; {\n      \/\/ take the resulting dataset and assign to a global object\n      window.fetchData.jsonData = jsonData;\n  }).catch(err =&gt; {\n      console.log(\"Fetch process failed\", err);\n  });<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Questo codice \u00e8 una snippet tratta da main.js nel repo GitHub.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il metodo <code>fetch()<\/code> invia una richiesta per i dati e noi convertiamo i risultati in JSON. Per assicurarci che lo statement seguente non vada in esecuzione fino a dopo aver completato il retrieve dell&#8217;intero dataset, usiamo il metodo <code>then()<\/code> e facciamo tutto il nostro data processing all&#8217;interno di quel blocco. Da ultimo, usiamo <code>console.log()<\/code> per loggare tutti gli errori.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il nostro obiettivo, qui, \u00e8 di identificare le dimension chiave che ci servono per fare i report &#8211; anno e stato &#8211; prima di aggregare il numero di arrivi per quelle dimension, rimuovendo il paese di origine e la citt\u00e0 di destinazione. Potete far riferimento allo script di Node.js <code>\/preprocess\/index.js<\/code> sul repo GitHub per maggiori dettagli su come farlo. Genera il file <code>aggregate.json<\/code> caricato da <code>fetch()<\/code> sopra.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dati multidimensionali<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">L&#8217;obiettivo della formattazione multidimensionale \u00e8 la flessibilit\u00e0: i dati sono sufficientemente dettagliati da far s\u00ec che l&#8217;utente non debba inviare una query al server ogni volta che desidera rispondere a una domanda diversa, ma riepilogati in modo tale che l&#8217;applicazione non debba procedere rapidamente all&#8217;interno dell&#8217;intero dataset con ogni nuovo pezzo di dati. \u00c8 necessario anticipare le domande e fornire dati che formulino le risposte. I clienti vogliono essere in grado di fare qualche analisi senza sentirsi costretti o completamente sopraffatti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Come per la maggior parte delle API, lavoreremo con i dati JSON. <a href=\"http:\/\/json.org\/\">JSON<\/a> \u00e8 uno standard che viene usato dalla maggior parte delle API per mandare dati alle applicazioni sotto forma di oggetti costituiti da coppie nome-valore. Prima di tornare al nostro use case, diamo un&#8217;occhiata a un esempio di dataset multidimensionale:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const ds = [{\n  \"year\": 2005,\n  \"state\": \"Alabama\",\n  \"total\": 1386,\n  \"priorYear\": 1201\n}, {\n  \"year\": 2005,\n  \"state\": \"Alaska\",\n  \"total\": 811,\n  \"priorYear\": 1541\n}, {\n  \"year\": 2006,\n  \"state\": \"Alabama\",\n  \"total\": 989,\n  \"priorYear\": 1386\n}];<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Con il nostro dataset aggregato in maniera appropriata, possiamo usare JavaScript per analizzarlo ulteriormente. Diamo un&#8217;occhiata ad alcuni metodi nativi per gli array per comporre i dati.With your dataset properly aggregated, we can use JavaScript to further analyze it. Let\u2019s take a look at some of JavaScript\u2019s native array methods for composing data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Come lavorare efficacemente con i dati via JavaScript<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Array.filter()<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Il metodo <code>filter()<\/code> del prototype <code>Array<\/code> (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/filter\"><code>Array.prototype.filter()<\/code><\/a>) prende una funzione che testa ogni item nell&#8217;array, ritornando un altro array che contiene solo i valori che hanno passato il test. Vi permette di creare dei sottoinsiemi significativi di dati basati su una selezione dropdown o dei filtri testuali. Supponendo che abbiate incluso dimensioni significative e discrete per il vostro dataset multidimensionale, il vostro utente sar\u00e0 in grado di ricavare delle opinioni guardando delle tranche individuali di dati.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ds.filter(d =&gt; d.state === \"Alabama\");\n\n\/\/ Result\n[{\n  state: \"Alabama\",\n  total: 1386,\n  year: 2005,\n  priorYear: 1201\n},{\n  state: \"Alabama\",\n  total: 989,\n  year: 2006,\n  priorYear: 1386\n}]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Array.map()<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Il metodo <code>map()<\/code> del prototype <code>Array<\/code> (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/map\"><code>Array.prototype.map()<\/code><\/a>) prende una funzione e ci fa passare ogni item dell&#8217;array, ritornando un nuovo array con un egual numero di elementi. Mappare i dati vi d\u00f2 l&#8217;abilit\u00e0 di creare dei dataset collegati. Uno use case per questo \u00e8 mappare dati ambigui a dati pi\u00f9 significativi e descrittivi. Un&#8217;altro \u00e8 di prendere delle metriche e farci dei calcoli per permettere un&#8217;analisi pi\u00f9 approfondita.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Use case n.1\u2014mappare i dati a dati pi\u00f9 significativi:<\/b><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ds.map(d =&gt; (d.state.indexOf(\"Alaska\")) ? \"Contiguous US\" : \"Continental US\");\n\n\/\/ Result\n[\n  \"Contiguous US\", \n  \"Continental US\", \n  \"Contiguous US\"\n]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Use case n.2\u2014mappare i dati ai risultati calcolati:<\/b><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ds.map(d =&gt; Math.round(((d.priorYear - d.total) \/ d.total) * 100));\n\n\/\/ Result\n[-13, 56, 40]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Array.reduce()<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Il metodo <code>reduce()<\/code> del prototype <code>Array<\/code> (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/reduce\"><code>Array.prototype.reduce()<\/code><\/a>) prende una funzione e ci fa girare ogni item dell&#8217;array, ritornando un risultato aggregato. \u00c8 usato pi\u00f9 comunemente per fare matematica, come aggiungere o moltiplicare ogni numero in un array, sebbene possa anche essere usato per concatenare stringhe o fare molte altre cose. L&#8217;ho sempre trovato un po&#8217; complicato: lo si impara meglio con un esempio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quando presenterete i dati, dovrete essere sicuri che siano riassunti in maniera da dare degli insight ai vostri utenti. Anche se avete fatto dei riassunti a livello generale dei dati lato server, qui \u00e8 dove permettete un&#8217;aggregazione ulteriore, basata sui bisogni specifici del consumatore. Per la nostra app, vogliamo aggiungere il totale a ogni entry e mostrare il risultato aggregato. Lo faremo usando <code>reduce()<\/code> per iterare in ogni record e per aggiungere il valore corrente all&#8217;accumulatore. Il risultato finale sar\u00e0 la somma di tutti i valori (totale) per l&#8217;array.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ds.reduce((accumulator, currentValue) =&gt; \naccumulator + currentValue.total, 0);\n\n\/\/ Result\n3364<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Applicare queste funzioni al nostro use case<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Una volta che avremo i nostri dati, assegneremo un evento al pulsante \u201cGet the Data\u201d che presenter\u00e0 il sottoinsieme appropriato dei nostri dati. Ricordate che abbiamo molte centinaia di item nei nostri dati JSON. Il codice per legare i dati al nostro pulsante si trova nel nostro main.js:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> document.getElementById(\"submitBtn\").onclick =\n  function(e){\n      e.preventDefault();\n      let state = document.getElementById(\"stateInput\").value || \"All\"\n      let year = document.getElementById(\"yearInput\").value || \"All\"\n      let subset = window.fetchData.filterData(year, state);\n      if (subset.length == 0  )\n        subset.push({'state': 'N\/A', 'year': 'N\/A', 'total': 'N\/A'})\n      document.getElementById(\"output\").innerHTML =\n      `&lt;table class=\"table\"&gt;\n        &lt;thead&gt;\n          &lt;tr&gt;\n            &lt;th scope=\"col\"&gt;State&lt;\/th&gt;\n            &lt;th scope=\"col\"&gt;Year&lt;\/th&gt;\n            &lt;th scope=\"col\"&gt;Arrivals&lt;\/th&gt;\n          &lt;\/tr&gt;\n        &lt;\/thead&gt;\n        &lt;tbody&gt;\n          &lt;tr&gt;\n            &lt;td&gt;${subset[0].state}&lt;\/td&gt;\n            &lt;td&gt;${subset[0].year}&lt;\/td&gt;\n            &lt;td&gt;${subset[0].total}&lt;\/td&gt;\n          &lt;\/tr&gt;\n        &lt;\/tbody&gt;\n      &lt;\/table&gt;`\n  }<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1150\" height=\"976\" src=\"https:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2019\/08\/fig3.png?fit=960%2C815\" alt=\"\" class=\"wp-image-7001009\" \/><figcaption>L&#8217;output finale una volta applicato il nostro codice<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Se lasciate vuoto lo stato o l&#8217;anno, quel campo andr\u00e0 di default a \u201cAll\u201d. Il seguente codice \u00e8 disponibile in <code>\/js\/main.js<\/code>. Dovreste osservare la funzione <code>filterData()<\/code>, che \u00e8 dove teniamo la porzione pi\u00f9 grossa delle funzionalit\u00e0 di aggregazione e filtering.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ with our data returned from our fetch call, we are going to \n\/\/ filter the data on the values entered in the text boxes\nfetchData.filterData = function(yr, state) {\n  \/\/ if \"All\" is entered for the year, we will filter on state \n  \/\/ and reduce the years to get a total of all years\n  if (yr === \"All\") {\n    let total = this.jsonData.filter(\n      \/\/ return all the data where state\n      \/\/ is equal to the input box\n      dState =&gt; (dState.state === state)\n        .reduce((accumulator, currentValue) =&gt; {\n          \/\/ aggregate the totals for every row that has \n          \/\/ the matched value\n          return accumulator + currentValue.total;\n        }, 0);\n\n    return [{'year': 'All', 'state': state, 'total': total}];\n  }\n\n  ...\n\n  \/\/ if a specific year and state are supplied, simply\n  \/\/ return the filtered subset for year and state based \n  \/\/ on the supplied values by chaining the two function\n  \/\/ calls together \n  let subset = this.jsonData.filter(dYr =&gt; dYr.year === yr)\n    .filter(dSt =&gt; dSt.state === state);\n\n  return subset; \n};\n\n\/\/ code that displays the data in the HTML table follows this. See main.js.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Quando uno stato o un anno \u00e8 vuoto, andr\u00e0 di default a \u201cAll\u201d e filtreremo il nostro dataset a quella particolare dimension e riassumeremo la metrica per tutte le righe in quella dimension. Quando verranno inseriti sia anno sia stato, filtreremo semplicemente i valori.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Abbiamo ora un esempio funzionante in cui:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>partiamo con un dataset raw, transazionale,<\/li><li>creiamo un dataset semi-aggregato, multidimensionale,<\/li><li>e costruiamo dinamicamente un risultato completamente composto.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Si noti che una volta che i dati vengono estratti dal client, possiamo manipolarli in un certo numero di modi diversi senza dover effettuare chiamate successive al server. Questo \u00e8 particolarmente utile perch\u00e9 se l&#8217;utente perde la connettivit\u00e0, non perde la capacit\u00e0 di manipolare i dati. Ci\u00f2 \u00e8 utile se si sta creando una progressive web app (PWA) che deve essere disponibile offline. (Se non siete sicuri se la vostra app web debba essere una PWA, <a href=\"https:\/\/alistapart.com\/article\/yes-that-web-project-should-be-a-pwa\"> questo articolo <\/a> pu\u00f2 aiutare.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una volta ottenuto il controllo completo su questi tre metodi, \u00e8 possibile creare praticamente qualsiasi analisi desiderata su un set di dati. Mappare una dimensione nel set di dati in una categoria pi\u00f9 ampia e riepilogare utilizzando reduce. Combinato con <a href=\"https:\/\/d3js.org\/\">una libreria come D3<\/a>, potete mappare questi dati in grafici e diagrammi per consentire una visualizzazione dei dati completamente personalizzabile.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusioni<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Questo articolo d\u00e0 un&#8217;idea migliore di ci\u00f2 che \u00e8 possibile in JavaScript quando si lavora con i dati. Come ho accennato, JavaScript lato client non \u00e8 in alcun modo un sostituto per la traduzione e la trasformazione dei dati sul server, dove dovrebbe essere fatto il lavoro pesante. Ma allo stesso tempo, non dovrebbe essere completamente escluso quando i dataset vengono trattati in maniera appropriata.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&#8217;elaborazione di enormi quantit\u00e0 di dati sul Web \u00e8 sempre un lavoro di back-end, tranne quando non lo \u00e8. A volte ha senso l&#8217;elaborazione dei dati nel browser mediante JavaScript. Quali sono questi casi d&#8217;uso e come possiamo riuscirci? Brian Greig ci dice tutto.<\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"closed","ping_status":"open","template":"","categories":[271],"tags":[],"coauthors":[551],"class_list":["post-7001004","article","type-article","status-publish","hentry","category-javascript"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/7001004","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=7001004"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=7001004"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=7001004"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=7001004"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=7001004"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}