[ PERHATIAN ] APLIKASI INI DIPROGRAM MENGGUNAKAN BAHASA: JAVASCRIPT

Panduan Syntax Kode

KLIK UNTUK MELIHAT FULL SOURCE CODE JAVASCRIPT
// 1. DATA RUMAH SAKIT
const dataFaskes = [
    { id: "N1", nama: "RSUD Pasar Minggu", jarak: 0.85, layanan: ["IGD", "ICU", "MRI", "Radiologi", "MCU", "Laboratorium"] },
    { id: "N2", nama: "Aji Waras Klinik", jarak: 1.8, layanan: ["Poli Umum", "Laboratorium", "Radiologi", "USG", "Apotek"] },
    { id: "N3", nama: "Lamina Hospital", jarak: 3.1, layanan: ["MRI", "Radiologi", "MCU", "Laboratorium", "CT SCAN", "X-Ray"] },
    { id: "N4", nama: "Kemang Medical Care Hospital", jarak: 2.1, layanan: ["IGD", "ICU", "HCU", "NICU", "Radiologi", "Laboratorium", "Apotek"] },
    { id: "N5", nama: "RS Murni Teguh Pejaten", jarak: 2.3, layanan: ["IGD", "ICU", "Radiologi", "Laboratorium", "Rehabilitasi"] },
    { id: "N6", nama: "RS Jakarta Medical Center", jarak: 3.4, layanan: ["IGD", "ICU", "Radiologi", "Laboratorium", "Apotek"] },
    { id: "N7", nama: "RSUD Jagakarsa", jarak: 3.5, layanan: ["IGD", "Radiologi", "MCU", "Laboratorium"] },
    { id: "N8", nama: "RS Marinir Cilandak", jarak: 6, layanan: ["IGD", "ICU", "Radiologi", "MCU", "Laboratorium"] },
    { id: "N9", nama: "RSUD Jati Padang", jarak: 3.5, layanan: ["IGD", "Radiologi", "MCU", "Laboratorium", "Apotek"] }
];

const kamusNama = {
    "N0": "UNSIA", "N1": "RSUD Pasar Minggu", "N2": "Aji Waras Klinik", "N3": "Lamina Hospital", 
    "N4": "Kemang Medical Care", "N5": "RS Murni Teguh", "N6": "RS JMC", "N7": "RSUD Jagakarsa", 
    "N8": "RS Marinir", "N9": "RSUD Jati Padang",
    "J1": "Jl. Harsono RM", "J2": "Jl. TB Simatupang", "J3": "Jl. Raya Cilandak KKO",
    "J4": "Jl. Ampera Raya", "J5": "Jl. Warung Jati Barat", "J6": "Jl. Hajjah Tutti Alawiyah",
    "J7": "Jl. Saco Ragunan", "J8": "Jl. Intan RSPP", "J9": "Jl. Raya Ragunan"
};

// 2. STRUKTUR GRAPH
const graphPeta = {
    "N0": ["J1"], 
    "J1": ["N0", "J2", "J5", "J7"],
    "J2": ["J1", "N1", "J3", "J4", "J8"], 
    "N1": ["J2"], 
    "J3": ["J2", "N2"], 
    "N2": ["J3"],
    "J4": ["J2", "N4"], 
    "N4": ["J4"],
    "J8": ["J2", "N8"], 
    "N8": ["J8"],
    "J5": ["J1", "N5", "N3", "J6", "J9"], 
    "N5": ["J5"],
    "N3": ["J5"],
    "J6": ["J5", "N6"], 
    "N6": ["J6"],
    "J9": ["J5", "N9"], 
    "N9": ["J9"],
    "J7": ["J1", "N7"], 
    "N7": ["J7"]
};

for (let key in graphPeta) graphPeta[key].sort();

// 3. ALGORITMA PENCARIAN (LINEAR SEARCH)
function searchingLayanan(kataKunci) {
    return dataFaskes.filter(rs => 
        rs.layanan.some(l => l.toLowerCase().includes(kataKunci.toLowerCase())) ||
        rs.nama.toLowerCase().includes(kataKunci.toLowerCase())
    );
}

// 4. ALGORITMA PENGURUTAN (BUBBLE SORT)
function sortingJarak(arrayData) {
    let arr = [...arrayData];
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - 1; j++) {
            if (arr[j].jarak > arr[j + 1].jarak) {
                let temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

// 5. ALGORITMA TRAVERSAL (BFS & DFS - Tetap Simpel)
function ruteBFS(start, target) {
    let antrean = [[start]];
    let dikunjungi = new Set([start]);
    let logPencarian = []; 

    while (antrean.length > 0) {
        let jalur = antrean.shift();
        let nodeSekarang = jalur[jalur.length - 1];
        
        logPencarian.push(nodeSekarang); // Catat jejak

        if (nodeSekarang === target) {
            return { ruteAsli: jalur, jejakVisual: logPencarian };
        }

        let tetangga = graphPeta[nodeSekarang] || [];
        for (let t of tetangga) {
            if (!dikunjungi.has(t)) {
                dikunjungi.add(t);
                antrean.push([...jalur, t]);
            }
        }
    }
    return null;
}

function ruteDFS(start, target, dikunjungi = new Set(), jalur = [], logPencarian = []) {
    dikunjungi.add(start);
    jalur.push(start);
    logPencarian.push(start); // Catat jejak

    if (start === target) {
        return { ruteAsli: jalur, jejakVisual: logPencarian };
    }

    let tetangga = graphPeta[start] || [];
    for (let t of tetangga) {
        if (!dikunjungi.has(t)) {
            let hasilJalur = ruteDFS(t, target, dikunjungi, [...jalur], logPencarian);
            if (hasilJalur) {
                return hasilJalur;
            }
        }
    }
    return null;
}

// 6. LOGIKA ANTARMUKA UI 
const box = document.getElementById("outputBox");
let animasiSedangBerjalan = false;

function pemicuCari() {
    const keyword = document.getElementById("inputCari").value;
    const hasil = searchingLayanan(keyword);
    if(hasil.length === 0) {
        box.innerHTML = `[Searching] "${keyword}" tidak ditemukan.`;
    } else {
        box.innerHTML = `[Searching] Ditemukan ${hasil.length} Faskes:<br>` + 
            hasil.map(rs => `- ${rs.nama}`).join('<br>');
    }
}

function pemicuUrut() {
    const hasilUrut = sortingJarak(dataFaskes);
    box.innerHTML = "[Sorting] Urutan Faskes Terdekat:<br>" + 
        hasilUrut.map((rs, idx) => `${idx + 1}. ${rs.nama} (Jarak: ${rs.jarak} Km)`).join('<br>');
}

function pemicuNavigasi(metode) {
    if (animasiSedangBerjalan) return;

    const tujuan = document.getElementById("pilihTujuan").value;
    const namaTujuan = kamusNama[tujuan];
    let hasilCari = metode === 'BFS' ? ruteBFS("N0", tujuan) : ruteDFS("N0", tujuan);

    if (hasilCari) {
        box.innerHTML = `<strong>[Metode ${metode}]</strong><br>Sedang menyimulasikan algoritma di peta...`;
        mainkanAnimasiPeta(hasilCari.jejakVisual, hasilCari.ruteAsli, metode, namaTujuan);
    } else {
        box.innerHTML = `[Metode ${metode}] Rute tidak ditemukan.`;
    }
}

Credits:
MUHAMMAD RAFLY AL BAIHAQI (250401010485)
PRASTYA ARDHI RAMADHAN (250401010498)
THOLE RAMADHAN ORRIZAL DERIDAMARA (250401010529)

1. Penyimpanan Data (Array & Object)

Contoh Paling Sederhana:
// Array (Daftar)
let daftarBuah = ["Apel", "Mangga"];

// Object (Kartu Profil)
let siswa = { nama: "Budi", umur: 20 };
Array itu seperti daftar belanjaan yang memanjang ke bawah. Object itu seperti KTP. Pada kode aplikasi kita, kita membuat daftar (Array) yang isinya adalah kumpulan profil lengkap KTP Rumah Sakit (Object).
Pembedahan Syntax Kode Asli:
const dataFaskes = [
->
const: Membuat variabel yang tidak boleh dihapus.
[ ]: Menandakan tipe data berbentuk Array (Daftar).
{ nama: "RSUD Pasar Minggu", jarak: 0.85 },
->
{ }: Membuka data Object. Kita menyimpan data nama (teks) dan data jarak (angka) rumah sakit ke-1.
{ nama: "Aji Waras Klinik", jarak: 1.8 }
->
Data rumah sakit ke-2. Tiap object selalu dipisahkan oleh tanda koma (,).
];
->
Tanda tutup kurung siku ] menandakan daftar rumah sakit telah ditutup/selesai.

2. Peta Sambungan Jalan (Graph)

Contoh Paling Sederhana:
let jalan = {
    "Rumah": ["Pasar", "Sekolah"]
};
Graph (Graf) adalah cara komputer melihat persimpangan jalan Google Maps. Komputer membacanya seperti ini: Jika saya berdiri di titik "Rumah", maka saya hanya punya 2 rute jalan yang bisa dilewati, yaitu rute menuju "Pasar" atau rute menuju "Sekolah".
Pembedahan Syntax Kode Asli:
const graphPeta = {
->
Membuka Object utama khusus untuk menyimpan kerangka peta rute persimpangan.
"J1": ["N0", "J2", "J5", "J7"]
->
"J1" adalah kunci posisi berdiri sekarang. Di sebelah kanannya adalah Array tujuan lokasi persimpangan yang nyambung (terhubung) ke J1.
};
->
Tanda tutup Object peta.

3. Algoritma Pencarian Teks (Linear Search)

Contoh Logika Paling Sederhana:
let kalimat = "Rumah Sakit";
if (kalimat.includes("Sakit")) {
    console.log("Berhasil ditemukan!");
}
Pencarian "Linear" artinya komputer membaca teks berurutan dari baris 1 sampai baris terakhir, persis seperti guru mencari nama murid di buku presensi absen sekolah.
Pembedahan Syntax Kode Asli:
function searchingLayanan(kataKunci) {
->
function: Membuka fungsi pencarian. kataKunci adalah tulisan yang diketik oleh pengguna web.
return dataFaskes.filter(rs =>
->
.filter(): Mengecek seluruh Array dataFaskes dan membuang yang salah (menyaring data yang benar saja).
rs.layanan.some(l => l.includes(kataKunci))
->
.some() & .includes(): Apakah dari daftar layanan RS ini, ada teks yang mirip (include) dengan kataKunci?
);
}
->
Tutup proses penyaringan dan kembalikan hasilnya.

4. Mengurutkan Jarak (Bubble Sort)

Contoh Logika Paling Sederhana:
if (Kotak_Kiri > Kotak_Kanan) {
    // Tukar posisi mereka berdua!
}
Komputer membandingkan dua kotak bersebelahan. Kalau kotak KIRI ternyata nilainya lebih besar/berat dari kotak KANAN, maka posisi mereka DITUKAR. Yang besar akan terus didorong pelan-pelan ke arah ujung barisan, mirip gelembung udara di air (Bubble).
Animasi Mengurutkan Angka (Bubble Sort)
3
1
2
5
6
4
Stikman secara bertahap mengangkat dan berhenti sebentar untuk membandingkan 2 angka.
Jika angka sebelah kiri lebih besar, maka akan ditukar posisinya. Jika angka sudah benar posisinya, ditaruh kembali.
Saat selesai di ujung kanan, stikman kembali ke kiri untuk mengulanginya lagi hingga barisan 1-6 urut sempurna.
Pembedahan Syntax Kode Asli:
if (arr[j].jarak > arr[j + 1].jarak) {
->
if ( > ): Mengecek apakah kotak bagian Kiri (j) jaraknya lebih besar/jauh dari kotak Kanan sebelahnya (j + 1).
let temp = arr[j];
->
temp: Variabel kantong cadangan. Mengamankan isi kotak Kiri supaya tidak hilang tertimpa.
arr[j] = arr[j + 1];
->
Pindahkan isi kotak Kanan (j + 1) ke tempat/meja kotak Kiri (j).
arr[j + 1] = temp;
->
Pindahkan kembali isi kantong cadangan (temp) ke tempat kotak Kanan. Tukar silang (swap) sukses!

5. Pencarian Melebar (BFS - Breadth First Search)

Komputer mencari jalan menggunakan sistem Antrean Kasir (Queue). Titik persimpangan yang dimasukkan ke antrean lebih dulu, pasti akan dicek lebih dulu (Keluar dari depan). Hasilnya, komputer mengecek rute terdekat secara melebar (per level/cabang terdekat) bak gelombang air.
Animasi Pencarian Melebar (BFS)
1. Memori Antrean (Queue)
Jalan A
Jalan B
Jalan C
2. Visualisasi Rute Peta (Kanan Atas)
TUJUAN
Stikman (biru) menelusuri secara merata dari titik awal. Ia mengecek seluruh cabang yang terdekat satu-persatu (kiri lalu kanan).
Jika belum bertemu tujuan, barulah ia melangkah lebih dalam ke level persimpangan berikutnya secara bertahap hingga menemukan tujuan di kanan atas.
Pembedahan Syntax Kode Asli:
let antrean = [[start]];
->
Membuat keranjang Array kosong untuk sistem mengantre, dan langsung memasukkan posisi awal berdiri (start).
while (antrean.length > 0) {
->
while: Memerintahkan komputer mengulangi pencarian tanpa henti selama antrean tidak kosong.
let jalur = antrean.shift();
->
.shift(): Mengeluarkan/mencabut rute dari barisan PALING DEPAN untuk dicek apakah itu tujuan kita.
antrean.push(tetangga);
->
.push(): Kalau rute tadi salah (belum ketemu), maka temuan persimpangan jalan di depannya dimasukkan ke antrean PALING BELAKANG untuk dicek besok-besok.

6. Pencarian Mendalam (DFS - Depth First Search)

Berbeda dengan BFS yang menyebar, DFS itu ibarat menerobos masuk ke dalam gang secara lurus terus sampai mentok (ujung). Kalau buntu, baru mundur. Komputer mencatat rute ini dengan sistem Tumpukan Barang (Stack). Barang yang ditumpuk terakhir di posisi paling atas, harus diambil duluan jika ingin mundur / membongkar susunannya (Keluar mundur).
Animasi Pencarian Mendalam (DFS)
1. Memori Tumpukan (Stack)
Gang A
Cabang B
Ujung C
2. Visualisasi Rute Peta (Kanan Bawah)
TUJUAN
Stikman (merah) menelusuri rute labirin dan selalu memprioritaskan mengeksplorasi cabang lurus/kiri lebih dalam terlebih dahulu.
Bila bertemu jalan buntu (garis merah tipis), ia akan mengingat langkah sebelumnya di dalam memori Stack dan mundur kembali (backtracking) melewati logo T/Siku untuk mencari cabang lain, hingga tujuan (hijau) berhasil ditemukan.
Pembedahan Syntax Kode Asli:
function ruteDFS(titikAwal) {
->
Membuka fungsi DFS untuk pertama kalinya (misalnya saat klik tombol).
for (let t of tetangga) {
->
for: Memutar roda untuk memeriksa jalan cabang di persimpangan ini satu-satu.
let hasil = ruteDFS(t);
->
REKURSIF: Ini ajaib. Fungsi ini ternyata memanggil namanya sendiri dari dalam untuk masuk ke cabang gang yang barusan ditemukan. Proses lurus akan terus menumpuk di atas.
}
return null;
->
Jika masuk perulangan ternyata buntu, kembalikan null (kosong). Saat menerima 'null', komputer akan otomatis mundur 1 langkah ke atas tumpukan barang untuk mengecek gang cabang lainnya.

7. Tombol dan Antarmuka (DOM / UI Logic)

Contoh Logika Paling Sederhana:
let layarTV = document.getElementById("layarOutput");

// Beri perintah ke layar TV
layarTV.innerHTML = "Tombol Berhasil Ditekan!";
JavaScript membutuhkan jembatan untuk bisa berinteraksi dengan layar web HTML. getElementById ibarat sebuah remote control. Saat Anda memencet tombol, JavaScript membalasnya dengan mencetak tulisan ke layar melalui syntax innerHTML.
Pembedahan Syntax Kode Asli:
const box = document.getElementById("outputBox");
->
getElementById: JavaScript mencari kotak di HTML yang memiliki ID `outputBox` dan mengendalikannya memakai remote bernama box.
function pemicuUrut() {
->
Fungsi ini akan tertembak (terpicu) ketika tombol 'Urutkan' ditekan di layar web.
box.innerHTML = "Berhasil Diurutkan!";
}
->
.innerHTML: Kita menggunakan remote `box` untuk menuliskan teks langsung masuk ke dalam layar website secara real-time.

Note: Visual Peta 2D sengaja tidak dibahas karena berada di luar materi struktur data dan murni berfungsi sebagai visualisasi metode DFS dan BFS.