Skip to content
Make with
m

maplibre-gl-temporal-control

Animate time-series data

Maintained by MUG-JP

A temporal control plugin for MapLibre GL JS that adds a timeline slider to animate time-series data on the map.

Live demo

maplibre-gl-temporal-control running on MapLibre GL JS in your browser

Loading the map…

Demo code
import TemporalControl from "maplibre-gl-temporal-control";
import type { CircleLayerSpecification } from "maplibre-gl";
import type { PluginDemo } from "../types";

export default {
  center: [10.45, 51.16], // Germany
  zoom: 4.8,
  run({ map }) {
    // Made-up monthly values for eight cities, one circle layer per month.
    const cities = [
      [13.4, 52.52],
      [9.99, 53.55],
      [11.58, 48.14],
      [6.96, 50.94],
      [8.68, 50.11],
      [9.18, 48.78],
      [12.37, 51.34],
      [7.47, 51.51],
    ];
    const months = [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "Jul",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec",
    ];
    const features = months.flatMap((_, month) =>
      cities.map((coordinates, i) => ({
        type: "Feature" as const,
        properties: { month, value: 5 + 15 * Math.abs(Math.sin((month + i) / 2)) },
        geometry: { type: "Point" as const, coordinates },
      })),
    );
    map.addSource("monthly", { type: "geojson", data: { type: "FeatureCollection", features } });

    const frames = months.map((title, month) => {
      const layer: CircleLayerSpecification = {
        id: `month-${month}`,
        type: "circle",
        source: "monthly",
        filter: ["==", ["get", "month"], month],
        paint: {
          "circle-radius": ["get", "value"],
          "circle-color": "#e4572e",
          "circle-opacity": 0.75,
        },
      };
      map.addLayer(layer);
      return { title, layers: [layer] };
    });

    // The control shows one frame at a time; play steps through the months.
    const control = new TemporalControl(frames, { interval: 700, position: "top-left" });
    map.addControl(control);
    control.play();
  },
} satisfies PluginDemo;