Во-первых, я довольно незнакома с javascript и его библиотекой d3.js, но я знаком с R. Создание информационных панелей с использованием Shiny было забавным и легким (благодаря stackoverflow). Теперь я хочу расширить его, подключив к нему элементы d3.
Я ищу источники информации о том, как фактически привязывать javascript к Shiny (панель инструментов R) и объяснять, что происходит на самом деле.
Фон: Я сделал учебник по js и jquery на w3schools и немного узнал о 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>
Где "d3io" является элементом div в ui, 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
)
))
Вот файл сервера:
# 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);
}
})
})
Конкретные вопросы:
1) Сервер .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);
Мое понимание:
Создайте новую блестящую выходную привязку, сначала найдите класс .d3io (элемент div), если ошибка записывается в консоль "Foe" (это специальный код?), если не ошибка, то renderValue использует функцию updateView с использованием данных (Where получает ли это значение от?) и пишет в консоль "Друг". Наконец, зарегистрируйте выход.
Надеюсь, что вы, ребята, можете помочь! Я создаю документ с шагами "Необходимые шаги, чтобы узнать, как реализовать javascript в блестящем, когда вы не знаете javascript", мне бы это понравилось!:)
Cheers, Длинные