├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── convert.R ├── dependencies.R ├── knit.R ├── publish.R ├── reexports.R ├── render.R ├── script.R ├── shiny.R ├── version.R └── zzz.R ├── README.md ├── codecov.yml ├── inst ├── examples │ ├── baranims.js │ └── barchart.js ├── htmlwidgets │ ├── lib │ │ ├── r2d3 │ │ │ └── r2d3-render.js │ │ └── webcomponents │ │ │ └── webcomponents.js │ ├── r2d3.js │ └── r2d3.yaml └── www │ ├── d3-jetpack │ └── d3-jetpack.js │ └── d3 │ ├── 3.5.17 │ ├── LICENSE │ └── d3.min.js │ ├── 4.13.0 │ ├── API.md │ ├── CHANGES.md │ ├── LICENSE │ ├── README.md │ └── d3.min.js │ ├── 5.9.2 │ ├── API.md │ ├── CHANGES.md │ ├── LICENSE │ ├── README.md │ └── d3.min.js │ └── 6.2.0 │ ├── API.md │ ├── CHANGES.md │ ├── LICENSE │ ├── README.md │ └── d3.min.js ├── man ├── as_d3_data.Rd ├── d3-shiny.Rd ├── default_sizing.Rd ├── figures │ ├── bar_chart.png │ ├── baranim-1.gif │ ├── barchart-1.png │ ├── bubbles_thumbnail.png │ ├── cartogram_thumbnail.png │ ├── chord_thumbnail.png │ ├── daily_build.png │ ├── new_script.png │ ├── r2d3-hex.png │ ├── rmarkdown-1.png │ └── rstudio_preview.png ├── html_dependencies_d3.Rd ├── r2d3.Rd ├── reexports.Rd ├── save_d3_html.Rd └── save_d3_png.Rd ├── pkgdown ├── _pkgdown.yml ├── extra.css └── extra.js ├── r2d3.Rproj ├── tests ├── testthat.R └── testthat │ ├── .gitignore │ ├── baranims.js │ ├── barchart.Rmd │ ├── barchart.css │ ├── barchart.js │ ├── barchart │ ├── app.R │ └── tests │ │ ├── shinytest-expected │ │ ├── 001.json │ │ ├── 001.png │ │ ├── 002.json │ │ └── 002.png │ │ └── shinytest.R │ ├── helper.js │ ├── test-examples.R │ ├── test-knit.R │ ├── test-render.R │ ├── test-save.R │ ├── test-shiny.R │ └── utils.R ├── tools ├── README │ ├── bar_chart.png │ ├── baranim-1.gif │ ├── barchart-1.png │ ├── bubbles_thumbnail.png │ ├── cartogram_thumbnail.png │ ├── chord_thumbnail.png │ ├── daily_build.png │ ├── new_script.png │ ├── r2d3-hex.png │ ├── rmarkdown-1.png │ └── rstudio_preview.png ├── code-partial.Rmd ├── gallery-template.Rmd └── gallery.R └── vignettes ├── advanced_rendering.Rmd ├── data_conversion.Rmd ├── dependencies.Rmd ├── development_and_debugging.Rmd ├── gallery.Rmd ├── gallery ├── bubbles │ ├── bubbles.js │ ├── flare.csv │ └── index.Rmd ├── bullets │ ├── bullets.css │ ├── bullets.js │ ├── bullets.json │ ├── d3_bullet.js │ └── index.Rmd ├── calendar │ ├── calendar.js │ ├── dji-latest.csv │ ├── dji.csv │ └── index.Rmd ├── cartogram │ ├── cartogram.css │ ├── cartogram.js │ ├── index.Rmd │ ├── topojson.min.js │ └── us.json ├── chord │ ├── chord.css │ ├── chord.js │ └── index.Rmd ├── circlepacking │ ├── circlepacking.css │ ├── circlepacking.js │ ├── flare.json │ └── index.Rmd ├── dendogram │ ├── dendogram.css │ ├── dendogram.js │ ├── flare.csv │ └── index.Rmd ├── forcegraph │ ├── forcegraph.css │ ├── forcegraph.js │ ├── index.Rmd │ └── miserables.json ├── morley │ ├── box.js │ ├── index.Rmd │ ├── morley.css │ ├── morley.csv │ └── morley.js ├── population │ ├── index.Rmd │ ├── population.css │ ├── population.csv │ └── population.js ├── radialtree │ ├── flare.csv │ ├── index.Rmd │ ├── radialtree.css │ └── radialtree.js ├── stackedbars │ ├── index.Rmd │ ├── stackedbars.css │ └── stackedbars.js ├── streamgraph │ ├── index.Rmd │ └── streamgraph.js ├── sunburst │ ├── flare.json │ ├── index.Rmd │ ├── sunburst.css │ └── sunburst.js ├── treemap │ ├── flare.json │ ├── index.Rmd │ ├── treemap.css │ └── treemap.js └── voronoi │ ├── index.Rmd │ ├── voronoi.css │ └── voronoi.js ├── images ├── attr.PNG ├── bar_chart.png ├── baranim-1.gif ├── browser_debugging_entry.png ├── browser_developer_tools.png ├── bubbles_thumbnail.png ├── bullets_thumbnail.png ├── calendar_thumbnail.png ├── cartogram_thumbnail.png ├── chord_thumbnail.png ├── circlepacking_thumbnail.png ├── console_logging.png ├── d3_book.jpg ├── d3toshiny.gif ├── daily_build.png ├── dendogram_thumbnail.png ├── error_debugging.png ├── export_dialog.png ├── export_menu.png ├── flexdashboard.png ├── forcegraph_thumbnail.png ├── morley_thumbnail.png ├── new_script.png ├── onclick.PNG ├── population_thumbnail.png ├── publish.png ├── r2d3-hex.png ├── radialtree_thumbnail.png ├── rmarkdown-1.png ├── rstudio_preview.png ├── show_in_new_window.png ├── stackedbars_thumbnail.png ├── streamgraph_thumbnail.png ├── sunburst_thumbnail.png ├── treemap_thumbnail.png └── voronoi_thumbnail.png ├── learning_d3.Rmd ├── package_development.Rmd ├── publishing.Rmd ├── shiny.Rmd ├── utils.R └── visualization_options.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.Rprofile$ 4 | LICENSE.md 5 | README.Rmd 6 | ^pkgdown.*$ 7 | ^docs.*$ 8 | ^images.*$ 9 | ^scratch.*$ 10 | ^sandbox.*$ 11 | ^vignettes/development_and_debugging.*$ 12 | ^vignettes/gallery.*$ 13 | ^vignettes/images/.*\.png$ 14 | ^vignettes/images/.*\.gif$ 15 | ^vignettes/introduction.*$ 16 | ^vignettes/publishing.*$ 17 | ^vignettes/shiny.*$ 18 | ^vignettes/tools.*$ 19 | ^testthat/barchart/.*$ 20 | tools/gallery.R 21 | tools/code-partial.Rmd 22 | tools/gallery-template.Rmd 23 | ^\.github$ 24 | ^codecov\.yml$ 25 | ^docs$ 26 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shiny-workflows 2 | # 3 | # NOTE: This Shiny team GHA workflow is overkill for most R packages. 4 | # For most R packages it is better to use https://github.com/r-lib/actions 5 | on: 6 | push: 7 | branches: [main, rc-**] 8 | pull_request: 9 | branches: [main] 10 | schedule: 11 | - cron: '0 4 * * 1' # every monday 12 | 13 | name: Package checks 14 | 15 | jobs: 16 | website: 17 | uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1 18 | routine: 19 | uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1 20 | R-CMD-check: 21 | uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .Rapp.history 3 | .RData 4 | .Ruserdata 5 | .Rproj.user 6 | .DS_Store 7 | sandbox 8 | README.html 9 | scratch 10 | inst/doc 11 | docs 12 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: r2d3 2 | Type: Package 3 | Title: Interface to 'D3' Visualizations 4 | Version: 0.2.5 5 | Authors@R: c( 6 | person("Nick", "Strayer", email = "nick.strayer@rstudio.com", role = c("aut", "cre")), 7 | person("Javier", "Luraschi", email = "jluraschi@gmail.com", role = c("aut")), 8 | person("JJ", "Allaire", role = c("aut")), 9 | person("Mike", "Bostock", role = c("ctb", "cph"), comment = "d3.js library, http://d3js.org"), 10 | person(family = "RStudio", role = c("cph")) 11 | ) 12 | Description: Suite of tools for using 'D3', a library for producing dynamic, interactive data 13 | visualizations. Supports translating objects into 'D3' friendly data structures, rendering 14 | 'D3' scripts, publishing 'D3' visualizations, incorporating 'D3' in R Markdown, creating 15 | interactive 'D3' applications with Shiny, and distributing 'D3' based 'htmlwidgets' in R 16 | packages. 17 | License: BSD_3_clause + file LICENSE 18 | Encoding: UTF-8 19 | Depends: 20 | R (>= 3.1.2) 21 | Imports: 22 | htmlwidgets (>= 1.2), htmltools, jsonlite, rstudioapi 23 | Suggests: 24 | knitr, 25 | rmarkdown, 26 | R6, 27 | shiny, 28 | shinytest, 29 | testthat, 30 | webshot 31 | Roxygen: list(markdown = TRUE) 32 | RoxygenNote: 7.1.2 33 | URL: https://rstudio.github.io/r2d3/, https://github.com/rstudio/r2d3 34 | BugReports: https://github.com/rstudio/r2d3/issues 35 | VignetteBuilder: knitr 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: RStudio, Inc 3 | ORGANIZATION: RStudio, Inc -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The 3-Clause BSD License 2 | ======================== 3 | 4 | Copyright © 2018 RStudio and others. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as_d3_data,default) 4 | export(as_d3_data) 5 | export(d3Output) 6 | export(default_sizing) 7 | export(html_dependencies_d3) 8 | export(r2d3) 9 | export(read_json) 10 | export(renderD3) 11 | export(save_d3_html) 12 | export(save_d3_png) 13 | export(sizingPolicy) 14 | import(htmlwidgets) 15 | import(tools) 16 | importFrom(htmltools,htmlDependency) 17 | importFrom(htmlwidgets,saveWidget) 18 | importFrom(htmlwidgets,sizingPolicy) 19 | importFrom(jsonlite,read_json) 20 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # r2d3 0.2.5 2 | 3 | - Support for D3 v6 (@dkjoluju, #85). 4 | 5 | # r2d3 0.2.4 6 | 7 | - Update D3 v5 from 5.0.0 to 5.9.2 (#54). 8 | 9 | - Avoid width and height from changing when refreshing rendering (#59). 10 | 11 | # r2d3 0.2.3 12 | 13 | - Fix default theme when running under RStudio 1.2 (#50). 14 | 15 | # r2d3 0.2.2 16 | 17 | - Fix examples that require pandoc to support CRAN's solaris environment. 18 | 19 | # r2d3 0.2.1 20 | 21 | - Skip tests that require pandoc to support CRAN's solaris environment. 22 | - Fix diagnostics message for dependencies with incorrect paths. 23 | 24 | # r2d3 0.2.0 25 | 26 | - Translate R objects into D3 friendly data structures 27 | - Render D3 scripts within the RStudio Viewer and R Notebooks 28 | - Publish D3 visualizations to the web 29 | - Incorporate D3 scripts into R Markdown reports, presentations, and dashboards 30 | - Create interacive D3 applications with Shiny 31 | - Distribute D3 based htmlwidgets in R packages -------------------------------------------------------------------------------- /R/convert.R: -------------------------------------------------------------------------------- 1 | #' Convert object to D3 data 2 | #' 3 | #' Generic method to transform R objects into D3 friendly data. 4 | #' 5 | #' @param x data 6 | #' @param ... Additional arguments for generic methods 7 | #' 8 | #' @details The value returned from `as_d3_data()` should be one of: 9 | #' 10 | #' - An R data frame. In this case the `HTMLWidgets.dataframeToD3()` 11 | #' JavaScript function will be called on the client to transform 12 | #' the data into D3 friendly (row-oriented) data; or 13 | #' 14 | #' - A JSON object created using [jsonlite::toJSON]; or 15 | #' 16 | #' - Any other R object which can be coverted to JSON using [jsonlite::toJSON]. 17 | #' 18 | #' @export 19 | as_d3_data <- function(x, ...) { 20 | UseMethod("as_d3_data") 21 | } 22 | 23 | #' @rdname as_d3_data 24 | #' @export 25 | as_d3_data.default <- function(x, ...) { 26 | x 27 | } 28 | -------------------------------------------------------------------------------- /R/dependencies.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' D3 HTML dependencies 4 | #' 5 | #' Create HTML dependencies for D3 and optional extensions 6 | #' 7 | #' @param version Major version of D3 8 | #' @param extensions D3 extensions to include. Currently the only supported 9 | #' extension is "jetpack" (). 10 | #' 11 | #' @details Create list of HTML dependencies for D3. Each version has 12 | #' a distinct root D3 object so it's possible to combine multiple versions 13 | #' of D3 on a single page. For example, D3 v5 is accessed via `d3v5` and 14 | #' D3 v4 is accessed via `d3v4`. Note however that D3 v3 is accessed via 15 | #' simply `d3` (for compabibilty with existing htmlwidgets that use 16 | #' this form). 17 | #' 18 | #' @note This function is exported for use by htmlwidgets. If you are 19 | #' using the `r2d3()` function to include D3 code within a document 20 | #' or application this dependency is included automatically so calling 21 | #' this function is unnecessary. 22 | #' 23 | #' @importFrom htmltools htmlDependency 24 | #' 25 | #' @examples 26 | #' 27 | #' library(r2d3) 28 | #' r2d3( 29 | #' data = c (0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 30 | #' script = system.file("examples/barchart.js", package = "r2d3"), 31 | #' dependencies = "d3-jetpack" 32 | #' ) 33 | #' 34 | #' @export 35 | html_dependencies_d3 <- function(version = c("6", "5", "4", "3"), extensions = NULL) { 36 | 37 | # validate version and determine full version number 38 | version <- match.arg(version) 39 | version_long <- version_complete(version) 40 | 41 | # determine unique name so we can host multiple versions of d3 on a single page 42 | # note that d3 v3 has no suffix so it can be compatible with existing htmlwidgets 43 | # that use d3 44 | name <- "d3" 45 | if (version != "3") 46 | name <- paste0(name, "v", version) 47 | 48 | # base dependency on d3 49 | html_dependencies <- list( 50 | htmlDependency( 51 | name = name, 52 | version = version_long, 53 | src = system.file(file.path("www/d3", version_long), package = "r2d3"), 54 | script = "d3.min.js" 55 | ) 56 | ) 57 | 58 | # validate extensions 59 | if (!is.null(extensions) && length(extensions) > 0) { 60 | # validate valid list of extensions 61 | extensions <- match.arg(extensions, choices = all_extensions(), several.ok = TRUE) 62 | # validate jetpack version requirements 63 | if ("d3-jetpack" %in% extensions && as.integer(version) <= 3) 64 | stop("d3-jetpack requires d3 version 4 or higher") 65 | } 66 | 67 | # apply extensions 68 | append(html_dependencies, lapply(extensions, function(extension) { 69 | switch(extension, 70 | `d3-jetpack` = htmlDependency( 71 | name = "d3-jetpack", 72 | version = "2.0.9", 73 | src = system.file("www/d3-jetpack", package = "r2d3"), 74 | script = "d3-jetpack.js" 75 | ) 76 | ) 77 | })) 78 | } 79 | 80 | all_extensions <- function() { 81 | c("d3-jetpack") 82 | } 83 | -------------------------------------------------------------------------------- /R/knit.R: -------------------------------------------------------------------------------- 1 | knit_d3 <- function (options) { 2 | knit_print <- get("knit_print", envir = asNamespace("knitr")) 3 | engine_output <- get("engine_output", envir = asNamespace("knitr")) 4 | 5 | if (identical(.Platform$GUI, "RStudio") && is.character(options$data)) { 6 | options$data <- get(options$data, envir = globalenv()) 7 | } 8 | 9 | if (is.null(options$d3_version)) { 10 | options$d3_version <- "5" 11 | } 12 | 13 | if (is.null(options$container)) { 14 | options$container <- "svg" 15 | } 16 | 17 | if ("reactive" %in% class(options$data)) { 18 | widget <- renderD3({ 19 | r2d3( 20 | options$data(), 21 | options$code 22 | ) 23 | }) 24 | } else { 25 | widget <- r2d3( 26 | data = options$data, 27 | script = options$code, 28 | options = options$options, 29 | container = options$container, 30 | d3_version = options$d3_version, 31 | dependencies = options$dependencies, 32 | width = options$width, 33 | height = options$height 34 | ) 35 | } 36 | 37 | if (identical(.Platform$GUI, "RStudio")) { 38 | widget 39 | } 40 | else { 41 | widget_output <- knit_print(widget, options = options) 42 | engine_output( 43 | options, out = list( 44 | structure(list(src = options$code), class = 'source'), 45 | widget_output 46 | ) 47 | ) 48 | } 49 | } -------------------------------------------------------------------------------- /R/publish.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Save a D3 visualization as HTML 4 | #' 5 | #' Save a D3 visualization to an HTML file (e.g. for sharing with others). 6 | #' 7 | #' @param d3 D3 visualization to save 8 | #' @param file File to save HTML into 9 | #' @param selfcontained Whether to save the HTML as a single self-contained file 10 | #' (with external resources base64 encoded) or a file with external resources 11 | #' placed in an adjacent directory. 12 | #' @param libdir Directory to copy HTML dependencies into (defaults to 13 | #' filename_files). 14 | #' @param background Text string giving the html background color of the widget. 15 | #' Defaults to white. 16 | #' @param title Text to use as the title of the generated page. 17 | #' @param knitrOptions A list of \pkg{knitr} chunk options. 18 | #' 19 | #' @importFrom htmlwidgets saveWidget 20 | #' 21 | #' @examples 22 | #' library(r2d3) 23 | #' 24 | #' viz <- r2d3( 25 | #' data = c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 26 | #' script = system.file("examples/barchart.js", package = "r2d3") 27 | #' ) 28 | #' 29 | #' save_d3_html( 30 | #' viz, 31 | #' file = tempfile(fileext = ".html"), 32 | #' selfcontained = FALSE 33 | #' ) 34 | #' @details 35 | #' 36 | #' Using \code{selfcontained} set to \code{TRUE} requires \href{https://pandoc.org/}{pandoc} 37 | #' to be installed. 38 | #' 39 | #' @seealso [save_d3_png()] 40 | #' 41 | #' @export 42 | save_d3_html <- function(d3, file, selfcontained = TRUE, libdir = NULL, 43 | background = "white", title = "D3 Visualization", 44 | knitrOptions = list()) { 45 | saveWidget( 46 | widget = d3, 47 | file = file, 48 | selfcontained = selfcontained, 49 | libdir = libdir, 50 | background = background, 51 | title = title, 52 | knitrOptions = knitrOptions 53 | ) 54 | } 55 | 56 | #' Save a D3 visualization as a PNG image 57 | #' 58 | #' Save a D3 visualization to PNG (e.g. for including in another document). 59 | #' 60 | #' @details PNG versions of D3 visualizations are created by displaying them in 61 | #' an offscreen web browser and taking a screenshot of the rendered web page. 62 | #' 63 | #' Using the `save_d3_png()` function requires that you install the 64 | #' \pkg{webshot} package, as well as the phantom.js headless browser (which 65 | #' you can install using the function `webshot::install_phantomjs()`). 66 | #' 67 | #' @inheritParams save_d3_html 68 | #' 69 | #' @param width Image width 70 | #' @param height Image height 71 | #' @param delay Time to wait before taking screenshot, in seconds. Sometimes a 72 | #' longer delay is needed for all assets to display properly. 73 | #' @param zoom A number specifying the zoom factor. A zoom factor of 2 will 74 | #' result in twice as many pixels vertically and horizontally. Note that 75 | #' using 2 is not exactly the same as taking a screenshot on a HiDPI (Retina) 76 | #' device: it is like increasing the zoom to 200 doubling the height and 77 | #' width of the browser window. This differs from using a HiDPI device 78 | #' because some web pages load different, higher-resolution images when they 79 | #' know they will be displayed on a HiDPI device (but using zoom will not 80 | #' report that there is a HiDPI device). 81 | #' 82 | #' @seealso [save_d3_html()] 83 | #' 84 | #' @export 85 | save_d3_png <- function(d3, file, background = "white", width = 992, height = 744, delay = 0.2, zoom = 1) { 86 | tmp_html <- tempfile("save_d3_png", fileext = ".html") 87 | on.exit(unlink(tmp_html)) 88 | save_d3_html(d3, file = tmp_html, background = background) 89 | if (requireNamespace("webshot", quietly = TRUE)) { 90 | webshot::webshot(tmp_html, file, vwidth = width, vheight = height, delay = delay, zoom = zoom) 91 | } else { 92 | stop("The webshot package is required to save D3 visualizations to PNG files.") 93 | } 94 | invisible(file) 95 | } -------------------------------------------------------------------------------- /R/reexports.R: -------------------------------------------------------------------------------- 1 | 2 | #' @importFrom htmlwidgets sizingPolicy 3 | #' @export 4 | htmlwidgets::sizingPolicy 5 | 6 | #' @importFrom jsonlite read_json 7 | #' @export 8 | jsonlite::read_json -------------------------------------------------------------------------------- /R/render.R: -------------------------------------------------------------------------------- 1 | #' D3 visualization 2 | #' 3 | #' Visualize data using a custom D3 visualization script 4 | #' 5 | #' @param data Data to be passed to D3 script. 6 | #' @param script JavaScript file containing the D3 script. 7 | #' @param css CSS file containing styles. The default value "auto" will use any CSS file 8 | #' located alongside the script file with the same stem (e.g. "barplot.css" would be 9 | #' used for "barplot.js") as well as any CSS file with the name "styles.css". 10 | #' @param options Options to be passed to D3 script. 11 | #' @param container The 'HTML' container of the D3 output. 12 | #' @param elementId Use an explicit element ID for the widget (rather than an 13 | #' automatically generated one). Useful if you have other JavaScript that needs to 14 | #' explicitly discover and interact with a specific widget instance. 15 | #' @param d3_version Major D3 version to use, the latest minor version is automatically 16 | #' picked. 17 | #' @param dependencies Additional HTML dependencies. These can take the form of paths to 18 | #' JavaScript or CSS files, or alternatively can be fully specified dependencies created 19 | #' with [htmltools::htmlDependency]. 20 | #' @param width Desired width for output widget. 21 | #' @param height Desired height for output widget. 22 | #' @param sizing Widget sizing policy (see [htmlwidgets::sizingPolicy]). 23 | #' @param viewer "internal" to use the RStudio internal viewer pane for output; "external" 24 | #' to display in an external RStudio window; "browser" to display in an external 25 | #' browser. 26 | #' 27 | #' @import htmlwidgets 28 | #' @import tools 29 | #' 30 | #' @details 31 | #' 32 | #' In order to scope CSS styles when multiple widgets are rendered, the Shadow DOM and 33 | #' the wecomponents polyfill is used, this feature can be turned off by setting the 34 | #' \code{r2d3.shadow} option to \code{FALSE}. 35 | #' 36 | #' @examples 37 | #' 38 | #' library(r2d3) 39 | #' r2d3( 40 | #' data = c (0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 41 | #' script = system.file("examples/barchart.js", package = "r2d3") 42 | #' ) 43 | #' 44 | #' @export 45 | r2d3 <- function( 46 | data, 47 | script, 48 | css = "auto", 49 | dependencies = NULL, 50 | options = NULL, 51 | d3_version = c("6", "5", "4", "3"), 52 | container = "svg", 53 | elementId = NULL, 54 | width = NULL, 55 | height = NULL, 56 | sizing = default_sizing(), 57 | viewer = c("internal", "external", "browser") 58 | ) 59 | { 60 | # allow data to be missing 61 | if (missing(data)) 62 | data <- c() 63 | 64 | # resolve version 65 | version <- match.arg(as.character(d3_version), choices = c("6", "5", "4", "3")) 66 | 67 | # auto-detect css styles 68 | if (identical(css, "auto")) { 69 | # auto-detect based on js filename and "styles.css" 70 | css_paths <- c(paste0(tools::file_path_sans_ext(script), ".css"), 71 | file.path(dirname(script), "styles.css")) 72 | css <- css_paths[file.exists(css_paths)] 73 | if (length(css) == 0) 74 | css <- NULL 75 | } 76 | 77 | # resolve inline dependencies 78 | inline_dependencies <- NULL 79 | if (!is.null(dependencies) || !is.null(css)) { 80 | 81 | # force dependencies to list if necessary 82 | if (inherits(dependencies, "html_dependency")) 83 | dependencies <- list(dependencies) 84 | 85 | inline_dependencies <- list( 86 | js = Filter(function(e) is.character(e) && identical(file_ext(e), "js"), dependencies), 87 | css = Filter(function(e) is.character(e) && identical(file_ext(e), "css"), dependencies) 88 | ) 89 | inline_dependencies$js <- as.character(inline_dependencies$js) 90 | inline_dependencies$css <- as.character(c(inline_dependencies$css, css)) 91 | } 92 | 93 | # resolve extension dependencies 94 | extension_dependencies <- as.character(Filter(function(e) is.character(e) && e %in% all_extensions(), dependencies)) 95 | 96 | # resolve html dependencies 97 | html_dependencies <- Filter(function(e) inherits(e, "html_dependency"), dependencies) 98 | html_dependencies <- append(html_dependencies, html_dependencies_d3(version, extensions = extension_dependencies)) 99 | 100 | # convert to d3 data 101 | data <- as_d3_data(data) 102 | 103 | # determine type 104 | type <- if (inherits(data, "data.frame")) "data.frame" else class(data)[[1]] 105 | 106 | # forward options using x 107 | x <- list( 108 | data = data, 109 | type = type, 110 | container = container, 111 | options = options, 112 | script = script_wrap( 113 | inline_dependencies$js, 114 | script, 115 | container 116 | ), 117 | style = script_read(inline_dependencies$css), 118 | version = as.integer(version), 119 | theme = list( 120 | default = default_theme(), 121 | runtime = runtime_theme() 122 | ), 123 | useShadow = getOption("r2d3.shadow", TRUE) 124 | ) 125 | 126 | # resolve viewer if it's explicitly specified 127 | if (!missing(viewer)) { 128 | viewer <- match.arg(viewer) 129 | if (viewer != "internal") { 130 | sizing$viewer$suppress <- TRUE 131 | sizing$browser$external <- viewer == "browser" 132 | } 133 | } 134 | 135 | # create widget 136 | htmlwidgets::createWidget( 137 | name = 'r2d3', 138 | x, 139 | width = width, 140 | height = height, 141 | package = 'r2d3', 142 | dependencies = html_dependencies, 143 | elementId = elementId, 144 | sizingPolicy = sizing 145 | ) 146 | } 147 | 148 | #' Default sizing policy for r2d3 widgets 149 | #' 150 | #' @details Use [htmlwidgets::sizingPolicy()] to specify an 151 | #' alternate policy. 152 | #' 153 | #' @keywords internal 154 | #' @export 155 | default_sizing <- function() { 156 | htmlwidgets::sizingPolicy( 157 | browser.fill = TRUE 158 | ) 159 | } 160 | 161 | default_theme <- function() { 162 | getOption( 163 | "r2d3.theme", 164 | list( 165 | background = "#FFFFFF", 166 | foreground = "#000000" 167 | ) 168 | ) 169 | } 170 | 171 | runtime_theme <- function() { 172 | if (exists(".rs.api.getThemeInfo")) { 173 | rstudio_default <- get(".rs.api.getThemeInfo")() 174 | 175 | # https://github.com/rstudio/rstudio/issues/4055 176 | list( 177 | background = "#FFFFFF", 178 | foreground = "#000000" 179 | ) 180 | } else { 181 | NULL 182 | } 183 | } -------------------------------------------------------------------------------- /R/script.R: -------------------------------------------------------------------------------- 1 | # Prepares a D3 script to be embedable into a widget 2 | script_wrap <- function(deps, script, container) { 3 | deps_contents <- script_read(deps) 4 | script_contents <- script_read(script) 5 | 6 | if (is.character(script_contents) && length(script_contents) > 1) 7 | script_contents <- paste(script_contents, collapse = "\n") 8 | 9 | script_contents <- paste( 10 | # some libraries expect the container to be created from the extended d3 object. 11 | container, " = d3.select(", container, ".node());", 12 | "\n", 13 | script_contents, 14 | sep = "" 15 | ) 16 | 17 | paste( 18 | "var d3Script = function(d3, r2d3, data, ", container, ", width, height, options, theme, console) {", 19 | "\n", 20 | # some libraries expect d3 to be accessible as this.d3 21 | "this.d3 = d3;", 22 | "\n", 23 | deps_contents, 24 | "\n", 25 | script_contents, 26 | "\n", 27 | "};", 28 | sep = "" 29 | ) 30 | } 31 | 32 | script_read <- function(script) { 33 | if ( 34 | is.null(script) || 35 | length(script) == 0 || 36 | any(!file.exists(script)) 37 | ) { 38 | return(script) 39 | } 40 | 41 | paste( 42 | sapply( 43 | script, 44 | function(e) paste( 45 | c( 46 | paste("/* R2D3 Source File: ", e, "*/"), 47 | readLines(e, warn = FALSE) 48 | ), collapse = "\n" 49 | ) 50 | ), 51 | collapse = "\n\n" 52 | ) 53 | } -------------------------------------------------------------------------------- /R/shiny.R: -------------------------------------------------------------------------------- 1 | #' Shiny bindings for d3 2 | #' 3 | #' Output and render functions for using d3 within Shiny 4 | #' applications and interactive Rmd documents. 5 | #' 6 | #' @param outputId output variable to read from 7 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 8 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 9 | #' string and have \code{'px'} appended. 10 | #' @param expr An expression that generates a d3 11 | #' @param env The environment in which to evaluate \code{expr}. 12 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 13 | #' is useful if you want to save an expression in a variable. 14 | #' 15 | #' @name d3-shiny 16 | #' 17 | #' @export 18 | d3Output <- function(outputId, width = '100%', height = '400px') 19 | { 20 | htmlwidgets::shinyWidgetOutput(outputId, 'r2d3', width, height) 21 | } 22 | 23 | #' @rdname d3-shiny 24 | #' @export 25 | renderD3 <- function(expr, env = parent.frame(), quoted = FALSE) 26 | { 27 | if (!quoted) { expr <- substitute(expr) } # force quoted 28 | htmlwidgets::shinyRenderWidget(expr, d3Output, env, quoted = TRUE) 29 | } -------------------------------------------------------------------------------- /R/version.R: -------------------------------------------------------------------------------- 1 | # Completes major version to full version 2 | version_complete <- function(minor) { 3 | versions <- list( 4 | "6" = "6.2.0", 5 | "5" = "5.9.2", 6 | "4" = "4.13.0", 7 | "3" = "3.5.17" 8 | ) 9 | 10 | version <- versions[[as.character(minor)]] 11 | 12 | if (is.null(version)) 13 | stop("Version ", minor, " is currently unsupported.") 14 | 15 | version 16 | } -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onAttach <- function(...) { 2 | 3 | if (requireNamespace("knitr", quietly = TRUE)) { 4 | knit_engines <- get("knit_engines", envir = asNamespace("knitr")) 5 | knit_engines$set(d3 = knit_d3) 6 | } 7 | 8 | rstudio <- rstudio_version() 9 | if (!is.null(rstudio)) { 10 | 11 | # check for desktop mode on windows and linux (other modes are fine) 12 | if (!is_osx() && (rstudio$mode == "desktop")) { 13 | 14 | if (rstudio$version < "1.2.637") 15 | packageStartupMessage( 16 | "r2d3 should be run under RStudio v1.2 or higher. Please update at:\n", 17 | "https://rstudio.com/products/rstudio/download/\n" 18 | ) 19 | } 20 | } 21 | } 22 | 23 | # get the current rstudio version and mode (desktop vs. server) 24 | rstudio_version <- function() { 25 | 26 | # Running at the RStudio console 27 | if (rstudioapi::isAvailable()) { 28 | 29 | rstudioapi::versionInfo() 30 | 31 | # Running in a child process 32 | } else if (!is.na(Sys.getenv("RSTUDIO", unset = NA))) { 33 | 34 | # detect desktop vs. server using server-only environment variable 35 | mode <- ifelse(is.na(Sys.getenv("RSTUDIO_HTTP_REFERER", unset = NA)), 36 | "desktop", "server") 37 | 38 | # detect version using Rmd new env var added in 1.2.638 39 | version <- Sys.getenv("RSTUDIO_VERSION", unset = "1.1") 40 | 41 | # return version info 42 | list( 43 | mode = mode, 44 | version = version 45 | ) 46 | 47 | # Not running in RStudio 48 | } else { 49 | NULL 50 | } 51 | } 52 | 53 | is_osx <- function() { 54 | Sys.info()["sysname"] == "Darwin" 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /inst/examples/baranims.js: -------------------------------------------------------------------------------- 1 | var barHeight = Math.floor(height / data.length); 2 | 3 | var bars = r2d3.svg.selectAll('rect') 4 | .data(r2d3.data); 5 | 6 | bars.enter() 7 | .append('rect') 8 | .attr('width', function(d) { return d * width; }) 9 | .attr('height', barHeight) 10 | .attr('y', function(d, i) { return i * barHeight; }) 11 | .attr('fill', 'steelblue'); 12 | 13 | bars.exit().remove(); 14 | 15 | bars.transition() 16 | .duration(100) 17 | .attr("width", function(d) { return d * width; }); 18 | -------------------------------------------------------------------------------- /inst/examples/barchart.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 2 | 3 | var barHeight = Math.floor(height / data.length); 4 | 5 | svg.selectAll('rect') 6 | .data(data) 7 | .enter().append('rect') 8 | .attr('width', function(d) { return d * width; }) 9 | .attr('height', barHeight) 10 | .attr('y', function(d, i) { return i * barHeight; }) 11 | .attr('fill', 'steelblue'); 12 | -------------------------------------------------------------------------------- /inst/htmlwidgets/r2d3.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | name: 'r2d3', 3 | type: 'output', 4 | factory: function(el, width, height) { 5 | 6 | var r2d3 = new R2D3(el, width, height); 7 | 8 | return { 9 | renderValue: function(x) { 10 | r2d3.widgetRender(x); 11 | }, 12 | 13 | resize: function(width, height) { 14 | r2d3.widgetResize(width, height); 15 | } 16 | }; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /inst/htmlwidgets/r2d3.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: r2d3-render 3 | version: 0.1.0 4 | src: htmlwidgets/lib/r2d3 5 | script: 6 | - r2d3-render.js 7 | - name: webcomponents 8 | version: 2.0.0 9 | src: htmlwidgets/lib/webcomponents 10 | script: 11 | - webcomponents.js 12 | -------------------------------------------------------------------------------- /inst/www/d3/3.5.17/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2016, Michael Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * The name Michael Bostock may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /inst/www/d3/4.13.0/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2017 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /inst/www/d3/4.13.0/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 10 | * [Release Notes](https://github.com/d3/d3/releases) 11 | * [Gallery](https://github.com/d3/d3/wiki/Gallery) 12 | * [Examples](https://bl.ocks.org/mbostock) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | var d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | var d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /inst/www/d3/5.9.2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2017 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /inst/www/d3/5.9.2/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 10 | * [Release Notes](https://github.com/d3/d3/releases) 11 | * [Gallery](https://github.com/d3/d3/wiki/Gallery) 12 | * [Examples](https://bl.ocks.org/mbostock) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | var d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | var d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /inst/www/d3/6.2.0/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2020 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /inst/www/d3/6.2.0/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [Introduction](https://observablehq.com/@d3/learn-d3) 10 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 11 | * [Releases](https://github.com/d3/d3/releases) 12 | * [Examples](https://observablehq.com/@d3/gallery) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | const d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | const d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /man/as_d3_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert.R 3 | \name{as_d3_data} 4 | \alias{as_d3_data} 5 | \alias{as_d3_data.default} 6 | \title{Convert object to D3 data} 7 | \usage{ 8 | as_d3_data(x, ...) 9 | 10 | \method{as_d3_data}{default}(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{data} 14 | 15 | \item{...}{Additional arguments for generic methods} 16 | } 17 | \description{ 18 | Generic method to transform R objects into D3 friendly data. 19 | } 20 | \details{ 21 | The value returned from \code{as_d3_data()} should be one of: 22 | \itemize{ 23 | \item An R data frame. In this case the \code{HTMLWidgets.dataframeToD3()} 24 | JavaScript function will be called on the client to transform 25 | the data into D3 friendly (row-oriented) data; or 26 | \item A JSON object created using \link[jsonlite:fromJSON]{jsonlite::toJSON}; or 27 | \item Any other R object which can be coverted to JSON using \link[jsonlite:fromJSON]{jsonlite::toJSON}. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/d3-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny.R 3 | \name{d3-shiny} 4 | \alias{d3-shiny} 5 | \alias{d3Output} 6 | \alias{renderD3} 7 | \title{Shiny bindings for d3} 8 | \usage{ 9 | d3Output(outputId, width = "100\%", height = "400px") 10 | 11 | renderD3(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a d3} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using d3 within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /man/default_sizing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/render.R 3 | \name{default_sizing} 4 | \alias{default_sizing} 5 | \title{Default sizing policy for r2d3 widgets} 6 | \usage{ 7 | default_sizing() 8 | } 9 | \description{ 10 | Default sizing policy for r2d3 widgets 11 | } 12 | \details{ 13 | Use \code{\link[htmlwidgets:sizingPolicy]{htmlwidgets::sizingPolicy()}} to specify an 14 | alternate policy. 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/figures/bar_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/bar_chart.png -------------------------------------------------------------------------------- /man/figures/baranim-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/baranim-1.gif -------------------------------------------------------------------------------- /man/figures/barchart-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/barchart-1.png -------------------------------------------------------------------------------- /man/figures/bubbles_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/bubbles_thumbnail.png -------------------------------------------------------------------------------- /man/figures/cartogram_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/cartogram_thumbnail.png -------------------------------------------------------------------------------- /man/figures/chord_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/chord_thumbnail.png -------------------------------------------------------------------------------- /man/figures/daily_build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/daily_build.png -------------------------------------------------------------------------------- /man/figures/new_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/new_script.png -------------------------------------------------------------------------------- /man/figures/r2d3-hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/r2d3-hex.png -------------------------------------------------------------------------------- /man/figures/rmarkdown-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/rmarkdown-1.png -------------------------------------------------------------------------------- /man/figures/rstudio_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/man/figures/rstudio_preview.png -------------------------------------------------------------------------------- /man/html_dependencies_d3.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dependencies.R 3 | \name{html_dependencies_d3} 4 | \alias{html_dependencies_d3} 5 | \title{D3 HTML dependencies} 6 | \usage{ 7 | html_dependencies_d3(version = c("6", "5", "4", "3"), extensions = NULL) 8 | } 9 | \arguments{ 10 | \item{version}{Major version of D3} 11 | 12 | \item{extensions}{D3 extensions to include. Currently the only supported 13 | extension is "jetpack" (\url{https://github.com/gka/d3-jetpack}).} 14 | } 15 | \description{ 16 | Create HTML dependencies for D3 and optional extensions 17 | } 18 | \details{ 19 | Create list of HTML dependencies for D3. Each version has 20 | a distinct root D3 object so it's possible to combine multiple versions 21 | of D3 on a single page. For example, D3 v5 is accessed via \code{d3v5} and 22 | D3 v4 is accessed via \code{d3v4}. Note however that D3 v3 is accessed via 23 | simply \code{d3} (for compabibilty with existing htmlwidgets that use 24 | this form). 25 | } 26 | \note{ 27 | This function is exported for use by htmlwidgets. If you are 28 | using the \code{r2d3()} function to include D3 code within a document 29 | or application this dependency is included automatically so calling 30 | this function is unnecessary. 31 | } 32 | \examples{ 33 | 34 | library(r2d3) 35 | r2d3( 36 | data = c (0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 37 | script = system.file("examples/barchart.js", package = "r2d3"), 38 | dependencies = "d3-jetpack" 39 | ) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /man/r2d3.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/render.R 3 | \name{r2d3} 4 | \alias{r2d3} 5 | \title{D3 visualization} 6 | \usage{ 7 | r2d3( 8 | data, 9 | script, 10 | css = "auto", 11 | dependencies = NULL, 12 | options = NULL, 13 | d3_version = c("6", "5", "4", "3"), 14 | container = "svg", 15 | elementId = NULL, 16 | width = NULL, 17 | height = NULL, 18 | sizing = default_sizing(), 19 | viewer = c("internal", "external", "browser") 20 | ) 21 | } 22 | \arguments{ 23 | \item{data}{Data to be passed to D3 script.} 24 | 25 | \item{script}{JavaScript file containing the D3 script.} 26 | 27 | \item{css}{CSS file containing styles. The default value "auto" will use any CSS file 28 | located alongside the script file with the same stem (e.g. "barplot.css" would be 29 | used for "barplot.js") as well as any CSS file with the name "styles.css".} 30 | 31 | \item{dependencies}{Additional HTML dependencies. These can take the form of paths to 32 | JavaScript or CSS files, or alternatively can be fully specified dependencies created 33 | with \link[htmltools:htmlDependency]{htmltools::htmlDependency}.} 34 | 35 | \item{options}{Options to be passed to D3 script.} 36 | 37 | \item{d3_version}{Major D3 version to use, the latest minor version is automatically 38 | picked.} 39 | 40 | \item{container}{The 'HTML' container of the D3 output.} 41 | 42 | \item{elementId}{Use an explicit element ID for the widget (rather than an 43 | automatically generated one). Useful if you have other JavaScript that needs to 44 | explicitly discover and interact with a specific widget instance.} 45 | 46 | \item{width}{Desired width for output widget.} 47 | 48 | \item{height}{Desired height for output widget.} 49 | 50 | \item{sizing}{Widget sizing policy (see \link[htmlwidgets:sizingPolicy]{htmlwidgets::sizingPolicy}).} 51 | 52 | \item{viewer}{"internal" to use the RStudio internal viewer pane for output; "external" 53 | to display in an external RStudio window; "browser" to display in an external 54 | browser.} 55 | } 56 | \description{ 57 | Visualize data using a custom D3 visualization script 58 | } 59 | \details{ 60 | In order to scope CSS styles when multiple widgets are rendered, the Shadow DOM and 61 | the wecomponents polyfill is used, this feature can be turned off by setting the 62 | \code{r2d3.shadow} option to \code{FALSE}. 63 | } 64 | \examples{ 65 | 66 | library(r2d3) 67 | r2d3( 68 | data = c (0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 69 | script = system.file("examples/barchart.js", package = "r2d3") 70 | ) 71 | 72 | } 73 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reexports.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{sizingPolicy} 7 | \alias{read_json} 8 | \title{Objects exported from other packages} 9 | \keyword{internal} 10 | \description{ 11 | These objects are imported from other packages. Follow the links 12 | below to see their documentation. 13 | 14 | \describe{ 15 | \item{htmlwidgets}{\code{\link[htmlwidgets]{sizingPolicy}}} 16 | 17 | \item{jsonlite}{\code{\link[jsonlite]{read_json}}} 18 | }} 19 | 20 | -------------------------------------------------------------------------------- /man/save_d3_html.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/publish.R 3 | \name{save_d3_html} 4 | \alias{save_d3_html} 5 | \title{Save a D3 visualization as HTML} 6 | \usage{ 7 | save_d3_html( 8 | d3, 9 | file, 10 | selfcontained = TRUE, 11 | libdir = NULL, 12 | background = "white", 13 | title = "D3 Visualization", 14 | knitrOptions = list() 15 | ) 16 | } 17 | \arguments{ 18 | \item{d3}{D3 visualization to save} 19 | 20 | \item{file}{File to save HTML into} 21 | 22 | \item{selfcontained}{Whether to save the HTML as a single self-contained file 23 | (with external resources base64 encoded) or a file with external resources 24 | placed in an adjacent directory.} 25 | 26 | \item{libdir}{Directory to copy HTML dependencies into (defaults to 27 | filename_files).} 28 | 29 | \item{background}{Text string giving the html background color of the widget. 30 | Defaults to white.} 31 | 32 | \item{title}{Text to use as the title of the generated page.} 33 | 34 | \item{knitrOptions}{A list of \pkg{knitr} chunk options.} 35 | } 36 | \description{ 37 | Save a D3 visualization to an HTML file (e.g. for sharing with others). 38 | } 39 | \details{ 40 | Using \code{selfcontained} set to \code{TRUE} requires \href{https://pandoc.org/}{pandoc} 41 | to be installed. 42 | } 43 | \examples{ 44 | library(r2d3) 45 | 46 | viz <- r2d3( 47 | data = c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 48 | script = system.file("examples/barchart.js", package = "r2d3") 49 | ) 50 | 51 | save_d3_html( 52 | viz, 53 | file = tempfile(fileext = ".html"), 54 | selfcontained = FALSE 55 | ) 56 | } 57 | \seealso{ 58 | \code{\link[=save_d3_png]{save_d3_png()}} 59 | } 60 | -------------------------------------------------------------------------------- /man/save_d3_png.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/publish.R 3 | \name{save_d3_png} 4 | \alias{save_d3_png} 5 | \title{Save a D3 visualization as a PNG image} 6 | \usage{ 7 | save_d3_png( 8 | d3, 9 | file, 10 | background = "white", 11 | width = 992, 12 | height = 744, 13 | delay = 0.2, 14 | zoom = 1 15 | ) 16 | } 17 | \arguments{ 18 | \item{d3}{D3 visualization to save} 19 | 20 | \item{file}{File to save HTML into} 21 | 22 | \item{background}{Text string giving the html background color of the widget. 23 | Defaults to white.} 24 | 25 | \item{width}{Image width} 26 | 27 | \item{height}{Image height} 28 | 29 | \item{delay}{Time to wait before taking screenshot, in seconds. Sometimes a 30 | longer delay is needed for all assets to display properly.} 31 | 32 | \item{zoom}{A number specifying the zoom factor. A zoom factor of 2 will 33 | result in twice as many pixels vertically and horizontally. Note that 34 | using 2 is not exactly the same as taking a screenshot on a HiDPI (Retina) 35 | device: it is like increasing the zoom to 200 doubling the height and 36 | width of the browser window. This differs from using a HiDPI device 37 | because some web pages load different, higher-resolution images when they 38 | know they will be displayed on a HiDPI device (but using zoom will not 39 | report that there is a HiDPI device).} 40 | } 41 | \description{ 42 | Save a D3 visualization to PNG (e.g. for including in another document). 43 | } 44 | \details{ 45 | PNG versions of D3 visualizations are created by displaying them in 46 | an offscreen web browser and taking a screenshot of the rendered web page. 47 | 48 | Using the \code{save_d3_png()} function requires that you install the 49 | \pkg{webshot} package, as well as the phantom.js headless browser (which 50 | you can install using the function \code{webshot::install_phantomjs()}). 51 | } 52 | \seealso{ 53 | \code{\link[=save_d3_html]{save_d3_html()}} 54 | } 55 | -------------------------------------------------------------------------------- /pkgdown/_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://rstudio.github.io/r2d3/ 2 | 3 | development: 4 | mode: auto 5 | 6 | template: 7 | params: 8 | bootswatch: flatly 9 | 10 | navbar: 11 | title: "r2d3" 12 | type: inverse 13 | left: 14 | - text: "Home" 15 | href: index.html 16 | - text: "Articles" 17 | menu: 18 | - text: Using 19 | - text: "R to D3 Data Conversion" 20 | href: articles/data_conversion.html 21 | - text: "D3 Visualization Options" 22 | href: articles/visualization_options.html 23 | - text: "Development and Debugging" 24 | href: articles/development_and_debugging.html 25 | - text: "Publishing D3 Visualizations" 26 | href: articles/publishing.html 27 | - text: "---" 28 | - text: Advanced 29 | - text: "Using r2d3 with Shiny" 30 | href: articles/shiny.html 31 | - text: "CSS and JavaScript Dependencies " 32 | href: articles/dependencies.html 33 | - text: "Advanced Rendering with Callbacks" 34 | href: articles/advanced_rendering.html 35 | - text: "Package Development" 36 | href: articles/package_development.html 37 | - text: "Learning D3" 38 | href: articles/learning_d3.html 39 | - text: "Gallery" 40 | href: articles/gallery.html 41 | - text: "Reference" 42 | href: reference/index.html 43 | 44 | reference: 45 | 46 | - title: "Rendering" 47 | contents: 48 | - r2d3 49 | - default_sizing 50 | 51 | - title: "Data" 52 | contents: 53 | - as_d3_data 54 | - read_json 55 | 56 | - title: "Publishing" 57 | contents: 58 | - save_d3_html 59 | - save_d3_png 60 | 61 | - title: "Shiny" 62 | contents: 63 | - d3Output 64 | - renderD3 65 | 66 | - title: "Miscellaneous" 67 | contents: 68 | - html_dependencies_d3 69 | -------------------------------------------------------------------------------- /pkgdown/extra.css: -------------------------------------------------------------------------------- 1 | 2 | .page-header { 3 | margin-bottom: 6px; 4 | } 5 | 6 | 7 | h4.date, 8 | h4.author { 9 | display: none; 10 | } 11 | 12 | h2.hasAnchor { 13 | font-weight: 350; 14 | } 15 | 16 | .contents h1, .contents h2, .contents h3, .contents h4 { 17 | padding-top: 60px; 18 | margin-top: -60px; 19 | } 20 | 21 | .contents .page-header { 22 | margin-top: 42px; 23 | } 24 | 25 | .contents h2 { 26 | font-size: 28px; 27 | padding-top: 70px; 28 | } 29 | 30 | .ref-index tbody { 31 | margin-bottom: 60px; 32 | } 33 | 34 | pre:not([class]) { 35 | background-color: white; 36 | } 37 | 38 | blockquote { 39 | font-size: inherit; 40 | } 41 | 42 | .examples .page-header { 43 | border-bottom: none; 44 | margin: 0; 45 | padding-bottom: 0; 46 | } 47 | 48 | .examples .sourceCode { 49 | margin-top: 25px; 50 | } 51 | 52 | #sidebar .nav>li>a { 53 | padding-top: 1px; 54 | padding-bottom: 2px; 55 | } 56 | 57 | #installation .sourceCode { 58 | font-size: 13px; 59 | } 60 | 61 | .r-plot { 62 | margin-top: 15px; 63 | margin-bottom: 20px; 64 | border: solid 1px #cccccc; 65 | } 66 | 67 | .screenshot, .illustration { 68 | margin-bottom: 20px; 69 | border: solid 1px #cccccc; 70 | } 71 | 72 | .thumbnail { 73 | margin-top: 10px; 74 | margin-bottom: 10px; 75 | border: 1px solid #cccccc; 76 | } 77 | 78 | .gallery-thumbnail { 79 | margin-right: 10px; 80 | display: inline; 81 | } 82 | 83 | .source-ref { 84 | margin-bottom: 20px; 85 | } 86 | 87 | .source-ref .caption { 88 | display: none; 89 | } 90 | 91 | .link-table td { 92 | padding-top: 20px !important; 93 | padding-bottom: 210x !important; 94 | } 95 | 96 | .alert-warning { 97 | color: #8a6d3b; 98 | background-color: #fcf8e3; 99 | padding: 15px; 100 | margin-top: 20px; 101 | margin-bottom: 20px; 102 | background-image: linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%); 103 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 104 | background-repeat: repeat-x; 105 | border: 1px solid #f5e79e; 106 | border-radius: 4px; 107 | } 108 | 109 | .navbar-brand .label { 110 | display: none; 111 | } 112 | 113 | .page-header>small { 114 | display: none; 115 | } 116 | 117 | .r2d3.html-widget > svg, 118 | .r2d3.html-widget > div { 119 | border: 1px solid #eee; 120 | } 121 | 122 | .r2d3.html-widget { 123 | margin-bottom: 20px; 124 | } 125 | 126 | pre code { 127 | word-wrap: break-word; 128 | white-space: pre-wrap; 129 | } 130 | 131 | #source-link { 132 | display: none; 133 | } 134 | 135 | a.sourceLine:hover { 136 | color: #375f84; 137 | } 138 | 139 | .thumbnail .caption { 140 | padding: 0; 141 | padding-top: 4px; 142 | padding-left: 3px; 143 | font-size: 0.9em; 144 | color: gray; 145 | } 146 | 147 | a.thumbnail:hover { 148 | text-decoration: none; 149 | } 150 | 151 | 152 | -------------------------------------------------------------------------------- /pkgdown/extra.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | $( document ).ready(function() { 4 | $('kbd').children().unwrap(); 5 | }); 6 | 7 | 8 | -------------------------------------------------------------------------------- /r2d3.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace 19 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(r2d3) 3 | 4 | test_check("r2d3") 5 | -------------------------------------------------------------------------------- /tests/testthat/.gitignore: -------------------------------------------------------------------------------- 1 | figure 2 | -------------------------------------------------------------------------------- /tests/testthat/baranims.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 2 | // 3 | // r2d3: https://rstudio.github.io/r2d3 4 | // 5 | 6 | var barHeight = Math.floor(height / data.length); 7 | 8 | var bars = r2d3.svg.selectAll('rect') 9 | .data(r2d3.data); 10 | 11 | bars.enter() 12 | .append('rect') 13 | .attr('width', function(d) { return d * width; }) 14 | .attr('height', barHeight) 15 | .attr('y', function(d, i) { return i * barHeight; }) 16 | .attr('fill', 'steelblue'); 17 | 18 | bars.exit().remove(); 19 | 20 | bars.transition() 21 | .duration(0) 22 | .attr("width", function(d) { return d * width; }); -------------------------------------------------------------------------------- /tests/testthat/barchart.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "barchart" 3 | output: html_document 4 | --- 5 | 6 | ```{r setup} 7 | library(r2d3) 8 | ``` 9 | 10 | ```{d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)} 11 | var barHeight = Math.floor(height / data.length); 12 | 13 | svg.selectAll('rect') 14 | .data(data) 15 | .enter().append('rect') 16 | .attr('width', function(d) { return d * width; }) 17 | .attr('height', barHeight) 18 | .attr('y', function(d, i) { return i * barHeight; }) 19 | .attr('fill', 'steelblue'); 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /tests/testthat/barchart.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | background: white; 4 | } 5 | -------------------------------------------------------------------------------- /tests/testthat/barchart.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 2 | 3 | var barHeight = Math.floor(height / data.length); 4 | 5 | svg.selectAll('rect') 6 | .data(data) 7 | .enter().append('rect') 8 | .attr('width', function(d) { return d * width; }) 9 | .attr('height', barHeight) 10 | .attr('y', function(d, i) { return i * barHeight; }) 11 | .attr('fill', 'steelblue'); 12 | -------------------------------------------------------------------------------- /tests/testthat/barchart/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(r2d3) 3 | 4 | ui <- fluidPage( 5 | inputPanel( 6 | sliderInput("bar_max", label = "Max:", 7 | min = 0.1, max = 1.0, value = 0.2, step = 0.1) 8 | ), 9 | d3Output("d3") 10 | ) 11 | 12 | server <- function(input, output) { 13 | output$d3 <- renderD3({ 14 | r2d3( 15 | rep(input$bar_max, 5), 16 | script = "../baranims.js" 17 | ) 18 | }) 19 | } 20 | 21 | shinyApp(ui = ui, server = server) -------------------------------------------------------------------------------- /tests/testthat/barchart/tests/shinytest-expected/001.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bar_max": 1 4 | }, 5 | "output": { 6 | "d3": { 7 | "x": { 8 | "data": [ 9 | 1, 10 | 1, 11 | 1, 12 | 1, 13 | 1 14 | ], 15 | "type": "integer", 16 | "container": "svg", 17 | "options": null, 18 | "script": "var d3Script = function(d3, r2d3, data, svg, width, height, options, theme, console) {\nthis.d3 = d3;\n\nsvg = d3.select(svg.node());\n/* R2D3 Source File: ../baranims.js */\n// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)\n//\n// r2d3: https://rstudio.github.io/r2d3\n//\n\nvar barHeight = Math.floor(height / data.length);\n\nvar bars = r2d3.svg.selectAll('rect')\n .data(r2d3.data);\n \nbars.enter()\n .append('rect')\n .attr('width', function(d) { return d * width; })\n .attr('height', barHeight)\n .attr('y', function(d, i) { return i * barHeight; })\n .attr('fill', 'steelblue');\n\nbars.exit().remove();\n\nbars.transition()\n .duration(0)\n .attr(\"width\", function(d) { return d * width; });\n};", 19 | "style": null, 20 | "version": 6, 21 | "theme": { 22 | "default": { 23 | "background": "#FFFFFF", 24 | "foreground": "#000000" 25 | }, 26 | "runtime": null 27 | }, 28 | "useShadow": true 29 | }, 30 | "evals": [ 31 | 32 | ], 33 | "jsHooks": [ 34 | 35 | ], 36 | "deps": [ 37 | { 38 | "name": "d3v6", 39 | "version": "6.2.0", 40 | "src": { 41 | "href": "d3v6-6.2.0" 42 | }, 43 | "meta": null, 44 | "script": "d3.min.js", 45 | "stylesheet": null, 46 | "head": null, 47 | "attachment": null, 48 | "package": null, 49 | "all_files": true 50 | } 51 | ] 52 | } 53 | }, 54 | "export": { 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/testthat/barchart/tests/shinytest-expected/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tests/testthat/barchart/tests/shinytest-expected/001.png -------------------------------------------------------------------------------- /tests/testthat/barchart/tests/shinytest-expected/002.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "bar_max": 0.2 4 | }, 5 | "output": { 6 | "d3": { 7 | "x": { 8 | "data": [ 9 | 0.2, 10 | 0.2, 11 | 0.2, 12 | 0.2, 13 | 0.2 14 | ], 15 | "type": "numeric", 16 | "container": "svg", 17 | "options": null, 18 | "script": "var d3Script = function(d3, r2d3, data, svg, width, height, options, theme, console) {\nthis.d3 = d3;\n\nsvg = d3.select(svg.node());\n/* R2D3 Source File: ../baranims.js */\n// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)\n//\n// r2d3: https://rstudio.github.io/r2d3\n//\n\nvar barHeight = Math.floor(height / data.length);\n\nvar bars = r2d3.svg.selectAll('rect')\n .data(r2d3.data);\n \nbars.enter()\n .append('rect')\n .attr('width', function(d) { return d * width; })\n .attr('height', barHeight)\n .attr('y', function(d, i) { return i * barHeight; })\n .attr('fill', 'steelblue');\n\nbars.exit().remove();\n\nbars.transition()\n .duration(0)\n .attr(\"width\", function(d) { return d * width; });\n};", 19 | "style": null, 20 | "version": 6, 21 | "theme": { 22 | "default": { 23 | "background": "#FFFFFF", 24 | "foreground": "#000000" 25 | }, 26 | "runtime": null 27 | }, 28 | "useShadow": true 29 | }, 30 | "evals": [ 31 | 32 | ], 33 | "jsHooks": [ 34 | 35 | ], 36 | "deps": [ 37 | { 38 | "name": "d3v6", 39 | "version": "6.2.0", 40 | "src": { 41 | "href": "d3v6-6.2.0" 42 | }, 43 | "meta": null, 44 | "script": "d3.min.js", 45 | "stylesheet": null, 46 | "head": null, 47 | "attachment": null, 48 | "package": null, 49 | "all_files": true 50 | } 51 | ] 52 | } 53 | }, 54 | "export": { 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/testthat/barchart/tests/shinytest-expected/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tests/testthat/barchart/tests/shinytest-expected/002.png -------------------------------------------------------------------------------- /tests/testthat/barchart/tests/shinytest.R: -------------------------------------------------------------------------------- 1 | app <- ShinyDriver$new("../") 2 | app$snapshotInit("shinytest") 3 | 4 | app$setInputs(bar_max = 1) 5 | app$snapshot() 6 | app$setInputs(bar_max = 0.2) 7 | app$snapshot() 8 | -------------------------------------------------------------------------------- /tests/testthat/helper.js: -------------------------------------------------------------------------------- 1 | 2 | // lending a helpful hand -------------------------------------------------------------------------------- /tests/testthat/test-examples.R: -------------------------------------------------------------------------------- 1 | context("examples") 2 | 3 | run_example <- function(example) { 4 | if (file_test("-d", example)) { 5 | knitr::knit( 6 | file.path(example, "index.Rmd"), 7 | output = tempfile("r2d3_example", fileext = ".md"), 8 | quiet = TRUE 9 | ) 10 | } 11 | } 12 | 13 | examples <- file.path("../../vignettes/gallery", 14 | c("bubbles", "cartogram", "chord") 15 | ) 16 | 17 | for (example in examples) { 18 | test_that(paste(basename(example), "example runs correctly"), { 19 | expect_error(run_example(example), NA) 20 | }) 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /tests/testthat/test-knit.R: -------------------------------------------------------------------------------- 1 | context("knit") 2 | 3 | source("utils.R") 4 | 5 | test_succeeds("r2d3 can knit visualizations", { 6 | skip_on_cran() 7 | 8 | if (!rmarkdown::pandoc_available()) 9 | skip("rmarkdown requires pandoc") 10 | 11 | output <- tempfile(fileext = ".html") 12 | rmarkdown::render("barchart.Rmd", output_file = output) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/test-render.R: -------------------------------------------------------------------------------- 1 | context("render") 2 | 3 | source("utils.R") 4 | 5 | test_succeeds("r2d3 can render visualizations", { 6 | render_r2d3_barchart() 7 | }) 8 | 9 | test_succeeds("r2d3 can specify d3_version", { 10 | render_r2d3_barchart(d3_version = 4) 11 | }) 12 | 13 | test_succeeds("r2d3 can provide user options", { 14 | render_r2d3_barchart(options = list(foo = "bar")) 15 | }) 16 | 17 | test_succeeds("r2d3 can specify dimensions", { 18 | render_r2d3_barchart(width = 800, height = 500) 19 | }) 20 | 21 | test_succeeds("r2d3 can provide custom css", { 22 | render_r2d3_barchart(css = "barchart.css") 23 | }) 24 | 25 | test_succeeds("r2d3 can provide javascript dependencies", { 26 | render_r2d3_barchart(dependencies = "helper.js") 27 | }) 28 | -------------------------------------------------------------------------------- /tests/testthat/test-save.R: -------------------------------------------------------------------------------- 1 | context("save") 2 | 3 | source("utils.R") 4 | 5 | test_that("d3 visualizations can be saved as html", { 6 | if (!rmarkdown::pandoc_available()) 7 | skip("selfcontained htmlwidgets require pandoc") 8 | 9 | d3 <- r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 10 | tmp <- tempfile(fileext = ".html") 11 | save_d3_html(d3, tmp) 12 | expect_true(file.exists(tmp)) 13 | }) 14 | 15 | test_that("d3 visualizations can be saved as png", { 16 | skip_on_cran() 17 | 18 | d3 <- r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 19 | tmp <- tempfile(fileext = ".png") 20 | save_d3_png(d3, tmp) 21 | expect_true(file.exists(tmp)) 22 | }) -------------------------------------------------------------------------------- /tests/testthat/test-shiny.R: -------------------------------------------------------------------------------- 1 | context("shiny") 2 | 3 | source("utils.R") 4 | 5 | test_that("r2d3 can be used in shiny applications", { 6 | skip_on_cran() 7 | 8 | shinytest::expect_pass(shinytest::testApp("barchart", compareImages = FALSE)) 9 | }) 10 | -------------------------------------------------------------------------------- /tests/testthat/utils.R: -------------------------------------------------------------------------------- 1 | library(r2d3) 2 | 3 | render_r2d3_barchart <- function(...) { 4 | r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js", ...) 5 | } 6 | 7 | test_succeeds <- function(desc, expr) { 8 | test_that(desc, { 9 | expect_error(force(expr), NA) 10 | }) 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tools/README/bar_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/bar_chart.png -------------------------------------------------------------------------------- /tools/README/baranim-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/baranim-1.gif -------------------------------------------------------------------------------- /tools/README/barchart-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/barchart-1.png -------------------------------------------------------------------------------- /tools/README/bubbles_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/bubbles_thumbnail.png -------------------------------------------------------------------------------- /tools/README/cartogram_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/cartogram_thumbnail.png -------------------------------------------------------------------------------- /tools/README/chord_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/chord_thumbnail.png -------------------------------------------------------------------------------- /tools/README/daily_build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/daily_build.png -------------------------------------------------------------------------------- /tools/README/new_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/new_script.png -------------------------------------------------------------------------------- /tools/README/r2d3-hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/r2d3-hex.png -------------------------------------------------------------------------------- /tools/README/rmarkdown-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/rmarkdown-1.png -------------------------------------------------------------------------------- /tools/README/rstudio_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/tools/README/rstudio_preview.png -------------------------------------------------------------------------------- /tools/code-partial.Rmd: -------------------------------------------------------------------------------- 1 | 2 | #### {{file}} 3 | 4 | ```{r, results='asis'} 5 | cat("```{{lang}}\n") 6 | writeLines(readLines("{{file}}", warn = FALSE)) 7 | cat("```\n") 8 | ``` 9 | 10 | -------------------------------------------------------------------------------- /tools/gallery-template.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: {{name}}" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | {{#dirs}} 19 | {{dir}} 20 | {{/dirs}} 21 |
22 |
23 | 24 |
25 | 26 | ```{r, echo=TRUE, eval=FALSE} 27 | r2d3({{{preview_args}}}, script = "{{name}}.js") 28 | ``` 29 | 30 | ```{r, echo=FALSE} 31 | r2d3({{{preview_args}}}, script = "{{name}}.js", width="100%") 32 | ``` 33 | 34 | {{#code_files}} 35 | {{> code_partial}} 36 | {{/code_files}} 37 | 38 |
39 | 40 |
41 | 42 | 43 | ```{js} 44 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 45 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 46 | $('a.list-group-item[href="../{{name}}/"]').addClass('active'); 47 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 48 | ``` 49 | -------------------------------------------------------------------------------- /tools/gallery.R: -------------------------------------------------------------------------------- 1 | 2 | library(whisker) 3 | 4 | whisker_template <- readLines("tools/gallery-template.Rmd") 5 | code_partial <- readLines("tools/code-partial.Rmd") 6 | 7 | gallery_dirs <- list.dirs("vignettes/gallery", recursive = FALSE) 8 | gallery_dirs_list <- iteratelist(basename(gallery_dirs), value="dir") 9 | 10 | # Generates a thumbnail image and puts it in vignettes/images/ 11 | create_thumbnail <- function(data) { 12 | current_dir <- getwd() 13 | on.exit(setwd(current_dir)) 14 | 15 | setwd(file.path("vignettes/gallery", data$name)) 16 | 17 | render_script <- paste(data$name, ".js", sep = "") 18 | 19 | render_command <- paste( 20 | "r2d3::r2d3(", 21 | data$preview_args, 22 | ", script = \"", 23 | render_script, 24 | "\", sizing = htmlwidgets::sizingPolicy(browser.fill = TRUE, padding = 0)", 25 | ")", 26 | sep = "" 27 | ) 28 | 29 | renderer <- parse(text = render_command) 30 | 31 | widget <- eval(renderer) 32 | 33 | render_dir <- tempfile() 34 | dir.create(render_dir) 35 | render_file <- file.path(normalizePath(render_dir), "index.html") 36 | 37 | htmlwidgets::saveWidget(widget, render_file) 38 | 39 | webshot_url <- paste("file://", render_file, sep = "") 40 | webshot_target <- paste("../../images/", data$name, "_thumbnail.png", sep = "") 41 | webshot::webshot( 42 | webshot_url, 43 | webshot_target, 44 | vwidth = 692, 45 | vheight = 474, 46 | delay = 3 47 | ) 48 | } 49 | 50 | for (dir in gallery_dirs) { 51 | message("Processing: ", basename(dir)) 52 | 53 | # base name 54 | name <- basename(dir) 55 | 56 | # preview args 57 | d3_script <- file.path(dir, paste0(name, ".js")) 58 | script_preview <- readLines(d3_script)[[1]] 59 | preview_args <- strsplit(script_preview, "!preview\\s+r2d3\\s+")[[1]][[2]] 60 | 61 | # code files 62 | list_files <- function(lang, mask = NULL) { 63 | files <- list.files(dir, pattern = glob2rx(paste0("*.", lang))) 64 | if (!is.null(mask)) 65 | files <- files[!grepl(mask, files)] 66 | main_js <- paste0(name, ".js") 67 | if (main_js %in% files) 68 | files <- unique(c(main_js, files)) 69 | lapply(files, function(file) list(lang = lang, file = file)) 70 | } 71 | code_files <- c( 72 | list_files("js", mask = glob2rx("*.min.js")), 73 | list_files("css") 74 | ) 75 | 76 | # prime data 77 | data <- list( 78 | name = name, 79 | dirs = gallery_dirs_list, 80 | preview_args = preview_args, 81 | code_files = code_files 82 | ) 83 | 84 | # render template 85 | gallery_rmd <- file.path(dir, "index.Rmd") 86 | output <- whisker.render(whisker_template, data = data, partials = list( 87 | code_partial = code_partial 88 | )) 89 | cat(output, "\n", file = gallery_rmd) 90 | 91 | # create thumbnail 92 | create_thumbnail(data) 93 | } 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /vignettes/advanced_rendering.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Advanced Rendering with Callbacks" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Advanced Rendering with Callbacks} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Overview 15 | 16 | By default, D3 visualizations created with **r2d3** are monolithic scripts that do all of their work as a single computation (the body of the script). While this makes scripts straightforward to author by default, not all visualizations will confirm to this simple model. Rather, some visualizations will want to distinguish between the following activities: 17 | 18 | 1) Code that performs one-time initialization for the visualization (e.g. creation of a D3 layout). 19 | 20 | 2) Code that runs whenever the data underlying the visualization is changed. 21 | 22 | 3) Code that runs whenever the visualizations container element is resized. 23 | 24 | This article describes how you can use the **r2d3** advanced rendering API to organize your visualization code to run in this more granular fashion. 25 | 26 | ## onRender Callback 27 | 28 | To distinguish between code that runs at initialization-time only and code that runs when data changes, organize your code so that the code which responds to data changes is contained within the `r2d3.onRender()` callback. For example: 29 | 30 | ```js 31 | // Initialization 32 | svg 33 | .attr("font-family", "sans-serif") 34 | .attr("font-size", "8") 35 | .attr("text-anchor", "middle"); 36 | 37 | var pack = d3.pack() 38 | .size([width, height]) 39 | .padding(1.5); 40 | 41 | var format = d3.format(",d"); 42 | var color = d3.scaleOrdinal(d3.schemeCategory20c); 43 | 44 | // Rendering 45 | r2d3.onRender(function(data, svg, width, height, options) { 46 | var root = d3.hierarchy({children: data}) 47 | .sum(function(d) { return d.value; }) 48 | .each(function(d) { 49 | if (id = d.data.id) { 50 | var id, i = id.lastIndexOf("."); 51 | d.id = id; 52 | d.package = id.slice(0, i); 53 | d.class = id.slice(i + 1); 54 | } 55 | }); 56 | 57 | var node = svg.selectAll(".node") 58 | .data(pack(root).leaves()) 59 | .enter().append("g") 60 | .attr("class", "node") 61 | .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 62 | 63 | node.append("circle") 64 | .attr("id", function(d) { return d.id; }) 65 | .attr("r", function(d) { return d.r; }) 66 | .style("fill", function(d) { return color(d.package); }); 67 | 68 | node.append("clipPath") 69 | .attr("id", function(d) { return "clip-" + d.id; }) 70 | .append("use") 71 | .attr("xlink:href", function(d) { return "#" + d.id; }); 72 | 73 | node.append("text") 74 | .attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }) 75 | .selectAll("tspan") 76 | .data(function(d) { return d.class.split(/(?=[A-Z][^A-Z])/g); }) 77 | .enter().append("tspan") 78 | .attr("x", 0) 79 | .attr("y", function(d, i, nodes) { return 13 + (i - nodes.length / 2 - 0.5) * 10; }) 80 | .text(function(d) { return d; }); 81 | 82 | node.append("title") 83 | .text(function(d) { return d.id + "\n" + format(d.value); }); 84 | }); 85 | ``` 86 | 87 | ## onResize Callback 88 | 89 | By default, when the element which contains your visualization is resized, **r2d3** will call back your script to re-render the visualization from scratch using the new size. In some cases this might be acceptable, but in other cases it makes sense to have code which explicitly handles the resize in a more efficient fashion. 90 | 91 | You can provide an explicit resize handler by implementing the `r2d3.onResize()` callback. For example, in a force directed D3 layout you might do this in the `onResize()` callback: 92 | 93 | ```js 94 | r2d3.onResize(function(width, height) { 95 | force.force("center", d3.forceCenter(width / 2, height / 2)) 96 | .restart(); 97 | }); 98 | ``` 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /vignettes/data_conversion.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "R to D3 Data Conversion" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{R to D3 Data Conversion} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Default conversion 15 | 16 | R objects provided as `data` for D3 visualizations are converted to JSON using the [jsonlite::toJSON()](https://www.rdocumentation.org/packages/jsonlite/versions/1.5/topics/toJSON%2C%20fromJSON) function, and use the same default serialization behavior as [Shiny](https://shiny.rstudio.com) and [htmlwidgets](http://www.htmlwidgets.org/develop_advanced.html#custom-json-serializer). 17 | 18 | This corresponds to the following call to `jsonlite::toJSON()`: 19 | 20 | ```r 21 | jsonlite::toJSON( 22 | dataframe = "columns", null = "null", na = "null", auto_unbox = TRUE, 23 | digits = getOption("shiny.json.digits", 16), use_signif = TRUE, force = TRUE, 24 | POSIXt = "ISO8601", UTC = TRUE, rownames = FALSE, keep_vec_names = TRUE, 25 | json_verabitm = TRUE 26 | ) 27 | ``` 28 | 29 | #### Data frames 30 | 31 | Data frames are serialized with a columns orientation as that is a more compact over the wire representation than rows orientation. When the data frame gets to the client **r2d3** calls the [HTMLWidgets.dataframeToD3()](http://www.htmlwidgets.org/develop_advanced.html#htmlwidgets.dataframetod3) method to transform the data to a D3-friendly rows orientation. 32 | 33 | Here is an example of the JSON columns-based representation of an R data frame: 34 | 35 | ``` 36 | { 37 | "Sepal.Length": [5.1, 4.9, 4.7], 38 | "Sepal.Width": [3.5, 3, 3.2], 39 | "Petal.Length": [1.4, 1.4, 1.3], 40 | "Petal.Width": [0.2, 0.2, 0.2], 41 | "Species": ["setosa", "setosa", "setosa"] 42 | } 43 | ``` 44 | 45 | After we apply `HTMLWidgets.dataframeToD3()`, it will become: 46 | 47 | ``` 48 | [ 49 | { 50 | "Sepal.Length": 5.1, 51 | "Sepal.Width": 3.5, 52 | "Petal.Length": 1.4, 53 | "Petal.Width": 0.2, 54 | "Species": "setosa" 55 | }, 56 | { 57 | "Sepal.Length": 4.9, 58 | "Sepal.Width": 3, 59 | "Petal.Length": 1.4, 60 | "Petal.Width": 0.2, 61 | "Species": "setosa" 62 | }, 63 | { 64 | "Sepal.Length": 4.7, 65 | "Sepal.Width": 3.2, 66 | "Petal.Length": 1.3, 67 | "Petal.Width": 0.2, 68 | "Species": "setosa" 69 | } 70 | ] 71 | ``` 72 | 73 | ## Custom conversion 74 | 75 | If you don't like the default JSON conversion provided for `data`, you can write your own function that uses [jsonlite](https://CRAN.R-project.org/package=jsonlite) to perform a custom conversion. For example: 76 | 77 | ```{r} 78 | data_to_json <- function(data) { 79 | jsonlite::toJSON(data, dataframe = "rows", auto_unbox = FALSE, rownames = TRUE) 80 | } 81 | 82 | r2d3(data = data_to_json(x), script = "barchart.js") 83 | ``` 84 | 85 | When a value returned from `jsonlite::toJSON()` is passed as the `data` argument **r2d3** won't attempt any additional conversion or transformation of the value. 86 | 87 | 88 | 89 | ## S3 conversion method 90 | 91 | You can implement the `as_d3_data()` S3 method to provide custom converters for any R class. For example, you could create an S3 method for the `igraph` class to convert data into a JSON that is optimized for rendering by a D3 network visualization: 92 | 93 | ```{r} 94 | as_d3_data.igraph <- function(x, ...) { 95 | # code to serialize igraph to D3 network friendly JSON 96 | } 97 | ``` 98 | 99 | -------------------------------------------------------------------------------- /vignettes/dependencies.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "CSS & JavaScript Dependencies" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{CSS & JavaScript Dependencies} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Overview 15 | 16 | Often times a D3 visualization will require additional components such as CSS styles, JavaScript helper functions, or even entire JavaScript libraries. This article describes how to include these dependencies along with your visualization. 17 | 18 | ## CSS Styles 19 | 20 | It's common to require a few CSS styles when creating a visualization. By convention, if you include a CSS file with the same base filename as your D3 script file it will automatically be included. For example, consider a D3 script "barchart.js" within a sub-directory: 21 | 22 | ```bash 23 | barchart.js 24 | barchart.css 25 | ``` 26 | 27 | If you render the "barchart.js" script like this: 28 | 29 | ```{r} 30 | r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 31 | ``` 32 | 33 | Then the "barchart.css" file will be automatically included. 34 | 35 | You can also name a CSS file "styles.css" (useful if you want multiple visualizations to share styles) and it will also be automatically included: 36 | 37 | ```bash 38 | barchart.js 39 | styles.css 40 | ``` 41 | 42 | Finally, you can explicitly include a CSS file of any name via the `css` parameter of `r2d3()`: 43 | 44 | ```{r} 45 | r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js", css = "theme.css") 46 | ``` 47 | 48 | ## d3-jetpack 49 | 50 | The **r2d3** package has built-in support for [d3-jetpack](https://github.com/gka/d3-jetpack), a set of convenience wrappers designed to speed up daily work with d3. You can include d3-jetpack in your visualization by specifing "d3-jetpack" in the `dependencies` parameter of `r2d3()`. For example: 51 | 52 | ```{r} 53 | r2d3( 54 | data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 55 | script = "barchart.js", dependencies = "d3-jetpack" 56 | ) 57 | ``` 58 | 59 | One commonly used d3-jetpack function is [`d3.conventions()`](https://github.com/gka/d3-jetpack#conventions). To use `d3.conventions()` with **r2d3** you need to forward the root element and size information provided automatically by **r2d3** to `d3.conventions()` as follows: 60 | 61 | ```{js, eval=FALSE, echo=TRUE} 62 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), dependencies = "d3-jetpack" 63 | 64 | var { svg, margin, height, width } = d3.conventions({ 65 | sel: svg, 66 | totalWidth: width, 67 | totalHeight: height, 68 | margin: { top: 10, bottom: 10 } 69 | }); 70 | 71 | var barHeight = Math.ceil(height / data.length); 72 | 73 | svg.selectAll('rect') 74 | .data(data) 75 | .enter().append('rect') 76 | .attr('width', function(d) { return d * width; }) 77 | .attr('height', barHeight) 78 | .attr('y', function(d, i) { return i * barHeight; }) 79 | .attr('fill', 'steelblue'); 80 | ``` 81 | 82 | 83 | ## JavaScript 84 | 85 | If your visualization depends on additional JavaScript files (e.g. a d3 extension or some common code that you want to re-use) you can specify this using the `dependencies` parameter of `r2d3()`. For example: 86 | 87 | ```{r} 88 | r2d3( 89 | data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 90 | script = "barchart.js", dependencies = "utils.js" 91 | ) 92 | ``` 93 | 94 | 95 | ## External Libraries 96 | 97 | You can include entire external libraries as dependencies by passing an "html_dependency" object created using the `htmltools::htmlDependency()` function. For example, here's how you would include the version of jQuery bundled with the **rmarkdown** package: 98 | 99 | ```{r} 100 | r2d3( 101 | data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), 102 | script = "barchart.js", dependencies = rmarkdown::html_dependency_jquery() 103 | ) 104 | ``` 105 | 106 | Note that you can pass a list of multiple dependencies (either paths to JavaScript files or "html_dependencies" objects) via the `dependencies` argument. 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /vignettes/development_and_debugging.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Development and Debugging" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Development and Debugging} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Overview 15 | 16 | This article describes recommend workflow for developing D3 visualizations, including: 17 | 18 | 1) Using integrated tools for **r2d3** within RStudio to preview visualizations; and 19 | 20 | 2) Using browser debugging tools to pinpoint errors in your code. 21 | 22 | Note that the development tools described above are only fully supported within the [RStudio v1.2 preview release](https://rstudio.com/products/rstudio/download/) (as opposed to the current stable release) so you should download the daily build before trying these features out. 23 | 24 | ## RStudio Preview 25 | 26 | The [RStudio v1.2 preview release](https://rstudio.com/products/rstudio/download/) includes support for previewing D3 scripts as you write them. To try this out, create a D3 script using the new file menu: 27 | 28 | 29 | 30 | A simple template for a D3 script (the barchart.js example shown above) is provided by default. You can use the **Preview** command (Ctrl+Shift+Enter) to render the visualization: 31 | 32 | 33 | 34 | You might wonder where the data comes from for the preview. Note that there is a special comment at the top of the D3 script: 35 | 36 | ```js 37 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 38 | ``` 39 | 40 | This comment enables you to specify the data (along with any other arguments to the `r2d3()` function) to use for the preview. 41 | 42 | ### Error Navigation 43 | 44 | If an error occurs while rendering a D3 visualization using preview mode then the error will be displayed in the Viewer pane: 45 | 46 | 47 | 48 | The source pane will also be navigated to the location in your script where the error occurred. 49 | 50 | ### Viewer Options 51 | 52 | The `viewer` argument to the `r2d3()` function enables you to customize how D3 visualizations are viewed when printed from within the RStudio console. The following options are available: 53 | 54 | | Option | Description | 55 | |---------------------|---------------------| 56 | | `viewer = "internal"` | (Default). Display within the RStudio Viewer pane. | 57 | | `viewer = "external"` | Display within an external RStudio Viewer window. | 58 | | `viewer = "browser"` | Display within an external web browser (e.g. Chrome). | 59 | 60 | The "external" option is useful if your visualization requires more space than an RStudio pane affords. The "browser" option is useful if you need access to browser debugging tools during development. 61 | 62 | Here's an example of adding the `viewer` argument to the preview comment at the top of a D3 script: 63 | 64 | ```js 65 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), viewer="external" 66 | ``` 67 | 68 | ## Console Logging 69 | 70 | When troubleshooting a visualization it is also often useful to print diagnostics to the JavaScript console. This is usually accomplished by calling `console.log()` with a message that can help you troubleshoot the problem at hand. 71 | 72 | For instance, the following script does not trigger any runtime errors but also does not render anything at all: 73 | 74 | ```{js} 75 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 76 | 77 | var barHeight = Math.ceil(height / data.length); 78 | 79 | svg.selectAll('rect') 80 | .data(data) 81 | .enter().append('rect') 82 | .attr('width', function(d) { return d; }) 83 | .attr('height', barHeight) 84 | .attr('y', function(d, i) { return i * barHeight; }) 85 | .attr('fill', 'steelblue'); 86 | ``` 87 | 88 | 89 | In this case, we think the problem might be with the `width` so we print this value to the console as follows: 90 | 91 | ```{js} 92 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 93 | 94 | var barHeight = Math.ceil(height / data.length); 95 | 96 | svg.selectAll('rect') 97 | .data(data) 98 | .enter().append('rect') 99 | .attr('width', function(d) { 100 | console.log("The width has value " + d) 101 | return d * width * 0; 102 | }) 103 | .attr('height', barHeight) 104 | .attr('y', function(d, i) { return i * barHeight; }) 105 | .attr('fill', 'steelblue'); 106 | ``` 107 | 108 | **r2d3** renders renders the JavaScript console output directly into the visualization. For this example, this will show that the `width` is `0.2`, which is too small to be visible: 109 | 110 | 111 | 112 | ## Debugging 113 | 114 | If you need to debug errors or other unexpected behavior in your D3 script, you can use the *Show in new window* window command within the RStudio Viewer to show the visualization in an external web browser: 115 | 116 | 117 | 118 | It's also possible to add the `viewer="browser"` option to your `!preview` comment at the top of the file to skip the RStudio Viewer and route the visualization directly to an external browser: 119 | 120 | ```js 121 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), viewer="browser" 122 | ``` 123 | 124 | Once you've opened the visualization you can use your browser **Developer Tools** to do additional debugging (typically you'll need to reload the page after you've opened the developer tools pane in order to reproduce the error): 125 | 126 | 127 | 128 | Your original D3 script and dependencies are available as a `r2d3-script-###` script which can be used to set breakpoints or inspect errors in detail: 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /vignettes/gallery.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | knitr::opts_chunk$set(echo = FALSE) 7 | source("utils.R") 8 | ``` 9 | 10 | The gallery includes several examples adapted for use with **r2d3** from . Other good sources of D3 examples are and . 11 | 12 | To learn more about how to code your own D3 visualizations, check out the article on [Learning D3](learning_d3.html). 13 | 14 | 15 | 16 | 42 | 68 | 94 | 120 | 121 | 122 | ```{js} 123 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 124 | ``` 125 | 126 | -------------------------------------------------------------------------------- /vignettes/gallery/bubbles/bubbles.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("flare.csv"), d3_version = 4 2 | 3 | // Based on https://bl.ocks.org/mbostock/4063269 4 | 5 | // Initialization 6 | svg.attr("font-family", "sans-serif") 7 | .attr("font-size", "8") 8 | .attr("text-anchor", "middle"); 9 | 10 | var svgSize = 600; 11 | var pack = d3.pack() 12 | .size([svgSize, svgSize]) 13 | .padding(1.5); 14 | 15 | var format = d3.format(",d"); 16 | var color = d3.scaleOrdinal(d3.schemeCategory20c); 17 | 18 | var group = svg.append("g"); 19 | 20 | // Resize 21 | r2d3.onResize(function(width, height) { 22 | var minSize = Math.min(width, height); 23 | var scale = minSize / svgSize; 24 | 25 | group.attr("transform", function(d) { 26 | return "" + 27 | "translate(" + (width - minSize) / 2 + "," + (height - minSize) / 2 + ")," + 28 | "scale(" + scale + "," + scale + ")"; 29 | }); 30 | }); 31 | 32 | // Rendering 33 | r2d3.onRender(function(data, svg, width, height, options) { 34 | var root = d3.hierarchy({children: data}) 35 | .sum(function(d) { return d.value; }) 36 | .each(function(d) { 37 | if (id = d.data.id) { 38 | var id, i = id.lastIndexOf("."); 39 | d.id = id; 40 | d.package = id.slice(0, i); 41 | d.class = id.slice(i + 1); 42 | } 43 | }); 44 | 45 | var node = group.selectAll(".node") 46 | .data(pack(root).leaves()) 47 | .enter().append("g") 48 | .attr("class", "node") 49 | .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 50 | 51 | node.append("circle") 52 | .attr("id", function(d) { return d.id; }) 53 | .attr("r", function(d) { return d.r; }) 54 | .style("fill", function(d) { return color(d.package); }); 55 | 56 | node.append("clipPath") 57 | .attr("id", function(d) { return "clip-" + d.id; }) 58 | .append("use") 59 | .attr("xlink:href", function(d) { return "#" + d.id; }); 60 | 61 | node.append("text") 62 | .attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }) 63 | .selectAll("tspan") 64 | .data(function(d) { return d.class.split(/(?=[A-Z][^A-Z])/g); }) 65 | .enter().append("tspan") 66 | .attr("x", 0) 67 | .attr("y", function(d, i, nodes) { return 13 + (i - nodes.length / 2 - 0.5) * 10; }) 68 | .text(function(d) { return d; }); 69 | 70 | node.append("title") 71 | .text(function(d) { return d.id + "\n" + format(d.value); }); 72 | 73 | r2d3.resize(width, height); 74 | }); 75 | -------------------------------------------------------------------------------- /vignettes/gallery/bubbles/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: bubbles" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "bubbles.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "bubbles.js", width="100%") 45 | ``` 46 | 47 | 48 | #### bubbles.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("bubbles.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | 57 |
58 | 59 |
60 | 61 | 62 | ```{js} 63 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 64 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 65 | $('a.list-group-item[href="../bubbles/"]').addClass('active'); 66 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 67 | ``` 68 | -------------------------------------------------------------------------------- /vignettes/gallery/bullets/bullets.css: -------------------------------------------------------------------------------- 1 | 2 | .bullet { font: 10px sans-serif; } 3 | .bullet .marker { stroke: #000; stroke-width: 2px; } 4 | .bullet .tick line { stroke: #666; stroke-width: .5px; } 5 | .bullet .range.s0 { fill: #eee; } 6 | .bullet .range.s1 { fill: #ddd; } 7 | .bullet .range.s2 { fill: #ccc; } 8 | .bullet .measure.s0 { fill: lightsteelblue; } 9 | .bullet .measure.s1 { fill: steelblue; } 10 | .bullet .title { font-size: 14px; font-weight: bold; } 11 | .bullet .subtitle { fill: #999; } 12 | 13 | .bullets { line-height: 0; } 14 | -------------------------------------------------------------------------------- /vignettes/gallery/bullets/bullets.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("bullets.json"), d3_version = 3, container = "div", dependencies = c("d3_bullet.js") 2 | 3 | // Based on https://bl.ocks.org/mbostock/4061961 4 | 5 | var margin = {top: 10, right: 40, bottom: 40, left: 130}; 6 | var width = width - margin.left - margin.right; 7 | var height = Math.floor(height / data.length) - margin.top - margin.bottom; 8 | 9 | div.attr("class", "bullets"); 10 | 11 | var chart = d3.bullet(margin.bottom) 12 | .width(width) 13 | .height(height); 14 | 15 | var svg = div.selectAll("svg") 16 | .data(data) 17 | .enter().append("svg") 18 | .attr("class", "bullet") 19 | .attr("width", width + margin.left + margin.right) 20 | .attr("height", height + margin.top + margin.bottom) 21 | .append("g") 22 | .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 23 | .call(chart); 24 | 25 | var title = svg.append("g") 26 | .style("text-anchor", "end") 27 | .attr("transform", "translate(-6," + height / 2 + ")"); 28 | 29 | title.append("text") 30 | .attr("class", "title") 31 | .text(function(d) { return d.title; }); 32 | 33 | title.append("text") 34 | .attr("class", "subtitle") 35 | .attr("dy", "1em") 36 | .text(function(d) { return d.subtitle; }); 37 | 38 | d3.selectAll("button").on("click", function() { 39 | svg.datum(randomize).call(chart.duration(1000)); // TODO automatic transition 40 | }); 41 | 42 | function randomize(d) { 43 | if (!d.randomizer) d.randomizer = randomizer(d); 44 | d.ranges = d.ranges.map(d.randomizer); 45 | d.markers = d.markers.map(d.randomizer); 46 | d.measures = d.measures.map(d.randomizer); 47 | return d; 48 | } 49 | 50 | function randomizer(d) { 51 | var k = d3.max(d.ranges) * .2; 52 | return function(d) { 53 | return Math.max(0, d + k * (Math.random() - .5)); 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /vignettes/gallery/bullets/bullets.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"title":"Revenue","subtitle":"US$, in thousands","ranges":[150,225,300],"measures":[220,270],"markers":[250]}, 3 | {"title":"Profit","subtitle":"%","ranges":[20,25,30],"measures":[21,23],"markers":[26]}, 4 | {"title":"Order Size","subtitle":"US$, average","ranges":[350,500,600],"measures":[100,320],"markers":[550]}, 5 | {"title":"New Customers","subtitle":"count","ranges":[1400,2000,2500],"measures":[1000,1650],"markers":[2100]}, 6 | {"title":"Satisfaction","subtitle":"out of 5","ranges":[3.5,4.25,5],"measures":[3.2,4.7],"markers":[4.4]} 7 | ] -------------------------------------------------------------------------------- /vignettes/gallery/bullets/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: bullets" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("bullets.json"), d3_version = 3, container = "div", dependencies = c("d3_bullet.js"), script = "bullets.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("bullets.json"), d3_version = 3, container = "div", dependencies = c("d3_bullet.js"), script = "bullets.js", width="100%") 45 | ``` 46 | 47 | 48 | #### bullets.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("bullets.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### d3_bullet.js 57 | 58 | ```{r, results='asis'} 59 | cat("```js\n") 60 | writeLines(readLines("d3_bullet.js", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | #### bullets.css 65 | 66 | ```{r, results='asis'} 67 | cat("```css\n") 68 | writeLines(readLines("bullets.css", warn = FALSE)) 69 | cat("```\n") 70 | ``` 71 | 72 | 73 |
74 | 75 |
76 | 77 | 78 | ```{js} 79 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 80 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 81 | $('a.list-group-item[href="../bullets/"]').addClass('active'); 82 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 83 | ``` 84 | -------------------------------------------------------------------------------- /vignettes/gallery/calendar/calendar.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("dji-latest.csv"), d3_version = 4, container = "div", options = list(start = 2006, end = 2011) 2 | 3 | // Based on https://bl.ocks.org/mbostock/4063318 4 | 5 | var height = height / (options.end - options.start), 6 | cellSize = height / 8; 7 | 8 | var formatPercent = d3.format(".1%"); 9 | 10 | var color = d3.scaleQuantize() 11 | .domain([-0.05, 0.05]) 12 | .range(["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"]); 13 | 14 | var svg = div 15 | .style("line-height", "0") 16 | .selectAll("svg") 17 | .data(d3.range(options.start, options.end)) 18 | .enter().append("svg") 19 | .attr("width", width) 20 | .attr("height", height) 21 | .append("g") 22 | .attr("transform", "translate(" + cellSize * 3.5 + "," + (height - cellSize * 7 - 1) + ")"); 23 | 24 | svg.append("text") 25 | .attr("transform", "translate(-" + (6 * height / 60) + "," + cellSize * 3.5 + ")rotate(-90)") 26 | .attr("font-family", "sans-serif") 27 | .attr("font-size", 2 + 8 * height / 60) 28 | .attr("text-anchor", "middle") 29 | .text(function(d) { return d; }); 30 | 31 | var rect = svg.append("g") 32 | .attr("fill", "none") 33 | .attr("stroke", "#ccc") 34 | .attr("stroke-width", "0.25") 35 | .selectAll("rect") 36 | .data(function(d) { return d3.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1)); }) 37 | .enter().append("rect") 38 | .attr("width", cellSize) 39 | .attr("height", cellSize) 40 | .attr("x", function(d) { return d3.timeWeek.count(d3.timeYear(d), d) * cellSize; }) 41 | .attr("y", function(d) { return d.getDay() * cellSize; }) 42 | .datum(d3.timeFormat("%Y-%m-%d")); 43 | 44 | svg.append("g") 45 | .attr("fill", "none") 46 | .attr("stroke", "#000") 47 | .attr("stroke-width", "0.25") 48 | .selectAll("path") 49 | .data(function(d) { return d3.timeMonths(new Date(d, 0, 1), new Date(d + 1, 0, 1)); }) 50 | .enter().append("path") 51 | .attr("d", pathMonth); 52 | 53 | r2d3.onRender(function(csv, div, width, height, options) { 54 | var data = d3.nest() 55 | .key(function(d) { return d.Date; }) 56 | .rollup(function(d) { return (d[0].Close - d[0].Open) / d[0].Open; }) 57 | .object(csv); 58 | 59 | rect.filter(function(d) { return d in data; }) 60 | .attr("fill", function(d) { return color(data[d]); }) 61 | .append("title") 62 | .text(function(d) { return d + ": " + formatPercent(data[d]); }); 63 | }); 64 | 65 | function pathMonth(t0) { 66 | var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0), 67 | d0 = t0.getDay(), w0 = d3.timeWeek.count(d3.timeYear(t0), t0), 68 | d1 = t1.getDay(), w1 = d3.timeWeek.count(d3.timeYear(t1), t1); 69 | return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize 70 | + "H" + w0 * cellSize + "V" + 7 * cellSize 71 | + "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize 72 | + "H" + (w1 + 1) * cellSize + "V" + 0 73 | + "H" + (w0 + 1) * cellSize + "Z"; 74 | } 75 | -------------------------------------------------------------------------------- /vignettes/gallery/calendar/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: calendar" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("dji-latest.csv"), d3_version = 4, container = "div", options = list(start = 2006, end = 2011), script = "calendar.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("dji-latest.csv"), d3_version = 4, container = "div", options = list(start = 2006, end = 2011), script = "calendar.js", width="100%") 45 | ``` 46 | 47 | 48 | #### calendar.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("calendar.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | 57 |
58 | 59 |
60 | 61 | 62 | ```{js} 63 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 64 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 65 | $('a.list-group-item[href="../calendar/"]').addClass('active'); 66 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 67 | ``` 68 | -------------------------------------------------------------------------------- /vignettes/gallery/cartogram/cartogram.css: -------------------------------------------------------------------------------- 1 | .land { 2 | fill: #fff; 3 | stroke: #ccc; 4 | } 5 | 6 | .state { 7 | fill: #ccc; 8 | stroke: #666; 9 | } 10 | -------------------------------------------------------------------------------- /vignettes/gallery/cartogram/cartogram.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("us.json"), d3_version = 3, dependencies = "topojson.min.js" 2 | 3 | // Based on https://bl.ocks.org/mbostock/4055908 4 | 5 | // Ratio of Obese (BMI >= 30) in U.S. Adults, CDC 2008 6 | var valueById = [ 7 | NaN, .187, .198, NaN, .133, .175, .151, NaN, .100, .125, 8 | .171, NaN, .172, .133, NaN, .108, .142, .167, .201, .175, 9 | .159, .169, .177, .141, .163, .117, .182, .153, .195, .189, 10 | .134, .163, .133, .151, .145, .130, .139, .169, .164, .175, 11 | .135, .152, .169, NaN, .132, .167, .139, .184, .159, .140, 12 | .146, .157, NaN, .139, .183, .160, .143 13 | ]; 14 | 15 | var path = d3.geo.path(); 16 | 17 | var root = svg 18 | .attr("width", "100%") 19 | .append("g"); 20 | 21 | r2d3.onRender(function(us, svg, width, height, options) { 22 | root.attr("transform", "scale(" + width / 900 + ")"); 23 | 24 | root.append("path") 25 | .datum(topojson.feature(us, us.objects.land)) 26 | .attr("class", "land") 27 | .attr("d", path); 28 | 29 | root.selectAll(".state") 30 | .data(topojson.feature(us, us.objects.states).features) 31 | .enter().append("path") 32 | .attr("class", "state") 33 | .attr("d", path) 34 | .attr("transform", function(d) { 35 | var centroid = path.centroid(d), 36 | x = centroid[0], 37 | y = centroid[1]; 38 | return "translate(" + x + "," + y + ")" 39 | + "scale(" + Math.sqrt(valueById[d.id] * 5 || 0) + ")" 40 | + "translate(" + -x + "," + -y + ")"; 41 | }) 42 | .style("stroke-width", function(d) { 43 | return 1 / Math.sqrt(valueById[d.id] * 5 || 1); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /vignettes/gallery/cartogram/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: cartogram" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("us.json"), d3_version = 3, dependencies = "topojson.min.js", script = "cartogram.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("us.json"), d3_version = 3, dependencies = "topojson.min.js", script = "cartogram.js", width="100%") 45 | ``` 46 | 47 | 48 | #### cartogram.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("cartogram.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### cartogram.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("cartogram.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../cartogram/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/cartogram/topojson.min.js: -------------------------------------------------------------------------------- 1 | // https://github.com/topojson/topojson-client Version 1.8.0. Copyright 2016 Mike Bostock. 2 | !function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.topojson=n.topojson||{})}(this,function(n){"use strict";function t(n){if(!n)return h;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0),n[0]=(t+=n[0])*e+i,n[1]=(r+=n[1])*o+u}}function r(n){if(!n)return h;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0);var c=Math.round((n[0]-i)/e),a=Math.round((n[1]-u)/o);n[0]=c-t,n[1]=a-r,t=c,r=a}}function e(n,t){for(var r,e=n.length,o=e-t;o<--e;)r=n[o],n[o++]=n[e],n[e]=r}function o(n,t){for(var r=0,e=n.length;r>>1;n[o]1){var c,a=[],s={LineString:o,MultiLineString:i,Polygon:i,MultiPolygon:function(n){n.forEach(i)}};u(t),a.forEach(arguments.length<3?function(n){f.push(n[0].i)}:function(n){r(n[0].g,n[n.length-1].g)&&f.push(n[0].i)})}else for(var l=0,h=n.arcs.length;l1)for(var u,f,c=1,a=e(i[0]);ca&&(f=i[0],i[0]=i[c],i[c]=f,a=u);return i})}}function l(n,t){return n[1][2]-t[1][2]}var h=function(){},p=function(n,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return i(n,t)})}:i(n,t)},v=function(n,t){function r(t){var r,e=n.arcs[t<0?~t:t],o=e[0];return n.transform?(r=[0,0],e.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=e[e.length-1],t<0?[r,o]:[o,r]}function e(n,t){for(var r in n){var e=n[r];delete t[e.start],delete e.start,delete e.end,e.forEach(function(n){o[n<0?~n:n]=1}),f.push(e)}}var o={},i={},u={},f=[],c=-1;return t.forEach(function(r,e){var o,i=n.arcs[r<0?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++c],t[c]=r,t[e]=o)}),t.forEach(function(n){var t,e,o=r(n),f=o[0],c=o[1];if(t=u[f])if(delete u[t.end],t.push(n),t.end=c,e=i[c]){delete i[e.start];var a=e===t?t:t.concat(e);i[a.start=t.start]=u[a.end=e.end]=a}else i[t.start]=u[t.end]=t;else if(t=i[c])if(delete i[t.start],t.unshift(n),t.start=f,e=u[f]){delete u[e.end];var s=e===t?t:e.concat(t);i[s.start=e.start]=u[s.end=t.end]=s}else i[t.start]=u[t.end]=t;else t=[n],i[t.start=f]=u[t.end=c]=t}),e(u,i),e(i,u),t.forEach(function(n){o[n<0?~n:n]||f.push([n])}),f},g=function(n){return u(n,f.apply(this,arguments))},d=function(n){return u(n,s.apply(this,arguments))},y=function(n){function t(n,t){n.forEach(function(n){n<0&&(n=~n);var r=i[n];r?r.push(t):i[n]=[t]})}function r(n,r){n.forEach(function(n){t(n,r)})}function e(n,t){"GeometryCollection"===n.type?n.geometries.forEach(function(n){e(n,t)}):n.type in f&&f[n.type](n.arcs,t)}var i={},u=n.map(function(){return[]}),f={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(n,t){n.forEach(function(n){r(n,t)})}};n.forEach(e);for(var c in i)for(var a=i[c],s=a.length,l=0;l0;){var r=(t+1>>1)-1,o=e[r];if(l(n,o)>=0)break;e[o._=t]=o,e[n._=t=r]=n}}function t(n,t){for(;;){var r=t+1<<1,i=r-1,u=t,f=e[u];if(i0&&(n=e[o],t(e[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(e[u]===r)return u!==--o&&(i=e[o],(l(i,r)<0?n:t)(e[i._=u]=i,u)),u},r},E=function(n,e){function o(n){f.remove(n),n[1][2]=e(n),f.push(n)}var i=t(n.transform),u=r(n.transform),f=m();return null==e&&(e=c),n.arcs.forEach(function(n){var t,r,c,a,s=[],l=0;for(r=0,c=n.length;r Math.PI ? "rotate(180) translate(-16)" : null; }) 55 | .style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) 56 | .text(function(d) { return formatValue(d.value); }); 57 | 58 | g.append("g") 59 | .attr("class", "ribbons") 60 | .selectAll("path") 61 | .data(function(chords) { return chords; }) 62 | .enter().append("path") 63 | .attr("d", ribbon) 64 | .style("fill", function(d) { return color(d.target.index); }) 65 | .style("stroke", function(d) { return d3.rgb(color(d.target.index)).darker(); }); 66 | 67 | // Returns an array of tick angles and values for a given group and step. 68 | function groupTicks(d, step) { 69 | var k = (d.endAngle - d.startAngle) / d.value; 70 | return d3.range(0, d.value, step).map(function(value) { 71 | return {value: value, angle: value * k + d.startAngle}; 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /vignettes/gallery/chord/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: chord" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = matrix(round(runif(16, 1, 10000)), ncol = 4, nrow = 4), script = "chord.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = matrix(round(runif(16, 1, 10000)), ncol = 4, nrow = 4), script = "chord.js", width="100%") 45 | ``` 46 | 47 | 48 | #### chord.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("chord.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### chord.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("chord.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../chord/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/circlepacking/circlepacking.css: -------------------------------------------------------------------------------- 1 | circle { 2 | fill: rgb(31, 119, 180); 3 | fill-opacity: .25; 4 | stroke: rgb(31, 119, 180); 5 | stroke-width: 1px; 6 | } 7 | 8 | .leaf circle { 9 | fill: #ff7f0e; 10 | fill-opacity: 1; 11 | } 12 | 13 | text { 14 | font: sans-serif; 15 | text-anchor: middle; 16 | } 17 | -------------------------------------------------------------------------------- /vignettes/gallery/circlepacking/circlepacking.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("flare.json"), d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063530 4 | 5 | var diameter = Math.min(width, height), 6 | g = svg.append("g").attr( 7 | "transform", 8 | "translate(" + (width - diameter) / 2 + "," + (height - diameter) / 2 + ")"), 9 | format = d3.format(",d"); 10 | 11 | var pack = d3.pack() 12 | .size([diameter - 4, diameter - 4]); 13 | 14 | r2d3.onRender(function(root, svg, width, height, options) { 15 | root = d3.hierarchy(root) 16 | .sum(function(d) { return d.size; }) 17 | .sort(function(a, b) { return b.value - a.value; }); 18 | 19 | var node = g.selectAll(".node") 20 | .data(pack(root).descendants()) 21 | .enter().append("g") 22 | .attr("class", function(d) { return d.children ? "node" : "leaf node"; }) 23 | .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 24 | 25 | node.append("title") 26 | .text(function(d) { return d.data.name + "\n" + format(d.value); }); 27 | 28 | node.append("circle") 29 | .attr("r", function(d) { return d.r; }); 30 | 31 | node.filter(function(d) { return !d.children; }).append("text") 32 | .attr("dy", "0.3em") 33 | .attr("font-size", Math.max(width, height) / 100) 34 | .text(function(d) { return d.data.name.substring(0, d.r / 3); }); 35 | }); 36 | -------------------------------------------------------------------------------- /vignettes/gallery/circlepacking/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: circlepacking" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 4, script = "circlepacking.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 4, script = "circlepacking.js", width="100%") 45 | ``` 46 | 47 | 48 | #### circlepacking.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("circlepacking.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### circlepacking.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("circlepacking.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../circlepacking/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/dendogram/dendogram.css: -------------------------------------------------------------------------------- 1 | .node circle { 2 | fill: #999; 3 | } 4 | 5 | .node text { 6 | font-family: sans-serif; 7 | } 8 | 9 | .node--internal circle { 10 | fill: #555; 11 | } 12 | 13 | .node--internal text { 14 | text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; 15 | } 16 | 17 | .link { 18 | fill: none; 19 | stroke: #555; 20 | stroke-opacity: 0.4; 21 | stroke-width: 1.5px; 22 | } 23 | -------------------------------------------------------------------------------- /vignettes/gallery/dendogram/dendogram.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("flare.csv"), d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063570 4 | 5 | var g = svg.append("g").attr("transform", "translate(40,0)"); 6 | 7 | var tree = d3.cluster() 8 | .size([height, width - 160]); 9 | 10 | var stratify = d3.stratify() 11 | .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); 12 | 13 | r2d3.onRender(function(data, svg, w, h, options) { 14 | var root = stratify(data) 15 | .sort(function(a, b) { return (a.height - b.height) || a.id.localeCompare(b.id); }); 16 | 17 | tree(root); 18 | 19 | var link = g.selectAll(".link") 20 | .data(root.descendants().slice(1)) 21 | .enter().append("path") 22 | .attr("class", "link") 23 | .attr("d", function(d) { 24 | return "M" + d.y + "," + d.x 25 | + "C" + (d.parent.y + 100) + "," + d.x 26 | + " " + (d.parent.y + 100) + "," + d.parent.x 27 | + " " + d.parent.y + "," + d.parent.x; 28 | }); 29 | 30 | var node = g.selectAll(".node") 31 | .data(root.descendants()) 32 | .enter().append("g") 33 | .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) 34 | .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) 35 | 36 | node.append("circle") 37 | .attr("r", 2.5); 38 | 39 | node.append("text") 40 | .attr("dy", 3) 41 | .attr("font-size", 2 + 4 * height / 1000) 42 | .attr("x", function(d) { return d.children ? -8 : 8; }) 43 | .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) 44 | .text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); }); 45 | }); 46 | -------------------------------------------------------------------------------- /vignettes/gallery/dendogram/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: dendogram" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "dendogram.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "dendogram.js", width="100%") 45 | ``` 46 | 47 | 48 | #### dendogram.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("dendogram.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### dendogram.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("dendogram.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../dendogram/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/forcegraph/forcegraph.css: -------------------------------------------------------------------------------- 1 | .links line { 2 | stroke: #999; 3 | stroke-opacity: 0.6; 4 | } 5 | 6 | .nodes circle { 7 | stroke: #fff; 8 | stroke-width: 1.5px; 9 | } 10 | -------------------------------------------------------------------------------- /vignettes/gallery/forcegraph/forcegraph.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("miserables.json"), d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063570 4 | 5 | var color = d3.scaleOrdinal(d3.schemeCategory20); 6 | var radius = 5; 7 | 8 | var simulation = d3.forceSimulation() 9 | .force("link", d3.forceLink().id(function(d) { return d.id; })) 10 | .force("charge", d3.forceManyBody()) 11 | .force("center", d3.forceCenter(width / 2, height / 2)); 12 | 13 | r2d3.onRender(function(graph, svg, width, height, options) { 14 | var link = svg.append("g") 15 | .attr("class", "links") 16 | .selectAll("line") 17 | .data(graph.links) 18 | .enter().append("line") 19 | .attr("stroke-width", function(d) { return Math.sqrt(d.value); }); 20 | 21 | var node = svg.append("g") 22 | .attr("class", "nodes") 23 | .selectAll("circle") 24 | .data(graph.nodes) 25 | .enter().append("circle") 26 | .attr("r", radius) 27 | .attr("fill", function(d) { return color(d.group); }) 28 | .call(d3.drag() 29 | .on("start", dragstarted) 30 | .on("drag", dragged) 31 | .on("end", dragended)); 32 | 33 | node.append("title") 34 | .text(function(d) { return d.id; }); 35 | 36 | simulation 37 | .nodes(graph.nodes) 38 | .on("tick", ticked); 39 | 40 | simulation.force("link") 41 | .links(graph.links); 42 | 43 | function ticked() { 44 | //constrains the nodes to be within a box 45 | node 46 | .attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); }) 47 | .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); }); 48 | 49 | link 50 | .attr("x1", function(d) { return d.source.x; }) 51 | .attr("y1", function(d) { return d.source.y; }) 52 | .attr("x2", function(d) { return d.target.x; }) 53 | .attr("y2", function(d) { return d.target.y; }); 54 | 55 | node 56 | .attr("cx", function(d) { return d.x; }) 57 | .attr("cy", function(d) { return d.y; }); 58 | } 59 | }); 60 | 61 | function dragstarted(d) { 62 | if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 63 | d.fx = d.x; 64 | d.fy = d.y; 65 | } 66 | 67 | function dragged(d) { 68 | d.fx = d3.event.x; 69 | d.fy = d3.event.y; 70 | } 71 | 72 | function dragended(d) { 73 | if (!d3.event.active) simulation.alphaTarget(0); 74 | d.fx = null; 75 | d.fy = null; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /vignettes/gallery/forcegraph/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: forcegraph" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("miserables.json"), d3_version = 4, script = "forcegraph.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("miserables.json"), d3_version = 4, script = "forcegraph.js", width="100%") 45 | ``` 46 | 47 | 48 | #### forcegraph.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("forcegraph.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### forcegraph.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("forcegraph.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../forcegraph/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/morley/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: morley" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("morley.csv"), d3_version = 3, container = "div", dependencies = c("box.js"), script = "morley.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("morley.csv"), d3_version = 3, container = "div", dependencies = c("box.js"), script = "morley.js", width="100%") 45 | ``` 46 | 47 | 48 | #### morley.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("morley.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### box.js 57 | 58 | ```{r, results='asis'} 59 | cat("```js\n") 60 | writeLines(readLines("box.js", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | #### morley.css 65 | 66 | ```{r, results='asis'} 67 | cat("```css\n") 68 | writeLines(readLines("morley.css", warn = FALSE)) 69 | cat("```\n") 70 | ``` 71 | 72 | 73 |
74 | 75 |
76 | 77 | 78 | ```{js} 79 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 80 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 81 | $('a.list-group-item[href="../morley/"]').addClass('active'); 82 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 83 | ``` 84 | -------------------------------------------------------------------------------- /vignettes/gallery/morley/morley.css: -------------------------------------------------------------------------------- 1 | .box { 2 | font: 10px sans-serif; 3 | } 4 | 5 | .box line, 6 | .box rect, 7 | .box circle { 8 | stroke-width: 1.5px; 9 | } 10 | 11 | .box .center { 12 | stroke-dasharray: 3,3; 13 | } 14 | 15 | .box .outlier { 16 | fill: none; 17 | stroke: #ccc; 18 | } 19 | -------------------------------------------------------------------------------- /vignettes/gallery/morley/morley.csv: -------------------------------------------------------------------------------- 1 | Expt,Run,Speed 2 | 1,1,850 3 | 1,2,740 4 | 1,3,900 5 | 1,4,1070 6 | 1,5,930 7 | 1,6,850 8 | 1,7,950 9 | 1,8,980 10 | 1,9,980 11 | 1,10,880 12 | 1,11,1000 13 | 1,12,980 14 | 1,13,930 15 | 1,14,650 16 | 1,15,760 17 | 1,16,810 18 | 1,17,1000 19 | 1,18,1000 20 | 1,19,960 21 | 1,20,960 22 | 2,1,960 23 | 2,2,940 24 | 2,3,960 25 | 2,4,940 26 | 2,5,880 27 | 2,6,800 28 | 2,7,850 29 | 2,8,880 30 | 2,9,900 31 | 2,10,840 32 | 2,11,830 33 | 2,12,790 34 | 2,13,810 35 | 2,14,880 36 | 2,15,880 37 | 2,16,830 38 | 2,17,800 39 | 2,18,790 40 | 2,19,760 41 | 2,20,800 42 | 3,1,880 43 | 3,2,880 44 | 3,3,880 45 | 3,4,860 46 | 3,5,720 47 | 3,6,720 48 | 3,7,620 49 | 3,8,860 50 | 3,9,970 51 | 3,10,950 52 | 3,11,880 53 | 3,12,910 54 | 3,13,850 55 | 3,14,870 56 | 3,15,840 57 | 3,16,840 58 | 3,17,850 59 | 3,18,840 60 | 3,19,840 61 | 3,20,840 62 | 4,1,890 63 | 4,2,810 64 | 4,3,810 65 | 4,4,820 66 | 4,5,800 67 | 4,6,770 68 | 4,7,760 69 | 4,8,740 70 | 4,9,750 71 | 4,10,760 72 | 4,11,910 73 | 4,12,920 74 | 4,13,890 75 | 4,14,860 76 | 4,15,880 77 | 4,16,720 78 | 4,17,840 79 | 4,18,850 80 | 4,19,850 81 | 4,20,780 82 | -------------------------------------------------------------------------------- /vignettes/gallery/morley/morley.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("morley.csv"), d3_version = 3, container = "div", dependencies = c("box.js") 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4061502 4 | 5 | var margin = {top: 10, right: 40, bottom: 20, left: 40}, 6 | width = (width/4) - 10 - margin.left - margin.right, 7 | height = height - margin.top - margin.bottom; 8 | 9 | var min = Infinity, 10 | max = -Infinity; 11 | 12 | var chart = d3.box() 13 | .whiskers(iqr(1.5)) 14 | .width(width) 15 | .height(height); 16 | 17 | r2d3.onRender(function(csv, div, w, h, options) { 18 | var data = []; 19 | 20 | csv.forEach(function(x) { 21 | var e = Math.floor(x.Expt - 1), 22 | r = Math.floor(x.Run - 1), 23 | s = Math.floor(x.Speed), 24 | d = data[e]; 25 | if (!d) d = data[e] = [s]; 26 | else d.push(s); 27 | if (s > max) max = s; 28 | if (s < min) min = s; 29 | }); 30 | 31 | chart.domain([min, max]); 32 | 33 | var svg = div.selectAll("svg") 34 | .data(data) 35 | .enter().append("svg") 36 | .attr("class", "box") 37 | .attr("width", width + margin.left + margin.right) 38 | .attr("height", height + margin.bottom + margin.top) 39 | .append("g") 40 | .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 41 | .call(chart); 42 | 43 | svg.selectAll(".box line, .box rect, .box circle ") 44 | .attr("fill", theme.background) 45 | .attr("stroke", theme.foreground); 46 | 47 | setInterval(function() { 48 | svg.datum(randomize).call(chart.duration(1000)); 49 | }, 2000); 50 | }); 51 | 52 | function randomize(d) { 53 | if (!d.randomizer) d.randomizer = randomizer(d); 54 | return d.map(d.randomizer); 55 | } 56 | 57 | function randomizer(d) { 58 | var k = d3.max(d) * .02; 59 | return function(d) { 60 | return Math.max(min, Math.min(max, d + k * (Math.random() - .5))); 61 | }; 62 | } 63 | 64 | // Returns a function to compute the interquartile range. 65 | function iqr(k) { 66 | return function(d, i) { 67 | var q1 = d.quartiles[0], 68 | q3 = d.quartiles[2], 69 | iqr = (q3 - q1) * k, 70 | i = -1, 71 | j = d.length; 72 | while (d[++i] < q1 - iqr); 73 | while (d[--j] > q3 + iqr); 74 | return [i, j]; 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /vignettes/gallery/population/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: population" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("population.csv"), d3_version = 3, options = list(year = 2000), script = "population.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("population.csv"), d3_version = 3, options = list(year = 2000), script = "population.js", width="100%") 45 | ``` 46 | 47 | 48 | #### population.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("population.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### population.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("population.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../population/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/population/population.css: -------------------------------------------------------------------------------- 1 | svg { 2 | font: sans-serif; 3 | } 4 | 5 | .y.axis path { 6 | display: none; 7 | } 8 | 9 | .y.axis line { 10 | stroke: #fff; 11 | stroke-opacity: .2; 12 | shape-rendering: crispEdges; 13 | } 14 | 15 | .y.axis .zero line { 16 | stroke: #000; 17 | stroke-opacity: 1; 18 | } 19 | 20 | .title { 21 | font: Helvetica Neue; 22 | fill: #666; 23 | } 24 | 25 | .birthyear, 26 | .age { 27 | text-anchor: middle; 28 | } 29 | 30 | .birthyear { 31 | fill: #fff; 32 | } 33 | 34 | rect { 35 | fill-opacity: .6; 36 | fill: #e377c2; 37 | } 38 | 39 | rect:first-child { 40 | fill: #1f77b4; 41 | } 42 | -------------------------------------------------------------------------------- /vignettes/gallery/population/population.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("population.csv"), d3_version = 3, options = list(year = 2000) 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4062085 4 | 5 | var margin = {top: 0, right: width / 24, bottom: height / 30, left: 0}, 6 | width = width - margin.left - margin.right, 7 | height = height - margin.top - margin.bottom, 8 | barWidth = Math.floor(width / 19) - 1; 9 | 10 | var x = d3.scale.linear() 11 | .range([barWidth / 2, width - barWidth / 2]); 12 | 13 | var y = d3.scale.linear() 14 | .range([height, 0]); 15 | 16 | var yAxis = d3.svg.axis() 17 | .scale(y) 18 | .orient("right") 19 | .tickSize(-width) 20 | .tickFormat(function(d) { return Math.round(d / 1e6) + "M"; }); 21 | 22 | // An SVG element with a bottom-right origin. 23 | svg 24 | .attr("width", width + margin.left + margin.right) 25 | .attr("height", height + margin.top + margin.bottom) 26 | .style("font-size", Math.min(width, height) / 60) 27 | .append("g") 28 | .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 29 | 30 | // A sliding container to hold the bars by birthyear. 31 | var birthyears = svg.append("g") 32 | .attr("class", "birthyears"); 33 | 34 | // A label for the current year. 35 | var title = svg.append("text") 36 | .attr("class", "title") 37 | .attr("dy", "1em") 38 | .attr("font-size", Math.min(width, height) / 6) 39 | .text(options.year); 40 | 41 | r2d3.onRender(function(data, svg, w, h, options) { 42 | 43 | // Convert strings to numbers. 44 | data.forEach(function(d) { 45 | d.people = +d.people; 46 | d.year = +d.year; 47 | d.age = +d.age; 48 | }); 49 | 50 | // Compute the extent of the data set in age and years. 51 | var age1 = d3.max(data, function(d) { return d.age; }), 52 | year0 = d3.min(data, function(d) { return d.year; }), 53 | year1 = d3.max(data, function(d) { return d.year; }), 54 | year = year1; 55 | 56 | // Update the scale domains. 57 | x.domain([year1 - age1, year1]); 58 | y.domain([0, d3.max(data, function(d) { return d.people; })]); 59 | 60 | // Produce a map from year and birthyear to [male, female]. 61 | data = d3.nest() 62 | .key(function(d) { return d.year; }) 63 | .key(function(d) { return d.year - d.age; }) 64 | .rollup(function(v) { return v.map(function(d) { return d.people; }); }) 65 | .map(data); 66 | 67 | // Add an axis to show the population values. 68 | svg.append("g") 69 | .attr("class", "y axis") 70 | .attr("transform", "translate(" + width + ",0)") 71 | .call(yAxis) 72 | .selectAll("g") 73 | .filter(function(value) { return !value; }) 74 | .classed("zero", true); 75 | 76 | // Add labeled rects for each birthyear (so that no enter or exit is required). 77 | var birthyear = birthyears.selectAll(".birthyear") 78 | .data(d3.range(year0 - age1, year1 + 1, 5)) 79 | .enter().append("g") 80 | .attr("class", "birthyear") 81 | .attr("transform", function(birthyear) { return "translate(" + x(birthyear) + ",0)"; }); 82 | 83 | birthyear.selectAll("rect") 84 | .data(function(birthyear) { return data[year][birthyear] || [0, 0]; }) 85 | .enter().append("rect") 86 | .attr("x", -barWidth / 2) 87 | .attr("width", barWidth) 88 | .attr("y", y) 89 | .attr("height", function(value) { return height - y(value); }); 90 | 91 | // Add labels to show birthyear. 92 | birthyear.append("text") 93 | .attr("y", height - 4) 94 | .text(function(birthyear) { return birthyear; }); 95 | 96 | // Add labels to show age (separate; not animated). 97 | svg.selectAll(".age") 98 | .data(d3.range(0, age1 + 1, 5)) 99 | .enter().append("text") 100 | .attr("class", "age") 101 | .attr("x", function(age) { return x(year - age); }) 102 | .attr("y", height + 4) 103 | .attr("dy", ".71em") 104 | .text(function(age) { return age; }); 105 | 106 | // Allow the arrow keys to change the displayed year. 107 | window.focus(); 108 | d3.select(window).on("keydown", function() { 109 | switch (d3.event.keyCode) { 110 | case 37: year = Math.max(year0, year - 10); break; 111 | case 39: year = Math.min(year1, year + 10); break; 112 | } 113 | update(); 114 | }); 115 | 116 | function update() { 117 | if (!(year in data)) return; 118 | title.text(year); 119 | 120 | birthyears.transition() 121 | .duration(750) 122 | .attr("transform", "translate(" + (x(year1) - x(year)) + ",0)"); 123 | 124 | birthyear.selectAll("rect") 125 | .data(function(birthyear) { return data[year][birthyear] || [0, 0]; }) 126 | .transition() 127 | .duration(750) 128 | .attr("y", y) 129 | .attr("height", function(value) { return height - y(value); }); 130 | } 131 | }); 132 | -------------------------------------------------------------------------------- /vignettes/gallery/radialtree/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: radialtree" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "radialtree.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "radialtree.js", width="100%") 45 | ``` 46 | 47 | 48 | #### radialtree.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("radialtree.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### radialtree.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("radialtree.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../radialtree/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/radialtree/radialtree.css: -------------------------------------------------------------------------------- 1 | .node circle { 2 | fill: #999; 3 | } 4 | 5 | .node text { 6 | font: 10px sans-serif; 7 | } 8 | 9 | .node--internal circle { 10 | fill: #555; 11 | } 12 | 13 | .node--internal text { 14 | text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; 15 | } 16 | 17 | .link { 18 | fill: none; 19 | stroke: #555; 20 | stroke-opacity: 0.4; 21 | stroke-width: 1.5px; 22 | } 23 | -------------------------------------------------------------------------------- /vignettes/gallery/radialtree/radialtree.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = read.csv("flare.csv"), d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063550 4 | 5 | var minSize = Math.min(width, height); 6 | var g = svg.append("g") 7 | .attr("transform", 8 | "translate(" + (width / 2) + "," + (height / 2) + ")," + 9 | "scale(" + minSize / 1200 + "," + minSize / 1200 + ")"); 10 | 11 | var stratify = d3.stratify() 12 | .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); 13 | 14 | var tree = d3.tree() 15 | .size([2 * Math.PI, 500]) 16 | .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; }); 17 | 18 | r2d3.onRender(function(data, svg, w, h, options) { 19 | var root = tree(stratify(data)); 20 | 21 | var link = g.selectAll(".link") 22 | .data(root.links()) 23 | .enter().append("path") 24 | .attr("class", "link") 25 | .attr("d", d3.linkRadial() 26 | .angle(function(d) { return d.x; }) 27 | .radius(function(d) { return d.y; })); 28 | 29 | var node = g.selectAll(".node") 30 | .data(root.descendants()) 31 | .enter().append("g") 32 | .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) 33 | .attr("transform", function(d) { return "translate(" + radialPoint(d.x, d.y) + ")"; }); 34 | 35 | node.append("circle") 36 | .attr("r", 2.5); 37 | 38 | node.append("text") 39 | .attr("dy", "0.31em") 40 | .attr("x", function(d) { return d.x < Math.PI === !d.children ? 6 : -6; }) 41 | .attr("text-anchor", function(d) { return d.x < Math.PI === !d.children ? "start" : "end"; }) 42 | .attr("transform", function(d) { return "rotate(" + (d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 180 / Math.PI + ")"; }) 43 | .text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); }); 44 | }); 45 | 46 | function radialPoint(x, y) { 47 | return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; 48 | } 49 | -------------------------------------------------------------------------------- /vignettes/gallery/stackedbars/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: stackedbars" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(d3_version = 4, script = "stackedbars.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(d3_version = 4, script = "stackedbars.js", width="100%") 45 | ``` 46 | 47 | 48 | #### stackedbars.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("stackedbars.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### stackedbars.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("stackedbars.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../stackedbars/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/stackedbars/stackedbars.css: -------------------------------------------------------------------------------- 1 | label { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /vignettes/gallery/stackedbars/stackedbars.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 d3_version = 4 2 | 3 | // Based on: http://bl.ocks.org/mbostock/3943967 4 | 5 | var n = 4, // The number of series. 6 | m = 58; // The number of values per series. 7 | 8 | // The xz array has m elements, representing the x-values shared by all series. 9 | // The yz array has n elements, representing the y-values of each of the n series. 10 | // Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i]. 11 | // The y01z array has the same structure as yz, but with stacked [y₀, y₁] instead of y. 12 | var xz = d3.range(m), 13 | yz = d3.range(n).map(function() { return bumps(m); }), 14 | y01z = d3.stack().keys(d3.range(n))(d3.transpose(yz)), 15 | yMax = d3.max(yz, function(y) { return d3.max(y); }), 16 | y1Max = d3.max(y01z, function(y) { return d3.max(y, function(d) { return d[1]; }); }); 17 | 18 | var margin = {top: 40, right: 10, bottom: 20, left: 10}, 19 | width = width - margin.left - margin.right, 20 | height = height - margin.top - margin.bottom, 21 | g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 22 | 23 | var x = d3.scaleBand() 24 | .domain(xz) 25 | .rangeRound([0, width]) 26 | .padding(0.08); 27 | 28 | var y = d3.scaleLinear() 29 | .domain([0, y1Max]) 30 | .range([height, 0]); 31 | 32 | var color = d3.scaleOrdinal() 33 | .domain(d3.range(n)) 34 | .range(d3.schemeCategory20c); 35 | 36 | var series = g.selectAll(".series") 37 | .data(y01z) 38 | .enter().append("g") 39 | .attr("fill", function(d, i) { return color(i); }); 40 | 41 | var rect = series.selectAll("rect") 42 | .data(function(d) { return d; }) 43 | .enter().append("rect") 44 | .attr("x", function(d, i) { return x(i); }) 45 | .attr("y", height) 46 | .attr("width", x.bandwidth()) 47 | .attr("height", 0); 48 | 49 | rect.transition() 50 | .delay(function(d, i) { return i * 10; }) 51 | .attr("y", function(d) { return y(d[1]); }) 52 | .attr("height", function(d) { return y(d[0]) - y(d[1]); }); 53 | 54 | g.append("g") 55 | .attr("class", "axis axis--x") 56 | .attr("transform", "translate(0," + height + ")") 57 | .style("font-size", Math.min(width, height * 2) / 90) 58 | .call(d3.axisBottom(x) 59 | .tickSize(0) 60 | .tickPadding(6)); 61 | 62 | d3.selectAll("input") 63 | .on("change", changed); 64 | 65 | var timeout = d3.timeout(function() { 66 | d3.select("input[value=\"grouped\"]") 67 | .property("checked", true) 68 | .dispatch("change"); 69 | }, 2000); 70 | 71 | function changed() { 72 | timeout.stop(); 73 | if (this.value === "grouped") transitionGrouped(); 74 | else transitionStacked(); 75 | } 76 | 77 | function transitionGrouped() { 78 | y.domain([0, yMax]); 79 | 80 | rect.transition() 81 | .duration(500) 82 | .delay(function(d, i) { return i * 10; }) 83 | .attr("x", function(d, i) { return x(i) + x.bandwidth() / n * this.parentNode.__data__.key; }) 84 | .attr("width", x.bandwidth() / n) 85 | .transition() 86 | .attr("y", function(d) { return y(d[1] - d[0]); }) 87 | .attr("height", function(d) { return y(0) - y(d[1] - d[0]); }); 88 | } 89 | 90 | function transitionStacked() { 91 | y.domain([0, y1Max]); 92 | 93 | rect.transition() 94 | .duration(500) 95 | .delay(function(d, i) { return i * 10; }) 96 | .attr("y", function(d) { return y(d[1]); }) 97 | .attr("height", function(d) { return y(d[0]) - y(d[1]); }) 98 | .transition() 99 | .attr("x", function(d, i) { return x(i); }) 100 | .attr("width", x.bandwidth()); 101 | } 102 | 103 | // Returns an array of m psuedorandom, smoothly-varying non-negative numbers. 104 | // Inspired by Lee Byron’s test data generator. 105 | // http://leebyron.com/streamgraph/ 106 | function bumps(m) { 107 | var values = [], i, j, w, x, y, z; 108 | 109 | // Initialize with uniform random values in [0.1, 0.2). 110 | for (i = 0; i < m; ++i) { 111 | values[i] = 0.1 + 0.1 * Math.random(); 112 | } 113 | 114 | // Add five random bumps. 115 | for (j = 0; j < 5; ++j) { 116 | x = 1 / (0.1 + Math.random()); 117 | y = 2 * Math.random() - 0.5; 118 | z = 10 / (0.1 + Math.random()); 119 | for (i = 0; i < m; i++) { 120 | w = (i / m - y) * z; 121 | values[i] += x * Math.exp(-w * w); 122 | } 123 | } 124 | 125 | // Ensure all values are positive. 126 | for (i = 0; i < m; ++i) { 127 | values[i] = Math.max(0, values[i]); 128 | } 129 | 130 | return values; 131 | } 132 | -------------------------------------------------------------------------------- /vignettes/gallery/streamgraph/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: streamgraph" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data=c(), script = "streamgraph.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data=c(), script = "streamgraph.js", width="100%") 45 | ``` 46 | 47 | 48 | #### streamgraph.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("streamgraph.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | 57 |
58 | 59 |
60 | 61 | 62 | ```{js} 63 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 64 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 65 | $('a.list-group-item[href="../streamgraph/"]').addClass('active'); 66 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 67 | ``` 68 | -------------------------------------------------------------------------------- /vignettes/gallery/streamgraph/streamgraph.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data=c() 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4060954 4 | 5 | var n = 20, // number of layers 6 | m = 200, // number of samples per layer 7 | k = 10; // number of bumps per layer 8 | 9 | var stack = d3.stack().keys(d3.range(n)).offset(d3.stackOffsetWiggle), 10 | layers0 = stack(d3.transpose(d3.range(n).map(function() { return bumps(m, k); }))), 11 | layers1 = stack(d3.transpose(d3.range(n).map(function() { return bumps(m, k); }))), 12 | layers = layers0.concat(layers1); 13 | 14 | var x = d3.scaleLinear() 15 | .domain([0, m - 1]) 16 | .range([0, width]); 17 | 18 | var y = d3.scaleLinear() 19 | .domain([d3.min(layers, stackMin), d3.max(layers, stackMax)]) 20 | .range([height, 0]); 21 | 22 | var z = d3.interpolateCool; 23 | 24 | var area = d3.area() 25 | .x(function(d, i) { return x(i); }) 26 | .y0(function(d) { return y(d[0]); }) 27 | .y1(function(d) { return y(d[1]); }); 28 | 29 | var widthOrginal = width; 30 | var heightOrginal = height; 31 | var root = svg.append("g"); 32 | 33 | root 34 | .selectAll("path") 35 | .data(layers0) 36 | .enter().append("path") 37 | .attr("d", area) 38 | .attr("fill", function() { return z(Math.random()); }); 39 | 40 | function stackMax(layer) { 41 | return d3.max(layer, function(d) { return d[1]; }); 42 | } 43 | 44 | function stackMin(layer) { 45 | return d3.min(layer, function(d) { return d[0]; }); 46 | } 47 | 48 | function transition() { 49 | var t; 50 | d3.selectAll("path") 51 | .data((t = layers1, layers1 = layers0, layers0 = t)) 52 | .transition() 53 | .duration(2500) 54 | .attr("d", area); 55 | } 56 | 57 | // Inspired by Lee Byron’s test data generator. 58 | function bumps(n, m) { 59 | var a = [], i; 60 | for (i = 0; i < n; ++i) a[i] = 0; 61 | for (i = 0; i < m; ++i) bump(a, n); 62 | return a; 63 | } 64 | 65 | function bump(a, n) { 66 | var x = 1 / (0.1 + Math.random()), 67 | y = 2 * Math.random() - 0.5, 68 | z = 10 / (0.1 + Math.random()); 69 | for (var i = 0; i < n; i++) { 70 | var w = (i / n - y) * z; 71 | a[i] += x * Math.exp(-w * w); 72 | } 73 | } 74 | 75 | r2d3.onResize(function(width, height) { 76 | root.attr("transform", "scale(" + width / widthOrginal + "," + height / heightOrginal + ")"); 77 | }); 78 | -------------------------------------------------------------------------------- /vignettes/gallery/sunburst/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: sunburst" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 3, script = "sunburst.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 3, script = "sunburst.js", width="100%") 45 | ``` 46 | 47 | 48 | #### sunburst.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("sunburst.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### sunburst.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("sunburst.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../sunburst/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/sunburst/sunburst.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | } 4 | -------------------------------------------------------------------------------- /vignettes/gallery/sunburst/sunburst.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("flare.json"), d3_version = 3 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063423 4 | 5 | var radius = Math.min(width, height) / 2, 6 | color = d3.scale.category20c(); 7 | 8 | var group = svg.append("g") 9 | .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); 10 | 11 | var partition = d3.layout.partition() 12 | .sort(null) 13 | .size([2 * Math.PI, radius * radius]) 14 | .value(function(d) { return 1; }); 15 | 16 | var arc = d3.svg.arc() 17 | .startAngle(function(d) { return d.x; }) 18 | .endAngle(function(d) { return d.x + d.dx; }) 19 | .innerRadius(function(d) { return Math.sqrt(d.y); }) 20 | .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); }); 21 | 22 | r2d3.onRender(function(root, svg, w, h, options) { 23 | var path = group.datum(root).selectAll("path") 24 | .data(partition.nodes) 25 | .enter().append("path") 26 | .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring 27 | .attr("d", arc) 28 | .style("stroke", "#fff") 29 | .style("fill", function(d) { return color((d.children ? d : d.parent).name); }) 30 | .style("fill-rule", "evenodd") 31 | .each(stash); 32 | 33 | d3.selectAll("input").on("change", function change() { 34 | var value = this.value === "count" 35 | ? function() { return 1; } 36 | : function(d) { return d.size; }; 37 | 38 | path 39 | .data(partition.value(value).nodes) 40 | .transition() 41 | .duration(1500) 42 | .attrTween("d", arcTween); 43 | }); 44 | }); 45 | 46 | // Stash the old values for transition. 47 | function stash(d) { 48 | d.x0 = d.x; 49 | d.dx0 = d.dx; 50 | } 51 | 52 | // Interpolate the arcs in data space. 53 | function arcTween(a) { 54 | var i = d3.interpolate({x: a.x0, dx: a.dx0}, a); 55 | return function(t) { 56 | var b = i(t); 57 | a.x0 = b.x; 58 | a.dx0 = b.dx; 59 | return arc(b); 60 | }; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /vignettes/gallery/treemap/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: treemap" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 4, script = "treemap.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(data = jsonlite::read_json("flare.json"), d3_version = 4, script = "treemap.js", width="100%") 45 | ``` 46 | 47 | 48 | #### treemap.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("treemap.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### treemap.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("treemap.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../treemap/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/treemap/treemap.css: -------------------------------------------------------------------------------- 1 | svg { 2 | font: 10px sans-serif; 3 | } 4 | -------------------------------------------------------------------------------- /vignettes/gallery/treemap/treemap.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = jsonlite::read_json("flare.json"), d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4063582 4 | 5 | var fader = function(color) { return d3.interpolateRgb(color, "#fff")(0.2); }, 6 | color = d3.scaleOrdinal(d3.schemeCategory20.map(fader)), 7 | format = d3.format(",d"); 8 | 9 | var treemap = d3.treemap() 10 | .tile(d3.treemapResquarify) 11 | .size([width, height]) 12 | .round(true) 13 | .paddingInner(1); 14 | 15 | r2d3.onRender(function(data, svg, w, h, options) { 16 | var root = d3.hierarchy(data) 17 | .eachBefore(function(d) { d.data.id = (d.parent ? d.parent.data.id + "." : "") + d.data.name; }) 18 | .sum(sumBySize) 19 | .sort(function(a, b) { return b.height - a.height || b.value - a.value; }); 20 | 21 | treemap(root); 22 | 23 | var cell = svg.selectAll("g") 24 | .data(root.leaves()) 25 | .enter().append("g") 26 | .attr("transform", function(d) { return "translate(" + d.x0 + "," + d.y0 + ")"; }); 27 | 28 | cell.append("rect") 29 | .attr("id", function(d) { return d.data.id; }) 30 | .attr("width", function(d) { return d.x1 - d.x0; }) 31 | .attr("height", function(d) { return d.y1 - d.y0; }) 32 | .attr("fill", function(d) { return color(d.parent.data.id); }); 33 | 34 | cell.append("clipPath") 35 | .attr("id", function(d) { return "clip-" + d.data.id; }) 36 | .append("use") 37 | .attr("xlink:href", function(d) { return "#" + d.data.id; }); 38 | 39 | cell.append("text") 40 | .attr("clip-path", function(d) { return "url(#clip-" + d.data.id + ")"; }) 41 | .style("font-size", Math.min(width, height) / 50) 42 | .selectAll("tspan") 43 | .data(function(d) { return d.data.name.split(/(?=[A-Z][^A-Z])/g); }) 44 | .enter().append("tspan") 45 | .attr("x", 4) 46 | .attr("y", function(d, i) { return 13 + i * 10; }) 47 | .text(function(d) { return d; }); 48 | 49 | cell.append("title") 50 | .text(function(d) { return d.data.id + "\n" + format(d.value); }); 51 | 52 | d3.selectAll("input") 53 | .data([sumBySize, sumByCount], function(d) { return d ? d.name : this.value; }) 54 | .on("change", changed); 55 | 56 | var timeout = d3.timeout(function() { 57 | d3.select("input[value=\"sumByCount\"]") 58 | .property("checked", true) 59 | .dispatch("change"); 60 | }, 2000); 61 | 62 | function changed(sum) { 63 | timeout.stop(); 64 | 65 | treemap(root.sum(sum)); 66 | 67 | cell.transition() 68 | .duration(750) 69 | .attr("transform", function(d) { return "translate(" + d.x0 + "," + d.y0 + ")"; }) 70 | .select("rect") 71 | .attr("width", function(d) { return d.x1 - d.x0; }) 72 | .attr("height", function(d) { return d.y1 - d.y0; }); 73 | } 74 | }); 75 | 76 | function sumByCount(d) { 77 | return d.children ? 0 : 1; 78 | } 79 | 80 | function sumBySize(d) { 81 | return d.size; 82 | } 83 | -------------------------------------------------------------------------------- /vignettes/gallery/voronoi/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Gallery: voronoi" 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | library(r2d3) 7 | knitr::opts_chunk$set(echo=FALSE, comment=NA) 8 | ``` 9 | 10 | 13 | 14 |
15 | 16 |
17 |
18 | bubbles 19 | bullets 20 | calendar 21 | cartogram 22 | chord 23 | circlepacking 24 | dendogram 25 | forcegraph 26 | morley 27 | population 28 | radialtree 29 | stackedbars 30 | streamgraph 31 | sunburst 32 | treemap 33 | voronoi 34 |
35 |
36 | 37 |
38 | 39 | ```{r, echo=TRUE, eval=FALSE} 40 | r2d3(d3_version = 4, script = "voronoi.js") 41 | ``` 42 | 43 | ```{r, echo=FALSE} 44 | r2d3(d3_version = 4, script = "voronoi.js", width="100%") 45 | ``` 46 | 47 | 48 | #### voronoi.js 49 | 50 | ```{r, results='asis'} 51 | cat("```js\n") 52 | writeLines(readLines("voronoi.js", warn = FALSE)) 53 | cat("```\n") 54 | ``` 55 | 56 | #### voronoi.css 57 | 58 | ```{r, results='asis'} 59 | cat("```css\n") 60 | writeLines(readLines("voronoi.css", warn = FALSE)) 61 | cat("```\n") 62 | ``` 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | ```{js} 71 | $('#source-link').appendTo($('.page-header')).css('display', 'block'); 72 | $('.template-vignette>.row>.col-md-9').attr('class', 'col-md-12'); 73 | $('a.list-group-item[href="../voronoi/"]').addClass('active'); 74 | $('a[href="../../../articles/gallery.html"]').parent().addClass('active'); 75 | ``` 76 | -------------------------------------------------------------------------------- /vignettes/gallery/voronoi/voronoi.css: -------------------------------------------------------------------------------- 1 | .links { 2 | stroke: #000; 3 | stroke-opacity: 0.2; 4 | } 5 | 6 | .polygons { 7 | fill: none; 8 | stroke: #000; 9 | } 10 | 11 | .polygons :first-child { 12 | fill: #f00; 13 | } 14 | 15 | .sites { 16 | fill: #000; 17 | stroke: #fff; 18 | } 19 | 20 | .sites :first-child { 21 | fill: #fff; 22 | } 23 | -------------------------------------------------------------------------------- /vignettes/gallery/voronoi/voronoi.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 d3_version = 4 2 | 3 | // Based on: https://bl.ocks.org/mbostock/4060366 4 | 5 | svg.on("touchmove mousemove", moved); 6 | 7 | var sites = d3.range(100) 8 | .map(function(d) { return [Math.random() * width, Math.random() * height]; }); 9 | 10 | var voronoi = d3.voronoi() 11 | .extent([[-8, -8], [width + 8, height + 8]]); 12 | 13 | var polygon = svg.append("g") 14 | .attr("class", "polygons") 15 | .selectAll("path") 16 | .data(voronoi.polygons(sites)) 17 | .enter().append("path") 18 | .call(redrawPolygon); 19 | 20 | var link = svg.append("g") 21 | .attr("class", "links") 22 | .selectAll("line") 23 | .data(voronoi.links(sites)) 24 | .enter().append("line") 25 | .call(redrawLink); 26 | 27 | var site = svg.append("g") 28 | .attr("class", "sites") 29 | .selectAll("circle") 30 | .data(sites) 31 | .enter().append("circle") 32 | .attr("r", 2.5) 33 | .call(redrawSite); 34 | 35 | function moved() { 36 | sites[0] = d3.mouse(this); 37 | redraw(); 38 | } 39 | 40 | function redraw() { 41 | var diagram = voronoi(sites); 42 | polygon = polygon.data(diagram.polygons()).call(redrawPolygon); 43 | link = link.data(diagram.links()), link.exit().remove(); 44 | link = link.enter().append("line").merge(link).call(redrawLink); 45 | site = site.data(sites).call(redrawSite); 46 | } 47 | 48 | function redrawPolygon(polygon) { 49 | polygon 50 | .attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; }); 51 | } 52 | 53 | function redrawLink(link) { 54 | link 55 | .attr("x1", function(d) { return d.source[0]; }) 56 | .attr("y1", function(d) { return d.source[1]; }) 57 | .attr("x2", function(d) { return d.target[0]; }) 58 | .attr("y2", function(d) { return d.target[1]; }); 59 | } 60 | 61 | function redrawSite(site) { 62 | site 63 | .attr("cx", function(d) { return d[0]; }) 64 | .attr("cy", function(d) { return d[1]; }); 65 | } 66 | -------------------------------------------------------------------------------- /vignettes/images/attr.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/attr.PNG -------------------------------------------------------------------------------- /vignettes/images/bar_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/bar_chart.png -------------------------------------------------------------------------------- /vignettes/images/baranim-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/baranim-1.gif -------------------------------------------------------------------------------- /vignettes/images/browser_debugging_entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/browser_debugging_entry.png -------------------------------------------------------------------------------- /vignettes/images/browser_developer_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/browser_developer_tools.png -------------------------------------------------------------------------------- /vignettes/images/bubbles_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/bubbles_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/bullets_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/bullets_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/calendar_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/calendar_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/cartogram_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/cartogram_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/chord_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/chord_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/circlepacking_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/circlepacking_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/console_logging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/console_logging.png -------------------------------------------------------------------------------- /vignettes/images/d3_book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/d3_book.jpg -------------------------------------------------------------------------------- /vignettes/images/d3toshiny.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/d3toshiny.gif -------------------------------------------------------------------------------- /vignettes/images/daily_build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/daily_build.png -------------------------------------------------------------------------------- /vignettes/images/dendogram_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/dendogram_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/error_debugging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/error_debugging.png -------------------------------------------------------------------------------- /vignettes/images/export_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/export_dialog.png -------------------------------------------------------------------------------- /vignettes/images/export_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/export_menu.png -------------------------------------------------------------------------------- /vignettes/images/flexdashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/flexdashboard.png -------------------------------------------------------------------------------- /vignettes/images/forcegraph_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/forcegraph_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/morley_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/morley_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/new_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/new_script.png -------------------------------------------------------------------------------- /vignettes/images/onclick.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/onclick.PNG -------------------------------------------------------------------------------- /vignettes/images/population_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/population_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/publish.png -------------------------------------------------------------------------------- /vignettes/images/r2d3-hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/r2d3-hex.png -------------------------------------------------------------------------------- /vignettes/images/radialtree_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/radialtree_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/rmarkdown-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/rmarkdown-1.png -------------------------------------------------------------------------------- /vignettes/images/rstudio_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/rstudio_preview.png -------------------------------------------------------------------------------- /vignettes/images/show_in_new_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/show_in_new_window.png -------------------------------------------------------------------------------- /vignettes/images/stackedbars_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/stackedbars_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/streamgraph_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/streamgraph_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/sunburst_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/sunburst_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/treemap_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/treemap_thumbnail.png -------------------------------------------------------------------------------- /vignettes/images/voronoi_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/r2d3/becfb81989c7fabfe79dee2dde999190025d4ba3/vignettes/images/voronoi_thumbnail.png -------------------------------------------------------------------------------- /vignettes/learning_d3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Learning D3" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Learning D3} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Introduction 15 | 16 | There are a number of excellent resources available for learning how to do data visualization with D3, including online tutorials, self-paced courses, and books. There are also sites that provide numerous examples to learn from. We'll enumerate these resources below as well as provide some tips on mapping the example D3 code you'll encounter back to code that works with **r2d3**. 17 | 18 | 19 | ## Books 20 | 21 | 22 | 23 | There are a number of books about D3 available, but only one has been updated to work with more recent versions of D3 (versions 4 and 5). That book is Scott Murray's [Interactive Data Visualization for the Web: An Introduction to Designing with D3](https://www.amazon.com/Interactive-Data-Visualization-Web-Introduction/dp/1491921285/). The book covers D3 from the ground up, presuming no existing experience with data visualization or web development. 24 | 25 | The book covers bar charts, scatter plots, pie charts, stacked bar charts, force-directed graphs, and geographic visualizations. The books includes over 140 examples as well as case studies with nine accomplished designers talking about their D3-based projects. 26 | 27 | ## Online Resources 28 | 29 | There are several good self paced online tutorials for learning D3 available, these include: 30 | 31 | 1) [Intro to D3.js from Square](http://square.github.io/intro-to-d3/) 32 | 33 | 2) [D3 in Depth from Peter Cook](https://www.d3indepth.com/) 34 | 35 | 3) [Dashing D3.js](https://www.dashingd3js.com/) 36 | 37 | There are also a number of websites that aggregate examples of D3 visualizations, these include: 38 | 39 | 1) [The D3 Gallery](https://github.com/d3/d3/wiki/Gallery) 40 | 41 | 2) [Mike Bostock's Blocks](https://bl.ocks.org/mbostock) 42 | 43 | 3) [VIDA D3 Explorer](https://vida.io/explore) 44 | 45 | ## Coding D3 for r2d3 46 | 47 | When you are learning D3 or translating D3 examples for use with R it's important to keep in mind that D3 examples will generally include code to load data, create an SVG or other root element, and establish a width and height for the visualization. On the other hand with **r2d3**, these variables are *provided automatically* so do not need to be created. Here is some code you'll typically see in D3 examples: 48 | 49 | Creating an SVG element to contain the visualization: 50 | 51 | ```{js, eval=FALSE} 52 | var svg = d3.select("body").append("svg"); 53 | ``` 54 | 55 | Hard-coding margins, width, and height for the visualization: 56 | 57 | ```{js, eval=FALSE} 58 | var margin = {top: 20, right: 20, bottom: 70, left: 40}, 59 | width = 600 - margin.left - margin.right, 60 | height = 300 - margin.top - margin.bottom; 61 | ``` 62 | 63 | Loading data for the visualization: 64 | 65 | ```{js, eval=FALSE} 66 | d3.csv("bar-data.csv", function(error, data) { 67 | 68 | }); 69 | ``` 70 | 71 | Code like the above isn't necessary with **r2d3**, since the following variables are provided automatically to your D3 script: 72 | 73 | - `data` --- The R data converted to JavaScript. 74 | - `svg` --- The svg container for the visualization 75 | - `width` --- The current width of the container 76 | - `height` --- The current height of the container 77 | - `options` --- Additional options provided by the user 78 | - `theme` --- Colors for the current theme 79 | 80 | For example, here's a simple **r2d3** script which makes use of these automatically provided variables: 81 | 82 | ```{js, eval=FALSE} 83 | // !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20) 84 | 85 | var barHeight = Math.floor(height / data.length); 86 | 87 | svg.selectAll('rect') 88 | .data(data) 89 | .enter().append('rect') 90 | .attr('width', function(d) { return d * width; }) 91 | .attr('height', barHeight) 92 | .attr('y', function(d, i) { return i * barHeight; }) 93 | .attr('fill', 'steelblue'); 94 | ``` 95 | 96 | 97 | -------------------------------------------------------------------------------- /vignettes/publishing.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Publishing D3 Visualizations" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Publishing D3 Visualizations} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(eval = FALSE) 12 | ``` 13 | 14 | ## Overview 15 | 16 | There are a variety of ways to publish D3 visualizations, including: 17 | 18 | 1) Saving as a standalone HTML file 19 | 20 | 2) Publishing to a service like [RPubs](https://rpubs.com) 21 | 22 | 3) Exporting to a static PNG version of the visualization 23 | 24 | 4) Copying to the clipboard and pasting into another application 25 | 26 | 5) Including within an [R Markdown](https://rmarkdown.rstudio.com) document or dashboard 27 | 28 | 6) Including within a [Shiny](https://shiny.rstudio.com) application 29 | 30 | This article describes each of these techniques for publishing visualizations 31 | 32 | ## Publishing HTML 33 | 34 | ### Save as HTML 35 | 36 | You can use the `save_d3_html()` function to save a D3 visualization as an HTML file. For example: 37 | 38 | ```{r} 39 | library(r2d3) 40 | viz <- r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 41 | save_d3_html(viz, file = "viz.html") 42 | ``` 43 | 44 | By default, the HTML file will be self-contained (all CSS and JavaScript dependencies will be embedded with the file) so that it's easy to share. If you want the dependencies written to a separate directory you can set `selfcontained = FALSE`. For example: 45 | 46 | ```{r} 47 | library(r2d3) 48 | viz <- r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 49 | save_d3_html(viz, file = "viz.html", selfcontained = FALSE) 50 | ``` 51 | 52 | Setting `selfcontained = FALSE` is useful if you want to embed your D3 visualization within another HTML page since it separates the visualization itself from various link and script dependencies that need to be placed in the HTML head. 53 | 54 | ### RPubs / RStudio Connect 55 | 56 | You can also publish visualizations to [RPubs](https://rpubs.com) or [RStudio Connect](https://www.rstudio.com/products/connect/). To do this, click the **Publish** button located in the top right of the RStudio Viewer pane: 57 | 58 | 59 | 60 | 61 | ## Static Images 62 | 63 | ### save_d3_png() 64 | 65 | You can use the `save_d3_png()` function to save a D3 visualization as a PNG image. For example: 66 | 67 | ```{r} 68 | library(r2d3) 69 | viz <- r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 70 | save_d3_png(viz, file = "viz.png") 71 | ``` 72 | 73 | Using the `save_d3_png()` function requires that you install the [webshot](https://cran.r-project.org/package=webshot) package, as well as the phantom.js headless browser (which you can install using the function `webshot::install_phantomjs()`). 74 | 75 | ### RStudio Viewer 76 | 77 | The RStudio Viewer pane has an **Export** menu that enables you to export D3 visualizations as PNG files as well as copy visualizations to the clipboard: 78 | 79 | 80 | 81 | The export dialog enables you to customize the size of the exported or copied image: 82 | 83 | 84 | 85 | ## R Markdown 86 | 87 | You can include D3 visualizations in an R Markdown document or R Notebook. You can do this by calling the `r2d3()` function from within an R code chunk: 88 | 89 | ```` 90 | --- 91 | output: html_document 92 | --- 93 | 94 | `r ````{r} 95 | library(r2d3) 96 | r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js") 97 | ``` 98 | ```` 99 | 100 | 101 | 102 | You can also include D3 visualization code inline using the `d3` R Markdown eng```` 103 | 104 | ```` 105 | `r ````{r setup} 106 | library(r2d3) 107 | bars <- c(10, 20, 30) 108 | ``` 109 | ```` 110 | 111 | ```` 112 | `r ````{d3 data=bars, options=list(color = 'orange')} 113 | svg.selectAll('rect') 114 | .data(data) 115 | .enter() 116 | .append('rect') 117 | .attr('width', function(d) { return d * 10; }) 118 | .attr('height', '20px') 119 | .attr('y', function(d, i) { return i * 22; }) 120 | .attr('fill', options.color); 121 | ``` 122 | ```` 123 | 124 | 125 | 126 | Note that in order to use the `d3` engine you need to add `library(r2d3)` to the setup chunk (as illustrated above). 127 | 128 | ### flexdashboard 129 | 130 | The [flexdashboard](https://rmarkdown.rstudio.com/flexdashboard) R Markdown format is a great way to publish a set of related D3 visualizations. You can use flexdashbaord to combine D3 visualizations with narrative, data tables, other [htmlwidgets](http://www.htmlwidgets.org), and static R plots: 131 | 132 | 133 | 134 | Check out the [flexdashboard online documentation](https://rmarkdown.rstudio.com/flexdashboard) for additional details. 135 | 136 | 137 | ## Shiny applications 138 | 139 | The `renderD3()` and `d3Output()` functions enable you to include D3 visualizations within [Shiny](https://shiny.rstudio.com) applications: 140 | 141 | ```{r eval=FALSE} 142 | library(shiny) 143 | library(r2d3) 144 | 145 | ui <- fluidPage( 146 | inputPanel( 147 | sliderInput("bar_max", label = "Max:", 148 | min = 0.1, max = 1.0, value = 0.2, step = 0.1) 149 | ), 150 | d3Output("d3") 151 | ) 152 | 153 | server <- function(input, output) { 154 | output$d3 <- renderD3({ 155 | r2d3( 156 | runif(5, 0, input$bar_max), 157 | script = system.file("examples/baranims.js", package = "r2d3") 158 | ) 159 | }) 160 | } 161 | 162 | shinyApp(ui = ui, server = server) 163 | ``` 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /vignettes/utils.R: -------------------------------------------------------------------------------- 1 | 2 | library(htmltools) 3 | 4 | # Generate HTML for a 3-wide bootstrap thumbnail 5 | thumbnail <- function(title, img, href, caption = TRUE) { 6 | div(class = "col-sm-3", 7 | a(class = "thumbnail", title = title, href = href, 8 | img(src = img), 9 | div(class = ifelse(caption, "caption", ""), 10 | ifelse(caption, title, "") 11 | ) 12 | ) 13 | ) 14 | } 15 | 16 | # Generate HTML for several rows of 4-wide bootstrap thumbnails 17 | thumbnails <- function(thumbs) { 18 | 19 | # capture arguments and setup rows to return 20 | numThumbs <- length(thumbs) 21 | fullRows <- numThumbs / 4 22 | rows <- tagList() 23 | 24 | # add a row of thumbnails 25 | addRow <- function(first, last) { 26 | rows <<- tagAppendChild(rows, div(class = "row", thumbs[first:last])) 27 | } 28 | 29 | # handle full rows 30 | for (i in 1:fullRows) { 31 | last <- i * 4 32 | first <- last-3 33 | addRow(first, last) 34 | } 35 | 36 | # check for leftovers 37 | leftover <- numThumbs %% 4 38 | if (leftover > 0) { 39 | last <- numThumbs 40 | first <- last - leftover + 1 41 | addRow(first, last) 42 | } 43 | 44 | # return the rows! 45 | rows 46 | } 47 | 48 | # Generate HTML for gallery 49 | examples <- function(examples = "auto", caption = TRUE) { 50 | 51 | # read examples into data frame (so we can easily sort/filter/etc) 52 | if (examples == "auto") 53 | examples <- list.dirs("gallery", recursive = FALSE, full.names = FALSE) 54 | examples <- data.frame( 55 | title = examples, 56 | img = file.path("images", paste0(examples, "_thumbnail.png")), 57 | href = file.path("gallery", paste0(examples, "/")), 58 | stringsAsFactors = FALSE 59 | ) 60 | 61 | # convert to list for thumbnail generation 62 | examples <- apply(examples, 1, function(r) { 63 | list(title = r["title"], 64 | img = r["img"], 65 | href = r["href"]) 66 | }) 67 | 68 | thumbnails(lapply(examples, function(x) { 69 | thumbnail(title = x$title, 70 | img = x$img, 71 | href = x$href, 72 | caption = caption) 73 | })) 74 | } 75 | 76 | 77 | --------------------------------------------------------------------------------