Reputation: 115
I have been using dash leaflet for creating my own dashboard with maps, and it has been great to be able to visualize things with an interactive map. However, there is one thing that I have been stumped on a while for how to deal with a click happening on a polygon or marker. To explain this, I have created a simple example below
import geopandas as gpd
import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash import Dash, html, Output, Input
import json
location = gpd.GeoDataFrame(geometry=gpd.points_from_xy([-74.0060], [40.7128]))
app = Dash()
app.layout = html.Div(
children=[
dl.Map(
center=[39, -98],
zoom=4,
children=[
dl.TileLayer(),
dl.GeoJSON(data=dlx.geojson_to_geobuf(json.loads(location.to_json())), format='geobuf', id='locations', zoomToBoundsOnClick=True)],
style={'width': '100%', 'height': '80vh'}, id="map"),
html.Div(id='counter')])
counter = 0
@app.callback(Output('counter', 'children'), Input('locations', 'click_feature'))
def update_counter(feature):
global counter
counter += 1
return str(counter)
if __name__ == "__main__":
app.run_server(debug=True)
And here is what the dashboard looks like when you first load it
Below the map there is a div that contains the number of times the geojson has been clicked (and I realize that when initializing that the function gets called, but that isn't the focus of this problem). When you click on the marker the first time, the div gets updated and the number increases. However, if you were to try and click on the marker again, the div does not update and there is no increase in the number. What I have figured out is that an event will only be fired if you click on a different marker (you can add a coordinate to the geojson and click between the two markers to see for yourself). In the example, this is a counter, but I am trying to filter my data to the location clicked on every time. So my question is what do you have to do to have your data filter every time the geojson is clicked on?
Another small thing that I have noticed is that even though I set zoomToBoundsOnClick to true, I do not have the map zoom in on the marker that I clicked on. This isn't a big deal, but it would be a nice to have. So if someone know how to get that work, that would also be appreciated.
Upvotes: 4
Views: 3095
Reputation: 6014
In Dash, a callback is only invoked when a property changes. If you click the same feature twice, the click_feature
property doesn't change, and the callback is thus not invoked. If you want to invoke the callback on every click, you can target the n_clicks
property - it is incremented on (every) click, and the callback will thus fire on every click.
Upvotes: 1