【问题标题】:How to preview mermaid graph in RStudio viewer?如何在 RStudio 查看器中预览美人鱼图?
【发布时间】:2022-12-22 07:33:24
【问题描述】:
背景:
可以“使用具有 .mmd 文件扩展名的外部文本文件可以在 RStudio 查看器中提供语法着色和预览的优势”(DiagrammeR Docs)
应该是这样的:
问题:
在我的最小工作示例中,图形未在查看器面板中呈现,但打印了 mermaid.mmd 文件中的纯文本(见下文)。如何修复此行为,以便呈现图表?
美人鱼.mmd:
graph LR
A-->B
查看器面板中的输出:
- mermaid.mmd 文件中的文本打印在查看器面板中,而不是呈现的图形中
我的设置
- RStudio 2022.07.2(<- 最新版本)
- R 版本 4.2.1 (2022-06-23 ucrt)
- DiagrammerR 版本 1.0.9(<- 最新版本)
- knitr 版本 1.40(<- 最新版本)
【问题讨论】:
标签:
r-markdown
rstudio
diagrammer
mermaid
【解决方案1】:
问题的技术原因
我发现了问题。它是在 DigrammeR::mermaid() 函数中处理外部 .mmd 文件的实现。
在 mermaid()-function 中,htmlwidgets::createWidget(name = "DiagrammeR", x = x, width = NULL, height = NULL, package = "DiagrammeR")-functions 接受处理过的输入 x 并渲染图形。此函数需要格式为“
图LR
A-->B
",每个输入都以 " 开头和结尾
“并且您的美人鱼代码中的每一行也由”分隔
“。但是来自外部 .mmd 文件 (readLines("mermaid.mmd", encoding = "UTF-8", warn = FALSE)) 的输入看起来像这样:
“图 LR” “A-->B”(每行美人鱼代码的分隔字符串)
将输入转换为所需的格式可以通过mermaid.code <- paste0("
",paste0(mermaid.code, collapse = "
"),"
")完成
不幸的是,DigrammeR::mermaid() 中的外部 .mmd 文件未实现此处理步骤
解决方案
-
构建一个新的 mermaid()-function,包括所需的处理步骤
-
用新函数替换 DiagrammeR 包中的 mermaid()-函数
# Build new mermaid()-function
mermaid.new = function (diagram = "", ..., width = NULL, height = NULL) {
is_connection_or_file <- inherits(diagram[1], "connection") ||
file.exists(diagram[1])
if (is_connection_or_file) {
diagram <- readLines(diagram, encoding = "UTF-8", warn = FALSE)
diagram <- paste0("
",paste0(d, collapse = "
"),"
") # NEW LINE
}
else {
if (length(diagram) > 1) {
nosep <- grep("[;
]", diagram)
if (length(nosep) < length(diagram)) {
diagram[-nosep] <- sapply(diagram[-nosep], function(c) {
paste0(c, ";")
})
}
diagram = paste0(diagram, collapse = "")
}
}
x <- list(diagram = diagram)
htmlwidgets::createWidget(name = "DiagrammeR", x = x, width = width,
height = height, package = "DiagrammeR")
}
#Replace mermaid()-function in DiagrammeR-package
if(!require("R.utils")) install.packages("R.utils")
library(R.utils)
reassignInPackage(name="mermaid", pkgName="DiagrammeR", mermaid.new, keepOld=FALSE)
# Test new function
DiagrammeR::mermaid("mer.mmd")