how to display htmlwidgets inside openCPU apps?
Asked Answered
T

1

11

We want to display an htmlwidget inside an OpenCPU application.The html is generated by Leaflet without problems, however we have some troubles to display it within the OpenCPU app. We used the following function to generate the Leaflet Map:

leafmap1 <- function(ecoregion='10105',wdpa_id='1500'){
require(leaflet)
require(shiny)
require(htmlwidgets)
m <- leaflet() %>%
addTiles() %>%  # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
m 
}

The JavaScript is as follows:

function SochiCtrl($scope){
$scope.ecoregions = ['10105']
$scope.wdpa_ids = ["1500"]
$scope.ecoregion = $scope.ecoregions[0]
$scope.wdpa_id = $scope.wdpa_ids[0]    
$scope.makeChart = function(){
   var req = ocpu.rpc("leafmap1", 
    {"ecoregion": $scope.ecoregion, "wdpa_id": $scope.wdpa_id}, function(output){   
    $('#map').html(output)
   }).fail(function(text){
     alert("Error: " + req.responseText);
   });
}
$scope.$watchCollection('[ecoregion, wdpa_id]', function(newValues){
  console.log(newValues)
  $scope.makeChart({ecoregion: newValues[0], wdpa_id: newValues[1]})
})
}

Now the app shows the Leaflet frame but I have some problems getting the json from OpenCPU I got the following error No method asJSON S3 class: htmlwidget. I also tried with:

m <- toJSON(m, force= TRUE) 

but it doesn't seem to work.
enter image description here

The full code is available at: https://github.com/Arevaju/ocpuleaflet.

Thanks a lot for your help and congratulations for your great work!!

Towards answered 26/11, 2015 at 12:55 Comment(3)
Can you include some example code of a widget you'd like to display?Pickup
No solution found?Leeds
Yes, take a look at this repo from Jeroen: github.com/opencpu/leafletapp. You will find the app at the OpenCPU website. Our working example can be found at: github.com/javimarlop/spdynmodocpuTowards
R
2

Sorry as this is not a tested answer, but this is easier to explain a proposed approach here than in a comment.

What I propose is to have your function leafmap1 return plain text (HTML) instead of the leaflet object.

You can see that the leaflet object inherits the class htmlwidget. For this class, there exists a method for the generic function toHTML that would allows retrieving such HTML code.

Assumed a leaflet object:

 m = leaflet() %>% addTiles()

Let's have a look at it's class:

class(m)
[1] "leaflet"    "htmlwidget"

Get the underlying generated html:

> (out <- unclass(htmlwidgets:::toHTML(m)))
[[1]]
<div id="htmlwidget-7863" style="width:100%;height:400px;" class="leaflet html-widget"></div>
[[2]]
<script type="application/json" data-for="htmlwidget-7863">{"x":{"calls":[{"method":"addTiles","args":    ["http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",null,null,{"minZoom":0,"maxZoom":18,"maxNativeZoom":null,"tileSize":256,"subdomains":"abc","errorTileUrl":"","tms":false,"continuousWorld":false,"noWrap":false,"zoomOffset":0,"zoomReverse":false,"opacity":1,"zIndex":null,"unloadInvisibleTiles":null,"updateWhenIdle":null,"detectRetina":false,"reuseTiles":false,"attribution":"&copy; <a href=\"http://openstreetmap.org\">OpenStreetMap\u003c/a> contributors, <a href=\"http://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA\u003c/a>"}]}]},"evals":[],"jsHooks":[]}</script>
[[3]]
NULL
attr(,"html_dependencies")
attr(,"html_dependencies")[[1]]
[...]

Third slot contains dependancies (javascript+css) so I guess those are already loaded in your report.

You may return the concatenation of the first two components (function result):

return(paste(out[[1]], out[[2]], sep="\n"))
Rotatory answered 11/10, 2016 at 12:53 Comment(7)
Nice, but how do you include the html in your script? Do you mind precise the js call on the client side?Leeds
I worked only once with opencpu, years ago. Does adding in HTML a div element and append the result to it? Sich as $('#results').append("<br/>");(found at #11419035)Rotatory
tryed session.getObject(function(outtxt){ $("#my_div").text(outtxt); }); and <div id="my_div"></div> and didn't worked. Maybe in a way I am not aware.Leeds
Can you try with append?Rotatory
Append add the underlying generated html. I have tried it but still miss something. The html copied/paste(plus a call of the css and js scripts) does not produce the graph so far. The bounty period come to an end so I'll give you the reward for the answer (the concept to return part of the code and manually set up the css and js library is a good one)Leeds
I can't find the toHTML function anywhere in the docs (cran.r-project.org/web/packages/htmlwidgets/htmlwidgets.pdf). Am I missing something ?Snoop
Sorry for delays -- didn't connect to stackOverflow before. You may see in my code that function is indeed not exported (visible) thus the ":::" before calling.Rotatory

© 2022 - 2024 — McMap. All rights reserved.