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.
The full code is available at: https://github.com/Arevaju/ocpuleaflet.
Thanks a lot for your help and congratulations for your great work!!
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":"© <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"))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With