├── .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 | [](https://travis-ci.org/daranzolin/compareBars)
18 |
19 | >"Less is more."
20 |
21 | >"Simplify simplify."
22 |
23 | 
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 | 
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 | 
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 | 
98 |
99 | Note that you must reshape your data into a 'non-tidy' form.
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # compareBars
5 |
6 | [](https://travis-ci.org/daranzolin/compareBars)
8 |
9 | > “Less is more.”
10 |
11 | > “Simplify simplify.”
12 |
13 | 
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 | 
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 | 
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 | 
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 | [](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 |
--------------------------------------------------------------------------------