Skip to content

Commit 783ae7e

Browse files
author
Bhaskar Karambelkar
committed
Auto show/hide legend with overlay group.
1 parent 404faa2 commit 783ae7e

File tree

5 files changed

+97
-38
lines changed

5 files changed

+97
-38
lines changed

R/legend.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,19 @@
4949
#' @param layerId the ID of the legend; subsequent calls to \code{addLegend}
5050
#' or \code{addControl} with the same \code{layerId} will replace this
5151
#' legend. The ID can also be used with \code{removeControl}.
52+
#' @param group \code{group} name of a leaflet layer group.
53+
#' Supplying this value will tie the legend to the leaflet layer group
54+
#' with this name and will auto add/remove the legend as the
55+
#' group is added/removed, for example via layerControl.
56+
#' You will need to set the \code{group} when you add a layer
57+
#' (e.g. \code{\link{addPolygons}}) and supply the same name here.
5258
#' @example inst/examples/legend.R
5359
#' @export
5460
addLegend <- function(
5561
map, position = c('topright', 'bottomright', 'bottomleft', 'topleft'),
5662
pal, values, na.label = 'NA', bins = 7, colors, opacity = 0.5, labels,
5763
labFormat = labelFormat(), title = NULL, className = "info legend",
58-
layerId = NULL
64+
layerId = NULL, group = NULL
5965
) {
6066
position = match.arg(position)
6167
type = 'unknown'; na.color = NULL
@@ -147,7 +153,7 @@ addLegend <- function(
147153
colors = I(unname(colors)), labels = I(unname(labels)),
148154
na_color = na.color, na_label = na.label, opacity = opacity,
149155
position = position, type = type, title = title, extra = extra,
150-
layerId = layerId, className = className
156+
layerId = layerId, className = className, group = group
151157
)
152158
invokeMethod(map, getMapData(map), "addLegend", legend)
153159
}

inst/examples/legend.R

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,25 @@ df = local({
1616
})
1717
pal = colorNumeric('OrRd', df$z)
1818
leaflet(df) %>%
19-
addCircleMarkers(~x, ~y, color = ~pal(z)) %>%
20-
addLegend(pal = pal, values = ~z)
19+
addTiles() %>%
20+
addCircleMarkers(~x, ~y, color = ~pal(z), group='circles') %>%
21+
addLegend(pal = pal, values = ~z, group='circles', position='bottomleft') %>%
22+
addLayersControl(overlayGroups = c('circles'))
2123

2224
# format legend labels
2325
df = data.frame(x = rnorm(100), y = rexp(100, 2), z = runif(100))
2426
pal = colorBin('PuOr', df$z, bins = c(0, .1, .4, .9, 1))
2527
leaflet(df) %>%
26-
addCircleMarkers(~x, ~y, color = ~pal(z)) %>%
27-
addLegend(pal = pal, values = ~z)
28+
addTiles() %>%
29+
addCircleMarkers(~x, ~y, color = ~pal(z), group='circles') %>%
30+
addLegend(pal = pal, values = ~z, group='circles', position='bottomleft') %>%
31+
addLayersControl(overlayGroups = c('circles'))
2832

2933
leaflet(df) %>%
30-
addCircleMarkers(~x, ~y, color = ~pal(z)) %>%
34+
addTiles() %>%
35+
addCircleMarkers(~x, ~y, color = ~pal(z), group='circles') %>%
3136
addLegend(pal = pal, values = ~z, labFormat = labelFormat(
3237
prefix = '(', suffix = ')%', between = ', ',
3338
transform = function(x) 100 * x
34-
))
39+
), group='circles', position='bottomleft' ) %>%
40+
addLayersControl(overlayGroups = c('circles'))

inst/htmlwidgets/leaflet.js

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,8 @@ methods.clearControls = function () {
17581758
};
17591759

17601760
methods.addLegend = function (options) {
1761+
var _this5 = this;
1762+
17611763
var legend = _leaflet2.default.control({ position: options.position });
17621764
var gradSpan = void 0;
17631765

@@ -1856,35 +1858,56 @@ methods.addLegend = function (options) {
18561858
return div;
18571859
};
18581860

1861+
if (options.group) {
1862+
(function () {
1863+
// Auto generate a layerID if not provided
1864+
if (!options.layerId) {
1865+
options.layerId = _leaflet2.default.stamp(legend);
1866+
}
1867+
1868+
var map = _this5;
1869+
map.on("overlayadd", function (e) {
1870+
if (e.name === options.group) {
1871+
map.controls.add(legend, options.layerId);
1872+
}
1873+
});
1874+
map.on("overlayremove", function (e) {
1875+
if (e.name === options.group) {
1876+
map.controls.remove(options.layerId);
1877+
}
1878+
});
1879+
})();
1880+
}
1881+
18591882
this.controls.add(legend, options.layerId);
18601883
};
18611884

18621885
methods.addLayersControl = function (baseGroups, overlayGroups, options) {
1863-
var _this5 = this;
1886+
var _this6 = this;
18641887

18651888
// Only allow one layers control at a time
18661889
methods.removeLayersControl.call(this);
18671890

18681891
var firstLayer = true;
18691892
var base = {};
18701893
_jquery2.default.each((0, _util.asArray)(baseGroups), function (i, g) {
1871-
var layer = _this5.layerManager.getLayerGroup(g, true);
1894+
var layer = _this6.layerManager.getLayerGroup(g, true);
18721895
if (layer) {
18731896
base[g] = layer;
18741897

18751898
// Check if >1 base layers are visible; if so, hide all but the first one
1876-
if (_this5.hasLayer(layer)) {
1899+
if (_this6.hasLayer(layer)) {
18771900
if (firstLayer) {
18781901
firstLayer = false;
18791902
} else {
1880-
_this5.removeLayer(layer);
1903+
_this6.removeLayer(layer);
18811904
}
18821905
}
18831906
}
18841907
});
18851908
var overlay = {};
18861909
_jquery2.default.each((0, _util.asArray)(overlayGroups), function (i, g) {
1887-
var layer = _this5.layerManager.getLayerGroup(g, true);
1910+
var layer = _this6.layerManager.getLayerGroup(g, true);
18881911
if (layer) {
18891912
overlay[g] = layer;
18901913
}
@@ -1918,23 +1941,23 @@ methods.removeScaleBar = function () {
19181941
};
19191942

19201943
methods.hideGroup = function (group) {
1921-
var _this6 = this;
1944+
var _this7 = this;
19221945

19231946
_jquery2.default.each((0, _util.asArray)(group), function (i, g) {
1924-
var layer = _this6.layerManager.getLayerGroup(g, true);
1947+
var layer = _this7.layerManager.getLayerGroup(g, true);
19251948
if (layer) {
1926-
_this6.removeLayer(layer);
1949+
_this7.removeLayer(layer);
19271950
}
19281951
});
19291952
};
19301953

19311954
methods.showGroup = function (group) {
1932-
var _this7 = this;
1955+
var _this8 = this;
19331956

19341957
_jquery2.default.each((0, _util.asArray)(group), function (i, g) {
1935-
var layer = _this7.layerManager.getLayerGroup(g, true);
1958+
var layer = _this8.layerManager.getLayerGroup(g, true);
19361959
if (layer) {
1937-
_this7.addLayer(layer);
1960+
_this8.addLayer(layer);
19381961
}
19391962
});
19401963
};
@@ -1968,10 +1991,10 @@ function setupShowHideGroupsOnZoom(map) {
19681991
}
19691992

19701993
methods.setGroupOptions = function (group, options) {
1971-
var _this8 = this;
1994+
var _this9 = this;
19721995

19731996
_jquery2.default.each((0, _util.asArray)(group), function (i, g) {
1974-
var layer = _this8.layerManager.getLayerGroup(g, true);
1997+
var layer = _this9.layerManager.getLayerGroup(g, true);
19751998
// This slightly tortured check is because 0 is a valid value for zoomLevels
19761999
if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) {
19772000
layer.zoomLevels = (0, _util.asArray)(options.zoomLevels);
@@ -2107,7 +2130,7 @@ methods.addRasterImage = function (uri, bounds, opacity, attribution, layerId, g
21072130
canvasTiles.drawTile = function (canvas, tilePoint, zoom) {
21082131
getImageData(function (imgData, w, h, mipmapper) {
21092132
try {
2110-
var _ret7 = function () {
2133+
var _ret8 = function () {
21112134
// The Context2D we'll being drawing onto. It's always 256x256.
21122135
var ctx = canvas.getContext("2d");
21132136

@@ -2231,7 +2254,7 @@ methods.addRasterImage = function (uri, bounds, opacity, attribution, layerId, g
22312254
}
22322255
}();
22332256

2234-
if ((typeof _ret7 === "undefined" ? "undefined" : _typeof(_ret7)) === "object") return _ret7.v;
2257+
if ((typeof _ret8 === "undefined" ? "undefined" : _typeof(_ret8)) === "object") return _ret8.v;
22352258
} finally {
22362259
canvasTiles.tileDrawn(canvas);
22372260
}
@@ -2265,7 +2288,7 @@ methods.removeMeasure = function () {
22652288
};
22662289

22672290
methods.addSelect = function (ctGroup) {
2268-
var _this9 = this;
2291+
var _this10 = this;
22692292

22702293
methods.removeSelect.call(this);
22712294

@@ -2276,42 +2299,42 @@ methods.addSelect = function (ctGroup) {
22762299
title: "Make a selection",
22772300
onClick: function onClick(btn, map) {
22782301
btn.state("select-active");
2279-
_this9._locationFilter = new _leaflet2.default.LocationFilter2();
2302+
_this10._locationFilter = new _leaflet2.default.LocationFilter2();
22802303

22812304
if (ctGroup) {
22822305
(function () {
22832306
var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup);
22842307
selectionHandle.on("change", function (e) {
22852308
if (e.sender !== selectionHandle) {
2286-
if (_this9._locationFilter) {
2287-
_this9._locationFilter.disable();
2309+
if (_this10._locationFilter) {
2310+
_this10._locationFilter.disable();
22882311
btn.state("select-inactive");
22892312
}
22902313
}
22912314
});
22922315
var handler = function handler(e) {
2293-
_this9.layerManager.brush(_this9._locationFilter.getBounds(), { sender: selectionHandle });
2316+
_this10.layerManager.brush(_this10._locationFilter.getBounds(), { sender: selectionHandle });
22942317
};
2295-
_this9._locationFilter.on("enabled", handler);
2296-
_this9._locationFilter.on("change", handler);
2297-
_this9._locationFilter.on("disabled", function () {
2318+
_this10._locationFilter.on("enabled", handler);
2319+
_this10._locationFilter.on("change", handler);
2320+
_this10._locationFilter.on("disabled", function () {
22982321
selectionHandle.close();
2299-
_this9._locationFilter = null;
2322+
_this10._locationFilter = null;
23002323
});
23012324
})();
23022325
}
23032326

2304-
_this9._locationFilter.addTo(map);
2327+
_this10._locationFilter.addTo(map);
23052328
}
23062329
}, {
23072330
stateName: "select-active",
23082331
icon: "ion-close-round",
23092332
title: "Dismiss selection",
23102333
onClick: function onClick(btn, map) {
23112334
btn.state("select-inactive");
2312-
_this9._locationFilter.disable();
2335+
_this10._locationFilter.disable();
23132336
// If explicitly dismissed, clear the crosstalk selections
2314-
_this9.layerManager.unbrush();
2337+
_this10.layerManager.unbrush();
23152338
}
23162339
}]
23172340
});
@@ -2348,7 +2371,6 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
23482371
// pixel of the original image has some contribution to the downscaled image)
23492372
// as opposed to a single-step downscaling which will discard a lot of data
23502373
// (and with sparse images at small scales can give very surprising results).
2351-
23522374
var Mipmapper = function () {
23532375
function Mipmapper(img) {
23542376
_classCallCheck(this, Mipmapper);

javascript/src/methods.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,25 @@ methods.addLegend = function(options) {
794794
return div;
795795
};
796796

797+
if(options.group) {
798+
// Auto generate a layerID if not provided
799+
if(!options.layerId) {
800+
options.layerId = L.stamp(legend);
801+
}
802+
803+
let map = this;
804+
map.on("overlayadd", function(e){
805+
if(e.name === options.group) {
806+
map.controls.add(legend, options.layerId);
807+
}
808+
});
809+
map.on("overlayremove", function(e){
810+
if(e.name === options.group) {
811+
map.controls.remove(options.layerId);
812+
}
813+
});
814+
}
815+
797816
this.controls.add(legend, options.layerId);
798817
};
799818

man/addLegend.Rd

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)