使用多个 sankeyNetwork (NetworkD3) 编织降价时控制 Firefox 中的绘图大小

controlling plot size in Firefox when knitting a markdown with multiple sankeyNetwork (NetworkD3)

这是对类似 的跟进。

我有同样的问题,但是当从 R Markdown 编织到 HTML 时。使用@CJYetman 贴心发布的解决方案,我能够为我的 sankey 获得正确的尺寸,但仅限于第一个。

我每次都尝试添加 onRender 并更新方括号中的数字,但我一定是做错了什么。这是完整的 R Markdown 代码(编织到 HTML 时只有第一个图表呈现):

---
title: "test"
author: "CS"
date: "02/08/2018"
output:
  html_document: default
  pdf_document: default
---

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

```{r}
library(htmlwidgets)
library(networkD3)
library(magrittr)

nodes = data.frame("name" = factor(as.character(1:9)),
                   "group" = as.character(c(1,2,2,3,3,4,4,4,4)))

links = as.data.frame(matrix(byrow = T, ncol = 3, c(
  0, 1, 1400,
  0, 2, 18600,
  1, 3, 400,
  1, 4, 1000,
  3, 5, 100,
  3, 6, 40,
  3, 7, 20,
  3, 8, 4
)))
names(links) = c("source","target","value")

links
```

this chart works fine in firefox:
```{r}
sn1 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
                    Target = "target", Value = "value", NodeID = "name", 
                    NodeGroup = "group", fontSize = 12)

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

but this one doesn't display at all when knitted:
```{r}
sn2 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
                    Target = "target", Value = "value", NodeID = "name", 
                    NodeGroup = "group", fontSize = 12, sinksRight = FALSE)

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

and neither does this one:
```{r}
sn3 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
                    Target = "target", Value = "value", NodeID = "name", 
                    NodeGroup = "group", fontSize = 12, sinksRight = FALSE)

htmlwidgets::onRender(sn3, 'document.getElementsByTagName("svg")[2].setAttribute("viewBox", "")')
```

1) 只使用一次htmlwidgets::onRender()函数,否则不太清楚JavaScript什么时候会运行以及什么其他元素在[=34=时会存在或不存在].

2) 在 htmlwidgets::onRender() 函数中(理想情况下 运行 当渲染最后一个 sankeyNetwork 时)从每个渲染的 sankeyNetworks 中移除视图框。

3) 为了使用 htmlwidgets::onRender() 函数 运行 多个 JavaScript 命令,将所有命令包装在一个 (JavaScript) 函数中

---
title: "test"
author: "CS"
date: "02/08/2018"
output:
  html_document: default
pdf_document: default
---

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

```{r}
library(htmlwidgets)
library(networkD3)
library(magrittr)

nodes = data.frame("name" = factor(as.character(1:9)),
                   "group" = as.character(c(1,2,2,3,3,4,4,4,4)))

links = as.data.frame(matrix(byrow = T, ncol = 3, c(
  0, 1, 1400,
  0, 2, 18600,
  1, 3, 400,
  1, 4, 1000,
  3, 5, 100,
  3, 6, 40,
  3, 7, 20,
  3, 8, 4
)))
names(links) = c("source","target","value")

links
```

this chart works fine in firefox:
  ```{r}
sn1 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
                     Target = "target", Value = "value", NodeID = "name",
                     NodeGroup = "group", fontSize = 12)

sn1
```

but this one doesn't display at all when knitted:
```{r}
sn2 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
                    Target = "target", Value = "value", NodeID = "name",
                    NodeGroup = "group", fontSize = 12, sinksRight = FALSE)

sn2
```

and neither does this one:
```{r}
sn3 <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
                    Target = "target", Value = "value", NodeID = "name",
                    NodeGroup = "group", fontSize = 12, sinksRight = FALSE)

htmlwidgets::onRender(sn3, jsCode =
        'function(){
          document.getElementsByTagName("svg")[0].setAttribute("viewBox", "");
          document.getElementsByTagName("svg")[1].setAttribute("viewBox", "");
          document.getElementsByTagName("svg")[2].setAttribute("viewBox", "");
        }')
```

更新 2020.04.02

我目前首选的方法是使用 htmlwidgets::onRender 专门针对传递的 htmlwidget 包含的 SVG,就像这样...

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

然后可以根据需要专门针对您页面上的尽可能多的 htmlwidgets 执行此操作,例如...

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

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