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, LayerToggleThe 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.