DataLens

Widget input (button, slider, selectbox, text_input)

Biarkan pengguna memfilter dan menjelajahi data dengan selectbox, slider, multiselect, input teks dan angka, lalu sambungkan ke filter pandas.

Level: Dasar · 8 menit baca

Latihan modul ini

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

Idenya

Dashboard menjadi aplikasi saat pembaca bisa mengajukan pertanyaan mereka sendiri: "hanya kategori Coffee", "order di atas Rp 500.000", "hanya channel app". Setiap widget adalah satu pertanyaan, dan berkat model rerun, memakai jawabannya hanyalah Python biasa: baca nilainya, filter DataFrame-nya, tampilkan hasilnya.

import pandas as pd

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

Memilih satu opsi: selectbox dan radio

Hal pertama yang diinginkan sebagian besar pengguna dashboard adalah melihat satu potongan data, seperti satu kategori produk. Selectbox memberi mereka dropdown berisi pilihan, dan apa pun yang dipilih langsung menjadi nilai kembaliannya, siap dipakai untuk memfilter:

import streamlit as st
import pandas as pd

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

categories = sorted(completed["category"].unique())
category = st.selectbox("Category", categories)
rows = completed[completed["category"] == category]
st.metric(f"{category} revenue", f"Rp {rows['revenue'].sum():,}")
st.dataframe(rows[["order_date", "product", "quantity", "revenue"]], hide_index=True)

Untuk menawarkan "semuanya" sebagai pilihan, tambahkan ke opsi-opsinya:

import streamlit as st

options = ["All"] + ["Coffee", "Electronics", "Home"]
choice = st.radio("Show", options, horizontal=True)
st.write("You picked", choice)

Memilih beberapa: multiselect

Kadang pengguna ingin lebih dari satu opsi sekaligus, seperti kedua channel penjualan atau salah satunya saja. Multiselect memungkinkan mereka memilih berapa pun:

import streamlit as st
import pandas as pd

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

channels = st.multiselect("Channels", ["web", "app"], default=["web", "app"])
rows = completed[completed["channel"].isin(channels)]
st.write(f"{rows['order_id'].nunique()} orders from {', '.join(channels) or 'no channel'}")

Multiselect mengembalikan list. isin langsung mengubahnya menjadi filter. Perhatikan kasus kosong: kalau pengguna menghapus semua channel, list-nya kosong dan begitu juga hasilnya. Tentukan apa yang seharusnya ditampilkan untuk itu.

Angka: slider dan number_input

Untuk filter angka, seperti "hanya tampilkan baris pesanan yang nilainya minimal sekian", slider lebih cepat dipakai daripada mengetik angka:

import streamlit as st
import pandas as pd

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

min_revenue = st.slider("Minimum line revenue (Rp)", 0, 1_000_000, 100_000, step=50_000)
big = completed[completed["revenue"] >= min_revenue]
st.write(f"{len(big)} order lines of at least Rp {min_revenue:,}")

st.slider(label, min, max, default, step=...). Beri tuple sebagai default dan ia menjadi range slider yang mengembalikan (low, high):

import streamlit as st

low, high = st.slider("Price range (thousand Rp)", 0, 400, (50, 200))
st.write(f"Between {low} and {high}")

st.number_input adalah kotak dengan tombol + dan −, lebih baik saat pengguna tahu angka persisnya (quantity, target).

Teks: text_input

Kotak pencarian memungkinkan pengguna menemukan produk berdasarkan nama tanpa menggulir seluruh tabel:

import streamlit as st
import pandas as pd

sales = pd.read_csv("sales.csv")
search = st.text_input("Search products", placeholder="e.g. coffee")
if search:
    hits = sales[sales["product"].str.contains(search, case=False)]
    st.write(f"{hits['product'].nunique()} matching products")
    st.dataframe(hits[["product", "category"]].drop_duplicates(), hide_index=True)

Kotak teks yang kosong mengembalikan "", jadi if search: hanya memfilter setelah pengguna mengetik. case=False membuat pencariannya tidak membedakan huruf besar-kecil.

Key: memberi nama widget

Setiap widget diidentifikasi oleh label-nya. Dua widget dengan label yang sama membingungkan Streamlit:

import streamlit as st

start = st.date_input("Date")
end = st.date_input("Date")

Streamlit berhenti dengan error: There are multiple identical st.date_input widgets with the same generated key. Beri masing-masing key= yang unik (dan label yang lebih baik):

import streamlit as st

start = st.date_input("From", key="start_date")
end = st.date_input("To", key="end_date")

Key menjadi penting bersama st.session_state, dua modul dari sekarang.

Menggabungkan filter

Aplikasi sungguhan merangkai beberapa widget menjadi satu DataFrame hasil filter:

import streamlit as st
import pandas as pd

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

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.metric("Revenue", f"Rp {rows['revenue'].sum():,}")
st.dataframe(rows, hide_index=True)

Baca input dulu, filter langkah demi langkah, lalu tampilkan. Saat logika filter-nya bertambah, pindahkan ke sebuah fungsi filter_sales(df, category, channels) yang bisa kamu uji tanpa Streamlit.

Mengapa ini penting untuk kode yang bersih

Widget adalah input pengguna, jadi semua aturan input berlaku: beri label yang jelas, ambil opsi dari data, tangani kasus kosong, dan simpan logika filter di fungsi biasa. Aplikasi yang filternya tinggal di satu fungsi teruji mudah diubah; aplikasi yang filternya tersebar di antara pemanggilan widget tidak.

Rangkuman

Latihan modul ini

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

Berikutnya: Layout: columns, tabs, sidebar, expander →