vueR
vueR copied to clipboard
link vue to crosstalk?
Playing around and here is a quick example. In reality, crosstalk can be subsumed by Vue as simply a shared, reactive state mechanism.
with crosstalk api
library(vueR)
library(crosstalk)
library(htmltools)
data(mtcars)
sd <- SharedData$new(mtcars)
browsable(
tagList(
html_dependency_vue(minified = FALSE),
filter_select("gear", "Gears", sd, ~gear),
filter_slider("mpg", "Miles per gallon", sd, "mpg"),
filter_slider("cyl", "Cylinders", sd, "cyl"),
tags$div(
id = "app",
tags$h3("Filter Handle"),
"{{ filter.filteredKeys ? filter.filteredKeys : 'nothing filtered' }}",
tags$h3("Selection Handle"),
"{{ selection.value ? selection.value : 'nothing selected' }}"
),
tags$script(HTML(
sprintf(
"
const app = new Vue({
el: '#app',
data() {
return {
filter: new crosstalk.FilterHandle('%1$s'),
selection: new crosstalk.SelectionHandle('%1$s')
}
}
})
",
sd$groupName()
)
))
)
)
with crosstalk api and plotly
library(crosstalk)
library(plotly)
library(vueR)
library(htmltools)
tx <- highlight_key(txhousing)
widgets <- bscols(
widths = c(12, 12, 12),
filter_select("city", "Cities", tx, ~city),
filter_slider("sales", "Sales", tx, ~sales),
filter_checkbox("year", "Years", tx, ~year, inline = TRUE)
)
bc <- bscols(
widths = c(4, 8), widgets,
plot_ly(tx, x = ~date, y = ~median, showlegend = FALSE) %>%
add_lines(color = ~city, colors = "black")
)
browsable(
tagList(
html_dependency_vue(minified = FALSE),
bc,
tags$div(
id = "app",
tags$h3("Filter Handle"),
"{{ filter.filteredKeys ? filter.filteredKeys : 'nothing filtered' }}",
tags$h3("Selection Handle"),
"{{ selection.value ? selection.value : 'nothing selected' }}"
),
tags$script(HTML(
sprintf(
"
const app = new Vue({
el: '#app',
data() {
return {
filter: new crosstalk.FilterHandle('%1$s'),
selection: new crosstalk.SelectionHandle('%1$s')
}
}
})
",
tx$groupName()
)
))
)
)
library(crosstalk)
library(plotly)
library(vueR)
library(htmltools)
mh <- mtcars %>% highlight_key(~cyl)
pl <- mh %>%
plot_ly(
x = ~wt, y = ~mpg, text = ~cyl, mode = "markers+text",
textposition = "top", hoverinfo = "x+y"
) %>%
highlight(on = "plotly_hover", off = "plotly_doubleclick")
browsable(
tagList(
html_dependency_vue(minified = FALSE),
pl,
tags$div(
id = "app",
tags$h3("Filter Handle"),
"{{ filter.filteredKeys ? filter.filteredKeys : 'nothing filtered' }}",
tags$h3("Selection Handle"),
"{{ selection.value ? selection.value : 'nothing selected' }}"
),
tags$script(HTML(
sprintf(
"
const app = new Vue({
el: '#app',
data() {
return {
filter: new crosstalk.FilterHandle('%1$s'),
selection: new crosstalk.SelectionHandle('%1$s')
}
}
})
",
mh$groupName()
)
))
)
)
direct (unadvisable)
library(vueR)
library(crosstalk)
library(htmltools)
data(mtcars)
sd <- SharedData$new(mtcars)
browsable(
tagList(
html_dependency_vue(minified = FALSE),
filter_slider("mpg", "Miles per gallon", sd, "mpg"),
filter_slider("cyl", "Cylinders", sd, "cyl"),
tags$div(
id = "app",
"{{ $data.get()._value ? $data.get()._value : 'nothing filtered' }}"
),
tags$script(HTML(
sprintf(
"
const app = new Vue({
el: '#app',
data() {
return crosstalk.group('%s').var('filterset')
}
})
",
sd$groupName()
)
))
)
)
nice!
I thought it would be fun to use a Vuetify v-select component to control crosstalk. Here is my first approach.
library(crosstalk)
library(plotly)
library(vueR)
library(htmltools)
mh <- mtcars %>% highlight_key(~cyl)
pl <- mh %>%
plot_ly(
x = ~wt, y = ~mpg, text = ~cyl, mode = "markers+text",
textposition = "top", hoverinfo = "x+y"
) %>%
highlight(on = "plotly_hover", off = "plotly_doubleclick")
browsable(
tagList(
vueR::html_dependency_vue(minified = FALSE),
tags$head(
tags$link(href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css", rel="stylesheet"),
tags$link( href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900", rel="stylesheet"),
tags$link(href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css", rel="stylesheet"),
tags$script(src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js")
),
tag(
"v-app",
list(
id = "app",
tags$div(HTML("<v-select :items = 'cyl' @change = 'updateSelected' v-model= 'selected' multiple chips/>")),
pl,
tags$h3("Filter Handle"),
"{{ filter.filteredKeys ? filter.filteredKeys : 'nothing filtered' }}",
tags$h3("Selection Handle"),
"{{ selection.value ? selection.value : 'nothing selected' }}"
)
),
tags$script(HTML(
sprintf(
"
const app = new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
filter: new crosstalk.FilterHandle('%1$s'),
selection: new crosstalk.SelectionHandle('%1$s'),
cyl: %2$s.map(d => d.toString()) // crosstalk keys are strings
}
},
computed: {
selected: function() {return this.selection.value}
},
methods: {
updateSelected: function(val) {
this.selection.set(Array.isArray(val) ? val : [val])
}
}
})
",
mh$groupName(),
jsonlite::toJSON(sort(unique(mh$data()$cyl)),auto_unbox=TRUE)
)
))
)
)
