绑定javascript(d3.js)到闪亮 [英] Binding javascript (d3.js) to shiny

查看:137
本文介绍了绑定javascript(d3.js)到闪亮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我对javascript及其库d3.js非常陌生,但我熟悉R.使用Shiny创建仪表板一直很有趣和容易(感谢stackoverflow)。现在我想通过连接d3元素来扩展它。



我正在寻找如何实际绑定javascript到Shiny(R仪表板)的信息源,并解释什么实际上正在进行。



背景:
我在w3schools上使用js和jquery教程,并使用Scott Murray的书(Interactive Data visualization for the web )。我希望这将足以让我理解关于如何在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(){
//可能不是惯用的javascript。

this.countValue = 0;

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

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

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

// BEGIN:OUTPUT BINDING
var d3OutputBinding = new Shiny.OutputBinding();
$ .extend(d3OutputBinding,{
find:function(scope){
return $(scope).find(。d3io);
},
renderError:function(el,data){
console.log(Foe);
},
renderValue:function b 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>

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

  #UI 
库(闪亮)

d3IO< - function(inputoutputID){
div(id = inputoutputID,class = inputoutputID,tag(svg,))#埃尔斯特erbij,maar werkt blijkbaar ook zonder
}

#定义闪亮的d3 chatter应用程序的UI
shinyUI(pageWithSidebar(

#应用程序标题
headerPanel(D3 Javascript chatter,
Demo of how to create D3 I / O and cumulative data transfer),

sidebarPanel(
tags $ p小部件是一个演示如何将闪亮的直接连接到javascript,没有任何输入元素。),
标签$ p(每次转换结束,客户端请求服务器另一个信息包,
to the existing set),
标签$ p(我不能声称这可能是惯用的javascript,因为我是一个新手,但它允许d3应用程序
在实际使用中,更复杂的请求/响应协议可能需要
。-AlexBBrown)
),

mainPanel(
includeHTML d3widget.js),
d3IO(d3io)#Creates div元素d3选择

))

这是服务器文件:

 #SERVER 
库(有光泽)
#定义响应d3请求所需的服务器逻辑
shinyServer(function(input,output){

#根据mpg生成所请求变量的图只有
#包括异常值如果请求
输出$ d3io< - reactive(function(){
if(is.null(input $ d3io)){
0;
} else {
list(rnorm(1)* 400 + 200,rnorm(1)* 400 + 200);
}
})
})

具体问题: / p>

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
console.log(Friend);
}
});
Shiny.outputBindings.register(d3OutputBinding);

我的理解是:



新的闪光输出绑定,首先找到类.d3io(div元素),如果错误然后写入控制台Foe(这是特殊的代码?),如果没有错误,然后renderValue使用函数updateView使用数据从?)并写入控制台朋友。最后注册输出。



希望你们能帮忙!我正在创建一个文档,其中包括当你不知道任何javascript时,学习如何将javascript实现为闪亮的必要步骤,我会喜欢!)



Cheers,
Long

解决方案

Hi Sweetbabyjesus您有两个问题:


1)server.r似乎获得称为d3io的输入(输入$ d3io),因为这不是在ui.r中定义,我推理它必须来自javascript文件。


该短语输入$ d3io 以下组件:




  • 输入是传递给函数的参数 - 列表
    存储应用程序中所有窗口小部件的当前值。

  • $ 是成员选择器。 li>
  • d3io 是指具有id
    ('d3IO(d3io)')的div元素的内容




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




  var d3OutputBinding = new Shiny.OutputBinding(); 

没错,这创建了一个Shiny.OutputBinding的实例,并将它分配给变量d3OutputBinding。 p>



  $。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);
}
} ;

此代码扩展了d3OutputBinding的行为, c $ c> find , renderError renderValue 。这三个函数是一个Shiny.OutputBinding所必需的。



find 是关键,因为它返回一个元素列表应该通过 el 参数传递到两个render函数中。注意,它的返回元素的css类是d3io - 这是前面提到的div。



注意 extend()是jQuery javascript库的函数, $ 在此上下文中是jQuery对象的别名。

  Shiny.outputBindings.register(d3OutputBinding); 

Lets Shiny知道这个新配置的对象应该立即使用。



Cheers,Nick


First, I am fairly unfamiliar with javascript and its library d3.js, but I am familiar with R. Creating dashboards using Shiny has been fun and easy (thanks to stackoverflow). Now I want to expand it by connect d3 elements to it.

I'm looking for information sources on how to actually bind javascript to Shiny (R dashboard) and explain what is actually going on.

Background: I did the tutorial on js and jquery on w3schools and learned (a bit) about d3 using Scott Murray's book (Interactive Data visualization for the web). I hoped this would be enough to make me understand the examples and explanation concerning how to build custom input/output bindings on the Shiny website:

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

But unfortunately I don't and I can't seem to find any examples which are in minimal working code. Many examples on github are to complex for me to dissect, most probably because of my little experience with javascript. Here is an examples of custom input binding with javascript:

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

Here is an example of an input & output binding I try to unfold:

<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>

Where "d3io" is a div element in the ui, updateView() is a function. Here is the 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
    )
))

Here is the server file:

# 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);
    }
  })
})

Specific questions:

1) The server.r seems to get input called "d3io" (input$d3io) since this is not defined in ui.r, I reasoned it must come from the javascript file. Which element does it actually refer to?

2) I have trouble understanding the custom binding part:

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);

My understanding is:

Create a new shiny outputbinding, first find the class .d3io (div element), if error then write to console "Foe" (is this special code?), if not error then renderValue using the function updateView using data (Where does it receive this value from?) and write to console "Friend". Finally register output.

Hope you guys can help! I'm creating a document with the steps on "The necessary steps to learn how to implement javascript into shiny when you don't know any javascript", I would love that!:)

Cheers, Long

解决方案

Hi Sweetbabyjesus (so fun to say). You had two questions:

1) The server.r seems to get input called "d3io" (input$d3io) since this is not defined in ui.r, I reasoned it must come from the javascript file. Which element does it actually refer to?

That phrase input$d3io has the following components:

  • input is a parameter passed into the function - it's a list that stores the current values of all the widgets in the app.
  • $ is the member selector.
  • d3io refers to the content of the div element with that id ('d3IO("d3io")') in the mainPanel of the UI.

2) I have trouble understanding the custom binding part:

var d3OutputBinding = new Shiny.OutputBinding();

That's right, this creates an instance of Shiny.OutputBinding and assigns it to the variable 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");
  }
});

This code extends the behaviour of d3OutputBinding with three functions called find, renderError and renderValue. Those three functions are required for a Shiny.OutputBinding.

find is the key because it returns a list of elements that should be passed into the two render functions via their el parameter. Notice it's returning elements whose css class is "d3io" - that's the same div mentioned earlier.

Note that extend() is a function of jQuery javascript library, and the $ in this context is an alias for the jQuery object.

Shiny.outputBindings.register(d3OutputBinding);

Lets Shiny know that this newly configured object should be put to use now.

Cheers, Nick

这篇关于绑定javascript(d3.js)到闪亮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆