Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 59dbb88
Showing
19 changed files
with
754 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Package: DiagrammeRsvg | ||
Type: Package | ||
Title: Export DiagrammeR Graphviz Graphs as SVG | ||
Version: 0.1 | ||
Date: 2016-02-02 | ||
Authors@R: person( | ||
"Richard", "Iannone" | ||
, role = c("aut", "cre") | ||
, email = "riannone@me.com" | ||
) | ||
Maintainer: Richard Iannone <riannone@me.com> | ||
Description: Allows for export of DiagrammeR Graphviz objects to SVG. | ||
License: MIT + file LICENSE | ||
Imports: V8 (>= 0.10) | ||
URL: https://github.com/rich-iannone/DiagrammeRsvg | ||
BugReports: https://github.com/rich-iannone/DiagrammeRsvg/issues | ||
RoxygenNote: 5.0.1 | ||
NeedsCompilation: no | ||
Packaged: 2016-02-03 22:57:22 UTC; riannone | ||
Author: Richard Iannone [aut, cre] | ||
Repository: CRAN | ||
Date/Publication: 2016-02-04 11:27:31 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
YEAR: 2016 | ||
COPYRIGHT HOLDER: Richard Iannone |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
b57b0037679924de303e78bfeef0a5a7 *DESCRIPTION | ||
5bc3b4b14b49ebcc410d51288b2df7bc *LICENSE | ||
7043dc5cc00de15b212e100d1debabf1 *NAMESPACE | ||
767abd58bb19f11af3592513b7d0f77b *R/export_svg.R | ||
ba8971116d0fa84a1c73a7f61082a273 *README.md | ||
fdfe1e83b79eec205a4843cabcb0a971 *inst/htmlwidgets/DiagrammeR.js | ||
49b47a8ee6d9356eadd28546e5385573 *inst/htmlwidgets/DiagrammeR.yaml | ||
c93c404ae98abcb660c70a31f58e25e2 *inst/htmlwidgets/grViz.js | ||
db70d925759cdf5fbda9ecf69cc9f371 *inst/htmlwidgets/grViz.yaml | ||
5e44e63b7491ec4b18f73d1b38334a04 *inst/htmlwidgets/lib/d3/LICENSE | ||
c9ddc1063ecffea499c39c74f96bccc0 *inst/htmlwidgets/lib/d3/d3.min.js | ||
04d7548521ef50aea6ddc72a7f1981f6 *inst/htmlwidgets/lib/dagre-d3/LICENSE | ||
0fac740c944fa84c3646d8d60882c17c *inst/htmlwidgets/lib/dagre-d3/dagre-d3.min.js | ||
4c6828671350452fdcb46bf28af7f42a *inst/htmlwidgets/lib/styles/styles.css | ||
0597ece6806477c1382a570bf20e40a8 *inst/htmlwidgets/lib/viz/viz.js | ||
4730f144eb0807d31fdeea3e4517d280 *inst/htmlwidgets/vivagraph.js | ||
c38b9b43fa32fd10d0295d8441d905c2 *inst/htmlwidgets/vivagraph.yaml | ||
d44b1090da7705eec8314b6cf8fc48bc *man/export_svg.Rd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Generated by roxygen2: do not edit by hand | ||
|
||
export(export_svg) | ||
importFrom(V8,new_context) | ||
importFrom(utils,packageVersion) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#' Export grViz graph as SVG with \code{V8} | ||
#' @description Use viz.js with \code{V8} to get the diagram rendered as SVG | ||
#' in R instead of the browser. | ||
#' @param gv htmlwidget to render as SVG. | ||
#' @return \code{string} of SVG XML text. | ||
#' @examples | ||
#' \dontrun{ | ||
#' library(DiagrammeR) | ||
#' svg <- export_svg(grViz('digraph{a->b; c->a; c->b; c->d;}')) | ||
#' | ||
#' # this can then be used with htmltools and can save significantly | ||
#' # on size of output using svg rather than unrendered grViz | ||
#' library(htmltools) | ||
#' html_print(HTML(svg)) | ||
#' } | ||
#' @importFrom V8 new_context | ||
#' @importFrom utils packageVersion | ||
#' @export export_svg | ||
|
||
export_svg <- function(gv){ | ||
|
||
# Check to make sure that V8 is available | ||
if(!requireNamespace("V8")) stop("V8 is required to export.", | ||
call. = FALSE) | ||
|
||
# Ensure that the minimum version of V8 is 1.0 | ||
stopifnot(packageVersion("V8") >= "0.10") | ||
|
||
# Check to make sure gv is grViz | ||
if(!inherits(gv, "grViz")) "gv must be a grViz htmlwidget." | ||
|
||
# Create a new V8 context | ||
ct <- new_context("window") | ||
|
||
# Source the `vis.js` JS library | ||
invisible(ct$source(system.file("htmlwidgets/lib/viz/viz.js", | ||
package = "DiagrammeR"))) | ||
|
||
# Create the SVG file | ||
svg <- | ||
ct$call("Viz", | ||
gv$x$diagram, | ||
"svg", | ||
gv$x$config$engine, | ||
gv$x$config$options) | ||
|
||
return(svg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# DiagrammeRsvg | ||
|
||
A utility package for providing **SVG** export to **DiagrammeR** graph diagrams. | ||
|
||
To install the package, use this statement: | ||
|
||
```R | ||
devtools::install_github('rich-iannone/DiagrammeRsvg') | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
HTMLWidgets.widget({ | ||
|
||
name: 'DiagrammeR', | ||
|
||
type: 'output', | ||
|
||
initialize: function(el, width, height) { | ||
|
||
/* wait to initialize until renderValue | ||
since x not provided until then | ||
and mermaid will try to build the diagram | ||
as soon as class of the div is set to "mermaid" | ||
*/ | ||
|
||
/* to prevent auto init() by mermaid | ||
not documented but | ||
see lines https://github.com/knsv/mermaid/blob/master/src/main.js#L100-L109 | ||
mermaid_config in global with mermaid_config.startOnLoad = false | ||
appears to turn off the auto init behavior | ||
allowing us to callback after manually init and then callback | ||
after complete | ||
*/ | ||
window.mermaid.startOnLoad = false; | ||
|
||
// set config options for Gantt | ||
// undocumented but these can be provided | ||
// so from R | ||
// m1 <- mermaid(spec) | ||
// m1$x$config = list(ganttConfig = list( barHeight = 100 ) ) | ||
mermaid.ganttConfig = { | ||
titleTopMargin:25, | ||
barHeight:20, | ||
barGap:4, | ||
topPadding:50, | ||
sidePadding:100, | ||
gridLineStartPadding:35, | ||
fontSize:11, | ||
numberSectionStyles:4, | ||
axisFormatter: [ | ||
// Within a day | ||
["%I:%M", function (d) { | ||
return d.getHours(); | ||
}], | ||
// Monday a week | ||
["w. %U", function (d) { | ||
return d.getDay() == 1; | ||
}], | ||
// Day within a week (not monday) | ||
["%a %d", function (d) { | ||
return d.getDay() && d.getDate() != 1; | ||
}], | ||
// within a month | ||
["%b %d", function (d) { | ||
return d.getDate() != 1; | ||
}], | ||
// Month | ||
["%m-%y", function (d) { | ||
return d.getMonth(); | ||
}] | ||
] | ||
}; | ||
|
||
return { | ||
// TODO: add instance fields as required | ||
} | ||
|
||
}, | ||
|
||
renderValue: function(el, x, instance) { | ||
|
||
// if no diagram provided then assume | ||
// that the diagrams are provided through htmltools tags | ||
// and DiagrammeR was just used for dependencies | ||
if ( x.diagram != "" ) { | ||
el.innerHTML = x.diagram; | ||
//if dynamic such as shiny remove data-processed | ||
// so mermaid will reprocess and redraw | ||
el.removeAttribute("data-processed"); | ||
el.classList.add('mermaid'); | ||
//make sure if shiny that we turn display back on | ||
el.style.display = ""; | ||
//again if dynamic such as shiny | ||
// explicitly run mermaid.init() | ||
} else { | ||
// set display to none | ||
// should we remove instead?? | ||
el.style.display = "none"; | ||
} | ||
|
||
// check for undocumented ganttConfig | ||
// to override the defaults manually entered | ||
// in initialize above | ||
// note this is really sloppy and will not | ||
// work well if multiple gantt charts | ||
// with custom configs here | ||
if( typeof x.config !== "undefined" && | ||
typeof x.config.ganttConfig !== "undefined" ){ | ||
Object.keys(x.config.ganttConfig).map(function(k){ | ||
window.mermaid.ganttConfig[k] = x.config.ganttConfig[k]; | ||
}) | ||
} | ||
|
||
|
||
// use this to sort of make our diagram responsive | ||
// or at a minimum fit within the bounds set by htmlwidgets | ||
// for the parent container | ||
function makeResponsive(el){ | ||
var svg = el.getElementsByTagName("svg")[0]; | ||
if(svg){ | ||
if(svg.width) {svg.removeAttribute("width")}; | ||
if(svg.height) {svg.removeAttribute("height")}; | ||
svg.style.width = "100%"; | ||
svg.style.height = "100%"; | ||
} | ||
}; | ||
|
||
|
||
// get all DiagrammeR mermaids widgets | ||
dg = document.getElementsByClassName("DiagrammeR"); | ||
// run mermaid.init | ||
// but use try catch block | ||
// to send error to the htmlwidget for display | ||
try{ | ||
mermaid.init( el ); | ||
|
||
// sort of make our diagram responsive | ||
// should we make this an option? | ||
// if so, then could easily add to list of post process tasks | ||
makeResponsive( el ); | ||
|
||
/* | ||
// change the id of our SVG assigned by mermaid to prevent conflict | ||
// mermaid.init has a counter that will reset to 0 | ||
// and cause duplication of SVG id if multiple | ||
d3.select(el).select("svg") | ||
.attr("id", "mermaidChart-" + el.id); | ||
// now we have to change the styling assigned by mermaid | ||
// to point to our new id that we have assigned | ||
// will add if since sequence diagrams do not have stylesheet | ||
if(d3.select(el).select("svg").select("style")[0][0]){ | ||
d3.select(el).select("svg").select("style")[0][0].innerHTML = d3.select(el).select("svg") | ||
.select("style")[0][0].innerHTML | ||
*/ | ||
/// sep comment for / in regex .replace(/mermaidChart[0-9]*/gi, "mermaidChart-" + el.id); | ||
/*} | ||
*/ | ||
|
||
// set up a container for tasks to perform after completion | ||
// one example would be add callbacks for event handling | ||
// styling | ||
if (!(typeof x.tasks === "undefined") ){ | ||
if ( (typeof x.tasks.length === "undefined") || | ||
(typeof x.tasks === "function" ) ) { | ||
// handle a function not enclosed in array | ||
// should be able to remove once using jsonlite | ||
x.tasks = [x.tasks]; | ||
} | ||
x.tasks.map(function(t){ | ||
// for each tasks add it to the mermaid.tasks with el | ||
t.call(el); | ||
}) | ||
} | ||
|
||
} catch(e) { | ||
// if error look for last processed DiagrammeR | ||
// and send error to the container div | ||
// with pre containing the errors | ||
var processedDg = d3.selectAll(".DiagrammeR[data-processed=true]"); | ||
// select the last | ||
processedDg = d3.select(processedDg[0][processedDg[0].length - 1]) | ||
// remove the svg | ||
processedDg.select("svg").remove(); | ||
|
||
//if dynamic such as shiny remove data-processed | ||
// so mermaid will reprocess and redraw | ||
if (HTMLWidgets.shinyMode) { | ||
el.removeAttribute("data-processed") | ||
} | ||
|
||
processedDg.append("pre").html( ["parse error with " + x.diagram, e.message].join("\n") ) | ||
} | ||
|
||
}, | ||
|
||
resize: function(el, width, height, instance) { | ||
|
||
} | ||
|
||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
dependencies: | ||
- name: d3 | ||
version: 3.3.8 | ||
src: htmlwidgets/lib/d3 | ||
script: d3.min.js | ||
- name: dagre | ||
version: 0.4.0 | ||
src: "htmlwidgets/lib/dagre-d3" | ||
script: "dagre-d3.min.js" | ||
- name: mermaid | ||
version: 0.3.0 | ||
src: htmlwidgets/lib/mermaid | ||
script: dist/mermaid.slim.min.js | ||
stylesheet: dist/mermaid.css | ||
- name: DiagrammeR-styles | ||
version: 0.2 | ||
src: htmlwidgets/lib/styles | ||
stylesheet: styles.css | ||
- name: chromatography | ||
version: 0.1 | ||
src: htmlwidgets/lib/chromatography | ||
script: chromatography.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
HTMLWidgets.widget({ | ||
|
||
name: 'grViz', | ||
|
||
type: 'output', | ||
|
||
initialize: function(el, width, height) { | ||
|
||
return { | ||
// TODO: add instance fields as required | ||
} | ||
|
||
}, | ||
|
||
renderValue: function(el, x, instance) { | ||
// use this to sort of make our diagram responsive | ||
// or at a minimum fit within the bounds set by htmlwidgets | ||
// for the parent container | ||
function makeResponsive(el){ | ||
var svg = el.getElementsByTagName("svg")[0]; | ||
if(svg){ | ||
if(svg.width) {svg.removeAttribute("width")}; | ||
if(svg.height) {svg.removeAttribute("height")}; | ||
svg.style.width = "100%"; | ||
svg.style.height = "100%"; | ||
} | ||
}; | ||
|
||
if ( x.diagram != "" ) { | ||
|
||
if ( typeof x.config === "undefined" ){ | ||
x.config = {}; | ||
x.config.engine = "dot"; | ||
x.config.options = {}; | ||
} | ||
|
||
try { | ||
el.innerHTML = Viz( x.diagram, format="svg", engine=x.config.engine, options=x.config.options ); | ||
|
||
makeResponsive(el); | ||
|
||
// set up a container for tasks to perform after completion | ||
// one example would be add callbacks for event handling | ||
// styling | ||
if (!(typeof x.tasks === "undefined") ){ | ||
if ( (typeof x.tasks.length === "undefined") || | ||
(typeof x.tasks === "function" ) ) { | ||
// handle a function not enclosed in array | ||
// should be able to remove once using jsonlite | ||
x.tasks = [x.tasks]; | ||
} | ||
x.tasks.map(function(t){ | ||
// for each tasks add it to the mermaid.tasks with el | ||
t.call(el); | ||
}) | ||
} | ||
} catch(e){ | ||
var p = document.createElement("pre") | ||
p.innerText = e; | ||
el.appendChild(p); | ||
} | ||
} | ||
|
||
}, | ||
|
||
resize: function(el, width, height, instance) { | ||
|
||
} | ||
|
||
|
||
}); |
Oops, something went wrong.