Visualizzazione dei risultati da 1 a 7 su 7

Discussione: metodo d3.html()

  1. #1
    Utente di HTML.it
    Registrato dal
    May 2021
    Messaggi
    12

    metodo d3.html()

    Salve a tutti... sono un super neofita di javascript; devo sostenere un esame universitario e ho creato una tabella che si costruisce da sola con il metodo d3.csv (e ovviamente un file .csv di base che ho costruito io) la tabella è un semplice palinsesto che forse dovrò sistemare perchè volevo renderlo responsive e ho ricevuto ottimi suggerimenti e aiuti QUI sul forum dedicato al CSS

    ora... siccome sono stato aiutato a scrivere lo script in questa parte:

    codice:
            .html(function (cella) {
                    const [ProgrammaNome, ProgrammaUrl, classeCella] = cella.split("|");
                    /* se la cella ha il valore dell'url, inserisco un link */
                    if (ProgrammaUrl) {
                       return "<a href='" + ProgrammaUrl + "' target='blank' \">" + ProgrammaNome + "</a>"
                    }
                    /* altrimenti mostro un testo normale */
                    /*Se non ci fosse le colonne "dalle" e "alle" non verrebbero visualizzate */
                    else {
                        return ProgrammaNome
                    }
                  }
                 )
        
    });
    
    volevo capire bene come funziona il metodo d3.html() e la sua sintassi.
    per comodità incollo sotto lo script completo

    codice:
     /* inserimento titolo h2 e paragrafo */
    d3.select("body")
        .append("h2")
        .text("Palinsesto programmi 2021")
    d3.select("body")
        .append("p")
        .text("Qui trovate la nostra programmazione settimanale: cliccate sul nome del proogramma per aprire la pagina relativa")
    
    /* inserimento dell'intestazion della tabella con le relative etichette */
    d3.select("body")
        .append("table")
        .append("thead")
        .append("tr")
        .selectAll("th")
        .data(["dalle", "alle", "LUNEDI", "dalle", "alle", "MARTEDI", "dalle", "alle","MERCOLEDI", 
               "dalle", "alle", "GIOVEDI", "dalle", "alle", "VENERDI", "dalle", "alle", "SABATO", 
               "dalle", "alle", "DOMENICA"
        ])
        .enter()
        .append("th")
        .text(function (d) { return d });
    
    d3.select("table")
        .append("tbody")
        .enter();
    
    /*divisione di ogni dato array in 3 parti ProgrammaNome, ProgrammaUrl e datoClasse */
    d3.csv("Palinsesto.csv", function (datiCaricati) {
        console.log(datiCaricati);
        var d = datiCaricati;
        d3.select("tbody")
            .append("tr")
            .selectAll("td")
            .data([d.dalle, d.alle, d.LUNEDI, d.dalle, d.alle, d.MARTEDI, d.dalle, d.alle, d.MERCOLEDI, 
                   d.dalle, d.alle, d.GIOVEDI, d.dalle, d.alle, d.VENERDI, d.dalle, d.alle, d.SABATO, 
                   d.dalle, d.alle, d.DOMENICA])
            .enter()
            .append("td")
            .attr("class",function(d){
                const [Pippo, Pluto, Topolino] = d.split("|");    
                return Topolino;
                })
            .html(function (cella) {
                    const [ProgrammaNome, ProgrammaUrl, classeCella] = cella.split("|");
                    /* se la cella ha il valore dell'url, inserisco un link */
                    if (ProgrammaUrl) {
                       return "<a href='" + ProgrammaUrl + "' target='blank' \">" + ProgrammaNome + "</a>"
                    }
                    /* altrimenti mostro un testo normale */
                    /*Se non ci fosse le colonne "dalle" e "alle" non verrebbero visualizzate */
                    else {
                        return ProgrammaNome
                    }
                  }
                 )
        
    });
    
    grazie :-)
    A.

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2021
    Messaggi
    12
    Sto studiando il metodo .html()... da quanto capisco:

    Se gli si passa un valore setta la proprietà innerHTML dell'elemento che si sta considerando (ad es, un <p> dato con .select("p")) e gli assegna quel valore; ergo:

    codice:
    d3.select("p")
    .html("ciccio")
    nel punto in cui ho inserito il paragrafo p questo avrà come contenuto "ciccio".


    Se invece gli si passa una funzione, questa viene eseguita e restituisce dei valori che vengono inseriti nella proprietà innerHTML degli elementi che si stanno considerando (quindi se gli do in pasto una funzione gli elementi HTML sono più di uno?)


  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,682
    Ciao, non sono esperto di D3 ma rispondo in base a quanto ho letto nella documentazione e da quanto ho provato personalmente.

    Qui la referenza del metodo html()

    Se gli si passa un valore setta la proprietà innerHTML
    Giusto

    Se invece gli si passa una funzione, questa viene eseguita e restituisce dei valori che vengono inseriti nella proprietà innerHTML degli elementi che si stanno considerando
    Corretto ma in particolare la funzione deve essere impostata per restituire qualcosa, cioè attraverso un return (che sia usato esplicitamente o, come nel caso di un array function, anche implicitamente).

    (quindi se gli do in pasto una funzione gli elementi HTML sono più di uno?)
    Non esattamente, gli elementi a cui è applicato il metodo html() prescindono dall'argomento di tale metodo (che sia un semplice valore o una funzione che restituisce un valore); dipendono invece dalla selezione precedentemente effettuata da uno dei metodi di selezione. Usando select() la selezione comprenderà un unico elemento, cioè il primo che viene rilevato attraverso il selettore, mentre usando selectAll() la selezione comprenderà tutti gli elementi rilevati dal selettore.

    La peculiarità di usare una funzione nel metodo html(), piuttosto che un semplice valore costante, sta nel fatto che tale funzione viene valutata per ogni elemento selezionato; alla funzione vengono passati 3 valori come argomenti: il dato corrente, l'indice corrente e il gruppo di nodi selezionati.

    In particolare, il dato corrente è basato sull'array di dati che è possibile unire alla selezione di elementi, ad esempio, attraverso il metodo data().

    Per comprendere meglio, formulo alcuni esempi con diverse situazioni.

    Considerando questo HTML:
    codice HTML:
    <p>Elemento 1</p>
    <p>Elemento 2</p>
    <p>Elemento 3</p>
    i seguenti script generano i risultati indicati:
    codice:
    d3.select('p')
      .html('Pippo');
    
    /* Risultato:
    
    <p>Pippo</p>
    <p>Elemento 2</p>
    <p>Elemento 3</p>
    
    */
    codice:
    d3.select('p')
      .html(function(){return 'Pippo'});
    
    /* Risultato:
    
    <p>Pippo</p>
    <p>Elemento 2</p>
    <p>Elemento 3</p>
    
    */
    codice:
    d3.selectAll('p')
      .html('Pippo');
    
    /* Risultato:
    
    <p>Pippo</p>
    <p>Pippo</p>
    <p>Pippo</p>
    
    */
    codice:
    d3.selectAll('p')
      .html(function(){return 'Pippo'});
    
    /* Risultato:
    
    <p>Pippo</p>
    <p>Pippo</p>
    <p>Pippo</p>
    
    */

    codice:
    d3.selectAll('p')
      .data(['Pippo', 'Pluto', 'Topolino'])
      .html(function(dato, indice, gruppo){
        return indice + ') ' + dato;
      });
    
    /* Risultato:
    
    <p>0) Pippo</p>
    <p>1) Pluto</p>
    <p>2) Topolino</p>
    
    */
    codice:
    d3.selectAll('p')
      .data(['Pippo', 'Pluto'])
      .html(function(dato, indice, gruppo){
        return indice + ') ' + dato;
      });
    
    /* Risultato:
    
    <p>0) Pippo</p>
    <p>1) Pluto</p>
    <p>Elemento 3</p>
    
    */
    ...

    Spero di aver chiarito qualche dubbio. Fai sapere.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2021
    Messaggi
    12
    Allora... intanto ringrazio per la pazienza e per il supporto puntuale, preciso e super dettagliato.

    Studierò per bene il metodo perchè all'esame ovviamente devo dare conto di quanto ho inserito nel codice.
    Riferendomi anche ai suggerimenti ricevuti QUI mi sa che resto sul codice precedente non responsive perchè le novità inserite e i concetti sono troppi e ho paura di non saperli padroneggiare al meglio.

    A tale proposito faccio ancora una domanda, stavolta di javascript, e perciò inserisco la inserisco in quësto thread:

    Come si vede nel codice che ho postato nel primo post del thread, nella parte finale dove ho inserito il codice:

    codice:
    /*divisione di ogni dato array in 3 parti ProgrammaNome, ProgrammaUrl e datoClasse */
    d3.csv("Palinsesto.csv", function (datiCaricati) {
        console.log(datiCaricati);
        var d = datiCaricati;
        d3.select("tbody")
            .append("tr")
            .selectAll("td")
            .data([d.dalle, d.alle, d.LUNEDI, d.dalle, d.alle, d.MARTEDI, d.dalle, d.alle, d.MERCOLEDI, 
                   d.dalle, d.alle, d.GIOVEDI, d.dalle, d.alle, d.VENERDI, d.dalle, d.alle, d.SABATO, 
                   d.dalle, d.alle, d.DOMENICA])
            .enter()
            .append("td")
            .attr("class",function(d){
                const [Pippo, Pluto, Topolino] = d.split("|");    
                return Topolino;
                })
            .html(function (cella) {
                    const [ProgrammaNome, ProgrammaUrl, classeCella] = cella.split("|");
                    /* se la cella ha il valore dell'url, inserisco un link */
                    if (ProgrammaUrl) {
                       return "<a href='" + ProgrammaUrl + "' target='blank' \">" + ProgrammaNome + "</a>"
                    }
                    /* altrimenti mostro un testo normale */
                    /*Se non ci fosse le colonne "dalle" e "alle" non verrebbero visualizzate */
                    else {
                        return ProgrammaNome
                    }
                  }
                 )

    ho usato due volte lo split per ricavare, la prima volta la classe da attribuire ad ogni singolo <td>
    codice:
    .append("td")
            .attr("class",function(d){
                const [Pippo, Pluto, Topolino] = d.split("|");    
                return Topolino;
                })

    e poi quando dovevo costruire il link nel <td> assegnando alle variabili ProgrammaNome e ProgrammaUrl rispettivamente il primo spezzone di testo ricavato dal file .csv e il secondo (il terzo è coem visto sopra inerente la classe CSS da assegnare al <td>)

    codice:
    .html(function (cella) {
                    const [ProgrammaNome, ProgrammaUrl, classeCella] = cella.split("|");
                    /* se la cella ha il valore dell'url, inserisco un link */
                    if (ProgrammaUrl) {
                       return "<a href='" + ProgrammaUrl + "' target='blank' \">" + ProgrammaNome + "</a>"
                    }
                    /* altrimenti mostro un testo normale */
                    /*Se non ci fosse le colonne "dalle" e "alle" non verrebbero visualizzate */
                    else {
                        return ProgrammaNome
                    }
                  }
                 )

    Orbene: la mia domanda è: posso inserire più sopra lo split in modo da ricavare ProgrammaNome, ProgrammaUrl e classeCella (Topolino nel primo split) in modo da usarli successivamente nell'assegnazione della classe CSS al <td> prima e poi nela costruzione del link ivi contenuto?
    In altre parole... i due split fanno la stessa cosa; posso farne uno solo?

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,682
    intanto ringrazio
    Prego

    la mia domanda è: posso inserire più sopra lo split in modo da ricavare ProgrammaNome, ProgrammaUrl e classeCella (Topolino nel primo split) in modo da usarli successivamente nell'assegnazione della classe CSS al <td> prima e poi nela costruzione del link ivi contenuto?
    In altre parole... i due split fanno la stessa cosa; posso farne uno solo?
    Sì, puoi fare un unico split ma dovresti cercare di capire meglio come poter impostare il tutto.

    Ti spiego...

    Si può comunque intervenire in svariati modi ma, se vuoi sfruttare i metodi forniti dalla libreria D3 in questione, devi tenere conto delle caratteristiche di funzionamento di tali metodi.

    Considera che sia il metodo attr() sia il metodo html() di D3 (e, in linea di massima, tutti gli altri metodi, di tale libreria, per la manipolazione degli elementi DOM) sono applicabili ad una "selezione D3". Se per questi metodi viene impostata una funzione di callback (esattamente come nel tuo script), questa funzione viene valutata per ciascun elemento DOM della relativa selezione.

    Considera inoltre che associando, alla selezione, un array di dati (ad es. col metodo data(), come nel tuo caso), ogni singolo dato viene passato alla funzione di callback in ordine di corrispondenza con gli elementi della selezione stessa. In altre parole, per ogni elemento della selezione viene valutata la funzione di callback a cui viene passato (come primo argomento) il corrispondente dato prelevato dall'array di dati associati.

    Quando chiedi "posso inserire più sopra lo split... ?", bisognerebbe capire cosa intendi per "più sopra". Se vuoi eseguire lo split fuori da quelle funzioni di callback (quelle definite per attr() e html()) , non puoi ottenere il dato relativo alla specifica cella, perché questo lo ottieni passando proprio attraverso a tali funzioni, le quali vengono eseguite per ogni cella.

    Detto questo, un modo semplice per recuperare il dato corrispondente ad un elemento della selezione è quello di leggerlo, appunto, attraverso l'argomento della relativa funzione di callback che può essere definita per i metodi in questione; cioè, il dato è più semplice leggerlo quando si è all'interno di una di quelle funzioni.

    Per semplificare i passaggi ed eliminare quindi uno split, potresti integrare, all'interno di uno di quei metodi, l'azione dell'altro metodo.

    Ad esempio, potresti rimuovere il metodo attr() che assegna la classe, e usare uno script che faccia comunque la stessa azione, scrivendolo però all'interno della funzione usata per il metodo html(). In questo modo avresti una sola funzione di callback dove ci sarà un unico split attraverso il quale potrai eseguire le varie azioni.

    Qui un esempio:
    codice:
    d3.csv("Palinsesto.csv", function (datiCaricati) {
        var d = datiCaricati;
        
        d3.select("tbody")
            .append("tr")
            .selectAll("td")
            .data([d.dalle, d.alle, d.LUNEDI, d.dalle, d.alle, d.MARTEDI, d.dalle, d.alle, d.MERCOLEDI, 
                   d.dalle, d.alle, d.GIOVEDI, d.dalle, d.alle, d.VENERDI, d.dalle, d.alle, d.SABATO, 
                   d.dalle, d.alle, d.DOMENICA])
            .enter()
            .append("td")
            .html(function(dato){
                const [ProgrammaNome, ProgrammaUrl, classeCella] = dato.split("|");
                
                // Aggiungo la classe (usando i metodi D3)
                if (classeCella) d3.select(this).classed(classeCella, true);
                // oppure con vanilla JavaScript ES6
                //if (classeCella) this.classList.add(classeCella);
                
                /* se la cella ha il valore dell'url, inserisco un link */
                if (ProgrammaUrl) {
                   return "<a href='" + ProgrammaUrl + "' target='blank' \">" + ProgrammaNome + "</a>"
                }
                /* altrimenti mostro un testo normale */
                /*Se non ci fosse le colonne "dalle" e "alle" non verrebbero visualizzate */
                else {
                    return ProgrammaNome
                }
            });
    });
    Da notare l'uso del this che fa riferimento all'elemento (td) corrente a cui vado ad applicare la classe. All'interno del callback di questi metodi infatti il contesto (cioè il valore di this) è riferito all'elemento corrente per il quale viene valutata la funzione.

    Questa può essere una soluzione ma, ripeto, si può fare in tanti altri modi. Suppongo comunque che la cosa più importante per te, sia comprendere al meglio i meccanismi di funzionamento, sia quelli specifici per la libreria D3 usata per il tuo elaborato, sia quelli relativi a JavaScript in modo più generale... poi tutto il resto viene di conseguenza.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2021
    Messaggi
    12
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio

    codice:
            .append("td")
            .html(function(dato){
                const [ProgrammaNome, ProgrammaUrl, classeCella] = dato.split("|");
                
                // Aggiungo la classe (usando i metodi D3)
                if (classeCella) d3.select(this).classed(classeCella, true);
                // oppure con vanilla JavaScript ES6
                //if (classeCella) this.classList.add(classeCella);
    Da notare l'uso del this che fa riferimento all'elemento (td) corrente a cui vado ad applicare la classe. All'interno del callback di questi metodi infatti il contesto (cioè il valore di this) è riferito all'elemento corrente per il quale viene valutata la funzione.
    Intanto grazie per la pazienza... :-D
    Quindi quella condizione if fa riferimento a td e non a html?
    smontando per così dire la condizione, e considerando D3 (e non vanilla per evitare casini...) , come dovrei leggerla?

    d3.select(this) come hai detto tu selezione il <td> ma non conosco il metodo .classed()...

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,682
    Quindi quella condizione if fa riferimento a td e non a html?
    No, la condizione if serve solo a verificare se la variabile (o meglio, la costante) classeCella risulta popolata, così come hai fatto per la condizione successiva, if(ProgrammaUrl). Quello che fa riferimento al td è proprio la parola chiave this.

    smontando per così dire la condizione, e considerando D3 (e non vanilla per evitare casini...) , come dovrei leggerla?
    Nota che nella condizione ho omesso le parentesi graffe perché è possibile farlo quando lo statement della condizione è costituito solo da una riga di codice.

    Quella stessa condizione può essere scritta così:
    codice:
    if (classeCella){
        d3.select(this).classed(classeCella, true);
    }
    non conosco il metodo .classed()
    Il metodo classed() aggiunge o rimuove le classi CSS.
    Basterebbe consultare la documentazione, vedi qui.

    Ad ogni modo, lo stesso risultato puoi ottenerlo col metodo attr() che forse ti è più familiare.

    Puoi quindi scrivere la condizione in questo modo:
    codice:
    if (classeCella){
        d3.select(this).attr("class", classeCella);
    }
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.