## Internal funcs for plotting Workflow
# Graphviz plot workflow
# df_wf: data frame, the standard df generated from subsetRmd function
# out_type: choose from 'html', 'svg', 'png'
# out_path: string, path of output plot, only apply from svg or png
# plot_style: one of 'detect', 'none', 'linear'
# default is detect, ignoring level but detecting the the longest branch
# linking first and last step as main branch.
# height: int, height of svg or png in pixels, default NULL, automatic
# width: int, width of svg or png in pixels, default NULL, automatic
# only selected steps will be plotted, make sure at least some steps are
# TRUE in 'selected' column in df_wf
#' #' @importFrom assertthat is.count
#' # @importFrom rsvg rsvg_svg rsvg_png
#' #' @noRd
#' .plotWF <- function(df_wf, plot_style="detect", out_type='html',
#' out_path='default', height=NULL, width=NULL){
#' # pre checks
#' assert_that(out_type %in% c('html', 'png', 'svg', 'shiny'),
#' msg = "output type needs to be one of 'html', 'png', 'svg'")
#' assert_that(plot_style %in% c('detect', 'none', 'linear'),
#' msg="plot style needs to be one of 'detect', 'none', 'linear'")
#' assert_that(is.data.frame(df_wf))
#' all(c("t_lvl", "t_number", "t_text","selected",
#' "no_run", "no_success", "link_to") %in% names(df_wf)) %>%
#' assert_that(msg=glue('One of following columns is missing: "t_lvl"',
#' '"t_number" "t_text" "selected"',
#' '"no_run" "no_success" "link_to"'))
#' if (out_path == 'default' & !out_type %in% c('html', 'shiny')){
#' assert_that(is.writeable(out_path))
#' assert_that(is.count(height) | is.null(height))
#' assert_that(is.count(width) | is.null(width))
#' out_path = switch(out_type,
#' 'svg' = paste0('wfplot',
#' format(Sys.time(), "%Y%m%d%H%M%S"),
#' '.svg'),
#' 'png' = paste0('wfplot',
#' format(Sys.time(), "%Y%m%d%H%M%S"),
#' '.png')
#' )
#' }
#' df_wf <- df_wf[df_wf$selected == TRUE, ]
#' if (nrow(df_wf) == 0) return(cat("no step is selected"))
#'
#' wf <- .make_plot(df_wf, plot_style, is_main_branch=FALSE)
#' wf <- append(wf, .make_plot(df_wf, plot_style, is_main_branch=TRUE),
#' after = length(wf) - 1)
#' # special case for detection style plotting, need to move unneeded
#' # nodes out of main branch
#' if (plot_style == "detect") wf <- .change_branch(df_wf, wf)
#' # collapse entire graph
#' # return(wf)
#' wf <- paste0(wf, collapse = "")
#' # plot
#' plot <- switch(out_type,
#' 'shiny' = DOT::dot(wf, return = "verbatim"),
#' 'html' = DOT::dot(wf)
#' )
#' return(plot)
#' }
# .find_long_branch <- function(t_number, link_to){
# track_back <- function(t_number, link_to, track_list){
# for (each_track_n in seq_len(length(track_list))){
# each_track = track_list[[each_track_n]] %>% unlist()
# previous_t_number <-
# names(link_to_list[
# which(vapply(link_to_list,
# function(x) any(x == t_number[each_track[1]]),
# logical(1))
# )
# ]
# )
# for (each_num in seq_len(length(previous_t_number))) {
# previous_link <- which(t_number == previous_t_number[each_num])
# newtrack = append(previous_link, each_track)
# if (each_num < 2){
# track_list[[each_track_n]] <- newtrack
# } else {
# track_list[[each_track_n + each_num - 1]] <- newtrack
# }
# }
# }
# if (length(previous_t_number) == 0) return(track_list)
# track_list <- track_back(t_number, link_to, track_list)
# return(track_list)
# }
# link_to_list <- str_split(link_to, ",") %>%
# lapply(function(x) str_remove_all(x, " "))
# names(link_to_list) <- t_number
# last_step <- list(length(t_number))
# track_list <- track_back(t_number, link_to, last_step)
# long <- vapply(track_list,
# function(x) all(c(1, length(t_number)) %in% x),
# logical(1)) %>%
# track_list[.] %>%
# vapply(length, FUN.VALUE = 1L) %>%
# which.max() %>% track_list[.] %>%
# unlist()
# return(long)
# }
#
# .make_plot <- function(df_wf, plot_style, is_main_branch=TRUE){
# if (is_main_branch){
# # graph start
# wf <- "subgraph { rank=same;\n"
# df_wf <- switch(plot_style,
# "detect"=df_wf[.find_long_branch(df_wf$t_number, df_wf$link_to), ],
# "none" =df_wf[0,],
# "linear"={
# df_wf$link_to[seq_len(nrow(df_wf) - 1)] <-
# df_wf$t_number[seq_len(nrow(df_wf))[-1]]; df_wf
# }
# )
# } else{
# wf <- switch(plot_style,
# "detect" = "digraph { rankdir=LR;\n",
# "none" = "digraph { rankdir=TB;\n",
# "linear" = "digraph { rankdir=LR;\n")
# df_wf <- switch(plot_style,
# "detect"=df_wf[-.find_long_branch(df_wf$t_number, df_wf$link_to), ],
# "none" =df_wf,
# "linear"=df_wf[0,]
# )
# }
# if (nrow(df_wf) == 0) return(c(wf, "}"))
#
# steps <- df_wf$t_number
# step_text <- str_replace_all(df_wf$t_text, '[\'\"]', "\\\\'")
# link_to <- df_wf$link_to
# # reslove 1 to n links
# link_to <- str_split(link_to, ",") %>%
# lapply(function(x) str_remove_all(x, " "))
# # set up colors
# step_color <- ifelse(
# df_wf$no_run == 0,
# 'gray',
# ifelse(
# is.na(df_wf$no_run) | is.na(df_wf$no_success),
# "black",
# ifelse(df_wf$no_run != df_wf$no_success, 'red', 'green')
# )
# )
# # dot language
# # add steps
# for (t in seq_along(steps)){
# if (!is.na(link_to[t]) & t < length(steps)){
# for (nlink in link_to[t]){
# wf <- append(
# wf,
# paste0(' n', str_replace_all(steps[t], "\\.", "_"), " -> ",
# ' n', str_replace_all(nlink, "\\.", "_"), ";\n")
# )
# }
# }
# }
# # add color, text
# wf <- c(wf, paste0(' n', str_replace_all(steps, "\\.", "_"),
# ' [label=\"',
# steps, step_text, ' ',
# ifelse(
# df_wf$no_run == 0, '',
# paste0(df_wf$no_success, '/', df_wf$no_run)
# ),
# '\"', 'fontcolor=', step_color,
# ' color=white',
# '];\n'))
# # end graph
# wf <- paste0(c(wf, "}"))
# return(wf)
# }
#
# .change_branch <- function(df_wf, wf){
# long <- .find_long_branch(df_wf$t_number, df_wf$link_to)
# plot_start <- wf %>% str_which("digraph")
# sub_start <- wf %>% str_which("subgraph ")
# sub_steps_lines <- wf %>% str_which(" -> [^\\[]") %>% .[. > sub_start]
# sub_number <- wf[sub_steps_lines] %>%
# str_remove_all("[->;\n]") %>% str_remove("^.*[ ]+") %>%
# str_remove("n") %>% str_replace_all("_", "\\.") %>%
# lapply(function(x) df_wf$t_number[df_wf$t_number == x]) %>%
# unlist()
# move_line_num <- sub_steps_lines[!sub_number %in% df_wf$t_number[long]]
# if (length(move_line_num) == 0) return(wf)
# move_lines <- wf[move_line_num]
# wf <- wf %>% .[-move_line_num] %>% append(move_lines, after = plot_start)
# return(wf)
# }
## Function used on this code:
# importFrom(magrittr,"%>%")
# importFrom("assertthat", "assert_that", "is.count")
# importFrom("stringr", "str_replace_all", "str_split",
# "str_remove", "str_which", "str_remove_all")
# importFrom("DOT", "dot")
# importFrom(assertthat,"is.writeable")
# importFrom("rsvg,"rsvg_svg", "rsvg_png")
# #test code
# source("subsetRmd.R")
# df_wf = subsetRmd("YOUR.Rmd")
# df_wf$no_success[3:8] = 1
# df_wf$no_run[3:5] = 10
# df_wf$no_run[6:8] = 1
# df_wf$selected[1:35] = TRUE
# df_wf$link_to = NA
# df_wf$link_to[1:(nrow(df_wf) - 1)] = df_wf$t_number[2:nrow(df_wf)]
# df_wf$link_to[3] = NA
# df_wf$link_to[1] = "1.1, 2"
# df_wf$link_to[4] = "2.1, 3"
# df_wf$link_to[14] = NA
# df_wf = df_wf[1:17,]
# df_wf$link_to[8] = "3, 2.5"
# df_wf$selected = TRUE
# .plotWF(df_wf, plot_style = "linear")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.