【问题标题】:controlling plot size in Firefox when knitting a markdown with multiple sankeyNetwork (NetworkD3)使用多个 sankeyNetwork (NetworkD3) 编织降价时在 Firefox 中控制绘图大小
【发布时间】:2018-08-02 15:50:18
【问题描述】:

这是对类似post 的跟进。

我有同样的问题,但是从 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", "")')
```

【问题讨论】:

    标签: r r-markdown sankey-diagram htmlwidgets networkd3


    【解决方案1】:

    1) 仅使用一次htmlwidgets::onRender() 函数,否则将不太清楚 JavaScript 何时运行以及运行时会存在哪些其他元素或不存在哪些其他元素。

    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") }')
    

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2021-10-26
      • 2017-01-29
      相关资源
      最近更新 更多