# Event Timeline > Build a resource-row, Gantt-style timeline in dash-mui-scheduler with EventTimeline — resources as rows, multi-day allocation bars and zoom presets. --- .. llms_copy::Event Timeline .. toc:: ### Event Timeline (Premium) `dms.EventTimeline` is a resource-row, Gantt-style timeline. Where the calendar lays events out on a day/week/month grid, the timeline turns each **resource into a row** and draws every event as a horizontal allocation bar on its row, across a configurable zoom `preset`. It wraps the MUI X `EventTimelinePremium` and, like every component here, is currently **beta**. .. admonition::Premium :color: yellow `EventTimeline` requires a MUI X Premium license key. Pass it via `licenseKey=os.environ.get("MUI_X_LICENSE_KEY", "")`. Without a valid key the timeline still renders and stays fully interactive, but a MUI watermark is drawn over it. That is expected — supply a real key to remove it. The data boundary is the same as the calendar. `events` is a list of plain dicts and is **both input and output**: the component writes the full array back on every create, move, resize or delete. Dates are ISO **strings** (for example `"2024-01-15T09:00:00"` for wall time, or a trailing `Z` for UTC), never Python `datetime` objects. The read-only `lastAction` output is `{type, event, event_timestamp}`, where `type` is one of `create`, `update`, `delete`, `move`, `resize` or `change`. ### Resources as rows A timeline needs `resources` — they are the rows. Each resource is a dict with at least an `id` and `title`, plus an optional `eventColor`: ```python resources = [ {"id": "team-a", "title": "Team A", "eventColor": "blue"}, {"id": "team-b", "title": "Team B", "eventColor": "green"}, ] ``` Each event names its row through the `resource` key, which must match one of the resource ids. On the timeline events should almost always have a `resource` — `shouldEventRequireResource` defaults to `True` here. The column that lists the row labels is titled with `resourceColumnLabel` (for example `"Team"`). The example below places several multi-day allocation bars across three rows and opens at the `dayAndWeek` zoom level. .. exec::docs.event_timeline.timeline_basic ```python # File: docs/event_timeline/timeline_basic.py import os from dash import html import dash_mui_scheduler as dms # On a timeline, resources are the ROWS. Each event sits on the row whose id # matches its `resource` key. Resources carry their own eventColor. resources = [ {"id": "team-a", "title": "Team A", "eventColor": "blue"}, {"id": "team-b", "title": "Team B", "eventColor": "green"}, {"id": "team-c", "title": "Team C", "eventColor": "orange"}, ] # Allocation bars span days. Dates are ISO strings (never Python datetime), # and `events` is both input and output — the component writes the full array # back on every create, move, resize or delete. events = [ { "id": "alloc-1", "title": "Discovery", "start": "2024-01-15T09:00:00", "end": "2024-01-17T17:00:00", "resource": "team-a", }, { "id": "alloc-2", "title": "Build phase", "start": "2024-01-18T09:00:00", "end": "2024-01-23T17:00:00", "resource": "team-a", }, { "id": "alloc-3", "title": "API integration", "start": "2024-01-16T09:00:00", "end": "2024-01-20T17:00:00", "resource": "team-b", }, { "id": "alloc-4", "title": "QA & hardening", "start": "2024-01-22T09:00:00", "end": "2024-01-25T17:00:00", "resource": "team-b", }, { "id": "alloc-5", "title": "Launch prep", "start": "2024-01-19T09:00:00", "end": "2024-01-24T17:00:00", "resource": "team-c", }, ] component = html.Div( dms.EventTimeline( id="event_timeline-basic", licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""), events=events, resources=resources, resourceColumnLabel="Team", defaultPreset="dayAndWeek", defaultVisibleDate="2024-01-15", height=400, ) ) ``` ### Zoom presets A preset controls how much time one screen of the timeline spans and how the header is divided. There are five: `dayAndHour` (the default), `dayAndMonth`, `dayAndWeek`, `monthAndYear` and `year`. Two props drive this: - `defaultPreset` / `preset` — the active zoom level. `defaultPreset` is uncontrolled (set it once at load); `preset` is controlled **in + out**, so a callback can both set it and read the user's changes back. - `presets` — the list of presets offered in the timeline's own zoom switcher. To drive the zoom from your own UI, wire a `dmc.SegmentedControl` to the `preset` prop. Because `preset` is controlled in + out, the callback below sets the zoom whenever the segmented control changes: ```python @callback( Output("event_timeline-presets", "preset"), Input("event_timeline-presets-control", "value"), ) def set_preset(value): return value ``` .. exec::docs.event_timeline.timeline_presets ```python # File: docs/event_timeline/timeline_presets.py import os from dash import Input, Output, callback import dash_mantine_components as dmc import dash_mui_scheduler as dms # Rows. resources = [ {"id": "mixer", "title": "Mixer", "eventColor": "purple"}, {"id": "studio", "title": "Studio", "eventColor": "teal"}, ] # A few multi-day allocations so the effect of each zoom preset is visible. events = [ { "id": "preset-1", "title": "Album mixdown", "start": "2024-01-15T10:00:00", "end": "2024-01-19T18:00:00", "resource": "mixer", }, { "id": "preset-2", "title": "Tracking sessions", "start": "2024-01-16T09:00:00", "end": "2024-01-22T20:00:00", "resource": "studio", }, { "id": "preset-3", "title": "Mastering", "start": "2024-01-23T10:00:00", "end": "2024-01-25T16:00:00", "resource": "mixer", }, ] # `preset` is controlled in + out: the SegmentedControl drives the zoom level. # The five presets are dayAndHour, dayAndMonth, dayAndWeek, monthAndYear, year. presets = ["dayAndHour", "dayAndWeek", "dayAndMonth", "monthAndYear", "year"] component = dmc.Stack( [ dmc.SegmentedControl( id="event_timeline-presets-control", data=[ {"label": "Day / Hour", "value": "dayAndHour"}, {"label": "Day / Week", "value": "dayAndWeek"}, {"label": "Day / Month", "value": "dayAndMonth"}, {"label": "Month / Year", "value": "monthAndYear"}, {"label": "Year", "value": "year"}, ], value="dayAndWeek", ), dms.EventTimeline( id="event_timeline-presets", licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""), events=events, resources=resources, resourceColumnLabel="Resource", presets=presets, preset="dayAndWeek", defaultVisibleDate="2024-01-15", height=400, ), ], gap="sm", ) @callback( Output("event_timeline-presets", "preset"), Input("event_timeline-presets-control", "value"), ) def set_preset(value): return value ``` ### EventTimeline props `EventTimeline` shares most of its props with the calendar (events, resources, visibility, drag/resize flags, preferences, timezone) and adds the timeline specifics: `resourceColumnLabel`, `preset` / `defaultPreset` and `presets`. It needs a `licenseKey`. .. kwargs::dash_mui_scheduler.EventTimeline --- *Source: /event-timeline*