Добавьте highcharts plotband после рендера в R блестящий /rcharts

Я пытаюсь воспроизвести эту ( jsfiddle) функциональность highcharts в приложении, работающем с rCharts и блестящем. Я хочу, чтобы пользовательское событие (изменяющее значение в текстовом поле) добавляло сюжетную полосу к уже обработанному графику (или в идеале удаляло предыдущий / добавляло новое). Я могу заставить его работать, перерисовывая график с помощью plotband в опциях xAxis, но это может быть очень медленным для некоторых графиков, которые я рисую.

Я не уверен, есть ли функциональность в пакетах r, но есть ли способ попасть в javascript для выполнения функции?

Вот минимальный рабочий пример:

server.R

library(shiny)
library(plyr)
library(rCharts)
shinyServer(function(input, output,session){
  output$h1chart <- renderChart({
    h1 <- rCharts::Highcharts$new()
    h1$chart(type = "spline")
    h1$series(data = c(1, 3, 2, 4, 5, 4, 6, 2, 3, 5, NA), dashStyle = "longdash")
    h1$series(data = c(NA, 4, 1, 3, 4, 2, 9, 1, 2, 3, 4), dashStyle = "shortdot")
    h1$legend(symbolWidth = 80)
    h1$xAxis(title = list(text = "Test Plot"),startOnTick=TRUE,min=1,max=9,endOnTick=TRUE,
          plotBands = list(list(from=1.5,to=3.5,color='rgba(68, 170, 213, 0.1)',label=list(text="1",style=list(color="#6D869F"),verticalAlign="bottom"))))
    h1$set(dom="h1chart")
    return(h1)
  })
  output$selectedOut <- renderUI({
    numericInput("selected", "", value=2.5)
  })
  output$windowOut <- renderUI({    
    sliderInput(inputId="window",label="Window size around selected point:",min=1,max=5,value=2)
  })
})#end server

ui.R:

library(shiny)
library(plyr)
library(rCharts)
shinyUI(pageWithSidebar(
  headerPanel(""),
  sidebarPanel(
    wellPanel(
      h6("Change here should update plotband:"),
      uiOutput("selectedOut"),
      uiOutput("windowOut")
    ),
    tags$head(tags$style(type="text/css", ".jslider { max-width: 245px; }"),tags$style(type='text/css', ".well { max-width: 250px; }"),
          tags$style(type='text/css', ".row-fluid .span4 {width: 20%}\n.row-fluid .span8 {width: 75%}"))
  ),
  mainPanel(showOutput("h1chart","highcharts"))  
))

Я могу зафиксировать изменения в числовом поле / ползунке с помощью этой функции:

addPB <- reactive({
  center <- as.numeric(input$selected[[1]])
  winHigh <- center+input$window[1]
  winLow <- center-input$window[1] #eventually I would use winLow/winHigh to change the plotband range
  list(winLow=winLow,winHigh=winHigh)
})
observe(print(addPB()$winLow))

И я пытался создать функцию javascript для их запуска, но я не знаю, как это сделать, как получить доступ к объекту старшей диаграммы с помощью javascript или как заставить код выполняться из блестящего кода.

#!function(){$('#container').highcharts().xAxis[0].addPlotBand({from: 2,to: 4, color: 'rgba(68, 170, 213, 0.1)', label: 'asdf'}); } !#

1 ответ

Решение

Вы можете сделать это с помощью передачи сообщений в Shiny. Вот как это работает. Всякий раз, когда вы меняете данные в ползунке или numericInput, сообщение отправляется на сервер с помощью session$sendCustomMessage вместе с полезной нагрузкой JSON, которая в этом случае band,

На стороне сервера сообщение получено Shiny.addCustomMessageHandler, Мы получаем доступ к существующей полосе, удаляем ее и затем создаем новую полосу, используя параметры, полученные обработчиком.

Для более подробного обзора передачи сообщений в Shiny, я бы порекомендовал прочитать этот отличный пост в блоге Марка Хекмана

Добавьте следующий код в server.R и ui.R

# addition to server.R
observe({
    center <- as.numeric(input$selected[[1]])
    winHigh <- center + input$window[1]
    winLow <- center - input$window[1]
    #eventually I would use winLow/winHigh to change the plotband range
    band = list(from = winLow, to = winHigh, color = "rgba(68, 170, 213, 0.1)")
    print(band)
    session$sendCustomMessage(type = "customMsg", band)
})

# addition to ui.R
mainPanel(
  showOutput("h1chart","highcharts"),
  tags$script('Shiny.addCustomMessageHandler("customMsg", function(bandOpts){
     chartXAxis = $("#h1chart").highcharts().xAxis[0]
     chartXAxis.removePlotBand()
     chartXAxis.addPlotBand(bandOpts)
   })')
)
Другие вопросы по тегам