Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link vue to crosstalk? #12

Open
timelyportfolio opened this issue May 21, 2021 · 2 comments
Open

link vue to crosstalk? #12

timelyportfolio opened this issue May 21, 2021 · 2 comments

Comments

@timelyportfolio
Copy link
Collaborator

timelyportfolio commented May 21, 2021

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()
)
    ))
  )
)
@FrissAnalytics
Copy link

nice!

@timelyportfolio
Copy link
Collaborator Author

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/vuetify@2.x/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/font@4.x/css/materialdesignicons.min.css", rel="stylesheet"),
      tags$script(src="https://cdn.jsdelivr.net/npm/vuetify@2.x/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)
)
    ))
  )
)

vuetify_plotly_crosstalk

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

No branches or pull requests

2 participants