There and Back Again competition entry https://shiny.petras.space/commute/
rstats
rshiny
census
competition
leaflet
javascript
stats-nz

leafletfunctions.R 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # Courtesy timelyportfolio on github:
  2. # https://github.com/rstudio/leaflet/issues/496#issuecomment-650122985
  3. ### R functions
  4. # add in methods from https://github.com/rstudio/leaflet/pull/598
  5. setCircleMarkerRadius <- function(map, layerId, radius, data=getMapData(map)){
  6. options <- list(layerId = layerId, radius = radius)
  7. # evaluate all options
  8. options <- evalFormula(options, data = data)
  9. # make them the same length (by building a data.frame)
  10. options <- do.call(data.frame, c(options, list(stringsAsFactors=FALSE)))
  11. leaflet::invokeMethod(map, data, "setRadius", options$layerId, options$radius)
  12. }
  13. setCircleMarkerStyle <- function(map, layerId
  14. , radius = NULL
  15. , stroke = NULL
  16. , color = NULL
  17. , weight = NULL
  18. , opacity = NULL
  19. , fill = NULL
  20. , fillColor = NULL
  21. , fillOpacity = NULL
  22. , dashArray = NULL
  23. , options = NULL
  24. , data = getMapData(map)
  25. ){
  26. if (!is.null(radius)){
  27. setCircleMarkerRadius(map, layerId = layerId, radius = radius, data = data)
  28. }
  29. options <- c(list(layerId = layerId),
  30. options,
  31. filterNULL(list(stroke = stroke, color = color,
  32. weight = weight, opacity = opacity,
  33. fill = fill, fillColor = fillColor,
  34. fillOpacity = fillOpacity, dashArray = dashArray
  35. )))
  36. if (length(options) < 2) { # no style options set
  37. return()
  38. }
  39. # evaluate all options
  40. options <- evalFormula(options, data = data)
  41. # make them the same length (by building a data.frame)
  42. options <- do.call(data.frame, c(options, list(stringsAsFactors=FALSE)))
  43. layerId <- options[[1]]
  44. style <- options[-1] # drop layer column
  45. #print(list(style=style))
  46. leaflet::invokeMethod(map, data, "setStyle", "marker", layerId, style);
  47. }
  48. setShapeStyle <- function( map, data = getMapData(map), layerId,
  49. stroke = NULL, color = NULL,
  50. weight = NULL, opacity = NULL,
  51. fill = NULL, fillColor = NULL,
  52. fillOpacity = NULL, dashArray = NULL,
  53. smoothFactor = NULL, noClip = NULL,
  54. options = NULL
  55. ){
  56. options <- c(list(layerId = layerId),
  57. options,
  58. filterNULL(list(stroke = stroke, color = color,
  59. weight = weight, opacity = opacity,
  60. fill = fill, fillColor = fillColor,
  61. fillOpacity = fillOpacity, dashArray = dashArray,
  62. smoothFactor = smoothFactor, noClip = noClip
  63. )))
  64. # evaluate all options
  65. options <- evalFormula(options, data = data)
  66. # make them the same length (by building a data.frame)
  67. options <- do.call(data.frame, c(options, list(stringsAsFactors=FALSE)))
  68. layerId <- options[[1]]
  69. style <- options[-1] # drop layer column
  70. #print(list(style=style))
  71. leaflet::invokeMethod(map, data, "setStyle", "shape", layerId, style);
  72. }
  73. ### JS methods
  74. leafletjs <- tags$head(
  75. # add in methods from https://github.com/rstudio/leaflet/pull/598
  76. tags$script(HTML(
  77. '
  78. window.LeafletWidget.methods.setStyle = function(category, layerId, style){
  79. var map = this;
  80. if (!layerId){
  81. return;
  82. } else if (!(typeof(layerId) === "object" && layerId.length)){ // in case a single layerid is given
  83. layerId = [layerId];
  84. }
  85. //convert columnstore to row store
  86. style = HTMLWidgets.dataframeToD3(style);
  87. //console.log(style);
  88. layerId.forEach(function(d,i){
  89. var layer = map.layerManager.getLayer(category, d);
  90. if (layer){ // or should this raise an error?
  91. layer.setStyle(style[i]);
  92. }
  93. });
  94. };
  95. window.LeafletWidget.methods.setRadius = function(layerId, radius){
  96. var map = this;
  97. if (!layerId){
  98. return;
  99. } else if (!(typeof(layerId) === "object" && layerId.length)){ // in case a single layerid is given
  100. layerId = [layerId];
  101. radius = [radius];
  102. }
  103. layerId.forEach(function(d,i){
  104. var layer = map.layerManager.getLayer("marker", d);
  105. if (layer){ // or should this raise an error?
  106. layer.setRadius(radius[i]);
  107. }
  108. });
  109. };
  110. '
  111. ))
  112. )