├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R └── compareBars.R ├── README.Rmd ├── README.md ├── compareBars.Rproj ├── cran-comments.md ├── inst ├── htmlwidgets │ ├── compareBars.js │ ├── compareBars.yaml │ └── lib │ │ ├── compareBars │ │ └── style.css │ │ ├── d3-tip │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ └── index-min.js │ │ └── d3 │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ ├── d3.js │ │ └── d3.min.js └── img │ ├── cbgif2.gif │ ├── compareBars2.png │ ├── compareBarstip.png │ └── ggplots.png └── man ├── compareBars-shiny.Rd └── compareBars.Rd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^README-.*\.png$ 5 | ^CONDUCT\.md$ 6 | ^cran-comments.md$ 7 | ^\.travis\.yml$ 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: compareBars 2 | Title: Simplify Comparative Bar Charts with D3.js 3 | Version: 0.0.1 4 | Authors@R: person("David", "Ranzolin", email = "daranzolin@gmail.com", role = c("aut", "cre")) 5 | Description: There are several ways to create a comparative bar chart. This package produces a bar chart 6 | that uses one fill color to specify the smaller of two variables, and two fill colors to indicate the 7 | magnitude of difference. 8 | Depends: R (>= 3.4.0) 9 | License: MIT + file LICENSE 10 | Encoding: UTF-8 11 | LazyData: true 12 | RoxygenNote: 6.0.1 13 | Imports: rlang, 14 | dplyr, 15 | htmlwidgets 16 | Suggests: testthat 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: David Ranzolin 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(compareBars) 4 | export(compareBarsOutput) 5 | export(renderCompareBars) 6 | import(htmlwidgets) 7 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # compareBars 0.0.1 2 | * Submitting to CRAN (2018-09-16) 3 | -------------------------------------------------------------------------------- /R/compareBars.R: -------------------------------------------------------------------------------- 1 | #' Function for creating simple comparative bar charts. 2 | #' 3 | #' Simplify comparative bar charts with d3.js: two values, one bar. For each level of an ordinal variable, 4 | #' compareBars compares the two values, and returns the smaller as a uniform color, and the larger 5 | #' remainder as a distinct color. 6 | #' 7 | #' @param data a data frame object in wide form. Must have one string/factor column, and two numeric 8 | #' columns to compare. 9 | #' @param ordinalVar unquoted name of the ordinal variable 10 | #' @param compareVar1 unquoted name of a numeric value to compare 11 | #' @param compareVar2 unquoted name of another numeric value to compare 12 | #' @param width width of the chart in pixels 13 | #' @param height height of the chart in pixels 14 | #' @param orientation if "vertical", the bars will render vertically along the x-axis. If 'horizontal', 15 | #' the bars will render horizontally along the y-axis. 16 | #' @param xLabel optional label for the x-axis 17 | #' @param yLabel optional label for the y-axis 18 | #' @param titleLabel optional label for the title 19 | #' @param subtitleLabel optional label for the subtitle 20 | #' @param compareVarFill1 fill color for one of the levels 21 | #' @param compareVarFill2 fill color for the other level 22 | #' @param minFillColor fill color for the smaller value 23 | #' @param fontFamily font family for the labels 24 | #' @param axisFormat axis formatting option, cf. d3-format on github 25 | #' @param tooltipFormat tooltip formatting option, cf. d3-format on github 26 | #' 27 | #'@examples 28 | #'\dontrun{ 29 | #' library(gapminder) 30 | #' library(tidyverse) 31 | #' gapminder %>% 32 | #' group_by(continent, year) %>% 33 | #' summarize(populations = sum(pop)) %>% 34 | #' spread(continent, populations) %>% 35 | #' mutate(year = factor(year)) %>% 36 | #' compareBars(year, Americas, Europe) 37 | #'} 38 | #' @import htmlwidgets 39 | #' 40 | #' @export 41 | compareBars <- function(data, 42 | ordinalVar = NULL, 43 | compareVar1 = NULL, 44 | compareVar2 = NULL, 45 | width = NULL, 46 | height = NULL, 47 | orientation = "vertical", 48 | xLabel = "", 49 | yLabel = "", 50 | titleLabel = "", 51 | subtitleLabel = "", 52 | compareVarFill1 = "#0072B2", 53 | compareVarFill2 = "#E69F00", 54 | minFillColor = "#ddd", 55 | fontFamily = "sans-serif", 56 | axisFormat = ".0s", 57 | tooltipFormat = ".0s") { 58 | 59 | if (!inherits(data, "data.frame")) { 60 | stop("data must be a data frame.", call. = FALSE) 61 | } 62 | 63 | if (!orientation %in% c("vertical", "horizontal")) { 64 | stop("orientation must be either 'vertical' or 'horizontal.'", call. = FALSE) 65 | } 66 | 67 | ov <- rlang::ensym(ordinalVar) 68 | cv1 <- rlang::ensym(compareVar1) 69 | cv2 <- rlang::ensym(compareVar2) 70 | 71 | data <- dplyr::select(data, !!!ov, !!!cv1, !!!cv2) 72 | 73 | if (sum(unlist(lapply(data, is.numeric))) != 2 && sum(!unlist(lapply(data, is.numeric))) != 1) { 74 | stop("ordinalVar must be a string or factor, and compareVar1 and compareVar2 must be numeric.", 75 | call. = FALSE) 76 | } 77 | 78 | settings <- list( 79 | xLabel = xLabel, 80 | yLabel = yLabel, 81 | titleLabel = titleLabel, 82 | subtitleLabel = subtitleLabel, 83 | compareVarFill1 = compareVarFill1, 84 | compareVarFill2 = compareVarFill2, 85 | minFillColor = minFillColor, 86 | orientation = orientation, 87 | fontFamily = fontFamily, 88 | axisFormat = axisFormat, 89 | tooltipFormat = tooltipFormat 90 | ) 91 | 92 | x = list( 93 | data = data, 94 | settings = settings 95 | ) 96 | 97 | htmlwidgets::createWidget( 98 | name = 'compareBars', 99 | x, 100 | width = width, 101 | height = height, 102 | package = 'compareBars', 103 | sizingPolicy = htmlwidgets::sizingPolicy() 104 | ) 105 | } 106 | 107 | #' Shiny bindings for compareBars 108 | #' 109 | #' Output and render functions for using compareBars within Shiny 110 | #' applications and interactive Rmd documents. 111 | #' 112 | #' @param outputId output variable to read from 113 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 114 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 115 | #' string and have \code{'px'} appended. 116 | #' @param expr An expression that generates a compareBars 117 | #' @param env The environment in which to evaluate \code{expr}. 118 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 119 | #' is useful if you want to save an expression in a variable. 120 | #' 121 | #' @name compareBars-shiny 122 | #' 123 | #' @export 124 | compareBarsOutput <- function(outputId, width = '100%', height = '400px'){ 125 | htmlwidgets::shinyWidgetOutput(outputId, 'compareBars', width, height, package = 'compareBars') 126 | } 127 | 128 | #' @rdname compareBars-shiny 129 | #' @export 130 | renderCompareBars <- function(expr, env = parent.frame(), quoted = FALSE) { 131 | if (!quoted) { expr <- substitute(expr) } # force quoted 132 | htmlwidgets::shinyRenderWidget(expr, compareBarsOutput, env, quoted = TRUE) 133 | } 134 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, echo = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "README-" 12 | ) 13 | ``` 14 | 15 | # compareBars 16 | 17 | [![Travis build status](https://travis-ci.org/daranzolin/compareBars.svg?branch=master)](https://travis-ci.org/daranzolin/compareBars) 18 | 19 | >"Less is more." 20 | 21 | >"Simplify simplify." 22 | 23 | ![Alt Text](https://raw.githubusercontent.com/daranzolin/compareBars/master/inst/img/cbgif2.gif) 24 | 25 | The goal of `compareBars` is to reduce the clutter of comparative bar charts. 26 | 27 | ## Installation 28 | 29 | You can install compareBars from github with: 30 | 31 | ```{r gh-installation, eval = FALSE} 32 | # install.packages("devtools") 33 | devtools::install_github("daranzolin/compareBars") 34 | ``` 35 | 36 | ## A simpler alternative 37 | 38 | Consider the following bar charts: 39 | 40 | ```{r warning=FALSE, message=FALSE, eval=FALSE} 41 | library(tidyverse) 42 | library(gapminder) 43 | library(patchwork) 44 | 45 | d <- gapminder %>% 46 | filter(continent %in% c("Americas", "Europe")) %>% 47 | group_by(continent, year) %>% 48 | summarize(pop = sum(pop)) 49 | 50 | p1 <- ggplot(d, aes(year, pop, fill = continent)) + geom_col() 51 | p2 <- ggplot(d, aes(year, pop, fill = continent)) + geom_col(position = "dodge") 52 | 53 | p1 + p2 + plot_layout(ncol = 1) 54 | ``` 55 | 56 | ![cb1](inst/img/ggplots.png) 57 | 58 | When did the total population of the Americas exceed the total population of Europe? With the top chart, you'd have to guess sometime between 1960 and 1980, but it's hard to tell at a glance. And while it's easier to tell with the second plot, the clarity comes at the sake of clutter. 59 | 60 | `compareBars` offers a simpler, cleaner alternative with d3.js: 61 | 62 | ```{r eval=FALSE} 63 | library(compareBars) 64 | d %>% 65 | spread(continent, pop) %>% 66 | mutate(year = factor(year)) %>% 67 | compareBars(year, Americas, Europe) 68 | ``` 69 | 70 | ![cb1](inst/img/compareBarstip.png) 71 | 72 | Not only is the moment when the Americas' population exceeded Europe's immediately clear, but you also get a much better sense of the magnitude by year. Approximating this kind of chart with ggplot requires a great deal of reshaping and wizardry. 73 | 74 | An interactive tooltip shows the magnitude of difference between the two levels. 75 | 76 | ## Other options 77 | 78 | You can adjust the chart by adding axis labels, titles, subtitles, specifying your own fill colors, changing the label fonts, and even the bar orientation: 79 | 80 | ```{r eval=FALSE} 81 | d %>% 82 | spread(continent, pop) %>% 83 | mutate(year = factor(year)) %>% 84 | compareBars(year, 85 | Americas, 86 | Europe, 87 | xLabel = "Population", 88 | yLabel = "Year", 89 | titleLabel = "Population, Europe and the Americas", 90 | subtitleLabel = "1952-2007", 91 | fontFamily = "Arial", 92 | compareVarFill1 = "pink", 93 | compareVarFill2 = "green", 94 | orientation = "horizontal") 95 | ``` 96 | 97 | ![cb2](inst/img/compareBars2.png) 98 | 99 | Note that you must reshape your data into a 'non-tidy' form. 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # compareBars 5 | 6 | [![Travis build 7 | status](https://travis-ci.org/daranzolin/compareBars.svg?branch=master)](https://travis-ci.org/daranzolin/compareBars) 8 | 9 | > “Less is more.” 10 | 11 | > “Simplify simplify.” 12 | 13 | ![Alt 14 | Text](https://raw.githubusercontent.com/daranzolin/compareBars/master/inst/img/cbgif2.gif) 15 | 16 | The goal of `compareBars` is to reduce the clutter of comparative bar 17 | charts. 18 | 19 | ## Installation 20 | 21 | You can install compareBars from github with: 22 | 23 | ``` r 24 | # install.packages("devtools") 25 | devtools::install_github("daranzolin/compareBars") 26 | ``` 27 | 28 | ## A simpler alternative 29 | 30 | Consider the following bar charts: 31 | 32 | ``` r 33 | library(tidyverse) 34 | library(gapminder) 35 | library(patchwork) 36 | 37 | d <- gapminder %>% 38 | filter(continent %in% c("Americas", "Europe")) %>% 39 | group_by(continent, year) %>% 40 | summarize(pop = sum(pop)) 41 | 42 | p1 <- ggplot(d, aes(year, pop, fill = continent)) + geom_col() 43 | p2 <- ggplot(d, aes(year, pop, fill = continent)) + geom_col(position = "dodge") 44 | 45 | p1 + p2 + plot_layout(ncol = 1) 46 | ``` 47 | 48 | ![cb1](inst/img/ggplots.png) 49 | 50 | When did the total population of the Americas exceed the total 51 | population of Europe? With the top chart, you’d have to guess sometime 52 | between 1960 and 1980, but it’s hard to tell at a glance. And while it’s 53 | easier to tell with the second plot, the clarity comes at the sake of 54 | clutter. 55 | 56 | `compareBars` offers a simpler, cleaner alternative with d3.js: 57 | 58 | ``` r 59 | library(compareBars) 60 | d %>% 61 | spread(continent, pop) %>% 62 | mutate(year = factor(year)) %>% 63 | compareBars(year, Americas, Europe) 64 | ``` 65 | 66 | ![cb1](inst/img/compareBarstip.png) 67 | 68 | Not only is the moment when the Americas’ population exceeded Europe’s 69 | immediately clear, but you also get a much better sense of the magnitude 70 | by year. Approximating this kind of chart with ggplot requires a great 71 | deal of reshaping and wizardry. 72 | 73 | An interactive tooltip shows the magnitude of difference between the two 74 | levels. 75 | 76 | ## Other options 77 | 78 | You can adjust the chart by adding axis labels, titles, subtitles, 79 | specifying your own fill colors, changing the label fonts, and even the 80 | bar orientation: 81 | 82 | ``` r 83 | d %>% 84 | spread(continent, pop) %>% 85 | mutate(year = factor(year)) %>% 86 | compareBars(year, 87 | Americas, 88 | Europe, 89 | xLabel = "Population", 90 | yLabel = "Year", 91 | titleLabel = "Population, Europe and the Americas", 92 | subtitleLabel = "1952-2007", 93 | fontFamily = "Arial", 94 | compareVarFill1 = "pink", 95 | compareVarFill2 = "green", 96 | orientation = "horizontal") 97 | ``` 98 | 99 | ![cb2](inst/img/compareBars2.png) 100 | 101 | Note that you must reshape your data into a ‘non-tidy’ form. 102 | -------------------------------------------------------------------------------- /compareBars.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environment 2 | * local OS X install, R 3.4.1 3 | * ubuntu 14.04 (on travis-ci), R 3.4.1 4 | 5 | ## R CMD check results 6 | 0 errors | 0 warnings | 0 notes 7 | 8 | ## First submission 9 | This is my first submission. 10 | -------------------------------------------------------------------------------- /inst/htmlwidgets/compareBars.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'compareBars', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | 11 | return { 12 | 13 | renderValue: function(opts) { 14 | 15 | const data = HTMLWidgets.dataframeToD3(opts.data); 16 | 17 | const svg = d3.select(el) 18 | .append("svg") 19 | .style("width", "100%") 20 | .style("height", "100%"); 21 | 22 | const cols = Object.keys(data[0]); 23 | const oc = cols[0]; 24 | const c1 = cols[1]; 25 | const c2 = cols[2]; 26 | 27 | const margin = ({top: 80, right: 120, bottom: 50, left: 100}); 28 | 29 | if (opts.settings.orientation === 'vertical') { 30 | 31 | let y0 = d3.scaleLinear() 32 | .domain([0, d3.max(data, d => Math.max(d[c1], d[c2]))]).nice() 33 | .range([height - margin.bottom, margin.top]); 34 | 35 | let x0 = d3.scaleBand() 36 | .domain(data.map(d => d[oc])) 37 | .range([margin.left, width - margin.right]) 38 | .padding(0.1); 39 | 40 | let xAxis = g => g 41 | .style("font-size", "18px") 42 | .attr("transform", `translate(0,${height - margin.bottom})`) 43 | .call(g => g.append("g") 44 | .call(d3.axisBottom(x0))) 45 | .call(g => g.selectAll(".domain").remove()); 46 | 47 | let yAxis = g => g 48 | .attr("transform", `translate(${margin.left},0)`) 49 | .call(d3.axisLeft(y0) 50 | .tickValues(d3.scaleLinear() 51 | .domain(y0.domain()) 52 | .ticks()).tickFormat(d3.format(opts.settings.axisFormat))) 53 | .call(g => g.selectAll(".tick line") 54 | .clone() 55 | .attr("stroke-opacity", 0.2) 56 | .attr("x2", width - margin.left - margin.right)) 57 | .call(g => g.select(".domain").remove()); 58 | 59 | svg.append("g").call(yAxis); 60 | 61 | svg.append("g") 62 | .attr("class", "grid") 63 | .attr("transform", `translate(${margin.left}, 0)`) 64 | .attr("stroke", "lightgrey") 65 | .attr("stroke-opacity", 0.5) 66 | .attr("stroke-width", 0.3); 67 | 68 | svg.append("g") 69 | .attr("fill", opts.settings.minFillColor) 70 | .selectAll("rect") 71 | .data(data) 72 | .enter().append("rect") 73 | .attr("x", d => x0(d[oc])) 74 | .attr("y", d => y0(Math.min(d[c1], d[c2]))) 75 | .attr("width", x0.bandwidth()) 76 | .attr("height", d => y0(0) - y0(Math.min(d[c1], d[c2]))); 77 | 78 | svg.append("g") 79 | .selectAll("rect") 80 | .data(data) 81 | .enter().append("rect") 82 | .attr("fill", d => d[c1] < d[c2] ? opts.settings.compareVarFill1 : opts.settings.compareVarFill2) 83 | .attr("y", d => y0(Math.max(d[c1], d[c2]))) 84 | .attr("x", d => x0(d[oc])) 85 | .attr("width", x0.bandwidth()) 86 | .attr("height", d => y0(Math.min(d[c1], d[c2])) - y0(Math.max(d[c1], d[c2]))); 87 | 88 | let tip = d3.tip() 89 | .attr('class', 'd3-tipV') 90 | .offset([-10, 0]) 91 | .html(function(d) { 92 | return ` ${d3.format(opts.settings.tooltipFormat)(Math.abs(d[c1] - d[c2]))}`; 93 | }); 94 | 95 | svg.call(tip); 96 | 97 | svg.append("g") 98 | .style("opacity", 0) 99 | .selectAll("rect") 100 | .data(data) 101 | .enter().append("rect") 102 | .attr("x", d => x0(d[oc])) 103 | .attr("y", d => y0(Math.max(d[c1], d[c2]))) 104 | .attr("width", x0.bandwidth()) 105 | .attr("height", d => y0(0) - y0(Math.max(d[c1], d[c2]))) 106 | .on('mouseover', tip.show) 107 | .on('mouseout', tip.hide); 108 | 109 | svg.append("text") 110 | .attr("class", "x label") 111 | .attr("text-anchor", "end") 112 | .style("font", `11px ${opts.settings.fontFamily}`) 113 | .attr("x", width - margin.left) 114 | .attr("y", height - margin.bottom/4) 115 | .text(opts.settings.xLabel); 116 | 117 | svg.append("text") 118 | .attr("class", "y label") 119 | .attr("text-anchor", "end") 120 | .style("font", "11px sans-serif") 121 | .attr("dy", ".85em") 122 | .attr("dx", "-5em") 123 | .attr("transform", "rotate(-90)") 124 | .text(opts.settings.yLabel); 125 | 126 | svg.append("text") 127 | .attr("x", margin.left) 128 | .attr("y", margin.top / 3) 129 | .attr("text-anchor", "left") 130 | .style("font-family", `${opts.settings.fontFamily}`) 131 | .style("font-size", "20px") 132 | .style("font-weight", "bold") 133 | .text(opts.settings.titleLabel); 134 | 135 | svg.append("text") 136 | .attr("x", margin.left) 137 | .attr("y", margin.top - (margin.top)/4) 138 | .attr("text-anchor", "left") 139 | .style("font-family", `${opts.settings.fontFamily}`) 140 | .style("font-size", "14px") 141 | .text(opts.settings.subtitleLabel); 142 | 143 | svg.append("rect") 144 | .style("fill", opts.settings.compareVarFill1) 145 | .attr("x", width - (margin.left)) 146 | .attr("y", height/4) 147 | .attr("width", 17) 148 | .attr("height", 17); 149 | 150 | svg.append("rect") 151 | .style("fill", opts.settings.compareVarFill2) 152 | .attr("x", width - (margin.left)) 153 | .attr("y", (height/4) - 20) 154 | .attr("width", 17) 155 | .attr("height", 17); 156 | 157 | svg.append("text") 158 | .style("font-family", `${opts.settings.fontFamily}`) 159 | .style("font-size", "14px") 160 | .attr("x", width - (margin.left) + 25) 161 | .attr("y", (height/4) - 6) 162 | .text(`${c1} >`); 163 | 164 | svg.append("text") 165 | .style("font-family", `${opts.settings.fontFamily}`) 166 | .style("font-size", "14px") 167 | .attr("x", width - (margin.left) + 25) 168 | .attr("y", (height/4) + 13) 169 | .text(`${c2} >`); 170 | 171 | svg.append("g").call(xAxis); 172 | 173 | } else { 174 | 175 | let x0 = d3.scaleLinear() 176 | .domain([0, d3.max(data, d => Math.max(d[c1], d[c2]))]).nice() 177 | .range([margin.left, width - margin.right]); 178 | 179 | let y0 = d3.scaleBand() 180 | .domain(data.map(d => d[oc])) 181 | .range([height - margin.bottom, margin.top]) 182 | .padding(0.1); 183 | 184 | let xAxis = g => g 185 | .attr("transform", `translate(0,${height - margin.bottom})`) 186 | .call(g => g.append("g")) 187 | .call(d3.axisBottom(x0) 188 | .tickFormat(d3.format(opts.settings.axisFormat))) 189 | .call(g => g.selectAll(".domain").remove()) 190 | .call(g => g.selectAll(".tick line") 191 | .clone() 192 | .attr("stroke-opacity", 0.2) 193 | .attr("y2", -height + margin.top + margin.bottom)) 194 | .call(g => g.select(".domain").remove()); 195 | 196 | let yAxis = g => g 197 | .attr("transform", `translate(${x0(0)},0)`) 198 | .call(d3.axisLeft(y0).ticks(10)) 199 | .call(g => g.selectAll(".tick:last-of-type text") 200 | .clone() 201 | .attr("dy", "-1.1em") 202 | .style("font-weight", "bold")); 203 | 204 | svg.append("g") 205 | .call(xAxis); 206 | 207 | //Legend box 208 | svg.append("rect") 209 | .style("fill", opts.settings.compareVarFill1) 210 | .attr("x", width - (margin.left)) 211 | .attr("y", height/4) 212 | .attr("width", 17) 213 | .attr("height", 17); 214 | 215 | let tip = d3.tip() 216 | .attr('class', 'd3-tipH') 217 | .direction('e') 218 | .offset([0, 10]) 219 | .html(function(d) { 220 | return ` ${d3.format(opts.settings.tooltipFormat)(Math.abs(d[c1] - d[c2]))}`; 221 | }); 222 | 223 | svg.call(tip); 224 | 225 | //Min fill bar 226 | svg.append("g") 227 | .attr("fill", opts.settings.minFillColor) 228 | .selectAll("rect") 229 | .data(data) 230 | .enter().append("rect") 231 | .attr("x", x0(0)) 232 | .attr("y", d => y0(d[oc])) 233 | .attr("width", d => x0(Math.min(d[c1], d[c2])) - x0(0)) 234 | .attr("height", d => y0.bandwidth()); 235 | 236 | svg.append("g") 237 | .selectAll("rect") 238 | .data(data) 239 | .enter().append("rect") 240 | .attr("fill", d => d[c1] < d[c2] ? opts.settings.compareVarFill1 : opts.settings.compareVarFill2) 241 | .attr("x", d => x0(Math.min(d[c1], d[c2]))) 242 | .attr("y", d => y0(d[oc])) 243 | .attr("width", d => x0(Math.max(d[c1], d[c2])) - x0(Math.min(d[c1], d[c2]))) 244 | .attr("height", d => y0.bandwidth()); 245 | 246 | svg.append("g") 247 | .style('opacity', 0) 248 | .selectAll("rect") 249 | .data(data) 250 | .enter().append("rect") 251 | .attr("x", x0(0)) 252 | .attr("y", d => y0(d[oc])) 253 | .attr("width", d => x0(Math.max(d[c1], d[c2])) - x0(0)) 254 | .attr("height", d => y0.bandwidth()) 255 | .on('mouseover', tip.show) 256 | .on('mouseout', tip.hide); 257 | 258 | 259 | //Legend box 260 | svg.append("rect") 261 | .style("fill", opts.settings.compareVarFill2) 262 | .attr("x", width - (margin.left)) 263 | .attr("y", (height/4) - 20) 264 | .attr("width", 17) 265 | .attr("height", 17); 266 | 267 | 268 | //Title label 269 | svg.append("text") 270 | .attr("x", margin.left) 271 | .attr("y", margin.top / 3) 272 | .attr("text-anchor", "left") 273 | .style("font-family", `${opts.settings.fontFamily}`) 274 | .style("font-size", "20px") 275 | .style("font-weight", "bold") 276 | .text(opts.settings.titleLabel); 277 | 278 | svg.append("text") 279 | .attr("class", "x label") 280 | .attr("text-anchor", "end") 281 | .style("font", `11px ${opts.settings.fontFamily}`) 282 | .attr("x", width - margin.left) 283 | .attr("y", height - margin.bottom/4) 284 | .text(opts.settings.xLabel); 285 | 286 | svg.append("text") 287 | .attr("class", "y label") 288 | .attr("text-anchor", "end") 289 | .style("font", "11px sans-serif") 290 | .attr("dy", ".85em") 291 | .attr("dx", "-5em") 292 | .attr("transform", "rotate(-90)") 293 | .text(opts.settings.yLabel); 294 | 295 | svg.append("text") 296 | .attr("x", margin.left) 297 | .attr("y", margin.top - (margin.top)/4) 298 | .attr("text-anchor", "left") 299 | .style("font-family", `${opts.settings.fontFamily}`) 300 | .style("font-size", "14px") 301 | .text(opts.settings.subtitleLabel); 302 | 303 | svg.append("text") 304 | .style("font-family", `${opts.settings.fontFamily}`) 305 | .style("font-size", "14px") 306 | .attr("x", width - (margin.left) + 25) 307 | .attr("y", (height/4) - 6) 308 | .text(`${c1} >`); 309 | 310 | svg.append("text") 311 | .style("font-family", `${opts.settings.fontFamily}`) 312 | .style("font-size", "14px") 313 | .attr("x", width - (margin.left) + 25) 314 | .attr("y", (height/4) + 13) 315 | .text(`${c2} >`); 316 | 317 | svg.append("g") 318 | .call(yAxis); 319 | } 320 | 321 | }, 322 | 323 | resize: function(width, height) { 324 | 325 | // TODO: code to re-render the widget with a new size 326 | 327 | } 328 | 329 | }; 330 | } 331 | }); 332 | -------------------------------------------------------------------------------- /inst/htmlwidgets/compareBars.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: d3 3 | version: 5.7.0 4 | src: htmlwidgets/lib/d3 5 | script: ./d3.min.js 6 | - name: compareBars 7 | src: htmlwidgets/lib/compareBars 8 | version: 0.0.1 9 | stylesheet: style.css 10 | - name: d3-tip 11 | src: htmlwidgets/lib/d3-tip 12 | version: 0.7.1 13 | script: 14 | - index-min.js 15 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/compareBars/style.css: -------------------------------------------------------------------------------- 1 | .d3-tipV { 2 | line-height: 1; 3 | font-weight: bold; 4 | padding: 12px; 5 | background: rgba(0, 0, 0, 0.8); 6 | color: #fff; 7 | border-radius: 2px; 8 | } 9 | 10 | .d3-tipV:after { 11 | box-sizing: border-box; 12 | display: inline; 13 | font-size: 10px; 14 | width: 100%; 15 | line-height: 1; 16 | color: rgba(0, 0, 0, 0.8); 17 | content: "\25BC"; 18 | position: absolute; 19 | text-align: center; 20 | } 21 | 22 | .d3-tipV.n:after { 23 | margin: -1px 0 0 0; 24 | top: 100%; 25 | left: 0; 26 | } 27 | 28 | .d3-tipH { 29 | line-height: 1; 30 | font-weight: bold; 31 | padding: 12px; 32 | background: rgba(0, 0, 0, 0.8); 33 | color: #fff; 34 | border-radius: 2px; 35 | pointer-events: none; 36 | } 37 | 38 | /*.d3-tipH:after { 39 | box-sizing: border-box; 40 | display: inline; 41 | font-size: 10px; 42 | width: 100%; 43 | line-height: 1; 44 | color: rgba(0, 0, 0, 0.8); 45 | content: "\25BC"; 46 | position: absolute; 47 | text-align: center; 48 | } */ 49 | 50 | .d3-tipH.w:after { 51 | content: "\25B6"; 52 | margin: -4px 0 0 -1px; 53 | top: 50%; 54 | left: 100%; 55 | } 56 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3-tip/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2013 Justin Palmer 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3-tip/README.md: -------------------------------------------------------------------------------- 1 | # d3.tip: Tooltips for d3.js visualizations 2 | 3 | [![](https://github-images.s3.amazonaws.com/skitch/Screen_Shot_2013-04-08_at_11.40.10_AM-20130408-114054.png)](http://bl.ocks.org/Caged/6476579) 4 | 5 | * [See a live demo](http://bl.ocks.org/Caged/6476579) 6 | * [Example code](/examples) 7 | 8 | ### API Docs 9 | See the [API Documentation](docs/index.md) 10 | 11 | ### Download Latest Version 12 | * [Development Version](https://raw.github.com/Caged/d3-tip/master/index.js) : **6kb** / **~2kb gzipped** 13 | 14 | ### Install with NPM 15 | ``` 16 | npm install d3-tip 17 | ``` 18 | 19 | ### Quick Usage 20 | ```javascript 21 | /* Initialize tooltip */ 22 | tip = d3.tip().attr('class', 'd3-tip').html(function(d) { return d; }); 23 | 24 | /* Invoke the tip in the context of your visualization */ 25 | vis.call(tip) 26 | 27 | vis.selectAll('rect') 28 | .data(data) 29 | .enter() 30 | .append('rect') 31 | .attr('width', function() { return x.rangeBand() }) 32 | .attr('height', function(d) { return h - y(d) }) 33 | .attr('y', function(d) { return y(d) }) 34 | .attr('x', function(d, i) { return x(i) }) 35 | .on('mouseover', tip.show) 36 | .on('mouseout', tip.hide) 37 | ``` 38 | 39 | If you want basic styling, you can include `example-styles.css` using a service like 40 | rawgithub.com. 41 | 42 | ```html 43 | 44 | ``` 45 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3-tip/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3-tip", 3 | "version": "0.7.1", 4 | "main": "index.js", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components", 9 | "bower_components", 10 | "examples", 11 | "Makefile", 12 | "docs" 13 | ], 14 | "dependencies": { 15 | "d3": "^4.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3-tip/index-min.js: -------------------------------------------------------------------------------- 1 | (function(root,factory){if(typeof define==="function"&&define.amd){define(["d3"],factory)}else if(typeof module==="object"&&module.exports){var d3=require("d3");module.exports=factory(d3)}else{root.d3.tip=factory(root.d3)}})(this,function(d3){return function(){var direction=d3_tip_direction,offset=d3_tip_offset,html=d3_tip_html,node=initNode(),svg=null,point=null,target=null;function tip(vis){svg=getSVGNode(vis);point=svg.createSVGPoint();document.body.appendChild(node)}tip.show=function(){var args=Array.prototype.slice.call(arguments);if(args[args.length-1]instanceof SVGElement)target=args.pop();var content=html.apply(this,args),poffset=offset.apply(this,args),dir=direction.apply(this,args),nodel=getNodeEl(),i=directions.length,coords,scrollTop=document.documentElement.scrollTop||document.body.scrollTop,scrollLeft=document.documentElement.scrollLeft||document.body.scrollLeft;nodel.html(content).style("opacity",1).style("pointer-events","all");while(i--)nodel.classed(directions[i],false);coords=direction_callbacks.get(dir).apply(this);nodel.classed(dir,true).style("top",coords.top+poffset[0]+scrollTop+"px").style("left",coords.left+poffset[1]+scrollLeft+"px");return tip};tip.hide=function(){var nodel=getNodeEl();nodel.style("opacity",0).style("pointer-events","none");return tip};tip.attr=function(n,v){if(arguments.length<2&&typeof n==="string"){return getNodeEl().attr(n)}else{var args=Array.prototype.slice.call(arguments);d3.selection.prototype.attr.apply(getNodeEl(),args)}return tip};tip.style=function(n,v){if(arguments.length<2&&typeof n==="string"){return getNodeEl().style(n)}else{var args=Array.prototype.slice.call(arguments);d3.selection.prototype.style.apply(getNodeEl(),args)}return tip};tip.direction=function(v){if(!arguments.length)return direction;direction=v==null?v:functor(v);return tip};tip.offset=function(v){if(!arguments.length)return offset;offset=v==null?v:functor(v);return tip};tip.html=function(v){if(!arguments.length)return html;html=v==null?v:functor(v);return tip};tip.destroy=function(){if(node){getNodeEl().remove();node=null}return tip};function d3_tip_direction(){return"n"}function d3_tip_offset(){return[0,0]}function d3_tip_html(){return" "}var direction_callbacks=d3.map({n:direction_n,s:direction_s,e:direction_e,w:direction_w,nw:direction_nw,ne:direction_ne,sw:direction_sw,se:direction_se}),directions=direction_callbacks.keys();function direction_n(){var bbox=getScreenBBox();return{top:bbox.n.y-node.offsetHeight,left:bbox.n.x-node.offsetWidth/2}}function direction_s(){var bbox=getScreenBBox();return{top:bbox.s.y,left:bbox.s.x-node.offsetWidth/2}}function direction_e(){var bbox=getScreenBBox();return{top:bbox.e.y-node.offsetHeight/2,left:bbox.e.x}}function direction_w(){var bbox=getScreenBBox();return{top:bbox.w.y-node.offsetHeight/2,left:bbox.w.x-node.offsetWidth}}function direction_nw(){var bbox=getScreenBBox();return{top:bbox.nw.y-node.offsetHeight,left:bbox.nw.x-node.offsetWidth}}function direction_ne(){var bbox=getScreenBBox();return{top:bbox.ne.y-node.offsetHeight,left:bbox.ne.x}}function direction_sw(){var bbox=getScreenBBox();return{top:bbox.sw.y,left:bbox.sw.x-node.offsetWidth}}function direction_se(){var bbox=getScreenBBox();return{top:bbox.se.y,left:bbox.e.x}}function initNode(){var node=d3.select(document.createElement("div"));node.style("position","absolute").style("top",0).style("opacity",0).style("pointer-events","none").style("box-sizing","border-box");return node.node()}function getSVGNode(el){el=el.node();if(el.tagName.toLowerCase()==="svg")return el;return el.ownerSVGElement}function getNodeEl(){if(node===null){node=initNode();document.body.appendChild(node)}return d3.select(node)}function getScreenBBox(){var targetel=target||d3.event.target;while("undefined"===typeof targetel.getScreenCTM&&"undefined"===targetel.parentNode){targetel=targetel.parentNode}var bbox={},matrix=targetel.getScreenCTM(),tbbox=targetel.getBBox(),width=tbbox.width,height=tbbox.height,x=tbbox.x,y=tbbox.y;point.x=x;point.y=y;bbox.nw=point.matrixTransform(matrix);point.x+=width;bbox.ne=point.matrixTransform(matrix);point.y+=height;bbox.se=point.matrixTransform(matrix);point.x-=width;bbox.sw=point.matrixTransform(matrix);point.y-=height/2;bbox.w=point.matrixTransform(matrix);point.x+=width;bbox.e=point.matrixTransform(matrix);point.x-=width/2;point.y-=height/2;bbox.n=point.matrixTransform(matrix);point.y+=height;bbox.s=point.matrixTransform(matrix);return bbox}function functor(v){return typeof v==="function"?v:function(){return v}}return tip}}); 2 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2017 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 10 | * [Release Notes](https://github.com/d3/d3/releases) 11 | * [Gallery](https://github.com/d3/d3/wiki/Gallery) 12 | * [Examples](https://bl.ocks.org/mbostock) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | 47 | In Node: 48 | 49 | ```js 50 | var d3 = require("d3"); 51 | ``` 52 | 53 | You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): 54 | 55 | ```js 56 | var d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); 57 | ``` 58 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/d3/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3", 3 | "description": "A JavaScript visualization library for HTML and SVG.", 4 | "main": "d3.js", 5 | "license": "BSD-3-Clause", 6 | "ignore": [] 7 | } 8 | -------------------------------------------------------------------------------- /inst/img/cbgif2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daranzolin/compareBars/3c56dae83dda15c4e3cb09712dbae5089d85e8d4/inst/img/cbgif2.gif -------------------------------------------------------------------------------- /inst/img/compareBars2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daranzolin/compareBars/3c56dae83dda15c4e3cb09712dbae5089d85e8d4/inst/img/compareBars2.png -------------------------------------------------------------------------------- /inst/img/compareBarstip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daranzolin/compareBars/3c56dae83dda15c4e3cb09712dbae5089d85e8d4/inst/img/compareBarstip.png -------------------------------------------------------------------------------- /inst/img/ggplots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daranzolin/compareBars/3c56dae83dda15c4e3cb09712dbae5089d85e8d4/inst/img/ggplots.png -------------------------------------------------------------------------------- /man/compareBars-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compareBars.R 3 | \name{compareBars-shiny} 4 | \alias{compareBars-shiny} 5 | \alias{compareBarsOutput} 6 | \alias{renderCompareBars} 7 | \title{Shiny bindings for compareBars} 8 | \usage{ 9 | compareBarsOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderCompareBars(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a compareBars} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using compareBars within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /man/compareBars.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compareBars.R 3 | \name{compareBars} 4 | \alias{compareBars} 5 | \title{Function for creating simple comparative bar charts.} 6 | \usage{ 7 | compareBars(data, ordinalVar = NULL, compareVar1 = NULL, 8 | compareVar2 = NULL, width = NULL, height = NULL, 9 | orientation = "vertical", xLabel = "", yLabel = "", titleLabel = "", 10 | subtitleLabel = "", compareVarFill1 = "#0072B2", 11 | compareVarFill2 = "#E69F00", minFillColor = "#ddd", 12 | fontFamily = "sans-serif", axisFormat = ".0s", tooltipFormat = ".0s") 13 | } 14 | \arguments{ 15 | \item{data}{a data frame object in wide form. Must have one string/factor column, and two numeric 16 | columns to compare.} 17 | 18 | \item{ordinalVar}{unquoted name of the ordinal variable} 19 | 20 | \item{compareVar1}{unquoted name of a numeric value to compare} 21 | 22 | \item{compareVar2}{unquoted name of another numeric value to compare} 23 | 24 | \item{width}{width of the chart in pixels} 25 | 26 | \item{height}{height of the chart in pixels} 27 | 28 | \item{orientation}{if "vertical", the bars will render vertically along the x-axis. If 'horizontal', 29 | the bars will render horizontally along the y-axis.} 30 | 31 | \item{xLabel}{optional label for the x-axis} 32 | 33 | \item{yLabel}{optional label for the y-axis} 34 | 35 | \item{titleLabel}{optional label for the title} 36 | 37 | \item{subtitleLabel}{optional label for the subtitle} 38 | 39 | \item{compareVarFill1}{fill color for one of the levels} 40 | 41 | \item{compareVarFill2}{fill color for the other level} 42 | 43 | \item{minFillColor}{fill color for the smaller value} 44 | 45 | \item{fontFamily}{font family for the labels} 46 | 47 | \item{axisFormat}{axis formatting option, cf. d3-format on github} 48 | 49 | \item{tooltipFormat}{tooltip formatting option, cf. d3-format on github} 50 | } 51 | \description{ 52 | Simplify comparative bar charts with d3.js: two values, one bar. For each level of an ordinal variable, 53 | compareBars compares the two values, and returns the smaller as a uniform color, and the larger 54 | remainder as a distinct color. 55 | } 56 | \examples{ 57 | \dontrun{ 58 | library(gapminder) 59 | library(tidyverse) 60 | gapminder \%>\% 61 | group_by(continent, year) \%>\% 62 | summarize(populations = sum(pop)) \%>\% 63 | spread(continent, populations) \%>\% 64 | mutate(year = factor(year)) \%>\% 65 | compareBars(year, Americas, Europe) 66 | } 67 | } 68 | --------------------------------------------------------------------------------