├── .Rbuildignore ├── .gitattributes ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ ├── pr-commands.yaml │ └── test-coverage.yaml ├── .gitignore ├── CONTRIBUTING.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── broker.R ├── compute_align.R ├── compute_auto_group.R ├── compute_bin.R ├── compute_boxplot.R ├── compute_count.R ├── compute_density.R ├── compute_model_prediction.R ├── compute_stack.R ├── compute_tabulate.R ├── data_cocaine.R ├── df_to_d3json.R ├── dplyr.R ├── explain.R ├── export.R ├── flatten.R ├── full_seq.R ├── ggvis.R ├── ggvis_html.R ├── guide_axis.R ├── guide_legend.R ├── guide_props.R ├── handle.R ├── handle_brush.R ├── handle_click.R ├── handle_keyboard.R ├── handle_resize.R ├── input.R ├── inputs.R ├── interact_tooltip.R ├── layer.R ├── layer_bars.R ├── layer_bins.R ├── layer_boxplots.R ├── layer_densities.R ├── layer_guess.R ├── layer_lines.R ├── layer_model_predictions.R ├── linked_brush.R ├── mark.R ├── marks.R ├── message.R ├── options.R ├── pipe.R ├── print.R ├── prop.R ├── prop_band.R ├── props.R ├── scale.R ├── scale_defaults.R ├── scale_ggvis.R ├── scales.R ├── shiny.R ├── shiny_layout.R ├── singular.R ├── subvis.R ├── transform.R ├── utils.R ├── utils_data.R ├── utils_names.R ├── utils_props.R ├── utils_reactive.R ├── utils_resolution.R ├── vector_type.R ├── vega.R ├── waggle.R └── zzz.r ├── README.md ├── bench └── all_same.R ├── codecov.yml ├── cran-comments.md ├── data └── cocaine.rda ├── demo ├── 00Index ├── apps │ ├── README.md │ ├── basic │ │ ├── server.r │ │ └── ui.r │ ├── brush-linked │ │ ├── server.r │ │ └── ui.r │ ├── brush-summary │ │ ├── server.r │ │ └── ui.r │ ├── linked-hover │ │ ├── server.r │ │ └── ui.r │ └── zoom │ │ ├── server.r │ │ └── ui.r ├── bar.r ├── boxplot.r ├── brush.r ├── dynamic.r ├── guides.r ├── histogram.r ├── hover.r ├── interactive.R ├── lines.r ├── rmarkdown │ ├── .gitignore │ ├── html_document.Rmd │ ├── interactive_doc.Rmd │ ├── ioslides_presentation.Rmd │ ├── linked_brush.Rmd │ └── zoom.Rmd ├── scales.r ├── scatterplot.r ├── size.r ├── smooth.r ├── subvis.R ├── tile.r └── tourr.r ├── ggvis.Rproj ├── inst ├── .gitignore ├── update.sh └── www │ ├── ggvis │ ├── css │ │ ├── gear.png │ │ └── ggvis.css │ └── js │ │ ├── ggvis.js │ │ └── shiny-ggvis.js │ └── lib │ ├── d3 │ ├── d3.js │ └── d3.min.js │ ├── detect-resize │ └── jquery.resize.js │ ├── jquery-ui │ ├── images │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_228ef1_256x240.png │ │ ├── ui-icons_ef8c08_256x240.png │ │ ├── ui-icons_ffd27a_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── index.html │ ├── jquery-ui.css │ ├── jquery-ui.js │ ├── jquery-ui.min.css │ ├── jquery-ui.min.js │ ├── jquery-ui.structure.css │ ├── jquery-ui.structure.min.css │ ├── jquery-ui.theme.css │ └── jquery-ui.theme.min.css │ ├── jquery │ ├── AUTHORS.txt │ ├── jquery.js │ └── jquery.min.js │ ├── lodash │ └── lodash.min.js │ └── vega │ ├── vega.js │ └── vega.min.js ├── man-roxygen └── properties.R ├── man ├── add_axis.Rd ├── add_data.Rd ├── add_guide_axis.Rd ├── add_guide_legend.Rd ├── add_legend.Rd ├── add_props.Rd ├── add_relative_scales.Rd ├── add_scale.Rd ├── add_tooltip.Rd ├── as.vega.Rd ├── auto_group.Rd ├── axis_props.Rd ├── band.Rd ├── bin_vector.Rd ├── cocaine.Rd ├── compute_align.Rd ├── compute_bin.Rd ├── compute_boxplot.Rd ├── compute_count.Rd ├── compute_density.Rd ├── compute_model_prediction.Rd ├── compute_stack.Rd ├── compute_tabulate.Rd ├── create_broker.Rd ├── create_input.Rd ├── default_options.Rd ├── dplyr-ggvis.Rd ├── explain.Rd ├── explain.ggvis.Rd ├── export_png.Rd ├── fullseq.Rd ├── get_data.Rd ├── ggvis.Rd ├── ggvisControlOutput.Rd ├── ggvisOutputElements.Rd ├── ggvis_message.Rd ├── ggvis_scale.Rd ├── group_by.Rd ├── handle_brush.Rd ├── handle_click.Rd ├── handle_resize.Rd ├── input_checkbox.Rd ├── input_select.Rd ├── input_slider.Rd ├── input_text.Rd ├── is.axis_props.Rd ├── is.broker.Rd ├── is.dynamic.Rd ├── is.ggvis.Rd ├── is.legend_props.Rd ├── is.scaled_value.Rd ├── knit_print.ggvis.Rd ├── layer_bars.Rd ├── layer_boxplots.Rd ├── layer_densities.Rd ├── layer_f.Rd ├── layer_guess.Rd ├── layer_histograms.Rd ├── layer_lines.Rd ├── layer_model_predictions.Rd ├── left_right.Rd ├── legend_props.Rd ├── linked_brush.Rd ├── mark.Rd ├── marks.Rd ├── new_prop.Rd ├── padding.Rd ├── pipe.Rd ├── print.ggvis.Rd ├── prop.Rd ├── prop_domain.Rd ├── propname_to_scale.Rd ├── props.Rd ├── resolution.Rd ├── save_spec.Rd ├── scale_datetime.Rd ├── scale_numeric.Rd ├── scale_ordinal.Rd ├── scaled_value.Rd ├── scales.Rd ├── scaletype_to_vega_scaletype.Rd ├── set_options.Rd ├── set_scale_label.Rd ├── shiny-ggvis.Rd ├── show_spec.Rd ├── show_tooltip.Rd ├── sidebarBottomPage.Rd ├── singular.Rd ├── subvis.Rd ├── vector_type.Rd ├── vega_data_parser.Rd ├── waggle.Rd └── zero_range.Rd ├── revdep ├── .gitignore ├── README.md ├── checks.rds ├── cran.md ├── email.yml ├── failures.md └── problems.md ├── tests ├── specs │ ├── bar.r │ ├── bar │ │ ├── categorical-x.json │ │ └── continuous-x.json │ ├── boxplot.r │ ├── boxplot │ │ ├── boxplot-categorical.json │ │ ├── boxplot-continuous.json │ │ └── boxplot-no-outliers.json │ ├── data.r │ ├── data │ │ └── dots.json │ ├── layer.r │ ├── layer │ │ ├── freqpoly-grouped.json │ │ ├── histogram.json │ │ ├── smooth-grouped.json │ │ └── smooth.json │ ├── line.r │ ├── line │ │ ├── basic.json │ │ ├── layer-line-nominal-x.json │ │ ├── layer-line.json │ │ └── sort.json │ ├── scales.R │ ├── scales │ │ ├── bars.json │ │ ├── combined_legend.json │ │ ├── custom.json │ │ ├── datetime.json │ │ ├── datetime_hist.json │ │ ├── domain_numeric.json │ │ ├── dual.json │ │ ├── hide_guides.json │ │ └── log.json │ ├── scatter.r │ └── scatter │ │ ├── basic.json │ │ ├── fill-continuous.json │ │ ├── fill-discrete.json │ │ └── transform.json ├── testthat.R └── testthat │ ├── test-compute-bin.r │ ├── test-compute-boxplot.r │ ├── test-compute-count.r │ ├── test-compute-density.r │ ├── test-compute-model-prediction.r │ ├── test-compute-stack.r │ ├── test-compute-tabulate.r │ ├── test-flatten.r │ ├── test-ggvis.R │ ├── test-is-dynamic.r │ ├── test-mark-properties.r │ ├── test-props.r │ ├── test-specs.r │ ├── test-utils-data.r │ └── test-utils.r └── tools └── updatejQueryResize.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | man-roxygen 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | bench 5 | ^\.travis\.yml$ 6 | ^node_modules$ 7 | ^CONTRIBUTING\.md$ 8 | ^revdep$ 9 | ^cran-comments\.md$ 10 | ^\.github$ 11 | ^CRAN-RELEASE$ 12 | ^codecov\.yml$ 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /NEWS.md merge=union 2 | 3 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | # 4 | # NOTE: This workflow is overkill for most R packages and 5 | # check-standard.yaml is likely a better choice. 6 | # usethis::use_github_action("check-standard") will install it. 7 | on: 8 | push: 9 | branches: [main, master] 10 | pull_request: 11 | branches: [main, master] 12 | 13 | name: R-CMD-check 14 | 15 | jobs: 16 | R-CMD-check: 17 | runs-on: ${{ matrix.config.os }} 18 | 19 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | config: 25 | - {os: macos-latest, r: 'release'} 26 | 27 | - {os: windows-latest, r: 'release'} 28 | # Use 3.6 to trigger usage of RTools35 29 | - {os: windows-latest, r: '3.6'} 30 | # use 4.1 to check with rtools40's older compiler 31 | - {os: windows-latest, r: '4.1'} 32 | 33 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 34 | - {os: ubuntu-latest, r: 'release'} 35 | - {os: ubuntu-latest, r: 'oldrel-1'} 36 | - {os: ubuntu-latest, r: 'oldrel-2'} 37 | - {os: ubuntu-latest, r: 'oldrel-3'} 38 | - {os: ubuntu-latest, r: 'oldrel-4'} 39 | 40 | env: 41 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 42 | R_KEEP_PKG_SOURCE: yes 43 | 44 | steps: 45 | - uses: actions/checkout@v4 46 | 47 | - uses: r-lib/actions/setup-pandoc@v2 48 | 49 | - uses: r-lib/actions/setup-r@v2 50 | with: 51 | r-version: ${{ matrix.config.r }} 52 | http-user-agent: ${{ matrix.config.http-user-agent }} 53 | use-public-rspm: true 54 | 55 | - uses: r-lib/actions/setup-r-dependencies@v2 56 | with: 57 | extra-packages: any::rcmdcheck 58 | needs: check 59 | 60 | - uses: r-lib/actions/check-r-package@v2 61 | with: 62 | upload-snapshots: true 63 | -------------------------------------------------------------------------------- /.github/workflows/pr-commands.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | name: Commands 8 | 9 | jobs: 10 | document: 11 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }} 12 | name: document 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - uses: r-lib/actions/pr-fetch@v2 20 | with: 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | - uses: r-lib/actions/setup-r@v2 24 | with: 25 | use-public-rspm: true 26 | 27 | - uses: r-lib/actions/setup-r-dependencies@v2 28 | with: 29 | extra-packages: any::roxygen2 30 | needs: pr-document 31 | 32 | - name: Document 33 | run: roxygen2::roxygenise() 34 | shell: Rscript {0} 35 | 36 | - name: commit 37 | run: | 38 | git config --local user.name "$GITHUB_ACTOR" 39 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 40 | git add man/\* NAMESPACE 41 | git commit -m 'Document' 42 | 43 | - uses: r-lib/actions/pr-push@v2 44 | with: 45 | repo-token: ${{ secrets.GITHUB_TOKEN }} 46 | 47 | style: 48 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }} 49 | name: style 50 | runs-on: ubuntu-latest 51 | env: 52 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 53 | steps: 54 | - uses: actions/checkout@v4 55 | 56 | - uses: r-lib/actions/pr-fetch@v2 57 | with: 58 | repo-token: ${{ secrets.GITHUB_TOKEN }} 59 | 60 | - uses: r-lib/actions/setup-r@v2 61 | 62 | - name: Install dependencies 63 | run: install.packages("styler") 64 | shell: Rscript {0} 65 | 66 | - name: Style 67 | run: styler::style_pkg() 68 | shell: Rscript {0} 69 | 70 | - name: commit 71 | run: | 72 | git config --local user.name "$GITHUB_ACTOR" 73 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 74 | git add \*.R 75 | git commit -m 'Style' 76 | 77 | - uses: r-lib/actions/pr-push@v2 78 | with: 79 | repo-token: ${{ secrets.GITHUB_TOKEN }} 80 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: | 31 | covr::codecov( 32 | quiet = FALSE, 33 | clean = FALSE, 34 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") 35 | ) 36 | shell: Rscript {0} 37 | 38 | - name: Show testthat output 39 | if: always() 40 | run: | 41 | ## -------------------------------------------------------------------- 42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true 43 | shell: bash 44 | 45 | - name: Upload test results 46 | if: failure() 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: coverage-test-failures 50 | path: ${{ runner.temp }}/package 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | We welcome contributions to the **ggvis** package. To submit a contribution: 3 | 4 | 1. [Fork](https://github.com/rstudio/ggvis/fork) the repository and make your changes. 5 | 6 | 2. Ensure that you have signed the [individual](https://www.rstudio.com/wp-content/uploads/2014/06/RStudioIndividualContributorAgreement.pdf) or [corporate](https://www.rstudio.com/wp-content/uploads/2014/06/RStudioCorporateContributorAgreement.pdf) contributor agreement as appropriate. You can send the signed copy to jj@rstudio.com. 7 | 8 | 3. Submit a [pull request](https://help.github.com/articles/using-pull-requests). 9 | 10 | We'll try to be as responsive as possible in reviewing and accepting pull requests. Appreciate your contributions very much! 11 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggvis 2 | Title: Interactive Grammar of Graphics 3 | Version: 0.4.9 4 | Authors@R: c( 5 | person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre")), 6 | person("Winston", "Chang", , "winston@posit.co", role = "aut"), 7 | person(, "Posit", role = "cph"), 8 | person(, "jQuery Foundation", role = "cph", 9 | comment = "jQuery library and jQuery UI library"), 10 | person(, "jQuery contributors", role = c("ctb", "cph"), 11 | comment = "jQuery library; authors listed in inst/www/lib/jquery/AUTHORS.txt"), 12 | person(, "jQuery UI contributors", role = c("ctb", "cph"), 13 | comment = "jQuery UI library; authors listed in inst/www/lib/jquery-ui/AUTHORS.txt"), 14 | person("Mike", "Bostock", role = c("ctb", "cph"), 15 | comment = "D3 library"), 16 | person(, "D3 contributors", role = "ctb", 17 | comment = "D3 library; authors listed at https://github.com/d3/d3/graphs/contributors"), 18 | person(, "Trifacta Inc.", role = "cph", 19 | comment = "Vega library"), 20 | person(, "Vega contributors", role = "ctb", 21 | comment = "Vega library; authors listed at https://github.com/trifacta/vega/graphs/contributors"), 22 | person("Sebastián", "Décima", role = c("ctb", "cph"), 23 | comment = "javascript-detect-element-resize library") 24 | ) 25 | Description: An implementation of an interactive grammar of graphics, 26 | taking the best parts of 'ggplot2', combining them with the reactive 27 | framework of 'shiny' and drawing web graphics using 'vega'. 28 | License: GPL-2 | file LICENSE 29 | URL: https://ggvis.rstudio.com/ 30 | Depends: 31 | R (>= 3.0) 32 | Imports: 33 | assertthat, 34 | dplyr (>= 0.5.0), 35 | htmltools (>= 0.2.4), 36 | jsonlite (>= 0.9.11), 37 | magrittr, 38 | methods, 39 | rlang, 40 | shiny (>= 0.11.1) 41 | Suggests: 42 | knitr (>= 1.6), 43 | lubridate, 44 | MASS, 45 | mgcv, 46 | rmarkdown, 47 | testthat (>= 0.8.1) 48 | Encoding: UTF-8 49 | LazyData: true 50 | RoxygenNote: 7.3.1 51 | -------------------------------------------------------------------------------- /R/broker.R: -------------------------------------------------------------------------------- 1 | #' Create a broker object 2 | #' 3 | #' A broker is a subclass of reactive. It can hold extra information to 4 | #' facilitate (or broker) communication between the client and the server. 5 | #' For example, an input broker may contain HTML controls to be emitted on the 6 | #' client web page, as well as a function to connect the inputs from the client 7 | #' to the reactive expression. 8 | #' 9 | #' Other types of brokers are possible. Another broker may create reactive 10 | #' observers and add information to the Vega spec, instead of having HTML 11 | #' controls. In this case, a reactive expression is still needed, although 12 | #' it can be a dummy value, like \code{reactive(NULL)}. 13 | #' 14 | #' @param r A reactive expression. 15 | #' @param controls An HTML control, or a list of HTML controls. 16 | #' @param connect A function to run at render time. This function takes the 17 | #' Shiny \code{session} object as its only argument, and is used to connect 18 | #' the session with the broker object. 19 | #' @param spec Object to put in the Vega spec. 20 | #' @export 21 | #' @keywords internal 22 | create_broker <- function(r, controls = NULL, connect = NULL, spec = NULL) { 23 | if (!shiny::is.reactive(r)) stop("r must be a reactive expression.") 24 | 25 | # If passed a bare control, wrap it into a list 26 | if (!is.null(controls) && inherits(controls, "shiny.tag")) { 27 | controls <- list(controls) 28 | names(controls) <- paste0("unnamed input ", seq_len(length(controls))) 29 | } 30 | 31 | class(r) <- c("broker", class(r)) 32 | 33 | attr(r, "broker") <- structure(list( 34 | controls = controls, 35 | connect = connect, 36 | spec = spec 37 | )) 38 | 39 | if (is.null(reactive_id(r))) { 40 | reactive_id(r) <- rand_id("reactive_") 41 | } 42 | 43 | r 44 | } 45 | 46 | #' Determine if an object is a broker object 47 | #' 48 | #' @param x An object to test. 49 | #' @export 50 | is.broker <- function(x) inherits(x, "broker") 51 | 52 | # Get the label of a connector function 53 | connector_label <- function(x) attr(x, "label", TRUE) 54 | 55 | # Set the label of a connector function 56 | `connector_label<-` <- function(x, value) { 57 | attr(x, "label") <- value 58 | x 59 | } 60 | -------------------------------------------------------------------------------- /R/compute_auto_group.R: -------------------------------------------------------------------------------- 1 | #' Automatically group data by grouping variables 2 | #' 3 | #' Use \code{auto_group} to group up a dataset on all categorical variables 4 | #' specified by props, and have each piece rendered by the same mark. 5 | #' 6 | #' @export 7 | #' @param vis The ggvis visualisation to modify. 8 | #' @param exclude A vector containing names of props to exclude from auto grouping. 9 | #' It is often useful to exclude \code{c("x", "y")}, when one of those variables 10 | #' is categorical. 11 | #' @seealso To manually specify grouping variables, see \code{\link{group_by}}. 12 | #' @examples 13 | #' # One line 14 | #' mtcars %>% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) %>% layer_paths() 15 | #' # One line for each level of cyl 16 | #' mtcars %>% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) %>% group_by(cyl) %>% 17 | #' layer_paths() 18 | #' mtcars %>% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) %>% auto_group() %>% 19 | #' layer_paths() 20 | #' 21 | #' # The grouping column can already be stored as a factor 22 | #' mtcars2 <- mtcars 23 | #' mtcars2$cyl <- factor(mtcars2$cyl) 24 | #' mtcars2 %>% ggvis(~disp, ~mpg, stroke = ~cyl) %>% auto_group() %>% 25 | #' layer_paths() 26 | auto_group <- function(vis, exclude = NULL) { 27 | 28 | # Figure out grouping variable 29 | data <- cur_data(vis) 30 | props <- cur_props(vis) 31 | 32 | # Drop props named in exclude 33 | pnames <- trim_prop_event(names(props)) 34 | props <- props[!(pnames %in% exclude)] 35 | 36 | countable <- vapply(props, 37 | function(prop) is.prop_variable(prop) && prop_countable(data, prop), 38 | logical(1) 39 | ) 40 | if (!any(countable)) return(vis) 41 | 42 | group_vars <- lapply(unname(props[countable]), "[[", "value") 43 | dplyr::group_by(vis, !!!group_vars) 44 | } 45 | -------------------------------------------------------------------------------- /R/data_cocaine.R: -------------------------------------------------------------------------------- 1 | #' Cocaine seizures in the US. 2 | #' 3 | #' This dataset comes from STRIDE, the System to Retrieve Information from Drug 4 | #' Evidence. It contains all concaine seizures in the US from 2007 that have 5 | #' a known weight. 6 | #' 7 | #' @section Variables: 8 | #' \describe{ 9 | #' \item{state}{State where seizure occured.} 10 | #' \item{potency}{Purity of cocaine, as percentage (100\% = pure cocaine, 11 | #' 0\% = all filler)} 12 | #' \item{weight}{Weight, in grams.} 13 | #' \item{month}{Month in which seizure occured.} 14 | #' \item{price}{Estimated value in USD.} 15 | #' } 16 | #' @section Use: 17 | #' Use of this data requires your agreement to refer to your analyses as 18 | #' "unvalidated DEA data and to claim authorship and responsibility for any 19 | #' inferences and/or conclusions you may draw from this information." 20 | #' @format Data frame with 3380 observations of 5 variables. 21 | "cocaine" 22 | -------------------------------------------------------------------------------- /R/df_to_d3json.R: -------------------------------------------------------------------------------- 1 | # Convert a data object to a D3-structured data object. 2 | df_to_d3json <- function(x) { 3 | rows <- nrow(x) 4 | colnames <- stats::setNames(names(x), names(x)) 5 | 6 | x <- lapply(x, format_vec_d3json) 7 | 8 | lapply(seq_len(rows), function(i) { 9 | lapply(colnames, function(colname) { 10 | .subset2(.subset2(x, colname), i) 11 | }) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /R/explain.R: -------------------------------------------------------------------------------- 1 | #' Explain details of an object 2 | #' 3 | #' This is a generic function which gives more details about an object than 4 | #' print, and is more focussed on human readable output than str. 5 | #' 6 | #' @export 7 | #' @seealso \code{dplyr::\link[dplyr]{explain}} for more information. 8 | #' @importFrom dplyr explain 9 | #' @name explain 10 | #' @examples 11 | #' p <- mtcars %>% ggvis(x = ~cyl) %>% layer_bars() 12 | #' explain(p) 13 | NULL 14 | 15 | #' Print out the structure of a ggvis object in a friendly format 16 | #' 17 | #' @param x Visualisation to explain 18 | #' @param ... Needed for compatibility with generic. Ignored by this method. 19 | #' @method explain ggvis 20 | #' @export 21 | explain.ggvis <- function (x, ...) { 22 | cat("Marks:\n") 23 | for (mark in x$marks) { 24 | cat(indent(format(mark), 2)) 25 | } 26 | cat("Data objects:\n") 27 | for (dat in x$data) { 28 | cat(indent(data_id(dat), 2), "\n") 29 | } 30 | cat("Reactives:\n") 31 | for (reactive in x$reactives) { 32 | cat(indent(reactive_id(reactive), 2)) 33 | if (is.broker(reactive)) { 34 | cat(" \n") 35 | } else { 36 | cat("\n") 37 | } 38 | } 39 | cat("Scales:\n") 40 | for (scale_name in names(x$scales)) { 41 | cat(indent(paste0(scale_name, ":\n"), 2)) 42 | for (scale in x$scales[[scale_name]]) { 43 | cat(indent(format(scale), 4)) 44 | cat("\n") 45 | } 46 | } 47 | cat("Axes:\n") 48 | for (axis in x$axes) { 49 | cat(indent(format(axis), 2)) 50 | cat("\n") 51 | } 52 | cat("Legends:\n") 53 | for (legend in x$legends) { 54 | cat(indent(format(legend), 2)) 55 | cat("\n") 56 | } 57 | cat("HTML controls:\n") 58 | for (control_name in names(x$controls)) { 59 | cat(indent(control_name, 2)) 60 | cat("\n") 61 | } 62 | cat("Client-side handlers:\n") 63 | for (handler in x$handlers) { 64 | cat(indent(paste0("<", handler$type, "> ", handler$id), 2)) 65 | cat("\n") 66 | } 67 | cat("Connector functions:\n") 68 | for (connector in x$connectors) { 69 | cat(indent(connector_label(connector), 2)) 70 | cat("\n") 71 | } 72 | cat("Options:\n") 73 | if (length(x$options) > 0) { 74 | params <- param_string(x$options, collapse = FALSE) 75 | cat(paste0(" ", format(paste0(names(params), ":")), " ", format(params), 76 | collapse = "\n")) 77 | cat("\n") 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /R/export.R: -------------------------------------------------------------------------------- 1 | #' Export a PNG or SVG from a ggvis object 2 | #' 3 | #' This requires that the external program \code{vg2png} is installed. This is 4 | #' part of the \code{vega} node.js module. 5 | #' 6 | #' @seealso \url{https://github.com/trifacta/vega} for information on installing 7 | #' \code{vg2png} and \code{vg2svg}. 8 | #' 9 | #' @param vis A ggvis object. 10 | #' @param file Output file name. If NULL, defaults to "plot.svg" or "plot.png". 11 | #' @examples 12 | #' \dontrun{ 13 | #' mtcars %>% ggvis(x = ~wt) %>% export_png() 14 | #' } 15 | #' @export 16 | export_png <- function(vis, file = NULL) { 17 | vega_file(vis, file = file, type = "png") 18 | } 19 | 20 | #' @rdname export_png 21 | #' @export 22 | export_svg <- function(vis, file = NULL) { 23 | vega_file(vis, file = file, type = "svg") 24 | } 25 | 26 | # Generate an output image file from a ggvis object 27 | # 28 | # @param vis A ggvis object. 29 | # @param file Output file name. If NULL, defaults to "plot.png". 30 | # @param type Output file type. 31 | vega_file <- function(vis, file = NULL, type = "png") { 32 | 33 | if (!(type %in% c("png", "svg"))) stop("type must be 'png' or 'svg'") 34 | 35 | if (is.null(file)) { 36 | file <- paste0("plot.", type) 37 | message("Writing to file ", file) 38 | } 39 | 40 | temp_dir <- tempfile(pattern = "ggvis") 41 | dir.create(temp_dir) 42 | 43 | # Try to find the external program that generates the images 44 | cmd <- paste0("vg2", type) 45 | 46 | # Search in these paths and use the first one found 47 | cmdsearch <- Sys.which(paste0(c("", "./bin/", "./node_modules/.bin/"), cmd)) 48 | found_idx <- which(nzchar(cmdsearch)) 49 | if (length(found_idx) == 0) 50 | stop("Conversion program ", cmd, "not found.") 51 | cmd <- cmdsearch[min(found_idx)] 52 | 53 | # Generate the Vega JSON spec 54 | json_file <- file.path(temp_dir, "plot.json") 55 | vega_json <- save_spec(vis, json_file) 56 | on.exit(unlink(json_file)) 57 | 58 | # Create the image file 59 | system2(cmd, args = c(json_file, file)) 60 | } 61 | -------------------------------------------------------------------------------- /R/flatten.R: -------------------------------------------------------------------------------- 1 | #' Creates a named list, giving the properties used by each dataset. 2 | #' 3 | #' @noRd 4 | #' @examples 5 | #' base <- mtcars %>% ggvis(~wt, ~mpg) 6 | #' base %>% layer_points() %>% combine_data_props() 7 | #' base %>% layer_points() %>% layer_points() %>% combine_data_props() 8 | #' base %>% layer_points(y = ~cyl) %>% layer_points(y = ~disp) %>% combine_data_props() 9 | #' base %>% layer_points() %>% layer_points(~conc, ~uptake, data = CO2) %>% 10 | #' combine_data_props() 11 | combine_data_props <- function(mark) { 12 | if (is.ggvis(mark)) return(combine_data_props(mark$marks)) 13 | if (identical(class(mark), "mark")) { 14 | return(stats::setNames(list(mark$props), data_id(mark$data))) 15 | } 16 | 17 | if (is.mark_group(mark)) { 18 | children <- mark$marks 19 | } else if (is.list(mark)) { 20 | children <- mark 21 | } else { 22 | stop("Invalid input") 23 | } 24 | all_props <- unlist(lapply(children, combine_data_props), recursive = FALSE) 25 | 26 | # Combine together props for data with same name 27 | props_by_id <- split(all_props, names(all_props)) 28 | props_by_id <- lapply(props_by_id, unlist, recursive = FALSE, use.names = FALSE) 29 | 30 | # Remove duplicates, and props that don't appear in the data 31 | lapply(props_by_id, function(props) { 32 | names <- safe_vega_var(vapply(props, prop_label, character(1))) 33 | ok <- !duplicated(names) & names != "" 34 | 35 | stats::setNames(props[ok], names[ok]) 36 | }) 37 | } 38 | 39 | # Create a new reactive dataset containing only the data actually used 40 | # by properties. 41 | active_props <- function(data, props) { 42 | reactive_prop <- function(props, parent_data) { 43 | force(props) 44 | force(parent_data) 45 | reactive({ 46 | apply_props(parent_data(), props) 47 | }) 48 | } 49 | 50 | data_out <- list() 51 | for (data_n in names(props)) { 52 | data_out[[data_n]] <- reactive_prop(props[[data_n]], data[[data_n]]) 53 | } 54 | 55 | data_out 56 | } 57 | 58 | # Apply properties to a data object, creating calculated columns and dropping 59 | # unused columns. 60 | apply_props <- function(data, props) { 61 | UseMethod("apply_props") 62 | } 63 | 64 | #' @export 65 | apply_props.data.frame <- function(data, props) { 66 | cols <- lapply(props, prop_value, data = data) 67 | names(cols) <- vapply(props, prop_label, character(1)) 68 | quickdf(cols) 69 | } 70 | 71 | #' @export 72 | apply_props.grouped_df <- function(data, props) { 73 | dplyr::do(data, apply_props(., props)) 74 | } 75 | -------------------------------------------------------------------------------- /R/full_seq.R: -------------------------------------------------------------------------------- 1 | #' Generate sequence of fixed size intervals covering range. 2 | #' 3 | #' @param range range 4 | #' @param size interval size 5 | #' @param ... other arguments passed on to methods 6 | #' @keywords internal 7 | #' @export 8 | fullseq <- function(range, size, ...) UseMethod("fullseq") 9 | 10 | #' @export 11 | fullseq.numeric <- function(range, size, ..., pad = FALSE) { 12 | # if (zero_range(range)) return(range + size * c(-1, 1) / 2) 13 | 14 | x <- seq( 15 | round_any(range[1], size, floor), 16 | round_any(range[2], size, ceiling), 17 | by = size 18 | ) 19 | 20 | if (pad) { 21 | # Add extra bin on bottom and on top, to guarantee that we cover complete 22 | # range of data, whether right = T or F 23 | c(min(x) - size, x, max(x) + size) 24 | } else { 25 | x 26 | } 27 | } 28 | 29 | #' @export 30 | fullseq.POSIXt <- function(range, size, ...) { 31 | seq(range[1], range[2], by = size) 32 | } 33 | #' @export 34 | fullseq.Date <- fullseq.POSIXt 35 | 36 | round_any <- function(x, accuracy, f = round) { 37 | f(x / accuracy) * accuracy 38 | } 39 | -------------------------------------------------------------------------------- /R/ggvis_html.R: -------------------------------------------------------------------------------- 1 | ggvis_path <- function(x) { 2 | system.file(package = "ggvis", "www", x) 3 | } 4 | 5 | # HTML dependencies of a ggvis plot 6 | ggvis_dependencies <- function() { 7 | 8 | minified <- getOption("ggvis.js_minified", TRUE) 9 | adjust_min <- function(x) { 10 | if (minified) return(x) 11 | gsub("\\.min", "", x) 12 | } 13 | 14 | deps <- list( 15 | htmltools::htmlDependency( 16 | name = "jquery", 17 | version = "1.11.0", 18 | src = ggvis_path("lib/jquery"), 19 | script = "jquery.min.js" 20 | ), 21 | htmltools::htmlDependency( 22 | name = "detect-resize", 23 | version = "0.5.3", 24 | src = ggvis_path("lib/detect-resize"), 25 | script = "jquery.resize.js" 26 | ), 27 | htmltools::htmlDependency( 28 | name = "jquery-ui", 29 | version = "1.11.4", 30 | src = ggvis_path("lib/jquery-ui"), 31 | script = adjust_min("jquery-ui.min.js"), 32 | stylesheet = adjust_min("jquery-ui.min.css") 33 | ), 34 | htmltools::htmlDependency( 35 | name = "d3", 36 | version = "3.5.2", 37 | src = ggvis_path("lib/d3"), 38 | script = adjust_min("d3.min.js") 39 | ), 40 | htmltools::htmlDependency( 41 | name = "vega", 42 | version = "1.4.3", 43 | src = ggvis_path("lib/vega"), 44 | script = adjust_min("vega.min.js") 45 | ), 46 | htmltools::htmlDependency( 47 | name = "lodash", 48 | version = "4.17.21", 49 | src = ggvis_path("lib/lodash"), 50 | script = adjust_min("lodash.min.js"), 51 | head = "" 52 | ), 53 | htmltools::htmlDependency( 54 | name = "ggvis", 55 | version = as.character(utils::packageVersion("ggvis")), 56 | src = ggvis_path("ggvis"), 57 | script = "js/ggvis.js", 58 | stylesheet = "css/ggvis.css" 59 | ) 60 | ) 61 | 62 | deps 63 | } 64 | 65 | shiny_dependency <- function() { 66 | htmltools::htmlDependency( 67 | name = "shiny-ggvis", 68 | version = as.character(utils::packageVersion("ggvis")), 69 | src = ggvis_path("ggvis"), 70 | script = "js/shiny-ggvis.js" 71 | ) 72 | } 73 | 74 | ggvis_app <- function(x, plot_id = rand_id("plot_"), 75 | ...) { 76 | 77 | ui <- ggvisLayout(plot_id, length(x$controls) > 0, spec = NULL, shiny = TRUE) 78 | 79 | server <- function(input, output, session) { 80 | r_gv <- reactive(x) 81 | bind_shiny(r_gv, session = session, plot_id = plot_id, 82 | controls_id = "ggvis_controls") 83 | } 84 | 85 | options <- compact(list(...)) 86 | 87 | shiny::shinyApp(ui = ui, server = server, options = options) 88 | } 89 | -------------------------------------------------------------------------------- /R/handle.R: -------------------------------------------------------------------------------- 1 | 2 | # Callback helper functions --------------------------------------------------- 3 | 4 | # Check that input is a funtion with the specified arguments 5 | check_callback <- function(f, args) { 6 | if (!is.null(f)) return() 7 | fname <- deparse2(substitute(f)) 8 | 9 | if (!is.function(f)) { 10 | stop(fname, " is not a function", call. = FALSE) 11 | } 12 | 13 | f_args <- names(formals(f)) 14 | if (any(f_args == "...")) return() 15 | 16 | if (!identical(f_args, args)) { 17 | stop(fname, " needs arguments: ", paste(args, collapse = ", "), 18 | call. = FALSE) 19 | } 20 | } 21 | 22 | # Given callback, id and session, setup an observer 23 | setup_callback <- function(f, id, session) { 24 | if (is.null(f)) return() 25 | 26 | shiny::observe({ 27 | value <- session$input[[id]] 28 | f(value, session) 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /R/handle_click.R: -------------------------------------------------------------------------------- 1 | #' Handle mouse actions on marks. 2 | #' 3 | #' @param vis Visualisation to listen to. 4 | #' @param on_click,on_mouse_over Callback function with arguments: 5 | #' \describe{ 6 | #' \item{data}{A data frame with one row} 7 | #' \item{location}{A named list with components x and y} 8 | #' \item{session}{The session, used to communicate with the browser} 9 | #' } 10 | #' @param on_mouse_out Callback function with argument: 11 | #' \describe{ 12 | #' \item{session}{The session, used to communicate with the browser} 13 | #' } 14 | #' @export 15 | #' @examples 16 | #' location <- function(location, ...) cat(location$x, "x", location$y, "\n") 17 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_points() %>% 18 | #' handle_click(location) 19 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_points() %>% 20 | #' handle_hover(function(...) cat("over\n"), function(...) cat("off\n")) 21 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_points() %>% 22 | #' handle_hover(function(data, ...) str(data)) 23 | handle_click <- function(vis, on_click = NULL) { 24 | check_callback(on_click, c("data", "location", "session")) 25 | 26 | connect <- function(session, plot_id) { 27 | watch_mouse(session, paste0(plot_id, "_mouse_click"), on_click) 28 | } 29 | 30 | spec <- list(type = "click") 31 | broker <- create_broker(reactive(NULL), connect = connect, spec = spec) 32 | register_reactive(vis, broker) 33 | } 34 | 35 | #' @rdname handle_click 36 | #' @export 37 | handle_hover <- function(vis, on_mouse_over = NULL, on_mouse_out = NULL) { 38 | if (!is.null(on_mouse_over)) 39 | check_callback(on_mouse_over, c("data", "location", "session")) 40 | if (!is.null(on_mouse_out)) 41 | check_callback(on_mouse_out, "session") 42 | 43 | connect <- function(session, plot_id) { 44 | watch_mouse(session, paste0(plot_id, "_mouse_over"), on_mouse_over) 45 | 46 | if (is.null(on_mouse_out)) return() 47 | shiny::observe({ 48 | value <- session$input[[paste0(plot_id, "_mouse_out")]] 49 | if (is.null(value)) return() 50 | 51 | on_mouse_out(session = session) 52 | }) 53 | } 54 | 55 | spec <- list(type = "hover") 56 | broker <- create_broker(reactive(NULL), connect = connect, spec = spec) 57 | register_reactive(vis, broker) 58 | } 59 | 60 | watch_mouse <- function(session, id, fun) { 61 | shiny::observe({ 62 | value <- session$input[[id]] 63 | if (is.null(value)) return() 64 | if (!is.list(value$data)) return() # axis ticks/labels etc 65 | 66 | df <- value$data 67 | class(df) <- "data.frame" 68 | attr(df, "row.names") <- .set_row_names(1L) 69 | 70 | fun( 71 | data = df, 72 | location = list(x = value$pagex, y = value$pagey), 73 | session = session 74 | ) 75 | }) 76 | } 77 | -------------------------------------------------------------------------------- /R/handle_resize.R: -------------------------------------------------------------------------------- 1 | #' Handlers and interactive inputs for plot sizing. 2 | #' 3 | #' @param vis Visualisation to listen to. 4 | #' @param on_resize Callback function with arguments: 5 | #' \describe{ 6 | #' \item{width,height}{Width and height in pixels} 7 | #' \item{padding}{A named list of four components giving the padding in 8 | #' each direction} 9 | #' \item{session}{The session, used to communicate with the browser} 10 | #' } 11 | #' @export 12 | #' @examples 13 | #' # This example just prints out the current dimensions to the console 14 | #' mtcars %>% ggvis(~mpg, ~wt) %>% 15 | #' layer_points() %>% 16 | #' handle_resize(function(width, height, ...) cat(width, "x", height, "\n")) 17 | #' 18 | #' # Use plot_width() and plot_height() to dynamically get the plot size 19 | #' # inside the plot. 20 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_text(text := plot_width()) 21 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_text(text := plot_height()) 22 | handle_resize <- function(vis, on_resize) { 23 | broker <- create_broker( 24 | reactive(NULL), 25 | connect = connect_resize(on_resize), 26 | spec = list(type = "resize") 27 | ) 28 | register_reactive(vis, broker) 29 | } 30 | 31 | 32 | #' @export 33 | #' @rdname handle_resize 34 | plot_width <- function(vis) { 35 | vals <- shiny::reactiveValues() 36 | vals$x <- 100 37 | on_resize <- function(width, ...) { 38 | vals$x <- width 39 | } 40 | 41 | create_broker( 42 | reactive(vals$x), 43 | connect = connect_resize(on_resize), 44 | spec = list(type = "resize") 45 | ) 46 | } 47 | 48 | #' @export 49 | #' @rdname handle_resize 50 | plot_height <- function(vis) { 51 | vals <- shiny::reactiveValues() 52 | vals$x <- 100 53 | on_resize <- function(height, ...) { 54 | vals$x <- height 55 | } 56 | 57 | create_broker( 58 | reactive(vals$x), 59 | connect = connect_resize(on_resize), 60 | spec = list(type = "resize") 61 | ) 62 | } 63 | 64 | 65 | connect_resize <- function(on_resize) { 66 | check_callback(on_resize, c("width", "height", "padding", "session")) 67 | 68 | function(session, plot_id) { 69 | id <- paste0(plot_id, "_resize") 70 | shiny::observe({ 71 | value <- session$input[[id]] 72 | if (is.null(value)) return() 73 | 74 | on_resize(width = value$width, height = value$height, 75 | padding = value$padding, session = value$session) 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /R/input.R: -------------------------------------------------------------------------------- 1 | #' Create a new interactive "input" object. 2 | #' 3 | #' An interactive input object is a reactive expression which wraps a reactive 4 | #' value. When the plot is rendered, an observer is created which pushes values 5 | #' into the reactive value in response to changes of an input object. Those 6 | #' changes invalidate the reactive expression, which will return the value, 7 | #' optionally passed through a mapping function. 8 | #' 9 | #' This function is designed to be used by authors of new types of interactive 10 | #' inputs. If you are a ggvis user, please use one of the more specific input 11 | #' functions starting with the \code{input_}. 12 | #' 13 | #' @param id The name of the input object in the Shiny app, such as 14 | #' "slider_1338869". 15 | #' @param default The default (starting) value for the input. 16 | #' @param map A mapping function. Defaults to \code{identity}, which simply 17 | #' returns the value unchanged. 18 | #' @param controls A Shiny HTML tag object representing the UI for the controls. 19 | #' @export 20 | #' @keywords internal 21 | create_input <- function(id = rand_id("input_"), default = NULL, 22 | map = identity, controls = NULL) { 23 | 24 | # Create a reactivevalues object to store the value. When a plot is rendered, 25 | # an observer will be set up to push values into val$x. 26 | vals <- shiny::reactiveValues() 27 | vals$x <- default 28 | 29 | # A reactive to wrap the reactive value 30 | res <- reactive({ 31 | map(vals$x) 32 | }) 33 | 34 | # This function is run at render time. It takes values from session$input$foo 35 | # and pushes them into val$foo. 36 | connect <- function(session, plot_id) { 37 | shiny::observe({ 38 | value <- session$input[[id]] 39 | if (is.null(value)) { 40 | # Need to explicitly set it to default when input is NULL, because some 41 | # inputs give NULL when they're cleared. (#272) 42 | vals$x <- default 43 | } else { 44 | vals$x <- value 45 | } 46 | }) 47 | } 48 | connector_label(connect) <- paste0("<", id, ">") 49 | 50 | # Wrap the shiny tag object into a list 51 | controls_l <- list() 52 | controls_l[[id]] <- controls 53 | 54 | create_broker(res, connect = connect, controls = controls_l) 55 | } 56 | -------------------------------------------------------------------------------- /R/layer.R: -------------------------------------------------------------------------------- 1 | #' Create a new layering function. 2 | #' 3 | #' The layer function is run, and then the state before the code was run 4 | #' is restored - this allows layers to be effectively isolated from 5 | #' the rest of the plot. 6 | #' 7 | #' @param vis The ggvis visualisation to modify. 8 | #' @param fun A function that takes a single argument, the current 9 | #' visualisation as input, and returns a modified visualisation. 10 | #' @keywords internal 11 | #' @export 12 | #' @examples 13 | #' mtcars %>% ggvis(~mpg) %>% 14 | #' layer_f(function(v) { 15 | #' v %>% compute_bin(~mpg) %>% layer_points(x = ~x_, y = ~count_) 16 | #' }) %>% 17 | #' layer_points(y = ~wt) 18 | layer_f <- function(vis, fun) { 19 | # Save current data and props 20 | old_data <- vis$cur_data 21 | old_props <- vis$cur_props 22 | 23 | vis <- fun(vis) 24 | 25 | # Restore previous data and props 26 | vis$cur_data <- old_data 27 | vis$cur_props <- old_props 28 | 29 | vis 30 | } 31 | -------------------------------------------------------------------------------- /R/layer_densities.R: -------------------------------------------------------------------------------- 1 | #' Transformation: density estimate 2 | #' 3 | #' \code{transform_density} is a data transformation that computes a kernel 4 | #' density estimate from a dataset. \code{layer_density} combines 5 | #' \code{transform_density} with \code{mark_path} and \code{mark_area} 6 | #' to display a smooth line and its standard errror. 7 | #' 8 | #' @param vis The visualisation to modify 9 | #' @param ... Visual properties, passed on to \code{\link{props}}. 10 | #' @param adjust Multiple the default bandwidth by this amount. Useful for 11 | #' controlling wiggliness of density. 12 | #' @inheritParams compute_density 13 | #' @param density_args Other arguments passed on to 14 | #' \code{\link{compute_density}} and thence to \code{\link{density}}. 15 | #' @param area Should there be a shaded region drawn under the curve? 16 | #' @export 17 | #' @examples 18 | #' # Basic density estimate 19 | #' faithful %>% ggvis(~waiting) %>% layer_densities() 20 | #' faithful %>% ggvis(~waiting) %>% layer_densities(area = FALSE) 21 | #' 22 | #' # Control bandwidth with adjust 23 | #' faithful %>% ggvis(~waiting) %>% layer_densities(adjust = .25) 24 | #' faithful %>% ggvis(~waiting) %>% 25 | #' layer_densities(adjust = input_slider(0.1, 5)) 26 | #' 27 | #' # Control stroke and fill 28 | #' faithful %>% ggvis(~waiting) %>% 29 | #' layer_densities(stroke := "red", fill := "red") 30 | #' 31 | #' # With groups 32 | #' PlantGrowth %>% ggvis(~weight, fill = ~group) %>% group_by(group) %>% 33 | #' layer_densities() 34 | #' PlantGrowth %>% ggvis(~weight, stroke = ~group) %>% group_by(group) %>% 35 | #' layer_densities(strokeWidth := 3, area = FALSE) 36 | layer_densities <- function(vis, ..., kernel = "gaussian", adjust = 1, 37 | density_args = list(), area = TRUE) { 38 | 39 | x_var <- find_prop_var(cur_props(vis), "x.update") 40 | 41 | vis <- set_scale_label(vis, "x", prop_label(cur_props(vis)$x.update)) 42 | vis <- set_scale_label(vis, "y", "density") 43 | 44 | props <- stroke_fill_defaults(props(...), 45 | stroke = props(~pred_, ~resp_), 46 | fill = props(~pred_, ~resp_, y2 = 0, fillOpacity := 0.2) 47 | ) 48 | 49 | pipeline <- function(x) { 50 | x <- do_call(compute_density, quote(x), x_var = x_var, kernel = kernel, 51 | adjust = adjust, .args = density_args) 52 | 53 | if (identical(area, TRUE)) { 54 | x <- emit_ribbons(x, props$fill) 55 | } 56 | x <- emit_paths(x, props$stroke) 57 | x 58 | } 59 | layer_f(vis, pipeline) 60 | } 61 | -------------------------------------------------------------------------------- /R/layer_lines.R: -------------------------------------------------------------------------------- 1 | #' Layer lines on a plot. 2 | #' 3 | #' \code{layer_lines} differs from \code{layer_paths} in that \code{layer_lines} 4 | #' sorts the data on the x variable, so the line will always proceed from left 5 | #' to right, whereas \code{layer_paths} will draw a line in whatever order 6 | #' appears in the data. 7 | #' 8 | #' @seealso \code{\link{layer_paths}} 9 | #' @export 10 | #' @param vis Visualisation to modify. 11 | #' @param ... Visual properties. 12 | #' @examples 13 | #' mtcars %>% ggvis(~wt, ~mpg, stroke = ~factor(cyl)) %>% layer_lines() 14 | #' 15 | #' # Equivalent to 16 | #' mtcars %>% ggvis(~wt, ~mpg, stroke = ~factor(cyl)) %>% 17 | #' group_by(cyl) %>% dplyr::arrange(wt) %>% layer_paths() 18 | layer_lines <- function(vis, ...) { 19 | 20 | x_var <- vis$cur_props$x.update$value 21 | 22 | layer_f(vis, function(x) { 23 | x <- auto_group(x, exclude = c("x", "y")) 24 | x <- dplyr::arrange(x, !!x_var) 25 | emit_paths(x, props(...)) 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /R/linked_brush.R: -------------------------------------------------------------------------------- 1 | #' Create a linked brush object. 2 | #' 3 | #' A linked brush has two sides: input and output 4 | #' 5 | #' @note \code{linked_brush} is very new and is likely to change substantially 6 | #' in the future 7 | #' @param keys vector of all possible keys, if known. 8 | #' @param fill brush colour 9 | #' @return A list with components: 10 | #' \item{input}{A function that takes a visualisation as an argument and 11 | #' adds an input brush to that plot} 12 | #' \item{selected}{A reactive providing a logical vector that describes 13 | #' which points are under the brush} 14 | #' \item{fill}{A reactive that gives the fill colour of points under the 15 | #' brush} 16 | #' @export 17 | #' @examples 18 | #' lb <- linked_brush(keys = 1:nrow(mtcars), "red") 19 | #' 20 | #' # Change the colour of the points 21 | #' mtcars %>% 22 | #' ggvis(~disp, ~mpg) %>% 23 | #' layer_points(fill := lb$fill, size.brush := 400) %>% 24 | #' lb$input() 25 | #' 26 | #' # Display one layer with all points and another layer with selected points 27 | #' library(shiny) 28 | #' mtcars %>% 29 | #' ggvis(~disp, ~mpg) %>% 30 | #' layer_points(size.brush := 400) %>% 31 | #' lb$input() %>% 32 | #' layer_points(fill := "red", data = reactive(mtcars[lb$selected(), ])) 33 | linked_brush <- function(keys, fill = "red") { 34 | stopifnot(is.character(fill), length(fill) == 1) 35 | 36 | rv <- shiny::reactiveValues(under_brush = character()) 37 | 38 | input <- function(vis) { 39 | handle_brush(vis, fill = fill, on_move = function(items, ...) { 40 | rv$under_brush <- items$key__ 41 | }) 42 | } 43 | 44 | selected_r <- reactive(keys %in% rv$under_brush) 45 | fill_r <- reactive(c("black", fill)[selected_r() + 1]) 46 | 47 | list( 48 | input = input, 49 | selected = create_broker(selected_r), 50 | fill = create_broker(fill_r) 51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /R/message.R: -------------------------------------------------------------------------------- 1 | #' Send a message to ggvis running on client 2 | #' 3 | #' This will be sent to the client and passed to a handler in ggvis.messages on 4 | #' the client side. The handler is specified by \code{type}. 5 | #' 6 | #' @param session A session object. 7 | #' @param type A string representing the type of the message. 8 | #' @param data An object (typically a list) containing information for the client. 9 | #' @param id A unique identifier for ggvis message handler (optional). 10 | #' @export 11 | ggvis_message <- function(session, type, data = NULL, id = NULL) { 12 | if (is.null(session)) { 13 | stop("Need an active Shiny session to send ggvis message") 14 | } 15 | session$sendCustomMessage("ggvis_message", 16 | list(type = type, id = id, data = data)) 17 | } 18 | -------------------------------------------------------------------------------- /R/pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe graphics 2 | #' 3 | #' Like dplyr, ggvis also uses the pipe function, \code{\%>\%} to turn 4 | #' function composition into a series of imperative statements. 5 | #' 6 | #' @importFrom magrittr %>% 7 | #' @name %>% 8 | #' @rdname pipe 9 | #' @export 10 | #' @param lhs,rhs A visualisation and a function to apply to it 11 | #' @examples 12 | #' # Instead of 13 | #' layer_points(ggvis(mtcars, ~mpg, ~wt)) 14 | #' # you can write 15 | #' mtcars %>% ggvis(~mpg, ~wt) %>% layer_points() 16 | NULL 17 | -------------------------------------------------------------------------------- /R/prop_band.R: -------------------------------------------------------------------------------- 1 | #' A band 2 | #' 3 | #' Bands are used to set the width or height on categorical scales - a band 4 | #' represent the height or width allocated for one level of a factor. 5 | #' 6 | #' @param offset,mult Additive and multiplicate offsets used to adjust the 7 | #' band size. For example, use \code{mult = 0.9} to make a bar take up 8 | #' 90\% of the space allocated for its category. 9 | #' @export 10 | #' @examples 11 | #' df <- data.frame(label = c("a", "b", "c"), n = c(10, 9, 4)) 12 | #' 13 | #' base <- df %>% ggvis(~label, y2 = 0, y = ~n) 14 | #' base %>% layer_rects(width = band()) 15 | #' base %>% layer_rects(width = band(offset = -1)) 16 | #' base %>% layer_rects(width = band(mult = 0.9)) 17 | #' 18 | #' # A nominal scale with padding is more symmetrical than band with a mult 19 | #' base %>% layer_rects(width = band(mult = 0.75)) 20 | #' base %>% layer_rects(width = band()) %>% 21 | #' scale_nominal("x", padding = 0.25, points = FALSE) 22 | band <- function(offset = NULL, mult = NULL) { 23 | structure( 24 | list(offset = offset, mult = mult), 25 | class = c("band") 26 | ) 27 | } 28 | 29 | #' @export 30 | new_prop.band <- function(x, property, scale, offset, mult, env, event, 31 | label) { 32 | if (!(property %in% c("width", "height"))) { 33 | stop("band() can only be used for width and height properties.") 34 | } 35 | if (identical(scale, FALSE)) stop("band() must be scaled.") 36 | 37 | structure( 38 | list( 39 | property = property, 40 | scale = decide_scale(scale %||% TRUE, property), 41 | offset = offset, 42 | mult = mult, 43 | event = event, 44 | env = NULL 45 | ), 46 | class = c("prop_band", "prop") 47 | ) 48 | } 49 | 50 | #' @export 51 | as.character.prop_band <- function(x, ...) "" 52 | 53 | #' @rdname band 54 | #' @param x object to test for band-ness 55 | is.prop_band <- function(x) inherits(x, "prop_band") 56 | 57 | #' @export 58 | prop_value.prop_band <- function(x, data) { 59 | NULL 60 | } 61 | 62 | #' @export 63 | prop_label.prop_band <- function(x) { 64 | "" 65 | } 66 | 67 | #' @export 68 | prop_domain.prop_band <- function(x, data) { 69 | NULL 70 | } 71 | 72 | #' @export 73 | prop_vega.prop_band <- function(x, default_scale) { 74 | compact(list( 75 | scale = x$scale, 76 | mult = x$mult, 77 | offset = x$offset, 78 | band = TRUE 79 | )) 80 | } 81 | -------------------------------------------------------------------------------- /R/scale.R: -------------------------------------------------------------------------------- 1 | range_prop <- function(x, name) { 2 | if (is.null(x)) return(list()) 3 | 4 | # Character vector always left as is 5 | if (is.character(x)) { 6 | return(named_list(name, x)) 7 | } 8 | 9 | assert_that(is.numeric(x), length(x) <= 2) 10 | n_miss <- sum(is.na(x)) 11 | 12 | if (n_miss == 0) { 13 | named_list(name, x) 14 | } else if (n_miss == 1) { 15 | if (is.na(x[1])) { 16 | named_list(paste0(name, "Max"), x[2]) 17 | } else { 18 | named_list(paste0(name, "Min"), x[1]) 19 | } 20 | } else if (n_miss == 2) { 21 | list() 22 | } 23 | 24 | } 25 | 26 | named_list <- function(names, ...) { 27 | stats::setNames(list(...), names) 28 | } 29 | 30 | #' Convert the name of a property to the name of its default scale. 31 | #' 32 | #' This is mainly used to ensure that similar properties share the same 33 | #' scale by default - e.g. \code{x} and \code{x2} should use the same 34 | #' scale. 35 | #' 36 | #' @param prop character vector of property names. Any unrecognised names 37 | #' are left unchanged. 38 | #' @return character vector of default scale names. 39 | #' @keywords internal 40 | #' @export 41 | #' @examples 42 | #' propname_to_scale(c("x", "x2")) 43 | #' propname_to_scale(c("foo", "bar")) 44 | #' propname_to_scale(c("opacity", "fillOpacity", "strokeOpacity")) 45 | propname_to_scale <- function(prop) { 46 | simplify <- c( 47 | "x2" = "x", 48 | "width" = "x", 49 | "y2" = "y", 50 | "height" = "y", 51 | "fillOpacity" = "opacity", 52 | "strokeOpacity" = "opacity", 53 | "innerRadius" = "radius", 54 | "outerRadius" = "radius", 55 | "startAngle" = "angle", 56 | "endAngle" = "angle" 57 | ) 58 | 59 | matches <- match(prop, names(simplify)) 60 | prop[!is.na(matches)] <- simplify[prop[!is.na(matches)]] 61 | prop 62 | } 63 | 64 | #' Given the type of a ggvis scale, get the name of its corresponding vega scale 65 | #' 66 | #' @param type property type: numeric, ordinal, nominal, logical or datetime. 67 | #' @keywords internal 68 | scaletype_to_vega_scaletype <- function(type) { 69 | unname(c( 70 | "numeric" = "quantitative", 71 | "ordinal" = "ordinal", 72 | "nominal" = "ordinal", 73 | "logical" = "ordinal", 74 | "datetime" = "time" 75 | )[type]) 76 | } 77 | -------------------------------------------------------------------------------- /R/singular.R: -------------------------------------------------------------------------------- 1 | #' singular. 2 | #' 3 | #' Use singular when you want constant x or y position. 4 | #' 5 | #' @export 6 | #' @examples 7 | #' mtcars %>% ggvis("", ~mpg) %>% 8 | #' layer_points() %>% 9 | #' scale_nominal("x") %>% 10 | #' add_axis("x", title = "", tick_size_major = 0) 11 | #' 12 | #' # OR 13 | #' mtcars %>% ggvis("", ~mpg) %>% 14 | #' layer_points() %>% 15 | #' scale_singular("x") 16 | #' 17 | #' # OR, even simpler 18 | #' mtcars %>% ggvis(singular(), ~mpg) %>% layer_points() 19 | #' 20 | #' # In the other direction: 21 | #' mtcars %>% ggvis(~mpg, singular()) %>% layer_points() 22 | #' @export 23 | singular <- function() { 24 | structure("", class = "singular") 25 | } 26 | 27 | #' @export 28 | rep.singular <- function(x, ...) { 29 | structure(NextMethod(), class = "singular") 30 | } 31 | #' @export 32 | print.singular <- function(x, ...) cat("\n") 33 | 34 | #' @export 35 | as.data.frame.singular <- function(x, ...) { 36 | df <- list(x) 37 | attr(df, "row.names") <- .set_row_names(length(x)) 38 | class(df) <- "data.frame" 39 | 40 | df 41 | } 42 | 43 | #' @export 44 | vector_type.singular <- function(x) "singular" 45 | 46 | #' @rdname singular 47 | #' @export 48 | #' @inheritParams scale_nominal 49 | scale_singular <- function(vis, property, name = property, label = name, 50 | points = TRUE, domain = NULL, override = NULL) { 51 | # Some of the arguments are ignored; they're there to provide a consistent 52 | # interface with other scales 53 | vis <- scale_nominal(vis, domain = "", property = property, name = name, 54 | label = "", points = points, override = override) 55 | vis <- add_axis(vis, property, tick_size_major = 0) 56 | vis 57 | } 58 | -------------------------------------------------------------------------------- /R/subvis.R: -------------------------------------------------------------------------------- 1 | #' Create a subvisualisation. 2 | #' 3 | #' @keywords internal 4 | #' @examples 5 | #' # Examples don't work yet 6 | #' \dontrun{ 7 | #' library(dplyr, warn.conflicts = FALSE) 8 | #' 9 | #' small <- nasaweather::atmos %>% 10 | #' filter(lat <= -11.217391, long <= -106.287, year == 1995) %>% 11 | #' group_by(long, lat) 12 | #' small %>% 13 | #' ggvis(~long, ~lat) %>% 14 | #' layer_points() 15 | #' 16 | #' small %>% 17 | #' ggvis(~long, ~lat) %>% 18 | #' subvis(width := 100, height := 100, stroke := "red") %>% 19 | #' layer_points(~month, ~ozone) 20 | #' 21 | #' small %>% 22 | #' ggvis(~long, ~lat) %>% 23 | #' subvis(width := 100, height := 100, stroke := "red") %>% 24 | #' layer_points(~month, ~ozone) %>% 25 | #' add_axis("x", ticks = 3) %>% 26 | #' add_axis("y", ticks = 3) 27 | #' } 28 | subvis <- function(vis, ..., data = NULL, width = NULL, height = NULL) { 29 | # Very similar to add_mark, but changes to cur_data and cur_props are 30 | # persistent, we use the special mark_group() and update cur_vis 31 | vis <- add_data(vis, data, deparse2(substitute(data))) 32 | vis <- add_props(vis, .props = props(...)) 33 | vis <- register_scales_from_props(vis, cur_props(vis)) 34 | 35 | new_mark <- mark_group(vis$cur_props, vis$cur_data) 36 | vis$marks <- append(vis$marks, list(new_mark)) 37 | 38 | # Parent properties control apperance mark_group, and are not 39 | # inherited by child 40 | vis$cur_props <- NULL 41 | vis$cur_vis <- c(vis$cur_vis, length(vis$marks)) 42 | vis 43 | 44 | vis 45 | } 46 | -------------------------------------------------------------------------------- /R/utils_names.R: -------------------------------------------------------------------------------- 1 | camelCase <- function(x) { 2 | words <- strsplit(x, "_") 3 | 4 | caps <- lapply(words, function(x) { 5 | if (length(x) == 1) return(x) 6 | x[-1] <- capitalise(x[-1]) 7 | x 8 | }) 9 | 10 | vapply(caps, paste0, collapse = "", FUN.VALUE = character(1)) 11 | } 12 | 13 | under_score <- function(x) { 14 | substr(x, 1, 1) <- tolower(substr(x, 1, 1)) 15 | tolower(gsub("([A-Z])", "_\\1", x)) 16 | } 17 | 18 | capitalise <- function(x, first = TRUE) { 19 | substr(x, 1, 1) <- toupper(substr(x, 1, 1)) 20 | x 21 | } -------------------------------------------------------------------------------- /R/utils_props.R: -------------------------------------------------------------------------------- 1 | # Given a character vector like c("x", "x.update", "x.enter"), report which ones 2 | # have .update, .enter, etc. 3 | has_prop_event <- function(x) { 4 | sub("^.*\\.", "", x) %in% c("enter", "exit", "update", "hover", "brush") 5 | } 6 | 7 | # Remove the trailing event from a prop name 8 | trim_prop_event <- function(x) { 9 | sub("\\.(enter|exit|update|hover|brush)$", "", x) 10 | } 11 | 12 | # Given a list with objects x.enter, x.update, y.update, return a list p of 13 | # ggvis_props objects, with structure p$enter$x, p$update$x, p$update$y. 14 | prop_event_sets <- function(props) { 15 | sets <- c("enter", "exit", "update", "hover", "brush") 16 | names(sets) <- sets 17 | 18 | x <- lapply(sets, function(set) { 19 | searchstr <- paste0("\\.", set, "$") 20 | matches <- props[grep(searchstr, names(props))] 21 | names(matches) <- trim_prop_event(names(matches)) 22 | matches 23 | }) 24 | 25 | compact(x) 26 | } 27 | 28 | # Given a props object, trim the .update, .enter, etc, and drop all those which 29 | # are named in `drop`. 30 | # drop_props( 31 | # props(x = ~wt, x.enter = 0, stroke.enter := "black", stroke.hover := "red"), 32 | # c("stroke", "strokeOpacity") 33 | # ) 34 | drop_props <- function(props, drop) { 35 | pnames <- trim_prop_event(names(props)) 36 | props[!(pnames %in% drop)] 37 | } 38 | 39 | stroke_fill_defaults <- function(props, stroke = list(), fill = list()) { 40 | stroke_props <- merge_props(stroke, props) 41 | stroke_props <- drop_props(stroke_props, c("fill", "fillOpacity")) 42 | stroke_props <- merge_props(stroke_props, props(fill := "transparent")) 43 | 44 | fill_props <- merge_props(fill, props) 45 | fill_props <- drop_props(fill_props, c("stroke", "strokeOpacity")) 46 | fill_props <- merge_props(fill_props, props(stroke := "transparent")) 47 | 48 | list(stroke = stroke_props, fill = fill_props) 49 | } 50 | 51 | # @param props A props object. 52 | # @param properties A character vector of properties to check. 53 | # @param events A character vector of events that are not supported 54 | # @param label A string naming the type of layer (like layer_bars), for error 55 | # messages. 56 | check_unsupported_props <- function(props, properties, events, label = "") { 57 | unsupported <- vapply(props, function(p) { 58 | (p$property %in% properties) && (p$event %in% events) 59 | }, logical(1)) 60 | 61 | if (any(unsupported)) { 62 | if (label == "") label <- "layer" 63 | stop(label, " presently cannot use properties ", 64 | paste(properties, collapse = ", "), " for ", 65 | paste(events, collapse = ", "), " events.") 66 | } 67 | invisible(NULL) 68 | } 69 | -------------------------------------------------------------------------------- /R/utils_reactive.R: -------------------------------------------------------------------------------- 1 | reactive_id <- function(x) { 2 | attr(x, "reactive_id", TRUE) 3 | } 4 | 5 | `reactive_id<-` <- function(x, value) { 6 | attr(x, "reactive_id") <- value 7 | x 8 | } 9 | 10 | 11 | # Pull reactives out of various types of objects 12 | extract_reactives <- function(x) UseMethod("extract_reactives") 13 | #' @export 14 | extract_reactives.ggvis_props <- function(x) { 15 | compact(lapply(x, extract_reactives)) 16 | } 17 | #' @export 18 | extract_reactives.prop_reactive <- function(x) x$value 19 | #' @export 20 | extract_reactives.default <- function(x) NULL 21 | 22 | # Get the value of a reactive or non-reactive object. 23 | value <- function(x) UseMethod("value") 24 | #' @export 25 | value.default <- function(x) x 26 | #' @export 27 | value.reactive <- function(x) x() 28 | 29 | values <- function(x) lapply(x, value) 30 | -------------------------------------------------------------------------------- /R/vector_type.R: -------------------------------------------------------------------------------- 1 | #' Determine the "type" of a vector 2 | #' 3 | #' The \code{vector_type} collapses down the class of base vectors into 4 | #' something useful more for visualisation, yielding one of "datetime", 5 | #' "numeric", "ordinal", "nominal" or "logical". 6 | #' 7 | #' @param x a vector 8 | #' @export 9 | #' @seealso \code{default_scale}, which uses this when picking the default 10 | #' scale. 11 | vector_type <- function(x) UseMethod("vector_type") 12 | 13 | #' @export 14 | vector_type.POSIXt <- function(x) "datetime" 15 | #' @export 16 | vector_type.Date <- function(x) "datetime" 17 | #' @export 18 | vector_type.numeric <- function(x) "numeric" 19 | #' @export 20 | vector_type.integer <- function(x) "numeric" 21 | #' @export 22 | vector_type.character <- function(x) "nominal" 23 | #' @export 24 | vector_type.logical <- function(x) "logical" 25 | #' @export 26 | vector_type.factor <- function(x) "nominal" 27 | #' @export 28 | vector_type.ordered <- function(x) "ordinal" 29 | #' @export 30 | vector_type.NULL <- function(x) "NULL" 31 | #' @export 32 | vector_type.default <- function(x) { 33 | stop("Unknown variable type: ", paste0(class(x), collapse = "/")) 34 | } 35 | 36 | # Reports whether a vector maps to a countable prop type 37 | vector_countable <- function(x) { 38 | countable_prop_type(vector_type(x)) 39 | } 40 | 41 | #' Determine the vega data type for a vector 42 | #' 43 | #' This is used to specify the data type so that the appropriate parser is used 44 | #' when Vega receives the data. 45 | #' @param x A vector. 46 | vega_data_parser <- function(x) UseMethod("vega_data_parser") 47 | 48 | #' @export 49 | vega_data_parser.POSIXt <- function(x) "number" 50 | #' @export 51 | vega_data_parser.Date <- function(x) "number" 52 | #' @export 53 | vega_data_parser.numeric <- function(x) "number" 54 | #' @export 55 | vega_data_parser.integer <- function(x) "number" 56 | #' @export 57 | vega_data_parser.character <- function(x) NULL 58 | #' @export 59 | vega_data_parser.logical <- function(x) "boolean" 60 | #' @export 61 | vega_data_parser.factor <- function(x) NULL 62 | #' @export 63 | vega_data_parser.ordered <- function(x) NULL 64 | #' @export 65 | vega_data_parser.NULL <- function(x) NULL 66 | #' @export 67 | vega_data_parser.default <- function(x) { 68 | stop("Unknown variable type: ", paste0(class(x), collapse = "/")) 69 | } 70 | -------------------------------------------------------------------------------- /R/waggle.R: -------------------------------------------------------------------------------- 1 | #' Waggle back and forth between two numbers 2 | #' 3 | #' @param min A minimum value. 4 | #' @param max A maximum value. 5 | #' @param value Starting value. Defaults to half-way between \code{min} and 6 | #' \code{max}. 7 | #' @param step How much value changes at each frame. Defaults to 50 steps 8 | #' between min and max so it takes 5 seconds to waggle once. 9 | #' @param fps number of frames per second. 10 | #' @export 11 | #' @examples 12 | #' span <- waggle(0.2, 1) 13 | #' mtcars %>% ggvis(~mpg, ~wt) %>% 14 | #' layer_points() %>% 15 | #' layer_smooths(span = span) 16 | waggle <- function(min, max, value = (min + max) / 2, step = (max - min) / 50, 17 | fps = 10) { 18 | 19 | vals <- shiny::reactiveValues() 20 | vals$x <- value 21 | 22 | connect <- function(session, plot_id) { 23 | direction <- 1 24 | shiny::observe({ 25 | shiny::invalidateLater(1000 / fps, NULL) 26 | 27 | next_value <- shiny::isolate(vals$x) + direction * step 28 | if (next_value < min || next_value > max) { 29 | direction <<- -1 * direction 30 | next_value <- pmax(pmin(next_value, max), min) 31 | } 32 | 33 | vals$x <<- next_value 34 | }) 35 | } 36 | 37 | create_broker(reactive(vals$x), connect = connect) 38 | } 39 | -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | .onAttach <- function(...) { 2 | if (!interactive() || stats::runif(1) > 0.1) return() 3 | packageStartupMessage("The ggvis API is currently rapidly evolving. ", 4 | "We strongly recommend that you do not rely on this for production, but ", 5 | "feel free to explore. If you encounter a clear bug, please file a ", 6 | "minimal reproducible example at https://github.com/rstudio/ggvis/issues. ", 7 | "For questions and other discussion, please use ", 8 | "https://groups.google.com/group/ggvis.") 9 | } 10 | 11 | .onLoad <- function(libname, pkgname) { 12 | register_s3_method("dplyr", "filter", "ggvis") 13 | register_s3_method("dplyr", "filter", "reactive") 14 | 15 | # ggvis provides methods for knitr::knit_print, but knitr isn't a Depends or 16 | # Imports of ggvis, only a Suggests. This code snippet manually registers 17 | # our method(s) with S3 once both ggvis and knitr are loaded. 18 | register_s3_method("knitr", "knit_print", "ggvis") 19 | } 20 | 21 | register_s3_method <- function(pkg, generic, class, fun = NULL) { 22 | stopifnot(is.character(pkg), length(pkg) == 1) 23 | stopifnot(is.character(generic), length(generic) == 1) 24 | stopifnot(is.character(class), length(class) == 1) 25 | 26 | if (is.null(fun)) { 27 | fun <- get(paste0(generic, ".", class), envir = parent.frame()) 28 | } else { 29 | stopifnot(is.function(fun)) 30 | } 31 | 32 | if (pkg %in% loadedNamespaces()) { 33 | registerS3method(generic, class, fun, envir = asNamespace(pkg)) 34 | } 35 | 36 | # Always register hook in case package is later unloaded & reloaded 37 | setHook( 38 | packageEvent(pkg, "onLoad"), 39 | function(...) { 40 | registerS3method(generic, class, fun, envir = asNamespace(pkg)) 41 | } 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ggvis 2 | 3 | ## Status 4 | ![](https://img.shields.io/badge/lifecycle-dormant-blue.svg) 5 | 6 | ggvis is currently dormant. We fundamentally believe in the ideas that underlie ggvis: reactive programming is the right foundation for interactive visualisation. However, we are not currently working on ggvis because we do not see it as the most pressing issue for the R community as you can only use interactive graphics once you've successfuly tackled the rest of the data analysis process. 7 | 8 | We hope to come back to ggvis in the future; in the meantime you might want to try out [plotly](https://plotly.com/ggplot2/getting-started/) or creating inteactive graphics [with shiny](https://posit.co/blog/shiny-0-12-interactive-plots-with-ggplot2/). 9 | 10 | ## Introduction 11 | 12 | The goal of ggvis is to make it easy to describe interactive web graphics in 13 | R. It combines: 14 | 15 | * a grammar of graphics from [ggplot2](https://github.com/tidyverse/ggplot2), 16 | 17 | * reactive programming from [shiny](https://github.com/rstudio/shiny), and 18 | 19 | * data transformation pipelines from [dplyr](https://github.com/tidyverse/dplyr). 20 | 21 | ggvis graphics are rendered with [vega](https://github.com/trifacta/vega), so you can generate both raster graphics with HTML5 canvas and vector graphics with 22 | [svg](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics). ggvis is less flexible than raw [d3](https://d3js.org/) or vega, but is much more succinct and is tailored to the needs of exploratory data analysis. 23 | 24 | If you find a bug, please file a minimal reproducible example at https://github.com/rstudio/ggvis/issues. If you're not sure if something is a bug, you'd like to discuss new features or have any other questions about ggvis, please join us on the mailing list: https://groups.google.com/group/ggvis. 25 | 26 | ## Installation 27 | 28 | Install the latest release version from CRAN with: 29 | 30 | ```R 31 | install.packages("ggvis") 32 | ``` 33 | 34 | Install the latest development version with: 35 | 36 | ```R 37 | # install.packages("devtools") 38 | devtools::install_github("rstudio/ggvis") 39 | ``` 40 | 41 | ## Getting started 42 | 43 | You construct a visualisation by piping pieces together with `%>%`. The pipeline starts with a data set, flows into `ggvis()` to specify default visual properties, then layers on some visual elements: 44 | 45 | ```R 46 | mtcars %>% ggvis(~mpg, ~wt) %>% layer_points() 47 | ``` 48 | 49 | The vignettes, available from https://ggvis.rstudio.com/, provide many more details. Start with the introduction, then work your way through the more advanced topics. Also check out the 50 | various demos in the `demo/` directory. See the basics in `demo/scatterplot.r` 51 | then check out the the coolest demos, `demo/interactive.r` and `demo/tourr.r`. 52 | -------------------------------------------------------------------------------- /bench/all_same.R: -------------------------------------------------------------------------------- 1 | # What's the fastest way to determine if a vector is all the same value? 2 | 3 | # Note: doesn't handle NA and zero-length vectors 4 | all_same1 <- function(x) all(x == x[1]) 5 | 6 | # One less comparison, but has to duplicate whole vector 7 | # Note: doesn't handle NA and zero-length vectors 8 | all_same2 <- function(x) all(x[-1] == x[1]) 9 | 10 | # Use unique. Handles NA and zero-length vectors 11 | all_same3 <- function(x) length(unique(x)) == 1 12 | 13 | # Like all_same1, but also handles NA and zero-length vectors 14 | all_same4 <- function(x) { 15 | nas <- is.na(x) 16 | if (length(x) == 0 || all(nas)) 17 | TRUE 18 | else if (any(nas)) 19 | FALSE 20 | else 21 | all(x == x[1]) 22 | } 23 | 24 | 25 | x_hard <- c(rep(1, 1000), 2) 26 | x_easy <- c(2, rep(1, 1000)) 27 | 28 | library(microbenchmark) 29 | options(digits = 3) 30 | 31 | print(microbenchmark( 32 | all_same1(x_hard), 33 | all_same2(x_hard), 34 | all_same3(x_hard), 35 | all_same4(x_hard), 36 | 37 | all_same1(x_easy), 38 | all_same2(x_easy), 39 | all_same3(x_easy), 40 | all_same4(x_easy) 41 | 42 | )) 43 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## R CMD check results 2 | There were no ERRORs, WARNINGs or NOTEs. 3 | 4 | ## Downstream dependencies 5 | 6 | We did not check revdeps since this just documentation fixes. 7 | -------------------------------------------------------------------------------- /data/cocaine.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/data/cocaine.rda -------------------------------------------------------------------------------- /demo/00Index: -------------------------------------------------------------------------------- 1 | bar Bar charsts 2 | boxplot Box plots 3 | histogram Histograms 4 | lines Line plots 5 | scatterplot Basic scatterplots 6 | smooth Plots with overlaid smoothers 7 | tile Tile plots (aka heatmaps) 8 | 9 | guides Controlling axes and legends 10 | scales Controlling scales 11 | 12 | dynamic Dynamic plots using reactive data sources 13 | tourr A dynamic plot displaying a simple grand tour 14 | 15 | interactive Simple interactive examples 16 | hover Adding custom hover behaviour 17 | brush Basic brushing 18 | 19 | size Control the size of the output plot 20 | 21 | subvis Subvisualizations (faceting) 22 | -------------------------------------------------------------------------------- /demo/apps/README.md: -------------------------------------------------------------------------------- 1 | This directory contains example Shiny apps. If you are in the top-level ggvis directory, these can be run with: 2 | 3 | ``` 4 | shiny::runApp('demo/apps/basic') 5 | ``` 6 | 7 | If you've installed `ggvis`, you can run the demo with 8 | 9 | ``` 10 | shiny::runApp(system.file("demo/apps/basic", package = "ggvis")) 11 | ``` 12 | -------------------------------------------------------------------------------- /demo/apps/basic/server.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | function(input, output, session) { 4 | # A reactive subset of mtcars 5 | mtc <- reactive({ mtcars[1:input$n, ] }) 6 | 7 | # A simple visualisation. In shiny apps, need to register observers 8 | # and tell shiny where to put the controls 9 | mtc %>% 10 | ggvis(~wt, ~mpg) %>% 11 | layer_points() %>% 12 | bind_shiny("plot", "plot_ui") 13 | 14 | output$mtc_table <- renderTable({ 15 | mtc()[, c("wt", "mpg")] 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /demo/apps/basic/ui.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | 4 | fluidPage(sidebarLayout( 5 | sidebarPanel( 6 | sliderInput("n", "Number of points", min = 1, max = nrow(mtcars), 7 | value = 10, step = 1), 8 | uiOutput("plot_ui") 9 | ), 10 | mainPanel( 11 | ggvisOutput("plot"), 12 | tableOutput("mtc_table") 13 | ) 14 | )) 15 | -------------------------------------------------------------------------------- /demo/apps/brush-linked/server.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | set.seed(1233) 4 | cocaine <- cocaine[sample(1:nrow(cocaine), 500), ] 5 | cocaine$id <- seq_len(nrow(cocaine)) 6 | 7 | shinyServer(function(input, output, session) { 8 | 9 | lb <- linked_brush(keys = cocaine$id, "red") 10 | 11 | cocaine %>% 12 | ggvis(~weight, ~price, key := ~id) %>% 13 | layer_points(fill := lb$fill, fill.brush := "red", opacity := 0.3) %>% 14 | lb$input() %>% 15 | set_options(width = 300, height = 300) %>% 16 | bind_shiny("plot1") # Very important! 17 | 18 | 19 | # A subset of cocaine, of only the selected points 20 | selected <- lb$selected 21 | cocaine_selected <- reactive({ 22 | cocaine[selected(), ] 23 | }) 24 | 25 | cocaine %>% 26 | ggvis(~potency) %>% 27 | layer_histograms(width = 5, boundary = 0) %>% 28 | add_data(cocaine_selected) %>% 29 | layer_histograms(width = 5, boundary = 0, fill := "#dd3333") %>% 30 | set_options(width = 300, height = 300) %>% 31 | bind_shiny("plot2") 32 | }) 33 | -------------------------------------------------------------------------------- /demo/apps/brush-linked/ui.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | shinyUI(bootstrapPage( 4 | ggvisOutput("plot1"), 5 | ggvisOutput("plot2") 6 | )) 7 | -------------------------------------------------------------------------------- /demo/apps/brush-summary/server.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | shinyServer(function(input, output, session) { 4 | mtcars <- cbind(mtcars, id = seq_len(nrow(mtcars))) 5 | 6 | # Create a linked brush object 7 | lb <- linked_brush(keys = mtcars$id, "red") 8 | 9 | # Just the brushed points 10 | selected <- lb$selected 11 | mtcars_selected <- reactive({ 12 | if (!any(selected())) return(mtcars) 13 | mtcars[selected(), ] 14 | }) 15 | 16 | mtcars %>% 17 | ggvis(~wt, ~mpg) %>% 18 | layer_points(fill := lb$fill, fill.brush := "red") %>% 19 | lb$input() %>% 20 | add_data(mtcars_selected) %>% 21 | layer_model_predictions(model = "lm")%>% 22 | bind_shiny("plot1") 23 | 24 | output$brush_data <- renderPrint({ 25 | cat("Number of points selected: ", nrow(mtcars_selected()), "\n\n") 26 | print(summary(mtcars_selected())) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /demo/apps/brush-summary/ui.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | shinyUI(bootstrapPage( 4 | ggvisOutput("plot1"), 5 | h3("Summary of brushed data (sent from client to server)"), 6 | verbatimTextOutput("brush_data") 7 | )) 8 | -------------------------------------------------------------------------------- /demo/apps/linked-hover/server.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | data(diamonds, package = "ggplot2") 3 | 4 | shinyServer(function(input, output, session) { 5 | 6 | values <- reactiveValues(selected = rep(TRUE, nrow(diamonds))) 7 | 8 | diamonds %>% ggvis(~carat) %>% 9 | layer_histograms(fill.hover := "red", width = 0.1) %>% 10 | handle_hover(function(data, ...) { 11 | values$selected <- diamonds$carat >= data$xmin_ & 12 | diamonds$carat < data$xmax_ 13 | }) %>% 14 | set_options(width = 400, height = 200) %>% 15 | bind_shiny("plot1") 16 | 17 | # Sub-histogram 18 | reactive(diamonds[values$selected, , drop = FALSE]) %>% 19 | ggvis(~carat) %>% 20 | layer_histograms(width = 0.01) %>% 21 | set_options(width = 400, height = 200) %>% 22 | bind_shiny("plot2") 23 | 24 | }) 25 | -------------------------------------------------------------------------------- /demo/apps/linked-hover/ui.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | shinyUI(bootstrapPage( 4 | ggvisOutput("plot1"), 5 | ggvisOutput("plot2") 6 | )) 7 | -------------------------------------------------------------------------------- /demo/apps/zoom/server.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | shinyServer(function(input, output, session) { 4 | reactive({ 5 | mtcars %>% ggvis(~disp, ~mpg) %>% 6 | layer_points() %>% 7 | scale_numeric("x", domain = input$x_domain, nice = FALSE, clamp = TRUE) %>% 8 | scale_numeric("y", domain = input$y_domain, nice = FALSE, clamp = TRUE) 9 | }) %>% 10 | bind_shiny("zoom") 11 | }) 12 | -------------------------------------------------------------------------------- /demo/apps/zoom/ui.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | var_range <- function(id, label, variable) { 4 | rng <- range(variable, na.rm = TRUE) 5 | sliderInput(id, label, rng[1], rng[2], rng) 6 | } 7 | 8 | shinyUI(pageWithSidebar( 9 | headerPanel("Zooming demo"), 10 | sidebarPanel( 11 | var_range("x_domain", "X", mtcars$disp), 12 | var_range("y_domain", "Y", mtcars$mpg) 13 | ), 14 | mainPanel( 15 | ggvisOutput("zoom") 16 | ) 17 | )) 18 | -------------------------------------------------------------------------------- /demo/bar.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Bar graph with continuous x, and y value supplied in the data 4 | pressure %>% ggvis(x = ~temperature, y = ~pressure) %>% 5 | layer_bars() 6 | 7 | # Categorical x, and y var supplied 8 | pressure %>% ggvis(~factor(temperature), ~pressure) %>% layer_bars() 9 | 10 | # No y var, and continuous x: bar graph of counts 11 | mtcars %>% ggvis(x = ~cyl) %>% layer_bars() 12 | 13 | # Notice how it differs from a histogram: a histogram has bins that span 14 | # ranges of x, but layer_bars shows the count at each unique x value. 15 | mtcars %>% ggvis(~wt) %>% layer_histograms() 16 | mtcars %>% ggvis(~wt) %>% layer_bars() 17 | 18 | # No y var, and categorical x: bar graph of counts at each x value 19 | mtcars %>% ggvis(~factor(cyl)) %>% layer_bars() 20 | 21 | 22 | # Hair and eye color data 23 | hec <- as.data.frame(xtabs(Freq ~ Hair + Eye, HairEyeColor)) 24 | 25 | # Without stacking - bars overlap 26 | hec %>% group_by(Eye) %>% 27 | ggvis(x = ~Hair, y = ~Freq, fill = ~Eye, fillOpacity := 0.5) %>% 28 | layer_bars(stack = FALSE) %>% 29 | scale_nominal("fill", 30 | domain = c("Brown", "Blue", "Hazel", "Green"), 31 | range = c("#995522", "#88CCFF", "#999933", "#00CC00")) 32 | 33 | # With stacking 34 | hec %>% group_by(Eye) %>% 35 | ggvis(x = ~Hair, y = ~Freq, fill = ~Eye, fillOpacity := 0.5) %>% 36 | layer_bars() %>% 37 | scale_nominal("fill", 38 | domain = c("Brown", "Blue", "Hazel", "Green"), 39 | range = c("#995522", "#88CCFF", "#999933", "#00CC00")) 40 | 41 | 42 | # Stacking in x direction instead of default y - need to be explicit about 43 | # all the steps 44 | hec %>% group_by(Eye) %>% 45 | ggvis(y = ~Hair, fill = ~Eye, fillOpacity := 0.5) %>% 46 | compute_stack(stack_var = ~Freq, group_var = ~Hair) %>% 47 | layer_rects(x = ~stack_lwr_, x2 = ~stack_upr_, height = band()) %>% 48 | scale_nominal("y", range = "height", padding = 0, points = FALSE) %>% 49 | scale_nominal("fill", 50 | domain = c("Brown", "Blue", "Hazel", "Green"), 51 | range = c("#995522", "#88CCFF", "#999933", "#00CC00")) 52 | -------------------------------------------------------------------------------- /demo/boxplot.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Make data set with categorical x 4 | mtc <- mtcars 5 | mtc$cyl <- factor(mtc$cyl) 6 | mtc %>% ggvis(~cyl, ~mpg) %>% layer_boxplots() 7 | # Set the width of the boxes to half the space between tick marks 8 | mtc %>% ggvis(~cyl, ~mpg) %>% layer_boxplots(width = 0.5) 9 | 10 | # Continuous x: boxes fill width between data values 11 | mtcars %>% ggvis(~cyl, ~mpg) %>% layer_boxplots() 12 | # Setting width=0.5 makes it 0.5 wide in the data space, which is 1/4 of the 13 | # distance between data values in this particular case. 14 | mtcars %>% ggvis(~cyl, ~mpg) %>% layer_boxplots(width = 0.5) 15 | 16 | -------------------------------------------------------------------------------- /demo/brush.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | #simple summary brush tooltip 3 | x_bar <- "x̄" 4 | sigma_hat <- "σ̂" 5 | 6 | brushed_summary <- function(items, session, page_loc, ...) { 7 | if (nrow(items) == 0) return() 8 | 9 | items$key__ <- NULL 10 | lines <- Map(function(name, vals) { 11 | paste0(name, ": ", 12 | x_bar, " = ", round(mean(vals), 2), " ", 13 | sigma_hat, " = ", round(sd(vals), 2) 14 | ) 15 | }, names(items), items) 16 | html <- paste(unlist(lines), collapse = "
\n") 17 | 18 | show_tooltip(session, page_loc$r + 5, page_loc$t, html) 19 | } 20 | 21 | # Scatter plot with brushing 22 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 23 | layer_points(size.brush := 400) %>% 24 | handle_brush(brushed_summary) 25 | 26 | # Bar graph with brushing 27 | pressure %>% ggvis(x = ~temperature, y = ~pressure) %>% 28 | scale_nominal("x", range = "width", padding = 0, points = FALSE) %>% 29 | layer_rects(y2 = 0, width = band(), fill.brush := "red") %>% 30 | handle_brush(brushed_summary) 31 | 32 | # Brushing with 10000 points 33 | data("diamonds", package="ggplot2") 34 | d <- diamonds[sample(nrow(diamonds), 10000), ] 35 | d %>% ggvis(x = ~carat, y = ~price) %>% 36 | layer_points(size := 40, fillOpacity := 0.02, fillOpacity.brush := 0.4) %>% 37 | handle_brush(brushed_summary) 38 | -------------------------------------------------------------------------------- /demo/guides.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>% 4 | layer_points() 5 | 6 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>% 7 | layer_points() %>% 8 | add_axis("x", title = "Weight") 9 | 10 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>% 11 | layer_points() %>% 12 | add_axis("x", title = "Weight", orient = "top") 13 | 14 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>% 15 | layer_points() %>% 16 | add_legend("fill", title = "Cylinders") 17 | 18 | # Combining two properties in one legend 19 | mtcars %>% 20 | ggvis(x = ~wt, y = ~mpg, fill = ~factor(cyl), shape = ~factor(cyl)) %>% 21 | layer_points() %>% 22 | add_legend(c("fill", "shape")) 23 | -------------------------------------------------------------------------------- /demo/histogram.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Histogram, fully specified 4 | mtcars %>% ggvis(x = ~wt) %>% 5 | compute_bin(~wt, width = 1, pad = FALSE) %>% 6 | layer_rects(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) 7 | 8 | # Or using shorthand layer 9 | mtcars %>% ggvis(x = ~wt) %>% layer_histograms() 10 | mtcars %>% ggvis(x = ~wt) %>% layer_histograms(width = 1) 11 | 12 | # Histogram, filled by cyl 13 | mtcars %>% ggvis(x = ~wt, fill = ~factor(cyl)) %>% 14 | group_by(cyl) %>% 15 | layer_histograms(width = 1) 16 | 17 | # Bigger dataset 18 | data(diamonds, package = "ggplot2") 19 | diamonds %>% ggvis(x = ~table) %>% layer_histograms() 20 | 21 | # Stacked histogram 22 | diamonds %>% ggvis(x = ~table, fill = ~cut) %>% 23 | group_by(cut) %>% 24 | layer_histograms(width = 1) 25 | 26 | # Histogram of dates 27 | set.seed(2934) 28 | dat <- data.frame(times = as.POSIXct("2013-07-01", tz = "GMT") + rnorm(200) * 60 * 60 * 24 * 7) 29 | dat %>% ggvis(x = ~times) %>% layer_histograms() 30 | -------------------------------------------------------------------------------- /demo/hover.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Scatter plot with hovering 4 | mtcars %>% ggvis(x = ~wt, y = ~mpg, size.hover := 200) %>% 5 | layer_points() 6 | 7 | # Larger point and outline when hovering 8 | mtcars %>% 9 | ggvis(x = ~wt, y = ~mpg, size.hover := 200, 10 | stroke := NA, stroke.hover := "red", strokeWidth := 3) %>% 11 | layer_points() 12 | 13 | # Line changes color and points change size when hovered over, with 250 ms 14 | # transition time 15 | pressure %>% ggvis(x = ~temperature, y = ~pressure) %>% 16 | layer_paths(stroke.hover := "red", strokeWidth.hover := 4, strokeWidth := 2) %>% 17 | layer_points(size := 50, size.hover := 200) %>% 18 | set_options(hover_duration = 250) 19 | 20 | # Hover with layer_smooths 21 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 22 | layer_points() %>% 23 | layer_smooths(fill.hover := "red", se = TRUE) 24 | 25 | # Opacity with layer_densities 26 | PlantGrowth %>% group_by(group) %>% 27 | ggvis(x = ~weight, stroke = ~group, fill = ~group, 28 | fillOpacity := 0.2, fillOpacity.hover := .5) %>% 29 | layer_densities() 30 | -------------------------------------------------------------------------------- /demo/lines.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | library(dplyr) # For arrange function 3 | 4 | set.seed(1780) 5 | df <- data.frame(x = runif(12), y = runif(12), z = gl(3, 4)) 6 | 7 | df %>% ggvis(x = ~x, y = ~y) %>% layer_paths() 8 | 9 | # Grouping, manually specified 10 | df %>% group_by(z) %>% 11 | ggvis(x = ~x, y = ~y, stroke = ~z, fill := NA) %>% 12 | layer_paths() %>% 13 | layer_points() 14 | 15 | # Grouping can happen after ggvis() call 16 | df %>% 17 | ggvis(x = ~x, y = ~y, stroke = ~z, fill := NA) %>% 18 | group_by(z) %>% 19 | layer_paths() %>% 20 | layer_points() 21 | 22 | # Data sorted by x 23 | df %>% ggvis(x = ~x, y = ~y) %>% 24 | arrange(x) %>% 25 | layer_paths() %>% 26 | layer_points() 27 | 28 | # layer_lines sorts and adds a mark_path 29 | df %>% ggvis(x = ~x, y = ~y) %>% 30 | layer_lines() %>% 31 | layer_points() 32 | 33 | # Data sorted by y 34 | df %>% ggvis(x = ~x, y = ~y) %>% 35 | arrange(y) %>% 36 | layer_paths() %>% 37 | layer_points() 38 | 39 | # Grouping with auto_group, and sorted 40 | df %>% ggvis(x = ~x, y = ~y, stroke = ~z, fill := NA) %>% 41 | auto_group() %>% 42 | arrange(x) %>% 43 | layer_paths() %>% 44 | layer_points() 45 | 46 | # Using layer_lines, which sorts the data 47 | df %>% ggvis(x = ~x, y = ~y, stroke = ~z, fill := NA) %>% 48 | layer_lines() %>% 49 | layer_points() 50 | 51 | 52 | # Dashed lines 53 | dat <- data.frame(x = rep(c(0, 1), 6), g = gl(6, 2)) 54 | dat %>% group_by(g) %>% 55 | ggvis(x = ~x, y = ~g) %>% 56 | layer_paths(strokeDash = ~g) %>% 57 | add_axis("y", grid = FALSE) %>% 58 | add_axis("x", grid = FALSE, title = "", tick_size_major = 0, ticks = 0) 59 | -------------------------------------------------------------------------------- /demo/rmarkdown/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /demo/rmarkdown/html_document.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using ggvis with knitr and rmarkdown" 3 | output: 4 | html_document: 5 | fig_width: 4 6 | fig_height: 2 7 | --- 8 | 9 | ```{r echo=FALSE} 10 | # Set up default dimensions. Width and height are multiplied by dpi to get 11 | # pixel dimensions. 12 | knitr::opts_chunk$set(fig.width = 4, fig.height = 3) 13 | ``` 14 | 15 | To embed a ggvis plot just call `ggvis`: 16 | 17 | ```{r, message = FALSE} 18 | library(ggvis) 19 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() 20 | ``` 21 | 22 | 23 | ```{r, fig.width = 8, fig.height = 6} 24 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 25 | layer_points() %>% 26 | layer_smooths() 27 | ``` 28 | -------------------------------------------------------------------------------- /demo/rmarkdown/interactive_doc.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ggvis in an interactive document" 3 | output: html_document 4 | runtime: shiny 5 | --- 6 | 7 | ```{r echo=FALSE, message = FALSE} 8 | library(knitr) 9 | library(ggvis) 10 | library(shiny) 11 | library(dplyr) 12 | ``` 13 | 14 | An interactive plot: 15 | 16 | ```{r, message = FALSE, fig.width = 6, fig.height = 4} 17 | cocaine %>% 18 | ggvis(x = ~potency) %>% 19 | layer_histograms(width = input_slider(1, 20, value = 5)) 20 | ``` 21 | 22 | 23 | An interactive table: 24 | 25 | ```{r, fig.width = 8, fig.height = 6} 26 | cocaine %>% 27 | group_by(state) %>% 28 | summarise(potency = mean(potency), weight = mean(weight)) %>% 29 | renderDataTable() 30 | ``` 31 | -------------------------------------------------------------------------------- /demo/rmarkdown/ioslides_presentation.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using ggvis with knitr and rmarkdown" 3 | author: Winston Chang 4 | output: 5 | ioslides_presentation: 6 | widescreen: true 7 | fig_width: 6 8 | fig_height: 4 9 | --- 10 | 11 | ## First Plot 12 | 13 | ```{r, message = FALSE} 14 | library(ggvis) 15 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() 16 | ``` 17 | 18 | ## Second Plot 19 | 20 | ```{r} 21 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 22 | layer_points() %>% 23 | layer_smooths() 24 | ``` 25 | -------------------------------------------------------------------------------- /demo/rmarkdown/linked_brush.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Brushing" 3 | output: html_document 4 | runtime: shiny 5 | --- 6 | ```{r, message = FALSE, echo = FALSE} 7 | library(ggvis) 8 | library(shiny) 9 | 10 | set.seed(1233) 11 | cocaine <- cocaine[sample(1:nrow(cocaine), 500), ] 12 | ``` 13 | 14 | Two linked plots. Brushing in the scatter plot will update the histogram. 15 | 16 | ```{r fig.width = 4, fig.height = 3, echo = FALSE, results = "hold"} 17 | cocaine$id <- seq_len(nrow(cocaine)) 18 | 19 | lb <- linked_brush(keys = cocaine$id, "red") 20 | 21 | cocaine %>% 22 | ggvis(~weight, ~price, key := ~id) %>% 23 | layer_points(fill := lb$fill, fill.brush := "red", opacity := 0.3) %>% 24 | lb$input() 25 | 26 | # A subset of cocaine, of only the selected points 27 | selected <- lb$selected 28 | cocaine_selected <- reactive({ 29 | cocaine[selected(), ] 30 | }) 31 | 32 | cocaine %>% 33 | ggvis(~potency) %>% 34 | layer_histograms(width = 5, boundary = 0) %>% 35 | add_data(cocaine_selected) %>% 36 | layer_histograms(width = 5, boundary = 0, fill := "#dd3333") 37 | ``` 38 | 39 | A summary of the selected points: 40 | 41 | ```{r, echo = FALSE} 42 | renderPrint( 43 | summary(cocaine_selected()) 44 | ) 45 | ``` 46 | -------------------------------------------------------------------------------- /demo/rmarkdown/zoom.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Zooming" 3 | output: html_document 4 | runtime: shiny 5 | --- 6 | 7 | First we load ggvis and shiny: 8 | 9 | ```{r, message = FALSE} 10 | options(width = 200) 11 | library(ggvis) 12 | library(shiny) 13 | ``` 14 | 15 | Then we create a linked brush object. This needs to know the possible linking keys. Here we're going to link together some plots of the `mtcars` dataset, so we'll add an `id` column, and use it as the keys: 16 | 17 | ```{r} 18 | # Add ID column to mtcars so that we can select from it 19 | mtcars2 <- cbind(mtcars, id = seq_len(nrow(mtcars))) 20 | 21 | lb <- linked_brush(keys = mtcars2$id, "red") 22 | ``` 23 | 24 | Next we create two plots. Points that are brushed on the first plot will be displayed on the second plot, and the scales will automatically adjust so that those points fill the plot. 25 | 26 | ```{r fig.width = 3, fig.height = 3, results = "hold"} 27 | mtcars2 %>% 28 | ggvis(~disp, ~mpg, key := ~id) %>% 29 | layer_points(fill := lb$fill, fill.brush := "red") %>% 30 | function(vis) lb$input(vis) 31 | 32 | # A subset of mtcars2, of only the selected points, or the whole data if nothing 33 | # is selected. 34 | selected <- lb$selected 35 | mtcars2_selected <- reactive({ 36 | if (!any(selected())) return(mtcars2) 37 | mtcars2[selected(), ] 38 | }) 39 | 40 | mtcars2_selected %>% 41 | ggvis(~disp, ~mpg) %>% 42 | layer_points(key := ~id) %>% 43 | set_options(duration = 100) 44 | ``` 45 | 46 | Also, we can show a table of the data, including a column indicating which ones are selected: 47 | 48 | ```{r} 49 | renderTable( 50 | cbind(mtcars2, selected = selected()) 51 | ) 52 | ``` 53 | -------------------------------------------------------------------------------- /demo/scales.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Discrete colours for fill and a manual scale for opacity 4 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~factor(cyl), fillOpacity = ~hp) %>% 5 | layer_points() %>% 6 | scale_numeric("opacity", range = c(0.2, 1)) 7 | 8 | # Control the domain of a scale - the y scale will go from 0 to whatever the 9 | # maximum of the data is. 10 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() %>% 11 | scale_numeric("y", domain = c(0, NA)) 12 | 13 | # Control the y range with a slider 14 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() %>% 15 | scale_numeric("y", domain = input_slider(0, 50, c(10, 40), label = "Y range")) 16 | 17 | # Control the lower y range with a slider 18 | # FIXME: clamp=TRUE is necessary to work around a sizing bug 19 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() %>% 20 | scale_numeric("y", clamp = TRUE, 21 | domain = input_slider(0, 50, label = "Lower Y", 22 | map = function(x) c(x, NA)) 23 | ) 24 | 25 | # Multiple x scales 26 | mtcars %>% ggvis(y = ~mpg, size := 25) %>% 27 | layer_points(prop("x", quote(disp), scale = "xdisp")) %>% 28 | layer_points(prop("x", quote(wt), scale = "xwt"), fill := "red") %>% 29 | add_axis("x", "xdisp", orient = "top") %>% 30 | add_axis("x", "xwt", orient = "bottom", 31 | properties = axis_props( 32 | ticks = list(stroke = "red"), 33 | labels = list(fill = "red") 34 | ) 35 | ) 36 | 37 | 38 | # Unscaled values in the data 39 | mtc <- mtcars 40 | mtc$color <- c("red", "teal", "#cccccc", "tan") 41 | mtc %>% ggvis(x = ~wt, y = ~mpg, fill := ~color) %>% layer_points() 42 | 43 | # Unscaled constant 44 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill := "red") %>% layer_points() 45 | -------------------------------------------------------------------------------- /demo/scatterplot.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Basic scatter plot 4 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() 5 | 6 | # Variable transformations 7 | mtcars %>% ggvis(x = ~wt, y = ~wt/mpg) %>% layer_points() 8 | mtcars %>% ggvis(x = ~factor(cyl), y = ~mpg) %>% layer_points() 9 | 10 | # With colour 11 | # continuous: 12 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>% layer_points() 13 | # and discrete: 14 | mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~factor(cyl)) %>% 15 | layer_points() 16 | 17 | # Use unscaled constant: 10 refers to 10 pixels from top 18 | mtcars %>% ggvis(x = ~wt) %>% 19 | layer_points(y = ~mpg) %>% 20 | layer_points(y := 10, fill := "red") 21 | 22 | # Use scaled constant: 10 refers to data space 23 | mtcars %>% ggvis(x = ~wt) %>% 24 | layer_points(y = ~mpg) %>% 25 | layer_points(y = 10, fill := "red") 26 | 27 | # Line and point graph 28 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 29 | layer_lines() %>% 30 | layer_points(fill := "red") 31 | 32 | # Two marks 33 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 34 | layer_points() %>% 35 | layer_points(fill := "red", size := 25) 36 | 37 | # Two marks at different levels of the tree, with different mappings for a 38 | # variable 39 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 40 | layer_points() %>% 41 | layer_points(fill := "red", y = ~qsec, size := 25) 42 | 43 | # Two y scales 44 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 45 | layer_points() %>% 46 | layer_points(fill := "red", prop("y", ~qsec, scale = "yq")) 47 | 48 | # Two separate data sets, equal in the tree 49 | mtc1 <- mtcars[1:10, ] 50 | mtc2 <- mtcars[11:20, ] 51 | ggvis(NULL, x = ~wt, y = ~mpg) %>% 52 | layer_points(stroke := "black", fill := "black", data = mtc1) %>% 53 | layer_points(fill := "red", size := 40, data = mtc2) 54 | 55 | # Scatter plot with one set of points with `cyl` mapped to stroke, 56 | # and another set with `am` mapped to fill 57 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 58 | layer_points(stroke = ~factor(cyl), fill := NA) %>% 59 | layer_points(fill = ~factor(am), size := 25) 60 | 61 | # Same as previous, but also with (useless) grouping in the layers 62 | mtcars %>% group_by(cyl) %>% 63 | ggvis(x = ~wt, y = ~mpg) %>% 64 | layer_points(stroke = ~factor(cyl), fill := NA) %>% 65 | layer_points(fill = ~factor(am), size := 25) 66 | 67 | # Use expression in a prop 68 | pressure %>% ggvis(x = ~temperature, y = ~log(pressure)) %>% layer_points() 69 | 70 | # Use variable from the calling environment 71 | y_min <- min(log(pressure$pressure)) 72 | pressure %>% ggvis(x = ~temperature, y = ~log(pressure) - y_min) %>% 73 | layer_points() 74 | -------------------------------------------------------------------------------- /demo/size.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Set size to 300x300 pixels 4 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 5 | layer_points() %>% 6 | set_options(width = 300, height = 300) 7 | 8 | # Set size to 300x300 pixels, and add 50 pixels padding on all sides 9 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 10 | layer_points() %>% 11 | set_options(width = 300, height = 300, padding = padding(50, 50, 50, 50)) 12 | -------------------------------------------------------------------------------- /demo/smooth.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | # Scatter plot with loess model line 4 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 5 | layer_points() %>% 6 | compute_smooth(mpg ~ wt, se = F) %>% 7 | layer_paths(x = ~pred_, y = ~resp_, stroke := "red") 8 | 9 | # Or with shorthand layer_smooth 10 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 11 | layer_points() %>% 12 | layer_smooths(stroke := "red") 13 | 14 | # With confidence region 15 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 16 | layer_points() %>% 17 | layer_smooths(stroke := "red", se = TRUE) 18 | 19 | # Scatter plot with lm model line 20 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 21 | layer_points() %>% 22 | layer_model_predictions(stroke := "red", model = "lm") 23 | 24 | # Scatterplot with lm and loess 25 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 26 | layer_points() %>% 27 | layer_smooths(stroke := "blue") %>% 28 | layer_model_predictions(stroke := "red", model = "lm") 29 | 30 | # Scatter plot with smooth for each level of cyl 31 | mtcars %>% ggvis(x = ~wt, y = ~mpg, stroke = ~factor(cyl)) %>% 32 | group_by(cyl) %>% 33 | layer_points() %>% 34 | layer_smooths() 35 | 36 | # Scatter plot with smooth for each level of cyl, but only points coloured 37 | mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% 38 | group_by(cyl) %>% 39 | layer_points(fill = ~factor(cyl)) %>% 40 | layer_smooths() 41 | -------------------------------------------------------------------------------- /demo/tile.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | pp <- function (n, r = 4) { 4 | width <- 2 * r * pi / (n - 1) 5 | 6 | mid <- seq(-r * pi, r * pi, len = n) 7 | df <- expand.grid(x = mid, y = mid) 8 | df$r <- sqrt(df$x^2 + df$y^2) 9 | df$z <- cos(df$r^2)*exp(-df$r/6) 10 | 11 | df$y2 <- df$y + width 12 | df$x2 <- df$x + width 13 | df$x <- df$x - width 14 | df$y <- df$y - width 15 | df 16 | } 17 | 18 | pp(100) %>% ggvis(~x, ~y, x2 = ~x2, y2 = ~y2, fill = ~ z, stroke := NA) %>% 19 | layer_rects() 20 | -------------------------------------------------------------------------------- /demo/tourr.r: -------------------------------------------------------------------------------- 1 | library(tourr) 2 | library(ggvis) 3 | library(shiny) 4 | 5 | aps <- 2 6 | fps <- 30 7 | 8 | mat <- rescale(as.matrix(flea[1:6])) 9 | tour <- new_tour(mat, grand_tour(), NULL) 10 | start <- tour(0) 11 | 12 | proj_data <- reactive({ 13 | invalidateLater(1000 / fps, NULL); 14 | step <- tour(aps / fps) 15 | data.frame(center(mat %*% step$proj), species = flea$species) 16 | }) 17 | 18 | proj_data %>% ggvis(~X1, ~X2, fill = ~species) %>% 19 | layer_points() %>% 20 | scale_numeric("x", domain = c(-1, 1)) %>% 21 | scale_numeric("y", domain = c(-1, 1)) %>% 22 | set_options(duration = 0) 23 | -------------------------------------------------------------------------------- /ggvis.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageBuildArgs: --no-build-vignettes 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /inst/.gitignore: -------------------------------------------------------------------------------- 1 | doc -------------------------------------------------------------------------------- /inst/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cd www/lib 6 | 7 | cd vega 8 | curl -O https://raw.github.com/trifacta/vega/master/vega.js 9 | curl -O https://raw.github.com/trifacta/vega/master/vega.min.js 10 | 11 | cd ../d3 12 | curl -O https://raw.github.com/mbostock/d3/master/d3.js 13 | curl -O https://raw.github.com/mbostock/d3/master/d3.min.js 14 | 15 | cd ../jquery 16 | curl http://code.jquery.com/jquery-1.11.0.min.js > jquery.min.js 17 | curl http://code.jquery.com/jquery-1.11.0.js > jquery.js 18 | 19 | cd ../../.. 20 | -------------------------------------------------------------------------------- /inst/www/ggvis/css/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/ggvis/css/gear.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /inst/www/lib/jquery-ui/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/inst/www/lib/jquery-ui/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /man-roxygen/properties.R: -------------------------------------------------------------------------------- 1 | #' @section Properties: 2 | #' 3 | #' You can set the following mark properties: 4 | #' 5 | #' \itemize{ 6 | #' \item x The first (typically left-most) x-coordinate. 7 | #' \item x2 The second (typically right-most) x-coordinate. 8 | #' \item width The width of the mark (if supported). 9 | #' \item y The first (typically top-most) y-coordinate. 10 | #' \item y2 The second (typically bottom-most) y-coordinate. 11 | #' \item height The height of the mark (if supported). 12 | #' \item opacity The overall opacity. 13 | #' \item fill The fill color. 14 | #' \item fillOpacity The fill opacity 15 | #' \item stroke The stroke color. 16 | #' \item strokeWidth The stroke width, in pixels. 17 | #' \item strokeOpacity The stroke opacity. 18 | #' \item size [symbol] The pixel area of the symbol. For example in the case 19 | #' of circles, the radius is determined in part by the square root of the size 20 | #' value. 21 | #' \item shape [symbol] The symbol shape to use. One of circle (default), 22 | #' square, cross, diamond, triangle-up, or triangle-down (symbol only) 23 | #' \item innerRadius [arc] The inner radius of the arc, in pixels. 24 | #' \item outerRadius [arc] The outer radius of the arc, in pixels. 25 | #' \item startAngle [arc] The start angle of the arc, in radians. 26 | #' \item endAngle [arc] The end angle of the arc, in radians. 27 | #' \item interpolate [area, line] The line interpolation method to use. One 28 | #' of linear, step-before, step-after, basis, basis-open, cardinal, 29 | #' cardinal-open, monotone. 30 | #' \item tension [area, line] Depending on the interpolation type, sets the 31 | #' tension parameter. 32 | #' \item url [image] The URL from which to retrieve the image. 33 | #' \item align [image, text] The horizontal alignment of the object. One of 34 | #' left, right, center. 35 | #' \item baseline [image, text] The vertical alignment of the object. One of 36 | #' top, middle, bottom. 37 | #' \item text [text] The text to display. 38 | #' \item dx [text] The horizontal margin, in pixels, between the text label 39 | #' and its anchor point. The value is ignored if the align property is center. 40 | #' \item dy [text] The vertical margin, in pixels, between the text label 41 | #' and its anchor point. The value is ignored if the baseline property is 42 | #' middle. 43 | #' \item angle [text] The rotation angle of the text, in degrees. 44 | #' \item font [text] The typeface to set the text in (e.g., Helvetica Neue). 45 | #' \item fontSize [text] The font size, in pixels. 46 | #' \item fontWeight [text] The font weight (e.g., bold). 47 | #' \item fontStyle [text] The font style (e.g., italic). 48 | #' } 49 | #' 50 | #' To each property, you can assign any property object (\code{\link{prop}}) 51 | #' either locally (i.e. in the mark), or in a parent \code{layer}. 52 | -------------------------------------------------------------------------------- /man/add_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{add_data} 4 | \alias{add_data} 5 | \title{Add dataset to a visualisation} 6 | \usage{ 7 | add_data(vis, data, name = deparse2(substitute(data)), add_suffix = TRUE) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to modify.} 11 | 12 | \item{data}{Data set to add.} 13 | 14 | \item{name}{Data of data - optional, but helps produce informative 15 | error messages.} 16 | 17 | \item{add_suffix}{Should a unique suffix be added to the data object's ID? 18 | This should only be FALSE when the spec requires a data set with a 19 | specific name.} 20 | } 21 | \description{ 22 | Add dataset to a visualisation 23 | } 24 | \examples{ 25 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() 26 | NULL \%>\% ggvis(~mpg, ~wt) \%>\% add_data(mtcars) \%>\% layer_points() 27 | } 28 | -------------------------------------------------------------------------------- /man/add_guide_axis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_axis.R 3 | \name{add_guide_axis} 4 | \alias{add_guide_axis} 5 | \title{Defunct function for adding an axis} 6 | \usage{ 7 | add_guide_axis(...) 8 | } 9 | \arguments{ 10 | \item{...}{Other arguments.} 11 | } 12 | \description{ 13 | This function has been replaced with \code{\link{add_axis}}. 14 | } 15 | -------------------------------------------------------------------------------- /man/add_guide_legend.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_legend.R 3 | \name{add_guide_legend} 4 | \alias{add_guide_legend} 5 | \title{Defunct function for adding a legend} 6 | \usage{ 7 | add_guide_legend(...) 8 | } 9 | \arguments{ 10 | \item{...}{Other arguments.} 11 | } 12 | \description{ 13 | This function has been replaced with \code{\link{add_legend}}. 14 | } 15 | -------------------------------------------------------------------------------- /man/add_props.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{add_props} 4 | \alias{add_props} 5 | \title{Add visual properties to a visualisation} 6 | \usage{ 7 | add_props(vis, ..., .props = NULL, inherit = NULL, env = parent.frame()) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to modify.} 11 | 12 | \item{...}{A set of name-value pairs. The name should be a valid vega 13 | property. 14 | 15 | The first two unnamed components are taken to be \code{x} and \code{y}. 16 | Any additional unnamed components will raise an error.} 17 | 18 | \item{.props}{When calling \code{props} from other functions, you'll 19 | often have a list of quoted function functions. You can pass that function 20 | to the \code{.props} argument instead of messing around with 21 | substitute. In other words, \code{.props} lets you opt out of the 22 | non-standard evaluation that \code{props} does.} 23 | 24 | \item{inherit}{If \code{TRUE}, the defaults, will inherit from properties 25 | from the parent layer If \code{FALSE}, it will start from nothing.} 26 | 27 | \item{env}{The environment in which to evaluate variable properties.} 28 | } 29 | \description{ 30 | Add visual properties to a visualisation 31 | } 32 | \examples{ 33 | mtcars \%>\% ggvis(~wt, ~mpg) \%>\% layer_points() 34 | mtcars \%>\% ggvis() \%>\% add_props(~wt, ~mpg) \%>\% layer_points() 35 | mtcars \%>\% ggvis(~wt) \%>\% add_props(y = ~mpg) \%>\% layer_points() 36 | } 37 | -------------------------------------------------------------------------------- /man/add_relative_scales.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scales.R 3 | \name{add_relative_scales} 4 | \alias{add_relative_scales} 5 | \title{Add x_rel and y_rel scales} 6 | \usage{ 7 | add_relative_scales(vis) 8 | } 9 | \arguments{ 10 | \item{vis}{A ggvis object.} 11 | } 12 | \description{ 13 | This function adds scales named \code{x_rel} and \code{y_rel}, each of which 14 | has a domain of 0 to 1, and the range is the plot's width or height. 15 | These scales are useful for positioning visual elements relative to the 16 | plotting area. For example, with legends. 17 | } 18 | \seealso{ 19 | \code{\link{add_legend}} for a usage example. 20 | } 21 | -------------------------------------------------------------------------------- /man/add_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{add_scale} 4 | \alias{add_scale} 5 | \title{Add arbitrary scales to ggvis.} 6 | \usage{ 7 | add_scale(vis, scale, data_domain = TRUE) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to modify.} 11 | 12 | \item{scale}{Scale object} 13 | 14 | \item{data_domain}{Should the domain be controlled by a data set which is 15 | added to the spec? Should only be set to FALSE in special cases.} 16 | } 17 | \description{ 18 | Add arbitrary scales to ggvis. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/add_tooltip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/interact_tooltip.R 3 | \name{add_tooltip} 4 | \alias{add_tooltip} 5 | \title{Add tooltips to a plot.} 6 | \usage{ 7 | add_tooltip(vis, html, on = c("hover", "click")) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to add tooltips to.} 11 | 12 | \item{html}{A function that takes a single argument as input. This argument 13 | will be a list containing the data in the mark currently under the 14 | mouse. It should return a string containing HTML or \code{NULL} to 15 | hide tooltip for the current element.} 16 | 17 | \item{on}{Should tooltips appear on hover, or on click?} 18 | } 19 | \description{ 20 | Add tooltips to a plot. 21 | } 22 | \examples{ 23 | ## Run these examples only in interactive R sessions 24 | if (interactive()) { 25 | 26 | all_values <- function(x) { 27 | if(is.null(x)) return(NULL) 28 | paste0(names(x), ": ", format(x), collapse = "
") 29 | } 30 | 31 | base <- mtcars \%>\% ggvis(x = ~wt, y = ~mpg) \%>\% 32 | layer_points() 33 | base \%>\% add_tooltip(all_values, "hover") 34 | base \%>\% add_tooltip(all_values, "click") 35 | 36 | # The data sent from client to the server contains only the data columns that 37 | # are used in the plot. If you want to get other columns of data, you should 38 | # to use a key to line up the item from the plot with a row in the data. 39 | mtc <- mtcars 40 | mtc$id <- 1:nrow(mtc) # Add an id column to use ask the key 41 | 42 | all_values <- function(x) { 43 | if(is.null(x)) return(NULL) 44 | row <- mtc[mtc$id == x$id, ] 45 | paste0(names(row), ": ", format(row), collapse = "
") 46 | } 47 | 48 | mtc \%>\% ggvis(x = ~wt, y = ~mpg, key := ~id) \%>\% 49 | layer_points() \%>\% 50 | add_tooltip(all_values, "hover") 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /man/as.vega.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vega.R 3 | \name{as.vega} 4 | \alias{as.vega} 5 | \alias{as.vega.ggvis} 6 | \title{Coerce an ggvis object to a vega list.} 7 | \usage{ 8 | as.vega(x, ...) 9 | 10 | \method{as.vega}{ggvis}(x, session = NULL, dynamic = FALSE, ...) 11 | } 12 | \arguments{ 13 | \item{x}{an object to convert to vega} 14 | 15 | \item{session}{a session object from shiny} 16 | 17 | \item{dynamic}{whether to generate dynamic or static spec} 18 | } 19 | \value{ 20 | a list. When converted to JSON, will be the type of structure 21 | that vega expects. 22 | } 23 | \description{ 24 | This generic function powers the coercion of ggvis objects to vega 25 | compatible data structures. 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /man/auto_group.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_auto_group.R 3 | \name{auto_group} 4 | \alias{auto_group} 5 | \title{Automatically group data by grouping variables} 6 | \usage{ 7 | auto_group(vis, exclude = NULL) 8 | } 9 | \arguments{ 10 | \item{vis}{The ggvis visualisation to modify.} 11 | 12 | \item{exclude}{A vector containing names of props to exclude from auto grouping. 13 | It is often useful to exclude \code{c("x", "y")}, when one of those variables 14 | is categorical.} 15 | } 16 | \description{ 17 | Use \code{auto_group} to group up a dataset on all categorical variables 18 | specified by props, and have each piece rendered by the same mark. 19 | } 20 | \examples{ 21 | # One line 22 | mtcars \%>\% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) \%>\% layer_paths() 23 | # One line for each level of cyl 24 | mtcars \%>\% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) \%>\% group_by(cyl) \%>\% 25 | layer_paths() 26 | mtcars \%>\% ggvis(~disp, ~mpg, stroke = ~factor(cyl)) \%>\% auto_group() \%>\% 27 | layer_paths() 28 | 29 | # The grouping column can already be stored as a factor 30 | mtcars2 <- mtcars 31 | mtcars2$cyl <- factor(mtcars2$cyl) 32 | mtcars2 \%>\% ggvis(~disp, ~mpg, stroke = ~cyl) \%>\% auto_group() \%>\% 33 | layer_paths() 34 | } 35 | \seealso{ 36 | To manually specify grouping variables, see \code{\link{group_by}}. 37 | } 38 | -------------------------------------------------------------------------------- /man/axis_props.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{axis_props} 4 | \alias{axis_props} 5 | \title{Create an axis_props object for controlling axis properties.} 6 | \usage{ 7 | axis_props( 8 | ticks = NULL, 9 | majorTicks = NULL, 10 | minorTicks = NULL, 11 | grid = NULL, 12 | labels = NULL, 13 | title = NULL, 14 | axis = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{ticks}{A named list of line properties for ticks.} 19 | 20 | \item{majorTicks}{A named list of line properties for major ticks.} 21 | 22 | \item{minorTicks}{A named list of line properties for minor ticks.} 23 | 24 | \item{grid}{A named list of line properties for grid lines.} 25 | 26 | \item{labels}{A named list of text properties for axis labels.} 27 | 28 | \item{title}{A named list of text properties for the axis title.} 29 | 30 | \item{axis}{A named list of line properties for the axis line.} 31 | } 32 | \description{ 33 | The items in each of the lists can be a literal value, like \code{5} or 34 | "blue", or they can be a \code{\link{scaled_value}} object. 35 | } 36 | -------------------------------------------------------------------------------- /man/band.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/prop_band.R 3 | \name{band} 4 | \alias{band} 5 | \alias{is.prop_band} 6 | \title{A band} 7 | \usage{ 8 | band(offset = NULL, mult = NULL) 9 | 10 | is.prop_band(x) 11 | } 12 | \arguments{ 13 | \item{offset, mult}{Additive and multiplicate offsets used to adjust the 14 | band size. For example, use \code{mult = 0.9} to make a bar take up 15 | 90\% of the space allocated for its category.} 16 | 17 | \item{x}{object to test for band-ness} 18 | } 19 | \description{ 20 | Bands are used to set the width or height on categorical scales - a band 21 | represent the height or width allocated for one level of a factor. 22 | } 23 | \examples{ 24 | df <- data.frame(label = c("a", "b", "c"), n = c(10, 9, 4)) 25 | 26 | base <- df \%>\% ggvis(~label, y2 = 0, y = ~n) 27 | base \%>\% layer_rects(width = band()) 28 | base \%>\% layer_rects(width = band(offset = -1)) 29 | base \%>\% layer_rects(width = band(mult = 0.9)) 30 | 31 | # A nominal scale with padding is more symmetrical than band with a mult 32 | base \%>\% layer_rects(width = band(mult = 0.75)) 33 | base \%>\% layer_rects(width = band()) \%>\% 34 | scale_nominal("x", padding = 0.25, points = FALSE) 35 | } 36 | -------------------------------------------------------------------------------- /man/bin_vector.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_bin.R 3 | \name{bin_vector} 4 | \alias{bin_vector} 5 | \alias{bin_vector.numeric} 6 | \title{Bin vectors} 7 | \usage{ 8 | bin_vector(x, weight = NULL, ...) 9 | 10 | \method{bin_vector}{numeric}( 11 | x, 12 | weight = NULL, 13 | ..., 14 | width = 1, 15 | origin = 0, 16 | closed = c("right", "left"), 17 | pad = FALSE 18 | ) 19 | } 20 | \arguments{ 21 | \item{x}{A vector to bin} 22 | 23 | \item{weight}{If specified, an integer vector of the same length as \code{x} 24 | representing the number of occurances of each value in \code{x}} 25 | 26 | \item{...}{additional arguments passed through to methods.} 27 | 28 | \item{width}{The width of a bin} 29 | 30 | \item{origin}{The left-most value for bins.} 31 | 32 | \item{closed}{One of \code{"right"} or \code{"left"} indicating whether 33 | right or left edges of bins are included in the bin.} 34 | 35 | \item{pad}{A logical indicating whether the bins should be padded to include 36 | an empty bin on each side.} 37 | } 38 | \description{ 39 | A generic and several implementations for binning vectors. 40 | } 41 | \keyword{internal} 42 | -------------------------------------------------------------------------------- /man/cocaine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_cocaine.R 3 | \docType{data} 4 | \name{cocaine} 5 | \alias{cocaine} 6 | \title{Cocaine seizures in the US.} 7 | \format{ 8 | Data frame with 3380 observations of 5 variables. 9 | } 10 | \usage{ 11 | cocaine 12 | } 13 | \description{ 14 | This dataset comes from STRIDE, the System to Retrieve Information from Drug 15 | Evidence. It contains all concaine seizures in the US from 2007 that have 16 | a known weight. 17 | } 18 | \section{Variables}{ 19 | 20 | \describe{ 21 | \item{state}{State where seizure occured.} 22 | \item{potency}{Purity of cocaine, as percentage (100\% = pure cocaine, 23 | 0\% = all filler)} 24 | \item{weight}{Weight, in grams.} 25 | \item{month}{Month in which seizure occured.} 26 | \item{price}{Estimated value in USD.} 27 | } 28 | } 29 | 30 | \section{Use}{ 31 | 32 | Use of this data requires your agreement to refer to your analyses as 33 | "unvalidated DEA data and to claim authorship and responsibility for any 34 | inferences and/or conclusions you may draw from this information." 35 | } 36 | 37 | \keyword{datasets} 38 | -------------------------------------------------------------------------------- /man/compute_align.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_align.R 3 | \name{compute_align} 4 | \alias{compute_align} 5 | \title{Align positions using length.} 6 | \usage{ 7 | compute_align(x, var, length = NULL, align = 0.5, dir = "x") 8 | } 9 | \arguments{ 10 | \item{x}{Dataset-like object to align. Built-in methods for data frames, 11 | grouped data frames and ggvis visualisations.} 12 | 13 | \item{var}{Name of variable to compute width of.} 14 | 15 | \item{length}{An absolute length to use. If \code{NULL} (the default), the 16 | width will be equivalent to the resolution of the data.} 17 | 18 | \item{align}{Where does the existing variable fall on the new bins? 19 | 0 = left edge, 0.5 = center, 1 = right edge.} 20 | 21 | \item{dir}{Direction, i.e. \code{"x"} or \code{"y"}. Used to generate 22 | variable names in output.} 23 | } 24 | \value{ 25 | The original data frame, with additional columns: 26 | \item{'dir'min_}{left boundary of bin} 27 | \item{'dir'max_}{right boundary of bin} 28 | \item{'dir'len_}{width of bin} 29 | } 30 | \description{ 31 | This compute function is often used in conjunction with 32 | \code{\link{compute_count}}, when used on data with a continuous x variable. 33 | By default, the computed width will be equal to the resolution of the data, 34 | or, in other words the smallest difference between two values in the data. 35 | } 36 | \details{ 37 | An absolute width for each x can be specified by using the \code{width} 38 | argument. If \code{width} is NULL (the default), it will use the resolution 39 | of the data as the width. 40 | } 41 | \examples{ 42 | mtcars \%>\% compute_count(~disp) \%>\% compute_align(~x_) 43 | mtcars \%>\% compute_count(~mpg) \%>\% compute_align(~x_) 44 | 45 | # Use a specific width 46 | pressure \%>\% compute_count(~temperature) \%>\% compute_align(~x_) 47 | pressure \%>\% compute_count(~temperature) \%>\% compute_align(~x_, length = 5) 48 | 49 | # It doesn't matter whether you transform inside or outside of a vis 50 | mtcars \%>\% compute_count(~cyl, ~wt) \%>\% 51 | compute_align(~x_, length = .5) \%>\% 52 | ggvis(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) \%>\% 53 | layer_rects() 54 | 55 | mtcars \%>\% 56 | ggvis(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) \%>\% 57 | compute_count(~cyl, ~wt) \%>\% 58 | compute_align(~x_) \%>\% 59 | layer_rects() 60 | 61 | # Varying align 62 | mtcars \%>\% 63 | ggvis(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) \%>\% 64 | compute_count(~cyl, ~wt) \%>\% 65 | compute_align(~x_, length = 0.5, align = input_slider(0, 1)) \%>\% 66 | layer_rects() 67 | } 68 | \seealso{ 69 | \code{\link{compute_bin}} For counting cases within ranges of 70 | a continuous variable. 71 | 72 | \code{\link{compute_count}} For counting cases at specific values 73 | of a variable. 74 | } 75 | -------------------------------------------------------------------------------- /man/compute_boxplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_boxplot.R 3 | \name{compute_boxplot} 4 | \alias{compute_boxplot} 5 | \title{Calculate boxplot values} 6 | \usage{ 7 | compute_boxplot(x, var = NULL, coef = 1.5) 8 | } 9 | \arguments{ 10 | \item{x}{Dataset-like object to compute boxplot values. There are built-in 11 | methods for data frames, grouped data frames, and ggvis visualisations.} 12 | 13 | \item{var}{Name of variable for which to compute boxplot values. The variable 14 | must be continuous.} 15 | 16 | \item{coef}{The maximum length of the whiskers as multiple of the 17 | inter-quartile range. Default value is 1.5.} 18 | } 19 | \value{ 20 | A data frame with columns: 21 | \item{min_}{Lower whisker = smallest observation greater than or equal to lower hinge - 1.5 * IQR} 22 | \item{lower_}{Lower hinge (25th percentile)} 23 | \item{median_}{Median (50th percentile)} 24 | \item{upper_}{Upper hinge (75th percentile)} 25 | \item{max_}{Upper whisker = largest observation less than or equal to upper hinge + 1.5 * IQR} 26 | \item{outliers_}{A vector of values that are outside of the min and max} 27 | } 28 | \description{ 29 | Calculate boxplot values 30 | } 31 | \examples{ 32 | mtcars \%>\% compute_boxplot(~mpg) 33 | mtcars \%>\% group_by(cyl) \%>\% compute_boxplot(~mpg) 34 | } 35 | \seealso{ 36 | \code{\link{layer_boxplots}} 37 | } 38 | -------------------------------------------------------------------------------- /man/compute_count.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_count.R 3 | \name{compute_count} 4 | \alias{compute_count} 5 | \title{Count data at each location} 6 | \usage{ 7 | compute_count(x, x_var, w_var = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{Dataset-like object to count. Built-in methods for data frames, 11 | grouped data frames and ggvis visualisations.} 12 | 13 | \item{x_var, w_var}{Names of x and weight variables.} 14 | } 15 | \value{ 16 | A data frame with columns: 17 | \item{count_}{the number of points} 18 | \item{x_}{the x value where the count was made} 19 | 20 | The width of each "bin" is set to the resolution of the data -- that is, the 21 | smallest difference between two x values. 22 | } 23 | \description{ 24 | Count data at each location 25 | } 26 | \examples{ 27 | mtcars \%>\% compute_count(~cyl) 28 | 29 | # Weight the counts by car weight value 30 | mtcars \%>\% compute_count(~cyl, ~wt) 31 | 32 | # If there's one weight value at each x, it effectively just renames columns. 33 | pressure \%>\% compute_count(~temperature, ~pressure) 34 | # Also get the width of each bin 35 | pressure \%>\% compute_count(~temperature, ~pressure) \%>\% compute_align(~x_) 36 | 37 | # It doesn't matter whether you transform inside or outside of a vis 38 | mtcars \%>\% compute_count(~cyl, ~wt) \%>\% 39 | compute_align(~x_) \%>\% 40 | ggvis(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) \%>\% 41 | layer_rects() 42 | 43 | mtcars \%>\% 44 | ggvis(x = ~xmin_, x2 = ~xmax_, y = ~count_, y2 = 0) \%>\% 45 | compute_count(~cyl, ~wt) \%>\% 46 | compute_align(~x_) \%>\% 47 | layer_rects() 48 | } 49 | \seealso{ 50 | \code{\link{compute_bin}} For counting cases within ranges of 51 | a continuous variable. 52 | 53 | \code{\link{compute_align}} For calculating the "width" of data. 54 | } 55 | -------------------------------------------------------------------------------- /man/compute_density.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_density.R 3 | \name{compute_density} 4 | \alias{compute_density} 5 | \title{Compute density of data.} 6 | \usage{ 7 | compute_density( 8 | x, 9 | x_var, 10 | w_var = NULL, 11 | kernel = "gaussian", 12 | trim = FALSE, 13 | n = 256L, 14 | na.rm = FALSE, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{x}{Dataset (data frame, \code{grouped_df} or ggvis) object to work 20 | with.} 21 | 22 | \item{x_var, w_var}{Names of variables to use for x position, and for 23 | weights.} 24 | 25 | \item{kernel}{Smoothing kernel. See \code{\link{density}} for details.} 26 | 27 | \item{trim}{If \code{TRUE}, the default, density estimates are trimmed to the 28 | actual range of the data. If \code{FALSE}, they are extended by the 29 | default 3 bandwidths (as specified by the \code{cut} parameter to 30 | \code{\link{density}}).} 31 | 32 | \item{n}{Number of points (along x) to use in the density estimate.} 33 | 34 | \item{na.rm}{If \code{TRUE} missing values will be silently removed, 35 | otherwise they will be removed with a warning.} 36 | 37 | \item{...}{Additional arguments passed on to \code{\link{density}}.} 38 | } 39 | \value{ 40 | A data frame with columns: 41 | \item{pred_}{regularly spaced grid of \code{n} locations} 42 | \item{resp_}{density estimate} 43 | } 44 | \description{ 45 | Compute density of data. 46 | } 47 | \examples{ 48 | mtcars \%>\% compute_density(~mpg, n = 5) 49 | mtcars \%>\% group_by(cyl) \%>\% compute_density(~mpg, n = 5) 50 | mtcars \%>\% ggvis(~mpg) \%>\% compute_density(~mpg, n = 5) \%>\% 51 | layer_points(~pred_, ~resp_) 52 | } 53 | -------------------------------------------------------------------------------- /man/compute_stack.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_stack.R 3 | \name{compute_stack} 4 | \alias{compute_stack} 5 | \title{Stack overlapping data.} 6 | \usage{ 7 | compute_stack(x, stack_var = NULL, group_var = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{A data object} 11 | 12 | \item{stack_var}{A string specifying the stacking variable.} 13 | 14 | \item{group_var}{A string specifying the grouping variable.} 15 | } 16 | \value{ 17 | A data frame with columns: 18 | \item{stack_upr_}{the lower y coordinate for a stack bar} 19 | \item{stack_lwr_}{the upper y coordinate for a stack bar} 20 | } 21 | \description{ 22 | Stack overlapping data. 23 | } 24 | \examples{ 25 | mtcars \%>\% cbind(count = 1) \%>\% compute_stack(~count, ~cyl) 26 | 27 | # Shouldn't use or affect existing grouping 28 | mtcars \%>\% cbind(count = 1) \%>\% group_by(am) \%>\% compute_stack(~count, ~cyl) 29 | 30 | # If given a ggvis object, will use x variable for stacking by default 31 | mtcars \%>\% ggvis(x = ~cyl, y = ~wt) \%>\% 32 | compute_stack(stack_var = ~wt, group_var = ~cyl) \%>\% 33 | layer_rects(x = ~cyl - 0.5, x2 = ~cyl + 0.5, y = ~stack_upr_, 34 | y2 = ~stack_lwr_) 35 | 36 | # Collapse across hair & eye colour data across sex 37 | hec <- as.data.frame(xtabs(Freq ~ Hair + Eye, HairEyeColor)) 38 | hec \%>\% compute_stack(~Freq, ~Hair) 39 | 40 | # Without stacking - bars overlap 41 | hec \%>\% ggvis(~Hair, ~Freq, fill = ~Eye, fillOpacity := 0.5) \%>\% 42 | layer_rects(y2 = 0, width = band()) 43 | 44 | # With stacking 45 | hec \%>\% ggvis(x = ~Hair, y = ~Freq, fill = ~Eye, fillOpacity := 0.5) \%>\% 46 | compute_stack(~Freq, ~Hair) \%>\% 47 | layer_rects(y = ~stack_lwr_, y2 = ~stack_upr_, width = band()) 48 | 49 | # layer_bars stacks automatically: 50 | hec \%>\% ggvis(~Hair, ~Freq, fill = ~Eye, fillOpacity := 0.5) \%>\% 51 | group_by(Eye) \%>\% 52 | layer_bars(width = 1) 53 | } 54 | -------------------------------------------------------------------------------- /man/compute_tabulate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compute_tabulate.R 3 | \name{compute_tabulate} 4 | \alias{compute_tabulate} 5 | \title{Count data at each location of a categorical variable} 6 | \usage{ 7 | compute_tabulate(x, x_var, w_var = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{Dataset-like object to count. Built-in methods for data frames, 11 | grouped data frames and ggvis visualisations.} 12 | 13 | \item{x_var, w_var}{Names of x and weight variables.} 14 | } 15 | \value{ 16 | A data frame with columns: 17 | \item{count_}{the number of points} 18 | \item{x_}{value of bin} 19 | } 20 | \description{ 21 | Count data at each location of a categorical variable 22 | } 23 | \examples{ 24 | library(dplyr) 25 | # The tabulated column must be countable (not numeric) 26 | \dontrun{mtcars \%>\% compute_tabulate(~cyl)} 27 | mtcars \%>\% mutate(cyl = factor(cyl)) \%>\% compute_tabulate(~cyl) 28 | 29 | # Or equivalently: 30 | mtcars \%>\% compute_tabulate(~factor(cyl)) 31 | 32 | # If there's one weight value at each x, it effectively just renames columns. 33 | pressure \%>\% compute_tabulate(~factor(temperature), ~pressure) 34 | 35 | # It doesn't matter whether you transform inside or outside of a vis 36 | mtcars \%>\% compute_tabulate(~factor(cyl)) \%>\% 37 | ggvis(x = ~x_, y = ~count_, y2 = 0) \%>\% 38 | layer_rects(width = band()) 39 | 40 | mtcars \%>\% 41 | ggvis(x = ~x_, y = ~count_, y2 = 0) \%>\% 42 | compute_tabulate(~factor(cyl)) \%>\% 43 | layer_rects(width = band()) 44 | 45 | # compute_tabulate is used automatically in layer_bars when no y prop 46 | # is supplied. 47 | mtcars \%>\% ggvis(x = ~factor(cyl)) \%>\% layer_bars() 48 | } 49 | \seealso{ 50 | \code{\link{compute_bin}} For counting cases within ranges of 51 | a continuous variable. 52 | 53 | \code{\link{compute_count}} For counting cases at specific locations 54 | of a continuous variable. This is useful when the variable is continuous 55 | but the data is granular. 56 | } 57 | -------------------------------------------------------------------------------- /man/create_broker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/broker.R 3 | \name{create_broker} 4 | \alias{create_broker} 5 | \title{Create a broker object} 6 | \usage{ 7 | create_broker(r, controls = NULL, connect = NULL, spec = NULL) 8 | } 9 | \arguments{ 10 | \item{r}{A reactive expression.} 11 | 12 | \item{controls}{An HTML control, or a list of HTML controls.} 13 | 14 | \item{connect}{A function to run at render time. This function takes the 15 | Shiny \code{session} object as its only argument, and is used to connect 16 | the session with the broker object.} 17 | 18 | \item{spec}{Object to put in the Vega spec.} 19 | } 20 | \description{ 21 | A broker is a subclass of reactive. It can hold extra information to 22 | facilitate (or broker) communication between the client and the server. 23 | For example, an input broker may contain HTML controls to be emitted on the 24 | client web page, as well as a function to connect the inputs from the client 25 | to the reactive expression. 26 | } 27 | \details{ 28 | Other types of brokers are possible. Another broker may create reactive 29 | observers and add information to the Vega spec, instead of having HTML 30 | controls. In this case, a reactive expression is still needed, although 31 | it can be a dummy value, like \code{reactive(NULL)}. 32 | } 33 | \keyword{internal} 34 | -------------------------------------------------------------------------------- /man/create_input.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/input.R 3 | \name{create_input} 4 | \alias{create_input} 5 | \title{Create a new interactive "input" object.} 6 | \usage{ 7 | create_input( 8 | id = rand_id("input_"), 9 | default = NULL, 10 | map = identity, 11 | controls = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{id}{The name of the input object in the Shiny app, such as 16 | "slider_1338869".} 17 | 18 | \item{default}{The default (starting) value for the input.} 19 | 20 | \item{map}{A mapping function. Defaults to \code{identity}, which simply 21 | returns the value unchanged.} 22 | 23 | \item{controls}{A Shiny HTML tag object representing the UI for the controls.} 24 | } 25 | \description{ 26 | An interactive input object is a reactive expression which wraps a reactive 27 | value. When the plot is rendered, an observer is created which pushes values 28 | into the reactive value in response to changes of an input object. Those 29 | changes invalidate the reactive expression, which will return the value, 30 | optionally passed through a mapping function. 31 | } 32 | \details{ 33 | This function is designed to be used by authors of new types of interactive 34 | inputs. If you are a ggvis user, please use one of the more specific input 35 | functions starting with the \code{input_}. 36 | } 37 | \keyword{internal} 38 | -------------------------------------------------------------------------------- /man/default_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{default_options} 4 | \alias{default_options} 5 | \title{Default options} 6 | \usage{ 7 | default_options() 8 | } 9 | \description{ 10 | This returns an object containing the default options for ggvis. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/explain.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explain.R 3 | \name{explain} 4 | \alias{explain} 5 | \title{Explain details of an object} 6 | \description{ 7 | This is a generic function which gives more details about an object than 8 | print, and is more focussed on human readable output than str. 9 | } 10 | \examples{ 11 | p <- mtcars \%>\% ggvis(x = ~cyl) \%>\% layer_bars() 12 | explain(p) 13 | } 14 | \seealso{ 15 | \code{dplyr::\link[dplyr]{explain}} for more information. 16 | } 17 | -------------------------------------------------------------------------------- /man/explain.ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explain.R 3 | \name{explain.ggvis} 4 | \alias{explain.ggvis} 5 | \title{Print out the structure of a ggvis object in a friendly format} 6 | \usage{ 7 | \method{explain}{ggvis}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Visualisation to explain} 11 | 12 | \item{...}{Needed for compatibility with generic. Ignored by this method.} 13 | } 14 | \description{ 15 | Print out the structure of a ggvis object in a friendly format 16 | } 17 | -------------------------------------------------------------------------------- /man/export_png.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/export.R 3 | \name{export_png} 4 | \alias{export_png} 5 | \alias{export_svg} 6 | \title{Export a PNG or SVG from a ggvis object} 7 | \usage{ 8 | export_png(vis, file = NULL) 9 | 10 | export_svg(vis, file = NULL) 11 | } 12 | \arguments{ 13 | \item{vis}{A ggvis object.} 14 | 15 | \item{file}{Output file name. If NULL, defaults to "plot.svg" or "plot.png".} 16 | } 17 | \description{ 18 | This requires that the external program \code{vg2png} is installed. This is 19 | part of the \code{vega} node.js module. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | mtcars \%>\% ggvis(x = ~wt) \%>\% export_png() 24 | } 25 | } 26 | \seealso{ 27 | \url{https://github.com/trifacta/vega} for information on installing 28 | \code{vg2png} and \code{vg2svg}. 29 | } 30 | -------------------------------------------------------------------------------- /man/fullseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/full_seq.R 3 | \name{fullseq} 4 | \alias{fullseq} 5 | \title{Generate sequence of fixed size intervals covering range.} 6 | \usage{ 7 | fullseq(range, size, ...) 8 | } 9 | \arguments{ 10 | \item{range}{range} 11 | 12 | \item{size}{interval size} 13 | 14 | \item{...}{other arguments passed on to methods} 15 | } 16 | \description{ 17 | Generate sequence of fixed size intervals covering range. 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/get_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils_data.R 3 | \name{get_data} 4 | \alias{get_data} 5 | \title{Get data from a ggvis object} 6 | \usage{ 7 | get_data(vis) 8 | } 9 | \arguments{ 10 | \item{vis}{A ggvis object.} 11 | } 12 | \description{ 13 | This function is useful for inspecting the data in a ggvis object. 14 | } 15 | \examples{ 16 | p <- cocaine \%>\% ggvis(~price) \%>\% layer_bars() 17 | get_data(p) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /man/ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{ggvis} 4 | \alias{ggvis} 5 | \title{Visualise a data set with a ggvis graphic.} 6 | \usage{ 7 | ggvis(data = NULL, ..., env = parent.frame()) 8 | } 9 | \arguments{ 10 | \item{data}{A data object.} 11 | 12 | \item{...}{Property mappings. If not named, the first two mappings are 13 | taken to be \code{x} and \code{y}. Common properties are \code{x}, 14 | \code{y}, \code{stroke}, \code{fill}, \code{opacity}, \code{shape}} 15 | 16 | \item{env}{Environment in which to evaluate properties.} 17 | } 18 | \description{ 19 | \code{ggvis} is used to turn a dataset into a visualisation, setting up 20 | default mappings between variables in the dataset and visual properties. 21 | Nothing will be displayed until you add additional layers. 22 | } 23 | \examples{ 24 | # If you don't supply a layer, ggvis uses layer_guess() to guess at 25 | # an appropriate type: 26 | mtcars \%>\% ggvis(~mpg, ~wt) 27 | mtcars \%>\% ggvis(~mpg, ~wt, fill = ~cyl) 28 | mtcars \%>\% ggvis(~mpg, ~wt, fill := "red") 29 | mtcars \%>\% ggvis(~mpg) 30 | 31 | # ggvis has a functional interface: every ggvis function takes a ggvis 32 | # an input and returns a modified ggvis as output. 33 | layer_points(ggvis(mtcars, ~mpg, ~wt)) 34 | 35 | # To make working with this interface more natural, ggvis imports the 36 | # pipe operator from magrittr. x \%>\% f(y) is equivalent to f(x, y) so 37 | # we can rewrite the previous command as 38 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() 39 | 40 | # For more complicated plots, add a line break after \%>\% 41 | mtcars \%>\% 42 | ggvis(~mpg, ~wt) \%>\% 43 | layer_points() \%>\% 44 | layer_smooths() 45 | } 46 | -------------------------------------------------------------------------------- /man/ggvisControlOutput.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny_layout.R 3 | \name{ggvisControlOutput} 4 | \alias{ggvisControlOutput} 5 | \title{Create a ggvis control output element in UI} 6 | \usage{ 7 | ggvisControlOutput(outputId, plotId = NULL) 8 | } 9 | \arguments{ 10 | \item{outputId}{The output variable to read the value from.} 11 | 12 | \item{plotId}{An optional plot ID or vector of plot IDs. The plots will 13 | have their .onControlOutput functions called after the controls are drawn.} 14 | } 15 | \description{ 16 | This is effectively the same as \code{\link[shiny]{uiOutput}}, except that 17 | on the client side it may call some plot resizing functions after new 18 | controls are drawn. 19 | } 20 | \details{ 21 | \code{ggvisControlOutput} is intended to be used with 22 | \code{\link{bind_shiny}} on the server side. 23 | } 24 | \examples{ 25 | ggvisControlOutput("plot1") 26 | } 27 | -------------------------------------------------------------------------------- /man/ggvisOutputElements.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny_layout.R 3 | \name{ggvisOutputElements} 4 | \alias{ggvisOutputElements} 5 | \title{Create HTML elements for ggvis output} 6 | \usage{ 7 | ggvisOutputElements(plot_id = rand_id("plot_id"), spec = NULL, shiny = TRUE) 8 | } 9 | \arguments{ 10 | \item{plot_id}{Unique identifier to use for the div containing the ggvis plot.} 11 | 12 | \item{spec}{Plot specification, used internally.} 13 | 14 | \item{shiny}{Should this include headers for Shiny? For dynamic and 15 | interactive plots, this should be TRUE; otherwise FALSE.} 16 | } 17 | \description{ 18 | This is an internal-facing function similar to ggvisOutput, but with more 19 | options. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/ggvis_message.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/message.R 3 | \name{ggvis_message} 4 | \alias{ggvis_message} 5 | \title{Send a message to ggvis running on client} 6 | \usage{ 7 | ggvis_message(session, type, data = NULL, id = NULL) 8 | } 9 | \arguments{ 10 | \item{session}{A session object.} 11 | 12 | \item{type}{A string representing the type of the message.} 13 | 14 | \item{data}{An object (typically a list) containing information for the client.} 15 | 16 | \item{id}{A unique identifier for ggvis message handler (optional).} 17 | } 18 | \description{ 19 | This will be sent to the client and passed to a handler in ggvis.messages on 20 | the client side. The handler is specified by \code{type}. 21 | } 22 | -------------------------------------------------------------------------------- /man/group_by.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr.R 3 | \name{group_by} 4 | \alias{group_by} 5 | \title{Divide data into groups.} 6 | \arguments{ 7 | \item{x}{a visualisation} 8 | 9 | \item{...}{variables to group by.} 10 | 11 | \item{add}{By default, when \code{add = FALSE}, \code{group_by} will 12 | override existing groups. To instead add to the existing groups, 13 | use \code{add = TRUE}} 14 | } 15 | \description{ 16 | Divide data into groups. 17 | } 18 | -------------------------------------------------------------------------------- /man/handle_brush.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/handle_brush.R 3 | \name{handle_brush} 4 | \alias{handle_brush} 5 | \title{Handle brush events on a visualisation.} 6 | \usage{ 7 | handle_brush(vis, on_move = NULL, fill = "black") 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to listen to.} 11 | 12 | \item{on_move}{Callback function with arguments: 13 | \describe{ 14 | \item{items}{A data frame containing information about the items 15 | under the plot. An empty data.frame if no points under the brush.} 16 | \item{page_loc}{Location of the brush with repsect to the page} 17 | \item{plot_loc}{Location of the brush with respect to the plot} 18 | \item{session}{The session, used to communicate with the browser} 19 | }} 20 | 21 | \item{fill}{Colour of the brush.} 22 | } 23 | \description{ 24 | Currently for brush events to be triggered on a visualisation, you must 25 | use a \code{.brush} property. This limitation will be lifted in the future. 26 | } 27 | \examples{ 28 | # Display tooltip when objects are brushed 29 | mtcars \%>\% 30 | ggvis(x = ~wt, y = ~mpg, size.brush := 400) \%>\% 31 | layer_points() \%>\% 32 | handle_brush(function(items, page_loc, session, ...) { 33 | show_tooltip(session, page_loc$r + 5, page_loc$t, html = nrow(items)) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /man/handle_click.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/handle_click.R 3 | \name{handle_click} 4 | \alias{handle_click} 5 | \alias{handle_hover} 6 | \title{Handle mouse actions on marks.} 7 | \usage{ 8 | handle_click(vis, on_click = NULL) 9 | 10 | handle_hover(vis, on_mouse_over = NULL, on_mouse_out = NULL) 11 | } 12 | \arguments{ 13 | \item{vis}{Visualisation to listen to.} 14 | 15 | \item{on_click, on_mouse_over}{Callback function with arguments: 16 | \describe{ 17 | \item{data}{A data frame with one row} 18 | \item{location}{A named list with components x and y} 19 | \item{session}{The session, used to communicate with the browser} 20 | }} 21 | 22 | \item{on_mouse_out}{Callback function with argument: 23 | \describe{ 24 | \item{session}{The session, used to communicate with the browser} 25 | }} 26 | } 27 | \description{ 28 | Handle mouse actions on marks. 29 | } 30 | \examples{ 31 | location <- function(location, ...) cat(location$x, "x", location$y, "\n") 32 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() \%>\% 33 | handle_click(location) 34 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() \%>\% 35 | handle_hover(function(...) cat("over\n"), function(...) cat("off\n")) 36 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() \%>\% 37 | handle_hover(function(data, ...) str(data)) 38 | } 39 | -------------------------------------------------------------------------------- /man/handle_resize.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/handle_resize.R 3 | \name{handle_resize} 4 | \alias{handle_resize} 5 | \alias{plot_width} 6 | \alias{plot_height} 7 | \title{Handlers and interactive inputs for plot sizing.} 8 | \usage{ 9 | handle_resize(vis, on_resize) 10 | 11 | plot_width(vis) 12 | 13 | plot_height(vis) 14 | } 15 | \arguments{ 16 | \item{vis}{Visualisation to listen to.} 17 | 18 | \item{on_resize}{Callback function with arguments: 19 | \describe{ 20 | \item{width,height}{Width and height in pixels} 21 | \item{padding}{A named list of four components giving the padding in 22 | each direction} 23 | \item{session}{The session, used to communicate with the browser} 24 | }} 25 | } 26 | \description{ 27 | Handlers and interactive inputs for plot sizing. 28 | } 29 | \examples{ 30 | # This example just prints out the current dimensions to the console 31 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% 32 | layer_points() \%>\% 33 | handle_resize(function(width, height, ...) cat(width, "x", height, "\n")) 34 | 35 | # Use plot_width() and plot_height() to dynamically get the plot size 36 | # inside the plot. 37 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_text(text := plot_width()) 38 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_text(text := plot_height()) 39 | } 40 | -------------------------------------------------------------------------------- /man/input_checkbox.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/inputs.R 3 | \name{input_checkbox} 4 | \alias{input_checkbox} 5 | \title{Create an interactive checkbox.} 6 | \usage{ 7 | input_checkbox( 8 | value = FALSE, 9 | label = "", 10 | id = rand_id("checkbox_"), 11 | map = identity 12 | ) 13 | } 14 | \arguments{ 15 | \item{value}{Initial value (\code{TRUE} or \code{FALSE}).} 16 | 17 | \item{label}{Display label for the control, or \code{NULL} for no label.} 18 | 19 | \item{id}{A unique identifier for this input. Usually generated 20 | automatically.} 21 | 22 | \item{map}{A function with single argument \code{x}, the value of the 23 | control on the client. Returns a modified value.} 24 | } 25 | \description{ 26 | Create an interactive checkbox. 27 | } 28 | \examples{ 29 | 30 | input_checkbox(label = "Confidence interval") 31 | input_checkbox(label = "Confidence interval", value = TRUE) 32 | 33 | # Used in layer_smooths 34 | mtcars \%>\% ggvis(~wt, ~mpg) \%>\% 35 | layer_smooths(se = input_checkbox(label = "Confidence interval")) 36 | 37 | # Used with a map function, to convert the boolean to another type of value 38 | model_type <- input_checkbox(label = "Use flexible curve", 39 | map = function(val) if(val) "loess" else "lm") 40 | mtcars \%>\% ggvis(~wt, ~mpg) \%>\% 41 | layer_model_predictions(model = model_type) 42 | } 43 | \seealso{ 44 | Other interactive input: 45 | \code{\link{input_select}()}, 46 | \code{\link{input_slider}()}, 47 | \code{\link{input_text}()} 48 | } 49 | \concept{interactive input} 50 | -------------------------------------------------------------------------------- /man/input_text.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/inputs.R 3 | \name{input_text} 4 | \alias{input_text} 5 | \alias{input_numeric} 6 | \title{Create an interactive text or numeric input box.} 7 | \usage{ 8 | input_text(value, label = "", id = rand_id("text_"), map = identity) 9 | 10 | input_numeric(value, label = "", id = rand_id("numeric_"), map = identity) 11 | } 12 | \arguments{ 13 | \item{value}{Initial value.} 14 | 15 | \item{label}{Display label for the control, or \code{NULL} for no label.} 16 | 17 | \item{id}{A unique identifier for this input. Usually generated 18 | automatically.} 19 | 20 | \item{map}{A function with single argument \code{x}, the value of the 21 | control on the client. Returns a modified value.} 22 | } 23 | \description{ 24 | \code{input_numeric} only allows numbers and comes with a spin box control. 25 | \code{input_text} allows any type of input. 26 | } 27 | \examples{ 28 | fill_text <- input_text(label = "Point color", value = "red") 29 | mtcars \%>\% ggvis(~wt, ~mpg, fill := fill_text) \%>\% layer_bars() 30 | 31 | size_num <- input_numeric(label = "Point size", value = 25) 32 | mtcars \%>\% ggvis(~wt, ~mpg, size := size_num) \%>\% layer_points() 33 | } 34 | \seealso{ 35 | Other interactive input: 36 | \code{\link{input_checkbox}()}, 37 | \code{\link{input_select}()}, 38 | \code{\link{input_slider}()} 39 | } 40 | \concept{interactive input} 41 | -------------------------------------------------------------------------------- /man/is.axis_props.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{is.axis_props} 4 | \alias{is.axis_props} 5 | \title{Tests whether an object is an axis_props object} 6 | \usage{ 7 | is.axis_props(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to test} 11 | } 12 | \description{ 13 | Tests whether an object is an axis_props object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/is.broker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/broker.R 3 | \name{is.broker} 4 | \alias{is.broker} 5 | \title{Determine if an object is a broker object} 6 | \usage{ 7 | is.broker(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object to test.} 11 | } 12 | \description{ 13 | Determine if an object is a broker object 14 | } 15 | -------------------------------------------------------------------------------- /man/is.dynamic.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{is.dynamic} 4 | \alias{is.dynamic} 5 | \title{Determine if an ggvis is dynamic (i.e. needs to be run in a shiny app)} 6 | \usage{ 7 | is.dynamic(x) 8 | } 9 | \description{ 10 | Determine if an ggvis is dynamic (i.e. needs to be run in a shiny app) 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/is.ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{is.ggvis} 4 | \alias{is.ggvis} 5 | \title{Is an object a ggvis object?} 6 | \usage{ 7 | is.ggvis(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to test} 11 | } 12 | \description{ 13 | Is an object a ggvis object? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/is.legend_props.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{is.legend_props} 4 | \alias{is.legend_props} 5 | \title{Tests whether an object is a legend_props object} 6 | \usage{ 7 | is.legend_props(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to test} 11 | } 12 | \description{ 13 | Tests whether an object is a legend_props object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/is.scaled_value.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{is.scaled_value} 4 | \alias{is.scaled_value} 5 | \title{Tests whether an object is a scaled_value object} 6 | \usage{ 7 | is.scaled_value(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to test} 11 | } 12 | \description{ 13 | Tests whether an object is a scaled_value object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/knit_print.ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{knit_print.ggvis} 4 | \alias{knit_print.ggvis} 5 | \title{Knit print method for ggvis plots.} 6 | \usage{ 7 | knit_print.ggvis(x, options = list(), inline = FALSE, ...) 8 | } 9 | \description{ 10 | Knit print method for ggvis plots. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/layer_boxplots.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer_boxplots.R 3 | \name{layer_boxplots} 4 | \alias{layer_boxplots} 5 | \title{Display data with a boxplot.} 6 | \usage{ 7 | layer_boxplots(vis, ..., coef = 1.5, width = NULL) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to modify} 11 | 12 | \item{...}{Visual properties used to override defaults.} 13 | 14 | \item{coef}{The maximum length of the whiskers as multiple of the 15 | inter-quartile range. Default value is 1.5.} 16 | 17 | \item{width}{Width of each bar. When x is continuous, this controls the width 18 | in the same units as x. When x is categorical, this controls the width as a 19 | proportion of the spacing between items (default is 0.9).} 20 | } 21 | \description{ 22 | This will add boxplots to a plot. The action of \code{layer_boxplots} depends 23 | on whether the \code{x} prop is continuous or categorical. 24 | } 25 | \details{ 26 | The upper and lower "hinges" correspond to the first and third quartiles (the 27 | 25th and 75th percentiles). This differs slightly from the method used by the 28 | \code{boxplot} function, and may be apparent with small samples. See 29 | \code{\link{boxplot.stats}} for more information on how hinge positions are 30 | calculated for \code{boxplot}. 31 | 32 | The upper whisker extends from the hinge to the highest value that is within 33 | 1.5 * IQR of the hinge, where IQR is the inter-quartile range, or distance 34 | between the first and third quartiles. The lower whisker extends from the 35 | hinge to the lowest value within 1.5 * IQR of the hinge. Data beyond the end 36 | of the whiskers are outliers and plotted as points (as specified by Tukey). 37 | } 38 | \examples{ 39 | library(dplyr) 40 | 41 | mtcars \%>\% ggvis(~factor(cyl), ~mpg) \%>\% layer_boxplots() 42 | # Set the width of the boxes to half the space between tick marks 43 | mtcars \%>\% ggvis(~factor(cyl), ~mpg) \%>\% layer_boxplots(width = 0.5) 44 | 45 | # Continuous x: boxes fill width between data values 46 | mtcars \%>\% ggvis(~cyl, ~mpg) \%>\% layer_boxplots() 47 | # Setting width=0.5 makes it 0.5 wide in the data space, which is 1/4 of the 48 | # distance between data values in this particular case. 49 | mtcars \%>\% ggvis(~cyl, ~mpg) \%>\% layer_boxplots(width = 0.5) 50 | 51 | # Smaller outlier points 52 | mtcars \%>\% ggvis(~factor(cyl), ~mpg) \%>\% layer_boxplots(size := 20) 53 | } 54 | \seealso{ 55 | \code{\link{compute_boxplot}} for more information on how data is 56 | transformed. 57 | } 58 | -------------------------------------------------------------------------------- /man/layer_densities.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer_densities.R 3 | \name{layer_densities} 4 | \alias{layer_densities} 5 | \title{Transformation: density estimate} 6 | \usage{ 7 | layer_densities( 8 | vis, 9 | ..., 10 | kernel = "gaussian", 11 | adjust = 1, 12 | density_args = list(), 13 | area = TRUE 14 | ) 15 | } 16 | \arguments{ 17 | \item{vis}{The visualisation to modify} 18 | 19 | \item{...}{Visual properties, passed on to \code{\link{props}}.} 20 | 21 | \item{kernel}{Smoothing kernel. See \code{\link{density}} for details.} 22 | 23 | \item{adjust}{Multiple the default bandwidth by this amount. Useful for 24 | controlling wiggliness of density.} 25 | 26 | \item{density_args}{Other arguments passed on to 27 | \code{\link{compute_density}} and thence to \code{\link{density}}.} 28 | 29 | \item{area}{Should there be a shaded region drawn under the curve?} 30 | } 31 | \description{ 32 | \code{transform_density} is a data transformation that computes a kernel 33 | density estimate from a dataset. \code{layer_density} combines 34 | \code{transform_density} with \code{mark_path} and \code{mark_area} 35 | to display a smooth line and its standard errror. 36 | } 37 | \examples{ 38 | # Basic density estimate 39 | faithful \%>\% ggvis(~waiting) \%>\% layer_densities() 40 | faithful \%>\% ggvis(~waiting) \%>\% layer_densities(area = FALSE) 41 | 42 | # Control bandwidth with adjust 43 | faithful \%>\% ggvis(~waiting) \%>\% layer_densities(adjust = .25) 44 | faithful \%>\% ggvis(~waiting) \%>\% 45 | layer_densities(adjust = input_slider(0.1, 5)) 46 | 47 | # Control stroke and fill 48 | faithful \%>\% ggvis(~waiting) \%>\% 49 | layer_densities(stroke := "red", fill := "red") 50 | 51 | # With groups 52 | PlantGrowth \%>\% ggvis(~weight, fill = ~group) \%>\% group_by(group) \%>\% 53 | layer_densities() 54 | PlantGrowth \%>\% ggvis(~weight, stroke = ~group) \%>\% group_by(group) \%>\% 55 | layer_densities(strokeWidth := 3, area = FALSE) 56 | } 57 | -------------------------------------------------------------------------------- /man/layer_f.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer.R 3 | \name{layer_f} 4 | \alias{layer_f} 5 | \title{Create a new layering function.} 6 | \usage{ 7 | layer_f(vis, fun) 8 | } 9 | \arguments{ 10 | \item{vis}{The ggvis visualisation to modify.} 11 | 12 | \item{fun}{A function that takes a single argument, the current 13 | visualisation as input, and returns a modified visualisation.} 14 | } 15 | \description{ 16 | The layer function is run, and then the state before the code was run 17 | is restored - this allows layers to be effectively isolated from 18 | the rest of the plot. 19 | } 20 | \examples{ 21 | mtcars \%>\% ggvis(~mpg) \%>\% 22 | layer_f(function(v) { 23 | v \%>\% compute_bin(~mpg) \%>\% layer_points(x = ~x_, y = ~count_) 24 | }) \%>\% 25 | layer_points(y = ~wt) 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /man/layer_guess.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer_guess.R 3 | \name{layer_guess} 4 | \alias{layer_guess} 5 | \title{Guess the right type of layer based on current properties.} 6 | \usage{ 7 | layer_guess(vis, ...) 8 | } 9 | \arguments{ 10 | \item{vis}{The visualisation to add the new layer to.} 11 | 12 | \item{...}{Other arguments passed on individual layers.} 13 | } 14 | \description{ 15 | \code{layer_guess} provides the magic behind the default behaviour of 16 | \code{\link{ggvis}}. 17 | } 18 | \section{Defaults}{ 19 | 20 | 21 | \itemize{ 22 | \item Continuous x, \code{\link{layer_histograms}} 23 | \item Categorical x, \code{\link{layer_bars}} 24 | \item Continuous x and y, \code{\link{layer_points}} 25 | } 26 | } 27 | 28 | \examples{ 29 | # A scatterplot: 30 | mtcars \%>\% ggvis(~mpg, ~wt) 31 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_guess() 32 | 33 | # A histogram: 34 | mtcars \%>\% ggvis(~mpg) 35 | mtcars \%>\% ggvis(~mpg) \%>\% layer_guess() 36 | } 37 | -------------------------------------------------------------------------------- /man/layer_lines.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer_lines.R 3 | \name{layer_lines} 4 | \alias{layer_lines} 5 | \title{Layer lines on a plot.} 6 | \usage{ 7 | layer_lines(vis, ...) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to modify.} 11 | 12 | \item{...}{Visual properties.} 13 | } 14 | \description{ 15 | \code{layer_lines} differs from \code{layer_paths} in that \code{layer_lines} 16 | sorts the data on the x variable, so the line will always proceed from left 17 | to right, whereas \code{layer_paths} will draw a line in whatever order 18 | appears in the data. 19 | } 20 | \examples{ 21 | mtcars \%>\% ggvis(~wt, ~mpg, stroke = ~factor(cyl)) \%>\% layer_lines() 22 | 23 | # Equivalent to 24 | mtcars \%>\% ggvis(~wt, ~mpg, stroke = ~factor(cyl)) \%>\% 25 | group_by(cyl) \%>\% dplyr::arrange(wt) \%>\% layer_paths() 26 | } 27 | \seealso{ 28 | \code{\link{layer_paths}} 29 | } 30 | -------------------------------------------------------------------------------- /man/left_right.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/handle_keyboard.R 3 | \name{left_right} 4 | \alias{left_right} 5 | \alias{up_down} 6 | \title{Interactive inputs bound to arrow keys.} 7 | \usage{ 8 | left_right(min, max, value = (min + max)/2, step = (max - min)/40) 9 | 10 | up_down(min, max, value = (min + max)/2, step = (max - min)/40) 11 | } 12 | \arguments{ 13 | \item{min}{A minimum value.} 14 | 15 | \item{max}{A maximum value.} 16 | 17 | \item{value}{The initial value before any keys are pressed. Defaults to 18 | half-way between \code{min} and \code{max}.} 19 | 20 | \item{step}{How much each key press changes \code{value}. Defaults to 21 | 40 steps along range} 22 | } 23 | \description{ 24 | Interactive inputs bound to arrow keys. 25 | } 26 | \examples{ 27 | size <- left_right(1, 801, value = 51, step = 50) 28 | opacity <- up_down(0, 1, value = 0.9, step = 0.05) 29 | 30 | mtcars \%>\% ggvis(~mpg, ~wt, size := size, opacity := opacity) \%>\% 31 | layer_points() 32 | } 33 | -------------------------------------------------------------------------------- /man/legend_props.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{legend_props} 4 | \alias{legend_props} 5 | \title{Create an axis_props object for controlling legend properties.} 6 | \usage{ 7 | legend_props( 8 | title = NULL, 9 | labels = NULL, 10 | symbols = NULL, 11 | gradient = NULL, 12 | legend = NULL 13 | ) 14 | } 15 | \arguments{ 16 | \item{title}{A named list of text properties for the legend title.} 17 | 18 | \item{labels}{A named list of text properties for legend labels.} 19 | 20 | \item{symbols}{A named list of line properties for symbols (for discrete 21 | legend items).} 22 | 23 | \item{gradient}{A named list of line properties a continuous color gradient.} 24 | 25 | \item{legend}{A named list of line properties for the overall legend. The 26 | x and y position can be set here, which will override automatic 27 | positioning.} 28 | } 29 | \description{ 30 | The items in each of the lists can be a literal value, like \code{5} or 31 | "blue", or they can be a \code{\link{scaled_value}} object. 32 | } 33 | -------------------------------------------------------------------------------- /man/linked_brush.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/linked_brush.R 3 | \name{linked_brush} 4 | \alias{linked_brush} 5 | \title{Create a linked brush object.} 6 | \usage{ 7 | linked_brush(keys, fill = "red") 8 | } 9 | \arguments{ 10 | \item{keys}{vector of all possible keys, if known.} 11 | 12 | \item{fill}{brush colour} 13 | } 14 | \value{ 15 | A list with components: 16 | \item{input}{A function that takes a visualisation as an argument and 17 | adds an input brush to that plot} 18 | \item{selected}{A reactive providing a logical vector that describes 19 | which points are under the brush} 20 | \item{fill}{A reactive that gives the fill colour of points under the 21 | brush} 22 | } 23 | \description{ 24 | A linked brush has two sides: input and output 25 | } 26 | \note{ 27 | \code{linked_brush} is very new and is likely to change substantially 28 | in the future 29 | } 30 | \examples{ 31 | lb <- linked_brush(keys = 1:nrow(mtcars), "red") 32 | 33 | # Change the colour of the points 34 | mtcars \%>\% 35 | ggvis(~disp, ~mpg) \%>\% 36 | layer_points(fill := lb$fill, size.brush := 400) \%>\% 37 | lb$input() 38 | 39 | # Display one layer with all points and another layer with selected points 40 | library(shiny) 41 | mtcars \%>\% 42 | ggvis(~disp, ~mpg) \%>\% 43 | layer_points(size.brush := 400) \%>\% 44 | lb$input() \%>\% 45 | layer_points(fill := "red", data = reactive(mtcars[lb$selected(), ])) 46 | } 47 | -------------------------------------------------------------------------------- /man/mark.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mark.R 3 | \name{mark} 4 | \alias{mark} 5 | \alias{is.mark} 6 | \title{Create a new "mark" object.} 7 | \usage{ 8 | mark(type, props, data) 9 | 10 | is.mark(x) 11 | } 12 | \arguments{ 13 | \item{type}{A string with the vega type.} 14 | 15 | \item{props}{A list of properties, created by \code{\link{props}}.} 16 | 17 | \item{data}{A reactive data object.} 18 | } 19 | \description{ 20 | A mark object is a close mapping to a vega mark object. Vega marks 21 | are documented in \url{https://vega.github.io/vega/docs/marks/}. 22 | } 23 | \details{ 24 | This function is designed to be used by authors of new types of mark. 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/new_prop.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/prop.R 3 | \name{new_prop} 4 | \alias{new_prop} 5 | \title{Create new prop object} 6 | \usage{ 7 | new_prop(x, property, scale, offset, mult, env, event, label) 8 | } 9 | \description{ 10 | The resulting object has the following fields: 11 | } 12 | \details{ 13 | \itemize{ 14 | \item property The name of a visual property, like "x", "x2", "width", "y", 15 | "fill". 16 | \item value A value. Can be a constant, reactive, or quoted expression. 17 | \item scale A string with name of a scale. Typically something like "x", 18 | "y", "fill", but can also be a custom name like "foo". 19 | \item offset Additive pixel offset used to adjust scaled values. 20 | \item mult Multiplicative pixel offset used to adjust scaled values. 21 | \item event A event like "update", "enter", "exit", "hover", "brush". 22 | \item env An environment in which to evaluate a variable or reactive value. 23 | } 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/padding.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{padding} 4 | \alias{padding} 5 | \title{Define padding.} 6 | \usage{ 7 | padding(top = NULL, right = NULL, bottom = NULL, left = NULL) 8 | } 9 | \arguments{ 10 | \item{top, right, bottom, left}{Amount of padding on each border. Can either 11 | be a single number, "auto", or "strict"} 12 | } 13 | \description{ 14 | Define padding. 15 | } 16 | \examples{ 17 | p <- mtcars \%>\% ggvis(~wt, ~mpg) \%>\% layer_points() 18 | p \%>\% set_options(padding = padding()) 19 | p \%>\% set_options(padding = padding(10, 10, 10, 10)) 20 | } 21 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe graphics} 6 | \arguments{ 7 | \item{lhs, rhs}{A visualisation and a function to apply to it} 8 | } 9 | \description{ 10 | Like dplyr, ggvis also uses the pipe function, \code{\%>\%} to turn 11 | function composition into a series of imperative statements. 12 | } 13 | \examples{ 14 | # Instead of 15 | layer_points(ggvis(mtcars, ~mpg, ~wt)) 16 | # you can write 17 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() 18 | } 19 | -------------------------------------------------------------------------------- /man/print.ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{print.ggvis} 4 | \alias{print.ggvis} 5 | \alias{view_static} 6 | \alias{view_dynamic} 7 | \title{View in a ggvis plot in the browser.} 8 | \usage{ 9 | \method{print}{ggvis}(x, dynamic = NA, launch = interactive(), ...) 10 | 11 | view_static(x, plot_id = rand_id("plot_"), dest = NULL) 12 | 13 | view_dynamic(x, plot_id = rand_id("plot_"), port = NULL, quiet = FALSE) 14 | } 15 | \arguments{ 16 | \item{x}{A ggvis object.} 17 | 18 | \item{dynamic}{Uses \code{view_dynamic} if \code{TRUE}, \code{view_static} if 19 | \code{FALSE}. The default, \code{NA}, chooses automatically based on the 20 | presence of reactives or interactive inputs in \code{x}.} 21 | 22 | \item{launch}{If \code{TRUE}, will launch plot in a viewer/browser. If 23 | \code{FALSE} returns an object that you can \code{print()} to launch.} 24 | 25 | \item{...}{Other arguments passed on to \code{view_dynamic} and 26 | \code{view_static} ?from \code{print}.} 27 | 28 | \item{plot_id}{Unique identifier used to identify the plot on the page.} 29 | 30 | \item{dest}{Deprecated (this no longer works).} 31 | 32 | \item{port}{the port on which to start the shiny app. If NULL (the default), 33 | Shiny will select a random port.} 34 | 35 | \item{quiet}{If \code{TRUE} show status messages from Shiny. (Default is 36 | \code{FALSE}.)} 37 | } 38 | \description{ 39 | \code{view_static} creates a static web page in a temporary directory; 40 | \code{view_dynamic} generate a dynamic shiny app and launches it. 41 | \code{print} automatically picks between the two. 42 | } 43 | \details{ 44 | If \code{view_static} is used on a ggvis object that has dynamic components, 45 | it will output a static plot. 46 | } 47 | \examples{ 48 | ## Run these examples only in interactive R sessions 49 | if (interactive()) { 50 | # In most cases view_static is unnecessary; these will do the same thing: 51 | mtcars \%>\% ggvis(~wt, ~mpg) 52 | mtcars \%>\% ggvis(~wt, ~mpg) \%>\% view_static() 53 | 54 | # Can find the output file with view_static() and html_print() 55 | outfile <- mtcars \%>\% ggvis(~wt, ~mpg) \%>\% 56 | view_static() \%>\% htmltools::html_print(viewer = NULL) 57 | } 58 | } 59 | \keyword{internal} 60 | -------------------------------------------------------------------------------- /man/prop.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/prop.R 3 | \name{prop} 4 | \alias{prop} 5 | \alias{is.prop} 6 | \alias{is.prop_constant} 7 | \alias{is.prop_variable} 8 | \alias{is.prop_reactive} 9 | \title{Create a property.} 10 | \usage{ 11 | prop( 12 | property, 13 | x, 14 | scale = NULL, 15 | offset = NULL, 16 | mult = NULL, 17 | env = parent.frame(), 18 | event = NULL, 19 | label = NULL 20 | ) 21 | 22 | is.prop(x) 23 | 24 | is.prop_constant(x) 25 | 26 | is.prop_variable(x) 27 | 28 | is.prop_reactive(x) 29 | } 30 | \arguments{ 31 | \item{property}{A property, like "x", "x2", "y", "fill", and so on.} 32 | 33 | \item{x}{The value of the property. This can be an atomic vector 34 | (a constant), a name or quoted call (a variable), a single-sided 35 | formula (a constant or variable depending on its contents), or a delayed 36 | reactive (which can be either variable or constant).} 37 | 38 | \item{scale}{If \code{NULL}, automatically determine behavior by the kind of 39 | value (constant, variable, or reactive). 40 | If \code{TRUE} use the default scale associated with property. 41 | If \code{FALSE}, do not scale the value. 42 | Otherwise supply a string to select a custom scale. 43 | If \code{x} is an interactive input, then this defaults to the scale 44 | parameter of the input.} 45 | 46 | \item{offset, mult}{Additive and multiplicate pixel offset used to adjust 47 | scaled values. These are useful if you want to place labels offset from 48 | points.} 49 | 50 | \item{env}{If \code{x} is a quoted call this provides the environment in 51 | which to look for variables not in the data. You should not need this in 52 | ordinary operation.} 53 | 54 | \item{event}{An event to which this property applies. One of "update", 55 | "enter", "exit", "hover", "brush".} 56 | 57 | \item{label}{A label for this prop to use for reporting errors.} 58 | } 59 | \description{ 60 | Properties are used to describe the visual properties of \link{marks}. 61 | You create a single property defintion with \code{prop}, and manage 62 | sets of named properties with \code{\link{props}} (which also provides 63 | shortcuts for creating the most common kind of properties) 64 | } 65 | \examples{ 66 | prop("x", 1) 67 | prop("x", ~1) 68 | prop("fill", quote(cyl)) 69 | prop("fill", ~cyl) 70 | prop("x", input_slider(0, 100)) 71 | 72 | # If you have a variable name as a string 73 | var <- "cyl" 74 | prop("x", as.name(var)) 75 | 76 | # Use a custom scale 77 | prop("y", quote(cyl), scale = "y-2") 78 | 79 | # Don't scale variable (i.e. it already makes sense in the visual space) 80 | prop("fill", ~colour, scale = FALSE) 81 | 82 | # Use a constant, but scaled 83 | prop("x", 5, scale = TRUE) 84 | 85 | # Use other events 86 | prop("y", quote(cyl), scale = "y-2") 87 | 88 | } 89 | \seealso{ 90 | \code{\link{props}} to manage multiple properties and to 91 | succintly create the most common types. 92 | } 93 | -------------------------------------------------------------------------------- /man/prop_domain.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/prop.R 3 | \name{prop_domain} 4 | \alias{prop_domain} 5 | \title{Property domain.} 6 | \usage{ 7 | prop_domain(x, data) 8 | } 9 | \arguments{ 10 | \item{x}{property to dispatch on} 11 | 12 | \item{data}{name of data set} 13 | } 14 | \description{ 15 | Property domain. 16 | } 17 | -------------------------------------------------------------------------------- /man/propname_to_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale.R 3 | \name{propname_to_scale} 4 | \alias{propname_to_scale} 5 | \title{Convert the name of a property to the name of its default scale.} 6 | \usage{ 7 | propname_to_scale(prop) 8 | } 9 | \arguments{ 10 | \item{prop}{character vector of property names. Any unrecognised names 11 | are left unchanged.} 12 | } 13 | \value{ 14 | character vector of default scale names. 15 | } 16 | \description{ 17 | This is mainly used to ensure that similar properties share the same 18 | scale by default - e.g. \code{x} and \code{x2} should use the same 19 | scale. 20 | } 21 | \examples{ 22 | propname_to_scale(c("x", "x2")) 23 | propname_to_scale(c("foo", "bar")) 24 | propname_to_scale(c("opacity", "fillOpacity", "strokeOpacity")) 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/resolution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils_resolution.R 3 | \name{resolution} 4 | \alias{resolution} 5 | \title{Compute the "resolution" of a data vector.} 6 | \usage{ 7 | resolution(x, zero = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{numeric vector} 11 | 12 | \item{zero}{should a zero value be automatically included in the 13 | computation of resolution} 14 | } 15 | \description{ 16 | The resolution is is the smallest non-zero distance between adjacent 17 | values. If there is only one unique value, then the resolution is defined 18 | to be one. 19 | } 20 | \details{ 21 | If x is an integer vector, then it is assumed to represent a discrete 22 | variable, and the resolution is 1. 23 | } 24 | \examples{ 25 | resolution(1:10) 26 | resolution((1:10) - 0.5) 27 | resolution((1:10) - 0.5, FALSE) 28 | resolution(c(1,2, 10, 20, 50)) 29 | resolution(as.integer(c(1, 10, 20, 50))) # Returns 1 30 | } 31 | -------------------------------------------------------------------------------- /man/save_spec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{save_spec} 4 | \alias{save_spec} 5 | \alias{view_spec} 6 | \title{Tools to save and view static specs.} 7 | \usage{ 8 | save_spec(x, path, ...) 9 | 10 | view_spec(path, ...) 11 | } 12 | \arguments{ 13 | \item{x}{a ggvis object} 14 | 15 | \item{path}{location to save spec to, or load spec from} 16 | 17 | \item{...}{other arguments passed to \code{as.vega}} 18 | } 19 | \description{ 20 | These functions are mainly useful for testing. 21 | } 22 | \keyword{internal} 23 | -------------------------------------------------------------------------------- /man/scaled_value.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guide_props.R 3 | \name{scaled_value} 4 | \alias{scaled_value} 5 | \title{Create a scaled_value object} 6 | \usage{ 7 | scaled_value(scale, value) 8 | } 9 | \arguments{ 10 | \item{scale}{The name of a scale, e.g., "x", "fill".} 11 | 12 | \item{value}{A value which will be transformed using the scale.} 13 | } 14 | \description{ 15 | These are for use with legends and axes. 16 | } 17 | -------------------------------------------------------------------------------- /man/scaletype_to_vega_scaletype.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale.R 3 | \name{scaletype_to_vega_scaletype} 4 | \alias{scaletype_to_vega_scaletype} 5 | \title{Given the type of a ggvis scale, get the name of its corresponding vega scale} 6 | \usage{ 7 | scaletype_to_vega_scaletype(type) 8 | } 9 | \arguments{ 10 | \item{type}{property type: numeric, ordinal, nominal, logical or datetime.} 11 | } 12 | \description{ 13 | Given the type of a ggvis scale, get the name of its corresponding vega scale 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/set_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{set_options} 4 | \alias{set_options} 5 | \title{Set options for a ggvis plot} 6 | \usage{ 7 | set_options( 8 | vis, 9 | width = NULL, 10 | height = NULL, 11 | keep_aspect = NULL, 12 | resizable = NULL, 13 | padding = NULL, 14 | duration = NULL, 15 | renderer = NULL, 16 | hover_duration = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{vis}{Visualisation to modify} 21 | 22 | \item{width, height}{Width and height of plot, in pixels. Default is 600x400. 23 | \code{width} or \code{height} can also be \code{"auto"}, in which case the 24 | plot will size to fit in the containing div. This is useful only in a Shiny 25 | app or custom HTML output. Note that \code{height="auto"} should only be 26 | used when the plot is placed within a div that has a fixed height; if not, 27 | automatic height will not work, due to the way that web browsers do 28 | vertical layout.} 29 | 30 | \item{keep_aspect}{Should the aspect ratio be preserved? The default value is 31 | \code{FALSE}, or the value of \code{getOption("ggvis.keep_aspect")}, if it 32 | is set.} 33 | 34 | \item{resizable}{If TRUE, allow the user to resize the plot. The default 35 | value is \code{TRUE}, or the value of \code{getOption("ggvis.resizable")}, 36 | if it is set. Not compatible when \code{width} or \code{height} is 37 | \code{"auto"}.} 38 | 39 | \item{padding}{A padding object specifying padding on the top, right, left, 40 | and bottom. See \code{\link{padding}}.} 41 | 42 | \item{duration}{Duration of transitions, in milliseconds.} 43 | 44 | \item{renderer}{The renderer to use in the browser. Can be \code{"canvas"} or 45 | \code{"svg"} (the default).} 46 | 47 | \item{hover_duration}{The amount of time for hover transitions, in 48 | milliseconds.} 49 | } 50 | \description{ 51 | Set options for a ggvis plot 52 | } 53 | \examples{ 54 | mtcars \%>\% 55 | ggvis(~wt, ~mpg) \%>\% 56 | layer_points() \%>\% 57 | set_options(width = 300, height = 200, padding = padding(10, 10, 10, 10)) 58 | 59 | # Display the default options 60 | str(default_options()) 61 | 62 | } 63 | \seealso{ 64 | \code{\link{getOption}} and \code{\link{options}}, for getting and 65 | setting global options. 66 | 67 | \code{\link{default_options}} to see the default options. 68 | } 69 | -------------------------------------------------------------------------------- /man/set_scale_label.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scales.R 3 | \name{set_scale_label} 4 | \alias{set_scale_label} 5 | \title{Set the label for a scale} 6 | \usage{ 7 | set_scale_label(vis, scale, label) 8 | } 9 | \arguments{ 10 | \item{vis}{A ggvis object.} 11 | 12 | \item{scale}{The name of a scale, like "x".} 13 | 14 | \item{label}{Text to use for the label.} 15 | } 16 | \description{ 17 | Set the label for a scale 18 | } 19 | -------------------------------------------------------------------------------- /man/shiny-ggvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny.R, R/shiny_layout.R 3 | \name{shiny-ggvis} 4 | \alias{shiny-ggvis} 5 | \alias{bind_shiny} 6 | \alias{bind_shiny_ui} 7 | \alias{ggvisOutput} 8 | \title{Connect a ggvis graphic to a shiny app.} 9 | \usage{ 10 | bind_shiny( 11 | vis, 12 | plot_id, 13 | controls_id = NULL, 14 | ..., 15 | session = shiny::getDefaultReactiveDomain() 16 | ) 17 | 18 | bind_shiny_ui(vis, controls_id, session = shiny::getDefaultReactiveDomain()) 19 | 20 | ggvisOutput(plot_id = rand_id("plot_id")) 21 | } 22 | \arguments{ 23 | \item{vis}{A ggvis object, or a reactive expression that returns a ggvis 24 | object.} 25 | 26 | \item{plot_id}{unique identifier to use for the div containing the ggvis plot.} 27 | 28 | \item{controls_id}{Unique identifier for controls div.} 29 | 30 | \item{...}{Other arguments passed to \code{as.vega}.} 31 | 32 | \item{session}{A Shiny session object.} 33 | } 34 | \description{ 35 | Embedding ggvis in a shiny app is easy. You need to make a place for it in 36 | your \code{ui.r} with \code{ggvisOutput}, and tell your \code{server.r} 37 | where to draw it with \code{bind_shiny}. It's easiest to learn by example: 38 | there are many shiny apps in \code{demo/apps/} that you can learn from. 39 | } 40 | \section{Client-side}{ 41 | 42 | In your UI, use \code{ggvisOutput()} in \code{ui.r} to insert an html 43 | placeholder for the plot. 44 | 45 | If you're going to be using interactive controls generated by ggvis, 46 | use \code{\link[shiny]{renderUI}()} to add a place holder. By convention, 47 | if the id of plot placehold is called "plot", call the controls placeholder 48 | "plot_ui". 49 | } 50 | 51 | \section{Server-side}{ 52 | 53 | When you run ggvis plot interactively, it is automatically plotted because 54 | it triggers the default print method. In shiny apps, you need to 55 | explicitly render the plot to a specific placeholder with 56 | \code{bind_shiny}: 57 | 58 | \code{p \%>\% bind_shiny("plot")} 59 | 60 | If the plot has controls, and you've reserved space for them in the UI, 61 | supply the name of the placeholder as the third argument: 62 | 63 | \code{p \%>\% bind_shiny("plot", "plot_ui")} 64 | } 65 | 66 | \examples{ 67 | ## Run these examples only in interactive R sessions 68 | if (interactive()) { 69 | 70 | # Simplest possible app: 71 | library(shiny) 72 | runApp(list( 73 | ui = bootstrapPage( 74 | ggvisOutput("p"), 75 | uiOutput("p_ui") 76 | ), 77 | server = function(..., session) { 78 | mtcars \%>\% 79 | ggvis(~wt, ~mpg) \%>\% 80 | layer_points() \%>\% 81 | layer_smooths(span = input_slider(0, 1)) \%>\% 82 | bind_shiny("p", "p_ui") 83 | } 84 | )) 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /man/show_spec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggvis.R 3 | \name{show_spec} 4 | \alias{show_spec} 5 | \title{Print out the vega plot specification} 6 | \usage{ 7 | show_spec(vis, pieces = NULL) 8 | } 9 | \arguments{ 10 | \item{vis}{Visualisation to print} 11 | 12 | \item{pieces}{Optional, a character or numeric vector used to 13 | pull out selected pieces of the spec} 14 | } 15 | \description{ 16 | Print out the vega plot specification 17 | } 18 | \examples{ 19 | base <- mtcars \%>\% ggvis(~mpg, ~wt) \%>\% layer_points() 20 | base \%>\% show_spec() 21 | base \%>\% show_spec("scales") 22 | } 23 | -------------------------------------------------------------------------------- /man/show_tooltip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/interact_tooltip.R 3 | \name{show_tooltip} 4 | \alias{show_tooltip} 5 | \alias{hide_tooltip} 6 | \title{Send a message to the client to show or hide a tooltip} 7 | \usage{ 8 | show_tooltip(session, l = 0, t = 0, html = "") 9 | 10 | hide_tooltip(session) 11 | } 12 | \arguments{ 13 | \item{session}{A Shiny session object.} 14 | 15 | \item{l}{Pixel location of left edge of tooltip (relative to page)} 16 | 17 | \item{t}{Pixel location of top edge of tooltip (relative to page)} 18 | 19 | \item{html}{HTML to display in the tooltip box.} 20 | } 21 | \description{ 22 | Send a message to the client to show or hide a tooltip 23 | } 24 | -------------------------------------------------------------------------------- /man/sidebarBottomPage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny_layout.R 3 | \name{sidebarBottomPage} 4 | \alias{sidebarBottomPage} 5 | \alias{sidebarBottomPanel} 6 | \alias{mainTopPanel} 7 | \title{Create a page with a sidebar} 8 | \usage{ 9 | sidebarBottomPage(sidebarPanel, mainPanel, shiny_headers = TRUE) 10 | 11 | sidebarBottomPanel(...) 12 | 13 | mainTopPanel(...) 14 | } 15 | \arguments{ 16 | \item{sidebarPanel}{The \code{\link{sidebarBottomPanel}} containing input 17 | controls.} 18 | 19 | \item{mainPanel}{The \code{\link{mainTopPanel}} containing the main content.} 20 | 21 | \item{shiny_headers}{Should Shiny headers be embedded in the page? This 22 | should be TRUE for interactive/dynamic pages, FALSE for static pages.} 23 | 24 | \item{...}{Additional tags.} 25 | } 26 | \description{ 27 | This creates a page with a sidebar, where the sidebar moves to the bottom 28 | when the width goes below a particular value. 29 | } 30 | \examples{ 31 | sidebarBottomPage(sidebarBottomPanel(), mainTopPanel()) 32 | } 33 | -------------------------------------------------------------------------------- /man/singular.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/singular.R 3 | \name{singular} 4 | \alias{singular} 5 | \alias{scale_singular} 6 | \title{singular.} 7 | \usage{ 8 | singular() 9 | 10 | scale_singular( 11 | vis, 12 | property, 13 | name = property, 14 | label = name, 15 | points = TRUE, 16 | domain = NULL, 17 | override = NULL 18 | ) 19 | } 20 | \arguments{ 21 | \item{vis}{A ggvis object.} 22 | 23 | \item{property}{The name of a property, such as "x", "y", "fill", "stroke", etc.} 24 | 25 | \item{name}{Name of the scale, such as "x", "y", "fill", etc. Can also be an 26 | arbitrary name like "foo".} 27 | 28 | \item{label}{Label for the scale. Used for axis or legend titles.} 29 | 30 | \item{points}{If \code{TRUE} (default), distributes the ordinal values over a 31 | quantitative range at uniformly spaced points. The spacing of the points 32 | can be adjusted using the padding property. If \code{FALSE}, the ordinal 33 | scale will construct evenly-spaced bands, rather than points. Note that 34 | if any mark is added with a \code{\link{band}()} prop, then the scale for 35 | that prop will automatically have \code{points} set to \code{FALSE}.} 36 | 37 | \item{domain}{The domain of the scale, representing the set of data values. 38 | For ordinal scales, a character vector; for quantitative scales, a numeric 39 | vector of length two. Either value (but not both) may be NA, in which 40 | case \code{domainMin} or \code{domainMax} is set. For dynamic scales, this 41 | can also be a reactive which returns the appropriate type of vector.} 42 | 43 | \item{override}{Should the domain specified by this ggvis_scale object 44 | override other ggvis_scale objects for the same scale? Useful when domain is 45 | manually specified. For example, by default, the domain of the scale 46 | will contain the range of the data, but when this is TRUE, the specified 47 | domain will override, and the domain can be smaller than the range of the 48 | data. If \code{FALSE}, the \code{domain} will not behave this way. If 49 | left \code{NULL}, then it will be treated as \code{TRUE} whenever 50 | \code{domain} is non-NULL.} 51 | } 52 | \description{ 53 | Use singular when you want constant x or y position. 54 | } 55 | \examples{ 56 | mtcars \%>\% ggvis("", ~mpg) \%>\% 57 | layer_points() \%>\% 58 | scale_nominal("x") \%>\% 59 | add_axis("x", title = "", tick_size_major = 0) 60 | 61 | # OR 62 | mtcars \%>\% ggvis("", ~mpg) \%>\% 63 | layer_points() \%>\% 64 | scale_singular("x") 65 | 66 | # OR, even simpler 67 | mtcars \%>\% ggvis(singular(), ~mpg) \%>\% layer_points() 68 | 69 | # In the other direction: 70 | mtcars \%>\% ggvis(~mpg, singular()) \%>\% layer_points() 71 | } 72 | -------------------------------------------------------------------------------- /man/subvis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subvis.R 3 | \name{subvis} 4 | \alias{subvis} 5 | \title{Create a subvisualisation.} 6 | \usage{ 7 | subvis(vis, ..., data = NULL, width = NULL, height = NULL) 8 | } 9 | \description{ 10 | Create a subvisualisation. 11 | } 12 | \examples{ 13 | # Examples don't work yet 14 | \dontrun{ 15 | library(dplyr, warn.conflicts = FALSE) 16 | 17 | small <- nasaweather::atmos \%>\% 18 | filter(lat <= -11.217391, long <= -106.287, year == 1995) \%>\% 19 | group_by(long, lat) 20 | small \%>\% 21 | ggvis(~long, ~lat) \%>\% 22 | layer_points() 23 | 24 | small \%>\% 25 | ggvis(~long, ~lat) \%>\% 26 | subvis(width := 100, height := 100, stroke := "red") \%>\% 27 | layer_points(~month, ~ozone) 28 | 29 | small \%>\% 30 | ggvis(~long, ~lat) \%>\% 31 | subvis(width := 100, height := 100, stroke := "red") \%>\% 32 | layer_points(~month, ~ozone) \%>\% 33 | add_axis("x", ticks = 3) \%>\% 34 | add_axis("y", ticks = 3) 35 | } 36 | } 37 | \keyword{internal} 38 | -------------------------------------------------------------------------------- /man/vector_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vector_type.R 3 | \name{vector_type} 4 | \alias{vector_type} 5 | \title{Determine the "type" of a vector} 6 | \usage{ 7 | vector_type(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | } 12 | \description{ 13 | The \code{vector_type} collapses down the class of base vectors into 14 | something useful more for visualisation, yielding one of "datetime", 15 | "numeric", "ordinal", "nominal" or "logical". 16 | } 17 | \seealso{ 18 | \code{default_scale}, which uses this when picking the default 19 | scale. 20 | } 21 | -------------------------------------------------------------------------------- /man/vega_data_parser.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vector_type.R 3 | \name{vega_data_parser} 4 | \alias{vega_data_parser} 5 | \title{Determine the vega data type for a vector} 6 | \usage{ 7 | vega_data_parser(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector.} 11 | } 12 | \description{ 13 | This is used to specify the data type so that the appropriate parser is used 14 | when Vega receives the data. 15 | } 16 | -------------------------------------------------------------------------------- /man/waggle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/waggle.R 3 | \name{waggle} 4 | \alias{waggle} 5 | \title{Waggle back and forth between two numbers} 6 | \usage{ 7 | waggle(min, max, value = (min + max)/2, step = (max - min)/50, fps = 10) 8 | } 9 | \arguments{ 10 | \item{min}{A minimum value.} 11 | 12 | \item{max}{A maximum value.} 13 | 14 | \item{value}{Starting value. Defaults to half-way between \code{min} and 15 | \code{max}.} 16 | 17 | \item{step}{How much value changes at each frame. Defaults to 50 steps 18 | between min and max so it takes 5 seconds to waggle once.} 19 | 20 | \item{fps}{number of frames per second.} 21 | } 22 | \description{ 23 | Waggle back and forth between two numbers 24 | } 25 | \examples{ 26 | span <- waggle(0.2, 1) 27 | mtcars \%>\% ggvis(~mpg, ~wt) \%>\% 28 | layer_points() \%>\% 29 | layer_smooths(span = span) 30 | } 31 | -------------------------------------------------------------------------------- /man/zero_range.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils_resolution.R 3 | \name{zero_range} 4 | \alias{zero_range} 5 | \title{Determine if range of vector is close to zero, with a specified tolerance} 6 | \usage{ 7 | zero_range(x, tol = .Machine$double.eps * 100) 8 | } 9 | \arguments{ 10 | \item{x}{numeric range: vector of length 2} 11 | 12 | \item{tol}{A value specifying the tolerance. Defaults to 13 | \code{.Machine$double.eps * 100}.} 14 | } 15 | \value{ 16 | logical \code{TRUE} if the relative difference of the endpoints of 17 | the range are not distinguishable from 0. 18 | } 19 | \description{ 20 | The machine epsilon is the difference between 1.0 and the next number 21 | that can be represented by the machine. By default, this function 22 | uses epsilon * 100 as the tolerance. First it scales the values so that 23 | they have a mean of 1, and then it checks if the difference between 24 | them is larger than the tolerance. 25 | } 26 | \examples{ 27 | eps <- .Machine$double.eps 28 | zero_range(c(1, 1 + eps)) # TRUE 29 | zero_range(c(1, 1 + 99 * eps)) # TRUE 30 | zero_range(c(1, 1 + 101 * eps)) # FALSE - Crossed the tol threshold 31 | zero_range(c(1, 1 + 2 * eps), tol = eps) # FALSE - Changed tol 32 | 33 | # Scaling up or down all the values has no effect since the values 34 | # are rescaled to 1 before checking against tol 35 | zero_range(100000 * c(1, 1 + eps)) # TRUE 36 | zero_range(100000 * c(1, 1 + 200 * eps)) # FALSE 37 | zero_range(.00001 * c(1, 1 + eps)) # TRUE 38 | zero_range(.00001 * c(1, 1 + 200 * eps)) # FALSE 39 | 40 | # NA values 41 | zero_range(c(1, NA)) # NA 42 | zero_range(c(1, NaN)) # NA 43 | 44 | # Infinite values 45 | zero_range(c(1, Inf)) # FALSE 46 | zero_range(c(-Inf, Inf)) # FALSE 47 | zero_range(c(Inf, Inf)) # TRUE 48 | 49 | } 50 | -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | **/ 2 | checks 3 | library 4 | checks.noindex 5 | library.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Revdeps 2 | 3 | -------------------------------------------------------------------------------- /revdep/checks.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/ggvis/f7b5fe7e25d32d57ed871ba8238892ca5641c8f5/revdep/checks.rds -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 4 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 0 new problems 6 | * We failed to check 0 packages 7 | 8 | -------------------------------------------------------------------------------- /revdep/email.yml: -------------------------------------------------------------------------------- 1 | release_date: ??? 2 | rel_release_date: ??? 3 | my_news_url: ??? 4 | release_version: ??? 5 | release_details: ??? 6 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /tests/specs/bar.r: -------------------------------------------------------------------------------- 1 | # Basic bar graphs 2 | library(ggvis) 3 | library(dplyr, warn.conflicts = FALSE) 4 | 5 | pressure %>% 6 | ggvis(~factor(temperature), ~pressure) %>% 7 | layer_bars(width = 0.5) %>% 8 | save_spec("bar/categorical-x.json") 9 | 10 | pressure %>% 11 | ggvis(x = ~temperature, y = ~pressure) %>% 12 | layer_bars(fill:="red") %>% 13 | save_spec("bar/continuous-x.json") 14 | -------------------------------------------------------------------------------- /tests/specs/boxplot.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | mtcars %>% 4 | ggvis(~cyl, ~mpg) %>% 5 | layer_boxplots() %>% 6 | save_spec("boxplot/boxplot-continuous.json") 7 | 8 | mtcars %>% 9 | ggvis(~factor(cyl), ~mpg) %>% 10 | layer_boxplots() %>% 11 | save_spec("boxplot/boxplot-categorical.json") 12 | 13 | 14 | dat <- data.frame(x = c('a','a','a','b','b','b'), y = c(1:3, 2:4)) 15 | dat %>% 16 | ggvis(x = ~x, y = ~y) %>% 17 | layer_boxplots() %>% 18 | save_spec("boxplot/boxplot-no-outliers.json") 19 | -------------------------------------------------------------------------------- /tests/specs/data.r: -------------------------------------------------------------------------------- 1 | # Data handling tests 2 | library(ggvis) 3 | library(dplyr, warn.conflicts = FALSE) 4 | 5 | # Using "." in names of grouped and non-grouped vars 6 | mtcars %>% 7 | dplyr::mutate(cyl.new = factor(cyl), mpg.new = mpg) %>% 8 | group_by(cyl.new) %>% 9 | ggvis(~wt, ~mpg.new, fill = ~cyl.new) %>% 10 | layer_points() %>% 11 | save_spec("data/dots.json") 12 | -------------------------------------------------------------------------------- /tests/specs/layer.r: -------------------------------------------------------------------------------- 1 | library(ggvis) 2 | 3 | mtcars %>% 4 | ggvis(x = ~wt) %>% 5 | layer_histograms(width = 1) %>% 6 | save_spec("layer/histogram.json") 7 | 8 | mtcars %>% 9 | ggvis(x = ~wt, stroke = ~cyl) %>% 10 | group_by(cyl) %>% 11 | layer_freqpolys(width = 1) %>% 12 | save_spec("layer/freqpoly-grouped.json") 13 | 14 | mtcars %>% 15 | ggvis(x = ~wt, y = ~mpg) %>% 16 | layer_smooths() %>% 17 | save_spec("layer/smooth.json") 18 | 19 | mtcars %>% 20 | ggvis(x = ~wt, y = ~mpg) %>% 21 | group_by(cyl) %>% 22 | layer_smooths() %>% 23 | save_spec("layer/smooth-grouped.json") 24 | -------------------------------------------------------------------------------- /tests/specs/line.r: -------------------------------------------------------------------------------- 1 | # Basic line graphs 2 | library(ggvis) 3 | library(dplyr, warn.conflicts = FALSE) 4 | 5 | set.seed(1780) 6 | df <- data.frame(x = runif(12), y = runif(12), z = gl(3, 4), 7 | w = factor(rep(letters[1:4], 3))) 8 | 9 | df %>% 10 | ggvis(x = ~x, y = ~y) %>% 11 | layer_paths() %>% 12 | save_spec("line/basic.json") 13 | 14 | df %>% 15 | ggvis(x = ~x, y = ~y) %>% 16 | arrange(x) %>% 17 | layer_paths() %>% 18 | save_spec("line/sort.json") 19 | 20 | df %>% 21 | ggvis(x = ~x, y = ~y, stroke = ~z) %>% 22 | layer_lines() %>% 23 | save_spec("line/layer-line.json") 24 | 25 | # Auto-grouping for lines with nominal x 26 | df %>% 27 | ggvis(x = ~w, y = ~y, stroke = ~z) %>% 28 | layer_lines() %>% 29 | save_spec("line/layer-line-nominal-x.json") 30 | -------------------------------------------------------------------------------- /tests/specs/scales.R: -------------------------------------------------------------------------------- 1 | # Modifying scales 2 | library(ggvis) 3 | 4 | set.seed(1014) 5 | df <- data.frame(x = 1:5, y = 5:1, z = runif(5)) 6 | 7 | # Override default scale property 8 | df %>% 9 | ggvis(x = ~x, y = ~x) %>% 10 | layer_points() %>% 11 | scale_numeric("x", trans = "log") %>% 12 | scale_numeric("y", trans = "log") %>% 13 | save_spec("scales/log.json") 14 | 15 | # Override default scale name 16 | df %>% 17 | ggvis(x = ~x, y = ~x, prop("fill", ~z, scale = "blah")) %>% 18 | layer_points() %>% 19 | add_legend("blah") %>% 20 | save_spec("scales/custom.json") 21 | 22 | # Dual scale 23 | df %>% 24 | ggvis(x = ~x) %>% 25 | layer_points(prop("y", ~y, scale = "y-y"), fill := "red") %>% 26 | layer_points(prop("y", ~z, scale = "y-z")) %>% 27 | save_spec("scales/dual.json") 28 | 29 | # Numeric domains 30 | df %>% 31 | ggvis(x = ~x, y = ~x, fill = ~z) %>% 32 | layer_points() %>% 33 | scale_numeric("x", domain = c(0, 10)) %>% 34 | scale_numeric("fill", domain = c(0, 2)) %>% 35 | save_spec("scales/domain_numeric.json") 36 | 37 | # Datetimes 38 | dat <- data.frame( 39 | time = as.POSIXct("2013-07-01", tz = "GMT") + rnorm(40) * 60 * 60 * 24 * 7, 40 | value = rnorm(40) 41 | ) 42 | 43 | dat %>% ggvis(~time, ~value) %>% layer_points() %>% 44 | save_spec("scales/datetime.json") 45 | 46 | dat %>% ggvis(~time) %>% layer_histograms() %>% 47 | save_spec("scales/datetime_hist.json") 48 | 49 | # Two properties in one legend, one on a custom scale 50 | df %>% 51 | ggvis(x = ~x, y = ~x, fill = ~factor(y), prop("shape", ~factor(y), "shape2")) %>% 52 | layer_points() %>% 53 | add_legend(c("fill", "shape2")) %>% 54 | save_spec("scales/combined_legend.json") 55 | 56 | # Nominal x with bars 57 | df %>% 58 | ggvis(x = ~factor(x), y = ~y) %>% 59 | layer_bars() %>% 60 | save_spec("scales/bars.json") 61 | 62 | # Hide axes and legends 63 | df %>% 64 | ggvis(x = ~x, y = ~y, fill = ~z, shape = ~factor(x)) %>% 65 | layer_points() %>% 66 | hide_legend("fill") %>% 67 | hide_legend("shape") %>% 68 | hide_axis("x") %>% 69 | hide_axis("y") %>% 70 | save_spec("scales/hide_guides.json") 71 | -------------------------------------------------------------------------------- /tests/specs/scales/log.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "name": ".0", 5 | "format": { 6 | "type": "csv", 7 | "parse": { 8 | "x": "number" 9 | } 10 | }, 11 | "values": "\"x\"\n1\n2\n3\n4\n5" 12 | }, 13 | { 14 | "name": "scale/x", 15 | "format": { 16 | "type": "csv", 17 | "parse": { 18 | "domain": "number" 19 | } 20 | }, 21 | "values": "\"domain\"\n0.8\n5.2" 22 | }, 23 | { 24 | "name": "scale/y", 25 | "format": { 26 | "type": "csv", 27 | "parse": { 28 | "domain": "number" 29 | } 30 | }, 31 | "values": "\"domain\"\n0.8\n5.2" 32 | } 33 | ], 34 | "scales": [ 35 | { 36 | "domain": { 37 | "data": "scale/x", 38 | "field": "data.domain" 39 | }, 40 | "name": "x", 41 | "type": "log", 42 | "zero": false, 43 | "nice": false, 44 | "clamp": false, 45 | "range": "width" 46 | }, 47 | { 48 | "domain": { 49 | "data": "scale/y", 50 | "field": "data.domain" 51 | }, 52 | "name": "y", 53 | "type": "log", 54 | "zero": false, 55 | "nice": false, 56 | "clamp": false, 57 | "range": "height" 58 | } 59 | ], 60 | "marks": [ 61 | { 62 | "type": "symbol", 63 | "properties": { 64 | "update": { 65 | "fill": { 66 | "value": "#000000" 67 | }, 68 | "size": { 69 | "value": 50 70 | }, 71 | "x": { 72 | "scale": "x", 73 | "field": "data.x" 74 | }, 75 | "y": { 76 | "scale": "y", 77 | "field": "data.x" 78 | } 79 | }, 80 | "ggvis": { 81 | "data": { 82 | "value": ".0" 83 | } 84 | } 85 | }, 86 | "from": { 87 | "data": ".0" 88 | } 89 | } 90 | ], 91 | "legends": [], 92 | "axes": [ 93 | { 94 | "type": "x", 95 | "scale": "x", 96 | "orient": "bottom", 97 | "layer": "back", 98 | "grid": true, 99 | "title": "x" 100 | }, 101 | { 102 | "type": "y", 103 | "scale": "y", 104 | "orient": "left", 105 | "layer": "back", 106 | "grid": true, 107 | "title": "x" 108 | } 109 | ], 110 | "padding": null, 111 | "ggvis_opts": { 112 | "width": 600, 113 | "height": 400, 114 | "keep_aspect": false, 115 | "resizable": true, 116 | "padding": {}, 117 | "duration": 250, 118 | "renderer": "svg", 119 | "hover_duration": 0 120 | }, 121 | "handlers": null 122 | } 123 | -------------------------------------------------------------------------------- /tests/specs/scatter.r: -------------------------------------------------------------------------------- 1 | # Basic scatterplot 2 | library(ggvis) 3 | 4 | set.seed(1014) 5 | df <- data.frame(x = 1:5, y = 5:1, z = runif(5)) 6 | 7 | df %>% 8 | ggvis(x = ~x, y = ~x) %>% 9 | layer_points() %>% 10 | save_spec("scatter/basic.json") 11 | 12 | df %>% 13 | ggvis(x = ~factor(x), y = ~x / y) %>% 14 | layer_points() %>% 15 | save_spec("scatter/transform.json") 16 | 17 | df %>% 18 | ggvis(x = ~x, y = ~y, fill = ~z) %>% 19 | layer_points() %>% 20 | save_spec("scatter/fill-continuous.json") 21 | 22 | df %>% 23 | ggvis(x = ~x, y = ~y, fill = ~factor(z)) %>% 24 | layer_points() %>% 25 | save_spec("scatter/fill-discrete.json") 26 | -------------------------------------------------------------------------------- /tests/specs/scatter/basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "name": ".0", 5 | "format": { 6 | "type": "csv", 7 | "parse": { 8 | "x": "number" 9 | } 10 | }, 11 | "values": "\"x\"\n1\n2\n3\n4\n5" 12 | }, 13 | { 14 | "name": "scale/x", 15 | "format": { 16 | "type": "csv", 17 | "parse": { 18 | "domain": "number" 19 | } 20 | }, 21 | "values": "\"domain\"\n0.8\n5.2" 22 | }, 23 | { 24 | "name": "scale/y", 25 | "format": { 26 | "type": "csv", 27 | "parse": { 28 | "domain": "number" 29 | } 30 | }, 31 | "values": "\"domain\"\n0.8\n5.2" 32 | } 33 | ], 34 | "scales": [ 35 | { 36 | "name": "x", 37 | "domain": { 38 | "data": "scale/x", 39 | "field": "data.domain" 40 | }, 41 | "zero": false, 42 | "nice": false, 43 | "clamp": false, 44 | "range": "width" 45 | }, 46 | { 47 | "name": "y", 48 | "domain": { 49 | "data": "scale/y", 50 | "field": "data.domain" 51 | }, 52 | "zero": false, 53 | "nice": false, 54 | "clamp": false, 55 | "range": "height" 56 | } 57 | ], 58 | "marks": [ 59 | { 60 | "type": "symbol", 61 | "properties": { 62 | "update": { 63 | "fill": { 64 | "value": "#000000" 65 | }, 66 | "size": { 67 | "value": 50 68 | }, 69 | "x": { 70 | "scale": "x", 71 | "field": "data.x" 72 | }, 73 | "y": { 74 | "scale": "y", 75 | "field": "data.x" 76 | } 77 | }, 78 | "ggvis": { 79 | "data": { 80 | "value": ".0" 81 | } 82 | } 83 | }, 84 | "from": { 85 | "data": ".0" 86 | } 87 | } 88 | ], 89 | "legends": [], 90 | "axes": [ 91 | { 92 | "type": "x", 93 | "scale": "x", 94 | "orient": "bottom", 95 | "layer": "back", 96 | "grid": true, 97 | "title": "x" 98 | }, 99 | { 100 | "type": "y", 101 | "scale": "y", 102 | "orient": "left", 103 | "layer": "back", 104 | "grid": true, 105 | "title": "x" 106 | } 107 | ], 108 | "padding": null, 109 | "ggvis_opts": { 110 | "width": 600, 111 | "height": 400, 112 | "keep_aspect": false, 113 | "resizable": true, 114 | "padding": {}, 115 | "duration": 250, 116 | "renderer": "svg", 117 | "hover_duration": 0 118 | }, 119 | "handlers": null 120 | } 121 | -------------------------------------------------------------------------------- /tests/specs/scatter/transform.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "name": ".0", 5 | "format": { 6 | "type": "csv", 7 | "parse": { 8 | "x/y": "number" 9 | } 10 | }, 11 | "values": "\"factor(x)\",\"x/y\"\n\"1\",0.2\n\"2\",0.5\n\"3\",1\n\"4\",2\n\"5\",5" 12 | }, 13 | { 14 | "name": "scale/x", 15 | "format": { 16 | "type": "csv", 17 | "parse": {} 18 | }, 19 | "values": "\"domain\"\n\"1\"\n\"2\"\n\"3\"\n\"4\"\n\"5\"" 20 | }, 21 | { 22 | "name": "scale/y", 23 | "format": { 24 | "type": "csv", 25 | "parse": { 26 | "domain": "number" 27 | } 28 | }, 29 | "values": "\"domain\"\n-0.04\n5.24" 30 | } 31 | ], 32 | "scales": [ 33 | { 34 | "name": "x", 35 | "type": "ordinal", 36 | "domain": { 37 | "data": "scale/x", 38 | "field": "data.domain" 39 | }, 40 | "points": true, 41 | "sort": false, 42 | "range": "width", 43 | "padding": 0.5 44 | }, 45 | { 46 | "name": "y", 47 | "domain": { 48 | "data": "scale/y", 49 | "field": "data.domain" 50 | }, 51 | "zero": false, 52 | "nice": false, 53 | "clamp": false, 54 | "range": "height" 55 | } 56 | ], 57 | "marks": [ 58 | { 59 | "type": "symbol", 60 | "properties": { 61 | "update": { 62 | "fill": { 63 | "value": "#000000" 64 | }, 65 | "size": { 66 | "value": 50 67 | }, 68 | "x": { 69 | "scale": "x", 70 | "field": "data.factor(x)" 71 | }, 72 | "y": { 73 | "scale": "y", 74 | "field": "data.x/y" 75 | } 76 | }, 77 | "ggvis": { 78 | "data": { 79 | "value": ".0" 80 | } 81 | } 82 | }, 83 | "from": { 84 | "data": ".0" 85 | } 86 | } 87 | ], 88 | "legends": [], 89 | "axes": [ 90 | { 91 | "type": "x", 92 | "scale": "x", 93 | "orient": "bottom", 94 | "layer": "back", 95 | "grid": true, 96 | "title": "factor(x)" 97 | }, 98 | { 99 | "type": "y", 100 | "scale": "y", 101 | "orient": "left", 102 | "layer": "back", 103 | "grid": true, 104 | "title": "x/y" 105 | } 106 | ], 107 | "padding": null, 108 | "ggvis_opts": { 109 | "width": 600, 110 | "height": 400, 111 | "keep_aspect": false, 112 | "resizable": true, 113 | "padding": {}, 114 | "duration": 250, 115 | "renderer": "svg", 116 | "hover_duration": 0 117 | }, 118 | "handlers": null 119 | } 120 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggvis) 3 | 4 | test_check("ggvis") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-compute-boxplot.r: -------------------------------------------------------------------------------- 1 | context("compute_boxplot") 2 | 3 | test_that("Zero-row inputs", { 4 | res <- mtcars[0,] %>% compute_boxplot(~mpg) 5 | expect_equal(nrow(res), 0) 6 | expect_true(setequal( 7 | names(res), 8 | c("min_", "lower_", "median_", "upper_", "max_", "outliers_") 9 | )) 10 | expect_identical(res$outliers_, list()) 11 | 12 | # Grouped 13 | res <- mtcars %>% group_by(cyl) %>% dplyr::filter(FALSE) %>% compute_boxplot(~mpg) 14 | expect_equal(nrow(res), 0) 15 | expect_true(setequal( 16 | names(res), 17 | c("cyl", "min_", "lower_", "median_", "upper_", "max_", "outliers_") 18 | )) 19 | expect_identical(res$outliers_, list()) 20 | }) 21 | -------------------------------------------------------------------------------- /tests/testthat/test-compute-count.r: -------------------------------------------------------------------------------- 1 | context("compute_count") 2 | 3 | test_that("count_vector correctly handles factors", { 4 | fac <- factor(c("A", "A", "C"), levels = c("A", "C")) 5 | expect_identical( 6 | count_vector(fac), 7 | data.frame( 8 | count_ = c(2, 1), 9 | x_ = factor(c("A", "C"), levels = c("A", "C")) 10 | ) 11 | ) 12 | 13 | # Levels that aren't represented are dropped from the count 14 | fac <- factor(c("A", "A", "C"), levels = c("A", "B", "C")) 15 | expect_identical( 16 | count_vector(fac), 17 | data.frame( 18 | count_ = c(2, 1), 19 | x_ = factor(c("A", "C"), levels = c("A", "B", "C")) 20 | ) 21 | ) 22 | 23 | # Factor with levels in non-lexical order 24 | fac <- factor(c("A", "A", "C"), levels = c("C", "A")) 25 | expect_identical( 26 | count_vector(fac), 27 | data.frame( 28 | count_ = c(1, 2), 29 | x_ = factor(c("C", "A"), levels = c("C", "A")) 30 | ) 31 | ) 32 | }) 33 | 34 | test_that("count_vector preserves dates and times", { 35 | dates <- as.Date("2013-07-01") + 1:100 36 | res <- count_vector(dates) 37 | # May not be identical because res$x_ gets coerced to int 38 | expect_equal(dates, res$x_) 39 | 40 | times <- as.POSIXct('2001-06-11 21:00', tz = 'America/New_York') + 1:10 * 100 41 | res <- count_vector(times) 42 | expect_identical(times, res$x_) 43 | 44 | times <- as.POSIXct('2001-06-11 21:00', tz = 'UTC') + seq(1, 1000, by = 10) 45 | res <- count_vector(times) 46 | expect_identical(times, res$x_) 47 | }) 48 | 49 | 50 | test_that("Zero-row inputs", { 51 | res <- mtcars[0,] %>% compute_count(~cyl) 52 | expect_equal(nrow(res), 0) 53 | expect_true(setequal(names(res), c("count_", "x_"))) 54 | 55 | # Grouped 56 | res <- mtcars %>% group_by(cyl) %>% dplyr::filter(FALSE) %>% compute_count(~cyl) 57 | expect_equal(nrow(res), 0) 58 | expect_true(setequal(names(res), c("cyl", "count_", "x_"))) 59 | }) 60 | -------------------------------------------------------------------------------- /tests/testthat/test-compute-density.r: -------------------------------------------------------------------------------- 1 | context("compute_density") 2 | 3 | test_that("compute_density respects arguments", { 4 | # Uses n 5 | res <- mtcars %>% compute_density(~mpg, n = 10) 6 | expect_equal(10, nrow(res)) 7 | 8 | # When trim = FALSE (default), result goes past bounds of original data 9 | expect_true(min(res$pred_) < min(mtcars$mpg) && max(res$pred_) > max(mtcars$mpg)) 10 | 11 | # When trim = TRUE, bounds of result match bounds of original data 12 | res <- mtcars %>% compute_density(~mpg, n = 10, trim = TRUE) 13 | expect_true(all(range(res$pred_) == range(mtcars$mpg))) 14 | }) 15 | 16 | 17 | test_that("Zero-row inputs", { 18 | res <- mtcars[0,] %>% compute_density(~mpg) 19 | expect_equal(nrow(res), 0) 20 | expect_true(setequal(names(res), c("pred_", "resp_"))) 21 | 22 | # Grouped 23 | res <- mtcars %>% group_by(cyl) %>% dplyr::filter(FALSE) %>% compute_density(~mpg) 24 | expect_equal(nrow(res), 0) 25 | expect_true(setequal(names(res), c("cyl", "pred_", "resp_"))) 26 | }) 27 | -------------------------------------------------------------------------------- /tests/testthat/test-compute-stack.r: -------------------------------------------------------------------------------- 1 | context("compute_stack") 2 | 3 | test_that("compute_stack works as expected", { 4 | dat <- data.frame( 5 | g1 = c("a", "a", "a", "b", "b", "c", "c", "c"), 6 | g2 = c(1, 2, 3, 1, 3, 1, 2, 3), 7 | val = 1:8 8 | ) 9 | 10 | # Basic stacking: stack y value at each x 11 | stacked <- dat %>% compute_stack(~val, ~g1) %>% as.data.frame() 12 | expected <- data.frame( 13 | stack_lwr_ = c(0,1,3,0,4,0,6,13), 14 | stack_upr_ = c(1,3,6,4,9,6,13,21) 15 | ) 16 | 17 | expect_equal(stacked[c("stack_lwr_", "stack_upr_")], expected) 18 | 19 | # With grouping 20 | stacked <- dat %>% group_by(g2) %>% compute_stack(~val, ~g1) %>% 21 | as.data.frame() 22 | expected <- expected[order(dat$g2), ] %>% as.data.frame() 23 | expected <- expected[order(dat$g2), ] %>% as.data.frame() 24 | expect_equal(stacked[c("stack_lwr_", "stack_upr_")], expected) 25 | }) 26 | 27 | 28 | test_that("Zero-row inputs", { 29 | res <- mtcars[0,] %>% compute_stack(~wt, ~cyl) 30 | expect_equal(nrow(res), 0) 31 | expect_true(setequal( 32 | names(res), 33 | c(names(mtcars), "group__", "stack_upr_", "stack_lwr_")) 34 | ) 35 | 36 | # Grouped 37 | res <- mtcars %>% group_by(cyl) %>% dplyr::filter(FALSE) %>% compute_stack(~wt, ~cyl) 38 | expect_equal(nrow(res), 0) 39 | expect_true(setequal( 40 | names(res), 41 | c(names(mtcars), "group__", "stack_upr_", "stack_lwr_")) 42 | ) 43 | }) 44 | -------------------------------------------------------------------------------- /tests/testthat/test-compute-tabulate.r: -------------------------------------------------------------------------------- 1 | context("compute_tabulate") 2 | 3 | test_that("Zero-row inputs", { 4 | res <- mtcars[0,] %>% compute_tabulate(~factor(cyl)) 5 | expect_equal(nrow(res), 0) 6 | expect_true(setequal(names(res), c("count_", "x_"))) 7 | 8 | # Grouped 9 | res <- mtcars %>% group_by(cyl) %>% dplyr::filter(FALSE) %>% compute_tabulate(~factor(cyl)) 10 | expect_equal(nrow(res), 0) 11 | expect_true(setequal(names(res), c("cyl", "count_", "x_"))) 12 | }) 13 | 14 | test_that("weights are added", { 15 | df <- data.frame(x = factor(rep(1:3, each = 3)), y = rep(2, 9)) 16 | 17 | out <- df %>% compute_tabulate(~x, ~y) 18 | expect_equal(out$count_, c(6, 6, 6)) 19 | }) 20 | -------------------------------------------------------------------------------- /tests/testthat/test-flatten.r: -------------------------------------------------------------------------------- 1 | context("Flatten") 2 | 3 | test_that("props inherited from parent", { 4 | p <- data.frame() %>% ggvis(x := 1) %>% 5 | add_props(y := 2) %>% 6 | layer_paths(x := 3) 7 | 8 | props <- p$marks[[1]]$props 9 | 10 | expect_equal(sort(names(props)), c("stroke.update", "x.update", "y.update")) 11 | expect_equal(props$x.update$value, 3) 12 | expect_equal(props$y.update$value, 2) 13 | }) 14 | 15 | test_that("no data is an error", { 16 | base <- NULL %>% ggvis(x = ~x, y = ~y) 17 | expect_error(base %>% layer_paths(), "No data supplied to mark") 18 | }) 19 | 20 | test_that("reactive source data only run once", { 21 | runs <- 0 22 | df <- data.frame(x = 1, y = 2) 23 | rdf <- shiny::reactive({ 24 | runs <<- runs + 1 25 | df 26 | }) 27 | 28 | p <- rdf %>% ggvis(~x, ~y) %>% layer_paths() %>% layer_points() 29 | expect_equal(length(p$data), 1) 30 | 31 | out_df <- shiny::isolate(p$data[[1]]()) 32 | expect_equal(out_df, df) 33 | expect_equal(runs, 1) 34 | }) 35 | -------------------------------------------------------------------------------- /tests/testthat/test-ggvis.R: -------------------------------------------------------------------------------- 1 | context("ggvis") 2 | # Recursively crawl a list and replace any environments with a special 3 | # environment. This is a workaround for a change in behavior in R 3.2.0 4 | # for all.equal when given two environments. 5 | blank_envs <- function(x) { 6 | replacement_env <- new.env(parent = emptyenv()) 7 | 8 | # Use `x[]<-` to preserve any attributes on x 9 | x[] <- lapply(x, function(val) { 10 | if (is.environment(val)) replacement_env 11 | else if (is.list(val)) blank_envs(val) 12 | else val 13 | }) 14 | 15 | x 16 | } 17 | 18 | test_that("plot the same regardless of order data/props added", { 19 | 20 | df <- data.frame(x = 1:10, y = 10:1) 21 | plots <- list( 22 | df %>% ggvis(~x, ~y) %>% layer_points(), 23 | NULL %>% ggvis(~x, ~y) %>% add_data(df) %>% layer_points(), 24 | NULL %>% ggvis(~x, ~y) %>% layer_points(data = df), 25 | ggvis() %>% add_data(df) %>% add_props(~x, ~y) %>% layer_points(), 26 | ggvis() %>% add_data(df) %>% add_props(~x) %>% layer_points(y = ~y) 27 | ) 28 | plots <- blank_envs(plots) 29 | 30 | marks <- lapply(plots, function(x) x$marks[[1]]) 31 | props <- lapply(marks, "[[", "props") 32 | data <- lapply(marks, function(x) x$data()) 33 | 34 | for (i in seq_along(marks)) { 35 | expect_equal( 36 | props[[i]][c("x.update", "y.update")], 37 | blank_envs(props(~x, ~y)) 38 | ) 39 | expect_equal(data[[i]], df) 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /tests/testthat/test-is-dynamic.r: -------------------------------------------------------------------------------- 1 | context("is.dynamic") 2 | library(shiny) 3 | 4 | test_that("regular plot is not dynamic", { 5 | p <- mtcars %>% ggvis(x = ~wt, y = ~cyl) %>% layer_points() 6 | expect_false(is.dynamic(p)) 7 | }) 8 | 9 | test_that("plot with reactive data source is dynamic", { 10 | p <- shiny::reactive(mtcars) %>% ggvis(x = ~wt, y = ~cyl) %>% layer_points() 11 | expect_true(is.dynamic(p)) 12 | }) 13 | 14 | test_that("plot with reactive transform param is dynamic", { 15 | p <- mtcars %>% ggvis(~mpg, ~wt) %>% layer_smooths(span = input_slider(0, 1)) 16 | expect_true(is.dynamic(p)) 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-mark-properties.r: -------------------------------------------------------------------------------- 1 | context("Mark: properties") 2 | 3 | test_that("check_mark_props returns true if all ok", { 4 | expect_true(check_mark_props("symbol", c("x", "y", "stroke"))) 5 | expect_true(check_mark_props("rect", c("x", "x2", "y", "y2"))) 6 | }) 7 | 8 | test_that("check_mark_props returns helpful suggestion for single incorrect", { 9 | expect_error(check_mark_props("symbol", "Stroke"), "stroke") 10 | expect_error(check_mark_props("symbol", "strke"), "stroke") 11 | }) 12 | 13 | test_that("check_mark_props doesn't give suggestion if really wrong", { 14 | expect_error(check_mark_props("symbol", "asdfasdfdsa"), "Unknown properties") 15 | }) 16 | 17 | 18 | test_that("check_mark_props returns helpful suggestion for mixture", { 19 | expect_error(check_mark_props("symbol", c("x", "Stroke")), "stroke") 20 | expect_error(check_mark_props("symbol", c("x", "strke")), "stroke") 21 | }) 22 | -------------------------------------------------------------------------------- /tests/testthat/test-specs.r: -------------------------------------------------------------------------------- 1 | context("specs") 2 | 3 | specs <- dir("../specs", pattern = "\\.[rR]$", full.names = TRUE) 4 | for (spec in specs) { 5 | suppressMessages( 6 | sys.source(spec, envir = new.env(), chdir = TRUE) 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /tests/testthat/test-utils.r: -------------------------------------------------------------------------------- 1 | context("utils") 2 | 3 | 4 | test_that("merge_vectors behaves as expected", { 5 | expect_identical(merge_vectors(c(a=1, b=2), c(c=3, d=4)), c(a=1, b=2, c=3, d=4)) 6 | 7 | # b appears twice; keep last version 8 | expect_identical(merge_vectors(c(a=1, b=2), c(b=3, c=4)), c(a=1, b=3, c=4)) 9 | expect_identical(merge_vectors(c(a=1), c(b=2, b=3, c=4)), c(a=1, b=3, c=4)) 10 | 11 | # NULL value 12 | expect_identical(merge_vectors(NULL, c(a=1, b=2)), c(a=1, b=2)) 13 | expect_identical(merge_vectors(c(a=1, b=2), NULL), c(a=1, b=2)) 14 | 15 | # Lists and empty lists 16 | expect_identical(merge_vectors(list(a=1, b=2), list(b=3, c=4)), 17 | list(a=1, b=3, c=4)) 18 | expect_identical(merge_vectors(list(a=1, b=2), list()), 19 | list(a=1, b=2)) 20 | expect_identical(merge_vectors(list(), list(a=1, b=2)), 21 | list(a=1, b=2)) 22 | 23 | expect_identical(merge_vectors(c(a=1, b=2), NULL), c(a=1, b=2)) 24 | 25 | expect_error(merge_vectors(c(1, 2), c(1, 2))) 26 | expect_error(merge_vectors(c(1, 2), c(a=1, b=2))) 27 | expect_error(merge_vectors(c(a=1, b=2), c(1, 2))) 28 | }) 29 | 30 | 31 | test_that("all_same behaves as expected", { 32 | expect_false(all_same(1:2)) 33 | expect_true(all_same(1)) 34 | expect_true(all_same(c(1, 1))) 35 | expect_true(all_same(NA)) 36 | expect_true(all_same(c(NA, NA))) 37 | expect_false(all_same(c(NA, 1))) 38 | 39 | # Zero-length vector 40 | expect_true(all_same(character())) 41 | 42 | # List (instead of atomic vector) 43 | expect_false(all_same(list())) 44 | expect_false(all_same(list(numeric(0)))) 45 | }) 46 | 47 | 48 | test_that("empty behaves as expected", { 49 | expect_true(empty(character(0))) 50 | expect_true(empty(logical(0))) 51 | expect_true(empty(list())) 52 | expect_true(empty(new.env())) 53 | 54 | # Named list with no elements 55 | x <- list(a=1) 56 | x$a <- NULL 57 | expect_true(empty(x)) 58 | 59 | expect_false(empty(100)) 60 | expect_false(empty(list(40))) 61 | e <- new.env() 62 | e$x <- 10 63 | expect_false(empty(e)) 64 | }) 65 | 66 | 67 | test_that("compact behaves as expected", { 68 | # Compact drops empty vectors and lists, but keeps environments even if empty 69 | e <- new.env() 70 | e$x <- 10 71 | ne <- new.env() 72 | x <- list(a = 1, b = list(), c = character(0), e = e, ne = ne) 73 | expect_identical(compact(x), list(a = 1, e = e, ne = ne)) 74 | }) 75 | -------------------------------------------------------------------------------- /tools/updatejQueryResize.R: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env Rscript 2 | 3 | # This script copies the resize detection script from: 4 | # https://github.com/sdecima/javascript-detect-element-resize 5 | # to the inst/ directory of this package. 6 | 7 | # This script can be sourced from RStudio, or run with Rscript. 8 | 9 | # Returns the file currently being sourced or run with Rscript 10 | thisFile <- function() { 11 | cmdArgs <- commandArgs(trailingOnly = FALSE) 12 | needle <- "--file=" 13 | match <- grep(needle, cmdArgs) 14 | if (length(match) > 0) { 15 | # Rscript 16 | return(normalizePath(sub(needle, "", cmdArgs[match]))) 17 | } else { 18 | # 'source'd via R console 19 | return(normalizePath(sys.frames()[[1]]$ofile)) 20 | } 21 | } 22 | 23 | url <- "https://raw.githubusercontent.com/sdecima/javascript-detect-element-resize/master/jquery.resize.js" 24 | destfile <- file.path(dirname(thisFile()), "../inst/www/lib/detect-resize/", 25 | basename(url)) 26 | 27 | downloader::download(url, destfile) 28 | --------------------------------------------------------------------------------