2

My blogdown sites (including plots, markdown, etc.) typically render fine on both Chrome and Firefox. Incidentally they usually work fine on IE as well, although I don't care as much about that browser. I'll include it in the discussion for completeness.

When I include a Sankey Network in blogdown utilizing the networkD3 R package things render 'properly' in Chrome and IE, but not in Firefox. Firefox artificially shrinks the size of the Sankey Network, see below:

enter image description here

Here's the code I'm using. Is there anything I can do to get the Sankey Network to render properly on Firefox, when using Sankey Networks with blogdown?

I did mess around with {r, fig.width=x, fig.height=y}. Increasing x and y increases the overall image size, while keeping the overall image in the same 'small' blogdown box, effectively decreasing the Sankey Network size even further than shown above. Decreasing x and y just decreases the image size, also making the Sankey Network smaller than shown above. I think I need to fix the rendering issue (present in Firefox, not present in Chrome).

---
title: "Data Analysis"
date: "2019-01-01T18:00:00-09:00"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(blogdown)
library(networkD3)
```

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

```{r sankey, echo=FALSE, error=FALSE, message=FALSE, warning=FALSE}
source <- c("A", "A", "B", "C", "D", "D", "E", "E")
target <- c("D", "E", "E", "D", "H", "I", "I", "H")
values <- c(1, 22, 5, 5, 5, 10, 10, 10)
nodes <- data.frame(name = unique(c(source, target)))
links <- data.frame(source = match(source, nodes$name) - 1,
                    target = match(target, nodes$name) - 1,
                    value = values)
sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
              Target = "target", Value = "value", NodeID = "name", 
              units = "unitX", fontSize = 12, nodeWidth = 20)
```

[EDIT] I've updated my code as shown below, based on this previous SO question. However, it still renders 'small' with no apparent change :(

---
title: "Data Analysis"
date: "2019-01-01T18:00:00-09:00"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(blogdown)
library(networkD3)
```

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

```{r sankey, echo=FALSE, error=FALSE, message=FALSE, warning=FALSE}
source <- c("A", "A", "B", "C", "D", "D", "E", "E")
target <- c("D", "E", "E", "D", "H", "I", "I", "H")
values <- c(1, 22, 5, 5, 5, 10, 10, 10)
nodes <- data.frame(name = unique(c(source, target)))
links <- data.frame(source = match(source, nodes$name) - 1,
                    target = match(target, nodes$name) - 1,
                    value = values)

sn <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
                    Target = "target", Value = "value", NodeID = "name", 
                    units = "unitX", fontSize = 12, nodeWidth = 20)

htmlwidgets::onRender(sn, 'document.getElementsByTagName("svg")[0].setAttribute("viewBox", "")')

# also tried this to no avail
# htmlwidgets::onRender(sn, 'document.getElementById().getElementsByTagName("svg")[0].setAttribute()')            
```
CJ Yetman
  • 8,373
  • 2
  • 24
  • 56
Display name
  • 4,153
  • 5
  • 27
  • 75
  • 1
    does this help https://stackoverflow.com/questions/51145370/tiny-plot-output-from-sankeynetwork-networkd3-in-firefox – CJ Yetman Mar 04 '19 at 17:38
  • @CJ Yetman thanks for the tip, I tried it but it didn't change anything. Can you take a quick look at my new code block (edited the original post with updates) and make sure I applied your suggestion properly? I think I did it right. Also submitted this as a bug per your link to GitHub. – Display name Mar 04 '19 at 18:50
  • 1
    it works for me on macOS 10.14.3, Firefox 65.0.1 – CJ Yetman Mar 05 '19 at 05:57
  • I just updated all my R packages. FF v65.0.2 and still not working. My computer is Win7 Pro and Ubuntu 18.04. Can't imagine it's OS related (but maybe). We tried. Thanks. I'll just advise users to use Chrome. – Display name Mar 05 '19 at 11:51
  • This is happening for me too – Gordon McDonald Apr 02 '20 at 02:34

2 Answers2

4

Based on the discussion in the Github issue, it seems the solution was to set the proper index number of the sankey plot in the htmlwidgets::onRender command.

So if the sankey plot is the first SVG on the page, the command should be:

htmlwidgets::onRender(sn, 'document.getElementsByTagName("svg")[0].setAttribute("viewBox", "")')

If the sankey plot is the second SVG on the page, the command should be:

htmlwidgets::onRender(sn, 'document.getElementsByTagName("svg")[1].setAttribute("viewBox", "")')

and so forth


UPDATE 2020.04.02

My currently preferred method to do this is to use htmlwidgets::onRender to target specifically the SVG contained by the passed htmlwidget, like this...

onRender(sn, 'function(el) { el.querySelector("svg").removeAttribute("viewBox") }')

That can then be done specifically to as many htmlwidgets on your page as necessary, for instance...

onRender(sn, 'function(el) { el.querySelector("svg").removeAttribute("viewBox") }')

onRender(sn2, 'function(el) { el.querySelector("svg").removeAttribute("viewBox") }')
CJ Yetman
  • 8,373
  • 2
  • 24
  • 56
0

Building on CJ Yetman's answer here's a hack that worked for me to get multiple Sankey plots to render correctly in Firefox.

Put this code in your Rmd:

htmlwidgets::onStaticRenderComplete('$.each( document.getElementsByTagName("svg"), function( index, value ){value.setAttribute("viewBox", null);});')

After it has rendered all the sankeys, it will loop though and set all of the viewBox attributes of svg objects to null, so that all the sankeys fill their bounding box.

Gordon McDonald
  • 269
  • 2
  • 12