-
Notifications
You must be signed in to change notification settings - Fork 103
/
package_development.Rmd
148 lines (101 loc) · 5.72 KB
/
package_development.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
---
title: "Package Development"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Package Development}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(eval = FALSE)
```
## Overview
You can redistribute your D3 visualizations as reusable components if you bundle them within an R package. There are two ways to accomplish this:
1) Create a wrapper function for the requisite call to `r2d3()` and include that in a package; or
2) Use your D3 script as the basis for the creation of an [htmlwidget](http://www.htmlwidgets.org).
This article covers both of these techniques, and also describes how to use the `html_dependencies_d3()` function to include multiple distinct versions of D3 within a document or application.
## R2D3 wrapper function
The simplest way to include a D3 visualization you have created with **r2d3** in an R package is to create a wrapper function. There are a few things to keep in mind when creating a wrapper function:
1) You should use `system.file()` for references to the D3 script or any other files (e.g. CSS stylesheets).
2) You should expose any [user level options](visualization_options.html#user-options) as arguments to your wrapper function.
3) You should include `width` and `height` parameters to enable callers of the function to explicitly override your [sizing policy](visualization_options.html#custom-sizing).
Here's an example wrapper function which illustrates:
```{r}
d3_barchart <- function(data, color = "orange", width = NULL, height = NULL) {
r2d3::r2d3(
data = data,
script = system.file("d3/barchart/barchart.js", package = "d3barchart"),
width = width,
height = height
)
}
```
## Creating an htmlwidget
The `r2d3()` function provides a generic mechanism for turning a standalone D3 visualization script into an [htmlwidget](http://www.htmlwidgets.org). Depending on your requirements, you may find it more convenient to convert your D3 script into a full blown htmlwidget.
The [htmlwidgets interface](http://www.htmlwidgets.org/develop_intro.html) provides more granular mechanisms for rendering visualizations, including distinguishing between code for one-time initialization, re-rendering based on new data, and resizing.
If you plan on creating an htmlwidget and wish to use version 4 or 5 of D3, please see the section below on [using multiple versions of d3] to ensure that you don't break other widgets that might be relying on an older version of D3.
Not that the **r2d3** package also supports an [advanced rendering](advanced_rendering.html) interface that more closely approximates the htmlwidgets API. Converting your visualization to use to the advanced rendering interface is therefore a good first step towards creating an htmlwidget.
## Multiple versions of D3
Many existing [htmlwidgets](http://www.htmlwidgets.org) use version 3 of the D3 library, which has the potential to cause problems when mixed with D3 visualizations that make use of version 4 or 5 of D3. This is because major versions of D3 are incompatible, so using version 4 or 5 with code written for version 3 will result in errors.
The **r2d3** package includes an `html_dependencies_d3()` function which enables you to use multiple incompatible versions of D3 within a single document or application. This is accomplished by renaming the global D3 object with a version suffix. So when using `html_dependencies_d3()` the following are the correct references to D3:
| Version | Object |
|---------------------|---------------------|
| 3 | `d3` |
| 4 | `d3v4` |
| 5 | `d3v5` |
For example, if you are using version 4 of D3 then your code might look like this:
```js
var outerRadius = Math.min(width, height) * 0.5 - 40,
innerRadius = outerRadius - 30;
var formatValue = d3v4.formatPrefix(",.0", 1e3);
var chord = d3v4.chord()
.padAngle(0.05)
.sortSubgroups(d3v4.descending);
var arc = d3v4.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var ribbon = d3v4.ribbon()
.radius(innerRadius);
```
Note that all references to the D3 library use `d3v4`.
Alternatively you could also create a local `d3` alias like this:
```js
var d3 = d3v4;
var outerRadius = Math.min(width, height) * 0.5 - 40,
innerRadius = outerRadius - 30;
var formatValue = d3.formatPrefix(",.0", 1e3);
var chord = d3.chord()
.padAngle(0.05)
.sortSubgroups(d3.descending);
var arc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var ribbon = d3.ribbon()
.radius(innerRadius);
```
This local alias technique is in fact what `r3d3()` does when executing D3 visualization scripts so you can always use `d3` to reference the D3 library and know you are getting the correct version.
However, if you are [creating an htmlwidget] you will need to be sure to reference the correct version of D3 (i.e. `d3`, `d3v4`, or `d3v4`) explicitly.
To incorporate the renamed, multiple-version friendly D3 libraries provided by **r2d3** into an [htmlwidget](http://www.htmlwidgets.org) you can use the `dependencies` argument of the `htmlwidgets::createWidget()` function. For example:
```{r}
htmlwidgets::createWidget(
"mywidget",
x,
width = width,
height = height,
package = "mypackage",
dependencies = r2d3::html_dependencies_d3(version = "4")
)
```
## d3-jetpack
The `html_dependencies_d3()` function has can optionally include [d3-jetpack](https://github.com/gka/d3-jetpack) along with D3. Include d3-jetpack by specifying it within the optional `extensions` argument:
```{r}
htmlwidgets::createWidget(
"mywidget",
x,
width = width,
height = height,
package = "mypackage",
dependencies = r2d3::html_dependencies_d3(version = "4",
extensions = "d3-jetpack")
)
```