Skip to content

Commit

Permalink
feat: only add visible markers (and tooltips) to DOM
Browse files Browse the repository at this point in the history
  • Loading branch information
yohanboniface committed Oct 9, 2024
1 parent 2ca6ffd commit 31453c0
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 12 deletions.
18 changes: 18 additions & 0 deletions umap/static/umap/js/modules/rendering/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,32 @@ export const LeafletMarker = Marker.extend({
return this.setLatLng(latlng)
},

getEvents: function () {
const events = Marker.prototype.getEvents.call(this)
events.moveend = this.onMoveEnd
return events
},

addInteractions() {
PointMixin.addInteractions.call(this)
this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
this.on('popupopen', this.highlight)
this.on('popupclose', this.resetHighlight)
},

onMoveEnd: function () {
this._initIcon()
this.update()
},

_initIcon: function () {
if (!this._map.getBounds().contains(this.getCenter())) {
if (this._icon) this._removeIcon()
if (this._tooltip && this.isTooltipOpen()) {
this.unbindTooltip()
}
return
}
this.options.icon = this.getIcon()
Marker.prototype._initIcon.call(this)
// Allow to run code when icon is actually part of the DOM
Expand Down
14 changes: 7 additions & 7 deletions umap/tests/integration/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_data_browser_should_be_open(live_server, page, bootstrap, map):


def test_data_browser_should_be_filterable(live_server, page, bootstrap, map):
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
markers = page.locator(".leaflet-marker-icon")
paths = page.locator(".leaflet-overlay-pane path")
Expand Down Expand Up @@ -115,7 +115,7 @@ def test_filter_uses_layer_setting_if_any(live_server, page, bootstrap, map):
datalayer = map.datalayer_set.first()
datalayer.settings["labelKey"] = "foo"
datalayer.save()
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
markers = page.locator(".leaflet-marker-icon")
paths = page.locator(".leaflet-overlay-pane path")
Expand Down Expand Up @@ -154,7 +154,7 @@ def test_filter_works_with_variable_in_labelKey(live_server, page, map):
data = deepcopy(DATALAYER_DATA)
data["_umap_options"]["labelKey"] = "{name} ({bar})"
DataLayerFactory(map=map, data=data)
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
markers = page.locator(".leaflet-marker-icon")
paths = page.locator(".leaflet-overlay-pane path")
Expand Down Expand Up @@ -182,7 +182,7 @@ def test_filter_works_with_missing_name(live_server, page, map):
data = deepcopy(DATALAYER_DATA)
del data["features"][0]["properties"]["name"]
DataLayerFactory(map=map, data=data, name="foobar")
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
markers = page.locator(".leaflet-marker-icon")
paths = page.locator(".leaflet-overlay-pane path")
Expand Down Expand Up @@ -299,7 +299,7 @@ def test_data_browser_with_variable_in_name(live_server, page, bootstrap, map):
# Include a variable
map.settings["properties"]["labelKey"] = "{name} ({foo})"
map.save()
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
expect(page.get_by_text("one point in france (point)")).to_be_visible()
expect(page.get_by_text("one line in new zeland (line)")).to_be_visible()
expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_visible()
Expand Down Expand Up @@ -335,7 +335,7 @@ def test_should_sort_features_in_natural_order(live_server, map, page):


def test_should_redraw_list_on_feature_delete(live_server, openmap, page, bootstrap):
page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
page.goto(f"{live_server.url}{openmap.get_absolute_url()}#2/19/-2")
# Enable edit
page.get_by_role("button", name="Edit").click()
buttons = page.locator(".umap-browser .datalayer li .icon-delete")
Expand Down Expand Up @@ -380,7 +380,7 @@ def test_should_use_color_variable(live_server, map, page):


def test_should_allow_to_toggle_datalayer_visibility(live_server, map, page, bootstrap):
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#2/19/-2")
markers = page.locator(".leaflet-marker-icon")
paths = page.locator(".leaflet-overlay-pane path")
expect(markers).to_have_count(1)
Expand Down
2 changes: 1 addition & 1 deletion umap/tests/integration/test_datalayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_should_honour_color_variable(live_server, map, page):
},
}
DataLayerFactory(map=map, data=data)
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/47.5/2.5")
expect(page.locator(".leaflet-overlay-pane path[fill='tomato']"))
markers = page.locator(".leaflet-marker-icon .icon_container")
expect(markers).to_have_css("background-color", "rgb(240, 248, 255)")
Expand Down
2 changes: 1 addition & 1 deletion umap/tests/integration/test_edit_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_can_edit_on_shift_click(live_server, openmap, page, datalayer):


def test_marker_style_should_have_precedence(live_server, openmap, page, bootstrap):
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.5/19")

# Change colour at layer level
page.get_by_role("link", name="Manage layers").click()
Expand Down
6 changes: 3 additions & 3 deletions umap/tests/integration/test_facets_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def test_date_facet_search(live_server, page, map):
map.save()
DataLayerFactory(map=map, data=DATALAYER_DATA1)
DataLayerFactory(map=map, data=DATALAYER_DATA2)
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/47.5/-1.5")
markers = page.locator(".leaflet-marker-icon")
expect(markers).to_have_count(4)
expect(page.get_by_text("Date Filter")).to_be_visible()
Expand All @@ -196,7 +196,7 @@ def test_choice_with_empty_value(live_server, page, map):
del data["features"][1]["properties"]["mytype"]
DataLayerFactory(map=map, data=data)
DataLayerFactory(map=map, data=DATALAYER_DATA2)
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/47.5/-1.5")
expect(page.get_by_text("<empty value>")).to_be_visible()
markers = page.locator(".leaflet-marker-icon")
expect(markers).to_have_count(4)
Expand All @@ -212,7 +212,7 @@ def test_number_with_zero_value(live_server, page, map):
data["features"][0]["properties"]["mynumber"] = 0
DataLayerFactory(map=map, data=data)
DataLayerFactory(map=map, data=DATALAYER_DATA2)
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/47.5/-1.5")
expect(page.get_by_label("Min")).to_have_value("0")
expect(page.get_by_label("Max")).to_have_value("14")
page.get_by_label("Min").fill("1")
Expand Down
63 changes: 63 additions & 0 deletions umap/tests/integration/test_view_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,66 @@ def test_extended_properties_in_popup(live_server, map, page, bootstrap):
expect(page.get_by_text("Alt: 241")).to_be_visible()
expect(page.get_by_text("Zoom: 7")).to_be_visible()
expect(page.get_by_text("Layer: test datalayer")).to_be_visible()


def test_only_visible_markers_are_added_to_dom(live_server, map, page):
data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "marker 1",
"description": "added to dom",
},
"geometry": {
"type": "Point",
"coordinates": [14.6, 48.5],
},
},
{
"type": "Feature",
"properties": {
"name": "marker 2",
"description": "not added to dom at load",
},
"geometry": {
"type": "Point",
"coordinates": [12.6, 44.5],
},
},
],
}
DataLayerFactory(map=map, data=data)
map.settings["properties"]["showLabel"] = True
map.save()
page.goto(f"{live_server.url}{map.get_absolute_url()}")
markers = page.locator(".leaflet-marker-icon")
tooltips = page.locator(".leaflet-tooltip")
expect(markers).to_have_count(1)
expect(tooltips).to_have_count(1)

# Zoom in/out to show the other marker
page.get_by_label("Zoom out").click()
expect(markers).to_have_count(2)
expect(tooltips).to_have_count(2)
page.get_by_label("Zoom in").click()
expect(markers).to_have_count(1)
expect(tooltips).to_have_count(1)

# Drag map to show/hide the marker
map_el = page.locator("#map")
map_el.drag_to(
map_el,
source_position={"x": 100, "y": 600},
target_position={"x": 100, "y": 200},
)
expect(markers).to_have_count(2)
expect(tooltips).to_have_count(2)
map_el.drag_to(
map_el,
source_position={"x": 100, "y": 600},
target_position={"x": 100, "y": 200},
)
expect(markers).to_have_count(1)
expect(tooltips).to_have_count(1)

0 comments on commit 31453c0

Please sign in to comment.