0

I'm trying to add y-axis labels to my sankey network. I managed to add x-axis labels using htmlwidgets::onRender. I tried adding some y-axis labels based on this answer. However, my x-axis labels from earlier disappears after adding the y labels. How do I keep the x labels?

code:

library(networkD3)
library(manipulateWidget)
library(htmltools)
library(htmlwidgets)

# prepare data
links <- data.frame(
  source = c("group_A","group_A", "group_B", "group_C", "group_C", "group_E"), 
  target = c("group_C","group_D", "group_E", "group_F", "group_G", "group_H"), 
  value = c(2,3, 2, 3, 1, 3)
)

nodes <- data.frame(
  name = unique(c(as.character(links$source), as.character(links$target)))
)

links$IDsource <- match(links$source, nodes$name) - 1
links$IDtarget <- match(links$target, nodes$name) - 1

# sankey network
sankey = sankeyNetwork(Links = links,
                       Nodes = nodes,
                       Source = "IDsource",
                       Target = "IDtarget",
                       Value = "value",
                       NodeID = "name",
                       fontSize = 20)

# add x-axis labels 
js_string <-
  '
   function(el) {

    var cols_x = this.sankey.nodes()
      .map(d => d.x).filter((v, i, a) => a.indexOf(v) === i)
      .sort(function(a, b){return a - b});

    var labels = ["A", "B", "C" ]

    cols_x.forEach((d, i) => {
      d3.select(el).select("svg")
        .append("text")
        .attr("x", d)
        .attr("y", 12)
        .attr("text-anchor", "start")
        .text(labels[i]);
    })
   }
  '

# original plot
sankey <- onRender(sankey, js_string)
sankey


# try adding y-axis labels
leftTx = tags$div( 
  style="max-width: 30vw; padding-bottom: 15px; height: 100%; display: flex; align-items: center; justify-content: center;", 
  tags$p("This text is on the left side"))
rightTx = tags$p("This text is on the right",
                 style="max-width:30vw")

cS <- combineWidgets(sankey,
                     leftCol = leftTx,
                     rightCol = rightTx)

cS

original diagram

enter image description here

after adding y labels

enter image description here

nightstand
  • 329
  • 2
  • 11

1 Answers1

1

You could add text to the left and the right within the same custom JavaScript you are using...

onRender(sankey, jsCode = '
function(el) {
  var cols_x = this.sankey.nodes()
    .map(d => d.x).filter((v, i, a) => a.indexOf(v) === i)
    .sort(function(a, b){return a - b});

  var labels = ["A", "B", "C" ]

  cols_x.forEach((d, i) => {
    d3.select(el).select("svg")
      .append("text")
      .attr("x", d)
      .attr("y", 12)
      .attr("text-anchor", "start")
      .text(labels[i]);
  })
  
  d3.select(el).select("svg")
      .append("text")
      .attr("x", 0)
      .attr("y", d3.select(el).select("svg").node().clientHeight / 2)
      .attr("text-anchor", "end")
      .text("text on left");
  
  d3.select(el).select("svg")
      .append("text")
      .attr("x", d3.select(el).select("svg").node().clientWidth)
      .attr("y", d3.select(el).select("svg").node().clientHeight / 2)
      .attr("text-anchor", "start")
      .text("text on right");
}
')

enter image description here

CJ Yetman
  • 8,373
  • 2
  • 24
  • 56