New Component: Streamlit Timeline, creating beautiful timelines with bi-directional communication

image
Open in Streamlit

Streamlit component for rendering vis.js timeline.

Check out the GitHub repositories streamlit-timeline and
streamlit-timeline-demo. For JavaScript examples,
check out the vis.js timeline examples and
documentation.

Installation

pip install streamlit-vis-timeline

Usage

import streamlit as st
from streamlit_timeline import st_timeline

st.set_page_config(layout="wide")

items = [
    {"id": 1, "content": "2022-10-20", "start": "2022-10-20"},
    {"id": 2, "content": "2022-10-09", "start": "2022-10-09"},
    {"id": 3, "content": "2022-10-18", "start": "2022-10-18"},
    {"id": 4, "content": "2022-10-16", "start": "2022-10-16"},
    {"id": 5, "content": "2022-10-25", "start": "2022-10-25"},
    {"id": 6, "content": "2022-10-27", "start": "2022-10-27"},
]

timeline = st_timeline(items, groups=[], options={}, height="300px")
st.subheader("Selected item")
st.write(timeline)

Demo

11 Likes

What a fabulous Component, Qiusheng! :raised_hands:

I’ve added it to @andfanilo’s Component tracker! :tada:

Huge thanks for this wonderful component, Qiusheng!

Would you have an idea how I could accomplish multiselection in my code? I checked the documentation and passed " ‘mulitselect’: True" into the options but it does not work.

import streamlit as st
from streamlit_timeline import st_timeline

st.set_page_config(layout="wide")

st.title("Test Plan")

items = [
    {"id": 1, "content": "Early shift", "start": "2022-10-17T08:00:00", "end": "2022-10-17T16:00:00", "group": "1"},

    {"id": 2, "content": "Early shift", "start": "2022-10-17T11:00:00", "end": "2022-10-17T15:00:00", "group": "2"},

    {"id": 3, "content": "Early shift", "start": "2022-10-17T10:00:00", "end": "2022-10-17T18:00:00", "group": "3"}
]

groups = [
    {"id": 1, "content": "Worker 1", "style": "color: black; background-color: #a9a9a98F;"},
    {"id": 2, "content": "Worker 2", "style": "color: black; background-color: #a9a9a98F;"},
    {"id": 3, "content": "Worker 3", "style": "color: black; background-color: #a9a9a98F;"}
]

timeline = st_timeline(items, groups=groups, options={"selectable": True, 
                                                      "multiselect": True, 
                                                      "zoomable": True, 
                                                      "verticalScroll": True, 
                                                      "stack": False,
                                                      "height": 200, 
                                                      "margin": {"axis": 5}, 
                                                      "groupHeightMode": "auto", 
                                                      "orientation": {"axis": "top", "item": "top"}})

st.subheader("Selected item")
st.write(timeline)

Any help is much appreciated - Thanks in advance!
Robert

1 Like

I am a beginner in python. So, I am not sure how do I get my dataframe into a format that is suited for this library. So, far I have done following but it is not working. I am getting error of “string indices must be integers”. My dataframe name is item3 here (a subset of my main dataframe filtereddata with columns of project name, start date, end date and some other columns. It doesn’t have an ID column, so I have inserted it manually.

import streamlit as st
from streamlit_timeline import st_timeline

filtered_data.insert(0,'New_ID', range(880, 880 + len(filtered_data)))
items3= filtered_data[['New_ID','start_date','end_date']]


items3 = filtered_data.to_json()
                        
items = [{'id':items3['New_ID'],'content':items3['end_date'],'start':items3["start_date"]}]

timeline = st_timeline(items, groups=[], options={}, height="300px")
st.subheader("Selected item")
st.write(timeline)

Solved! Error was in JSON date conversion

1 Like

Hello,

Could someone please help me change the style of the line and the dot?
My only success is to change the box’s style without changing the line and the dot.

thank you

Amazing component! Loved it!
I am planning to use it to schedule the production at my ice cream factory. So far I was able to to display the data, it has worked perfectly. But I was not able to store the new “start” data after rearranged, as the component returns the initial value of the item. Does anyone have a work around for this? Here is my code:

import streamlit as st
from streamlit_timeline import st_timeline


st.set_page_config(page_title="Timeline", layout="wide")
if 'timeline' not in st.session_state:
    st.session_state['timeline'] = None
    st.session_state['timeline_items'] = [
        {"id": 1, "content": "static 1", "start": "2022-10-20"},
        {"id": 2, "content": "Editable 1", "start": "2022-10-09", "editable": True},
        {"id": 3, "content": "Editable 2", "start": "2022-10-18", "editable": True},
        {"id": 4, "content": "static 2", "start": "2022-10-16"},
        {"id": 5, "content": "static 3", "start": "2022-10-25"},
        {"id": 6, "content": "static 4", "start": "2022-10-27"},
    ]


def display_return_info(place):
    with place:
        with st.container():
            st.title('Returned value:')
            st.write(st.session_state['timeline'])


def run_code():
    st.title("Streamlit Timeline")
    timeline_form = st.form(key='foo')
    return_vals = st.empty()

    with timeline_form:
        timeline = st_timeline(st.session_state['timeline_items'], groups=[], options={}, height="300px")
        if st.form_submit_button('Done'):
            st.session_state['timeline'] = timeline
            display_return_info(return_vals)


run_code()

Thank you!

With “start” and “end” you can configure the start and endpoint of the axis once the timeline is loaded for the first time. When setting these options the timeline does not load at all. The code needs to be rerun to display the timeline.

from streamlit_timeline import st_timeline

st_timeline(items=[], groups=[], options={
    "start": "2014-01-10",
    "end": "2016-01-10",
    }
)

I posted a Github issue Github but has anyone here an idea, why this happens, one “start” or “end” are configured?

Thanks for any help in advance!
Robert

Another issue I figured out is the clustering option which seems not to work properly.

I am rendering about 20k items and therefore would like to use the “cluster” option described at the documentation of vis.js timeline vis.js Docu

I am trying to cluster items with the following code but nothing happens.

from streamlit_timeline import st_timeline

items = [
    {"id": 1, "start": "2023-05-01", "end": "2023-05-09", "group": 3},
    {"id": 2, "start": "2023-05-06", "end": "2023-05-12", "group": 3}
]

st_timeline(items=items, 
            groups=[], 
            height=200, 
            options={
              "cluster": {"showStipes": True, "maxItems": 5}
            }
)

I tried to play around with the formatting of the option such as put the True into a string (“true”) etc. but all tries failed so far.

Does anybody have an idea?

Thanks in advance!

Hello! I have a similar issue here, does anyone know how to change the box style and line colour? Also, any idea how to insert custom dates on the x axis for the particular events added to the timeline? Thanks!

Hi,
I have one question here.

How can have this Timeline directly within Streamlit in Snowflake? Or if you know any alternative solution for having a Timeline directly in Snowflake?

Thank you!