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' )