Creating clickable areas on a MapEl that trigger a callback with values

Hi all

I am trying to create a map that can be clicked on, which in turn generates a bunch of statistics based on the part of the map that was clicked. For example, if zone_1 is clicked, the statistics for that zone are displayed in a DataTable somewhere else on the same page. For now, a simple Label that shows the last location clicked will suffice.

Here is the reduced layout:

    html.Div([
        html.Label(
            id="current_location",
            children=""
        )
    ]),
    html.Div([
        html.MapEl(
            children=[
                html.Area(id='zone_1', target='', shape="poly", coords="0,0,210,210,421,0,0,0",
                          alt="zone_1"),
                html.Area(id='zone_2', target='', shape="poly", coords="210,210,421,0,421,421,210,421,210,210",
                          alt="zone_2"),
                html.Area(id='zone_3', target='', shape="poly", coords="0,0,210,210,210,421,0,421,0,0",
                          alt="zone3"),
            ],
            name='map'),
        html.Img(src="assets/map_basic.png", useMap='#map')
    ]),

I can make the different clickable areas click through to separate pages fine, which implies the map is set up correctly, but I want to stay on the same page and pass a value to a callback to run some statistics on it.

What is the best way to approach this?

Furthermore, would there be a simple way to then scale this to be used with 100+ clickable areas?

Any help would be appreciated, cheers!

I don’t have any experience with mapEl, but you should be able to use n_clicks and pattern matching callbacks.

Alternatively, could you use one of the maps available in dcc.Graph with the plotly graphing library? Or are your regions not geographical?

Hi Chris

Unfortunately the regions are not geographical, so the ‘map’ is going to have to be tailored to spec, which i am happy to do once i figure out the underlying callback process.
How would one go about using the n_clicks values of multiple different regions on a map to determine which one had been clicked? Do you have an example of this?

Cheers, Jono

Now you mention it, a bit of research has turned up the “Pattern-Matching Callbacks” documentation, which seem like exactly what I will need for this task. I’ll give it a shot and see how it turns out.

Update

So what i’ve ended up doing is having a bunch of dummy triggers using the n_clicks of each html.Area, which fires a callback that reads the specific trigger from dash.callback_context's prop_id, and then i can pattern match it from there:

@app.callback(
    Output('code', 'obfuscation'),
    [
        Input('bay_010101', 'n_clicks'),
        Input('bay_010201', 'n_clicks'),
        Input('bay_010301', 'n_clicks'),
    ]
)
def display_output(one, two, three):
    trigger = dash.callback_context.triggered[0]['prop_id']
    ...

Cheers for the idea Chris. Love your work!

1 Like