Place text values to right of sankey diagram

前端 未结 1 678
眼角桃花
眼角桃花 2020-12-19 05:13

Is there a trick to placing text on a sankey diagram rendered using networkD3? I would like to have the values of the endpoints be displayed as text to the right of their b

相关标签:
1条回答
  • 2020-12-19 05:58

    Sorry, I just now ran across this. This would be a great use for the new onRender function in htmlwidgets. I tried to comment inline to explain the couple of lines of added JavaScript to move the node text. networkD3 filters in these lines to change the placement to right or left based on width. We will just apply this to all of the text so it will be to the right of our node rectangles.

    library(networkD3)
    library(data.table)
    set.seed(1999)
    links <- data.table(
      src = rep(0:4, times=c(1,1,2,3,5)),
      target = sample(1:11, 12, TRUE),
      value = sample(100, 12)
    )[src < target, ]  # no loops
    nodes <- data.table(name=LETTERS[1:12])
    
    ## Need to hover to get counts
    sankeyNetwork(Links=links, Nodes=nodes, Source='src', Target='target',
                  Value='value', NodeID='name', fontSize=16)
    
    ## Add text to label
    txt <- links[, .(total = sum(value)), by=c('target')]
    nodes[txt$target+1L, name := paste0(name, ' (', txt$total, ')')]
    
    ## Displays the counts as part of the labels
    sankeyNetwork(Links=links, Nodes=nodes, Source='src', Target='target',
                  Value='value', NodeID='name', fontSize=16, width=600, height=300)
    
    
    
    #################### move leaf node text right ################
    # for this to work
    #   install the newest htmlwidgets
    #   devtools::install_github("ramnathv/htmlwidgets")
    
    library(htmlwidgets)
    #  add margin left since we'll need extra room
    #   if you are wondering why margin left,
    #   I think we just discovered a bug
    sn <- sankeyNetwork(
      Links=links, Nodes=nodes, Source='src', Target='target',
      Value='value', NodeID='name', fontSize=16,
      width=600, height=300,
      # give us so room for our newly aligned labels
      margin = list("left"=100)
    )
    # see how it looks
    sn
    
    # now let's use the new htmlwidget function
    #  onRender
    onRender(
      sn,
    '
    function(el,x){
      // select all our node text
      var node_text = d3.select(el)
        .selectAll(".node text")
        //and make them match
        //https://github.com/christophergandrud/networkD3/blob/master/inst/htmlwidgets/sankeyNetwork.js#L180-L181
        .attr("x", 6 + x.options.nodeWidth)
        .attr("text-anchor", "start");
    }
    '
    )
    
    0 讨论(0)
提交回复
热议问题