Setup Menus in Admin Panel

School.Dataninja.it

Visualizzazioni dati con d3js: modificare attributi e stili

Una volta selezionati gli elementi su cui vuoi agire, puoi modificare attributi, classi e stili con alcuni metodi utili.

Ora che hai imparato a selezionare gli elementi della pagina che ti interessano, è ora di modificarne gli attributi. D3js mette a disposizione un semplice metodo generico che agisce sulle selezioni: attr(). Ci sono però anche altri metodi comodi che semplificano la sintassi nel caso di operazioni comuni, come impostare gli stili o aggiungere e rimuovere classi.

Ma cosa significa agire su una selezione? Il metodo select() torna un solo elemento, per cui è abbastanza intuitivo: qualsiasi metodo a valle agisce sull’unico elemento selezionato. Il metodo selectAll() invece ritorna una selezione con molti elementi, un array di elementi. Tutti i metodi a valle agiranno su tutti gli elementi della selezione, uno alla volta, dal primo all’ultimo (ma in generale conoscerne l’ordine non è importante). Di fatto viene eseguito un ciclo su di essi e, per ognuno di essi, le stesse operazioni indicate. In altre parole, il ciclo c’è, ma non si vede (e questo è un bene).

Attributi: il metodo attr()

È il metodo generico, se chiamato con il solo nome dell’attributo come parametro ne ritorna il valore corrente (o null se non è specificato). Se viene chiamato con una stringa come secondo parametro, invece, imposta il nuovo valore all’attributo menzionato. Se il secondo parametro è null, rimuove l’attributo menzionato. Ecco alcuni esempi applicati all’elemento  <a id="link" href="school.dataninja.it">Link</a> :

  • d3.select("a#link").attr("href")  ritorna “school.dataninja.it”;
  • d3.select("a#link").attr("href", "#")  imposta l’url del link alla pagina stessa in cui è contenuto;
  • d3.select("a#link").attr("href", null)  rimuove l’url associato al link

Ecco un esempio un po’ curioso che puoi provare su questa pagina:  d3.select("#content").selectAll("a").attr("href", null) . Se lo provi nella console del browser, per tornare alla situazione originaria dovrai ricaricare la pagina.

Fai attenzione che se usi attr() per leggere il valore di di un attributo, il metodo torna quel valore, non la selezione corrente, per cui non potrai più concatenare altri metodi a valle di attr(). Se invece lo usi per impostare un nuovo valore, allora tornerà la selezione corrente e gli eventuali metodi successivi funzioneranno come atteso.

C’è anche un altro metodo molto simileproperty(), che agisce su alcuni attributi particolari, come il valore associato a un elemento input di testo. Si comporta esattamente allo stesso modo di attr().

Classi: il metodo classed()

L’attributo class di un elemento è un attributo qualsiasi, per cui può essere impostato o modificato con il metodo attr(). Si tratta però di un attributo particolare, perché non è a singolo valore (una chiave, un valore associato), ma a molti valori (una chiave, ma molti valori associati, sotto forma di stringhe separate da spazi). In altre parole, modificando l’attributo class con il metodo attr() sostituisci tutte le classi prima associate all’elemento: d3.select("a#link").attr("class", "link large")  sull’elemento <a id="link" class="link small external">Link</a>  produce <a id="link" class="link large">Link</a> . Questo è molto comodo quando vuoi associare da zero delle classi a un elemento, ma può essere un problema quando vuoi agire sulla presenza o meno di singole classi.

Il metodo classed() prende due parametri: il primo è il nome della classe, il secondo un valore booleano vero o falso. Se vero aggiunge la classe all’elemento selezionato, se falso la rimuove. Ecco come modificare l’esempio precedente: d3.select("a#link").classed("small", false).classed("large", true)  sull’elemento <a id="link" class="link small external">Link</a>  produce <a id="link" class="link large external">Link</a> .

Se vuoi agire contemporaneamente su più classi puoi evitare di concatenare i metodi classed() e passare invece un oggetto che abbia come chiavi i nomi delle classi e come valori verofalso. L’esempio precedente sarebbe modificato in d3.select("a#link").classed({ "small": false, "large": true }) .

Se non specifichi il secondo parametro, il metodo torna verofalso a seconda che quella particolare classe sia presente oppure no.

Stili: il metodo style()

L’attributo style di un elemento è particolare, perché permette di inserire delle regole CSS in linea con il codice HTML. Per esempio: <div id="box" style="color:red;background-color:black;">Box</div> . Se ci pensi è una situazione simile a quella delle classi. In quel caso uno spazio separa i valori multipli (un array di valori) associati all’attributo class. In questo caso un punto e virgola separa coppie chiave:valore multiple (un array di oggetti) associate all’attributo style. Il metodo style() si comporta così in maniera molto simile a quanto già visto per le classi. Per produrre l’esempio precedente a partire da un div vuoto: d3.select("#box").style("color", "red").style("background-color", "black") .

Come per classed(), anche in questo caso puoi passare un oggetto con tutte le regole da modificare: d3.select("#box").style({ "color": "red", "background-color": "black" }) . E anche in questo caso se non viene specificato il secondo parametro il metodo ritorna il valore corrente, mentre se è uguale a null la regola viene eliminata.

Combinare l’azione dei CSS

Il bello di manipolare direttamente gli elementi standard del DOM della pagina sta nel fatto che puoi combinare insieme l’azione di tutte le tecnologie standard che fanno del Web quello che vediamo tutti i giorni. Le regole dei fogli di stile della pagina, per esempio, anche se totalmente indipendenti dall’azione dei metodi di d3js, si sommano alle regole in-line che imposti sugli elementi in base ai dati. La regola generale è quindi di descrivere il layout e lo stile degli elementi della pagina come al solito, con CSS esterni. Intervenire con regole in-line solo per quel che riguarda quegli stili che dipendono quantitativamente dai dati. E quando i dati definiscono uno stato dell’elemento, per esempio se è attivo o meno, è buona norma associarvi delle classi con nomi significativi e delegare a un CSS esterno le regole di stile associate a quelle classi.

Letture: 438