Skip to content

Instantly share code, notes, and snippets.

@yjunechoe
Created July 29, 2021 12:30
Show Gist options
  • Select an option

  • Save yjunechoe/074e0020841fec3009b239583f305adc to your computer and use it in GitHub Desktop.

Select an option

Save yjunechoe/074e0020841fec3009b239583f305adc to your computer and use it in GitHub Desktop.
{r2d3} + {crosstalk}
---
title: "r2d3 fun2"
output:
html_document:
highlight: tango
---
```{r}
r2d3_xtalk <- function(...) {
# capture arguments to be passed to r2d3
args <- list(...)
# intercept and modify if shared data
if (crosstalk::is.SharedData(args$data)) {
crosstalkOpts <- list(
key = args$data$key(),
group = args$data$groupName()
)
args$data <- args$data$origData()
args$data$`__crosstalkKey__` <- crosstalkOpts$key
args$dep <- c(args$dep, crosstalk::crosstalkLibs())
args$options <- c(args$options, list("__crosstalkGroup__" = crosstalkOpts$group))
}
do.call(r2d3::r2d3, args)
}
```
```{r, out.width="100%"}
library(crosstalk)
library(htmltools)
library(DT)
mtcars_shared <- SharedData$new(mtcars[c("mpg", "hp")])
bscols(widths = c(4, 8),
tags$div(
tags$div(
list(
filter_slider("mpg", "Miles Per Gallon", mtcars_shared, ~mpg),
filter_slider("hp", "Horse Power", mtcars_shared, ~hp)
),
style = "padding: 10px 30px; border: 3px solid grey; border-radius: 5px; height: 100%"
),
datatable(mtcars_shared, width = "100%", options = list(pageLength = 4, dom = 'tp'))
),
r2d3_xtalk("xtalk_r2d3_test.js", data = mtcars_shared, width = "100%")
)
```
// crosstalk setup
const filterHandle = new crosstalk.FilterHandle()
filterHandle.setGroup(options.__crosstalkGroup__)
// plot code
const dims = {
margin: {t: 10, r: 20, b: 20, l: 25}
}
dims.panel = {
width: width - dims.margin.r - dims.margin.l,
height: height - dims.margin.t - dims.margin.b
}
const xScale = d3.scaleLinear()
.domain(d3.extent(data, d => d.mpg))
.range([0, dims.panel.width])
.nice()
const yScale = d3.scaleLinear()
.domain(d3.extent(data, d => d.hp))
.range([0, dims.panel.height])
.nice()
const panel = svg.append("g")
.style("transform", `translate(${dims.margin.l}px, ${dims.margin.t}px)`)
panel.selectAll("circle")
.data(data, d => d.__crosstalkKey__)
.join("circle")
.attr("cx", d => xScale(d.mpg))
.attr("cy", d => yScale(d.hp))
.attr("r", 5)
.attr("fill", "steelblue")
function update(filteredData) {
panel.selectAll("circle")
.data(filteredData, d => d.__crosstalkKey__)
.join("circle")
.attr("cx", d => xScale(d.mpg))
.attr("cy", d => yScale(d.hp))
.attr("r", 5)
.attr("fill", "steelblue")
}
panel.append("g").style("transform", `translate(0px, ${dims.panel.height}px)`).call(d3.axisBottom(xScale))
panel.append("g").call(d3.axisLeft(yScale))
panel.append("text")
.attr("x", 550)
.attr("y", 450)
.text("Custon D3 plot made in {r2d3}")
.style("text-anchor", "end")
.style("font-size", "22px")
// crosstalk callbacks
filterHandle.on("change", function(e) {
update(data.filter(d => e.value.includes(d.__crosstalkKey__)))
})
@yjunechoe
Copy link
Copy Markdown
Author

r2d3_xtalk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment