Vinculando javascript (d3.js) a brilhante

Primeiro, não estou familiarizado com javascript e sua biblioteca d3.js., mas estou familiarizado com R. Criar painéis usando o Shiny foi divertido e fácil (graças ao stackoverflow). Agora eu quero expandi-lo conectando elementos d3 a ele.

Estou procurando fontes de informações sobre como realmente vincular o javascript ao Shiny (painel R) e explicar o que realmente está acontecendo.

Contexto: Fiz o tutorial sobre js e jquery no w3schools e aprendi (um pouco) sobre o d3 usando o livro de Scott Murray (visualização de dados interativos para a web). Eu esperava que isso fosse suficiente para me fazer entender os exemplos e as explicações sobre como criar ligações personalizadas de entrada / saída no site da Shiny:

http://shiny.rstudio.com/articles/building-inputs.html

Mas, infelizmente, não encontro e não consigo encontrar nenhum exemplo que esteja no código de trabalho mínimo. Muitos exemplos no github são complexos para eu dissecar, provavelmente por causa da minha pouca experiência com javascript. Aqui estão alguns exemplos de ligação de entrada personalizada com javascript:

https://github.com/jcheng5/shiny-js-examples/tree/master/input

Aqui está um exemplo de uma ligação de entrada e saída que tento desdobrar:

<script src="http://d3js.org/d3.v3.js"></script>
<script type="text/javascript">
(function(){
  // Probably not idiomatic javascript.

  this.countValue=0;

  // BEGIN: FUNCTION
  updateView = function(message) {

    var svg = d3.select(".d3io").select("svg")

    svg.append("text")
      .transition()
      .attr("x",message[0])
      .attr("y",message[1])
      .text(countValue)
      .each("end",function(){
        if(countValue<100) {
          countValue+=1;
          $(".d3io").trigger("change");
        }
      })
  }
  // END: FUNCTION

  //BEGIN: OUTPUT BINDING
  var d3OutputBinding = new Shiny.OutputBinding();
  $.extend(d3OutputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    renderError: function(el,error) {
      console.log("Foe");
    },
    renderValue: function(el,data) {
      updateView(data);
      console.log("Friend");
    }
  });
  Shiny.outputBindings.register(d3OutputBinding);
  //END: OUTPUT BINDING

  //BEGIN: INPUT BINDING
  var d3InputBinding = new Shiny.InputBinding();
  $.extend(d3InputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    getValue: function(el) {
      return countValue;
    },
    subscribe: function(el, callback) {
      $(el).on("change.d3InputBinding", function(e) {
        callback();
      });
    }
  });
  Shiny.inputBindings.register(d3InputBinding);
 //END: OUTPUT BINDING

})()
</script>

Onde "d3io" é um elemento div na interface do usuário, updateView () é uma função. Aqui está a interface do usuário:

#UI
library(shiny)

d3IO <- function(inputoutputID) {
  div(id=inputoutputID,class=inputoutputID,tag("svg","")) #; eerst zat ; erbij, maar werkt blijkbaar ook zonder
}

# Define UI for shiny d3 chatter application
shinyUI(pageWithSidebar(

  # Application title
  headerPanel("D3 Javascript chatter",
              "Demo of how to create D3 I/O and cumulative data transfer"),

  sidebarPanel(
    tags$p("This widget is a demonstration of how to wire shiny direct to javascript, without any input elements."),
    tags$p("Each time a transition ends, the client asks the server for another packet of information, and adds it
            to the existing set"),
    tags$p("I can't claim this is likely to be idiomatic javascript, because I'm a novice, but it allows d3 apps
            to do progressive rendering.  In real use, a more complex request/response protocol will probably be
            required.  -AlexBBrown")
  ),

  mainPanel(
    includeHTML("d3widget.js"),
    d3IO("d3io") #Creates div element that d3 selects
    )
))

Aqui está o arquivo do servidor:

# SERVER
library(shiny)
# Define server logic required to respond to d3 requests
shinyServer(function(input, output) {

  # Generate a plot of the requested variable against mpg and only 
  # include outliers if requested
  output$d3io <- reactive(function() {
    if (is.null(input$d3io)) {
      0;
    } else {
      list(rnorm(1)*400+200,rnorm(1)*400+200);
    }
  })
})

Questões específicas:

1) O server.r parece receber uma entrada chamada "d3io" (entrada $ d3io), pois isso não está definido no ui.r, concluí que ele deve vir do arquivo javascript. A qual elemento ele realmente se refere?

2) Tenho problemas para entender a parte de ligação personalizada:

var d3OutputBinding = new Shiny.OutputBinding();
  $.extend(d3OutputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    renderError: function(el,error) {
      console.log("Foe");
    },
    renderValue: function(el,data) {
      updateView(data);
      console.log("Friend");
    }
  });
  Shiny.outputBindings.register(d3OutputBinding);

Meu entendimento é:

Crie uma nova ligação de saída brilhante, encontre primeiro a classe .d3io (elemento div), se o erro for gravado no console "Foe" (esse código especial?), Se não houver erro, renderValue usando a função updateView using data (Onde ele recebe esse valor de?) e escreva no console "Friend". Por fim, registre a saída.

Espero que vocês possam ajudar! Estou criando um documento com as etapas em "As etapas necessárias para aprender a implementar o javascript em brilhante quando você não conhece nenhum javascript", eu adoraria! :)

Saúde, longo

questionAnswers(4)

yourAnswerToTheQuestion