examples - Enlace javascript(d3.js) a brillante
d3js charts examples (4)
En primer lugar, no estoy bastante familiarizado con javascript y su biblioteca d3.js, pero estoy familiarizado con R. La creación de paneles utilizando Shiny ha sido divertida y fácil (gracias a stackoverflow). Ahora quiero expandirlo conectando elementos d3 a él.
Estoy buscando fuentes de información sobre cómo vincular javascript a Shiny (R tablero de instrumentos) y explicar lo que realmente está sucediendo.
Antecedentes: Hice el tutorial sobre js y jquery en w3schools y aprendí (un poco) sobre d3 usando el libro de Scott Murray (Visualización interactiva de datos para la web). Esperé que esto fuera suficiente para hacerme comprender los ejemplos y las explicaciones sobre cómo crear enlaces personalizados de entrada / salida en el sitio web de Shiny:
http://shiny.rstudio.com/articles/building-inputs.html
Pero desafortunadamente no lo hago y no puedo encontrar ejemplos que tengan un código de trabajo mínimo. Muchos ejemplos en github son complejos para mi disección, muy probablemente debido a mi poca experiencia con javascript. Aquí hay un ejemplo de enlace de entrada personalizado con javascript:
https://github.com/jcheng5/shiny-js-examples/tree/master/input
Aquí hay un ejemplo de un enlace de entrada y salida que intento desplegar:
<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>
Donde "d3io" es un elemento div en la interfaz de usuario, updateView () es una función. Aquí está el 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
)
))
Aquí está el archivo del 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);
}
})
})
Preguntás especificas:
1) El servidor.r parece recibir una entrada llamada "d3io" (entrada $ d3io) ya que no está definida en ui.r, razoné que debe provenir del archivo javascript. ¿A qué elemento se refiere realmente?
2) Tengo problemas para entender la parte de encuadernación 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);
Mi entendimiento es:
Cree un nuevo enlace de salida brillante, primero encuentre la clase .d3io (elemento div), si el error escribe en la consola "Foe" (¿es este código especial?), Si no es un error, luego renderValue usando la función updateView usando datos (¿Dónde recibe? este valor?) y escribe en la consola "Amigo". Finalmente registra salida.
Espero que ustedes puedan ayudar! Estoy creando un documento con los pasos en "Los pasos necesarios para aprender a implementar Javascript en brillante cuando no conoces ningún javascript", ¡me encantaría! :)
Saludos, Long
¿Está familiarizado con el paquete rCharts ? Puede funcionar bastante bien con Shiny y la mayoría de las opciones de salida se basan en las variantes D3. Two examples
Hola Sweetbabyjesus (muy divertido de decir). Usted tenía dos preguntas:
1) El servidor.r parece recibir una entrada llamada "d3io" (entrada $ d3io) ya que no está definida en ui.r, razoné que debe provenir del archivo javascript. ¿A qué elemento se refiere realmente?
Esa frase input$d3io
tiene los siguientes componentes:
-
input
es un parámetro que se pasa a la función; es una lista que almacena los valores actuales de todos los widgets en la aplicación. -
$
es el selector de miembros. -
d3io
refiere al contenido del elemento div con esa identificación (''d3IO ("d3io")'') en el Panel principal de la IU.
2) Tengo problemas para entender la parte de encuadernación personalizada:
var d3OutputBinding = new Shiny.OutputBinding();
Así es, esto crea una instancia de Shiny.OutputBinding y lo asigna a la 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");
}
});
Este código amplía el comportamiento de d3OutputBinding con tres funciones llamadas find
, renderError
y renderValue
. Esas tres funciones son necesarias para un Shiny.OutputBinding.
find
es la clave porque devuelve una lista de elementos que deben pasar a las dos funciones de renderización a través de su parámetro el. Observe que devuelve elementos cuya clase css es "d3io" - ese es el mismo div mencionado anteriormente.
Tenga en cuenta que extend()
es una función de la biblioteca jQuery javascript, y $
en este contexto es un alias para el objeto jQuery.
Shiny.outputBindings.register(d3OutputBinding);
Permite a Shiny saber que este objeto recién configurado debería usarse ahora.
Saludos, Nick
Muy ocupado con el trabajo, no he tenido la oportunidad de publicarlo. Tenga en cuenta que se trata de una solución alternativa que utiliza CustomMessageHandler (y no estoy usando un enlace de entrada / salida personalizado). Aquí va:
Objetivo: enviar datos desde el marco de datos para crear un árbol D3JS usando customMessageHandler.
Ruta: Logré enviar datos en formato data.frame a un árbol d3js. Después de hacer clic en el botón de acción, cambia los datos en el marco de datos al formato JSON y luego lo envía al archivo js que crea el árbol. Los datos del árbol están codificados en "server.r".
¿Dónde está el código? En mi github! https://github.com/SweetBabyJesus/shiny-d3js-simple-binding
Original: Creé un algoritmo de árbol basado en CHAID para crear ideas a partir de grandes conjuntos de datos. Las personas pueden subir sus csv al tablero de mandos que luego escupe el árbol d3js :) El código es algo largo, por lo tanto, lo corté para usted y creé un ejemplo de código mínimo.
Espero que te guste.
Saludos, Long
Voy a dar un paso atrás y supongo que quieres los sorprendentes resultados que D3 es capaz de hacer, pero que no están necesariamente vinculados a D3. Esencialmente, responderé esta pregunta:
¿Cuáles son los pasos necesarios para aprender cómo implementar JavaScript en Shiny cuando no conoce ningún JavaScript?
Aunque D3 es increíblemente poderoso, también es muy difícil de dominar, incluso para muchas personas que se sienten cómodas con JavaScript. Aunque me encanta D3 y lo uso casi todos los días, recomendaría no hacerlo en este caso. En cambio, hay una biblioteca llamada Plotly , que utiliza D3 en segundo plano, pero está diseñada específicamente para la comunidad científica y los científicos de datos, por lo que es muy amigable para la comunidad R.
Tienen un completo tutorial para conectarse a Shiny e incluso tienen un convertidor ggplot2 si ya está familiarizado con esa sintaxis, como muchos en el mundo R. A menos que sus necesidades sean muy inusuales, es probable que Plotly satisfaga sus necesidades tan bien como escribir directamente en D3, con una curva de aprendizaje mucho más amigable.