from data.data import *
def generate(lama_hari, is_img=False, data = ambil_data_emas()):
lama_hari = lama_hari if lama_hari >= lhs[0] else lhs[0]
# Preprocessing DataFrame
df = pd.DataFrame(data['data']['priceList'])[::-1][:lama_hari]
df['hargaBeli'] = pd.to_numeric(df['hargaBeli'])
df['hargaJual'] = pd.to_numeric(df['hargaJual'])
df['lastUpdate'] = tglf(df["lastUpdate"])
df = df.sort_values('lastUpdate').reset_index(drop=True)
df.rename(columns={
"hargaBeli": "hargaJual",
"hargaJual": "hargaBeli"
}, inplace=True)
hasil = []
df["hargaBeli"] *=100
df["hargaJual"] *=100
mindf = min(df["lastUpdate"])
isstb = []
isstbt = []
validTB = []
harga_jual_sekarang = df.iloc[-1]['hargaJual']
for i, tb in tqdm(enumerate(tanggal_beli)):
idx = (df['lastUpdate'] - tb).abs().idxmin()
row = df.loc[idx]
harga_beli = row['hargaBeli']
harga_jual = row['hargaJual']
tanggal_beli_riil = row['lastUpdate'].date()
if tb >=mindf:
validTB.append(tb)
tanggal_jual = df.iloc[-1]['lastUpdate'].date()
nilai_jual = harga_jual_sekarang * berat_gram[i]
profit = nilai_jual - uang_awal[i]
hasil.append({
"No": (i - len(isstb) + len(isstbt)) + 1,
"TglB": tanggal_beli_riil,
"HBg": harga_beli,
"g": berat_gram[i],
"M": uang_awal[i],
"TglJ": tanggal_jual,
"HJg": harga_jual,
"NJ": nilai_jual,
"PL": profit
})
if len(isstb) >=1:
isstb.append(True)
isstbt.append(True)
continue
isstb.append(True)
# Tambahkan total
total_berat = sum([h["g"] for h in hasil])
total_modal = sum([h["M"] for h in hasil])
total_nilai_jual = sum([h["NJ"] for h in hasil])
total_profit = sum([h["PL"] for h in hasil])
df.rename(columns={
"hargaBeli": "Harga Beli",
"hargaJual": "Harga Jual"
}, inplace=True)
# --- Tabel Transaksi ---
header = [
"No",
"Tgl Beli",
"Harga Beli/g (Rp)",
"Berat (g)",
"Modal (Rp)",
"Tgl Jual",
"Harga Jual/g (Rp)",
f"Nilai Jual Rp{harga_jual_sekarang:,.0f}/g",
"Profit/Loss (Rp)"
]
profit_loss_values = [row['PL'] for row in hasil] + [total_profit]
cells = [
[row["No"] for row in hasil],
[row["TglB"].strftime("%Y-%m-%d") for row in hasil],
[f"Rp {row['HBg']:,.0f}" for row in hasil],
[f"{row['g']:.4f} g" for row in hasil],
[f"Rp {row['M']:,.0f}" for row in hasil],
[row["TglJ"].strftime("%Y-%m-%d") for row in hasil],
[f"Rp {row['HJg']:,.0f}" for row in hasil],
[f"Rp {row['NJ']:,.0f}" for row in hasil],
[f"Rp {row['PL']:,.0f}" for row in hasil],
]
# Tambahkan total ke akhir tabel
for i, val in enumerate([
"Total",
misy*len(cells[1][0])+misy*(round(len(cells[1][0])/7.5)),
misy*len(cells[2][0])+misy*(round(len(cells[2][0])/7.5)),
f"{total_berat:.4f} g",
f"Rp {total_modal:,.0f}",
misy*len(cells[5][0])+misy*(round(len(cells[5][0])/7.5)),
misy*len(cells[6][0])+misy*(round(len(cells[6][0])/7.5)),
f"Rp {total_nilai_jual:,.0f}",
f"Rp {total_profit:,.0f}"
]):
cells[i].append(val)
lch = len(cells[0]) + 1
profit_loss_header_color = "#b3f3b3" if all(v > 0 for v in profit_loss_values) else (
"#f7b3b3" if all(v < 0 for v in profit_loss_values) else "#ffd6e7"
)
profit_loss_cell_colors = [
"#d4fcd4" if v > 0 else "#ffd6e0" if v < 0 else "#ffffff"
for v in profit_loss_values
]
header_fill_color[-1] = profit_loss_header_color
cells_fill_color[-1] = profit_loss_cell_colors
# Buat figure subplot dengan 2 baris: [0]=tabel, [1]=grafik
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=False,
vertical_spacing=0.1,
row_heights=[(lch if lch >= 5 else 5) / 10, 0.5],
specs=[[{"type": "table"}], [{"type": "scatter"}]]
)
# Tambahkan tabel transaksi emas
fig.add_trace(go.Table(
header=dict(values=header, fill_color=header_fill_color, align='center'),
cells=dict(values=cells, fill_color=cells_fill_color, align='center'),
columnwidth=cwta
), row=1, col=1)
# Tambahkan garis harga beli & jual
fig.add_trace(go.Scatter(
x=df['lastUpdate'], y=df['Harga Beli'], name="Harga Beli", line=dict(color='green')
), row=2, col=1)
fig.add_trace(go.Scatter(
x=df['lastUpdate'], y=df['Harga Jual'], name="Harga Jual", line=dict(color='red')
), row=2, col=1)
lbp = None
# Titik beli
for i, tb in tqdm(enumerate(validTB)):
lbp = "top" if i % 2 == 0 else "bottom"
fig.add_trace(go.Scatter(
x=[tb], y=[hasil[i]["HBg"]],
mode='markers+text',
name=f'Transaksi ke-{i+1} (Beli)',
text=[# f'Beli ke-{i+1}
(Rp {hasil[i]["M"]:,.0f})' if lama_hari <= 80 else
f'B{i+1}'],
textposition=f'{"top" if i % 2 == 0 else "bottom"} center',
# textfont=dict(size=10),
marker=dict(color='green', size=10)
), row=2, col=1)
continue
# Titik jual terakhir
fig.add_trace(go.Scatter(
x=[df.iloc[-1]['lastUpdate']], y=[df.iloc[-1]['Harga Jual']],
mode='markers+text',
name='Harga Jual Terakhir',
text=[# 'Jual Sekarang' if lama_hari <= 60 else
'JS'],
textposition=f'{"top" if lbp == "bottom" else lbp} center',
# textfont=dict(size=10),
marker=dict(color='red', size=10)
), row=2, col=1)
freq = get_freq(lama_hari)
# buat daftar tanggal sebagai tick values
tickvals = pd.date_range(
start=df['lastUpdate'].min().normalize(),
end=df['lastUpdate'].max().normalize(),
freq=freq
)
# Layout akhir
fig.update_layout(
title=dict(
text=f"📊 Tabel dan Grafik Harga Emas Pegadaian Digital per Gram ({lama_hari} Hari Terakhir)
Diambil pada {timestamp_lokal} dengan frekuensi {freq}",
x=0.5
),
xaxis=dict(
rangeslider=dict(visible=True),
type="date",
tickvals=tickvals,
tickformat="%Y-%m-%d",
tickangle=-90,
),
yaxis=dict(
title="Harga per Gram",
tickprefix="Rp ",
tickformat=",",
range=[min(df["Harga Jual"]) - 100_000, max(df["Harga Beli"]) + 100_000],
)
)
# terapkan ke sumbu x di subplot ke-2 (grafik)
fig.update_xaxes(
tickvals=tickvals,
tickformat="%Y-%m-%d",
tickangle=-90,
row=2, col=1
)
# Format Rupiah pada sumbu Y
fig.update_yaxes(
tickprefix="Rp ",
tickformat=",", # koma ribuan
row=2, col=1
)
# fig.show()
exts_img = ["png", "jpg", "jpeg", "webp", "svg", "pdf"]
exts = ["html"] + exts_img
filename_base = "grafik/pegadaian_digital/" + f"{lama_hari}/" + "hasil"
fitq = tqdm(exts, desc="Menyimpan grafik")
for ext in fitq:
filepath = f"{filename_base}.{ext}"
fitq.set_description(f"Saving {ext.upper()}")
try:
d = (
fig.to_html(full_html=False, include_plotlyjs='cdn')
if ext == "html"
else fig.to_image(format=ext)
)
uf(filepath, d)
except Exception as e:
print(f"Gagal menyimpan {ext}: {e}")
print("is_img", is_img)
return fig.to_image("svg").decode() if is_img else fig.to_html(
# full_html=False, include_plotlyjs='cdn'
)