使用 reactR 编写基于 React 的 htmlwidgets

使用 reactR 编写基于 React 的 htmlwidgets

Authoring htmlwidgets powered by React with reactRreactR 提供的介绍文档,该文使用 sparklines 作为示例讲解了如何使用 reactR 编写自己的 html 控件。

前几步

Build Your Own React-based htmlwidget!!! 一文中我已经介绍了开头需要的一些操作,这里不再赘述:

1
2
3
4
5
# 创建包
usethis::create_package('sparklines')
# 创建html控件
# https://unpkg.com/[email protected]/
reactR::scaffoldReactWidget('sparklines', npmPkgs = c("react-sparklines" = "^1.7.0"))

编译 JavaScript

注意这里需要按照 Build Your Own React-based htmlwidget!!! 中的方法修改 webpack.config.js

1
2
yarn install
yarn run webpack

安装与运行测试

1
2
3
devtools::document()
devtools::install(quick = TRUE)
shiny::runApp()

如果出现了hello word就说明你的包初步建立成功了。

自定义绑定

这里我们选择 react-sparklines 中的这个示例:

1
2
3
4
5
6
7
import React from 'react';
import { Sparklines } from 'react-sparklines';

<Sparklines data={sampleData}>
<SparklinesLine color="#56b45d" />
<SparklinesSpots style={{ fill: "#56b45d" }} />
</Sparklines>

我们希望最终的 R 函数是这样的:

1
2
3
4
5
6
library(sparklines)
sparklines(
data = sampleData,
sparklinesLine(color = "#56b45d"),
sparklinesSpots(style = list(fill = "#56b45d"))
)

R 函数绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sparklines <- function(data, ..., width = NULL, height = NULL) {

# describe a React component to send to the browser for rendering.
content <- reactR::component(
"Sparklines",
list(data = data, ...)
)

# create widget
htmlwidgets::createWidget(
name = 'sparklines',
reactR::reactMarkup(content),
width = width,
height = height,
package = 'sparklines'
)
}

我们还需要再定义一些函数来使得用户更容易的定义其它组件:

1
2
3
4
5
6
7
8
9
#' @export
sparklinesLine <- function(...) {
reactR::React$SparklinesLine(...)
}

#' @export
sparklinesSpots <- function(...) {
reactR::React$SparklinesSpots(...)
}

JS 绑定

我们需要将 sparklines.js 文件修改成下面的样子:

1
2
3
4
5
6
7
8
import { Sparklines, SparklinesLine, SparklinesSpots } from 'react-sparklines';
import { reactWidget } from 'reactR';

reactWidget('sparklines', 'output', {
Sparklines: Sparklines,
SparklinesLine: SparklinesLine,
SparklinesSpots: SparklinesSpots
});

再次安装测试

JS
1
2
yarn install
yarn run webpack --mode=development
1
2
devtools::document()
devtools::install(quick = TRUE)

再把 shiny 中 server 里面的绘图部分改成:

1
2
3
4
5
sparklines(
rnorm(100),
sparklinesLine(color = "#56b45d"),
sparklinesSpots(style = list(fill = "#fff"))
)

运行:

1
shiny::runApp()

未来的探索

实际上我研究了好多次,尝试在图表中增加图例、标题等东西,但是始终没有效果。

nivopie @jienagu

我发现这位朋友也写了个 nivopie :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# devtools::install_github("jienagu/nivopie")
library(nivopie)
df2 <- data.frame(
id = c("A", "B", "C", "D", "e", "f", "g"),
value = c(12, 13, 45, 90, 250, 300, 500),
label = c("a", "b", "c", "d", "e", "f", "g")
)
df2$id <- as.factor(df2$id)

nivopie(df2, innerRadius = 0.5,
cornerRadius = 5,
fit = T, sortByValue = T,
colors = 'set2',
enableRadialLabels = F,
radialLabelsLinkDiagonalLength = 1,
radialLabelsLinkHorizontalLength = 8,
enableSlicesLabels = T,
sliceLabel = 'id',
isInteractive = T)

# R

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×