Skip to content

Tutorial 4 — A cross-filtered dashboard

Turn the map from Tutorial 1 into a control: filter on the map and the rest of the dashboard follows; click an earthquake and every panel narrows to it. About twenty minutes.

You need: the dashboard from Tutorial 1, or any map with a categorical column.

A map whose filter drives a dashboard variable

The idea

The map and the dashboard talk through dashboard variables, and the variable is read from the URL. Two things follow from that, and they are the whole reason this design was chosen:

  • The map reacts to a variable even when its own query never mentions it, so filtering costs no round trip to the database.
  • A shared link carries the state. Send someone the URL and they see what you were looking at.

1. Add a variable

Dashboard settings → Variables → New variable.

FieldValue
TypeText box
Nameplace
Defaultleave empty

A text box, because the map is going to write into it. A query variable would fight you.

2. Bind a map filter to it

Back on the map panel, Panel options → Cross-filtering → + Add mapping:

FieldValue
Fieldplace
Variableplace

Now open kepler's own Filters panel on the left, add a filter on place, and type something — Alaska, say. Two things happen: the map filters, and the dashboard variable at the top of the screen takes the value.

Change the variable by hand instead, and the map's filter follows. This channel is two-way.

3. Give it something to drive

Add a second panel — Table — with the same Infinity query as the map, plus one column filter that reads the variable. The simplest version needs no query change at all: add a Filter data by values transformation on place, matching $place.

Now filtering on the map filters the table.

Why not just use Grafana's panel-to-panel filtering?

Because it does not exist between arbitrary panels, and because a variable is in the URL. This is more setup for a much more useful result — every panel on the dashboard can read it, and the state survives a link.

4. Click an earthquake, filter everything

A second mapping, this time driven by clicks rather than filters:

FieldValue
Fieldplace
Variableplace
SourceClick

Click any point on the map. The variable takes that event's place.

Click empty ocean and it clears — but only if the value currently in the variable was published by this panel. A value that arrived in a shared link survives a stray click, which is the behaviour you want when someone sends you a dashboard.

Some variables should never go empty: a selected country that every query of the dashboard filters on, say. Turn on Keep on empty click in that row and a click on empty map leaves the variable as it is; only clicking another entity changes it.

This channel is one way: map → variable. Changing the variable does not move the selection.

A one-pixel target is a one-pixel target

Clicking works by deck.gl's colour picking: what you can click is exactly what is drawn. If clicks seem not to register, raise the point radius before suspecting the mapping.

5. Numeric ranges

Add a third mapping with two variables and it becomes a range mapping. Create two more text box variables, mag_min and mag_max:

FieldValue
Fieldmag
Variablemag_min
Variable (to)mag_max

Now a numeric range filter on mag in kepler's filter panel publishes both bounds, and a consuming query can say:

sql
WHERE mag BETWEEN $mag_min AND $mag_max

Remove the filter and both variables are written blank, rather than keeping their last values — otherwise the map would be at "no filter" while the variables held a range, and neither side would ever agree again.

6. Guard the empty value

Every one of these variables is empty before you touch anything, and consuming panels run anyway. In SQL:

sql
WHERE ('$place' = '' OR place = '$place')

Whether to quote depends on the data source — see Variable formats.

7. Share it

Copy the URL. It contains var-place=.... Open it in a private window: the dashboard arrives filtered, and the map's filter is applied from the variable.

What you learned

  • Filters are two-way; clicks are one-way.
  • The URL is the transport, which is why links carry state.
  • A second variable turns a mapping into a numeric range.
  • Clearing writes blanks deliberately, to keep both sides able to drive.
  • Published variables start empty, so consumers need a guard.

Next

Tutorial 5 — Click the map, query a radius, where the click publishes a place rather than a column, and another panel answers a spatial question about it.

Apache-2.0. Bundles kepler.gl (MIT) and flowmap.gl (Apache-2.0).