Yes, R users can use React as shown in this blog post. This example uses Semiotic
from Elijah Meeks. I temporarily built a standalone JS while issue gets resolved by the real experts.
This is a replication of the Semiotic dotplot example. The JavaScript is mostly copied directly from the example except for minor modifications to inject R data.
library(htmltools)
library(reactR)
library(tidyr)
# thanks to https://github.com/emeeks/semiotic/issues/70
# use unpkg for semiotic
semiotic <- htmlDependency(
name = "semiotic",
version = "1.2.4",
src = c(href = "https://unpkg.com/semiotic/dist"),
script = "semiotic.min.js"
)
# original data was in wide format
dotwide <- data.frame(
region = c("Developed regions", "Developing regions", "Northern Africa", "Sub-Saharan Africa", "Latin America and the Caribbean", "Caucasus and Central Asia", "Eastern Asia", "Eastern Asia excluding China", "Southern Asia", "Southern Asia excluding India", "South-eastern Asia", "Western Asia", "Oceania", "World"),
y1990 = c(7.6, 36.4, 30, 45.5, 22.1, 25.7, 24.5, 11.6, 50.6, 49.3, 27.4, 27.5, 26.3, 33.3),
y2013 = c(3.4, 22, 13.3, 31.1, 9.2, 14.8, 7.7, 7.5, 29.5, 30.1, 14.4, 13.7, 21.3, 20),
stringsAsFactors = FALSE
)
# convert to long format in R rather than JavaScript
dotlong <- gather(dotwide, type, value, -region)
dotplot <- tags$script(HTML(babel_transform(
sprintf('
const colors = {
y1990: "#00a2ce",
y2013: "#4d430c"
};
const dotRadius = 8;
const baseData = %s
const data = %s;
const lineAnnotations = baseData.map(d => Object.assign({ type: "range" }, d));
function drawRange({ d, rScale, orFrameState }) {
if (d.type === "range") {
const start = rScale(d.y1990) - dotRadius;
const end = rScale(d.y2013) + dotRadius;
const y = orFrameState.projectedColumns[d.region].middle;
return (
<line
key={`connector-${d.region}`}
x1={start}
x2={end}
y1={y}
y2={y}
style={{ stroke: "black", strokeWidth: 2 }}
/>
);
}
return null;
}
const dotplot =
<Semiotic.ORFrame
title={"Neonatal Mortality Rate by Region"}
size={[700, 500]}
data={data}
rAccessor={d => d.value}
oAccessor={d => d.region}
style={(d, i) => ({
fill: colors[d.type],
stroke: "white",
strokeWidth: 1
})}
type={{ type: "point", r: dotRadius }}
projection={"horizontal"}
axis={{ orient: "bottom", tickFormat: d => `${d}%%` }}
margin={{ left: 215, top: 50, bottom: 40, right: 10 }}
oPadding={10}
svgAnnotationRules={drawRange}
annotations={lineAnnotations}
pieceHoverAnnotation={true}
oLabel={d => (
<text style={{ textAnchor: "end" }} transform="translate(-15,6)">
{d}
</text>
)}
/>
ReactDOM.render(dotplot, document.body)
',
jsonlite::toJSON(dotwide, dataframe="rows"),
jsonlite::toJSON(dotlong, dataframe="rows")
)
)))
browsable(
tagList(
dotplot,
html_dependency_react(offline=FALSE),
semiotic
)
)
https://unpkg.com/react/umd/react.production.min.js
https://unpkg.com/react-dom/umd/react-dom.production.min.js
https://unpkg.com/semiotic/dist/semiotic.min.js