Filter a Streamlit Traffic Dashboard Without Turning the Layout Into Glue

Filtered traffic dashboard in Streamlit
Suggested cover: a Streamlit dashboard selecting camera and vehicle filters before drawing KPI cards and first charts.

The first dashboard layer should answer simple questions quickly

Once the history frame is available, the dashboard has a straightforward job: pick a camera, pick vehicle types, show the current summary, then draw the first charts. That sequence is more valuable than it looks because it matches how people naturally read monitoring pages.

The temptation is to jump straight into charts. A better move is to establish the filter scope and KPI cards first. Charts make more sense when the reader already knows which slice of the data they are looking at.

This section is also where a large file can begin to feel sticky. Layout code, metrics and filtering can cling to each other if the structure is not intentional. A small amount of narrative scaffolding keeps the reading order intact.

Dashboard termMeaningWhy it stays practical
Filter scopeThe selected camera and set of vehicle types.It defines the exact slice the rest of the UI is allowed to talk about.
KPI cardA small metric block summarizing the latest row.It gives readers orientation before they inspect charts.
Shape chartA chart that describes how traffic is distributed.It adds pattern recognition after the summary layer is already in place.
        cur.execute(sql)
        conn.commit()
        print("Done!")
    except Exception as e:
        print(f"Error: {e}")

This alternative component keeps the forecast-card arithmetic in a quiet corner so the main recoverable slice can stay focused on dashboard flow.

Tiny helpers like that are especially useful in dashboards because they peel arithmetic away from layout code without creating a second abstraction maze.

    finally:
        if cur: cur.close()
        if conn: conn.close()

if __name__ == "__main__":
    run_batch_pipeline()

The ninth marked slice covers the filter selection, the latest-row KPI layer and the first two chart families, which makes it the real dashboard spine.

That spine is strong because it respects the reading order. The sidebar narrows the scope, the cards establish the current state, and only then do the charts explain shape and timing.

Alternative component: keep peak-hour extraction self-contained

CREATE TABLE IF NOT EXISTS mart.traffic_history (
    id SERIAL PRIMARY KEY,
    report_hour TIMESTAMP NOT NULL,
    camera_id VARCHAR(50) NOT NULL,
    vehicle_type VARCHAR(50) NOT NULL,

This neighboring block is deliberately color-separated. It belongs beside the KPI slice, but it is not part of the numbered chain you may want to recover later.

Putting a helper like that next to the main slice keeps the article full without pushing more inline detail into the recoverable fragment than it needs.

  • Resolve the filter scope before any KPI or chart logic runs.
  • Let the newest row drive the summary cards because that is the fastest route to context.
  • Keep the first charts tied to clear questions such as load by hour and vehicle mix.