Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Fullscreen dashboard

A compact chart in the page, a full dashboard behind the ⛶ button: the Fullscreen widget’s fullscreen= layout can show different and more widgets than the in-page view. Here the fullscreen view adds a lonboard map and controls that interact with both the map and the chart.

import numpy as np
import geopandas as gpd
from shapely.geometry import Point
from ipywidgets import jsdlink
from lonboard import Map, ScatterplotLayer
from lonboard.layer_extension import DataFilterExtension
from manywidgets import Chart, Column, Dropdown, Fullscreen, Grid, RangeSlider, Text
from manywidgets.lonboard import FilterBinder, LayerToggle

The in-page view

Synthetic sensor stations around San Francisco, summarized as a small chart. This chart is all the page shows inline — the map only exists in the fullscreen layout.

rng = np.random.default_rng(42)
n = 12
vals = np.round(rng.uniform(0, 10, n), 1)
pts = [Point(-122.45 + 0.012 * i, 37.74 + 0.008 * ((i * 5) % 7)) for i in range(n)]
gdf = gpd.GeoDataFrame({"value": vals}, geometry=pts, crs="EPSG:4326")

chart = Chart(
    title="Sensor readings by station",
    x_label="station", y_label="value",
    chart_type="bar", width=1100, height=260,
)
chart.add_series(x=np.arange(n), y=vals, name="reading")

The fullscreen dashboard

The fullscreen= layout is a classic rail + map split: the left column stacks the controls and the same chart instance (a widget can appear in both views — traits stay in sync), the right column is the map. The range slider filters the map’s points through a FilterBinder (the binder widget must be part of the displayed layout to work in static export), and the dropdown re-types the chart via jsdlink.

Two sizing tricks worth copying: the map takes height="70vh" (lonboard accepts any CSS length) so it scales with the screen, and the chart’s width=1100 oversizes it on purpose — charts are capped at max-width: 100%, so an oversized chart simply fills whatever column it lands in. style= on the Fullscreen cascades --mw-* tokens to everything in the overlay; here it lets the control cards stretch to the rail width.

layer = ScatterplotLayer.from_geopandas(
    gdf,
    get_radius=350, radius_units="meters", get_fill_color=[200, 30, 30],
    extensions=[DataFilterExtension(filter_size=1)],
    get_filter_value=vals, filter_range=(0, 10),
)
m = Map(layer, view_state={"longitude": -122.38, "latitude": 37.765, "zoom": 11}, height="70vh")

stations = LayerToggle(layer, label="Stations", value=True)
reading_range = RangeSlider(label="Reading range", min=0, max=10, low=0, high=10, step=0.5)
fb = FilterBinder(reading_range, layer, label="readings")  # low/high -> layer.filter_range
kind = Dropdown(label="Chart type", options=["bar", "line", "scatter"], value="bar")
jsdlink((kind, "value"), (chart, "chart_type"))

rail = Column(stations, reading_range, fb, kind, chart, gap="4px")
dashboard = Column(
    Text(value="### Sensor dashboard", markdown=True),
    Grid(rail, m, columns=2, gap="16px"),
    gap="4px",
)

Fullscreen(
    chart,
    fullscreen=dashboard,
    widget_id="sensor-dashboard",
    style={"--mw-control-max-width": "100%"},
)

Sharing the dashboard

On the exported page, opening fullscreen updates the URL to ?fullscreen=sensor-dashboard — copy it to share a link that opens straight into the dashboard. The explicit widget_id= keeps that link stable across re-exports.