-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
viz. with rbokeh does not work #108
Comments
(the It looks like rbokeh is trying to open a Jupyter comm, which isn't implemented for the R kernel yet. I'd guess the Bokeh JS is doing something to detect whether it's being used in a notebook, and if so it assumes that it's valid to open a comm. @damianavila, @hafen, does that sound right? To make it work, either:
|
I have the impression that this issue is common to all of the family of htmlwidgets. I've just tried networkD3 with similar results. |
Enzo is correct - the rbokeh output is an htmlwidget, so it should render like any htmlwidget. I'd love to see this working in jupyter but unfortunately I don't have much expertise here. |
AFAIK, rbokeh does not try to use comms (but I can be wrong because I did not see the code base for a while), so this is probably related with htmlwidgets... |
@ramnathv @timelyportfolio could you kindly give a piece of advice? |
For this to work, one would have to write an R package to handle the comms in |
The following code will save the widget as a local html file library(htmlwidgets)
library(rbokeh)
x = figure() %>% ly_points(cars$speed, cars$dist)
tf = 'test.html'
saveWidget(x, file = tf, selfcontained = F) I tried using |
How does htmlwidgets JS communicate with the backend in general? The @ramnathv , if you call |
@takluyver currently we have only implemented communication protocols for |
@takluyver. The |
Are the communications for shiny HTTP requests, websocket messages, or something else? How practical would it be to do similar communications patterns over Jupyter comms? And would packages like rbokeh need changes to run within Jupyter, or would htmlwidgets abstract all the differences away? ( |
Shiny uses websockets. I think it is very feasible for us to implement comm protocols for Jupyter in htmlwidgets, thereby abstracting things away for packages that depend on it. This was the approach I was suggesting earlier. As for the comm protocol, we need to know how to do two things. One, how to load js/css dependencies, and two, insert the relevant html div into the notebook. I think I know how to do (2). So (1) is where we would need help. Another point of note, is how do notebooks handle redundancies in dependencies. So let us say I have one widget that has loaded |
@ramnathv I think I've missed this |
Here is how you would embed a htmlwidget as an iframe. library(htmlwidgets)
library(rbokeh)
x = figure() %>% ly_points(cars$speed, cars$dist)
tf = 'myfigure.html'
saveWidget(x, file = tf, selfcontained = F)
IRdisplay::display_html(paste("<iframe src=' ", tf, " ' width = 100% height = 400")) Note that I used |
i really hate tempfiles. let’s do this instead: IRdisplay::display_html(toHTML(x)) and if it somehow need to be isolated, let’s use the |
While @ramnathv code works (adding IRdisplay::display_html(toHTML(x))
Which |
oh, sorry, it’s not exported. but it has an exported alias: IRdisplay::display_html(as.tags(x)) |
@flying-sheep I can get to it with
but I get:
Realising that the
But I get the same (not surprising as
|
it’s in 0.5. update htmlwidgets and you’ll have this should work: display_html(as.character(as.tags(x))) or we can do sth. smart with
|
here’s a dumb, ad-hoc version that works at least for DiagrammR. this displays how useful a dependency mechanism for jupyter notebooks would be 😆 library(DiagrammeR)
library(htmltools)
library(htmlwidgets)
library(repr)
repr_html.htmlwidget <- function(w) {
tags <- renderTags(as.tags(w))
deps <- ''
for (dep in tags$dependencies) {
if (!is.null(dep$script)) {
f <- file.path(dep$src$file, dep$script)
deps <- sprintf('%s\n<script>// %s\n%s</script>', deps, f, readChar(f, file.info(f)$size))
}
if (!is.null(dep$stylesheet)) {
f <- file.path(dep$src$file, dep$stylesheet)
deps <- sprintf('%s\n<style>/* %s */\n%s</style>', deps, f, readChar(f, file.info(f)$size))
}
}
paste(deps, tags$html, '<script>HTMLWidgets.staticRender()</script>', sep = '\n');
}
g <- grViz("
digraph {
layout = twopi
node [shape = circle]
A -> {B C D}
}")
display_html(repr_html(g)) |
A dependency specification mechanism would be awesome. The wrapper function by @flying-sheep is a good start. However, it may not work always, since it simply inlines js/css assets, without paying attention to additional dependencies that these files might import. Writing a wrapper function that invokes I would still recommend the |
The DiagrammeR example of @flying-sheep works in a fresh session if I change the last line to
For the OP's question, this
will not display anything (but a white rectangle) with the following sessionInfo():
|
very inefficient. we should either push the dependency management or code some simple hack to fix this. maybe it can be done with a simple helper that searches for script tags with we should be able to chain-load or parallelly-load them, which is easy with promise code. // event to promise
const once = (emitter, event) =>
new Promise((resolve, reject) =>
emitter.addEventListener(event, resolve))
function load_script(id, url) {
const existing = document.getElementById(id)
if (existing)
return Promise.resolve(existing)
const script = document.createElement('script')
script.setAttribute('id', id)
script.setAttribute('src', url)
document.head.appendChild(script)
return once(script, 'load')
}
function load_dependencies(deps, callback) {
let promise = null
//sequentially load all deps in the array
if (Array.isArray(deps)) {
promise = load_dependencies(deps.shift())
if (deps.length > 0) promise = promise.then(load_dependencies(deps))
//parallelly load all deps in the object
} else {
promise = Promise.all(Object.keys(deps).map(id => load_script(id, deps[id])))
}
if (callback) promise = promise.then(callback)
return promise
}
//example: parallelly load underscore and d3,
//after both are finished, load react (makes no sense but whatever)
load_dependencies([
{
'_-1.8.3': 'http://...',
'd3-3.5.6': 'http://...',
},
{ 'react-1.4.0': 'http://' }
]) missing from above code |
I think the
comes form somethign different, I get that as well on any kernel startup... Will open a new issue for that... |
First of all, I've just installed yesterday the new OS from Apple
El Capitan
- I mention this in case there is some specific issue related to it.Alo, this assumes that IRkernel / Jyupiter works with the family of htmlwidgets. So far I've tested two and both don't work.
This is the code
I get the following code at the UI in red, but it is not a major issue as I normally get it also in Studio
In red:
Nothing happen in the browser. This is what I get in the console:
Afterward if I do
!R --version
(no matter if I restart the kernel etc.):The text was updated successfully, but these errors were encountered: