D3: Grafici ad albero - Etichette migliorate

    let svg = d3.select("body").append("svg")
            .attr("width",670).attr("height",300)

let margin = { top: 5, right: 135, bottom: 5, left: 50 }
let innerWidth = 670 - margin.left - margin.right
let innerHeight = 300 - margin.top - margin.bottom

let graph = svg.append('g')
               .attr('transform', `translate(${margin.left},${margin.top})`)

d3.json("menu.json").then(data => {
    
    let root = d3.hierarchy(data)
    let treeLayout = d3.tree().size([innerHeight, innerWidth])
    treeLayout(root)
    
    let links = root.links()
    let linkGenerator = d3.linkHorizontal()
                          .x(d => d.y)
                          .y(d => d.x)
                          
    graph.selectAll('path')
         .data(links).join('path')
         .attr('d', linkGenerator)
         .attr("fill", "none")
         .attr("stroke", "Chocolate")
  
    graph.selectAll('text')
         .data(root.descendants()).join('text')
         .text(d => d.data.name)
         .attr('x', d => d.y)
         .attr('y', d => d.x)
         .attr('dy', '0.2em')
         .attr('font-size', d => d.height>0 ? 28-d.depth*4 : 14)
         .attr('text-anchor', d => d.children ? 'middle' : 'start')
         .style("text-shadow", "1px 1px 2px white, -1px -1px 2px white")
})
  

Modificando l’attributo dy degli elementi text è possibile cambiare la posizione sull’asse delle y e far centrare le etichette verticalmente. Lo spostamento verso il basso corrisponde al 20% dell’altezza del font dell’elemento (em).

La dimensione del testo (font-size) si può far ridurre man mano che il livello gerarchico aumenta (28-d.depth*4) se il nodo non è una “foglia” (d.height>0). In caso contrario la dimensione si può impostare a 14 px.

Il punto di ancoraggio dell’etichetta (text-anchor) può essere centrato (middle) se il nodo ha figli (d.children) o impostato a sinistra (start), in caso contrario.

Per migliorare la leggibilità, compromessa dalle sovrapposizioni, è possibile creare un effetto glow impostando due “ombre” (text-shadow) bianche e contrapposte. Volendo, si potrebbero aggiungere altre “ombre” bianche contrapposte in modo perpendicolare alle prime due.


Strutturazione dei file: