DataLens

Layout: columns, tabs, sidebar, expander

Susun aplikasi menjadi sidebar berisi filter, deretan metric, tab untuk tampilan berbeda dan expander untuk detail.

Level: Menengah · 8 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Secara default, Streamlit menumpuk semuanya dalam satu kolom, dari atas ke bawah. Itu cukup untuk sebuah script, tapi dashboard sungguhan punya struktur: filter di samping, angka utama dalam satu baris, tampilan berbeda di tab, detail disimpan rapi sampai ada yang membutuhkannya. Empat alat layout mencakup hampir setiap kasus.

Apa pun yang ditulis ke st.sidebar muncul di panel yang bisa dilipat di sebelah kiri:

import streamlit as st
import pandas as pd

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]

with st.sidebar:
    st.header("Filters")
    category = st.selectbox("Category", ["All"] + sorted(completed["category"].unique()))
    channels = st.multiselect("Channels", ["web", "app"], default=["web", "app"])

rows = completed[completed["channel"].isin(channels)]
if category != "All":
    rows = rows[rows["category"] == category]

st.title("Sales dashboard")
st.write(f"{rows['order_id'].nunique()} orders match the filters.")

with st.sidebar: mengirim semua yang ada di dalam blok ke sidebar. st.sidebar.selectbox(...) melakukan hal yang sama untuk satu elemen. Menaruh filter di sidebar menyisakan area utama untuk hasil, pola yang langsung dikenali pengguna.

Kolom: hal-hal berdampingan

Secara bawaan, Streamlit menumpuk setiap elemen dalam satu kolom panjang. Itu tidak masalah di ponsel, tapi di laptop membuang tempat dan membuat pembaca harus menggulir. Solusi klasiknya adalah satu baris angka utama yang berdampingan di bagian atas halaman:

import streamlit as st

col1, col2, col3 = st.columns(3)
col1.metric("Revenue", "Rp 11.8M", "12%")
col2.metric("Orders", 26, "4")
col3.metric("Avg order", "Rp 455K", "-3%")

st.columns(3) mengembalikan tiga objek kolom; panggil elemen pada objek itu (col1.metric(...)) atau pakai with col1:. List angka mengatur lebar relatif:

import streamlit as st
import pandas as pd

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]

left, right = st.columns([2, 1])
with left:
    st.subheader("Orders")
    st.dataframe(completed[["order_date", "product", "revenue"]], hide_index=True)
with right:
    st.subheader("By channel")
    st.dataframe(completed.groupby("channel", as_index=False)["revenue"].sum(), hide_index=True)

[2, 1] membuat kolom kiri dua kali lebih lebar. Di ponsel, Streamlit otomatis menumpuk kolom secara vertikal.

Tab: tampilan berbeda dari data yang sama

Dashboard sering punya beberapa cara melihat data yang sama: ringkasan, rincian per produk, baris-baris mentahnya. Menaruh semuanya di satu halaman membuatnya sangat panjang. Tab memungkinkan pembaca berpindah antartampilan:

import streamlit as st
import pandas as pd

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]

overview, by_product, raw = st.tabs(["Overview", "By product", "Raw data"])
with overview:
    st.metric("Revenue", f"Rp {completed['revenue'].sum():,}")
with by_product:
    st.dataframe(completed.groupby("product", as_index=False)["revenue"].sum(), hide_index=True)
with raw:
    st.dataframe(completed, hide_index=True)

Tab menjaga halaman tetap pendek sambil menawarkan beberapa tampilan. Satu hal yang perlu diketahui: semua tab berjalan di setiap rerun, bahkan yang tersembunyi. Tab mengatur halaman; ia tidak menghemat komputasi.

Expander: detail sesuai permintaan

Ada informasi yang berguna tapi tidak untuk semua orang, seperti bagaimana persisnya sebuah angka dihitung. Expander menyembunyikannya di balik satu klik, supaya tidak memenuhi halaman:

import streamlit as st

st.metric("Cancelled orders", 10)
with st.expander("How is this counted?"):
    st.write("Orders with status *cancelled*, by order date. "
             "Orders cancelled after shipping are counted as returns, not cancellations.")

Expander sempurna untuk catatan cara perhitungan, data mentah dan "opsi lanjutan": tersedia bagi yang menginginkannya, tidak terlihat bagi orang lain.

Container dan placeholder

st.container() mengelompokkan elemen supaya kamu bisa mengisinya tidak berurutan:

import streamlit as st

header = st.container()
choice = st.radio("Period", ["This week", "This month"], horizontal=True)
with header:
    st.subheader(f"Report: {choice}")

Subheader muncul di atas radio, meskipun kode yang mengisinya berjalan sesudahnya. st.empty() menampung satu elemen yang bisa kamu ganti nanti, praktis untuk pesan progres.

Menyatukan semuanya

Kerangka dashboard yang khas:

import streamlit as st
import pandas as pd

st.set_page_config(page_title="Toko Kita", layout="wide")

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]

with st.sidebar:
    channels = st.multiselect("Channels", ["web", "app"], default=["web", "app"])
rows = completed[completed["channel"].isin(channels)]

st.title("Toko Kita sales")
c1, c2 = st.columns(2)
c1.metric("Revenue", f"Rp {rows['revenue'].sum():,}")
c2.metric("Orders", rows["order_id"].nunique())

tab1, tab2 = st.tabs(["By category", "Raw data"])
with tab1:
    st.bar_chart(rows.groupby("category")["revenue"].sum())
with tab2:
    st.dataframe(rows, hide_index=True)

st.set_page_config(layout="wide") memakai seluruh lebar browser. Perintah ini harus menjadi perintah Streamlit pertama di script.

Mengapa ini penting untuk kode yang bersih

Kode layout mencerminkan struktur halaman, jadi buat kodenya seterstruktur halamannya: satu blok with per area, filter dikumpulkan di blok sidebar, kode tampilan dikelompokkan per tab. Saat layout dan kode punya bentuk yang sama, mencari "di mana metric itu dihitung?" hanya butuh beberapa detik.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Menampilkan DataFrame dan grafik →