# Timeline

## Introduction

**`Timeline`** widget is used to display video timeline. It can be used to get current frame and display information about the frame or it's annotation.

## Function signature

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 6], [6, 11], [12, 15], [16, 17], [18, 19], [20, 31]],
    colors=["#DB7093", "#93db70", "#7093db", "#70dbb8", "#db8370", "#db70c9"],
    height="30px",
)
```

![default](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/e79702bb-9a9a-46bb-87a1-00c0fc786064)

## Parameters

|     Parameters    |        Type       |              Description              |
| :---------------: | :---------------: | :-----------------------------------: |
|   `frames_count`  |       `int`       |         Timeline frames count         |
|    `intervals`    | `List[List[int]]` |            Frame intervals            |
|      `colors`     |    `List[str]`    | Intervals colors in `hex` color codes |
|      `height`     |       `str`       |        Timeline height in `px`        |
|  `pointer_color`  |       `str`       |          Color of the pointer         |
| `tooltip_content` |      `Widget`     |         Content of the tooltip        |
|    `widget_id`    |       `str`       |            ID of the widget           |

### frames\_count

Timeline (video) frames count.

**type:** `int`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 6], [6, 11], [12, 15], [16, 17], [18, 19], [20, 31]],
    colors=["#DB7093", "#93db70", "#7093db", "#70dbb8", "#db8370", "#db70c9"],
)
```

![frames\_count](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/e79702bb-9a9a-46bb-87a1-00c0fc786064)

### intervals

Set frame intervals. Each interval is a list of two integers: `[start_frame, end_frame]`. Intervals and color lists must be the same length.

**type:** `List[List[int]]`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 15], [16, 31]],
    colors=["#93db70", "#7093db"],
)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/172757aa-3bd9-4516-941f-d528d34c1eee)

### colors

Set interval colors in `hex` color codes. Intervals and color lists must be the same length.

**type:** `List[str]`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 31]],
    colors=["#4C0013"],
)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/ca97c624-bcdd-4a49-9f3a-307298b0b51a)

### height

Set widget height in `px`.

**type:** `str`

**default value:** `30px`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 6], [6, 11], [12, 15], [16, 17], [18, 19], [20, 31]],
    colors=["#DB7093", "#93db70", "#7093db", "#70dbb8", "#db8370", "#db70c9"],
    height="60px",
)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/668e3834-5c6e-4591-a2a8-44500b6fea16)

### pointer\_color

Color of the pointer. Set hex color code or `None` to use the default color.

**type:** `str`

**default value:** `None`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 6], [6, 11], [12, 15], [16, 17], [18, 19], [20, 31]],
    colors=["#DB7093", "#93db70", "#7093db", "#70dbb8", "#db8370", "#db70c9"],
    pointer_color="#FF0000", # red color
)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/867fe213-5c4f-4601-988f-84e85bd16361)

### tooltip\_content

Content of Tooltip.

**type:** `Widget`

**default value:** `None`

```python
timeline = Timeline(
    frames_count=31,
    intervals=[[0, 6], [6, 11], [12, 15], [16, 17], [18, 19], [20, 31]],
    colors=["#DB7093", "#93db70", "#7093db", "#70dbb8", "#db8370", "#db70c9"],
    pointer_color="#FF0000", # red color
    tooltip_content=Text("Clickable Area", "text"),
)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/e42d1bd5-5691-4289-b532-c7cc8c8d30e7)

### widget\_id

ID of the widget.

**type:** `str`

**default value:** `None`

## Mini App Example

You can find this example in our Github repository:

[supervisely-ecosystem/ui-widgets-demos/controls/008\_timeline/src/main.py](https://github.com/supervisely-ecosystem/ui-widgets-demos/blob/master/controls/008_timeline/src/main.py)

### Import libraries

```python
import os
from random import randint
import supervisely as sly
from dotenv import load_dotenv
from supervisely.app.widgets import (
    Card,
    Container,
    Timeline,
    Text,
    InputNumber,
    VideoThumbnail,
)
```

### Write a function for dividing the total number of frames by ranges

```python
def divide_to_ranges(total, n):
    step = total // n
    ranges = []
    for i in range(n):
        start = i * step
        end = start + step - 1 if i < n - 1 else total - 1
        ranges.append([start, end])
    return ranges, len(ranges)
```

### Write function generating random hex colors for each range

```python
def generate_hex_colors(n):
    colors = []
    for _ in range(n):
        color = "#{:06x}".format(randint(0, 0xFFFFFF))
        colors.append(color)
    return colors
```

### Init API client

First, we load environment variables with credentials and init API for communicating with Supervisely Instance:

```python
load_dotenv("local.env")
load_dotenv(os.path.expanduser("~/supervisely.env"))

api = sly.Api()
```

### Initialize `Video ID` we will use

```python
video_id = 350000  # set your video id here
```

### Get video info from server and prepare VideoThumbnail widget

```python
video = api.video.get_info_by_id(video_id)
video_thumbnail = VideoThumbnail(video)
```

### Get video intervals and colors from video frame count

```python
video_intervals, intervals_n = divide_to_ranges(video.frames_count, 5)
intervals_colors = generate_hex_colors(intervals_n)
```

### Initialize Timeline widget

```python
timeline = Timeline(
    frames_count=video.frames_count,
    intervals=video_intervals,
    colors=intervals_colors,
    height="35px",
)
```

### Create InputNumber widget for setting current frame

```python
timeline_select_frame = InputNumber(value=1, min=0, max=video.frames_count, step=1)
timeline_text = Text("<span>Frame:</span>")
```

### Create Timeline container

```python
timeline_container = Container(
    widgets=[
        timeline,
        timeline_text,
        timeline_select_frame,
    ],
    direction="horizontal",
    fractions=[1, 0, 0],
    style="place-items: center;",
)
```

### Create app layout

```python
main_container = Container(widgets=[video_thumbnail, timeline_container])
layout = Card(title="Timeline", content=main_container)
```

### Create app using layout

Create an app object with layout parameter.

```python
app = sly.Application(layout=layout)
```

![](https://github.com/supervisely-ecosystem/ui-widgets-demos/assets/48913536/564094d3-b0b0-4988-a43e-760b26cd0cab)

### Add callbacks for changing the current frame

```python
@timeline.click
def show_current_value(pointer):
    timeline_select_frame.value = pointer


@timeline_select_frame.value_changed
def set_timeline_pointer(frame):
    timeline.set_pointer(frame)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.supervisely.com/app-development/widgets/controls/timeline.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
