{"action":"created","issue":{"url":"https://api.github.com/repos/rstudio/leaflet/issues/290","repository_url":"https://api.github.com/repos/rstudio/leaflet","labels_url":"https://api.github.com/repos/rstudio/leaflet/issues/290/labels{/name}","comments_url":"https://api.github.com/repos/rstudio/leaflet/issues/290/comments","events_url":"https://api.github.com/repos/rstudio/leaflet/issues/290/events","html_url":"https://github.com/rstudio/leaflet/issues/290","id":176321222,"number":290,"title":"Provide a way to add plugins and methods in external packages","user":{"login":"cuche27","id":3432606,"avatar_url":"https://avatars.githubusercontent.com/u/3432606?v=3","gravatar_id":"","url":"https://api.github.com/users/cuche27","html_url":"https://github.com/cuche27","followers_url":"https://api.github.com/users/cuche27/followers","following_url":"https://api.github.com/users/cuche27/following{/other_user}","gists_url":"https://api.github.com/users/cuche27/gists{/gist_id}","starred_url":"https://api.github.com/users/cuche27/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cuche27/subscriptions","organizations_url":"https://api.github.com/users/cuche27/orgs","repos_url":"https://api.github.com/users/cuche27/repos","events_url":"https://api.github.com/users/cuche27/events{/privacy}","received_events_url":"https://api.github.com/users/cuche27/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rstudio/leaflet/labels/duplicate","name":"duplicate","color":"cccccc"},{"url":"https://api.github.com/repos/rstudio/leaflet/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":{"login":"bhaskarvk","id":1761224,"avatar_url":"https://avatars.githubusercontent.com/u/1761224?v=3","gravatar_id":"","url":"https://api.github.com/users/bhaskarvk","html_url":"https://github.com/bhaskarvk","followers_url":"https://api.github.com/users/bhaskarvk/followers","following_url":"https://api.github.com/users/bhaskarvk/following{/other_user}","gists_url":"https://api.github.com/users/bhaskarvk/gists{/gist_id}","starred_url":"https://api.github.com/users/bhaskarvk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhaskarvk/subscriptions","organizations_url":"https://api.github.com/users/bhaskarvk/orgs","repos_url":"https://api.github.com/users/bhaskarvk/repos","events_url":"https://api.github.com/users/bhaskarvk/events{/privacy}","received_events_url":"https://api.github.com/users/bhaskarvk/received_events","type":"User","site_admin":false},"assignees":[{"login":"bhaskarvk","id":1761224,"avatar_url":"https://avatars.githubusercontent.com/u/1761224?v=3","gravatar_id":"","url":"https://api.github.com/users/bhaskarvk","html_url":"https://github.com/bhaskarvk","followers_url":"https://api.github.com/users/bhaskarvk/followers","following_url":"https://api.github.com/users/bhaskarvk/following{/other_user}","gists_url":"https://api.github.com/users/bhaskarvk/gists{/gist_id}","starred_url":"https://api.github.com/users/bhaskarvk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhaskarvk/subscriptions","organizations_url":"https://api.github.com/users/bhaskarvk/orgs","repos_url":"https://api.github.com/users/bhaskarvk/repos","events_url":"https://api.github.com/users/bhaskarvk/events{/privacy}","received_events_url":"https://api.github.com/users/bhaskarvk/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/rstudio/leaflet/milestones/1","html_url":"https://github.com/rstudio/leaflet/milestones/v1.1","labels_url":"https://api.github.com/repos/rstudio/leaflet/milestones/1/labels","id":1978877,"number":1,"title":"v1.1","description":"","creator":{"login":"jcheng5","id":129551,"avatar_url":"https://avatars.githubusercontent.com/u/129551?v=3","gravatar_id":"","url":"https://api.github.com/users/jcheng5","html_url":"https://github.com/jcheng5","followers_url":"https://api.github.com/users/jcheng5/followers","following_url":"https://api.github.com/users/jcheng5/following{/other_user}","gists_url":"https://api.github.com/users/jcheng5/gists{/gist_id}","starred_url":"https://api.github.com/users/jcheng5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jcheng5/subscriptions","organizations_url":"https://api.github.com/users/jcheng5/orgs","repos_url":"https://api.github.com/users/jcheng5/repos","events_url":"https://api.github.com/users/jcheng5/events{/privacy}","received_events_url":"https://api.github.com/users/jcheng5/received_events","type":"User","site_admin":false},"open_issues":22,"closed_issues":3,"state":"open","created_at":"2016-09-01T22:31:24Z","updated_at":"2016-09-12T12:50:38Z","due_on":null,"closed_at":null},"comments":1,"created_at":"2016-09-12T08:35:10Z","updated_at":"2016-09-12T12:50:47Z","closed_at":null,"body":"Related to #283. \r\n\r\nIt would be nice to be able to easily add a plugin to leaflet map and to define new methods in the `LeafletWidget` object so that we can invoke them with the R function `invokeMethod()`.\r\n\r\nFor now, here is how I proceed:\r\n\r\n* I wrote a javascript file that define a new leaflet object and that inject two new methods in `LeafletWidget` object:\r\n\r\n```js\r\n// Leaflet class for drawing a simple  segment with an arrow on its middle that \r\n// represents its direction.\r\nL.DirectedSegment = L.Class.extend({\r\n  options:{...},\r\n  initialize: function(...) {...},\r\n  onAdd: function(...) {...},\r\n  onRemove: function(...) {...},\r\n  _reset: function(...) {...},\r\n  setStyle: function(...) {...},\r\n});\r\n\r\nL.directedSegment = function(start, end, options) {\r\n  return new L.DirectedSegment(start, end, options);\r\n};\r\n\r\n// INJECT METHODS THAT CREATE AND UPDATE DIRECTED SEGMENTS\r\n\r\n/*\r\nAdd a segment on the map with a triangle in the middle representing its direction.\r\n\r\n@param data:\r\n  data.frame with columns x0, y0, x1, y1 and optionnaly dir, color, opacity, weight\r\n  and layerId\r\n    \r\n*/\r\nwindow.LeafletWidget.methods.addDirectedSegments = function(data) {\r\n  for (var i = 0; i < data.x0.length; i++) {\r\n    var style = {};\r\n    if (data.color) style.color = data.color[i];\r\n    if (data.opacity) style.opacity = data.opacity[i];\r\n    if (data.weight) style.weight = data.weight[i];\r\n    if (data.dir) style.dir = data.dir[i];\r\n    var l = L.directedSegment([data.y0[i], data.x0[i]], [data.y1[i], data.x1[i]], style);\r\n    \r\n    var id = data.layerId ? data.layerId[i] : undefined;\r\n    \r\n    this.layerManager.addLayer(l, \"directedSegment\", id);\r\n  }\r\n};\r\n\r\n/*\r\nUpdate the style of directed segments\r\n\r\n@param data\r\n  data.frame with columns layerId and optionnaly dir, color, opacity and weight\r\n  \r\n*/\r\nwindow.LeafletWidget.methods.updateDirectedSegments = function(data) {\r\n  for (var i = 0; i < data.layerId.length; i++) {\r\n    var style = {};\r\n    if (data.color) style.color = data.color[i];\r\n    if (data.opacity) style.opacity = data.opacity[i];\r\n    if (data.weight) style.weight = data.weight[i];\r\n    if (data.dir) style.dir = data.dir[i];\r\n    \r\n    var l = this.layerManager.getLayer(\"directedSegment\", data.layerId[i]);\r\n    l.setStyle(style);\r\n    \r\n  }\r\n};\r\n```\r\n\r\n* Then I wrote two R functions that add the javascript dependency to a leaflet object and that invoke the methods defined above:\r\n\r\n```r\r\n#' @export\r\naddDirectedSegments <- function(map, x0, y0, x1, y1, color = \"blue\", weight = 3, opacity = 1, dir = 1, layerId = NULL) {\r\n  # Check if javascript dependency is present\r\n  deps <- sapply(map$dependencies, function(x) x$name)\r\n  if (! \"directedSegment\" %in% deps) {\r\n    dep <- htmlDependency(\r\n      \"directedSegment\", \r\n      \"1.0\",\r\n      src = system.file(\"leafletPlugins\", package = \"antaresViz\"), \r\n      script = \"directedSegment.js\"\r\n    )\r\n    map$dependencies <- c(map$dependencies, list(dep))\r\n  }\r\n  \r\n  data <- data.frame(x0 = x0, y0 = y0, x1 = x1, y1 = y1, dir = dir, \r\n                     color = color, weight = weight, opacity = opacity)\r\n  \r\n  if(!is.null(layerId)) data$layerId <- layerId\r\n  \r\n  invokeMethod(map, data = leaflet:::getMapData(map), \"addDirectedSegments\", data)\r\n}\r\n\r\n#' @export\r\nupdateDirectedSegments <- function(map, layerId, color = \"blue\", weight = 3, opacity = 1, dir = 1) {\r\n  data <- data.frame(layerId = layerId, color = color, weight = weight, opacity = opacity, dir = dir)\r\n  \r\n  invokeMethod(map, data = leaflet:::getMapData(map), \"updateDirectedSegments\", data)\r\n}\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/rstudio/leaflet/issues/comments/246337045","html_url":"https://github.com/rstudio/leaflet/issues/290#issuecomment-246337045","issue_url":"https://api.github.com/repos/rstudio/leaflet/issues/290","id":246337045,"user":{"login":"bhaskarvk","id":1761224,"avatar_url":"https://avatars.githubusercontent.com/u/1761224?v=3","gravatar_id":"","url":"https://api.github.com/users/bhaskarvk","html_url":"https://github.com/bhaskarvk","followers_url":"https://api.github.com/users/bhaskarvk/followers","following_url":"https://api.github.com/users/bhaskarvk/following{/other_user}","gists_url":"https://api.github.com/users/bhaskarvk/gists{/gist_id}","starred_url":"https://api.github.com/users/bhaskarvk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhaskarvk/subscriptions","organizations_url":"https://api.github.com/users/bhaskarvk/orgs","repos_url":"https://api.github.com/users/bhaskarvk/repos","events_url":"https://api.github.com/users/bhaskarvk/events{/privacy}","received_events_url":"https://api.github.com/users/bhaskarvk/received_events","type":"User","site_admin":false},"created_at":"2016-09-12T12:50:47Z","updated_at":"2016-09-12T12:50:47Z","body":"Thanks for a detailed example. I'll track this in #283."}}
{"actor":{"display_login":"bhaskarvk"}}