This communicates the big idea.
If I know the id of a line during layout, I can add a callback (handle_polyline_click())
But if a polyline is added dynamically after layout (clicking the “add dynamic lines” button), how do I capture a click?
import dash
from dash import html, Output, Input, State
import dash_leaflet as dl
app = dash.Dash(__name__)
@app.callback(
Output("map", "children"),
Input("plotLines", "n_clicks"),
State("map", "children")
)
def populateLines(n_clicks, mapChildren):
# (make some kind of db query):
dfPolyLines = getPolyLinesFromDB()
for index, row in dfPolyLines.iterrows():
line = dl.Polyline(<properties based on row>)
mapChildren.append(line)
return mapChildren
app.layout = html.Div([
dl.Map(center=[56, 10], id="map", zoom=6, children=[
dl.TileLayer(),
dl.Polyline(
id="my-polyline",
positions=[[55, 10], [57, 12], [58, 8]],
color="blue",
weight=5
),
], style={'width': '100%', 'height': '50vh'}),
html.Div(id="polyline-click-output")
dbc.Button("Add Dynamic Lines", id="plotLines", n_clicks=0),
])
@app.callback(
Output("polyline-click-output", "children"),
Input("my-polyline", "n_clicks"),
State("my-polyline", "clickData"),
prevent_initial_call=True
)
def handle_polyline_click(n_clicks, click_data):
if click_data:
lat = click_data["latlng"]["lat"]
lon = click_data["latlng"]["lng"]
return f"Polyline clicked {n_clicks} times at Lat: {lat:.2f}, Lng: {lon:.2f}"
return "Click the polyline!"
if __name__ == '__main__':
app.run_server(debug=True)