Inserting hyperlinks into node labels in DiagrammeR - r

I would like to be able to create flowcharts with DiagrammeR in R so that I can export SVG through the devtools::install_github('rich-iannone/DiagrammeRsvg') package.
My flowcharts must include hyperlinks in some of the nodes, unfortunately I can't find an acceptable way to create node labels with functioning <a> tags. Here are the different methods I've tried:
Mermaid
Using DiagrammeR(diagram = "", type = "mermaid") it's possible to use HTML tags in the node labels:
library("DiagrammeR")
DiagrammeR("graph TB;
A{Is your data public?} -- yes -->C;
A -- no -->B[<center><b>Oxshef: dataviz</b> only supports researchers <br> in the creation of interactive data visualisations that public</center>];
C{<center>Please make it public?</center>};
D[<center>Supported!</center>];
E[<center>Unsupported!</center>];
F[Refer to our tutorial];
C -- yes -->D;
C -- no -->E;
C -- I don't know -->F")
But to use the <a> tag we need to use an = which the parser vomits over:
DiagrammeR("graph TB;
A{Is your data public?} -- yes -->C;
A -- no -->B[<center><b>Oxshef: dataviz</b> only supports researchers <br> in the creation of interactive data visualisations that public</center>];
C{<center>Please make it public?</center>};
D[<center>Supported!</center>];
E[<center>Unsupported!</center>];
F[Refer to our <a href='http://google.com'>tutorial</a>];
C -- yes -->D;
C -- no -->E;
C -- I don't know -->F")
grViz
Here's the same flowchart as above but with all html stripped out and converted to grViz:
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [overlap = true, fontsize = 10]
# several 'node' statements
node [shape = box,
fontname = Helvetica]
A [label = 'Is your data public?']; B [label = 'Please make it public'];
C [label = 'Tech Question']; D [label = 'Supported' ];
E [label = 'Unsupported!']; F [label = 'Refer to our tutorial']
# several 'edge' statements
A->B A->C C->D [label = 'yes'] C->E [label = 'no'] C->F [label = 'Unknown']
}
")
This doesn't support HTML tags:
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [overlap = true, fontsize = 10]
# several 'node' statements
node [shape = box,
fontname = Helvetica]
A [label = 'Is your data public?']; B [label = '<b>Please</b> make it public'];
C [label = 'Tech Question']; D [label = 'Supported' ];
E [label = 'Unsupported!']; F [label = 'Refer to our tutorial']
# several 'edge' statements
A->B A->C C->D [label = 'yes'] C->E [label = 'no'] C->F [label = 'Unknown']
}
")
create_graph
DiagrammeR also lets us create graph as follows:
ndf_no_tags <- create_node_df(n = 6,
label = c("Is your data public?",
"Please make it public",
"Tech Question",
"Supported",
"Unsupported",
"Refer to our tutorial"))
# Create an edge data frame (edf)
edf <- create_edge_df(from = c(1, 1, 3, 3, 3),
to = c(2, 3, 4, 5, 6))
ndf_no_tags %>%
create_graph(edges_df = edf) %>%
render_graph()
But it escapes HTML tags:
ndf_with_tags <- create_node_df(n = 6,
label = c("Is your data public?",
"<b>Please</b> make it public",
"Tech Question",
"Supported",
"Unsupported",
"Refer to our tutorial"))
ndf_with_tags %>%
create_graph(edges_df = edf) %>%
render_graph()

I figured it out for the mermaid function:
mermaid('
graph LR
A-->B
A-->C
C-->E
B-->D
C-->D
D-->F
E-->F
click B "http://www.github.com" "This is a link"
')
the click B <link> option requires double quotes, and thankfully R accepts single quotes for the entire mermaid code block.

Related

Changing layout DiagrammeR

I'm trying to make a SEM graph using R and DiagrammeR. I have the graph set up but I'm trying to have some of the nodes (CSEW, ONS and Police) at the bottom of the graph to make it easier to read.
Here is what I have so far. Any recommendations in how to move the three circles to the bottom would be welcomed.
library(DiagrammeR)
grViz("
digraph MTMM {
subgraph {
node [shape = box, fixedsize = true, width = 1]
rank = same; bike_c; bike_p; bike_o
burg_c; burg_p; burg_o
theft_c; theft_p; theft_o
viol_c; viol_p; viol_o
}
subgraph {
node [shape = circle, fixedsize = true, width = 1]
Bicycle; Burglary; Theft; Violence
}
subgraph {
node [shape = circle, fixedsize = true, width = 1]
CSEW; ONS; Police
}
Bicycle -> {bike_c bike_p bike_o}
Burglary -> {burg_c burg_p burg_o}
Theft -> {theft_c theft_p theft_o}
Violence -> {viol_c viol_p viol_o}
CSEW -> {bike_c burg_c theft_c viol_c} [label = '1']
ONS -> {bike_o burg_o theft_o viol_o} [label = '1']
Police -> {bike_p burg_p theft_p viol_p} [label = '1']
{rank = same; CSEW; ONS; Police}
{rank = same; Bicycle; Burglary; Theft; Violence}
}
")
If you want have node A above node B, you must point from A -> B, this is graphviz' fundamental logic. If you want the arrow point in the other direction, you do so by telling graphviz: A -> B[ dir = back].
In your case, replace the three lines concerned with
{bike_c burg_c theft_c viol_c} -> CSEW [dir = back, label = '1']
{bike_o burg_o theft_o viol_o} -> ONS[dir = back, label = '1']
{bike_p burg_p theft_p viol_p} -> Police[dir = back, label = '1']
which gives you

using diagrammeR, how can I make a node fillcolor dependent on a condition?

Firstly... I could be approaching this task incorrectly. I am new to diagrammeR functionality, and if what I am understanding about diagrammeR is fallacious, from a programming perspective, I would not be surprised.
The issue arises in the 'node [fillcolor = COLOR]' statement of the code.
If I simply write 'fillcolor = Green, style = filled' instead of fillcolor = object1, then it works perfectly. Similarly, if I replace Green with 'Crimson', or any other color, no problems.
My issue is that I want this color to change, depending on the value of an object that is determined by a condition. Basically, if too few sick people are going to see a doctor, this should raise a red flag on a report I'm creating on a daily basis, and programming this manually every day would be a bit of a pain.
What I have tried:
instead of specifying a color, I am trying to use the output of a conditional object as the fillcolor (e.g. what I have tried below)
fillcolor = object1 - fills the final box with black fillcolor =
', object1 ' - final box is black-filled again fillcolor =
object1[1] - outputs results in an error fillcolor = ',
object1[1] ' - final box is black-filled again
# Just create some random data for a flow chart
a = 100 # Total people
b = 60 # Number of total that are sick
c = 19 # Number of sick that saw a doctor
d = round(c/b * 100) # percent of sick who saw a doctor
# create a flowchart-list-object
flow <- list(a=a, b=b, c=c, d=d)
# this could be where I am going wrong
# Condition that determines if the Percentage of sick people who saw a doctor
# is above 40%
if (d > 40) {
object1 <- 'Green'
} else
object1 <- 'Crimson'
# Output the flowchart using grViz
DiagrammeR::grViz("
digraph dot {
graph[layout = dot, fontsize = 15]
# Node numbers with labelled text
node [shape = box,
width = 3,
fontname = Helvetica]
a [label = '##1']
b [label = '##2']
c [label = '##3']
# First set of node to edge connections
a -> b -> c
node [fillcolor = object1, style = filled]
d [label = '##4']
c -> d
}
[1]: paste0('Total Sick \\n ', flow$a, '')
[2]: paste0('Number of total sick \\n ', flow$b, '')
[3]: paste0('Number of Sick who see a doctor \\n ', flow$c, '')
[4]: paste0('% of sick who see a doctor \\n ', flow$d, '')
")
I would expect the final box in the flowchart to be green if the percentage of those sick is above 40% or crimson(red) if it is below 40%.
Thanks for all/any help!
You must define the color as a footnote, just like the nodes' labels. This is because object1 is an R variable, not an actual value. I have defined it at the end as footnote [5]:.
DiagrammeR::grViz("
digraph dot {
graph[layout = dot, fontsize = 15]
# Node numbers with labelled text
node [shape = box,
width = 3,
fontname = Helvetica]
a [label = '##1']
b [label = '##2']
c [label = '##3']
# First set of node to edge connections
a -> b -> c
d [style = filled, fillcolor = '##5', label = '##4']
c -> d
}
[1]: paste0('Total Sick \\n ', flow$a, '')
[2]: paste0('Number of total sick \\n ', flow$b, '')
[3]: paste0('Number of Sick who see a doctor \\n ', flow$c, '')
[4]: paste0('% of sick who see a doctor \\n ', flow$d, '')
[5]: object1
")

DiagrammeR fontsize argument does nothing

I can change the fontsize argument below to be either graph [fontsize = 1] or graph [fontsize = 10] or graph [fontsize = 100] and the output in my R Studio viewer is identical. It appears the font defaults to a reasonable size that fills the node it occupies. How do I change the font size?
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'FooBar']
B [label = 'BarFoo']
A -> B
}
")
You change the font size of the node labels within the node declaration.
You can change it using node: node [shape = box, fontsize=5] or in a specific node label with: A [label = 'FooBar', fontsize=5]

Incorrect Lithuanian symbols in a GraphViz graph (via DiagrammeR, R)

I use GrapViz graphs through R package DiagrammeR and RStudio. In my graphs international symbols like Ąą Čč Ęę Ėė Įį Šš Ųų Ūū Žž which are either in "Latin-4" ("ISO-8859-4") or in "Latin-6" ("ISO-8859-10") chart sets are not displayed correctly. I am aware of parameter charset [link], but it does not seem working with ("Latin-4" or "Latin-6").
Is there a way to use the listed symbols in GraphViz? I wonder if there is a possibility to indicate encoding in some other way?
digraph Latin6 {
graph [label = "Latin 6";
charset = "ISO-8859-10"]
A [label = "<A> Ąą"]
C [label = "<C> Čč"]
E [label = "<E> Ęę"]
E2 [label = "<E2> Ėė"]
I [label = "<I> Įį"]
S [label = "<S> Šš"]
U [label = "<U> Ųų"]
U2 [label = "<U2> Ūū"]
Zz [label = "<Zz> Žž"]
A -> C;
C -> E;
E -> E2;
E2 -> I;
S -> U;
U -> U2;
U2 -> Zz
}
I know that HTML symbols like #261; from UTF-8 Latin Extended A table may be used. If this conversion from international to HTML symbols is the only option, I would like to know if there is a function in R dedicated for direct (International symbol to HTML code) and backward (vice versa) conversion?

Justify node text in DiagrammeR

Does anybody know if DiagrammeR currently supports left- and right-justification of node labels when using GraphViz?
Here is a quick example, where I would like to left-justify the text within both of the nodes:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\nBar']
B [label = 'Bar\nFoo']
A -> B
}
")
I was able to find one resource here for the native GraphViz that uses /l for left-justification, but when I try that within the grViz function I receive an error. For example:
library(DiagrammeR)
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\lBar']
B [label = 'Bar\lFoo']
A -> B
}
")
I appreciate any help in advance!
You need a double backslash to escape the first slash. Here are left and right justified labels:
grViz("
digraph test {
graph [fontsize = 10]
node [shape = box]
A [label = 'Foo\\lBar\\l']
B [label = 'Bar\\rFoo\\r']
A -> B
}
")

Resources