htmlropencpuhtmlwidgetsvisnetwork

display a visNetwork object with opencpu


I'm trying to embed a visNetwork object returned from a function, into an html div but so far I have no success.

Let's say that there is an R function that returns a visNetwork object. In its simplest form could look like:

get_plot <-function()
{
  nodes <- data.frame(id = 1:3)
  edges <- data.frame(from = c(1,2), to = c(1,3))
  visNetwork::visNetwork(nodes, edges, width = "100%")
}

I tried to retrieve the plot with two different methods.

  1. Using the rplot() method of opencpu :

    var req = $("#plot-div").rplot("get_plot",{});

which returns

ocpu/tmp/x09f8951024d611/graphics/last/png?width=100&height=100 404 (Not Found)

and indeed there is no /grraphics directory presented.

  1. Using the usual ocpu.call() method of the opencpu to see what it can gets as response

    var req = ocpu.call("get_plot",{}, function (session8){ session8.getObject( function(data){ console.log(data); }) })

This one returned

ocpu/tmp/x0dabe1f8c83093/R/.val/json 400 (Bad Request)

and when visited the link I saw an error informing me that No method asJSON S3 class: htmlwidget.

Did anyone achieve to retrieve a visNetwork object using openCPU and embed it into an html page? Is this possible or not?


Solution

  • The underlying question is how one can use htmlwidgets with opencpu. There exists an example app for this: https://github.com/rwebapps/leafletapp. I have extended this package with two files, mainly using copy&paste from the existing package.. R function:

    #' @export
    get_plot <- function() {
      nodes <- data.frame(id = 1:3)
      edges <- data.frame(from = c(1,2), to = c(1,3))
      n <- visNetwork::visNetwork(nodes, edges, width = "100%")
      htmlwidgets::saveWidget(n, "mynet.html", selfcontained = FALSE)
    }
    

    HTML page:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Example map</title>
    
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <link rel="stylesheet" href="app.css">
    
    <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <script src="opencpu-0.5.js"></script>
    <script>
      $(function(){
      $("#netsubmit").click(function(e){
        e.preventDefault();
        var btn = $(this).attr("disabled", "disabled");
        var req = ocpu.call("get_plot", {}, function(session){
          $("iframe").attr('src', session.getFileURL("mynet.html"));
        }).fail(function(text){
          alert("Error: " + req.responseText);
        }).always(function(){
          btn.removeAttr("disabled");
        });
      });
    });
    </script>
    
    </head>
    
    <body>
    
      <div class="container">
        <div class="col-sm-3">
          <form>
            <button type="submit" id="netsubmit" class="btn btn-default">Update Network!</button>
          </form>
        </div>
      </div>
    
    <iframe src="about:blank"></iframe>
    
    </body>
    
    </html>
    

    The basic idea is to save the htmlwidget to a HTML page on the server and display that page in an iframe.