将javascript(d3.js)绑定到闪亮

Swe*_*sus 39 javascript r d3.js shiny

首先,我对javascript及其库d3.js相当不熟悉,但我熟悉R.使用Shiny创建仪表板非常有趣(感谢stackoverflow).现在我想通过连接d3元素来扩展它.

我正在寻找有关如何将javascript实际绑定到Shiny(R仪表板)并解释实际情况的信息来源.

背景:我在w3schools上做了关于js和jquery的教程,并使用Scott Murray的书(Web上的交互式数据可视化)学习了一些关于d3的知识.我希望这足以让我理解有关如何在Shiny网站上构建自定义输入/输出绑定的示例和解释:

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

但不幸的是,我没有,我似乎无法找到任何最小工作代码的例子.关于github的许多例子都让我很难解剖,很可能是因为我对javascript的经验很少.以下是使用javascript自定义输入绑定的示例:

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

这是我尝试展开的输入和输出绑定的示例:

<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>
Run Code Online (Sandbox Code Playgroud)

其中"d3io"是ui中的div元素,updateView()是一个函数.这是ui:

#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
    )
))
Run Code Online (Sandbox Code Playgroud)

这是服务器文件:

# 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);
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

具体问题:

1)server.r似乎得到了名为"d3io"的输入(输入$ d3io),因为这没有在ui.r中定义,我推断它必须来自javascript文件.它实际上指的是哪个元素?

2)我无法理解自定义绑定部分:

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);
Run Code Online (Sandbox Code Playgroud)

我的理解是:

创建一个新的闪亮输出绑定,首先找到类.d3io(div元素),如果错误然后写入控制台"Foe"(这是特殊代码?),如果没有错误那么renderValue使用函数updateView使用数据(它在哪里接收)这个值来自?)并写入控制台"朋友".最后注册输出.

希望你们能帮忙!我正在创建一个文档,其中的步骤是"学习如何在不知道任何javascript的情况下将javascript实现为闪亮的必要步骤",我很乐意!:)

干杯,龙

gkn*_*ker 11

你好Sweetbabyjesus(这很有趣).你有两个问题:

1)server.r似乎得到了名为"d3io"的输入(输入$ d3io),因为这没有在ui.r中定义,我推断它必须来自javascript文件.它实际上指的是哪个元素?

该短语input$d3io包含以下组件:

  • input 是传递给函数的参数 - 它是一个列表,用于存储应用程序中所有小部件的当前值.
  • $ 是成员选择器.
  • d3io 指的是UI的mainPanel中具有该id('d3IO("d3io")')的div元素的内容.

2)我无法理解自定义绑定部分:

var d3OutputBinding = new Shiny.OutputBinding();
Run Code Online (Sandbox Code Playgroud)

没错,这会创建一个Shiny.OutputBinding实例并将其分配给变量d3OutputBinding.

$.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");
  }
});
Run Code Online (Sandbox Code Playgroud)

此代码使用三个函数和find,扩展了d3OutputBinding的行为.Shiny.OutputBinding需要这三个函数.renderErrorrenderValue

find是键,因为它返回一个元素列表,这些元素应该通过它们的el参数传递给两个渲染函数.注意它返回的css类为"d3io"的元素 - 这与前面提到的div相同.

请注意,这extend()是jQuery javascript库的一个功能,$在此上下文中是jQuery对象的别名.

Shiny.outputBindings.register(d3OutputBinding);
Run Code Online (Sandbox Code Playgroud)

让Shiny知道现在应该使用这个新配置的对象.

干杯,尼克


Chr*_*itz 8

我要退后一步,假设你想要D3能够获得惊人的结果,但不一定与D3有关.基本上,我将回答这个问题:

当您不知道任何JavaScript时,学习如何将JavaScript实现为Shiny的必要步骤是什么?

虽然D3功能非常强大,但它也很难掌握 - 即使对于那些对JavaScript非常熟悉的人来说也是如此.虽然我喜欢D3并且几乎每天都使用它,但在这种情况下我建议不要使用它.相反,有一个名为Plotly的库,它在背景中使用D3,但是专门为科学界和数据科学家构建,因此它对R社区非常友好.

他们有一个连接到Shiny全面教程,如果你已经熟悉那个语法,甚至还有一个ggplot2转换器,就像R世界中的许多人一样.除非您的需求非常不寻常,否则Plotly可能会直接在D3中提供您的需求,并且学习曲线更加友好.