├── .Rbuildignore ├── .gitignore ├── .lintr ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── abs-path-checking.R ├── auto_cogs.R ├── charm.R ├── cog.R ├── facet_trelliscope.R ├── helpers.R ├── htmlwidget.R ├── input_cogs.R ├── json_writers.R ├── make_png.R ├── state.R ├── thumbnail.R ├── tidy.R ├── trelliscope.R └── trelliscopejs-package.R ├── README.md ├── _pkgdown.yml ├── appveyor.yml ├── codecov.yml ├── cran-comments.md ├── data └── mpg_labels.R ├── docs ├── 404.html ├── LICENSE-text.html ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon.png ├── articles │ ├── index.html │ ├── trelliscopejs.html │ └── trelliscopejs_files │ │ └── figure-html │ │ ├── unnamed-chunk-2-1.png │ │ ├── unnamed-chunk-3-1.png │ │ └── unnamed-chunk-4-1.png ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── link.svg ├── logo.png ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml └── reference │ ├── Trelliscope-shiny.html │ ├── as_cognostics.html │ ├── cog.html │ ├── cog_disp_filter.html │ ├── cog_href.html │ ├── cogs.html │ ├── facet_trelliscope.html │ ├── figures │ ├── logo.png │ └── trelliscope.png │ ├── img_panel.html │ ├── img_panel_local.html │ ├── index.html │ ├── map2_cog.html │ ├── map2_plot.html │ ├── map_cog.html │ ├── map_plot.html │ ├── mpg_labels.html │ ├── panel.html │ ├── panels.html │ ├── prepare_display.html │ ├── print.facet_trelliscope.html │ ├── set_labels.html │ ├── sort_spec.html │ ├── trelliscope.html │ ├── trelliscopejs-package.html │ ├── update_display_list.html │ ├── write_cognostics.html │ ├── write_config.html │ ├── write_display_obj.html │ ├── write_panel.html │ └── write_panels.html ├── inst └── htmlwidgets │ ├── lib │ └── trelliscopejs_widget │ │ ├── css │ │ ├── 2.1c1d28a5.chunk.css │ │ └── main.ef767570.chunk.css │ │ ├── js │ │ ├── 2.6925164e.chunk.js │ │ ├── main.c951d10a.chunk.js │ │ └── runtime-main.d9025fd8.js │ │ └── media │ │ ├── icomoon.5dd3ffcb.eot │ │ ├── icomoon.7a81c5bd.woff │ │ ├── icomoon.8454373a.ttf │ │ ├── icomoon.bb221738.svg │ │ ├── opensans-light-webfont.2e2ab17f.woff │ │ ├── opensans-light-webfont.fc71142f.woff2 │ │ ├── opensans-regular-webfont.9503b8a2.woff │ │ └── opensans-regular-webfont.f10027aa.woff2 │ ├── trelliscopejs_widget.js │ └── trelliscopejs_widget.yaml ├── man-roxygen ├── ex-facet_trelliscope.R ├── ex-trelliscope.R ├── param-has-legend.R ├── param-split-aspect.R └── param-split-layout.R ├── man ├── Trelliscope-shiny.Rd ├── as_cognostics.Rd ├── cog.Rd ├── cog_disp_filter.Rd ├── cog_href.Rd ├── cogs.Rd ├── create_cog_template.Rd ├── facet_trelliscope.Rd ├── figures │ └── logo.png ├── img_panel.Rd ├── img_panel_local.Rd ├── input_cogs.Rd ├── input_cogs_api.Rd ├── input_radio.Rd ├── input_text.Rd ├── map2_cog.Rd ├── map2_plot.Rd ├── map_cog.Rd ├── map_plot.Rd ├── md_description.Rd ├── mpg_labels.Rd ├── panels.Rd ├── prepare_display.Rd ├── print.facet_trelliscope.Rd ├── set_labels.Rd ├── sort_spec.Rd ├── tr_charm.Rd ├── trelliscope.Rd ├── trelliscopejs-package.Rd ├── update_display_list.Rd ├── view_item.Rd ├── view_list.Rd ├── write_cognostics.Rd ├── write_config.Rd ├── write_display_obj.Rd ├── write_panel.Rd └── write_panels.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── tests ├── testthat.R └── testthat │ ├── test-trelliscope.R │ └── test-zzz-lintr.R └── vignettes └── trelliscopejs.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | man-roxygen 2 | \.git 3 | ^\.travis\.yml$ 4 | ^\.lintr$ 5 | \.DS_Store 6 | node_modules/ 7 | ..Rcheck 8 | CONTRIBUTING\.md 9 | LICENSE\.md 10 | _ignore 11 | package.json 12 | tools/ 13 | cran-comments.md 14 | ^tools 15 | _test/ 16 | ^codecov\.yml$ 17 | ^_gh-pages$ 18 | ^revdep$ 19 | ^.*\.code-workspace$ 20 | ^appveyor\.yml$ 21 | ^_pkgdown\.yml$ 22 | ^docs$ 23 | ^pkgdown$ 24 | ^CRAN-RELEASE$ 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .tmp 3 | .idea 4 | dist 5 | .publish 6 | _ignore 7 | *.sublime-* 8 | .DS_Store 9 | _test 10 | inst/doc 11 | _gh-pages 12 | *.code-workspace 13 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: with_defaults( 2 | commented_code_linter = NULL, 3 | line_length_linter = line_length_linter(100) 4 | ) 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: R 3 | sudo: false 4 | cache: packages 5 | 6 | r_github_packages: 7 | - schloerke/travisDrat 8 | 9 | after_success: 10 | - Rscript -e "covr::codecov()" 11 | - Rscript -e "packagedocs::deploy_travis()" 12 | - Rscript -e "travisDrat::deploy_drat(drat_repo = 'schloerke/drat', valid_branches = 'master')" 13 | 14 | env: 15 | global: 16 | - secure: o9xvHNCD5Hmb5pw+wiWkWsCxaVb4l6tPJIz6QvQ5HsYAp/c/vP85lSgNq+EQ1wESAOEpclhxhaiJml6ePdzwHslElDHa9hG3OGUaynS1sinpkrBKy2TxDSuLKkgCnuPQO9z7G2vS1ob6uQJkqeExc4YZxCByVYHjucg/mJuMgVyMGoFBMWmDhAB7h+GnRTMBygLl7JmLQug8MQpDmUxKbKUuyFEGTYrvsxB6TrJGFBa42SVebO+os+jfbAEivFNVB4kKe1hwcl3yjsztguJE7d7A2L9s1NYJwEOPIWlhzkMzwTppDD5m79baC2wS8PDq8vvEZWG4Guqq91twZnMDnEKpVUIuD6hGbm+988IYjWCeTtugRHTd91lv4Mi9SiIzMKjbFuCGaNb4/QQwfKA7QfG73GJkUhPx91eM1vLiYVZ4/smQUi/ReuEI7GuhaRdAWP/9kofXQJEzPHPCK/By5wF63T7gV0i2ESLabqUHZZAbyG4ndZ/EuuXAmgUk6IQWJ8k10jJORpJFOOZKpPooIbZVDgW1hqTqK4p9Y4NDZhVCt1iYPUGZ/PV6f06/Zl3bqWi8fEWFgTzLD2nHglPfWwzsdndqusq+3NUrBqO5UyFxw8JoPy2G+lbvIwbJkb8HFDX7vf2Q2JUnYRbdrqdghyXrHZi3H4Tiqb9s8eUIyr8= 17 | - secure: k3WT/jgT0Hj/ZLk5oXAH4UOZWWBebAC1hTsKv6aq63pfBMxzFnhub4TOzai+H4s0X2Nafq6G/eXJhu3liyNBA2FYuZQ5Fat3Vwf6fnKPsslh3hsyeIfSoUweghtfqGY229Q7LETacDu7lSSzshboK7FkEbT2u0A/XqaM/E9OuLjATjhs8C6GhrV6O/FXd2Xos5zOqLkdi75Zm4XN8i/u9D4DxatLZdHmGa4TXTTWJvEIBL6O22+WRDuQLmLqeUV+tpkLCcyPnMOKtIxJQVYBEyIAIuPcI/k9FqAPQQUbRsY5WZmXGSydhwFU8+wHHi65A3AFo/Nh/QhV4jrIFSev41Fm5dXCBprDGpYQEaypdVXNC8Fu7s9lSrucrNXZxNoETeVdh584MHsW7e6XzAFNyEIbscoV6jfLMZK25SBYW7isKhpKGTMJiTV1l5+VCUyrEBTa0HfxWx2wj9ZnDzpkST+IGjPl7dguDGmsZeSnvWNRN5jIsQn9ecx7WV+lXJxmiNu2um0bF2Prcm8EpyjdBBd/UyF396WOwZ5SSAm+mBnlcshhF/+WyynI9+BKuaGVU7p8WJIkKqiBmN0big/1f4B7vg86C2vXi7Rq4vjGq/KJnn4+Yvy4pWuGIq0Gwl7ojqNZ8Q7uYN5LzQGcbht0NnX5/vmspAYSke/BdZeOhAk= 18 | 19 | notifications: 20 | email: 21 | on_success: change 22 | on_failure: change 23 | 24 | branches: 25 | only: 26 | - master 27 | - dev 28 | - travis 29 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: trelliscopejs 2 | Title: Create Interactive Trelliscope Displays 3 | Version: 0.2.10 4 | Authors@R: c( 5 | person(given = "Ryan", 6 | family = "Hafen", 7 | role = c("aut", "cre"), 8 | email = "rhafen@gmail.com", 9 | comment = c(ORCID = "0000-0002-5516-8367")), 10 | person(given = "Barret", 11 | family = "Schloerke", 12 | email = "schloerke@gmail.com", 13 | role = "aut")) 14 | Description: Trelliscope is a scalable, flexible, interactive approach to visualizing data (Hafen, 2013 ). This package provides methods that make it easy to create a Trelliscope display specification for TrelliscopeJS. High-level functions are provided for creating displays from within 'tidyverse' or 'ggplot2' workflows. Low-level functions are also provided for creating new interfaces. 15 | Depends: 16 | R (>= 3.4.0) 17 | License: BSD_3_clause + file LICENSE 18 | Encoding: UTF-8 19 | LazyData: true 20 | Imports: 21 | dplyr, 22 | purrr, 23 | grid, 24 | htmltools, 25 | DistributionUtils, 26 | grDevices, 27 | gtable, 28 | digest, 29 | jsonlite, 30 | ggplot2 (>= 3.2.1), 31 | base64enc, 32 | htmlwidgets, 33 | graphics, 34 | progress, 35 | utils, 36 | knitr, 37 | webshot, 38 | autocogs, 39 | tidyr, 40 | rlang, 41 | fidelius 42 | Suggests: 43 | plotly, 44 | testthat, 45 | covr, 46 | gapminder, 47 | rmarkdown, 48 | shiny, 49 | housingData 50 | RoxygenNote: 7.1.2 51 | URL: https://hafen.github.io/trelliscopejs/, https://github.com/hafen/trelliscopejs 52 | BugReports: https://github.com/hafen/trelliscopejs/issues 53 | VignetteBuilder: knitr 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2016 2 | COPYRIGHT HOLDER: Ryan Hafen 3 | ORGANIZATION: Hafen Consulting, LLC 4 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("[",panel_promise) 4 | S3method("[",trelliscope_cogs) 5 | S3method("[",trelliscope_panels) 6 | S3method(ggplot_add,facet_trelliscope) 7 | S3method(knit_print,facet_trelliscope) 8 | S3method(print,facet_trelliscope) 9 | S3method(print,trelliscopejs_widget) 10 | S3method(trelliscope,data.frame) 11 | export(as_cognostics) 12 | export(cog) 13 | export(cog_disp_filter) 14 | export(cog_href) 15 | export(cogs) 16 | export(create_cog_template) 17 | export(facet_trelliscope) 18 | export(img_panel) 19 | export(img_panel_local) 20 | export(input_cogs) 21 | export(input_cogs_api) 22 | export(input_radio) 23 | export(input_text) 24 | export(map2_cog) 25 | export(map2_plot) 26 | export(map_cog) 27 | export(map_plot) 28 | export(md_description) 29 | export(panels) 30 | export(pmap_cog) 31 | export(pmap_plot) 32 | export(prepare_display) 33 | export(renderTrelliscope) 34 | export(set_labels) 35 | export(sort_spec) 36 | export(tr_charm) 37 | export(trelliscope) 38 | export(trelliscopeOutput) 39 | export(update_display_list) 40 | export(view_item) 41 | export(view_list) 42 | export(write_cognostics) 43 | export(write_config) 44 | export(write_display_obj) 45 | export(write_panel) 46 | export(write_panels) 47 | import(dplyr) 48 | import(ggplot2) 49 | import(htmltools) 50 | import(progress) 51 | importFrom(DistributionUtils,skewness) 52 | importFrom(autocogs,panel_cogs) 53 | importFrom(base64enc,base64encode) 54 | importFrom(digest,digest) 55 | importFrom(fidelius,charm) 56 | importFrom(ggplot2,facet_wrap) 57 | importFrom(ggplot2,ggplot_build) 58 | importFrom(grDevices,nclass.Sturges) 59 | importFrom(grDevices,png) 60 | importFrom(graphics,hist) 61 | importFrom(graphics,plot) 62 | importFrom(gtable,gtable_filter) 63 | importFrom(jsonlite,fromJSON) 64 | importFrom(jsonlite,toJSON) 65 | importFrom(knitr,knit_print) 66 | importFrom(rlang,as_name) 67 | importFrom(rlang,eval_tidy) 68 | importFrom(stats,as.formula) 69 | importFrom(tidyr,nest) 70 | importFrom(tidyr,nest_) 71 | importFrom(tidyr,unnest) 72 | importFrom(utils,packageVersion) 73 | importFrom(webshot,webshot) 74 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # trelliscopejs 0.2 2 | 3 | - Updates for compatibility with dplyr 1.0 (0.2.5) 4 | - Allow non-standard panel objects and message if nothing is plotted 5 | - Make cognostics json full precision 6 | - Add logic to handle rendering if done within a Shiny app 7 | - Remove contents of div prior to rendering widget 8 | - Update trelliscopejs dependency 9 | - Update to use newer tidyr unnest syntax 10 | - Support for linked displays and related displays 11 | 12 | # trelliscopejs 0.1 13 | 14 | - Add auto detection of URL cogs when using cog() explicitly (0.1.18) 15 | - Fix issue with dplyr issue dealing with multiple factor facet columns (0.1.18) 16 | - Fix issue with preserving custom panel column class when sorting and filtering with dplyr (0.1.17) 17 | - Fix bug in auto cognostics with non-numeric/character types, fixes #63 (0.1.16) 18 | - Fix bug in cognostics types not carrying over correctly, fixes #66 (0.1.15) 19 | - Update internals to work with latest ggplot2 (0.1.12) 20 | - Add `plotly_cfg` argument to `facet_trelliscope()` (0.1.11) 21 | - Update trelliscopejs-lib to avoid double slashes in urls (0.1.10) 22 | - Fix issue in checking for Shiny (0.1.9) 23 | - Use `by_row()` from purrrlyr (0.1.8) 24 | - Use webshot for thumbnails and don't create thumbnails by default (0.1.8) 25 | - Update and add new tidyverse functions (0.1.7) 26 | - Update to trelliscopejs-lib 0.1.15 (polyfills for older browser support) (0.1.6) 27 | - Try trelliscopejs-lib with polyfills (0.1.6) 28 | - Add "tidyverse" helper `panels_by_row()` (0.1.6) 29 | - Update to trelliscopejs-lib 0.1.14 (0.1.5) 30 | - Fix issue with total panels not always being stored correctly (0.1.5) 31 | - Update to trelliscopejs-lib 0.1.12 (0.1.4) 32 | - Make sure correct config.json(p) is used and knitr handling is done right (0.1.4) 33 | - Add all dependencies to htmlwidget when `self_contained` is `TRUE` (0.1.4) 34 | - Add test for jsonp = FALSE (0.1.4) 35 | - Add tidyr to test script (0.1.4) 36 | - Fix facet_trelliscope docs to point to the right place (0.1.4) 37 | - Don't import plotly explicitly since it's optional (0.1.4) 38 | - Experimental initial support for ggplotly with facet_trelliscope (0.1.4) 39 | - Update tests (0.1.3) 40 | - Make `as_cognostics()` not always require key and `cond_cols` (0.1.3) 41 | - Fix issue where cog data is written to 'pretty' json when it shouldn't be (0.1.3) 42 | - Fix bug in self_contained where cogs aren't parsed correctly (0.1.3) 43 | - Fix issue where cog data is written to 'pretty' json when it shouldn't be 44 | - Fix bug in self_contained where cogs aren't parsed correctly 45 | - Make nested cogs preserve attributes 46 | - Fix progress bar issue introduced with img_panel 47 | - Add example for `cogs()` 48 | - Add img_panel function 49 | - Update cogs to support panelSrc and make cog_href automatic if URLs detected 50 | - Update trelliscopejs-lib 51 | - Make auto_cog ignore already-computed cognostics 52 | - Add auto_cog option to `trelliscope()` 53 | - Update vignettes 54 | - Update docs 55 | - http -> https 56 | - Update so docs deploy 57 | - Update viewer 58 | - Add vignettes 59 | - Rename things and get facet results to print in knitr 60 | - Add 'cogs' function 61 | - Only look for sorting if cond vars are not sorted 62 | - Update viewer 63 | - Make default sorting on conditional variables rather than default labels 64 | - Add cog_href 65 | - Rename to trelliscopejs 66 | - Remove unnecessary dependencies 67 | - Minor bug fixes and more test coverage 68 | - Add code coverage to travis 69 | - Update README 70 | - Major overhaul to reach initial 'release' 71 | - Add (most) htmlwidget dependencies 72 | - Make trelliscope an htmlwidget 73 | - Add ID for apps to prepare for htmlwidgets 74 | - Add sanitize function 75 | - Add all parameters to facet_trelliscope and sanitize keys 76 | - Sanitize trelliscope args and keys and update example 77 | - Add basic 'trelliscope' function and clean everything else up 78 | - First pass at facet_trelliscope 79 | - Cleaner web paths 80 | - Don't show dir create warnings 81 | - Add a progress bar to write_panels 82 | - Initial commit 83 | -------------------------------------------------------------------------------- /R/abs-path-checking.R: -------------------------------------------------------------------------------- 1 | # The following code was taken directly from the {xfun} package. It is 2 | # licensed under the MIT license. The copyright holder is Yihui Xie. 3 | # See https://github.com/yihui/xfun for the package and details. 4 | 5 | is_abs_path <- function (x) { 6 | if (is_unix()) 7 | grepl("^[/~]", x) 8 | else !same_path(x, file.path(".", x)) 9 | } 10 | 11 | same_path <- function (p1, p2, ...) { 12 | normalize_path(p1, ...) == normalize_path(p2, ...) 13 | } 14 | 15 | normalize_path <- function (x, winslash = "/", must_work = FALSE) { 16 | res = normalizePath(x, winslash = winslash, mustWork = must_work) 17 | if (is_windows()) 18 | res[is.na(x)] = NA 19 | res 20 | } 21 | 22 | is_windows <- function () { 23 | .Platform$OS.type == "windows" 24 | } 25 | 26 | is_unix <- function () { 27 | .Platform$OS.type == "unix" 28 | } 29 | -------------------------------------------------------------------------------- /R/auto_cogs.R: -------------------------------------------------------------------------------- 1 | # 2 | # get_label <- function(data, cols) { 3 | # sapply(cols, function(col) { 4 | # lbl <- attr(data[[col]], "label") 5 | # if (is.null(lbl)) 6 | # lbl <- col 7 | # lbl 8 | # }) 9 | # } 10 | 11 | stop_nice <- function(...) { 12 | stop(paste(strwrap(paste(...), exdent = 7), collapse = "\n"), call. = FALSE) 13 | } 14 | 15 | 16 | # #' Compute automatic cognostics 17 | # #' 18 | # #' @param data a list of data frames (one per subset), a grouped data frame, or a nested data frame 19 | # #' @return If the input is a list of data frames, the return value is a list of data frames containing the cognostics. If the input is a grouped or nested df, the result will be a nested df with a new column containing the cognostics. 20 | # #' @importFrom purrr map map_df 21 | # #' @export 22 | # #' @seealso \code{\link{trelliscope}} 23 | # auto_cogs <- function(data) { 24 | # 25 | # # if a grouped df, nest it so we have a nested df 26 | # if (inherits(data, "grouped_df")) { 27 | # # nesting causes label attributes to be lost, so preserve them... 28 | # # (need to find a better way to deal with this) 29 | # labels <- lapply(data, function(x) attr(x, "label")) 30 | # 31 | # data <- nest(data) 32 | # 33 | # # set first subset label attributes (auto_cogs will look for them here) 34 | # for (nm in names(data$data[[1]])) 35 | # attr(data$data[[1]][[nm]], "label") <- labels[[nm]] 36 | # } 37 | # 38 | # # in the case of nested df, there should be atomic columns indicating splitting variables 39 | # # and then a single "list" column of data frames 40 | # data_is_df <- FALSE 41 | # if (is.data.frame(data)) { 42 | # data_is_df <- TRUE 43 | # 44 | # is_atomic <- sapply(data, is.atomic) 45 | # # at_least_one_atomic <- length(which(is_atomic)) > 0 46 | # exactly_one_non_atomic <- length(which(!is_atomic)) == 1 47 | # if (!exactly_one_non_atomic) 48 | # stop_nice("Data supplied to auto_cogs must be a data frame with a single", 49 | # "nested data frame column.") 50 | # 51 | # nest_nm <- names(data)[which(!is_atomic)] 52 | # 53 | # if (! inherits(data[[nest_nm]][[1]], "data.frame")) 54 | # stop_nice("Data in nested column supplied to auto_cogs must contain data frames.") 55 | # 56 | # cog_data <- data[[nest_nm]] 57 | # } else { 58 | # cog_data <- data 59 | # } 60 | # 61 | # # cog_spec is a list specifying the cognostics and their descriptions 62 | # # so that we can add these in later 63 | # 64 | # ## determine which columns to compute what kind of cognostics for 65 | # cog_spec <- list( 66 | # count = tibble(col = NA, cogname = "count", desc = "number of observations") 67 | # ) 68 | # 69 | # # if any columns are unique per group, add them as an "identity" cognostic 70 | # tmp <- cog_data %>% purrr::map_df(. %>% summarise_all(n_distinct)) 71 | # unique_cols <- names(tmp)[sapply(tmp, function(x) all(x == 1))] 72 | # if (length(unique_cols) > 0) { 73 | # cog_spec$unique <- tibble( 74 | # col = unique_cols, 75 | # cogname = sanitize(unique_cols), 76 | # desc = get_label(cog_data[[1]], unique_cols)) 77 | # } 78 | # 79 | # # if numeric and not unique, get the mean (TODO - other summary stats and group them) 80 | # num_cols <- names(cog_data[[1]])[sapply(cog_data[[1]], is.numeric)] 81 | # num_cols <- setdiff(num_cols, unique_cols) 82 | # if (length(num_cols) > 0) 83 | # cog_spec$num <- tibble( 84 | # col = num_cols, 85 | # cogname = paste0(sanitize(num_cols), "_mean"), 86 | # desc = paste("mean", get_label(cog_data[[1]], num_cols))) 87 | # 88 | # tmp <- bind_rows(cog_spec) 89 | # cog_desc <- as.list(tmp$desc) 90 | # names(cog_desc) <- tmp$cogname 91 | # 92 | # res <- map_cog(cog_data, function(x) { 93 | # res <- tibble(count = nrow(x)) 94 | # for (ii in seq_along(cog_spec$unique$col)) 95 | # res[[cog_spec$unique$cogname[ii]]] <- x[[cog_spec$unique$col[ii]]][1] 96 | # for (ii in seq_along(cog_spec$num$col)) 97 | # res[[cog_spec$num$cogname[ii]]] <- mean(x[[cog_spec$num$col[ii]]]) 98 | # res 99 | # }) 100 | # 101 | # if (data_is_df) { 102 | # return( 103 | # data %>% 104 | # mutate(auto_cogs = res) 105 | # ) 106 | # } else { 107 | # return(res) 108 | # } 109 | # } 110 | -------------------------------------------------------------------------------- /R/charm.R: -------------------------------------------------------------------------------- 1 | #' Use fidelius to password protect a trelliscope display 2 | #' @param x an object of class "facet_trelliscope" or 3 | #' "trelliscopejs_widget" 4 | #' @param ... arguments passed to [fidelius::charm()] 5 | #' @export 6 | tr_charm <- function(x, ...) { 7 | if (!inherits(x, c("facet_trelliscope", "trelliscopejs_widget"))) 8 | stop("Can only call tr_charm() on a trelliscope object") 9 | attr(x, "fidelius_pars") <- list(...) 10 | x 11 | } 12 | -------------------------------------------------------------------------------- /R/htmlwidget.R: -------------------------------------------------------------------------------- 1 | trelliscope_widget <- function(id, config_info, www_dir, latest_display, 2 | dependencies = NULL, self_contained, spa = TRUE, width = NULL, height = NULL, 3 | sc_deps = NULL) { 4 | 5 | # TODO: warn if width or height are too small 6 | 7 | # forward options using x 8 | x <- list( 9 | id = id, 10 | config_info = config_info, 11 | self_contained = self_contained, 12 | latest_display = latest_display, 13 | spa = spa, 14 | in_knitr = is_in_knitr(), 15 | in_shiny = is_in_shiny(), 16 | in_notebook = in_rmarkdown_notebook()) 17 | 18 | if (spa) { 19 | width <- height <- "100%" 20 | } 21 | 22 | deps <- NULL 23 | if (self_contained && is.list(sc_deps) && length(sc_deps) > 1) { 24 | dnms <- sapply(sc_deps, function(x) x$name) 25 | deps <- sc_deps[dnms != "htmlwidgets"] 26 | } 27 | 28 | # create widget 29 | wdgt <- htmlwidgets::createWidget( 30 | name = "trelliscopejs_widget", 31 | x, 32 | width = width, 33 | height = height, 34 | dependencies = deps, 35 | package = "trelliscopejs", 36 | sizingPolicy = htmlwidgets::sizingPolicy(padding = 0, browser.fill = TRUE, 37 | knitr.defaultWidth = 900, knitr.defaultHeight = 550, knitr.figure = FALSE, 38 | viewer.defaultWidth = "100%", viewer.defaultHeight = "100%", viewer.padding = 0, 39 | viewer.fill = TRUE, 40 | browser.defaultWidth = "100%", browser.defaultHeight = "100%", browser.padding = 0), 41 | preRenderHook = prerender_selfcontained 42 | ) 43 | 44 | # don't want these to get shipped in the html page 45 | # but we do want them to persist so we can edit the object... 46 | attr(wdgt, "trelliscope_pars") <- list( 47 | www_dir = www_dir 48 | ) 49 | 50 | return(wdgt) 51 | } 52 | 53 | prerender_selfcontained <- function(x) { 54 | if (x$x$self_contained) { 55 | www_dir <- attr(x, "trelliscope_pars")$www_dir 56 | path <- file.path(www_dir, "appfiles") 57 | disp_path <- file.path(path, "displays", x$x$latest_display$group, 58 | x$x$latest_display$name) 59 | pfs <- list.files(file.path(disp_path, "json"), full.names = TRUE) 60 | panels <- lapply(pfs, function(f) 61 | readLines(f, warn = FALSE)) 62 | names(panels) <- basename(gsub("\\.json$", "", pfs)) 63 | 64 | x$x$config_info <- paste0("{ \"config\": ", 65 | paste(readLines(file.path(path, "config.json"), warn = FALSE), 66 | collapse = ""), 67 | ", \"displayList\": ", 68 | paste(readLines(file.path(path, "displays", "displayList.json"), warn = FALSE), 69 | collapse = ""), 70 | ", \"displayObj\": ", 71 | readLines(file.path(disp_path, "displayObj.json"), warn = FALSE), 72 | ", \"cogData\": ", 73 | paste(readLines(file.path(disp_path, "cogData.json"), warn = FALSE), 74 | collapse = ""), 75 | ", \"panels\": {", 76 | paste("\"", names(panels), "\": ", panels, sep = "", collapse = ", "), 77 | "}}") 78 | } else { 79 | x$x$config_info <- paste0("'", x$x$config_info, "'") 80 | } 81 | x 82 | } 83 | 84 | #' @importFrom knitr knit_print 85 | #' @export 86 | knit_print.facet_trelliscope <- function(x, ..., options = NULL) { 87 | x <- print.facet_trelliscope(x) 88 | knitr::knit_print(x, ..., options = options) 89 | } 90 | 91 | # nolint start 92 | 93 | # Override print.htmlwidget for trelliscopejs_widget so we can control the output location 94 | #' @export 95 | print.trelliscopejs_widget <- function(x, ..., view = interactive()) { 96 | 97 | if (x$x$in_notebook && x$x$self_contained) { 98 | print_fn <- try(get("print.htmlwidget"), silent = TRUE) 99 | if (!inherits(print_fn, "try-error")) { 100 | return(print_fn(x)) 101 | } 102 | } 103 | 104 | # if (x$x$self_contained) { 105 | # # we want to use the 106 | # class(x) <- gsub("trelliscopejs_widget", "trelliscopejs_widget2", class(x)) 107 | # return(print(x)) 108 | # } 109 | 110 | # if we have a viewer then forward viewer pane height (if any) 111 | viewer <- getOption("viewer") 112 | if (!is.null(viewer)) { 113 | viewerFunc <- function(url) { 114 | 115 | # get the requested pane height (it defaults to NULL) 116 | paneHeight <- x$sizingPolicy$viewer$paneHeight 117 | 118 | # convert maximize to -1 for compatibility with older versions of rstudio 119 | # (newer versions convert 'maximize' to -1 interally, older versions 120 | # will simply ignore the height if it's less than zero) 121 | if (identical(paneHeight, "maximize")) 122 | paneHeight <- -1 123 | 124 | # call the viewer 125 | viewer(url, height = paneHeight) 126 | } 127 | } else { 128 | viewerFunc <- utils::browseURL 129 | } 130 | 131 | www_dir <- attr(x, "trelliscope_pars")$www_dir 132 | 133 | # TODO: check if www_dir is in tempdir() or not and handle / warn appropriately 134 | # based on self_contained, etc. 135 | 136 | # call html_print with the viewer 137 | el_tags <- htmltools::as.tags(x, standalone = FALSE) 138 | trelliscope_html_print(el_tags, 139 | www_dir = www_dir, 140 | viewer = if (view) viewerFunc, 141 | fidelius_pars = attr(x, "fidelius_pars") 142 | ) 143 | 144 | # return value 145 | invisible(x) 146 | } 147 | 148 | # nolint end 149 | 150 | #' @importFrom fidelius charm 151 | trelliscope_html_print <- function(html, www_dir = NULL, background = "white", 152 | viewer = getOption("viewer", utils::browseURL), fidelius_pars = NULL) { 153 | 154 | if (is.null(www_dir)) 155 | www_dir <- tempfile("viewhtml") 156 | if (!dir.exists(www_dir)) 157 | dir.create(www_dir) 158 | www_dir <- normalizePath(www_dir) 159 | index_html <- file.path(www_dir, "index.html") 160 | 161 | htmltools::save_html(html, file = index_html, background = background, 162 | libdir = "lib") 163 | 164 | if (!is.null(fidelius_pars)) { 165 | fidelius_pars$input <- index_html 166 | do.call(fidelius::charm, fidelius_pars) 167 | } 168 | 169 | if (!is.null(viewer)) 170 | viewer(index_html) 171 | 172 | invisible(index_html) 173 | } 174 | 175 | # nolint start 176 | 177 | #' Shiny bindings for Trelliscope 178 | #' 179 | #' Output and render functions for using trelliscopejs_widget within Shiny 180 | #' applications and interactive Rmd documents. 181 | #' 182 | #' @param outputId output variable to read from 183 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 184 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 185 | #' string and have \code{'px'} appended. 186 | #' @param expr An expression that generates a trelliscopejs_widget 187 | #' @param env The environment in which to evaluate \code{expr}. 188 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 189 | #' is useful if you want to save an expression in a variable. 190 | #' 191 | #' @name Trelliscope-shiny 192 | #' 193 | #' @export 194 | trelliscopeOutput <- function(outputId, width = "100%", height = "400px") { 195 | htmlwidgets::shinyWidgetOutput(outputId, "trelliscopejs_widget", width, height, 196 | package = "trelliscopejs") 197 | } 198 | 199 | #' @rdname Trelliscope-shiny 200 | #' @export 201 | renderTrelliscope <- function(expr, env = parent.frame(), quoted = FALSE) { 202 | if (!quoted) { 203 | expr <- substitute(expr) 204 | } # force quoted 205 | htmlwidgets::shinyRenderWidget(expr, trelliscopeOutput, env, quoted = TRUE) 206 | } 207 | 208 | # nolint end 209 | -------------------------------------------------------------------------------- /R/input_cogs.R: -------------------------------------------------------------------------------- 1 | #' Specify a collection of input cognostics to be stored in browser localStorage 2 | #' 3 | #' @param \ldots objects created by any of \code{\link{input_radio}}, 4 | #' \code{\link{input_text}} 5 | #' @param feedback_email optional feedback email address that input feedback can be sent to 6 | #' @param extra_cogs optional vector of names of non-input "regular" cognostics to include in the csv output 7 | #' @export 8 | input_cogs <- function(..., 9 | feedback_email = NULL, 10 | extra_cogs = NULL 11 | ) { 12 | is_input <- unlist(lapply(list(...), function(x) 13 | inherits(x, "input_cog"))) 14 | if (!all(is_input)) 15 | stop("All 'input_cogs()' arguments must be of type 'input_cog'.", 16 | call. = FALSE) 17 | 18 | if (is.null(extra_cogs)) 19 | extra_cogs <- list() 20 | 21 | res <- structure(list(...), class = c("input_cogs", "list")) 22 | attr(res, "feedback_email") <- feedback_email 23 | attr(res, "input_csv_vars") <- extra_cogs 24 | attr(res, "input_type") <- "localStorage" 25 | 26 | res 27 | } 28 | 29 | #' Specify a collection of input cognostics to be stored using an API 30 | #' 31 | #' @param \ldots objects created by any of \code{\link{input_radio}}, 32 | #' \code{\link{input_text}} 33 | #' @param set_url URL of the API endpoint for setting a single input 34 | #' @param get_url URL of the API endpoint for getting all inputs for the display 35 | #' @param get_request_options request options for the API call to set inputs 36 | #' @param set_request_options request options for the API call to get inputs 37 | #' @details See [here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options for more information about request options. 38 | #' @export 39 | input_cogs_api <- function(..., 40 | set_url, 41 | get_url, 42 | get_request_options = list( 43 | mode = "cors", 44 | method = "GET","headers" = list( 45 | `Content-Type` = "application/json", 46 | Accept = "application/json" 47 | ) 48 | ), 49 | set_request_options = list( 50 | mode = "cors", 51 | method = "POST", 52 | headers = list( 53 | `Content-Type` = "application/json", 54 | Accept = "application/json" 55 | ) 56 | ) 57 | ) { 58 | is_input <- unlist(lapply(list(...), function(x) 59 | inherits(x, "input_cog"))) 60 | if (!all(is_input)) 61 | stop("All 'input_cogs()' arguments must be of type 'input_cog'.", 62 | call. = FALSE) 63 | 64 | input_api <- list( 65 | get = get_url, 66 | set = set_url, 67 | getRequestOptions = get_request_options, 68 | setRequestOptions = set_request_options 69 | ) 70 | 71 | res <- structure(list(...), class = c("input_cogs", "", "list")) 72 | attr(res, "input_api") <- input_api 73 | attr(res, "input_type") <- "API" 74 | 75 | res 76 | } 77 | 78 | #' Specify a radio button input 79 | #' 80 | #' @param name name of the input 81 | #' @param desc optional description of the input 82 | #' @param options a character vector of options to select between 83 | #' @param group optional categorization of the input for organizational purposes in the viewer (currently not implemented in the viewer) 84 | #' @param default_label should this input be shown under the panel in the viewer by default? 85 | #' @export 86 | input_radio <- function(name, desc = NULL, options, group = NULL, 87 | default_label = TRUE) { 88 | 89 | structure(list( 90 | name = name, 91 | desc = ifelse(is.null(desc), name, desc), 92 | type = "input_radio", 93 | options = options, 94 | group = ifelse(is.null(group), "input", group), 95 | defLabel = default_label, 96 | defActive = TRUE, 97 | filterable = FALSE 98 | ), class = c("input_cog", "input_radio", "list")) 99 | } 100 | 101 | #' Specify a text input 102 | #' 103 | #' @param name name of the input 104 | #' @param desc optional description of the input 105 | #' @param width width (in characters) of the text box popout 106 | #' @param height height (in lines of text) of the text box popout 107 | #' @param group optional categorization of the input for organizational purposes in the viewer (currently not implemented in the viewer) 108 | #' @param default_label should this input be shown under the panel in the viewer by default? 109 | #' @export 110 | input_text <- function(name, desc = NULL, width = 80, height = 3, 111 | group = NULL, default_label = TRUE) { 112 | 113 | structure(list( 114 | name = name, 115 | desc = ifelse(is.null(desc), name, desc), 116 | type = "input_text", 117 | width = width, 118 | height = height, 119 | group = ifelse(is.null(group), "input", group), 120 | defLabel = default_label, 121 | defActive = TRUE, 122 | filterable = FALSE 123 | ), class = c("input_cog", "input_text", "list")) 124 | } 125 | -------------------------------------------------------------------------------- /R/make_png.R: -------------------------------------------------------------------------------- 1 | get_png_units <- function(width, height, orig_width = width, res = 72, 2 | base_point_size = 12, pixelratio = 2) { 3 | 4 | width <- as.numeric(gsub("px", "", width)) 5 | height <- as.numeric(gsub("px", "", height)) 6 | orig_width <- as.numeric(gsub("px", "", orig_width)) 7 | 8 | # need to convert unit to pixels 9 | # need to have 'fac' factor if coming from unit 10 | width_is_unit <- height_is_unit <- FALSE 11 | if (inherits(width, "unit")) { 12 | width <- unit_to_px(width, res) 13 | orig_width <- width 14 | width_is_unit <- TRUE 15 | } 16 | if (inherits(height, "unit")) { 17 | height <- unit_to_px(height, res) 18 | orig_height <- height 19 | height_is_unit <- TRUE 20 | } 21 | 22 | fac <- max(min(width / orig_width, 1), 0.65) * 1.5 23 | pointsize <- base_point_size 24 | 25 | list( 26 | res = res * pixelratio * fac, 27 | width = width * pixelratio * ifelse(width_is_unit, fac, 1), 28 | height = height * pixelratio * ifelse(height_is_unit, fac, 1), 29 | pointsize = base_point_size * fac 30 | ) 31 | } 32 | 33 | #' @importFrom grDevices png 34 | make_png <- function(p, file, width, height, orig_width = width, res = 72, 35 | base_point_size = 12, pixelratio = 2) { 36 | 37 | pngfun <- grDevices::png 38 | # if (capabilities("aqua")) { 39 | # } else { 40 | # pkg <- "Cairo" # nolint 41 | # if (suppressWarnings(suppressMessages(require(pkg, character.only = TRUE)))) { 42 | # pngfun <- Cairo::CairoPNG 43 | # } else { 44 | # pngfun <- grDevices::png 45 | # } 46 | # } 47 | 48 | units <- get_png_units(width, height, orig_width, res, 49 | base_point_size, pixelratio) 50 | 51 | pngfun(filename = file, 52 | res = units$res, 53 | width = units$width, 54 | height = units$height, 55 | pointsize = units$pointsize) 56 | 57 | unknown_object <- FALSE 58 | dv <- grDevices::dev.cur() 59 | tryCatch({ 60 | if (inherits(p, "trellis")) { 61 | # p$par.settings$fontsize <- list(text = pointsize, points = pointsize * 2 / 3) 62 | print(p) 63 | } else if (inherits(p, "ggplot")) { 64 | print(p) 65 | } else if (inherits(p, "gtable")) { 66 | grid::grid.draw(p) 67 | } else { 68 | unknown_object <- TRUE 69 | try(print(p), silent = TRUE) 70 | } 71 | }, 72 | finally = grDevices::dev.off(dv)) 73 | 74 | # if panel function didn't plot anything then make a blank panel 75 | # res = res * pixelratio, 76 | if (!file.exists(file)) { 77 | if (unknown_object) { 78 | cls <- paste(class(p), collapse = ", ") 79 | message("The panel object of class'", cls, 80 | "' is not a standard plot object and did not produce a panel file.") 81 | } 82 | pngfun(filename = file, width = width * pixelratio, height = height * pixelratio, 83 | pointsize = units$pointsize) 84 | blank_image("no panel") 85 | grDevices::dev.off() 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /R/state.R: -------------------------------------------------------------------------------- 1 | ## functions to check and help specify state 2 | ## (lots to do here and all subject to change...) 3 | ##--------------------------------------------------------- 4 | 5 | #' Specify how a display should be sorted 6 | #' 7 | #' @param name variable name to sort on 8 | #' @param dir direction to sort ('asc' or 'desc') 9 | #' @export 10 | sort_spec <- function(name, dir = "asc") { 11 | list(name = name, dir = dir) 12 | } 13 | 14 | # #' Specify how a display should be filtered 15 | # #' 16 | # #' @param name variable name to sort on 17 | # #' @param type either "select" or "regex" 18 | # #' @param value If \code{type} is "select", a vector of values to select. If \code{type} is "regex", a string indicating a regular expression 19 | # filter_cat_spec <- function(name, type = c("select", "regex"), value) { 20 | # if (type == "regex" && length(value) > 1) 21 | # stop_nice("If specifying a filter of type 'regex', the value must be a string.") 22 | # list(name = name, type = type, value = value) 23 | # } 24 | 25 | # #' Specify how a display should be filtered 26 | # #' 27 | # #' @param name variable name to sort on 28 | # #' @param type either "select" or "regex" 29 | # #' @param value If \code{type} is "select", a vector of values to select. If \code{type} is "regex", a string indicating a regular expression 30 | # filter_num_spec <- function(name, from = NA, to = NA) { 31 | # list(name = name, from = from, to = to) 32 | # } 33 | -------------------------------------------------------------------------------- /R/thumbnail.R: -------------------------------------------------------------------------------- 1 | write_thumb <- function(panel_example, path, width, height, thumb = TRUE) { 2 | if (is.character(panel_example) && file.exists(panel_example)) { 3 | ext <- tools::file_ext(panel_example) 4 | if (ext == "png") { 5 | path <- paste0(tools::file_path_sans_ext(path), ".", ext) 6 | file.copy(thumb, path) 7 | } 8 | } else { 9 | if (thumb) { 10 | if (inherits(panel_example, "htmlwidget")) { 11 | widget_thumbnail(panel_example, path, width, height) 12 | } else { 13 | suppressMessages( 14 | make_png(panel_example, file = path, 15 | width = width, height = height)) 16 | } 17 | } 18 | 19 | # need "!thumb" in case overwriting existing 20 | if (!file.exists(path) || !thumb) { 21 | suppressMessages( 22 | make_png(blank_image(), file = path, 23 | width = width, height = height)) 24 | } 25 | } 26 | } 27 | 28 | #' @importFrom graphics plot 29 | #' @importFrom webshot webshot 30 | widget_thumbnail <- function(p, thumb_path, width, height, delay = 0.5) { 31 | thumb_path <- path.expand(thumb_path) 32 | 33 | success <- FALSE 34 | res <- try({ 35 | ff <- tempfile(fileext = ".html") 36 | ffjs <- tempfile(fileext = ".js") 37 | 38 | # don't want any padding 39 | p$sizingPolicy$padding <- 0 # nolint 40 | suppressMessages(htmlwidgets::saveWidget(p, ff, selfcontained = FALSE)) 41 | 42 | webshot::webshot(paste0("file://", ff), thumb_path, vwidth = width, vheight = height, 43 | delay = delay) 44 | }, silent = TRUE) 45 | if (!inherits(res, "try-error")) { 46 | success <- TRUE 47 | } 48 | if (!file.exists(thumb_path)) 49 | success <- FALSE 50 | 51 | if (!success) 52 | message("* could not create htmlwidget thumbnail... will use blank thumbnail...") 53 | } 54 | 55 | #' @import ggplot2 56 | blank_image <- function(txt = "no thumbnail") { 57 | ggplot(data = data.frame(x = 0.5, y = 0.75, label = txt)) + 58 | geom_text(aes(x = x, y = y, label = label), size = 8) + 59 | labs(x = NULL, y = NULL, title = NULL) + 60 | scale_x_continuous(expand = c(0, 0), limits = c(0, 1)) + 61 | scale_y_continuous(expand = c(0, 0), limits = c(0, 1)) + 62 | theme( 63 | panel.background = element_rect(fill = "transparent", colour = NA), 64 | plot.background = element_rect(fill = "transparent", colour = NA), 65 | panel.grid = element_blank(), 66 | panel.border = element_blank(), 67 | plot.margin = unit(c(0, 0, 0, 0), "null"), 68 | axis.ticks = element_blank(), 69 | axis.text = element_blank(), 70 | axis.title = element_blank(), 71 | axis.line = element_blank(), 72 | legend.position = "none", 73 | axis.ticks.length = unit(0, "null") 74 | ) 75 | } 76 | -------------------------------------------------------------------------------- /R/trelliscopejs-package.R: -------------------------------------------------------------------------------- 1 | utils::globalVariables(c(".", "x", "y", "label")) 2 | 3 | #' trelliscopejs 4 | #' 5 | #' Create interactive Trelliscope displays 6 | #' 7 | #' \url{https://hafen.github.io/trelliscopejs/} 8 | #' 9 | #' @name trelliscopejs-package 10 | #' @examples 11 | #' help(package = trelliscopejs) 12 | #' @docType package 13 | NULL 14 | 15 | #' Labels for ggplot2 "mpg" data 16 | #' 17 | "mpg_labels" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Build Status](https://travis-ci.org/hafen/trelliscopejs.svg?branch=master)](https://travis-ci.org/hafen/trelliscopejs) 3 | [![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/hafen/trelliscopejs?branch=master&svg=true)](https://ci.appveyor.com/project/hafen/trelliscopejs) 4 | [![codecov.io](https://codecov.io/github/hafen/trelliscopejs/coverage.svg?branch=master)](https://codecov.io/github/hafen/trelliscopejs?branch=master) 5 | [![CRAN](http://www.r-pkg.org/badges/version/trelliscopejs)](https://cran.r-project.org/package=trelliscopejs) 6 | 7 | 8 | # trelliscopejs 9 | 10 | Trelliscope is a scalable, flexible, interactive approach to visualizing data. The trelliscopejs R package provides methods that make it easy to create a Trelliscope display specification for the Trelliscope JavaScript library [trelliscopejs-lib](https://github.com/hafen/trelliscopejs-lib). High-level functions are provided for creating displays from within dplyr (via `summarise()`) or ggplot2 (via `facet_trelliscope()`) workflows. Low-level functions are also provided for creating new interfaces. 11 | 12 | ### Install 13 | 14 | ```r 15 | install.packages("trelliscopejs") 16 | ``` 17 | 18 | To install the latest development version: 19 | 20 | ```r 21 | # install.packages("remotes") # if "remotes" is not already installed 22 | devtools::install_github("hafen/trelliscopejs") 23 | ``` 24 | 25 | ## Demos 26 | 27 | - [Gapminder](https://hafen.github.io/trelliscopejs-demo/gapminder/) 28 | - [Gapminder with Plotly panels](https://hafen.github.io/trelliscopejs-demo/gapminder_plotly/) 29 | - [Monthly U.S. home prices by county](https://hafen.github.io/trelliscopejs-demo/housing/) 30 | - [Pokemon](https://hafen.github.io/trelliscopejs-demo/pokemon/) 31 | 32 | ## Examples 33 | 34 | Here is a simple example using the ggplot2 interface. Using trelliscopejs in this way is as easy as swapping `facet_wrap()` with `facet_trelliscope()` and specifying some additional options. 35 | 36 | Please see the [package vignettes](https://hafen.github.io/trelliscopejs/) for more. 37 | 38 | ```r 39 | library(trelliscopejs) 40 | library(ggplot2) 41 | library(gapminder) 42 | 43 | qplot(year, lifeExp, data = gapminder) + 44 | xlim(1948, 2011) + ylim(10, 95) + theme_bw() + 45 | facet_trelliscope(~ country + continent, nrow = 2, ncol = 7, width = 300) 46 | ``` 47 | 48 |
49 |
50 |
51 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: docs 2 | 3 | toc: 4 | depth: 1 5 | 6 | reference: 7 | - title: "Trelliscope Functions" 8 | desc: "Functions for creating Trelliscope displays." 9 | contents: 10 | - trelliscope 11 | - facet_trelliscope 12 | - img_panel 13 | - img_panel_local 14 | - print.facet_trelliscope 15 | - title: "Cognostics" 16 | desc: "Functions for creating and modifying the behavior of cognostics." 17 | contents: 18 | - cog 19 | - cog_href 20 | - cogs 21 | - cog_disp_filter 22 | - title: "Helpers" 23 | desc: "Helper functions for working in the tidyverse." 24 | contents: 25 | - map2_cog 26 | - map2_plot 27 | - map_cog 28 | - map_plot 29 | - panels 30 | - set_labels 31 | - sort_spec 32 | - title: "Low-level Functions" 33 | desc: "Low-level functions." 34 | contents: 35 | - prepare_display 36 | - update_display_list 37 | - write_cognostics 38 | - write_config 39 | - write_display_obj 40 | - write_panel 41 | - write_panels 42 | - as_cognostics 43 | - title: "Datasets" 44 | desc: "Datasets" 45 | contents: 46 | - mpg_labels 47 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | cache: 14 | - C:\RLibrary 15 | 16 | environment: 17 | NOT_CRAN: true 18 | # env vars that may need to be set, at least temporarily, from time to time 19 | # see https://github.com/krlmlr/r-appveyor#readme for details 20 | # USE_RTOOLS: true 21 | # R_REMOTES_STANDALONE: true 22 | 23 | # Adapt as necessary starting from here 24 | 25 | build_script: 26 | - travis-tool.sh install_deps 27 | 28 | test_script: 29 | - travis-tool.sh run_tests 30 | 31 | on_failure: 32 | - 7z a failure.zip *.Rcheck\* 33 | - appveyor PushArtifact failure.zip 34 | 35 | artifacts: 36 | - path: '*.Rcheck\**\*.log' 37 | name: Logs 38 | 39 | - path: '*.Rcheck\**\*.out' 40 | name: Logs 41 | 42 | - path: '*.Rcheck\**\*.fail' 43 | name: Logs 44 | 45 | - path: '*.Rcheck\**\*.Rout' 46 | name: Logs 47 | 48 | - path: '\*_*.tar.gz' 49 | name: Bits 50 | 51 | - path: '\*_*.zip' 52 | name: Bits 53 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | range: "70...95" 5 | status: 6 | patch: 7 | default: 8 | branches: 9 | - master 10 | - dev 11 | target: '80' 12 | project: 13 | default: 14 | branches: 15 | - master 16 | - dev 17 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | Resubmission: 2 | 3 | Addressed possibly invalid URL corrections requests. 4 | 5 | ## Test environments 6 | 7 | * local OS X install, R 4.0.3 8 | * ubuntu 16.04 (on travis-ci), R 4.0.2 9 | * Windows R (on Appveyor) R 4.0.3 10 | * win-builder (devel and release) 11 | 12 | ## R CMD check results 13 | 14 | 0 errors | 0 warnings | 0 notes 15 | 16 | ## Reverse dependencies 17 | 18 | There are no reverse dependencies. 19 | -------------------------------------------------------------------------------- /data/mpg_labels.R: -------------------------------------------------------------------------------- 1 | mpg_labels <- list( 2 | model = "model name", 3 | displ = "engine displacement, in litres", 4 | year = "year of manufacture", 5 | cyl = "number of cylinders", 6 | trans = "type of transmission", 7 | drv = "front / rear / 4-wheel drive", 8 | cty = "city miles per gallon", 9 | hwy = "highway miles per gallon", 10 | fl = "fuel type", 11 | class = "type of car" 12 | ) 13 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page not found (404) • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 | 116 | 117 | 118 | 119 |
120 | 121 |
122 |
123 | 126 | 127 | Content not found. Please use links in the navbar. 128 | 129 |
130 | 131 | 136 | 137 |
138 | 139 | 140 | 141 |
142 | 145 | 146 |
147 |

Site built with pkgdown 1.6.1.

148 |
149 | 150 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 | 116 | 117 | 118 | 119 |
120 | 121 |
122 |
123 | 126 | 127 |
YEAR: 2016
128 | COPYRIGHT HOLDER: Ryan Hafen
129 | ORGANIZATION: Hafen Consulting, LLC
130 | 
131 | 132 |
133 | 134 | 139 | 140 |
141 | 142 | 143 | 144 |
145 | 148 | 149 |
150 |

Site built with pkgdown 1.6.1.

151 |
152 | 153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /docs/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Articles • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 | 116 | 117 | 118 | 119 |
120 | 121 |
122 |
123 | 126 | 127 |
128 |

All vignettes

129 |

130 | 131 |
132 |
Introduction to trelliscopejs
133 |
134 |
135 |
136 |
137 |
138 | 139 | 140 |
141 | 144 | 145 |
146 |

Site built with pkgdown 1.6.1.

147 |
148 | 149 |
150 |
151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/articles/trelliscopejs_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 | 116 | 117 | 118 | 119 |
120 | 121 |
122 |
123 | 126 | 127 |
    128 |
  • 129 |

    Ryan Hafen. Author, maintainer. 130 |

    131 |
  • 132 |
  • 133 |

    Barret Schloerke. Author. 134 |

    135 |
  • 136 |
137 | 138 |
139 | 140 |
141 | 142 | 143 | 144 |
145 | 148 | 149 |
150 |

Site built with pkgdown 1.6.1.

151 |
152 | 153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/favicon.ico -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/logo.png -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent; 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.2.3.2 2 | pkgdown: 1.6.1 3 | pkgdown_sha: ~ 4 | articles: 5 | trelliscopejs: trelliscopejs.html 6 | last_built: 2021-01-28T00:49Z 7 | 8 | -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/figures/trelliscope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/docs/reference/figures/trelliscope.png -------------------------------------------------------------------------------- /docs/reference/img_panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Cast a vector of URLs pointing to images as an image panel source — img_panel • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Cast a vector of URLs pointing to images as an image panel source

    132 |
    133 | 134 |
    img_panel(x)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 |
    x

    a vector of URLs pointing to images

    144 | 145 | 146 |
    147 | 152 |
    153 | 154 | 155 |
    156 | 159 | 160 |
    161 |

    Site built with pkgdown 1.6.1.

    162 |
    163 | 164 |
    165 |
    166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /docs/reference/mpg_labels.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Labels for ggplot2 "mpg" data — mpg_labels • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Labels for ggplot2 "mpg" data

    132 |
    133 | 134 |
    mpg_labels
    135 | 136 | 137 |

    Format

    138 | 139 |

    An object of class list of length 10.

    140 | 141 |
    142 | 147 |
    148 | 149 | 150 |
    151 | 154 | 155 |
    156 |

    Site built with pkgdown 1.6.1.

    157 |
    158 | 159 |
    160 |
    161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/reference/prepare_display.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set up all auxiliary files needed for a Trelliscope app — prepare_display • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Set up all auxiliary files needed for a Trelliscope app

    132 |
    133 | 134 |
    prepare_display(base_path, id, self_contained = FALSE, jsonp = TRUE, pb = NULL)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 |
    base_path

    the base directory of the trelliscope application

    id

    a unique id for the application

    self_contained

    should the Trelliscope display be a self-contained html document?

    jsonp

    should json for display list and app config be jsonp (TRUE) or json (FALSE)?

    pb

    optional progress bar object to pass in and use to report progress

    160 | 161 | 162 |
    163 | 168 |
    169 | 170 | 171 |
    172 | 175 | 176 |
    177 |

    Site built with pkgdown 1.6.1.

    178 |
    179 | 180 |
    181 |
    182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /docs/reference/print.facet_trelliscope.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Print facet trelliscope object — print.facet_trelliscope • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Print facet trelliscope object

    132 |
    133 | 134 |
    # S3 method for facet_trelliscope
    135 | print(x, ...)
    136 | 137 |

    Arguments

    138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
    x

    plot object

    ...

    ignored

    149 | 150 | 151 |
    152 | 157 |
    158 | 159 | 160 |
    161 | 164 | 165 |
    166 |

    Site built with pkgdown 1.6.1.

    167 |
    168 | 169 |
    170 |
    171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /docs/reference/set_labels.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set labels for a data frame — set_labels • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Set labels for a data frame

    132 |
    133 | 134 |
    set_labels(dat, label_list)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
    dat

    a data frame to apply labels to

    label_list

    a named list with names matching those of dat and values being labels

    148 | 149 |

    Value

    150 | 151 |

    data frame with labels attached as attributes (attached to each column and named "label")

    152 | 153 |
    154 | 159 |
    160 | 161 | 162 |
    163 | 166 | 167 |
    168 |

    Site built with pkgdown 1.6.1.

    169 |
    170 | 171 |
    172 |
    173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /docs/reference/sort_spec.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Specify how a display should be sorted — sort_spec • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Specify how a display should be sorted

    132 |
    133 | 134 |
    sort_spec(name, dir = "asc")
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
    name

    variable name to sort on

    dir

    direction to sort ('asc' or 'desc')

    148 | 149 | 150 |
    151 | 156 |
    157 | 158 | 159 |
    160 | 163 | 164 |
    165 |

    Site built with pkgdown 1.6.1.

    166 |
    167 | 168 |
    169 |
    170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /docs/reference/trelliscopejs-package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | trelliscopejs — trelliscopejs-package • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Create interactive Trelliscope displays

    132 |
    133 | 134 | 135 | 136 |

    Details

    137 | 138 |

    https://hafen.github.io/trelliscopejs/

    139 | 140 |

    Examples

    141 |
    help(package = trelliscopejs) 142 |
    143 |
    144 | 149 |
    150 | 151 | 152 |
    153 | 156 | 157 |
    158 |

    Site built with pkgdown 1.6.1.

    159 |
    160 | 161 |
    162 |
    163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /docs/reference/update_display_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Update Trelliscope app display list file — update_display_list • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Update Trelliscope app display list file

    132 |
    133 | 134 |
    update_display_list(base_path, jsonp = TRUE)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
    base_path

    the base directory of the trelliscope application

    jsonp

    should json for display list be jsonp (TRUE) or json (FALSE)?

    148 | 149 | 150 |
    151 | 156 |
    157 | 158 | 159 |
    160 | 163 | 164 |
    165 |

    Site built with pkgdown 1.6.1.

    166 |
    167 | 168 |
    169 |
    170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /docs/reference/write_panels.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Write a list of plot objects as panels in a Trelliscope display — write_panels • trelliscopejs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 117 | 118 | 119 | 120 |
    121 | 122 |
    123 |
    124 | 129 | 130 |
    131 |

    Write a list of plot objects as panels in a Trelliscope display

    132 |
    133 | 134 |
    write_panels(plot_list, ..., pb = NULL)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
    plot_list

    a named list of plot objects to be written as panels (objects can be trellis, ggplot2, or htmlwidget) with the list names being the keys for the panels

    ...

    params passed directly to write_panel

    pb

    optional progress bar object to pass in and use to report progress

    152 | 153 | 154 |
    155 | 160 |
    161 | 162 | 163 |
    164 | 167 | 168 |
    169 |

    Site built with pkgdown 1.6.1.

    170 |
    171 | 172 |
    173 |
    174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/trelliscopejs_widget/css/2.1c1d28a5.chunk.css: -------------------------------------------------------------------------------- 1 | .ReactVirtualized__Table__headerRow{font-weight:700;text-transform:uppercase}.ReactVirtualized__Table__headerRow,.ReactVirtualized__Table__row{display:flex;flex-direction:row;align-items:center}.ReactVirtualized__Table__headerTruncatedText{display:inline-block;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ReactVirtualized__Table__headerColumn,.ReactVirtualized__Table__rowColumn{margin-right:10px;min-width:0}.ReactVirtualized__Table__rowColumn{text-overflow:ellipsis;white-space:nowrap}.ReactVirtualized__Table__headerColumn:first-of-type,.ReactVirtualized__Table__rowColumn:first-of-type{margin-left:10px}.ReactVirtualized__Table__sortableHeaderColumn{cursor:pointer}.ReactVirtualized__Table__sortableHeaderIconContainer{display:flex;align-items:center}.ReactVirtualized__Table__sortableHeaderIcon{flex:0 0 24px;height:1em;width:1em;fill:currentColor} 2 | /*# sourceMappingURL=2.1c1d28a5.chunk.css.map */ -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/trelliscopejs_widget/css/main.ef767570.chunk.css: -------------------------------------------------------------------------------- 1 | .trelliscope-fullscreen-body{margin:0;overflow:hidden;height:100vh;width:100vw}.trelliscope-fullscreen-html{height:100vh;width:100vw}.trelliscope-fullscreen-el{z-index:7000;width:100%!important;height:100%!important;position:fixed!important;top:0;left:0}.trelliscope-app-container{background:#fff}.trelliscope-app{line-height:normal}.trelliscope-app,.trelliscope-app button{font-family:"Open Sans",sans-serif;font-weight:300}.trelliscope-app td,.trelliscope-app th{box-sizing:initial}.trelliscope-app label,.trelliscope-app table{font-weight:300}.trelliscope-app button:focus{outline:0}.trelliscope-app h1,.trelliscope-app h2,.trelliscope-app h3,.trelliscope-app h4,.trelliscope-app h5,.trelliscope-app h6,.trelliscope-app strong{font-weight:400;color:#000}.trelliscope-app th{font-weight:400}.trelliscope-app h1{font-size:24px}.trelliscope-app h2{font-size:20px}.trelliscope-app a{color:#ff5252}@font-face{font-family:"icomoon";src:url(../media/icomoon.5dd3ffcb.eot);src:url(../media/icomoon.5dd3ffcb.eot#iefix) format("embedded-opentype"),url(../media/icomoon.8454373a.ttf) format("truetype"),url(../media/icomoon.7a81c5bd.woff) format("woff"),url(../media/icomoon.bb221738.svg#icomoon) format("svg");font-weight:400;font-style:normal;font-display:block}[class*=" icon-"],[class^=icon-]{font-family:"icomoon"!important;speak:none;font-style:normal;font-weight:400;font-feature-settings:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-eye:before,.icon-views:before,.icon-vision:before,.icon-visit:before{content:"\e90d"}.icon-dice:before{content:"\e904"}.icon-cog:before{content:"\e901"}.icon-info:before{content:"\e905"}.icon-th:before{content:"\f00a"}.icon-close:before,.icon-remove:before,.icon-times:before{content:"\f00d"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-times-circle:before{content:"\f057"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-folder-open:before{content:"\f07c"}.icon-filter:before{content:"\f0b0"}.icon-list-ul:before{content:"\f0ca"}.icon-sort:before,.icon-unsorted:before{content:"\f0dc"}.icon-sort-desc:before,.icon-sort-down:before{content:"\f0dd"}.icon-sort-asc:before,.icon-sort-up:before{content:"\f0de"}.icon-rotate-left:before,.icon-undo:before{content:"\f0e2"}.icon-chevron-circle-left:before{content:"\f137"}.icon-chevron-circle-right:before{content:"\f138"}.icon-chevron-circle-up:before{content:"\f139"}.icon-chevron-circle-down:before{content:"\f13a"}.icon-sort-alpha-asc:before{content:"\f15d"}.icon-sort-alpha-desc:before{content:"\f15e"}.icon-sort-amount-asc:before{content:"\f160"}.icon-sort-amount-desc:before{content:"\f161"}.icon-sort-numeric-asc:before{content:"\f162"}.icon-sort-numeric-desc:before{content:"\f163"}.icon-angle-right:before{content:"\e909"}.icon-angle-left:before{content:"\e90a"}.icon-angle-double-right:before{content:"\e90b"}.icon-angle-double-left:before{content:"\e90c"}.icon-open-add:before{content:"\e998"}.icon-bycol:before{content:"\e906"}.icon-byrow:before{content:"\e999"}.icon-help:before{content:"\e887"}.icon-help_outline:before{content:"\e8fd"}.icon-info2:before{content:"\e88e"}.icon-info_outline:before{content:"\e88f"}.icon-more_vert:before{content:"\e5d4"}.icon-wb_incandescent:before{content:"\e42e"}.icon-label_outline:before{content:"\e902"}.icon-label:before{content:"\e903"}.icon-arrow-left:before{content:"\e094"}.icon-arrow-right:before{content:"\e095"}.icon-arrow-up:before{content:"\e096"}.icon-arrow-down:before{content:"\e097"}.icon-grid-2:before{content:"\e103"}.icon-maximize:before{content:"\e112"}.icon-minimize:before{content:"\e113"}.icon-open:before{content:"\e128"}.icon-th-list:before{content:"\e900"}@font-face{font-family:"Open Sans";font-style:normal;font-weight:300;src:url(../media/opensans-light-webfont.fc71142f.woff2) format("woff2"),url(../media/opensans-light-webfont.2e2ab17f.woff) format("woff")}@font-face{font-family:"Open Sans";font-style:normal;font-weight:400;src:url(../media/opensans-regular-webfont.f10027aa.woff2) format("woff2"),url(../media/opensans-regular-webfont.9503b8a2.woff) format("woff")} 2 | /*# sourceMappingURL=main.ef767570.chunk.css.map */ -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/trelliscopejs_widget/js/runtime-main.d9025fd8.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,u,i=r[0],p=r[1],f=r[2],c=0,s=[];c% 10 | nest(data = !one_of(c("manufacturer", "class"))) %>% 11 | mutate( 12 | mean_city_mpg = map_dbl(data, ~ mean(.$cty)), 13 | panel = map_plot(data, function(x) { 14 | plot_ly(data = x, x = ~cty, y = ~hwy, 15 | type = "scatter", mode = "markers") 16 | }) 17 | ) 18 | 19 | d %>% trelliscope(name = "city_vs_highway_mpg") 20 | 21 | # set default layout 22 | d %>% trelliscope(name = "city_vs_highway_mpg", nrow = 2, ncol = 3) 23 | 24 | # set the output path for where files will be stored 25 | my_displays <- tempfile() 26 | d %>% trelliscope(name = "city_vs_highway_mpg", path = my_displays) 27 | 28 | # multiple displays can be added to the same path and all will be available in the viewer 29 | d %>% trelliscope(name = "city_vs_highway_mpg2", path = my_displays) 30 | 31 | # ordering the data frame will set default sort order of the display 32 | d %>% 33 | arrange(-mean_city_mpg) %>% 34 | trelliscope(name = "city_vs_highway_mpg") 35 | 36 | # tidyverse + ggplot2 37 | mpg %>% 38 | nest(data = !one_of(c("manufacturer", "class"))) %>% 39 | mutate( 40 | panel = map_plot(data, ~ 41 | qplot(cty, hwy, data = .) + xlab("cty") + ylab("hwy") + 42 | xlim(7, 37) + ylim(9, 47) + theme_bw())) %>% 43 | trelliscope(name = "tidy_gg") 44 | 45 | # computing additional cognostics 46 | mpg_cog <- mpg %>% 47 | nest(data = !one_of(c("manufacturer", "class"))) %>% 48 | mutate( 49 | cogs = map_cog(data, ~ tibble( 50 | mean_city_mpg = mean(.$cty), 51 | mean_hwy_mpg = mean(.$hwy), 52 | most_common_drv = tail(names(table(.$drv)), 1) 53 | )) 54 | ) 55 | 56 | # computing additional cognostics explicitly using cog() 57 | # so we can specify descriptions, etc. 58 | mpg_cog2 <- mpg %>% 59 | nest(data = !one_of(c("manufacturer", "class"))) %>% 60 | mutate( 61 | cogs = map_cog(data, ~ tibble( 62 | mean_city_mpg = cog(mean(.$cty), desc = "Mean city mpg"), 63 | mean_hwy_mpg = cog(mean(.$hwy), desc = "Mean highway mpg"), 64 | most_common_drv = cog(tail(names(table(.$drv)), 1), desc = "Most common drive type") 65 | )), 66 | panel = map_plot(data, function(x) { 67 | plot_ly(data = x, x = ~cty, y = ~hwy, 68 | type = "scatter", mode = "markers") %>% 69 | layout( 70 | xaxis = list(range = c(9, 47)), 71 | yaxis = list(range = c(7, 37))) 72 | }) 73 | ) 74 | 75 | mpg_cog2 %>% 76 | trelliscope(name = "city_vs_highway_mpg", nrow = 1, ncol = 2) 77 | } 78 | -------------------------------------------------------------------------------- /man-roxygen/param-has-legend.R: -------------------------------------------------------------------------------- 1 | #' @param has_legend should a legend be reported for split_layout 2 | -------------------------------------------------------------------------------- /man-roxygen/param-split-aspect.R: -------------------------------------------------------------------------------- 1 | #' @param split_aspect list indicating aspect ratios of axes for a split layout. Only applies to ggplot2 plot objects. 2 | -------------------------------------------------------------------------------- /man-roxygen/param-split-layout.R: -------------------------------------------------------------------------------- 1 | #' @param split_layout boolean that determines if the layout is split into components like a facet_grid vs. individual panels like facet_wrap. Only applies to ggplot2 plot objects. 2 | -------------------------------------------------------------------------------- /man/Trelliscope-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/htmlwidget.R 3 | \name{Trelliscope-shiny} 4 | \alias{Trelliscope-shiny} 5 | \alias{trelliscopeOutput} 6 | \alias{renderTrelliscope} 7 | \title{Shiny bindings for Trelliscope} 8 | \usage{ 9 | trelliscopeOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderTrelliscope(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 trelliscopejs_widget} 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 trelliscopejs_widget within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /man/as_cognostics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cog.R 3 | \name{as_cognostics} 4 | \alias{as_cognostics} 5 | \title{Cast a data frame as a cognostics data frame} 6 | \usage{ 7 | as_cognostics( 8 | x, 9 | cond_cols, 10 | key_col = NULL, 11 | cog_desc = NULL, 12 | needs_key = TRUE, 13 | needs_cond = TRUE, 14 | group = "common" 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a data frame} 19 | 20 | \item{cond_cols}{the column name(s) that comprise the conditioning variables} 21 | 22 | \item{key_col}{the column name that indicates the panel key} 23 | 24 | \item{cog_desc}{an optional named list of descriptions for the cognostics columns} 25 | 26 | \item{needs_key}{does the result need to have a "key" column?} 27 | 28 | \item{needs_cond}{does the result need to have conditioning variable columns?} 29 | 30 | \item{group}{value to be used in the \code{\link{cog}} group} 31 | } 32 | \description{ 33 | Cast a data frame as a cognostics data frame 34 | } 35 | -------------------------------------------------------------------------------- /man/cog.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cog.R 3 | \name{cog} 4 | \alias{cog} 5 | \title{Cast Column as a Cognostic} 6 | \usage{ 7 | cog( 8 | val = NULL, 9 | desc = "", 10 | group = "common", 11 | type = NULL, 12 | default_label = FALSE, 13 | default_active = TRUE, 14 | filterable = TRUE, 15 | sortable = TRUE, 16 | log = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{val}{a scalar value (numeric, character, date, etc.)} 21 | 22 | \item{desc}{a description for this cognostic value} 23 | 24 | \item{group}{optional categorization of the cognostic for organizational purposes in the viewer (currently not implemented in the viewer)} 25 | 26 | \item{type}{the desired type of cognostic you would like to compute (see details)} 27 | 28 | \item{default_label}{should this cognostic be used as a panel label in the viewer by default?} 29 | 30 | \item{default_active}{should this cognostic be active (available for sort / filter / sample) by default?} 31 | 32 | \item{filterable}{should this cognostic be filterable? Default is \code{TRUE}. It can be useful to set this to \code{FALSE} if the cognostic is categorical with many unique values and is only desired to be used as a panel label.} 33 | 34 | \item{sortable}{should this cognostic be sortable?} 35 | 36 | \item{log}{when being used in the viewer for visual univariate and bivariate filters, should the log be computed? Useful when the distribution of the cognostic is very long-tailed or has large outliers. Can either be a logical or a positive integer indicating the base.} 37 | } 38 | \value{ 39 | object of class "cog" 40 | } 41 | \description{ 42 | Cast a column of a cognostics data frame as a cognostic object 43 | } 44 | \details{ 45 | Different types of cognostics can be specified through the \code{type} argument that will affect how the user is able to interact with those cognostics in the viewer. This can usually be ignored because it will be inferred from the implicit data type of \code{val}. But there are special types of cognostics, such as geographic coordinates and relations (not implemented) that can be specified as well. Current possibilities for \code{type} are "key", "integer", "numeric", "factor", "date", "time", "href". 46 | } 47 | \examples{ 48 | library(dplyr) 49 | library(tidyr) 50 | library(purrr) 51 | library(ggplot2) 52 | library(plotly) 53 | 54 | mpg_cog <- mpg \%>\% 55 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 56 | mutate( 57 | cogs = map_cog(data, ~ tibble( 58 | mean_city_mpg = cog(mean(.$cty), desc = "Mean city mpg"), 59 | mean_hwy_mpg = cog(mean(.$hwy), desc = "Mean highway mpg"), 60 | most_common_drv = cog(tail(names(table(.$drv)), 1), desc = "Most common drive type") 61 | )), 62 | panel = map_plot(data, function(x) { 63 | plot_ly(data = x, x = ~cty, y = ~hwy, 64 | type = "scatter", mode = "markers") \%>\% 65 | layout( 66 | xaxis = list(range = c(9, 47)), 67 | yaxis = list(range = c(7, 37))) 68 | }) 69 | ) 70 | 71 | trelliscope(mpg_cog, name = "city_vs_highway_mpg", nrow = 1, ncol = 2) 72 | } 73 | -------------------------------------------------------------------------------- /man/cog_disp_filter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cog.R 3 | \name{cog_disp_filter} 4 | \alias{cog_disp_filter} 5 | \title{Helper function for creating a cognostic for a link to another display in a filtered state} 6 | \usage{ 7 | cog_disp_filter( 8 | display, 9 | var, 10 | val, 11 | desc = "link", 12 | group = "common", 13 | type = c("href", "href_hash"), 14 | default_label = FALSE, 15 | default_active = FALSE, 16 | filterable = FALSE, 17 | sortable = FALSE 18 | ) 19 | } 20 | \arguments{ 21 | \item{display}{A string indicating the name of the display to link to.} 22 | 23 | \item{var}{A string indicating the variable name to filter on.} 24 | 25 | \item{val}{A string indicating the value of the filter.} 26 | 27 | \item{desc}{a description for this cognostic value} 28 | 29 | \item{group}{optional categorization of the cognostic for organizational purposes in the viewer (currently not implemented in the viewer)} 30 | 31 | \item{type}{of either "href" or "href_hash". "href" will open the link in a new page. "href_hash" will update the page's hash and reload the page (useful when changing state inside an iframe)} 32 | 33 | \item{default_label}{should this cognostic be used as a panel label in the viewer by default?} 34 | 35 | \item{default_active}{should this cognostic be active (available for sort / filter / sample) by default?} 36 | 37 | \item{filterable}{should this cognostic be filterable? Default is \code{TRUE}. It can be useful to set this to \code{FALSE} if the cognostic is categorical with many unique values and is only desired to be used as a panel label.} 38 | 39 | \item{sortable}{should this cognostic be sortable?} 40 | } 41 | \description{ 42 | Helper function for creating a cognostic for a link to another display in a filtered state 43 | } 44 | -------------------------------------------------------------------------------- /man/cog_href.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cog.R 3 | \name{cog_href} 4 | \alias{cog_href} 5 | \title{Href Cognostic} 6 | \usage{ 7 | cog_href( 8 | x, 9 | desc = "link", 10 | group = "common", 11 | type = c("href", "href_hash"), 12 | default_label = FALSE, 13 | default_active = FALSE, 14 | filterable = FALSE, 15 | sortable = FALSE, 16 | log = FALSE 17 | ) 18 | } 19 | \arguments{ 20 | \item{x}{URL to link to} 21 | 22 | \item{desc, group, default_label, default_active, filterable, sortable, log}{arguments passed to \code{\link{cog}}} 23 | 24 | \item{type}{of either "href" or "href_hash". "href" will open the link in a new page. "href_hash" will update the page's hash and reload the page (useful when changing state inside an iframe)} 25 | } 26 | \description{ 27 | Create href to be used as cognostics in a trelliscope display 28 | } 29 | \examples{ 30 | \donttest{ 31 | library(dplyr) 32 | library(tidyr) 33 | library(plotly) 34 | iris \%>\% 35 | nest(data = -Species) \%>\% 36 | mutate( 37 | panel = map_plot(data, function(x) { 38 | plot_ly(data = x, x = ~Sepal.Length, y = ~Sepal.Width, 39 | type = "scatter", mode = "markers") 40 | }), 41 | wiki_link = cog_href(paste0("https://en.wikipedia.org/wiki/Iris_", 42 | tolower(Species))[1], default_label = TRUE, 43 | desc = "link to species on wikipedia") 44 | ) \%>\% 45 | trelliscope(name = "iris_species", ncol = 3) 46 | } 47 | } 48 | \seealso{ 49 | \code{\link{cog}} 50 | } 51 | -------------------------------------------------------------------------------- /man/cogs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{cogs} 4 | \alias{cogs} 5 | \title{Cogs Wrapper Function} 6 | \usage{ 7 | cogs(.x, .f, ...) 8 | } 9 | \arguments{ 10 | \item{.x}{a list or atomic vector (see \code{\link[purrr]{map}} for details)} 11 | 12 | \item{.f}{a function, formula, or atomic vector (see \code{\link[purrr]{map}} for details)} 13 | 14 | \item{...}{additional arguments passed on to .f (see \code{\link[purrr]{map}} for details)} 15 | } 16 | \description{ 17 | Cogs Wrapper Function 18 | } 19 | \details{ 20 | See \code{\link[purrr]{map}} 21 | } 22 | \examples{ 23 | \donttest{ 24 | library(dplyr) 25 | library(tidyr) 26 | library(plotly) 27 | ggplot2::mpg \%>\% 28 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 29 | mutate( 30 | additional_cogs = map_cog(data, function(x) { 31 | tibble( 32 | max_city_mpg = cog(max(x$cty), desc = "Max city mpg"), 33 | min_city_mpg = cog(min(x$cty), desc = "Min city mpg")) 34 | }), 35 | panel = map_plot(data, function(x) { 36 | plot_ly(data = x, x = ~cty, y = ~hwy, 37 | type = "scatter", mode = "markers") 38 | }) 39 | ) \%>\% 40 | trelliscope(name = "city_vs_highway_mpg", nrow = 1, ncol = 2) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /man/create_cog_template.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cog.R 3 | \name{create_cog_template} 4 | \alias{create_cog_template} 5 | \title{Create a cognostics template that can be edited and used to specify 6 | cognostics in a display 7 | #' @param x a data frame that will be used as an input for the 8 | trelliscope display. If NULL, a blank template will be created.} 9 | \usage{ 10 | create_cog_template(x = NULL) 11 | } 12 | \description{ 13 | Create a cognostics template that can be edited and used to specify 14 | cognostics in a display 15 | #' @param x a data frame that will be used as an input for the 16 | trelliscope display. If NULL, a blank template will be created. 17 | } 18 | \note{ 19 | The input `x` can be a starting point and does not need to 20 | contain all variables that may be added later. 21 | Also note that after you edit the output (for example using the 22 | editData package, or writing to a csv and editing in Excel) to reflect 23 | how you would like the cognostics to display in the viewer, you can 24 | Add this specification to your trelliscope display with 25 | [add_cog_template()]. 26 | } 27 | -------------------------------------------------------------------------------- /man/facet_trelliscope.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet_trelliscope.R 3 | \name{facet_trelliscope} 4 | \alias{facet_trelliscope} 5 | \title{Facet Trelliscope} 6 | \usage{ 7 | facet_trelliscope( 8 | facets, 9 | nrow = 1, 10 | ncol = 1, 11 | scales = "same", 12 | name = NULL, 13 | group = "common", 14 | desc = ggplot2::waiver(), 15 | md_desc = ggplot2::waiver(), 16 | path = NULL, 17 | height = 500, 18 | width = 500, 19 | inputs = NULL, 20 | state = NULL, 21 | views = NULL, 22 | jsonp = TRUE, 23 | as_plotly = FALSE, 24 | plotly_args = NULL, 25 | plotly_cfg = NULL, 26 | split_sig = NULL, 27 | google_analytics_id = NULL, 28 | self_contained = FALSE, 29 | thumb = TRUE, 30 | require_token = FALSE, 31 | id = NULL, 32 | order = 1, 33 | disclaimer = FALSE, 34 | update_plots = TRUE, 35 | auto_cog = FALSE, 36 | split_layout = FALSE, 37 | data = ggplot2::waiver() 38 | ) 39 | } 40 | \arguments{ 41 | \item{facets}{formula to facet the panels on. Similar to \code{ggplot2::\link[ggplot2]{facet_wrap}}'s \code{facets}} 42 | 43 | \item{nrow}{the number of rows of panels to display by default} 44 | 45 | \item{ncol}{the number of columns of panels to display by default} 46 | 47 | \item{scales}{should scales be the same (\code{"same"}, the default), free (\code{"free"}), or sliced (\code{"sliced"}). May provide a single string or two strings, one for the X and Y axis respectively.} 48 | 49 | \item{name}{name of the display} 50 | 51 | \item{group}{group that the display belongs to} 52 | 53 | \item{desc}{description of the display} 54 | 55 | \item{md_desc}{optional string of markdown that will be shown in the viewer for additional context about the display} 56 | 57 | \item{path}{the base directory of the trelliscope application} 58 | 59 | \item{height}{height in pixels of each panel} 60 | 61 | \item{width}{width in pixels of each panel} 62 | 63 | \item{inputs}{optional set of input specifications (using \code{\link{input_cogs}}) to allow user input for each panel} 64 | 65 | \item{state}{the initial state the display will open in} 66 | 67 | \item{views}{an optional list of pre-specified views of the display (experimental)} 68 | 69 | \item{jsonp}{should json for display object be jsonp (TRUE) or json (FALSE)?} 70 | 71 | \item{as_plotly}{should the panels be written as plotly objects?} 72 | 73 | \item{plotly_args}{optional named list of arguments to send to \code{ggplotly}} 74 | 75 | \item{plotly_cfg}{optional named list of arguments to send to plotly's \code{config} method} 76 | 77 | \item{split_sig}{optional string that specifies the "signature" of the data splitting. If not specified, this is calculated as the md5 hash of the sorted unique facet variables. This is used to identify "related displays" - different displays that are based on the same faceting scheme. This parameter should only be specified manually if a display's faceting is mostly similar to another display's.} 78 | 79 | \item{google_analytics_id}{optional string specifying Google Analytics ID} 80 | 81 | \item{self_contained}{should the Trelliscope display be a self-contained html document? (see note)} 82 | 83 | \item{thumb}{should a thumbnail be created?} 84 | 85 | \item{require_token}{require a special token for all displays to be visible (experimental)} 86 | 87 | \item{id}{set a hard-coded ID for this app (do not set this if the display will be part of a larger web page)} 88 | 89 | \item{order}{an integer indicating the order that the display should appear in if using multiple displays} 90 | 91 | \item{disclaimer}{an optional string of html to include as a disclaimer for the set of displays} 92 | 93 | \item{auto_cog}{should auto cogs be computed (if possible)?} 94 | 95 | \item{split_layout}{boolean that determines if the layout is split into components like a facet_grid vs. individual panels like facet_wrap. Only applies to ggplot2 plot objects.} 96 | 97 | \item{data}{data used for faceting. Defaults to the first layer data} 98 | } 99 | \description{ 100 | Facet Trelliscope 101 | } 102 | \note{ 103 | Note that \code{self_contained} is severely limiting and should only be used in cases where you would either like your display to show up in the RStudio viewer pane, in an interactive R Markdown Notebook, or in a self-contained R Markdown html document. 104 | 105 | Note that \code{self_contained} is severely limiting and should only be used in cases where you would either like your display to show up in the RStudio viewer pane, in an interactive R Markdown Notebook, or in a self-contained R Markdown html document. 106 | } 107 | \examples{ 108 | \dontrun{ 109 | library(ggplot2) 110 | 111 | # basically swap out facet_wrap for facet_trelliscope 112 | qplot(cty, hwy, data = mpg) + 113 | facet_trelliscope(~ class + manufacturer) 114 | 115 | # not required, but if you set labels, these will be added as 116 | # descriptions to the cognostics that are automatically computed 117 | mpg <- set_labels(mpg, mpg_labels) 118 | 119 | qplot(cty, hwy, data = mpg) + 120 | theme_bw() + 121 | facet_trelliscope(~ manufacturer + class, nrow = 2, ncol = 4) 122 | 123 | # using plotly 124 | library(plotly) 125 | qplot(cty, hwy, data = mpg) + 126 | theme_bw() + 127 | facet_trelliscope(~ manufacturer + class, nrow = 2, ncol = 4, as_plotly = TRUE) 128 | 129 | qplot(class, cty, data = mpg, geom = c("boxplot", "jitter"), na.rm = TRUE) + 130 | facet_trelliscope(~ class, ncol = 7, height = 800, width = 200, 131 | state = list(sort = list(sort_spec("cty_mean")))) + 132 | theme_bw() 133 | 134 | library(gapminder) 135 | qplot(year, lifeExp, data = gapminder) + 136 | xlim(1948, 2011) + ylim(10, 95) + theme_bw() + 137 | facet_trelliscope(~ country + continent, nrow = 2, ncol = 7, 138 | width = 300, as_plotly = TRUE, 139 | plotly_cfg = list(displayModeBar = FALSE)) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/man/figures/logo.png -------------------------------------------------------------------------------- /man/img_panel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{img_panel} 4 | \alias{img_panel} 5 | \title{Cast a vector of URLs pointing to images as an image panel source} 6 | \usage{ 7 | img_panel(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector of URLs pointing to images} 11 | } 12 | \description{ 13 | Cast a vector of URLs pointing to images as an image panel source 14 | } 15 | -------------------------------------------------------------------------------- /man/img_panel_local.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{img_panel_local} 4 | \alias{img_panel_local} 5 | \title{Cast a vector of URLs pointing to local images as an image panel source} 6 | \usage{ 7 | img_panel_local(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector of URLs pointing to images} 11 | } 12 | \description{ 13 | Cast a vector of URLs pointing to local images as an image panel source 14 | } 15 | \note{ 16 | \code{x} must be paths relative to the \code{path} argument passed to \code{\link{trelliscope}}. 17 | } 18 | \examples{ 19 | \dontrun{ 20 | # assuming images are available locally in relative path pokemon_local/images 21 | pokemon$img <- img_panel_local(paste0("images/", basename(pokemon$url_image))) 22 | trelliscope(pokemon, name = "pokemon", path = "pokemon_local") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /man/input_cogs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/input_cogs.R 3 | \name{input_cogs} 4 | \alias{input_cogs} 5 | \title{Specify a collection of input cognostics to be stored in browser localStorage} 6 | \usage{ 7 | input_cogs(..., feedback_email = NULL, extra_cogs = NULL) 8 | } 9 | \arguments{ 10 | \item{feedback_email}{optional feedback email address that input feedback can be sent to} 11 | 12 | \item{extra_cogs}{optional vector of names of non-input "regular" cognostics to include in the csv output} 13 | 14 | \item{\ldots}{objects created by any of \code{\link{input_radio}}, 15 | \code{\link{input_text}}} 16 | } 17 | \description{ 18 | Specify a collection of input cognostics to be stored in browser localStorage 19 | } 20 | -------------------------------------------------------------------------------- /man/input_cogs_api.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/input_cogs.R 3 | \name{input_cogs_api} 4 | \alias{input_cogs_api} 5 | \title{Specify a collection of input cognostics to be stored using an API} 6 | \usage{ 7 | input_cogs_api( 8 | ..., 9 | set_url, 10 | get_url, 11 | get_request_options = list(mode = "cors", method = "GET", headers = 12 | list(`Content-Type` = "application/json", Accept = "application/json")), 13 | set_request_options = list(mode = "cors", method = "POST", headers = 14 | list(`Content-Type` = "application/json", Accept = "application/json")) 15 | ) 16 | } 17 | \arguments{ 18 | \item{set_url}{URL of the API endpoint for setting a single input} 19 | 20 | \item{get_url}{URL of the API endpoint for getting all inputs for the display} 21 | 22 | \item{get_request_options}{request options for the API call to set inputs} 23 | 24 | \item{set_request_options}{request options for the API call to get inputs} 25 | 26 | \item{\ldots}{objects created by any of \code{\link{input_radio}}, 27 | \code{\link{input_text}}} 28 | } 29 | \description{ 30 | Specify a collection of input cognostics to be stored using an API 31 | } 32 | \details{ 33 | See [here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options for more information about request options. 34 | } 35 | -------------------------------------------------------------------------------- /man/input_radio.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/input_cogs.R 3 | \name{input_radio} 4 | \alias{input_radio} 5 | \title{Specify a radio button input} 6 | \usage{ 7 | input_radio(name, desc = NULL, options, group = NULL, default_label = TRUE) 8 | } 9 | \arguments{ 10 | \item{name}{name of the input} 11 | 12 | \item{desc}{optional description of the input} 13 | 14 | \item{options}{a character vector of options to select between} 15 | 16 | \item{group}{optional categorization of the input for organizational purposes in the viewer (currently not implemented in the viewer)} 17 | 18 | \item{default_label}{should this input be shown under the panel in the viewer by default?} 19 | } 20 | \description{ 21 | Specify a radio button input 22 | } 23 | -------------------------------------------------------------------------------- /man/input_text.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/input_cogs.R 3 | \name{input_text} 4 | \alias{input_text} 5 | \title{Specify a text input} 6 | \usage{ 7 | input_text( 8 | name, 9 | desc = NULL, 10 | width = 80, 11 | height = 3, 12 | group = NULL, 13 | default_label = TRUE 14 | ) 15 | } 16 | \arguments{ 17 | \item{name}{name of the input} 18 | 19 | \item{desc}{optional description of the input} 20 | 21 | \item{width}{width (in characters) of the text box popout} 22 | 23 | \item{height}{height (in lines of text) of the text box popout} 24 | 25 | \item{group}{optional categorization of the input for organizational purposes in the viewer (currently not implemented in the viewer)} 26 | 27 | \item{default_label}{should this input be shown under the panel in the viewer by default?} 28 | } 29 | \description{ 30 | Specify a text input 31 | } 32 | -------------------------------------------------------------------------------- /man/map2_cog.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{map2_cog} 4 | \alias{map2_cog} 5 | \alias{pmap_cog} 6 | \title{Map over multiple inputs simultaneously and return a vector of cognostics data frames} 7 | \usage{ 8 | map2_cog(.x, .y, .f, ...) 9 | 10 | pmap_cog(.l, .f, ...) 11 | } 12 | \arguments{ 13 | \item{.x, .y}{Vectors of the same length. A vector of length 1 will be recycled.} 14 | 15 | \item{.f}{A function, formula, or atomic vector (see \code{\link[purrr]{map2}} for details)} 16 | 17 | \item{...}{additional arguments passed on to .f.} 18 | 19 | \item{.l}{A list of lists. The length of .l determines the number of arguments that .f will be called with. List names will be used if present.} 20 | } 21 | \description{ 22 | Map over multiple inputs simultaneously and return a vector of cognostics data frames 23 | } 24 | \details{ 25 | See \code{\link[purrr]{map2}} 26 | } 27 | \examples{ 28 | \donttest{ 29 | library(tidyr) 30 | library(purrr) 31 | library(plotly) 32 | library(dplyr) 33 | 34 | iris \%>\% 35 | nest(data = -Species) \%>\% 36 | mutate( 37 | mod = map(data, ~ lm(Sepal.Length ~ Sepal.Width, data = .x)), 38 | cogs = map2_cog(data, mod, function(data, mod) { 39 | tibble(max_sl = max(data$Sepal.Length), slope = coef(mod)[2]) 40 | }), 41 | panel = map2_plot(data, mod, function(data, mod) { 42 | plot_ly(data = data, x = ~Sepal.Width, y = ~Sepal.Length, 43 | type = "scatter", mode = "markers", name = "data") \%>\% 44 | add_trace(data = data, x = ~Sepal.Width, y = ~predict(mod), 45 | mode = "lines", name = "lm") 46 | })) \%>\% 47 | trelliscope(name = "iris") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/map2_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{map2_plot} 4 | \alias{map2_plot} 5 | \alias{pmap_plot} 6 | \title{Map over multiple inputs simultaneously and return a vector of plots} 7 | \usage{ 8 | map2_plot(.x, .y, .f, ...) 9 | 10 | pmap_plot(.l, .f, ...) 11 | } 12 | \arguments{ 13 | \item{.x, .y}{Vectors of the same length. A vector of length 1 will be recycled.} 14 | 15 | \item{.f}{A function, formula, or atomic vector (see \code{\link[purrr]{map2}} for details)} 16 | 17 | \item{...}{additional arguments passed on to .f.} 18 | 19 | \item{.l}{A list of lists. The length of .l determines the number of arguments that .f will be called with. List names will be used if present.} 20 | } 21 | \description{ 22 | Map over multiple inputs simultaneously and return a vector of plots 23 | } 24 | \details{ 25 | See \code{\link[purrr]{map2}} 26 | } 27 | \examples{ 28 | \donttest{ 29 | library(tidyr) 30 | library(purrr) 31 | library(plotly) 32 | library(dplyr) 33 | 34 | iris \%>\% 35 | nest(data = -Species) \%>\% 36 | mutate( 37 | mod = map(data, ~ lm(Sepal.Length ~ Sepal.Width, data = .x)), 38 | panel = map2_plot(data, mod, function(data, mod) { 39 | plot_ly(data = data, x = ~Sepal.Width, y = ~Sepal.Length, 40 | type = "scatter", mode = "markers", name = "data") \%>\% 41 | add_trace(data = data, x = ~Sepal.Width, y = ~predict(mod), 42 | mode = "lines", name = "lm") 43 | })) \%>\% 44 | trelliscope(name = "iris") 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /man/map_cog.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{map_cog} 4 | \alias{map_cog} 5 | \title{Apply a function to each element of a vector and return a vector of cognostics data frames} 6 | \usage{ 7 | map_cog(.x, .f, ...) 8 | } 9 | \arguments{ 10 | \item{.x}{a list or atomic vector (see \code{\link[purrr]{map}} for details)} 11 | 12 | \item{.f}{a function, formula, or atomic vector (see \code{\link[purrr]{map}} for details)} 13 | 14 | \item{...}{additional arguments passed on to .f (see \code{\link[purrr]{map}} for details)} 15 | } 16 | \description{ 17 | Apply a function to each element of a vector and return a vector of cognostics data frames 18 | } 19 | \details{ 20 | See \code{\link[purrr]{map}} 21 | } 22 | \examples{ 23 | \donttest{ 24 | library(dplyr) 25 | library(tidyr) 26 | library(plotly) 27 | ggplot2::mpg \%>\% 28 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 29 | mutate( 30 | cog = map_cog(data, function(x) tibble(mean_hwy = mean(x$hwy))), 31 | panel = map_plot(data, function(x) { 32 | plot_ly(data = x, x = ~cty, y = ~hwy, 33 | type = "scatter", mode = "markers") 34 | }) 35 | ) \%>\% 36 | trelliscope(name = "city_vs_highway_mpg") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/map_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{map_plot} 4 | \alias{map_plot} 5 | \title{Apply a function to each element of a vector and return a vector of plots} 6 | \usage{ 7 | map_plot(.x, .f, ...) 8 | } 9 | \arguments{ 10 | \item{.x}{a list or atomic vector (see \code{\link[purrr]{map}} for details)} 11 | 12 | \item{.f}{a function, formula, or atomic vector (see \code{\link[purrr]{map}} for details)} 13 | 14 | \item{...}{additional arguments passed on to .f (see \code{\link[purrr]{map}} for details)} 15 | } 16 | \description{ 17 | Apply a function to each element of a vector and return a vector of plots 18 | } 19 | \details{ 20 | See \code{\link[purrr]{map}} 21 | } 22 | \examples{ 23 | \donttest{ 24 | library(dplyr) 25 | library(tidyr) 26 | library(purrr) 27 | library(plotly) 28 | library(gapminder) 29 | 30 | # nest gapminder data by country 31 | by_country <- gapminder \%>\% 32 | nest(data = !one_of(c("country", "continent"))) 33 | 34 | # add in a plot column with map_plot 35 | by_country <- by_country \%>\% mutate( 36 | panel = map_plot(data, function(x) { 37 | plot_ly(data = x, x = ~year, y = ~lifeExp, 38 | type = "scatter", mode = "markers") \%>\% 39 | layout( 40 | xaxis = list(range = c(1948, 2011)), 41 | yaxis = list(range = c(10, 95))) 42 | })) 43 | 44 | # plot it 45 | by_country \%>\% 46 | trelliscope("gapminder", nrow = 2, ncol = 7, width = 300) 47 | 48 | # example using mpg data 49 | ggplot2::mpg \%>\% 50 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 51 | mutate(panel = map_plot(data, function(x) { 52 | plot_ly(data = x, x = ~hwy, y = ~cty, 53 | type = "scatter", mode = "markers") 54 | })) \%>\% 55 | trelliscope(name = "city_vs_highway_mpg") 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /man/md_description.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{md_description} 4 | \alias{md_description} 5 | \title{Specify a markdown description for a display} 6 | \usage{ 7 | md_description( 8 | content = "", 9 | title = "Information About This Display", 10 | show = FALSE 11 | ) 12 | } 13 | \arguments{ 14 | \item{content}{Markdown content} 15 | 16 | \item{title}{Title of the dialog box that displays this content} 17 | 18 | \item{show}{should the markdown description be shown by default when the display is loaded?} 19 | } 20 | \description{ 21 | Specify a markdown description for a display 22 | } 23 | -------------------------------------------------------------------------------- /man/mpg_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trelliscopejs-package.R 3 | \docType{data} 4 | \name{mpg_labels} 5 | \alias{mpg_labels} 6 | \title{Labels for ggplot2 "mpg" data} 7 | \format{ 8 | An object of class \code{list} of length 10. 9 | } 10 | \usage{ 11 | mpg_labels 12 | } 13 | \description{ 14 | Labels for ggplot2 "mpg" data 15 | } 16 | \keyword{datasets} 17 | -------------------------------------------------------------------------------- /man/panels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tidy.R 3 | \name{panels} 4 | \alias{panels} 5 | \title{Panels Wrapper Function} 6 | \usage{ 7 | panels(.x, .f, ...) 8 | } 9 | \arguments{ 10 | \item{.x}{a list or atomic vector (see \code{\link[purrr]{map}} for details)} 11 | 12 | \item{.f}{a function, formula, or atomic vector (see \code{\link[purrr]{map}} for details)} 13 | 14 | \item{...}{additional arguments passed on to .f (see \code{\link[purrr]{map}} for details)} 15 | } 16 | \description{ 17 | Panels Wrapper Function 18 | } 19 | \details{ 20 | See \code{\link[purrr]{map}} 21 | } 22 | \examples{ 23 | \donttest{ 24 | library(dplyr) 25 | library(tidyr) 26 | library(plotly) 27 | ggplot2::mpg \%>\% 28 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 29 | mutate(panel = map_plot(data, function(x) { 30 | plot_ly(data = x, x = ~hwy, y = ~cty, 31 | type = "scatter", mode = "markers") 32 | })) \%>\% 33 | trelliscope(name = "city_vs_highway_mpg") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/prepare_display.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{prepare_display} 4 | \alias{prepare_display} 5 | \title{Set up all auxiliary files needed for a Trelliscope app} 6 | \usage{ 7 | prepare_display( 8 | base_path, 9 | id, 10 | self_contained = FALSE, 11 | jsonp = TRUE, 12 | require_token = FALSE, 13 | disclaimer = FALSE, 14 | pb = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{base_path}{the base directory of the trelliscope application} 19 | 20 | \item{id}{a unique id for the application} 21 | 22 | \item{self_contained}{should the Trelliscope display be a self-contained html document?} 23 | 24 | \item{jsonp}{should json for display list and app config be jsonp (TRUE) or json (FALSE)?} 25 | 26 | \item{require_token}{require a special token for all displays to be visible (experimental)} 27 | 28 | \item{disclaimer}{an optional string of html to include as a disclaimer for the set of displays} 29 | 30 | \item{pb}{optional progress bar object to pass in and use to report progress} 31 | } 32 | \description{ 33 | Set up all auxiliary files needed for a Trelliscope app 34 | } 35 | -------------------------------------------------------------------------------- /man/print.facet_trelliscope.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet_trelliscope.R 3 | \name{print.facet_trelliscope} 4 | \alias{print.facet_trelliscope} 5 | \title{Print facet trelliscope object} 6 | \usage{ 7 | \method{print}{facet_trelliscope}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object} 11 | 12 | \item{...}{ignored} 13 | } 14 | \description{ 15 | Print facet trelliscope object 16 | } 17 | -------------------------------------------------------------------------------- /man/set_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{set_labels} 4 | \alias{set_labels} 5 | \title{Set labels for a data frame} 6 | \usage{ 7 | set_labels(dat, label_list) 8 | } 9 | \arguments{ 10 | \item{dat}{a data frame to apply labels to} 11 | 12 | \item{label_list}{a named list with names matching those of \code{dat} and values being labels} 13 | } 14 | \value{ 15 | data frame with labels attached as attributes (attached to each column and named "label") 16 | } 17 | \description{ 18 | Set labels for a data frame 19 | } 20 | -------------------------------------------------------------------------------- /man/sort_spec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/state.R 3 | \name{sort_spec} 4 | \alias{sort_spec} 5 | \title{Specify how a display should be sorted} 6 | \usage{ 7 | sort_spec(name, dir = "asc") 8 | } 9 | \arguments{ 10 | \item{name}{variable name to sort on} 11 | 12 | \item{dir}{direction to sort ('asc' or 'desc')} 13 | } 14 | \description{ 15 | Specify how a display should be sorted 16 | } 17 | -------------------------------------------------------------------------------- /man/tr_charm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/charm.R 3 | \name{tr_charm} 4 | \alias{tr_charm} 5 | \title{Use fidelius to password protect a trelliscope display} 6 | \usage{ 7 | tr_charm(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class "facet_trelliscope" or 11 | "trelliscopejs_widget"} 12 | 13 | \item{...}{arguments passed to [fidelius::charm()]} 14 | } 15 | \description{ 16 | Use fidelius to password protect a trelliscope display 17 | } 18 | -------------------------------------------------------------------------------- /man/trelliscope.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trelliscope.R 3 | \name{trelliscope} 4 | \alias{trelliscope} 5 | \title{Create a Trelliscope Display} 6 | \usage{ 7 | trelliscope( 8 | x, 9 | name, 10 | group = "common", 11 | panel_col = NULL, 12 | cond_cols = NULL, 13 | desc = "", 14 | md_desc = "", 15 | path, 16 | height = 500, 17 | width = 500, 18 | inputs = NULL, 19 | google_analytics_id = NULL, 20 | auto_cog = FALSE, 21 | state = NULL, 22 | views = NULL, 23 | nrow = 1, 24 | ncol = 1, 25 | jsonp = TRUE, 26 | split_sig = NULL, 27 | self_contained = FALSE, 28 | thumb = FALSE, 29 | require_token = FALSE, 30 | id = NULL, 31 | order = 1, 32 | disclaimer = FALSE, 33 | update_plots = TRUE 34 | ) 35 | } 36 | \arguments{ 37 | \item{x}{an object to create at trelliscope display for} 38 | 39 | \item{name}{name of the display} 40 | 41 | \item{group}{group that the display belongs to} 42 | 43 | \item{panel_col}{optional string specifying the column to use for panels (if there are multiple plot columns in \code{x})} 44 | 45 | \item{cond_cols}{optionsl vector of columns to specify as "conditioning" columns - combined they must be unique and not have any missing values} 46 | 47 | \item{desc}{optional text description of the display} 48 | 49 | \item{md_desc}{optional string of markdown that will be shown in the viewer for additional context about the display} 50 | 51 | \item{path}{the base directory of the trelliscope application} 52 | 53 | \item{height}{height in pixels of each panel} 54 | 55 | \item{width}{width in pixels of each panel} 56 | 57 | \item{inputs}{optional set of input specifications (using \code{\link{input_cogs}}) to allow user input for each panel} 58 | 59 | \item{google_analytics_id}{optional string specifying Google Analytics ID} 60 | 61 | \item{auto_cog}{should auto cogs be computed (if possible)?} 62 | 63 | \item{state}{the initial state the display will open in} 64 | 65 | \item{views}{an optional list of pre-specified views of the display (experimental)} 66 | 67 | \item{nrow}{the number of rows of panels to display by default} 68 | 69 | \item{ncol}{the number of columns of panels to display by default} 70 | 71 | \item{jsonp}{should json for display object be jsonp (TRUE) or json (FALSE)?} 72 | 73 | \item{split_sig}{optional string that specifies the "signature" of the data splitting. If not specified, this is calculated as the md5 hash of the sorted unique facet variables. This is used to identify "related displays" - different displays that are based on the same faceting scheme. This parameter should only be specified manually if a display's faceting is mostly similar to another display's.} 74 | 75 | \item{self_contained}{should the Trelliscope display be a self-contained html document? (see note)} 76 | 77 | \item{thumb}{should a thumbnail be created?} 78 | 79 | \item{require_token}{require a special token for all displays to be visible (experimental)} 80 | 81 | \item{id}{set a hard-coded ID for this app (do not set this if the display will be part of a larger web page)} 82 | 83 | \item{order}{an integer indicating the order that the display should appear in if using multiple displays} 84 | 85 | \item{disclaimer}{an optional string of html to include as a disclaimer for the set of displays} 86 | 87 | \item{update_plots}{should the plots be updated? This is to allow slight updates to the underlying display data without the need to re-render all of the plots. Use it carefully.} 88 | } 89 | \description{ 90 | Create a Trelliscope Display 91 | } 92 | \note{ 93 | Note that \code{self_contained} is severely limiting and should only be used in cases where you would either like your display to show up in the RStudio viewer pane, in an interactive R Markdown Notebook, or in a self-contained R Markdown html document. 94 | } 95 | \examples{ 96 | \dontrun{ 97 | library(dplyr) 98 | library(tidyr) 99 | library(purrr) 100 | library(plotly) 101 | library(ggplot2) 102 | 103 | # tidyverse + plotly 104 | d <- mpg \%>\% 105 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 106 | mutate( 107 | mean_city_mpg = map_dbl(data, ~ mean(.$cty)), 108 | panel = map_plot(data, function(x) { 109 | plot_ly(data = x, x = ~cty, y = ~hwy, 110 | type = "scatter", mode = "markers") 111 | }) 112 | ) 113 | 114 | d \%>\% trelliscope(name = "city_vs_highway_mpg") 115 | 116 | # set default layout 117 | d \%>\% trelliscope(name = "city_vs_highway_mpg", nrow = 2, ncol = 3) 118 | 119 | # set the output path for where files will be stored 120 | my_displays <- tempfile() 121 | d \%>\% trelliscope(name = "city_vs_highway_mpg", path = my_displays) 122 | 123 | # multiple displays can be added to the same path and all will be available in the viewer 124 | d \%>\% trelliscope(name = "city_vs_highway_mpg2", path = my_displays) 125 | 126 | # ordering the data frame will set default sort order of the display 127 | d \%>\% 128 | arrange(-mean_city_mpg) \%>\% 129 | trelliscope(name = "city_vs_highway_mpg") 130 | 131 | # tidyverse + ggplot2 132 | mpg \%>\% 133 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 134 | mutate( 135 | panel = map_plot(data, ~ 136 | qplot(cty, hwy, data = .) + xlab("cty") + ylab("hwy") + 137 | xlim(7, 37) + ylim(9, 47) + theme_bw())) \%>\% 138 | trelliscope(name = "tidy_gg") 139 | 140 | # computing additional cognostics 141 | mpg_cog <- mpg \%>\% 142 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 143 | mutate( 144 | cogs = map_cog(data, ~ tibble( 145 | mean_city_mpg = mean(.$cty), 146 | mean_hwy_mpg = mean(.$hwy), 147 | most_common_drv = tail(names(table(.$drv)), 1) 148 | )) 149 | ) 150 | 151 | # computing additional cognostics explicitly using cog() 152 | # so we can specify descriptions, etc. 153 | mpg_cog2 <- mpg \%>\% 154 | nest(data = !one_of(c("manufacturer", "class"))) \%>\% 155 | mutate( 156 | cogs = map_cog(data, ~ tibble( 157 | mean_city_mpg = cog(mean(.$cty), desc = "Mean city mpg"), 158 | mean_hwy_mpg = cog(mean(.$hwy), desc = "Mean highway mpg"), 159 | most_common_drv = cog(tail(names(table(.$drv)), 1), desc = "Most common drive type") 160 | )), 161 | panel = map_plot(data, function(x) { 162 | plot_ly(data = x, x = ~cty, y = ~hwy, 163 | type = "scatter", mode = "markers") \%>\% 164 | layout( 165 | xaxis = list(range = c(9, 47)), 166 | yaxis = list(range = c(7, 37))) 167 | }) 168 | ) 169 | 170 | mpg_cog2 \%>\% 171 | trelliscope(name = "city_vs_highway_mpg", nrow = 1, ncol = 2) 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /man/trelliscopejs-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trelliscopejs-package.R 3 | \docType{package} 4 | \name{trelliscopejs-package} 5 | \alias{trelliscopejs-package} 6 | \title{trelliscopejs} 7 | \description{ 8 | Create interactive Trelliscope displays 9 | } 10 | \details{ 11 | \url{https://hafen.github.io/trelliscopejs/} 12 | } 13 | \examples{ 14 | help(package = trelliscopejs) 15 | } 16 | -------------------------------------------------------------------------------- /man/update_display_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{update_display_list} 4 | \alias{update_display_list} 5 | \title{Update Trelliscope app display list file} 6 | \usage{ 7 | update_display_list(base_path, jsonp = TRUE) 8 | } 9 | \arguments{ 10 | \item{base_path}{the base directory of the trelliscope application} 11 | 12 | \item{jsonp}{should json for display list be jsonp (TRUE) or json (FALSE)?} 13 | } 14 | \description{ 15 | Update Trelliscope app display list file 16 | } 17 | -------------------------------------------------------------------------------- /man/view_item.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{view_item} 4 | \alias{view_item} 5 | \title{Construct a list of view items} 6 | \usage{ 7 | view_item(name, hash) 8 | } 9 | \arguments{ 10 | \item{name}{A string indicating the name of the view (will be displayed in the "Views" sidebar)} 11 | 12 | \item{hash}{A URL hash that sends the user to this view (typically the URL starting with &nrow=...)} 13 | } 14 | \description{ 15 | Construct a list of view items 16 | } 17 | -------------------------------------------------------------------------------- /man/view_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{view_list} 4 | \alias{view_list} 5 | \title{Construct a list of view items} 6 | \usage{ 7 | view_list(...) 8 | } 9 | \arguments{ 10 | \item{...}{Objects created using \code{\link{view_item}}} 11 | } 12 | \description{ 13 | Construct a list of view items 14 | } 15 | -------------------------------------------------------------------------------- /man/write_cognostics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{write_cognostics} 4 | \alias{write_cognostics} 5 | \title{Write cognostics data for a display in a Trelliscope app} 6 | \usage{ 7 | write_cognostics(cogdf, base_path, id, name, group = "common", jsonp = TRUE) 8 | } 9 | \arguments{ 10 | \item{cogdf}{a data frame of cognostics, prepared with \code{\link{as_cognostics}}} 11 | 12 | \item{base_path}{the base directory of the trelliscope application} 13 | 14 | \item{id}{a unique id for the application} 15 | 16 | \item{name}{name of the display} 17 | 18 | \item{group}{group that the display belongs to} 19 | 20 | \item{jsonp}{should json for cognostics be jsonp (TRUE) or json (FALSE)?} 21 | } 22 | \description{ 23 | Write cognostics data for a display in a Trelliscope app 24 | } 25 | -------------------------------------------------------------------------------- /man/write_config.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{write_config} 4 | \alias{write_config} 5 | \title{Write Trelliscope app configuration file} 6 | \usage{ 7 | write_config( 8 | base_path, 9 | id, 10 | self_contained = FALSE, 11 | jsonp = TRUE, 12 | require_token = FALSE, 13 | disclaimer = FALSE, 14 | split_layout = FALSE, 15 | has_legend = FALSE 16 | ) 17 | } 18 | \arguments{ 19 | \item{base_path}{the base directory of the trelliscope application} 20 | 21 | \item{id}{a unique id for the application} 22 | 23 | \item{self_contained}{should the Trelliscope display be a self-contained html document?} 24 | 25 | \item{jsonp}{should json for app config be jsonp (TRUE) or json (FALSE)?} 26 | 27 | \item{require_token}{require a special token for all displays to be visible (experimental)} 28 | 29 | \item{disclaimer}{an optional string of html to include as a disclaimer for the set of displays} 30 | 31 | \item{split_layout}{boolean that determines if the layout is split into components like a facet_grid vs. individual panels like facet_wrap. Only applies to ggplot2 plot objects.} 32 | 33 | \item{has_legend}{should a legend be reported for split_layout} 34 | } 35 | \description{ 36 | Write Trelliscope app configuration file 37 | } 38 | -------------------------------------------------------------------------------- /man/write_display_obj.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{write_display_obj} 4 | \alias{write_display_obj} 5 | \title{Write a "display object" file for a Trelliscope app} 6 | \usage{ 7 | write_display_obj( 8 | cogdf, 9 | panel_example, 10 | base_path, 11 | id, 12 | name, 13 | group = "common", 14 | desc = "", 15 | height = 500, 16 | width = 500, 17 | inputs = NULL, 18 | md_desc = "", 19 | state = NULL, 20 | google_analytics_id = NULL, 21 | views = NULL, 22 | jsonp = TRUE, 23 | split_sig = NULL, 24 | panel_img_col = NULL, 25 | self_contained = FALSE, 26 | thumb = TRUE, 27 | split_layout = FALSE, 28 | split_aspect = NULL, 29 | has_legend = FALSE, 30 | order = 1, 31 | pb = NULL 32 | ) 33 | } 34 | \arguments{ 35 | \item{cogdf}{a data frame of cognostics, prepared with \code{\link{as_cognostics}}} 36 | 37 | \item{panel_example}{an example object of one panel of a display (can be trellis, ggplot2, or htmlwidget object)} 38 | 39 | \item{base_path}{the base directory of the trelliscope application} 40 | 41 | \item{id}{a unique id for the application} 42 | 43 | \item{name}{name of the display} 44 | 45 | \item{group}{group that the display belongs to} 46 | 47 | \item{desc}{description of the display} 48 | 49 | \item{height}{height in pixels of each panel} 50 | 51 | \item{width}{width in pixels of each panel} 52 | 53 | \item{inputs}{optional set of input specifications (using \code{\link{input_cogs}}) to allow user input for each panel} 54 | 55 | \item{md_desc}{optional string of markdown that will be shown in the viewer for additional context about the display} 56 | 57 | \item{state}{the initial state the display will open in} 58 | 59 | \item{google_analytics_id}{optional string specifying Google Analytics ID} 60 | 61 | \item{views}{an optional list of pre-specified views of the display (experimental)} 62 | 63 | \item{jsonp}{should json for display object be jsonp (TRUE) or json (FALSE)?} 64 | 65 | \item{split_sig}{optional string "signature" specifying the data splitting} 66 | 67 | \item{panel_img_col}{which column (if any) is a panel image column?} 68 | 69 | \item{self_contained}{should the Trelliscope display be a self-contained html document?} 70 | 71 | \item{thumb}{should a thumbnail be created?} 72 | 73 | \item{split_layout}{boolean that determines if the layout is split into components like a facet_grid vs. individual panels like facet_wrap. Only applies to ggplot2 plot objects.} 74 | 75 | \item{split_aspect}{list indicating aspect ratios of axes for a split layout. Only applies to ggplot2 plot objects.} 76 | 77 | \item{has_legend}{should a legend be reported for split_layout} 78 | 79 | \item{order}{an integer indicating the order that the display should appear in if using multiple displays} 80 | 81 | \item{pb}{optional progress bar object to pass in and use to report progress} 82 | } 83 | \description{ 84 | Write a "display object" file for a Trelliscope app 85 | } 86 | -------------------------------------------------------------------------------- /man/write_panel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{write_panel} 4 | \alias{write_panel} 5 | \title{Write a plot object as a panel in a Trelliscope display} 6 | \usage{ 7 | write_panel( 8 | plot_object, 9 | key, 10 | base_path, 11 | name, 12 | group = "common", 13 | width, 14 | height, 15 | jsonp = TRUE, 16 | split_layout = FALSE 17 | ) 18 | } 19 | \arguments{ 20 | \item{plot_object}{a plot object to be written (can be trellis, ggplot2, or htmlwidget)} 21 | 22 | \item{key}{a string identifying the panel key, which will be used as the panel file name and which the \code{panelKey} column of the cognostics data frame should point to} 23 | 24 | \item{base_path}{the base directory of the trelliscope application} 25 | 26 | \item{name}{name of the display that the panel belongs to} 27 | 28 | \item{group}{group name of the display that the panel belongs to} 29 | 30 | \item{width}{width in pixels of each panel} 31 | 32 | \item{height}{height in pixels of each panel} 33 | 34 | \item{jsonp}{should json for panel be jsonp (TRUE) or json (FALSE)?} 35 | 36 | \item{split_layout}{boolean that determines if the layout is split into components like a facet_grid vs. individual panels like facet_wrap. Only applies to ggplot2 plot objects.} 37 | } 38 | \description{ 39 | Write a plot object as a panel in a Trelliscope display 40 | } 41 | -------------------------------------------------------------------------------- /man/write_panels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/json_writers.R 3 | \name{write_panels} 4 | \alias{write_panels} 5 | \title{Write a list of plot objects as panels in a Trelliscope display} 6 | \usage{ 7 | write_panels(plot_list, ..., pb = NULL) 8 | } 9 | \arguments{ 10 | \item{plot_list}{a named list of plot objects to be written as panels (objects can be trellis, ggplot2, or htmlwidget) with the list names being the keys for the panels} 11 | 12 | \item{...}{params passed directly to \code{\link{write_panel}}} 13 | 14 | \item{pb}{optional progress bar object to pass in and use to report progress} 15 | } 16 | \description{ 17 | Write a list of plot objects as panels in a Trelliscope display 18 | } 19 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hafen/trelliscopejs/e0805c98db6b9af913e49fa264b4ebb943e430c0/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(trelliscopejs) 3 | 4 | test_check("trelliscopejs") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-zzz-lintr.R: -------------------------------------------------------------------------------- 1 | 2 | # # https://github.com/jimhester/lintr 3 | # if (requireNamespace("lintr", quietly = TRUE)) { 4 | # context("lints") 5 | # test_that("package Style", { 6 | # lintr::expect_lint_free(cache = TRUE) 7 | # }) 8 | # } 9 | 10 | # lintr::lint_package() 11 | # covr::package_coverage() 12 | --------------------------------------------------------------------------------