Pengenalan Web Form

  • Form berperan penting dalam hal interaksi antara sistem dengan pengguna, misalkan form pencarian, log in, dst
  • Struktur Form HTML bisa dibuat menggunakan elemen <form> yang digunakan pada set kontrol lainnya seperti input text, checkboxes, buttons, dll.

<form action="/submit-form" method="POST">
  <!-- Form controls go here -->
  <input type="submit" value="Submit">
</form>
            

Text Input Labels

  • Text Input dan Labels memungkinkan pengguna memasukkan informasi data kedalam form dengan menggunakan elemen <input> dengan type="text"
  • 
    <label for="username">Username:</label>
    <input type="text" id="username" name="username">
                  
    Type bisa berbentuk text, email atau password

Radio Buttons dan Checkboxes

  • Radio button memungkinkan user untuk memilih hanya satu pilihan sedangkan untuk Checkboxes merupakan form yang digunakan untuk pilihan yang lebih dari 1 pilihan pada saat yang bersamaan.
  • 
    label for="username">Username:</label>
    <input type="text" id="username" name="username">
    
    <input type="radio" id="male" name="gender" value="male">
    <label for="male">Male</label><br>
    
    <input type="radio" id="female" name="gender" value="female">
    <label for="female">Female</label><br>
    
    <input type="checkbox" id="subscribe" name="subscribe" value="yes">
    <label for="subscribe">Subscribe to newsletter</label><br>
                  

Text Area

  • Yang membedakan textarea dengan input biasa adalah textarea bisa digunakan ketika input mempunyai baris yang banyak.
    Ini dapat dicapai dengan menggunakan elemen <textarea> pada pembukaan dan penutupan tag seperti pada contoh.
  • 
    label for="username">Username:</label>
    <input type="text" id="username" name="username">
    
    <input type="radio" id="male" name="gender" value="male">
    <label for="male">Male</label><br>
    
    <input type="radio" id="female" name="gender" value="female">
    <label for="female">Female</label><br>
    
    <input type="checkbox" id="subscribe" name="subscribe" value="yes">
    <label for="subscribe">Subscribe to newsletter</label><br>
                  

Intro css

  • Apa itu CSS?
    CSS adalah singkatan dari Cascading Style Sheets. Ini digunakan untuk mengatur style elemen HTML.
  • Cara menyertakan file css
    • Inline CSS:
      
      <h1 style="color: blue;">Hello World</h1>
                          
    • Internal CSS:
      
      <style> h1 { color: blue; } </style>
                              
    • External CSS:
      
      <link rel="stylesheet" href="styles.css">
                          

Sintaks Dasar css

  • Selector:
    Menargetkan elemen HTML yang mau kita style
  • Property:
    Adalah aspek elemen yng hendak kita ganti(mis, warna).
    • Inline CSS:
      
        <h1 style="color: blue;">Hello World</h1>
                            
  • Value:
    Value yang ditetapkan ke properti (misalnya, blue).
                        
      h1 {
        color: blue;
        font-size: 20px;
      }
                        
                      

Selector

  • Selector Elemen:
    Menargetkan dengan nama elemen (mis, p untuk paragraph).
  • Selector Kelas:
    Menargetkan dengan nama kelas (mis, .class-name).
  • Selector ID:
    Menargetkan dengan ID (mis, #id-name).
    
      .example-class {
        color: red;
      }
      #example-id {
        font-size: 18px;
      }
                        

Warna dan Background

  • Property Warna:
    color: red;
  • Warna Background:
    background-color: yellow;
  • Gambar Background:
    background-image: url('image.jpg');
    
    body {
      background-color: lightgray;
    }
    
    h1 {
      color: green;
      background-image: url('background.jpg');
    }
                        

Model Box

Dalam CSS, istilah Model Box digunakan pada desain dan layout. Visualisasinya dapat dilihat pada gambar dibawah


.box {
  width: 200px;
  padding: 10px;
  border: 2px solid black;
  margin: 20px;
}
              

Terdiri dari konten, padding, border dan margin

  • Konten: Konten aktual box.
  • Padding: Memberikan ruang area sekitar konten (dalam border)
    Adalah property yang digunakan untuk membuat ruang antara elemen dan border. Ruang ini terdapat dalam elemen border.
    • Padding dapat diset dalam 4 arah sebagai berikut
      • padding-top: 10px;
      • padding-right: 15px;
      • padding-bottom: 10px;
      • padding-left: 15px;
      • Shorthand:padding: 10px 15px; (top dan bottom 10px, left dan right 15px)
    • Uniform Padding
      • padding: 20px; (applies 20px padding to top, right, bottom, and left)
    
    /* Individual paddings */
    .element {
        padding-top: 10px;
        padding-right: 15px;
        padding-bottom: 10px;
        padding-left: 15px;
    }
    
    /* Shorthand padding */
    .element {
        padding: 10px 15px; /* top & bottom 10px, right & left 15px */
    }
    
    /* Uniform padding */
    .element {
        padding: 20px; /* 20px padding on all sides */
    }
    
    Contoh Lengkapnya sebagai berikut:
    
    <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Contoh Padding</title>
          <style>
              .box {
                  width: 100px;
                  height: 100px;
                  background-color: lightblue;
                  padding: 20px;
                  border: 2px solid black;
              }
        </style>
      </head>
      <body>
        <div class="box">Content</div>
      </body>
      </html>
    
  • Border: Merupakan ruang area sekitar padding dan konten.
    Dalam CSS, property border digunakan untuk mendefiniskan batas suatu elemen. Digunakan untuk menambahkan garis, atau suatu frame di sekeliling padding dan content.
    Border meningkatkan pandangan secara visual dari elemen elemen dengan memisahkannya dengan elemen lainnya seperti mendefinisikan tepi, atau aspek dekorasi lainnya.
    • Berikut adalah beberapa poin kunci mengenai border property:
      • Border Properties:
        • border-width: Mendefinisikan ketebalan border (mis, 2px, 0.5em, thin, medium, thick).
        • border-style Mendefinisikan style border (mis, solid, dotted, dashed, double, groove, ridge, inset, outset, none, hidden).
        • border-color Mendefinisikan warna border (mis, #000, blue, rgba(0, 0, 0, 0.5)).
      • Shorthand Property:
        Kita bisa menggunakan properti border untuk menset semua properti sekaligus dengan
        
        border: 2px solid black;
                                  
      • Sisi sisi individu:
        Kita dapat menset border border secara sisi individual elemen dengan menggunakan properti properti yang spesifik
        • border-top: Menset border pada sisi atas.
        • border-right: Menset border pada sisi kanan.
        • border-bottom: Menset border pada sisi bawah.
        • border-left: Menset border pada sisi kiri.
      • Border Radius:
        properti border-radius memungkinkan kita untuk membuat sudut yang bulat, misal pada code berikut.
        
        border-radius: 10px;
                                  
    Berikut adalah contoh penggunaan kode css tersebut
    
    /* Basic border */
    .element {
        border: 2px solid black;
    }
    
    /* Individual border properties */
    .element {
        border-width: 2px;
        border-style: solid;
        border-color: black;
    }
    
    /* Different borders on each side */
    .element {
        border-top: 2px solid red;
        border-right: 3px dashed green;
        border-bottom: 4px double blue;
        border-left: 5px groove purple;
    }
    
    /* Rounded corners */
    .element {
        border: 2px solid black;
        border-radius: 10px;
    }
                      
    Contoh Lengkapnya sebagai berikut:
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Border Example/<title>
        <style>
          .box {
                width: 100px;
                height: 100px;
                background-color: lightblue;
                border: 2px solid black;
                border-radius: 10px;
            }
        </style>
      </head>
      <body>
        <div class="box"></div>
      </body>
    </html>
                      
  • Margin: Memberikan ruang area di luar border.
  • Dalam CSS, property margin digunakan untuk menciptakan ruang di sekeliling elemen elemen, diluar border.
    Berikut adalah beberapa poin kunci tentang properti margin:
    • Spacing Elements:
      Margin yang menciptakan ruang antara elemen elemen. Sebagai contoh, jika ada dua paragraf, dapat digunakan margin untuk memastikan bahwa ada ruang diantaranya
    • Setting Margins:
      Sama seperti pada padding, margin dapat diset dari 4 sisi elemen (top, right, bottom, left) secara terpisah, atau juga bisa digunakan shorthand properties.
      • margin-top: 10px;
      • margin-right: 15px;
      • margin-bottom: 10px;
      • margin-left: 15px;
      • Shorthand: margin: 10px 15px;(top dan bottom 10px, left dan right 15px)
    • Auto Margins:
      margin: auto;, seringkali digunakan untuk memusatkan elemen-elemen pada level block secara horizontal. dalam container, asalkan container didefinisikan lebarnya.
    • Negative Margins:
      Nilai negatif dapat digunakan pada margin untuk menarik elemen untuk saling mendekati atau membuatnya overlap.
    Berikut adalah contoh penggunaan kode css tersebut
    
    /* Individual margins */
    .element {
      margin-top: 20px;
      margin-right: 30px;
      margin-bottom: 20px;
      margin-left: 30px;
    }
                        
    /* Shorthand margin */
    .element {
      margin: 20px 30px; /* top & bottom 20px, right & left 30px */
    }
                        
    /* Centering a block element horizontally */
    .container {
      width: 800px;
      margin: 0 auto; /* 0 for top & bottom, auto for left & right */
    }
                      
    Contoh Lengkapnya sebagai berikut:
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Margin Example</title>
        <style>
          .box {
            width: 100px;
            height: 100px;
            background-color: lightblue;
            margin: 20px;
          }
        </style>
      </head>
      <body>
        <div class="box"></div>
        <div class="box"></div>
      </body>
      </html>
                      

Display dan Positioning

Display property menspesifikasikan sifat display dari suatu elemen.

  • Display Property:
    • block: Elemen yang ditampilkan sebagai block mis, <div>
    • inline: Elemen yang ditampilkan sebagai inline mis, <span>
    • inline-block: Mengkombinasikan fitur block dan inline
    • none: Menyembunyikan elemen elemen
  • Position Property:
    • static: Posisi Default
    • relative: Posisi relatif terhadap posisi normal.
    • absolute: Posisi relatif terdekat dengan posisi elemen terdekat.
    • fixed: Posisi relatif terhadap viewport
  • Berikut adalah contoh penggunaan kode css tersebut
    
    .relative-box {
      position: relative;
      left: 20px;
      top: 10px;
    }
    
    .absolute-box {
      position: absolute;
      right: 10px;
      bottom: 5px;
    }
                      

Berikut contoh Lengkapnya
            
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contoh Display dan Position </title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <div class="container">
      <header class="header">Header (Block Element)</header>
      <nav class="navbar">Navigation (Block Element)</nav>
      <main class="content">
        <div class="sidebar">Sidebar (Absolute Position)</div>
        <div class="main-content">Main Content (Relative Position)</div>
      </main>
      <footer class="footer">Footer (Fixed Position)</footer>
    </div>
  </body>
</html>

            
          

3. Implementasi Flex Layout

Desain layout berperan penting dalam proses pembuatan Dashboard. Dalam dunia desain modern, ada dua kategori yang paling sering digunakan yaitu pendekatan dengan flex dan grid.

  • Flexbox
    • Merupakan 1 dimensi model layout yang memungkinkan kita dalam mengatur distribusi ruang dan penjajaran antara objek yang berada dalam container, bahkan ketika kita tidak mengetahui ukurannya, atau dikenal dengan pengaturan ruang secara dinamis
  • Grid Layout
    • Merupakan desain dua dimensional yang memungkinkan kita mengontrol desain dari sisi kolom dan baris.
    • Untuk desain yang kompleks
    • Cocok untuk desain skala yang besar
  • Desain Flexbox
  • Akan lebih praktis, apabila kita sertakan dengan menggunakan contoh. Berikut adalah contoh menggunakan flex layout Berikut adalah langkah langkah dalam implementasi flex layout

    1. Berikut adalah contoh implementasi dashboard menggunakan flex design

    2. 
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Dashboard Grid Layout</title>
          <link rel="stylesheet" href="style.css">
        </head>
                                      
        <body>
        <div class="container">
          <div class="box">1 </div>
          <div class="box">2 </div>
          <div class="box">3 </div>
        </div>
        </body>
      </html>
                      
    3. Stylingnya adalah sebagai berikut
    4. 
      .container {
        display: flex; /* Gunakan Flexbox */
      }
                      
      .box {
        flex: 1; /* flex-grow sama untuk semua kotak */
        background-color: #f0f0f0;
        border: 1px solid #ccc;
        padding: 20px;
        margin: 10px;
        text-align: center;
      }
                      
      @media (max-width: 768px) {
        .container {
          /* Untuk layar mobile maka objek akan tersusun seceara vertikal */
          flex-direction: column; 
        }
      }
                      
  • Desain Dashboard Sederhana

Implementasi Grid Layout

Langkah langkah

  • Buat folder project baru.
  • Dalam folder tersebut, buat index.html dan style.css.
  • Link style.css ke index.html.

Berikut adalah source code nya:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard Grid Layout</title>
    <link rel="stylesheet" href="style.css">
  </head>
              
  <body>
    <div class="container">
      <!-- Disini akan diisi dengan konten dashboard -->
    </div>
  </body>
</html>
              

Struktur Dasar HTML

Struktur HTML untuk layout Dashboard

  • Definisikan bagian dasar seperti: header, sidebar, main content, dan footer.
  • Tambahkan konten placeholder.

<!-- index.html (dalam .container div) -->
<header class="header">Header</header>
<aside class="sidebar">Sidebar</aside>
<main class="main-content">Main Content</main>
<footer class="footer">Footer</footer>
            


Setup CSS Dasar

Diperlukan untuk styling dasar layout.

Langkah langkahnya adalah sebagai berikut

  • Reset default browser styles dengan cara menset marginnya 0 dan font-family: Arial, sans-serif
  • Definisikan styles dasar untuk body dan kontainer
  • Hasil akhir yang hendak kita capai adalah:

    ini dimungkinkan dengan menggunakan css sebagai berikut:

    
      /* style.css */
      body {
        margin: 0;
        font-family: Arial, sans-serif;
      }
                    
      .container {
        display: grid;
        grid-template-areas:
          'header header header'
          'sidebar main-content main-content'
          'footer footer footer';
        grid-template-rows: 60px 1fr 40px;
        grid-template-columns: 200px 1fr;
        height: 100vh;
      }
                    
      .header {
        grid-area: header;
        background: #333;
        color: white;
        text-align: center;
        line-height: 60px;
      }
                    
      .sidebar {
        grid-area: sidebar;
        background: #444;
        color: white;
        padding: 20px;
      }
                    
      .main-content {
        grid-area: main-content;
        padding: 20px;
      }
                    
      .footer {
        grid-area: footer;
        background: #333;
        color: white;
        text-align: center;
        line-height: 40px;
      }
    


    Penjelasan Kode CSS

    Properti grid-template-areas dalam CSS Grid Layout digunakan untuk mendefinisikan area grid yang diberi nama di dalam sebuah kontainer grid.

    Properti ini menyediakan cara visual dan intuitif untuk menyusun elemen dengan memberikan nama pada berbagai bagian grid, yang kemudian dapat dirujuk dalam CSS untuk menentukan posisi elemen anak.

    
      .container {
        display: grid;
        grid-template-areas:
          'header header header'
          'sidebar main-content main-content'
          'footer footer footer';
        ...
    }
    
    Penjelasan

    Kode diatas mendefinisikan struktur tata letak grid dengan tiga baris dan tiga kolom. Setiap string dalam properti grid-template-areas mewakili satu baris dalam grid, dan setiap kata mewakili satu sel dalam baris tersebut. Sel-sel yang memiliki nama yang sama digabungkan menjadi satu area.
    Berikut uraian:

    1. Baris Pertama: 'header header header'
      • Baris ini terdiri dari tiga kolom.
      • Ketiga kolom tersebut diberi nama area header.
      • Artinya area header ini mempunyai tiga kolom pada baris pertama.
    2. Baris Kedua: 'sidebar main-content main-content'
      • Baris ini juga terdiri dari tiga kolom.
      • Kolom pertama dinamakan area sidebar.
      • Kolom kedua dan ketiga sama-sama diberi nama area main-content. Artinya area main-content ini mempunyai dua kolom pada baris kedua.
    3. Baris Ketiga: 'footer footer footer'
      • Baris ini, seperti baris pertama yang juga terdiri dari tiga kolom.
      • Semua tiga kolumn dinamakan footer.

grid-template-rows: 60px 1fr 40px;
            

Representasi dalam bentuk diagram bisa dilihat pada gambar berikut:

Kemudian baris code selanjutnya


grid-template-columns: 200px 1fr;
            

menjelaskan bahwa

  1. 200px: adalah ukuran dari lebar kolom pertama sebesar 200px, dalam hal ini merupakan lebar sidebar
  2. 1fr: adalah ukuran fleksibel dari kolom sisa, dalam hal ini adalah main content

Representasi dalam bentuk diagram bisa dilihat pada gambar berikut:

Selanjutnya baris code:

 
.header {
  grid-area: header;
  ...
}

menjelaskan bahwa properti grid-area dalam CSS Grid Layout digunakan dalam penempatan item grid ke area grid tertentu yang telah ditentukan dalam properti grid-template-areas dari grid.
Ini membantu dalam memposisikan elemen-elemen di dalam tata letak grid berdasarkan nama-nama yang telah Anda tentukan.

  • .header: Ini merupakan CSS selector yang menargetkan sebuah elemen header kelas.
  • grid-area: header;: Ini menentukan elemen .header ke dalam grid area yang bernama header.
Hal ini juga berlaku untuk grid area lainnya seperti, sidebar, main-content dan footer

Setup CSS Lanjut

Disini kita akan membuat layout dengan properties grid tambahan dan desain responsif.

Berikut langkah langkahnya

  • Tambahkan bagian bagian lainnya pada (mis, widgets, stats).
  • Gunakan grid-template-areas untuk menddefinisikan suatu layout yang lebih kompleks layout.
  • Pengimplementasian desain responsf dengan menggunakan media queries.
  •                 
    <!-- index.html (di dalam .container div) -->
    <header class="header">Header</header>
    <aside class="sidebar">Sidebar</aside>
    <section class="stats">Stats</section>
    <section class="widgets">Widgets</section>
    <main class="main-content">Main Content</main>
    <footer class="footer">Footer</footer>
                  
                

    Berikut juga css

    
    /* style.css */
    .container {
        display: grid;
        grid-template-areas:
            'header header header'
            'sidebar stats widgets'
            'sidebar main-content main-content'
            'footer footer footer';
        grid-template-rows: 60px auto 1fr 40px;
        grid-template-columns: 200px 1fr 1fr;
        height: 100vh;
    }
    
    .stats {
        grid-area: stats;
        background: #555;
        color: white;
        padding: 20px;
    }
    
    .widgets {
        grid-area: widgets;
        background: #666;
        color: white;
        padding: 20px;
    }
    
    @media (max-width: 768px) {
        .container {
            grid-template-areas:
                'header'
                'sidebar'
                'stats'
                'widgets'
                'main-content'
                'footer';
            grid-template-rows: 60px auto auto auto 1fr 40px;
            grid-template-columns: 1fr;
        }
    }
    
    

Latihan: Implementasikan area lainnya seperti charts/graphs, KPI, dst

Pengenalan JavaScript

  • Apa itu JavaScript?
    High-level programming language yang utamanya digunakan untuk meningkatan interactifitas dan fungsionalitas suatu website. JavaScript merupakan teknologi inti pada web, sejajar dengan HTML dand CSS. JavaScript memungkinkan konten menjadi dinamis seperti form interactif form, animasi, dan fitur client-side lainnya.

  • Cara Menjalankan Program JavaScript

    • Browser Console
      • Chrome: Klik Kanan > Inspect > Console
      • Firefox: Klik Kanan > Inspect Element > Console
      Jalankan kode berikut
      
      console.log("Hello, World!");
                            
    • File HTML
      • Buat file index.html
      • Tambahkan Kode
        
        <!DOCTYPE html>
        <html>
          <body>
            <script>
              console.log("Hello, World!");
              alert("Hello, World!");
            </script>
          </body>
        </html>
                                  
      • Buka dengan klik kanan pada VSCode

Variabel dan Tipe Data

  • Variabel
    Deklarasi variabel menggunakan kata kunci var, let dan const
    • var: scope nya adalah dalam block fungsi, dapat dideklarasi/diassign ulang
      
        var x = 10;
        x = 20;
                          
    • let: scope nya adalah dalam block {}, dapat diassign ulang
      
        let y = 10;
        y = 20;
                          
    • const: scope nya adalah dalam block {}, tidak dapat dideklarasi/diassign ulang
      
        const z = 10;
        // z = 20; // Error
                          
  • Tipe Data
    • Numbers adalah nilai numerik.
    • Strings adalah nilai teks dalam tanda kutip.
    • Booleans bernilai true atau false.
    • Null adalah ketidak adaan nilai.
    • Undefined adalah dideklarasi tapi tidak diassign.
            
let nama = "Alia";
const umur = 30;
var isStudent = false;

console.log(nama); // Output: Alia
console.log(umur); // Output: 30
console.log(isStudent); // Output: false

            
          

Operator Dasar

Konsep dasar

  • Operator Aritmatik (+, -, *, /, %)
  • Operator Assignment (=, +=, -=, dst.)
              
let x = 10;
let y = 5;

console.log(x + y); // Output: 15
console.log(x - y); // Output: 5
console.log(x * y); // Output: 50
console.log(x / y); // Output: 2
console.log(x % y); // Output: 0

              
            

Fungsi

Konsep dasar

  • Pendefinisian Fungsi
  • parameter fungsi dan nilai balik

function katakan(nama) {
  return "Hello, " + nama + "!";
}
console.log(katakan("Alia")); // Output: Hello, Alia!
            
            

Kondisi

Konsep Dasar

  • Kondisi: if, else if, else
  • Operator perbandingan (==, ===, !=, !==, >, <,>=, <=)

let suhu = 20;

if (suhu > 30) {
    console.log("Panas!");
} else if (suhu > 20) {
    console.log("Hangat.");
} else {
    console.log("Dingin.");
}

            

Looping

Konsep Dasar

  • for loop
  • while loop

for (let i = 0; i < 5; i++) {
  console.log("Iteration " + i);
}
            
let hitung = 0;
while (hitung < 5) {
  console.log("Hitung " + hitung);
  hitung++;
}
            
            

Arrays

Konsep Dasar

  • Pendeklerasian array
  • Cara mengakses elemen pada array
  • Fungsi fungsi pada array (push, pop, shift, unshift)

let buah2an = ["Apel", "Pisang", "Ceri"];
console.log(buah2an[0]); // Output: Apel

buah2an.push("Kurma");
console.log(buah2an); // Output: ["Apel", "Pisang", "Ceri", "Kurma"]

buah2an.pop();
console.log(buah2an); // Output: ["Apel", "Pisang", "Ceri"]

            

Objects

Konsep Dasar

  • Pendeklerasian object
  • Cara mengakses properti pada object
  • Fungsi fungsi pada object

              let person = {
                name: "Alice",
                age: 30,
                greet: function() {
                    return "Hello, " + this.name;
                }
            };
            
            console.log(person.name); // Output: Alice
            console.log(person.greet()); // Output: Hello, Alice
            
            

Manipulasi DOM

Konsep Dasar

  • Penyeleksian elemen
  • Pengubahan content dan styles
  • 
    <!DOCTYPE html>
    <html>
      <body>
        <h1 id="title">Hello</h1>
        <button onclick="changeText()">Click me</button>
    
        <script>
            function changeText() {
                document.getElementById("title").innerText = "Hello, JavaScript!";
        }
        </script>
      </body>
    </html>
    
                  

Events

Konsep Dasar

  • Event listeners
  • Event even lain yang umum (click, mouseover, etc.)
  • 
    <!DOCTYPE html>
    <html>
      <body>
        <button id="tombolSaya">Click me</button>
    
        <script>
            document.getElementById("tombolSaya").addEventListener("click", function() {
                alert("Tombol telah diklik!");
            });
        </script>
      </body>
    </html>
    
                

JSON dan Fetch API

Konsep Dasar

  • JSON format
  • Fetching data dari suatu API
Berikut adalah contoh ril dari hal ini

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contoh Fetch API</title>
    <style>
      body {
          font-family: Arial, sans-serif;
          margin: 0;
          padding: 0;
          background-color: #f8f9fa;
      }
      #output {
          max-width: 800px;
          margin: 20px auto;
          padding: 20px;
          background-color: #fff;
          border-radius: 8px;
          box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      }
      .post {
          margin-bottom: 20px;
          padding: 15px;
          border-bottom: 1px solid #ddd;
      }
      .post:last-child {
          border-bottom: none;
      }
      .post h3 {
          margin: 0 0 10px 0;
          font-size: 1.2em;
          color: #333;
      }
      .post p {
          margin: 0;
          line-height: 1.5;
          color: #666;
      }
      </style>
    <script src="api.js" defer></script>
  </head>
  <body>
    <div id="output"></div>
  </body>
</html>

            

JavaScriptnya adalah sebagai berikut


document.addEventListener('DOMContentLoaded', () => {
  const output = document.getElementById('output');
  fetch('https://jsonplaceholder.typicode.com/posts')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  }).then(data => {
    // Display the data
    displayData(data);
  }).catch(error => {
    console.error('There was a problem fetching the data:', error);
    output.textContent = 'There was a problem fetching the data. Please try again later.';
  });
            
  function displayData(data) {
    output.innerHTML = '

Posts

'; data.forEach(post => { const postElement = document.createElement('div'); postElement.classList.add('post'); postElement.innerHTML = `

${post.title}

${post.body}

`; output.appendChild(postElement); }); } });

Dan hasilnya bisa dilihat pada gambar dibawah ini

Fitur ES6

Konsep Dasar

  • Arrow functions
  • Template literals
  • Destructuring

const add = (a, b) => a + b;
console.log(add(5, 3)); // Output: 8

let user = {name: "Alice", age: 30};
let {name, age} = user;
console.log(`Name: ${name}, Age: ${age}`); // Output: Name: Alice, Age: 30

            
Berikut adalah contoh lengkapnya

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contoh Fitur ES6</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .feature {
            margin-bottom: 20px;
        }
        .feature h2 {
            margin-bottom: 10px;
        }
        .output {
            background-color: #f0f0f0;
            padding: 10px;
            border-radius: 5px;
        }
    </style>
    <script defer src="script.js"></script>
  </head>
  <body>
    <div class="feature">
      <h2>Arrow Functions</h2>
      <div id="arrow-functions" class="output"></div>
    </div>
    <div class="feature">
      <h2>Template Literals</h2>
      <div id="template-literals" class="output"></div>
    </div>
        
    
    <div class="feature">
      <h2>Destructuring</h2>
      <div id="destructuring" class="output"></div>
    </div>
  </body>
</html>

Berikut script.jsnya adalah
  
    document.addEventListener('DOMContentLoaded', () => {
      // Arrow Functions
      const contohArrowFunctions = () => {
          return [1, 2, 3, 4, 5].map(num => num * 2);
      };
      document.getElementById('arrow-functions').textContent = `${contohArrowFunctions().join(', ')}`;
  
      // Template Literals
      const contohTemplateLiterals = () => {
          const nama = 'Alia';
          const umur = 30;
          return `Nama saya adalah ${nama} dan Umurku ${umur} tahun.`;
      };
      document.getElementById('template-literals').textContent = `${contohTemplateLiterals()}`;
  
      // Destructuring
      const contohDestructuring = () => {
          const user = { nama: 'Bob', umur: 25 };
          const { nama, umur } = user;
          return `Nama: ${nama}, Umur: ${umur}`;
      };
      document.getElementById('destructuring').textContent = `${contohDestructuring()}`;
  });
  
  

Pengenalan D3.js

Konsep Dasar

  • Apa itu D3.js

    D3.js (Data-Driven Documents) adalah JavaScript library digunakan untuk membuat visualisasi data menjadi interaktif dan dinamis pada browser dengan menggunakan SVG, HTML, dan CSS.

  • Alasan menggunakan D3.js:
    • Fleksibel dan kapabilitas manipulasi data yang mumpuni
    • Tersedia berbagai ragam jenis visualisasi(charts, graphs, maps, dll.)
  • Ada berbagai cara dalam menggunakan d3js, yaitu
    1. Memasukkan d3.js melalui cdn

      Ini merupakan cara termudah untuk menggunakan D3.js dalam web project

      • Tambahkan script tag berikut pada <head> atau <body> pada file HTML
                            
      <!DOCTYPE html>
      <html>
      <head>
        <title>D3.js Example</title>
        <script src="https://d3js.org/d3.v7.min.js"></script>
        </head>
        <body>
          <!-- Konten ada disini -->
          <script>
          // Kode D3.js ada disini
          </script>
        </body>
      </html>
                            
                          
    2. Menggunakan npm dalam penginstalan D3.js

      Jika menggunakan Node.js dan suatu package manager seperti npm, maka D3.js dapat diinstal secara lokal maka ikuti langkah seperti

      • Inisialisasi project Node.js yang baru dengan:
        npm init -y
      • Instalasi D3.js dengan menggunakan npm:
        npm i d3
      • Import dan gunakan D3.js pada file JavaScript:
                                  
        // sample.js
        import * as d3 from 'd3';
        // Kode D3.js disini
                                  
                                

Elemen SVG dasar

Kita akan membuat elemen dasar svg menggunakan D3.js.

  1. Setting up File HTML

    Buat suatu file index.html file konten berikut. Dimana ini akan memberikan suatu halaman HTML dan menyertakan library D3.js.

                        
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Elemen SVG Dasar dengan D3.js</title>
        <script src="https://d3js.org/d3.v6.min.js"></script>
      </head>
      <body>
        <script>
          // kode D3.js disini 
        </script>
      </body>
    </html>
                        
                      
  2. Buat Kanvas SVG

    Di dalam tag <script>,elemen SVG dibuat. Ini akan menjadi kanvas semua bentuk akan digambar.

    
    
                      
  3. Tambahkan Bentuk Dasar

    Sekarang, tambahkan beberapa bentuk dasar seperti persegi panjang, lingkaran, dan garis ke kanvas SVG.

    
    
                      
    Berikut adalah file lengkap `index.html` dengan kode D3.js untuk membuat dan menambahkan elemen SVG dasar.
                      
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SVG Elemen Dasar dengan D3.js</title>
        <script src="https://d3js.org/d3.v6.min.js"></script>
        </head>
        <body>
          <script>
            // Set the dimensions of the SVG canvas
            var width = 500;
            var height = 500;
    
            // Create the SVG element and set its dimensions
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", width)
                        .attr("height", height);
    
            // Append a rectangle
            svg.append("rect")
               .attr("x", 50)
               .attr("y", 50)
               .attr("width", 100)
               .attr("height", 50)
               .attr("fill", "blue");
    
            // Append a circle
            svg.append("circle")
               .attr("cx", 200)
               .attr("cy", 75)
               .attr("r", 50)
               .attr("fill", "green");
    
            // Append a line
            svg.append("line")
               .attr("x1", 300)
               .attr("y1", 50)
               .attr("x2", 400)
               .attr("y2", 100)
               .attr("stroke", "black")
               .attr("stroke-width", 2);
          </script>
        </body>
      </html>
                      
                    

SVG Elemen Binding Data

Dasar dasar data binding

  1. Buat suatu dataset:
                        
    <script>
      const data = [10, 20, 30, 40, 50];
    </script>
                        
                      
  2. Binding data pada lingkaran
    • Update script untuk binding data:
                          
      <script>
        svg.selectAll("circle")
          .data(data)
          .enter()
          .append("circle")
          .attr("cx", (d, i) => i * 60 + 50)
          .attr("cy", 100)
          .attr("r", d => d)
          .attr("fill", "purple");
      </script>
                          
                        
    • Lengkapnya adalah
                        
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Binding Data pada Elemen SVG dengan D3.js</title>
          <script src="https://d3js.org/d3.v6.min.js"></script>
          <style>
            .bar {
              fill: steelblue;
            }
            .bar:hover {
              fill: orange;
            }
          </style>
        </head>
        <body>
          <script>
              // Data array
              var data = [30, 86, 168, 281, 303, 365];
      
              // Set dimensi pada kanvas SVG
              var width = 500;
              var height = 500;
              var barWidth = 40;
              var barPadding = 5;
      
              // Buat elemen SVG dan set dimensinya
              var svg = d3.select("body")
                          .append("svg")
                          .attr("width", width)
                          .attr("height", height);
      
              // Bind data pada elemen SVG
              svg.selectAll("rect")
                 .data(data)
                 .enter()
                 .append("rect")
                 .attr("class", "bar")
                 .attr("x", (d, i) => i * (barWidth + barPadding))
                 .attr("y", d => height - d)
                 .attr("width", barWidth)
                 .attr("height", d => d);
            </script>
          </body>
        </html>
                        
                      

Skala dan Sumbu

Disini kita akan mencoba memahami skala dan sumbu untuk mappng nilai data menjadi visual

  1. Buat skala:
    • Tambahkan fungsi skala
                            
      <script>
        const xScale = d3.scaleLinear()
          .domain([0, d3.max(data)])
          .range([0, 500]);
      
        const yScale = d3.scaleLinear()
          .domain([0, d3.max(data)])
          .range([500, 0]);
      </script>
                            
                          
  2. Menggunakan skala dengen elemen SVG:
    • Bind data pada lingkaran menggunakan skala
      
      <script>
        svg.selectAll("circle")
          .data(data)
          .enter()
          .append("circle")
          .attr("cx", d => xScale(d))
          .attr("cy", d => yScale(d))
          .attr("r", 10)
          .attr("fill", "orange");
      </script>
                        
  3. Penambahan sumbu:
    • Tambahkan sumbu X dan Y:
                            
      <script>
        const xAxis = d3.axisBottom(xScale);
        const yAxis = d3.axisLeft(yScale);
                          
        svg.append("g")
          .attr("transform", "translate(0,500)")
          .call(xAxis);
                          
        svg.append("g")
          .attr("transform", "translate(0,0)")
          .call(yAxis);
      </script>
                          
  4. Berikut contoh lengkap
                    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Menggunakan Skala dengan D3.js</title>
        <script src="https://d3js.org/d3.v6.min.js"></script>
        <style>
            .bar {
                fill: steelblue;
            }
            .bar:hover {
                fill: orange;
            }
            .axis-label {
                font-size: 14px;
            }
        </style>
      </head>
      <body>
        <script>
            // Data array
            var data = [30, 86, 168, 281, 303, 365];
    
            // Set dimensi kanvas SVG
            var width = 500;
            var height = 500;
            var margin = {top: 20, right: 20, bottom: 30, left: 40};
    
            // Buat elemen SVG dan set dimensinya
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .append("g")
                        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
            // Set up skala
            var xScale = d3.scaleBand()
                           .domain(data.map((d, i) => i))
                           .range([0, width])
                           .padding(0.1);
    
            var yScale = d3.scaleLinear()
                           .domain([0, d3.max(data)])
                           .range([height, 0]);
    
            // Tambahkan sumbu
            svg.append("g")
               .attr("class", "x-axis")
               .attr("transform", "translate(0," + height + ")")
               .call(d3.axisBottom(xScale).tickFormat(i => i + 1));
    
            svg.append("g")
               .attr("class", "y-axis")
               .call(d3.axisLeft(yScale));
    
            // Bind data pada elemen SVG  dan buat bar/batang
            svg.selectAll(".bar")
               .data(data)
               .enter()
               .append("rect")
               .attr("class", "bar")
               .attr("x", (d, i) => xScale(i))
               .attr("y", d => yScale(d))
               .attr("width", xScale.bandwidth())
               .attr("height", d => height - yScale(d));
        </script>
      </body>
    </html>
                    
                  

Contoh Line Chart Sederhana

Disini kita akan mencoba memahami cara memvisualisasi data ke dalam line chart

  1. Set up File HTML
                      
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Line Chart dengan label sumbu menggunakan D3.js</title>
        <script src="https://d3js.org/d3.v6.min.js"></script>
        <style>
            .line {
                fill: none;
                stroke: steelblue;
                stroke-width: 2px;
            }
            .axis-label {
                font-size: 14px;
            }
        </style>
        </head>
        <body>
        <script>
            // Kode D3.js disini
        </script>
      </body>
    </html>
                      
                    
  2. Definiskan Data

    Kita mendefinisikan data di dalam tag <script>. Untuk contoh ini kita akan menggunakan suatu array dari objek dimana setiap objek akan merepresentasikan suatu titik x (Tahun) dan y nilai (Harga).

                        
    
                        
                      

  3. Set up Skala dan sumbu

    Definisikan skala dan sumbu pada map dari nilai data menjadi nilai pixel, dan tambahkan label sumbu.

    
    
                    
  4. Definisikan Line Generator dan buat Line

    Gunakan D3 line generator untuk membuat path data untuk line dan sematkannya pada SVG, tambahkan kode berikut:

                    
    
                    
                  

    Hasil gambar akhir akan seperti gambar dibawah ini

    Berikut ini adalah kode lengkap dalam file index.html dengan kode D3.js untuk membuat suatu line chart dengan label sumbu:

                    
    <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Line Chart dengan Label sumbu D3.js</title>
          <script src="https://d3js.org/d3.v6.min.js"></script>
          <style>
            .line {
                fill: none;
                stroke: steelblue;
                stroke-width: 2px;
            }
            .axis-label {
                font-size: 14px;
            }
          </style>
        </head>
        
        <body>
          <script>
          // Data array
          var data = [
            { x: 0, y: 30 },
            { x: 1, y: 86 },
            { x: 2, y: 168 },
            { x: 3, y: 281 },
            { x: 4, y: 303 },
            { x: 5, y: 365 },
            { x: 6, y: 400 }
          ];
    
          // Set dimensi untuk kanvas SVG
          var width = 500;
          var height = 300;
          var margin = { top: 40, right: 20, bottom: 50, left: 50 };
    
          // Buat elemen SVG dan set dimensinya
          var svg = d3.select("body")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
          // Set up skala
          var xScale = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.x)])
            .range([0, width]);
    
          // Flip the y-axis  
          var yScale = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.y)])
            .range([0, height]); 
    
          // Tambahkan sumbu
          svg.append("g")
            .attr("transform", "translate(0,0)") // Pindahkan x-axis ke atas
            .call(d3.axisTop(xScale)); // Gunakan axisTop 
          svg.append("g")
            .call(d3.axisLeft(yScale));
    
          // Tambahkan label sumbu
          svg.append("text")
            .attr("class", "axis-label")
            .attr("transform", "translate(" + (width / 2) + " ," + (-margin.top / 2) + ")")
            .style("text-anchor", "middle")
            .text("Days");
    
          svg.append("text")
            .attr("class", "axis-label")
            .attr("transform", "rotate(-90)")
            .attr("y", 0 - margin.left)
            .attr("x", 0 - (height / 2))
            .attr("dy", "1em")
            .style("text-anchor", "middle")
            .text("Depth (m)");
    
          // Definisikan line
          var line = d3.line()
            .x(d => xScale(d.x))
            .y(d => yScale(d.y));
    
          // Tambahkan line pada SVG
          svg.append("path")
            .datum(data)
            .attr("class", "line")
            .attr("d", line);
        </script>
      </body>
    </html>
    
                      
                    
                  

Contoh penggunaan D3 js

Disini kita akan menjalankan sample dari website d3.js

              
<!DOCTYPE html>
  <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Contoh D3.js Bar Chart</title>
    <style>
      .chart {
        margin-top: 20px;
      }
    </style>
    <script src="https://d3js.org/d3.v6.min.js"></script>
  </head>
  
  <body>
    <button onclick="chart.update((a, b) => b.depth - a.depth)">Sorting Kedalaman Sumur</button>
    <button onclick="chart.update((a, b) => d3.ascending(a.letter, b.letter))">Sorting Nama</button>
    <div class="chart"></div>

    <script>
      const data = [
        {letter: "A", depth: 23},
        {letter: "B", depth: 44},
        {letter: "C", depth: 54},
        {letter: "D", depth: 12},
        {letter: "E", depth: 33},
        {letter: "F", depth: 67},
        {letter: "G", depth: 39},
        {letter: "H", depth: 18},
        {letter: "I", depth: 26},
        {letter: "J", depth: 10},
        {letter: "K", depth: 22},
        {letter: "L", depth: 44},
        {letter: "M", depth: 77},
        {letter: "N", depth: 35},
        {letter: "O", depth: 48},
        {letter: "P", depth: 66},
        {letter: "Q", depth: 11},
        {letter: "R", depth: 51},
        {letter: "S", depth: 99},
        {letter: "T", depth: 23},
        {letter: "U", depth: 47},
        {letter: "V", depth: 73},
        {letter: "W", depth: 31},
        {letter: "X", depth: 55},
        {letter: "Y", depth: 88},
        {letter: "Z", depth: 17}
      ];

      const chart = (function() {
        const width = 640;
        const height = 400;
        const marginTop = 20;
        const marginRight = 0;
        const marginBottom = 30;
        const marginLeft = 40;
        
        const x = d3.scaleBand()
          .domain(data.map(d => d.letter))
          .range([marginLeft, width - marginRight])
          .padding(0.1);

        const xAxis = d3.axisBottom(x).tickSizeOuter(0);

        const y = d3.scaleLinear()
          .domain([0, d3.max(data, d => d.depth)]).nice()
          .range([height - marginBottom, marginTop]);

        const svg = d3.create("svg")
            .attr("viewBox", [0, 0, width, height])
            .attr("style", `max-width: ${width}px; height: auto; font: 10px sans-serif; overflow: visible;`);

        const bar = svg.append("g")
            .attr("fill", "steelblue")
          .selectAll("rect")
          .data(data)
          .join("rect")
            .style("mix-blend-mode", "multiply")
            .attr("x", d => x(d.letter))
            .attr("y", d => y(d.depth))
            .attr("height", d => y(0) - y(d.depth))
            .attr("width", x.bandwidth());

        const gx = svg.append("g")
            .attr("transform", `translate(0,${height - marginBottom})`)
            .call(xAxis);
        
        const gy = svg.append("g")
            .attr("transform", `translate(${marginLeft},0)`)
            .call(d3.axisLeft(y))
            .call(g => g.select(".domain").remove());

        return Object.assign(svg.node(), {
          update(order) {
            x.domain(data.sort(order).map(d => d.letter));

            const t = svg.transition()
                .duration(750);

            bar.data(data, d => d.letter)
                .order()
              .transition(t)
                .delay((d, i) => i * 20)
                .attr("x", d => x(d.letter));

            gx.transition(t)
                .call(xAxis)
              .selectAll(".tick")
                .delay((d, i) => i * 20);
          }
        });
      })();

    document.querySelector('.chart').appendChild(chart);
    </script>
  </body>
</html>
              
            

Pengenalan NodeJS dan ExpressJS

  • Apa itu NodeJS
  • Node.js adalah runtime environment yang memungkinkan kita menjalankan JavaScript di server. Node.js menggunakan model I/O yang berorientasi pada event dan non-blocking, yang membuatnya efisien dan scalable.

  • Apa itu ExpressJS
  • Express.js adalah framework web untuk Node.js yang menyederhanakan pembuatan aplikasi web dan API. Express.js menyediakan berbagai fitur untuk membangun aplikasi yang robust/kuat.

  • Instalasi Node.js dan Express.js
  • Instal Node.js dari situs resmi dan cek instalasi dengan menggunakan perintah:

    
    node -v
    npm -v
    
    

    Buat suatu direktori untuk sampel project:

    
    mkdir myapp
    cd myapp
    npm init -y
    npm install express
    
    
Disini kita akan menjalankan sample dari website d3.js

              
<!DOCTYPE html>
  <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Contoh D3.js Bar Chart</title>
    <style>
      .chart {
        margin-top: 20px;
      }
    </style>
    <script src="https://d3js.org/d3.v6.min.js"></script>
  </head>
  
  <body>
    <button onclick="chart.update((a, b) => b.depth - a.depth)">Sorting Kedalaman Sumur</button>
    <button onclick="chart.update((a, b) => d3.ascending(a.letter, b.letter))">Sorting Nama</button>
    <div class="chart"></div>

    <script>
      const data = [
        {letter: "A", depth: 23},
        {letter: "B", depth: 44},
        {letter: "C", depth: 54},
        {letter: "D", depth: 12},
        {letter: "E", depth: 33},
        {letter: "F", depth: 67},
        {letter: "G", depth: 39},
        {letter: "H", depth: 18},
        {letter: "I", depth: 26},
        {letter: "J", depth: 10},
        {letter: "K", depth: 22},
        {letter: "L", depth: 44},
        {letter: "M", depth: 77},
        {letter: "N", depth: 35},
        {letter: "O", depth: 48},
        {letter: "P", depth: 66},
        {letter: "Q", depth: 11},
        {letter: "R", depth: 51},
        {letter: "S", depth: 99},
        {letter: "T", depth: 23},
        {letter: "U", depth: 47},
        {letter: "V", depth: 73},
        {letter: "W", depth: 31},
        {letter: "X", depth: 55},
        {letter: "Y", depth: 88},
        {letter: "Z", depth: 17}
      ];

      const chart = (function() {
        const width = 640;
        const height = 400;
        const marginTop = 20;
        const marginRight = 0;
        const marginBottom = 30;
        const marginLeft = 40;
        
        const x = d3.scaleBand()
          .domain(data.map(d => d.letter))
          .range([marginLeft, width - marginRight])
          .padding(0.1);

        const xAxis = d3.axisBottom(x).tickSizeOuter(0);

        const y = d3.scaleLinear()
          .domain([0, d3.max(data, d => d.depth)]).nice()
          .range([height - marginBottom, marginTop]);

        const svg = d3.create("svg")
            .attr("viewBox", [0, 0, width, height])
            .attr("style", `max-width: ${width}px; height: auto; font: 10px sans-serif; overflow: visible;`);

        const bar = svg.append("g")
            .attr("fill", "steelblue")
          .selectAll("rect")
          .data(data)
          .join("rect")
            .style("mix-blend-mode", "multiply")
            .attr("x", d => x(d.letter))
            .attr("y", d => y(d.depth))
            .attr("height", d => y(0) - y(d.depth))
            .attr("width", x.bandwidth());

        const gx = svg.append("g")
            .attr("transform", `translate(0,${height - marginBottom})`)
            .call(xAxis);
        
        const gy = svg.append("g")
            .attr("transform", `translate(${marginLeft},0)`)
            .call(d3.axisLeft(y))
            .call(g => g.select(".domain").remove());

        return Object.assign(svg.node(), {
          update(order) {
            x.domain(data.sort(order).map(d => d.letter));

            const t = svg.transition()
                .duration(750);

            bar.data(data, d => d.letter)
                .order()
              .transition(t)
                .delay((d, i) => i * 20)
                .attr("x", d => x(d.letter));

            gx.transition(t)
                .call(xAxis)
              .selectAll(".tick")
                .delay((d, i) => i * 20);
          }
        });
      })();

    document.querySelector('.chart').appendChild(chart);
    </script>
  </body>
</html>