Daftar Isi
- Pendahuluan
- ⭐ Pentingnya Visualisasi Data yang Efektif dalam Dashboard Bisnis
- ⭐ Mengenal Chart.js dan ApexCharts: Pustaka JavaScript Andalan untuk Chart Interaktif
- Chart.js (https://www.chartjs.org/)
- ApexCharts (https://apexcharts.com/)
- ⭐ Gambaran Umum: Apa yang Akan Kita Bangun dalam Artikel Ini
- Mempersiapkan Proyek Kamu
- ⭐ Struktur Proyek: Dimana Kita Akan Menempatkan Karya Kita?
- ⭐ HTML Dasar: Fondasi Kokoh Dashboard Kita
- ⭐ Menyertakan Library: Memberi "Nyawa" pada Chart Kita
- ⭐ Styling dengan Tailwind CSS: Sentuhan Estetika yang Modern
- Bagian 1: Sales Overview - Membangun Donut Chart Interaktif dengan Chart.js
- ⭐ Step 1: Menyiapkan "Panggung" HTML untuk Donut Chart Kita
- 💡 Kenapa Struktur HTML Ini Penting?
- ⭐ Step 2: Memberi "Nyawa" pada Chart dengan JavaScript (
js/doughnut-chart.js)- 💡 Penjelasan Alur Kode JavaScript (Detail Langkah demi Langkah):
document.addEventListener("DOMContentLoaded", function () { ... });salesDataByTimeRange(Bank Data Penjualan):categoryColors(Palet Warna):ctxdanmyDoughnutChart(Persiapan Kanvas untuk Menggambar):createPattern(color)(Trik Tekstur Keren):formatNumberTok(num)(Fungsi Perapi Angka):updateChart(selectedTimeRange)(Pusat Kendali Chart Interaktif):
- 💡 Penjelasan Alur Kode JavaScript (Detail Langkah demi Langkah):
- ⭐ Step 1: Menyiapkan "Panggung" HTML untuk Donut Chart Kita
- Bagian 2: Total Profit - Membuat Line Chart Dinamis dengan ApexCharts
- ⭐ Step 1: Menyiapkan "Panggung" HTML untuk Tren Profit Kita
- ⭐ Step 2: Memberi "Nyawa" pada Chart dengan JavaScript (
js/line-chart.js)document.addEventListener("DOMContentLoaded", function () { ... });profitData(Bank Data Profit):calculateGrowth(currentValue, previousValue)(Si Penghitung Pertumbuhan):updateGrowthDisplay(data)(Si Pengubah Tampilan Pertumbuhan):initialChartOptions(Blueprint Chart ApexCharts):- Inisialisasi Chart (
new ApexCharts(...)danrender()): - Logika Interaktif (Menanggapi Dropdown):
- Tips Pengembangan dan Peningkatan
- ⭐ Pengelolaan Data: Dari Data Dummy ke Data Nyata
- Apa itu API Backend?
- Langkah-langkah Integrasi Data Nyata:
- ⭐ Kustomisasi Lanjutan: Tampilan Lebih Kaya
- Kustomisasi Lanjutan pada Chart.js (Donut Chart):
- Kustomisasi Lanjutan pada ApexCharts (Line Chart):
- ⭐ Responsivitas: Tampilan di Berbagai Ukuran Layar
- ⭐ Performa: Menangani Data Besar dengan Cepat
- ⭐ Aksesibilitas: Dashboard untuk Semua Orang
- ⭐ Pengelolaan Data: Dari Data Dummy ke Data Nyata
- Studi Kasus & Sumber Belajar Terpercaya ( BuildWithAngga )
- ⭐ Belajar dari Real Project, Bukan Teori Doang
- ⭐ Visual Interaktif & UI Keren
- ⭐ Materi Up-to-date & Fokus ke Industri
- ⭐ Penjelasan Simpel, Bahasa Indonesia
- ⭐ Mentoring & Sertifikat Karier
- Kesimpulan
- ⭐ Ringkasan Pencapaian:
- ⭐ Manfaat Visualisasi Data yang Dinamis dan Mudah Dipahami:
- ⭐ Potensi untuk Eksplorasi Lebih Lanjut dan Aplikasi di Proyek kamu Sendiri:
Pendahuluan

⭐ Pentingnya Visualisasi Data yang Efektif dalam Dashboard Bisnis
Pernahkah kamu merasa tenggelam dalam lautan angka dan tabel yang membingungkan? Di era digital yang serba cepat ini, data ibarat "emas" baru bagi bisnis. Namun, menumpuk data saja tidak cukup, lho! Kuncinya adalah bagaimana kita bisa mencerna dan memahami data tersebut dengan cepat, sehingga bisa menjadi dasar untuk mengambil keputusan strategis yang tepat. Bayangkan jika kamu bisa melihat sekilas tren penjualan, performa produk, atau fluktuasi profit hanya dalam hitungan detik. Nah, di sinilah peran visualisasi data menjadi sangat krusial!
Dashboard yang dirancang dengan baik itu seperti kompas bagi bisnis kamu. Ia tidak hanya menyajikan deretan angka mati, tetapi juga mengubahnya menjadi "cerita" visual yang hidup dan mudah dipahami. Dengan visualisasi yang efektif, kita bisa langsung melihat pola, mendeteksi anomali yang perlu diwaspadai, dan bahkan memprediksi tren masa depan. Jadi, visualisasi data bukan cuma soal estetika, tapi juga fondasi penting untuk membuat keputusan bisnis yang lebih cerdas dan proaktif. Siap mengubah data mentah jadi wawasan berharga? Yuk, lanjutkan!
⭐ Mengenal Chart.js dan ApexCharts: Pustaka JavaScript Andalan untuk Chart Interaktif
Sekarang, mungkin kamu bertanya-tanya, "Bagaimana sih caranya membuat visualisasi data yang ciamik itu?" Jangan khawatir! Ada banyak "senjata rahasia" di dunia pengembangan web, dan dua di antaranya yang paling populer dan powerful adalah Chart.js dan ApexCharts.
1. Chart.js (https://www.chartjs.org/)

Ini ibarat teman baik yang ramah dan serbaguna. Ia adalah pustaka charting open-source yang sangat disukai para developer. Kenapa? Karena kesederhanaannya untuk dipelajari dan kemampuannya menghasilkan berbagai jenis chart yang bersih, responsif, dan terlihat modern. Mau bikin bar chart, line chart, atau Donut Chart yang menarik seperti yang akan kita gunakan nanti? Chart.js jagonya!
2. ApexCharts (https://apexcharts.com/)

Di sisi lain, ada ApexCharts (https://apexcharts.com/), sang pustaka charting yang lebih "serius" tapi super fleksibel. ApexCharts menawarkan fitur-fitur canggih untuk visualisasi yang lebih kompleks dan interaktif. Jika kamu butuh Line Chart dengan tooltip yang detail, atau ingin memvisualisasikan tren profit yang dinamis dengan area yang diisi gradasi, ApexCharts adalah pilihan yang tepat. Kedua pustaka ini memiliki kelebihan masing-masing dan akan kita manfaatkan bersama untuk menciptakan dashboard yang kaya fitur!
⭐ Gambaran Umum: Apa yang Akan Kita Bangun dalam Artikel Ini
Oke, sudah tidak sabar untuk mulai ngoding? Di artikel ini, kita akan langsung terjun ke praktik untuk membangun sebuah dashboard yang interaktif dan informatif. Fokus utama kita adalah menciptakan dua komponen visualisasi data penting:
- Dashboard "Sales Overview" dengan Donut Chart (menggunakan Chart.js): Kita akan membuat Donut Chart yang memvisualisasikan data penjualan kamu berdasarkan kategori produk (Electronic, Furniture, Clothes, Shoes). Yang menarik, chart ini akan dilengkapi dengan fungsionalitas pemilihan rentang waktu (harian, mingguan, bulanan, dll.) sehingga kamu bisa melihat distribusi penjualan dalam periode yang berbeda secara real-time.
- Dashboard "Total Profit" dengan Line Chart (menggunakan ApexCharts): Selanjutnya, kita akan membangun Line Chart yang elegan untuk menampilkan tren profit dari waktu ke waktu. Chart ini juga akan memiliki interaktivitas pemilihan rentang waktu, memungkinkan kamu melacak naik-turunnya profit dalam skala harian, mingguan, bulanan, bahkan tahunan. Kita juga akan menambahkan indikator persentase pertumbuhan profit, lho!
Jadi, bersiaplah untuk mengubah data mentah menjadi visualisasi yang informatif dan mudah digunakan, memberikan kamu kendali lebih besar atas insight bisnis kamu.
Mempersiapkan Proyek Kamu
Baiklah, teman-teman pembaca yang antusias! Setelah kita sama-sama "melek" betapa dahsyatnya visualisasi data, sekarang tiba saatnya untuk menyiapkan "arena" kita, alias lingkungan proyeknya. Anggap saja ini seperti menata workspace impian kamu sebelum mulai merakit sesuatu yang luar biasa. Persiapan yang rapi itu kunci, supaya proses coding kita nanti bisa mengalir lancar tanpa hambatan berarti. Yuk, kita siapkan bersama-sama!
⭐ Struktur Proyek: Dimana Kita Akan Menempatkan Karya Kita?

Agar pekerjaan kita terorganisir dan mudah dikelola, penting banget nih punya struktur folder yang jelas. Ini memang standar di dunia web development, tapi percaya deh, ini adalah kebiasaan baik yang akan sangat membantu kamu di kemudian hari! Kali ini, kita akan sedikit menyesuaikan penempatan file CSS kita. Kira-kira, nanti file-file ajaib kita akan tersusun manis seperti ini:
nama-proyek-dashboard/
└── src/
├───├── index.html
├───├── output.css <-- File CSS hasil kompilasi Tailwind ada di sini!
├───├── input.css <-- File CSS sumber untuk Tailwind
└── js/
├── doughnut-chart.js
└── line-chart.js
index.html: Ini adalah "rumah" utama dashboard kita, tempat semua elemen visual dan struktur halaman kita akan bersemayam.output.css: Ini adalah file CSS yang akan kita link keindex.html. File ini dihasilkan secara otomatis oleh Tailwind CSS dariinput.css.input.css: Ini adalah file CSS "sumber" kita, tempat kita mengimpor base, components, dan utilities dari Tailwind. Kita tidak akan mengedit file ini langsung, tapi ini penting untuk proses kompilasi Tailwind.js/: Nah, folder ini adalah "otak" di balik layar, tempat semua logika JavaScript kita berada. Kita sengaja memisahkan kode untuk Donut Chart (doughnut-chart.js) dan Line Chart (line-chart.js) ke dalam file yang berbeda. Kenapa? Biar lebih rapi, modular, dan gampang kalau ada bug atau mau di- upgrade nanti!
Gimana, sudah terbayang kan betapa rapinya nanti proyek kita?
⭐ HTML Dasar: Fondasi Kokoh Dashboard Kita

Setiap karya besar pasti butuh fondasi dan kerangka yang kokoh, kan? Sama halnya dengan dashboard kita! File index.html ini akan menjadi kerangka utama, tempat kita menempatkan semua "daging" dashboard kita, sekaligus menjadi kanvas di mana chart-chart keren kita akan "hidup".
Yuk, kita intip sedikit kerangka HTML dasarnya dengan penyesuaian untuk lokasi CSS:
<!DOCTYPE **html**>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard Visualisasi Data Keren</title>
<link href="./output.css" rel="stylesheet" /> <-- Path CSS sudah disesuaikan!
<script src="<https://cdn.jsdelivr.net/npm/chart.js>"></script>
<link href="<https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap>" rel="stylesheet" />
</head>
<body class="bg-[#F1F2F4]">
<div class="flex gap-4 mx-auto">
.......
</div>
<script src="<https://cdn.jsdelivr.net/npm/apexcharts>"></script>
<script src="js/doughnut-chart.js"></script>
<script src="js/line-chart.js"></script>
</body>
</html>
Mari kita bedah sedikit bagian pentingnya:
<head>: Di sini kita meletakkan informasi dasar halaman (seperticharsetdanviewportyang penting untuk responsivitas di berbagai perangkat!), judul yang muncul di tab browser, dan juga tempat kita "memanggil" file CSS dan pustaka Chart.js. Oh ya, kita juga pakai fontPlus Jakarta Sansdari Google Fonts biar tampilan dashboard makin modern dan enak dibaca!<link href="./output.css" rel="stylesheet" />: Perhatikan perubahan di sini! Karenaoutput.csssekarang setingkat denganindex.html, path-nya jadi lebih sederhana, cukup./output.css.<body class="bg-[#F1F2F4]">: Kita beri sedikit sentuhan warna background yang lembut dan elegan di seluruh halaman.- Pustaka JavaScript: Perhatikan dua baris
<script>di bagian paling bawah<body>. Kita mengimpor ApexCharts di sana, diikuti dengan file JavaScript kustom kita (doughnut-chart.jsdanline-chart.js). Kenapa di bawah? Biar elemen HTML dashboard kita sudah siap "disentuh" oleh kode JavaScript kita saat script ini dieksekusi. Ini praktik terbaik, lho!
⭐ Menyertakan Library: Memberi "Nyawa" pada Chart Kita
Seperti sudah kita lihat di kerangka HTML tadi, kita akan langsung "memanggil" kedua pustaka charting favorit kita, Chart.js dan ApexCharts, dari CDN (Content Delivery Network). Cara ini praktis banget dan cocok buat memulai proyek dengan cepat tanpa perlu instalasi yang rumit-rumit.
- Untuk Chart.js: Cukup tambahkan baris
<script src="<https://cdn.jsdelivr.net/npm/chart.js>"></script>di dalam tag<head>kamu. - Untuk ApexCharts: Kita akan tambahkan
<script src="<https://cdn.jsdelivr.net/npm/apexcharts>"></script>di bagian paling bawah<body>, tepat sebelum file JavaScript kustom kita. Ini adalah trik kecil untuk memastikan ApexCharts sudah "siap tempur" sebelum kode kita memanggilnya.
Dengan begini, semua "peralatan tempur" yang kita butuhkan sudah terpasang rapi di index.html kita!
⭐ Styling dengan Tailwind CSS: Sentuhan Estetika yang Modern

Data yang divisualisasikan dengan baik itu harus cantik juga, dong! Nah, di proyek ini kita akan memanfaatkan Tailwind CSS. Ini bukan sekadar framework CSS biasa, melainkan pendekatan utility-first. Artinya, kita bisa mendesain tampilan hanya dengan menambahkan kelas-kelas CSS langsung di elemen HTML kita. Lihat saja kelas-kelas seperti flex, gap-4, bg-white, rounded-2xl, p-6, atau text-2xl font-medium yang akan kita pakai di HTML kamu nanti, itu semua adalah kelas Tailwind yang membuat tampilan kita jadi lebih keren dan responsive tanpa perlu menulis CSS dari nol!
Untuk menggunakan Tailwind CSS di proyek ini, kamu perlu melakukan setup kecil. Pertama paste di terminal perintah ini:
npm install tailwindcss @tailwindcss/cli
Perintah ini akan menginstal tailwind css dalam project kamu.
Selanjutnya buat file bernama input.css setingkat dengan index.html, lalu isi dengan kode ini:
/* input.css */
@import "tailwindcss";
body {
font-family: "Plus Jakarta Sans", sans-serif;
background: #f7f8fa;
}
File input.css ini adalah titik awal bagi Tailwind untuk "membentuk" semua kelas CSS-nya. Setelah itu, kamu perlu menjalankan perintah kompilasi Tailwind dari terminal (setelah kamu menginstal Tailwind CSS via npm, misalnya) untuk menghasilkan file output.css yang akan kita gunakan di browser. Perintahnya kira-kira seperti ini:
npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch
Perintah di atas akan membaca input.css, memproses semua kelas Tailwind yang kamu gunakan di HTML, dan menuliskannya ke output.css. Opsi --watch itu penting banget, dia akan otomatis mengkompilasi ulang output.css setiap kali kamu membuat perubahan di file HTML atau JavaScript kamu. Jadi, kamu bisa fokus coding dan melihat hasilnya secara instan!
Pastikan kamu punya file output.css yang sudah digenerate dengan benar di samping index.html, dan sudah di-link di <head> HTML, seperti yang sudah kita intip tadi. Dengan Tailwind, kita bisa membuat antarmuka yang bersih, modern, dan profesional dengan sangat efisien. Super fleksibel deh pokoknya!
Gimana, sudah siap semua "fondasi" dan "perkakas"nya? Kalau sudah, berarti kita sudah siap banget untuk melangkah ke bagian paling seru: mulai coding chart-chartnya! Mari kita lanjutkan petualangan ini!
Bagian 1: Sales Overview - Membangun Donut Chart Interaktif dengan Chart.js

Setelah kita menyiapkan "perkakas" dan "arena" proyek, sekarang saatnya kita mulai membangun visualisasi data yang pertama, yaitu bagian "Sales Overview" atau gambaran umum penjualan. Di sini, kita akan membuat sebuah Donut Chart yang interaktif menggunakan pustaka JavaScript bernama Chart.js.
Bayangkan Donut Chart seperti kue donat yang dibagi-bagi. Setiap potongan donat mewakili porsi penjualan dari kategori produk yang berbeda (misalnya, Elektronik, Furnitur, Pakaian, Sepatu). Dengan melihat ukuran setiap potongan, kita bisa langsung tahu kategori mana yang paling banyak menyumbang penjualan, dan mana yang porsinya lebih kecil.
Yang lebih keren lagi, chart ini nanti bisa kita ubah-ubah datanya secara instan Misalnya, kita bisa melihat porsi penjualan untuk hari ini, minggu ini, bulan ini, atau bahkan setahun penuh, hanya dengan memilih dari sebuah menu dropdown. Mari kita mulai langkah demi langkah
⭐ Step 1: Menyiapkan "Panggung" HTML untuk Donut Chart Kita
Sebelum Chart.js bisa menggambar apa pun, kita perlu menyediakan tempat di halaman web kita (index.html) sebagai "kanvas" untuk chart tersebut, dan juga area untuk menampilkan informasi pendukungnya. kamu bisa meletakkan kode ini di dalam div yang memiliki kelas flex gap-4 mx-auto di dalam <body> file index.html kamu.
<section class="chart-container w-full bg-white rounded-2xl p-6">
<div class="flex items-center justify-between">
<h1 class="text-2xl font-medium">Sales Overview</h1>
<div class="border border-gray-300 rounded-lg p-1">
<select id="timeRangeSelector" class="focus:outline-none">
<option value="day">Day</option>
<option value="week">Week</option>
<option value="month" selected>Month</option>
<option value="quarter">Quarter</option>
<option value="year">Year</option>
<option value="custom">Custom Range</option>
</select>
</div>
</div>
<div class="flex items-center gap-7 mt-8">
<div id="chartdiv" class="size-[220px] relative">
<canvas id="myDoughnutChart"></canvas>
<div class="sub-text absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center gap-2">
<strong class="text-3xl font-medium" id="visitsValue"></strong>
<p class="text-[#414141] text-center"><span id="visitsTimeRange">Weekly</span> Visits</p>
</div>
</div>
<div class="flex flex-col items-center gap-8 flex-1 w-full">
<div class="flex items-center gap-3 w-full">
<div class="w-9 h-10 bg-[#EDFFB1] rounded-lg flex items-center justify-center shrink-0">
<img src="" alt="" id="totalSalesBullet" />
</div>
<div class="flex flex-col gap-[2px] flex-1">
<p>Number of Sales</p>
<p class="font-medium text-xl">$<span id="totalSalesValue"></span></p>
</div>
</div>
<div class="grid grid-cols-2 gap-4 w-full">
<div class="flex flex-col gap-[6px]">
<div class="flex gap-2 items-center">
<span class="size-3 rounded-full category-bullet shrink-0" data-category="Electronic"></span>
<p>Electronic</p>
</div>
<p class="font-medium">$<span id="electronicValue"></span></p>
</div>
<div class="flex flex-col gap-[6px]">
<div class="flex items-center gap-2">
<span class="size-3 rounded-full category-bullet shrink-0" data-category="Furniture"></span>
<p>Furniture</p>
</div>
<p class="font-medium">$<span id="furnitureValue"></span></p>
</div>
<div class="flex flex-col gap-[6px]">
<div class="flex items-center gap-2">
<span class="size-3 rounded-full category-bullet shrink-0" data-category="Clothes"></span>
<p>Clothes</p>
</div>
<p class="font-medium">$<span id="clothesValue"></span></p>
</div>
<div class="flex flex-col gap-[6px]">
<div class="flex gap-2 items-center">
<span class="size-3 rounded-full category-bullet shrink-0" data-category="Shoes"></span>
<p>Shoes</p>
</div>
<p class="font-medium">$<span id="shoesValue"></span></p>
</div>
</div>
</div>
</div>
</section>
💡 Kenapa Struktur HTML Ini Penting?
- Jelas dan Terpisah: Setiap bagian punya "rumah" sendiri (
<section>dan<div>berlapis). Ini memudahkan kita nanti kalau mau mengubah atau menambahkan sesuatu. - ID Unik: Hampir semua elemen yang akan kita ubah atau isi datanya dengan JavaScript memiliki
idyang unik (misalnyamyDoughnutChart,timeRangeSelector,visitsValue,electronicValue). Ini seperti nama panggilan agar JavaScript tahu elemen mana yang harus dipegang. - Data Kategori (
data-category): Untuk bullet points kategori (<span>), kita pakai atributdata-category. Ini cara pintar untuk "menempelkan" informasi (kategori produknya) langsung ke elemen HTML, sehingga JavaScript bisa dengan mudah membaca dan menggunakannya. - Siap untuk Styling: Kelas-kelas Tailwind CSS (seperti
flex,bg-white,rounded-2xl,p-6) sudah kita tambahkan agar tampilannya langsung cantik begitu halaman dimuat, bahkan sebelum JavaScript bekerja.
Panggung sudah siap, lampunya sudah terpasang. Sekarang, mari kita hidupkan panggung ini dengan JavaScript
⭐ Step 2: Memberi "Nyawa" pada Chart dengan JavaScript (js/doughnut-chart.js)

Sekarang, buka file js/doughnut-chart.js kamu (yang ada di dalam folder js/). Di sinilah semua "keajaiban" akan terjadi. Kita akan menulis kode yang mengambil data, mengolahnya, dan memberitahu Chart.js bagaimana menggambar Donut Chart yang interaktif.
<aside> 💡
Penting: Seluruh kode JavaScript ini akan kita letakkan di dalam blok document.addEventListener("DOMContentLoaded", function () { ... });
</aside>
Ini memastikan bahwa kode kita hanya akan berjalan setelah seluruh halaman HTML selesai dimuat, jadi elemen-elemen seperti <canvas> dan <select> pasti sudah tersedia saat JavaScript mencoba mengaksesnya.
// js/doughnut-chart.js
document.addEventListener("DOMContentLoaded", function () {
// Pastikan HTML siap sebelum JavaScript berjalan.
// 1. Data Penjualan (Simulasi): salesDataByTimeRange
// Berisi data penjualan per kategori dan kunjungan, diatur per hari, minggu, bulan, dll.
// (Di dunia nyata, data ini biasanya dari server/API).
const salesDataByTimeRange = {
day: { Electronic: 2000, Furniture: 2500, Clothes: 800, Shoes: 400, visits: 3500, },
week: { Electronic: 300, Furniture: 7000, Clothes: 1500, Shoes: 1000, visits: 102000, },
month: { Electronic: 50000, Furniture: 30000, Clothes: 10000, Shoes: 10000, visits: 102000, }, // Default
quarter: { Electronic: 10000, Furniture: 30000, Clothes: 5000, Shoes: 6000, visits: 1200000, },
year: { Electronic: 60000, Furniture: 120000, Clothes: 20000, Shoes: 25000, visits: 5000000, },
custom: { Electronic: 0, Furniture: 0, Clothes: 0, Shoes: 0, visits: 0, },
};
// 2. Warna untuk Setiap Kategori di Chart.
// 'Electronic' akan diubah jadi pola nanti.
const categoryColors = {
Electronic: "#DFD4FB",
Furniture: "#6A40FD",
Clothes: "#D5FD5B",
Shoes: "#AB91F5",
};
// Ambil "kanvas" untuk menggambar chart dari HTML.
const ctx = document.getElementById("myDoughnutChart").getContext("2d");
let myDoughnutChart; // Variabel untuk menyimpan chart yang sedang aktif.
// 3. Fungsi untuk Membuat Pola Garis (misal untuk kategori Electronic).
// Ini bikin tekstur garis-garis di segmen chart.
function createPattern(color) {
const patternCanvas = document.createElement("canvas");
const patternCtx = patternCanvas.getContext("2d");
patternCanvas.width = 10;
patternCanvas.height = 10;
patternCtx.strokeStyle = color;
patternCtx.lineWidth = 2;
patternCtx.beginPath();
patternCtx.moveTo(0, 10);
patternCtx.lineTo(10, 0);
patternCtx.stroke();
return ctx.createPattern(patternCanvas, "repeat");
}
// Terapkan pola garis ke kategori Electronic.
const electronicPattern = createPattern("#DFD4FB");
categoryColors.Electronic = electronicPattern;
// 4. Fungsi untuk Mempersingkat Angka Besar (misal: 120000 jadi "120k").
// Agar lebih mudah dibaca.
function formatNumberToK(num) {
if (num >= 1000000) return (num / 1000000).toFixed(1).replace(/\\.0$/, "") + "M";
if (num >= 1000) return (num / 1000).toFixed(1).replace(/\\.0$/, "") + "k";
return num.toLocaleString();
}
// 5. Fungsi Utama: updateChart() - Menggambar & Memperbarui Chart serta Info Pendukung.
// Dipanggil setiap kali periode waktu dipilih dari dropdown.
function updateChart(selectedTimeRange) {
const currentSalesData = salesDataByTimeRange[selectedTimeRange];
// Siapkan data & warna sesuai urutan yang diinginkan untuk chart.
const orderedLabels = ["Electronic", "Shoes", "Furniture", "Clothes"];
const orderedDataValues = orderedLabels.map((label) => currentSalesData[label]);
const orderedBackgroundColors = orderedLabels.map((label) => categoryColors[label]);
// Hancurkan chart lama jika ada, agar tidak menumpuk.
if (myDoughnutChart) {
myDoughnutChart.destroy();
}
// Buat Donut Chart baru dengan Chart.js.
myDoughnutChart = new Chart(ctx, {
type: "doughnut",
data: {
labels: orderedLabels,
datasets: [{
data: orderedDataValues,
backgroundColor: orderedBackgroundColors,
borderColor: "white",
borderWidth: 2,
borderRadius: 10,
}],
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: "60%", // Ukuran lubang tengah donat.
rotation: 180,
plugins: {
legend: { display: false }, // Sembunyikan legenda bawaan (kita punya info di samping).
tooltip: {
callbacks: { // Atur teks yang muncul saat kursor diarahkan ke segmen chart.
label: function (context) {
let label = context.label || "";
if (label) label += ": ";
if (context.parsed !== null) label += "$" + context.parsed.toLocaleString();
return label;
},
},
},
},
},
});
// --- Isi Data ke Elemen HTML di Samping Chart ---
// Hitung & tampilkan Total Penjualan.
let totalSales = 0;
for (const category in currentSalesData) {
if (category !== "visits" && typeof currentSalesData[category] === "number") {
totalSales += currentSalesData[category];
}
}
document.getElementById("totalSalesValue").textContent = totalSales.toLocaleString();
document.getElementById("totalSalesBullet").style.backgroundColor = "#6c757d";
// Tampilkan nilai penjualan per kategori.
document.getElementById("electronicValue").textContent = currentSalesData.Electronic.toLocaleString();
document.getElementById("furnitureValue").textContent = currentSalesData.Furniture.toLocaleString();
document.getElementById("clothesValue").textContent = currentSalesData.Clothes.toLocaleString();
document.getElementById("shoesValue").textContent = currentSalesData.Shoes.toLocaleString();
// Atur warna bullet poin kategori (untuk Electronic pakai warna dasarnya saja).
const categoryBullets = document.querySelectorAll(".category-bullet");
categoryBullets.forEach((bullet) => {
const category = bullet.dataset.category;
bullet.style.backgroundColor = (category === "Electronic") ? "#DFD4FB" : categoryColors[category];
});
// --- Perbarui Nilai Kunjungan (Visits) di Tengah Chart ---
document.getElementById("visitsValue").textContent = formatNumberToK(currentSalesData.visits);
// Ubah teks periode waktu (misal: "month" jadi "Monthly").
let timeRangeText = selectedTimeRange.charAt(0).toUpperCase() + selectedTimeRange.slice(1);
if (timeRangeText === "Day") timeRangeText = "Daily";
if (timeRangeText === "Week") timeRangeText = "Weekly";
if (timeRangeText === "Month") timeRangeText = "Monthly";
if (timeRangeText === "Quarter") timeRangeText = "Quarterly";
if (timeRangeText === "Year") timeRangeText = "Yearly";
if (timeRangeText === "Custom") timeRangeText = "Custom Range";
document.getElementById("visitsTimeRange").textContent = timeRangeText;
}
// 6. Buat Chart Interaktif: Menghubungkan dropdown ke fungsi updateChart().
// Setiap kali pilihan di dropdown berubah, chart akan diperbarui.
const timeRangeSelector = document.getElementById("timeRangeSelector");
timeRangeSelector.addEventListener("change", function () {
const selectedValue = this.value;
updateChart(selectedValue);
});
// 7. Tampilkan Chart saat Halaman Pertama Kali Dimuat.
// Default-nya akan menampilkan data "Month" (bulanan).
updateChart("month");
});
💡 Penjelasan Alur Kode JavaScript (Detail Langkah demi Langkah):
1. document.addEventListener("DOMContentLoaded", function () { ... });:
Ini adalah "gerbang masuk" kode JavaScript kita. Ia memastikan seluruh halaman HTML kamu sudah selesai dimuat dan siap untuk dimanipulasi oleh JavaScript sebelum kode di dalamnya mulai berjalan. Ini mencegah kesalahan yang mungkin terjadi jika JavaScript mencoba mengakses elemen HTML yang belum ada.
2. salesDataByTimeRange (Bank Data Penjualan):
- Ini adalah objek JavaScript yang menyimpan semua data penjualan dan kunjungan kita. Bayangkan ini seperti "database mini" di dalam kode kamu.
- Setiap "kunci" dalam objek ini (
day,week,month,quarter,year,custom) adalah periode waktu yang berbeda. - Setiap periode waktu memiliki data penjualan untuk setiap kategori produk (Electronic, Furniture, Clothes, Shoes) dan juga jumlah total
visits(kunjungan). Ini memungkinkan kita untuk dengan mudah mengambil data yang tepat sesuai dengan pilihan pengguna di dropdown.
3. categoryColors (Palet Warna):
- Objek ini berfungsi sebagai palet warna untuk segmen-segmen di Donut Chart kita. Setiap kategori produk (Furniture, Clothes, Shoes) punya kode warna heksadesimal (
#6A40FD, dll.) yang akan membuat segmennya tampil dengan warna solid. - Namun, perhatikan
Electronic: "#DFD4FB". Ini adalah warna dasar, tapi nanti akan kita timpa dengan pola garis untuk membuatnya unik.
4. ctx dan myDoughnutChart (Persiapan Kanvas untuk Menggambar):
const ctx = document.getElementById("myDoughnutChart").getContext("2d");: Baris ini mengambil elemen<canvas>dari HTML kita (ingat ID-nya:myDoughnutChart?). Kemudian, ia mendapatkan "konteks gambar 2D" dari kanvas tersebut. Ini seperti mendapatkan kuas dan palet warna untuk mulai melukis di kanvas digital kamu.let myDoughnutChart;: Ini adalah variabel kosong. Kita akan menyimpannya sebagai "referensi" ke Donut Chart yang akan kita buat. Mengapa perlu? Agar nanti kita bisa "menghancurkan" chart yang lama sebelum menggambar yang baru, menghindari tumpukan chart di memori.
5. createPattern(color) (Trik Tekstur Keren):
- Ini adalah fungsi yang cukup unik untuk membuat efek visual khusus. Daripada hanya warna solid, kita ingin segmen "Electronic" di Donut Chart memiliki pola garis-garis miring.
- Bagaimana cara kerjanya?
document.createElement("canvas"): Fungsi ini secara sementara membuat elemen<canvas>baru yang sangat kecil (10x10 piksel) di memori, bukan di layar.patternCtx.strokeStyle = color; ... patternCtx.stroke();: Di kanvas kecil itu, kita menggambar sebuah garis diagonal dengan warna yang ditentukan.ctx.createPattern(patternCanvas, "repeat"): Ini adalah bagian ajaibnya Chart.js (melalui konteks kanvas utamactx) bisa menggunakan gambar dari kanvas kecil itu sebagai "pola" yang akan diulang-ulang untuk mengisi area segmen chart.
const electronicPattern = createPattern("#DFD4FB");dancategoryColors.Electronic = electronicPattern;: Di sini kita memanggil fungsicreatePatternuntuk membuat pola dengan warna dasar ungu muda, lalu kita mengganti nilaiElectronicdicategoryColorsdari kode warna solid menjadi pola yang baru dibuat ini. Jadi, nanti Chart.js akan tahu, "Oh, untuk Electronic, aku harus mengisi segmennya dengan pola garis ini"
6. formatNumberToK(num) (Fungsi Perapi Angka):
- Ini adalah fungsi pembantu sederhana yang bertujuan untuk membuat angka-angka besar di dashboard lebih mudah dibaca sekilas.
- Contoh: Jika penjualannya 50000, akan diformat menjadi "50k". Jika 1200000, akan menjadi "1.2M". Ini sangat membantu readability di dashboard.
7. updateChart(selectedTimeRange) (Pusat Kendali Chart Interaktif):
Ini adalah fungsi paling penting dan "otak" di balik Donut Chart interaktif kita. Fungsi ini bertanggung jawab untuk:
- ⭐ Mengambil Data yang Benar:
const currentSalesData = salesDataByTimeRange[selectedTimeRange];-> Baris ini mengambil data penjualan yang spesifik (harian, mingguan, bulanan, dll.) berdasarkanselectedTimeRangeyang diberikan (dari pilihan dropdown). - ⭐ Pengurutan Data:
orderedLabels,orderedDataValues,orderedBackgroundColorsdibuat. Ini penting agar segmen chart selalu muncul dalam urutan yang konsisten dan mudah diinterpretasikan, terlepas dari data mana yang paling besar. - ⭐ Mekanisme Penghancuran Chart Lama (
if (myDoughnutChart) { myDoughnutChart.destroy(); }): Ini adalah langkah krusial Setiap kali fungsiupdateChartdipanggil (misalnya, saat user memilih periode waktu baru), kita tidak ingin Chart.js menggambar chart baru di atas chart yang sudah ada.myDoughnutChart.destroy()akan membersihkan chart lama dari memori dan kanvas, sehingga chart baru bisa digambar dengan bersih. - ⭐ Membuat Chart Baru (
myDoughnutChart = new Chart(ctx, { ... });): Di sinilah Donut Chart yang baru digambar.type: "doughnut": Jelas, kita ingin chart berbentuk donat.data: Di sini kita masukkan label (nama kategori), nilai data (penjualan), dan warna latar belakang untuk setiap segmen.backgroundColorakan menggunakan pola untuk "Electronic" yang sudah kita buat.options: Ini adalah pengaturan "cerdas" yang membuat chart kita terlihat bagus dan interaktif:responsive: truedanmaintainAspectRatio: false: Membuat chart secara otomatis menyesuaikan ukurannya dengan ukuran layar atau wadahnya, tanpa memaksakan rasio.cutout: "60%": Mengatur ukuran lubang di tengah donat (semakin kecil angkanya, semakin besar lubangnya).rotation: 180: Memutar posisi awal segmen chart (opsional, untuk estetika).plugins.legend.display: false: Kita sengaja menyembunyikan legenda bawaan Chart.js karena kita sudah punya detail kategori yang lebih bagus di samping chart.tooltip.callbacks.label: Ini adalah bagian yang sangat berguna untuk mengkustomisasi teks yang muncul saat kamu mengarahkan kursor ke segmen donat. Kita membuatnya menampilkan nama kategori dan nilai penjualannya dalam format mata uang (contoh: "Electronic: $50,000").
- ⭐ Mengisi Data ke Elemen HTML Pendukung: Setelah chart digambar, fungsi ini juga akan mencari semua elemen HTML yang sudah kita siapkan dengan ID tertentu (misal:
totalSalesValue,electronicValue,visitsValue,visitsTimeRange, dll.) dan mengisitextContentmereka dengan data yang relevan daricurrentSalesData. - ⭐ Mengatur Warna Bullet Kategori: Kode ini akan menemukan semua
<span>dengan kelascategory-bulletdan mengaturbackground-colormereka agar sesuai dengan warna segmen di chart. Perlu diingat, untuk "Electronic", karena di chart kita pakai pola, untuk bullet HTML-nya kita gunakan warna dasarnya saja (#DFD4FB) karena elemen HTML biasa tidak bisa menampilkan pola kompleks. - ⭐ Memperbarui Teks Kunjungan (
Visits): MenggunakanformatNumberToK, nilai kunjungan (visitsValue) di tengah chart akan diperbarui dengan format yang ringkas (misal: "102k"). TeksvisitsTimeRangejuga akan disesuaikan (misal: dari "Month" menjadi "Monthly"). - ⭐
timeRangeSelector.addEventListener("change", function () { ... });(Menghidupkan Interaktivitas Dropdown): o- Ini adalah "pendengar" utama kita.
document.getElementById("timeRangeSelector")mendapatkan elemen dropdown kita dari HTML. addEventListener("change", ...): Baris ini memberitahu JavaScript untuk "mendengarkan". Setiap kali pengguna mengubah pilihan di dropdown (changeevent), fungsi yang ada di dalamnya akan otomatis dijalankan.const selectedValue = this.value;: Kita mendapatkan nilai dari opsi yang dipilih pengguna (misal, jika memilih "Week", makaselectedValueakan menjadi "week").updateChart(selectedValue);: Terakhir, kita memanggil fungsiupdateChartdenganselectedValueyang baru didapat. Ini akan memicu seluruh proses penggambaran ulang chart dan pembaruan informasi di sampingnya dengan data yang sesuai.
- Ini adalah "pendengar" utama kita.
- ⭐
updateChart("month");(Inisialisasi Chart Awal): o- Baris ini sangat penting Ketika halaman web kamu pertama kali dimuat di browser, kita ingin chart dan semua informasinya langsung muncul tanpa perlu user melakukan apa-apa. Jadi, kita langsung memanggil
updateChartdenganmonthsebagai nilai default. Ini memastikan dashboard kamu sudah "hidup" begitu terlihat.
- Baris ini sangat penting Ketika halaman web kamu pertama kali dimuat di browser, kita ingin chart dan semua informasinya langsung muncul tanpa perlu user melakukan apa-apa. Jadi, kita langsung memanggil
Bagian 2: Total Profit - Membuat Line Chart Dinamis dengan ApexCharts

Setelah kita berhasil membuat Donut Chart penjualan yang interaktif di "Sales Overview", sekarang kita beralih ke sisi lain dari dashboard kita: melihat tren profit! Untuk bagian ini, kita akan pakai ApexCharts, pustaka yang nggak kalah canggih dan asyik buat bikin chart garis (Line Chart) yang dinamis.
Visualisasi profit ini penting banget, lho! Ibaratnya, kalau Donut Chart tadi menunjukkan "kue" penjualan kita dibagi-bagi, Line Chart ini akan menunjukkan "perjalanan" profit kita dari waktu ke waktu. Apakah profit kita lagi naik daun, stagnan, atau justru ada penurunan yang perlu diwaspadai? Semua bisa terlihat jelas di sini! Dan yang paling menarik, kita bisa mengubah rentang waktu yang ditampilkan, sama seperti di Donut Chart.
Mari kita mulai lagi dari menyiapkan tempatnya di HTML!
⭐ Step 1: Menyiapkan "Panggung" HTML untuk Tren Profit Kita
Sama seperti Donut Chart tadi, kita perlu menyiapkan "panggung" atau tempat di index.html agar Line Chart kita bisa muncul. Kode ini akan berada di samping atau di bawah <section> "Sales Overview" yang sudah kita buat sebelumnya. kamu bisa menambahkannya di dalam div utama yang punya kelas flex gap-4 mx-auto di dalam <body>.
<section class="flex flex-col gap-4 w-full bg-white rounded-2xl p-9">
<div class="flex items-center justify-between">
<h1 class="text-2xl font-medium">Total Profit</h1>
<div class="border border-gray-300 rounded-lg p-1">
<select id="timeRangeSelectorLine" class="focus:outline-none">
<option value="day">Day</option>
<option value="week">Week</option>
<option value="month" selected>Month</option>
<option value="quarter">Quarter</option>
<option value="year">Year</option>
<option value="custom">Custom Range</option>
</select>
</div>
</div>
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between gap-2">
<div class="flex items-center gap-1">
<div class="size-9 bg-[#EBE8FB] rounded-lg flex items-center justify-center shrink-0">
<img src="" alt="" id="totalSalesBullet" />
</div>
<h4>Profit Trend</h4>
</div>
<div class="flex items-center gap-1">
<div class="flex items-center gap-0.5">
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjQ1NDcgNC44NTQ0OUwxMS4xNjY0IDQuODU0NDlMNy4zMzMyOCAxMS41MjExTDMuMzMzMjggNy40OTk3NkwyLjU0NTk2IDguMjY5NjlMMC45OTk1MSAxNi4wMDAzTDE2LjAwMDMgMC45OTk5MDhMMTMuNDU0NyA0LjgzNDQ5WiIgZmlsbD0iIzM5QjM0OSIvPgo8L3N2Zz4K" alt="arrow-up" class="shrink-0" id="growthArrow" />
<p class="presentase-growth text-[#39b349]">0.00%</p>
</div>
<p class="text-[#7F8583]">Growth</p>
</div>
</div>
<div id="profitTrendChart" class="min-w-full"></div>
</div>
</section>
Penjelasan Singkat Elemen HTML-nya:
<section class="flex flex-col ...">: Ini adalah "kotak" besar berwarna putih dengan sudut membulat yang membungkus semua elemen di bagian "Total Profit". Ini adalah wadah utama kita.- Judul dan Dropdown Pemilihan Waktu:
<h1 class="text-2xl font-medium">Total Profit</h1>: Judul utama untuk bagian ini.<select id="timeRangeSelectorLine">: Ini adalah dropdown yang memungkinkan pengguna memilih rentang waktu (harian, mingguan, bulanan, dll.) untuk data profit. Ingat ID-nya,timeRangeSelectorLine, ini penting untuk JavaScript!
- Informasi Tren Profit dan Pertumbuhan:
- Ada tulisan "Profit Trend" dengan ikon kecil.
- Lalu ada bagian "Growth":
<img src="..." id="growthArrow" />: Ini adalah ikon panah. JavaScript kita yang akan mengatur apakah panahnya menghadap ke atas (profit naik), ke bawah (profit turun), atau mendatar (stagnan), bahkan mengubah warnanya!<p class="presentase-growth">0.00%</p>: Ini adalah tempat di mana persentase pertumbuhan profit akan ditampilkan (misal: "5.23%" atau "-2.10%"). Warnanya juga akan berubah sesuai kondisi profit.
<div id="profitTrendChart" class="min-w-full"></div>: Ini adalah "kanvas" kita untuk Line Chart profit. IDprofitTrendChartadalah nama panggilannya di JavaScript nanti.
Panggung sudah siap, semua elemennya sudah di tempatnya. Sekarang, mari kita berikan "nyawa" dengan kode JavaScript!
⭐ Step 2: Memberi "Nyawa" pada Chart dengan JavaScript (js/line-chart.js)

Sekarang, buka file js/line-chart.js kamu. Di sinilah semua logika cerdas untuk Line Chart kita akan bersemayam. Kode ini akan mengambil data, mengolahnya, dan memerintahkan ApexCharts untuk menggambarnya dengan indah.
// js/line-chart.js
document.addEventListener("DOMContentLoaded", function () {
// Pastikan halaman HTML sudah dimuat sepenuhnya sebelum menjalankan kode.
// 1. Data Profit (Contoh): profitData
// Berisi data profit dan label waktu untuk periode Harian, Mingguan, Bulanan, dll.
// (Di aplikasi sungguhan, data ini biasanya dari server).
const profitData = {
yearly: { data: [30000, 40000, 50000, 60000, 80000, 96755.77, 70000, 120000, 60000, 160000, 150000, 32000], categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], },
daily: { data: [10000, 15000, 20000, 17000, 25000, 22000, 30000], categories: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], },
weekly: { data: [50000, 60000, 75000, 80000], categories: ["Week 1", "Week 2", "Week 3", "Week 4"], },
quarterly: { data: [45000, 55000, 70000, 96000], categories: ["Q1", "Q2", "Q3", "Q4"], },
multiYear: { data: [250000, 275000, 310000], categories: ["2022", "2023", "2024"], },
custom: { data: [40000, 42000, 43000, 47000], categories: ["Jun 10", "Jun 11", "Jun 12", "Jun 13"], },
};
// 2. Fungsi: Menghitung Persentase Kenaikan/Penurunan Profit.
function calculateGrowth(currentValue, previousValue) {
if (previousValue === 0) return currentValue === 0 ? "0.00" : "N/A";
const growth = ((currentValue - previousValue) / previousValue) * 100;
return growth.toFixed(2);
}
// 3. Fungsi Utama: updateGrowthDisplay() - Mengubah Tampilan Persentase & Panah Pertumbuhan.
// Ini yang membuat angka dan arah panah profit 'hidup'.
function updateGrowthDisplay(data) {
const growthPercentageElement = document.querySelector(".presentase-growth");
const growthArrowElement = document.getElementById("growthArrow");
// Jika data tidak cukup atau elemen tidak ada, tampilkan 0% netral.
if (!growthPercentageElement || !growthArrowElement || data.length < 2) {
growthPercentageElement.textContent = "0.00%";
growthPercentageElement.classList.remove("text-[#39b349]", "text-red-500");
growthPercentageElement.classList.add("text-[#7F8583]");
growthArrowElement.src = "data:image/svg+xml;base64,..."; // SVG panah datar
growthArrowElement.style.transform = "rotate(90deg)";
return;
}
// Hitung pertumbuhan profit dari dua data terakhir.
const lastValue = data[data.length - 1];
const previousLastValue = data[data.length - 2];
const growth = parseFloat(calculateGrowth(lastValue, previousLastValue));
// Atur teks persentase (hilangkan minus jika turun) dan hapus warna lama.
growthPercentageElement.textContent = `${Math.abs(growth).toFixed(2)}%`;
growthPercentageElement.classList.remove("text-[#39b349]", "text-red-500", "text-[#7F8583]");
// Ubah warna teks dan arah panah sesuai tren profit (naik, turun, atau datar).
if (growth > 0) { // Naik
growthPercentageElement.classList.add("text-[#39b349]");
growthArrowElement.src = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjQ1NDcgNC44NTQ0OUwxMS4xNjY0IDQuODU0NDlMNy4zMzMyOCAxMS41MjExTDMuMzMzMjggNy40OTk3NkwyLjU0NTk2IDguMjY5NjlMMC45OTk1MSAxNi4wMDAzTDE2LjAwMDMgMC45OTk5MDhMMTMuNDU0NyA0LjgzNDQ5WiIgZmlsbD0iIzM5QjM0OSIvPgo8L3N2Zz4K"; // Panah ke atas (SVG)
growthArrowElement.style.transform = "rotate(0deg)";
} else if (growth < 0) { // Turun
growthPercentageElement.classList.add("text-red-500");
growthArrowElement.src = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTIuNTQ1OTEgMTEuMTQ1NUw0LjgzMzk0IDExLjE0NTVMOC42NjY5MiA0LjQ3OTA3TDEyLjY2NjkgOC41MDAzNkwxMy40NTQyIDcuNzMwMzFMMTUuOTk5OSAwTDAuMDAwMzg3MTU1IDE1LjAwMDJMMi41NDU5MSAxMS4xNjU1WiIgZmlsbD0iI0Y3NTE1MSIvPgo8L3N2Zz4K"; // Panah ke bawah (SVG)
growthArrowElement.style.transform = "rotate(0deg)";
} else { // Datar
growthPercentageElement.classList.add("text-[#7F8583]");
growthArrowElement.src = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTcuOTk5OTYgOC44MzU3OUwzLjk5OTk2IDQuODI4NzlMMi43Mjk5NiA2LjQxMDc5TDcuOTk5OTYgMTEuNzc5OEwxMy4yNjk5IDYuNDEwNzlMMTEuOTk5OSA0LjgyODc5TDcuOTk5OTYgOC44MzU3OVoiIGZpbGw9IiM3RjI1OEIiLz4KPC9zdmc+"; // Panah datar (SVG)
growthArrowElement.style.transform = "rotate(90deg)";
}
}
// 4. Pengaturan Awal ApexCharts (Blueprint Chart).
// Semua detail tampilan dan fungsi chart ada di sini.
const initialChartOptions = {
chart: {
type: "area", // Jenis chart: area (garis + area terisi di bawahnya)
toolbar: { show: false }, // Sembunyikan toolbar
events: { // Panggil updateGrowthDisplay saat chart dimuat/diperbarui.
mounted: (chartContext, config) => updateGrowthDisplay(config.series[0].data),
updated: (chartContext, config) => updateGrowthDisplay(config.series[0].data),
},
},
series: [{ name: "Profit", data: profitData.yearly.data.slice(4, 10), }], // Data awal (Mei-Okt).
xaxis: { categories: profitData.yearly.categories.slice(4, 10), }, // Label sumbu X.
yaxis: { // Pengaturan sumbu Y.
min: 0, max: 200000, tickAmount: 4,
labels: {
formatter: (val) => (val >= 1000 ? "$" + val / 1000 + "K" : "$" + val), // Format jadi "$50K".
},
},
dataLabels: { enabled: false }, // Sembunyikan angka di garis chart.
stroke: { curve: "smooth", width: 2, }, // Garis chart halus dan tebal 2px.
fill: { // Area bawah garis chart.
type: "gradient", // Efek gradasi.
gradient: {
shadeIntensity: 1, opacityFrom: 0.4, opacityTo: 0, stops: [0, 90, 100],
colorStops: [{ offset: 0, color: "#B38BFE", opacity: 0.5 }, { offset: 100, color: "#FFFFFF", opacity: 0 }],
},
},
tooltip: { // Pengaturan pop-up info saat kursor di chart.
x: { format: "MMMM" }, // Format tanggal/bulan.
y: {
formatter: (val) => "$" + val.toLocaleString(), // Format nilai profit.
title: { formatter: (seriesName) => '' }, // Sembunyikan nama seri ("Profit") di tooltip.
},
},
colors: ["#B38BFE"], // Warna utama garis chart (ungu).
};
// 5. Buat dan Tampilkan Chart ApexCharts di halaman.
const profitTrendChart = new ApexCharts(document.querySelector("#profitTrendChart"), initialChartOptions);
profitTrendChart.render();
// 6. Membuat Chart Interaktif: Menghubungkan Dropdown ke Chart.
const timeRangeSelector = document.getElementById("timeRangeSelectorLine");
// Tampilkan persentase pertumbuhan awal.
const defaultData = profitData.yearly.data.slice(4, 10);
updateGrowthDisplay(defaultData);
// Jika dropdown ditemukan:
if (timeRangeSelector) {
// Dengarkan perubahan pilihan di dropdown.
timeRangeSelector.addEventListener("change", (event) => {
const selectedValue = event.target.value;
let newData = [];
let newCategories = [];
let newXaxisFormat = "MMMM";
// Pilih data dan format yang sesuai berdasarkan pilihan dropdown.
switch (selectedValue) {
case "day": newData = profitData.daily.data; newCategories = profitData.daily.categories; newXaxisFormat = "MMM dd"; break;
case "week": newData = profitData.weekly.data; newCategories = profitData.weekly.categories; newXaxisFormat = "dd MMM"; break;
case "month": newData = profitData.yearly.data.slice(4, 10); newCategories = profitData.yearly.categories.slice(4, 10); newXaxisFormat = "MMMM"; break;
case "quarter": newData = profitData.quarterly.data; newCategories = profitData.quarterly.categories; newXaxisFormat = "QQQ"; break;
case "year": newData = profitData.multiYear.data; newCategories = profitData.multiYear.categories; newXaxisFormat = "yyyy"; break;
case "custom": newData = profitData.custom.data; newCategories = profitData.custom.categories; newXaxisFormat = "MMM dd"; break;
default: newData = profitData.yearly.data.slice(4, 10); newCategories = profitData.yearly.categories.slice(4, 10); newXaxisFormat = "MMMM"; break;
}
// Perbarui chart dengan data dan pengaturan baru (tanpa menggambar ulang dari awal).
profitTrendChart.updateOptions({
series: [{ data: newData }],
xaxis: { categories: newCategories },
tooltip: { x: { format: newXaxisFormat, }, },
});
// Perbarui juga tampilan persentase pertumbuhan dengan data yang baru.
updateGrowthDisplay(newData);
});
} else {
console.warn("Dropdown profit tidak ditemukan. Periksa ID di HTML.");
}
});
Penjelasan Alur Kode JavaScript (Perintah demi Perintah):
1. document.addEventListener("DOMContentLoaded", function () { ... });:
Seperti sebelumnya, ini memastikan seluruh halaman HTML kamu sudah selesai dimuat dan siap untuk dimanipulasi oleh JavaScript sebelum kode di dalamnya mulai berjalan.
2. profitData (Bank Data Profit):
- Ini adalah objek JavaScript yang menyimpan semua data profit kita untuk berbagai periode waktu (harian, mingguan, bulanan, kuartalan, tahunan, atau bahkan kustom).
- Setiap periode punya
data(angka profit) dancategories(label seperti "Jan", "Feb", "Mon", "Tue"). Data ini bersifat simulasi, di aplikasi nyata akan datang dari server.
3. calculateGrowth(currentValue, previousValue) (Si Penghitung Pertumbuhan):
- Fungsi kecil ini adalah "kalkulator" kita. Tugasnya sederhana: menghitung berapa persen profit naik atau turun dari satu titik ke titik berikutnya.
- Ia mengambil dua angka (profit saat ini dan profit sebelumnya) lalu menerapkan rumus persentase pertumbuhan. Ada juga logika untuk menangani kasus di mana profit sebelumnya adalah nol.
4. updateGrowthDisplay(data) (Si Pengubah Tampilan Pertumbuhan):
- Ini fungsi yang membuat persentase dan panah pertumbuhan di dashboard kita jadi hidup!
- Mencari Elemen: Pertama, ia mencari elemen HTML yang menampilkan persentase (
.presentase-growth) dan panah (#growthArrow). - Menghitung dan Menampilkan: Ia menggunakan data profit terbaru (
data) untuk memanggilcalculateGrowth. Hasilnya kemudian ditampilkan di elemen persentase. - Mengatur Warna dan Panah:
- Jika profit naik (
growth > 0), teks persentase akan hijau, dan panah menunjuk ke atas. - Jika profit turun (
growth < 0), teks persentase akan merah, dan panah menunjuk ke bawah. - Jika tidak ada perubahan, teks akan abu-abu dan panah akan terlihat datar.
- Jika profit naik (
- Ini memberikan umpan balik visual instan kepada pengguna tentang tren profit.
5. initialChartOptions (Blueprint Chart ApexCharts):
- Ini adalah objek raksasa yang berisi semua detail tentang bagaimana Line Chart kita harus terlihat dan berperilaku. Anggap saja ini daftar instruksi lengkap untuk ApexCharts.
chart: Bagian ini mengatur jenis chart (area- garis dengan area terisi di bawahnya), menyembunyikan toolbar bawaan ApexCharts agar lebih bersih, dan yang paling penting, adaevents: { mounted, updated }. Ini adalah "pemicu" yang akan memanggilupdateGrowthDisplaysetiap kali chart digambar pertama kali atau diperbarui, memastikan info pertumbuhan selalu akurat.series: Di sinilah data profit utama kita diletakkan. Kita beri nama "Profit" (meskipun tidak akan terlihat di tooltip) dan data awal yang diambil dari data tahunan (profitData.yearly).xaxisdanyaxis: Pengaturan untuk sumbu horizontal (waktu) dan vertikal (nilai profit). Kita tentukan labelnya (categories), rentang nilai (min,max), dan bagaimana label angkanya diformat (misal: "$50K").dataLabels: { enabled: false }: Ini menyembunyikan angka kecil di atas setiap titik data di garis chart, membuat chart terlihat lebih rapi.stroke: Mengatur tampilan garis chart (melengkungsmoothdan tebalnyawidth: 2).fill: Ini yang membuat area di bawah garis chart berwarna dan bergradasi (gradient). Sangat bagus untuk visualisasi!tooltip: Mengatur bagaimana pop-up info muncul saat kamu mengarahkan kursor ke garis chart. Kita kustomisasi agar label tanggalnya sesuai dan nilai profitnya diformat dengan tanda dolar. Baristitle.formatter: function (seriesName) { return ''; }ini sangat penting karena ini yang menyembunyikan nama seri "Profit" di tooltip, membuatnya lebih ringkas.colors: Menentukan warna garis chart kita (ungu).
6. Inisialisasi Chart (new ApexCharts(...) dan render()):
const profitTrendChart = new ApexCharts(document.querySelector("#profitTrendChart"), initialChartOptions);: Di baris ini, kita "meminta" ApexCharts untuk membuat chart. Kita memberitahunya untuk menggambar di dalam elemen HTML dengan IDprofitTrendChartdan menggunakan semua pengaturan yang sudah kita siapkan diinitialChartOptions.profitTrendChart.render();: Ini seperti tombol "Mulai Menggambar!". Chart akan langsung muncul di halaman web kamu.
7. Logika Interaktif (Menanggapi Dropdown):
document.addEventListener("DOMContentLoaded", () => { ... });: Sekali lagi, pastikan semua HTML sudah siap.const timeRangeSelector = document.getElementById("timeRangeSelectorLine");: Kita ambil elemen dropdown "Total Profit".- Initial Growth Display: Kita panggil
updateGrowthDisplayuntuk data awal agar info pertumbuhan langsung muncul saat halaman dimuat. timeRangeSelector.addEventListener("change", (event) => { ... });: Ini adalah "pendengar" utama kita. Setiap kali pengguna memilih opsi baru di dropdown, kode di dalamnya akan berjalan.switch (selectedValue): Ini seperti "penentu nasib" data kita. Berdasarkan pilihan pengguna (misal: "day", "week"), ia akan mengambil set data profit (newData), label sumbu X (newCategories), dan format tanggal/waktu yang sesuai (newXaxisFormat) dariprofitData.profitTrendChart.updateOptions({ ... });: Ini adalah fitur super dari ApexCharts! Daripada menghapus dan menggambar ulang seluruh chart (yang bisa bikin kedip), ApexCharts bisaupdateOptionssecara mulus. Kita hanya perlu memberinya data dan kategori yang baru, dan ApexCharts akan otomatis menyesuaikan garisnya. Kita juga perbarui format tooltip X-axis di sini.updateGrowthDisplay(newData);: Sangat penting! Setelah chart diperbarui dengan data baru, kita harus memanggilupdateGrowthDisplaylagi agar persentase pertumbuhan dan arah panah selalu mencerminkan data terbaru.
Dengan semua langkah ini, Line Chart "Total Profit" kamu tidak hanya terlihat profesional tetapi juga sangat interaktif, siap memberikan wawasan tentang kesehatan finansial kamu secara real-time.
Tips Pengembangan dan Peningkatan

Di sini, kita akan membahas bagaimana kamu bisa membawa dashboard yang sudah kita buat ini ke level selanjutnya, membuatnya lebih profesional, efisien, dan ramah pengguna.
Selamat! kamu sudah berhasil membangun dua visualisasi data interaktif yang keren untuk dashboard kamu. Tapi, perjalanan seorang developer tidak pernah berhenti. Selalu ada cara untuk membuat proyek kamu lebih baik, lebih kuat, dan lebih mudah digunakan. Bagian ini akan membahas beberapa tips penting untuk pengembangan dan peningkatan dashboard kamu.
⭐ Pengelolaan Data: Dari Data Dummy ke Data Nyata
Sejauh ini, kita menggunakan data simulasi (salesDataByTimeRange dan profitData) yang kita tulis langsung di kode JavaScript. Ini sangat bagus untuk belajar dan membangun prototipe. Namun, di dunia nyata, data kamu pasti datang dari sumber eksternal, biasanya dari sebuah API backend (Application Programming Interface).
1. Apa itu API Backend?
Bayangkan API backend sebagai "pelayan" yang siap melayani permintaan data kamu. Ketika aplikasi frontend (dashboard Anda) membutuhkan data penjualan terbaru, ia akan "memesan" data tersebut ke backend melalui API. Backend kemudian akan mengambil data dari database (misal: MySQL, PostgreSQL, MongoDB) dan "mengirimkannya" kembali ke frontend dalam format yang mudah dipahami, seperti JSON.
2. Langkah-langkah Integrasi Data Nyata:
1. Pilih Metode Pengambilan Data (Fetch/Axios):
fetch()API (Bawaan JavaScript): Ini adalah cara paling modern dan direkomendasikan untuk mengambil data dari server.- Axios (Pustaka Pihak Ketiga): Axios adalah pustaka populer yang menawarkan fitur lebih lengkap dan penanganan error yang lebih baik dibanding
fetch(), cocok untuk proyek yang lebih besar.
Contoh Penggunaan fetch():
// js/main-logic.js atau di dalam file chart.js yang relevan
async function fetchDataFromAPI(endpoint) {
try {
// Mengambil data dari alamat API tertentu
const response = await fetch(`https://api.yourdashboard.com/${endpoint}`); // Ganti dengan alamat API Anda
// Memeriksa apakah respons sukses (kode status 200-299)
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Mengubah respons menjadi format JSON
const data = await response.json();
return data; // Mengembalikan data yang sudah siap dipakai
} catch (error) {
console.error("Terjadi masalah saat mengambil data:", error);
// kamu bisa menampilkan pesan error ke user di sini
return null; // Kembalikan null atau data default jika error
}
}
// Contoh penggunaan saat memuat data untuk chart:
document.addEventListener("DOMContentLoaded", async function() {
// Ambil data penjualan bulanan dari API
const monthlySales = await fetchDataFromAPI('sales/month');
if (monthlySales) {
// Proses data yang didapat dari API dan gunakan untuk updateChart
// Misalnya, jika API mengembalikan { electronic: 50000, furniture: 30000, ... }
// kamu perlu memetakannya ke format yang diharapkan oleh chart kamu.
// updateChart(monthlySales); // Panggil fungsi update chart kamu dengan data baru
}
// Ambil data profit tahunan dari API
const yearlyProfit = await fetchDataFromAPI('profit/year');
if (yearlyProfit) {
// Proses data profit dan perbarui line chart
// profitTrendChart.updateSeries([{ data: yearlyProfit.data }]);
// updateGrowthDisplay(yearlyProfit.data);
}
});
- Penanganan Loading State:
Saat data sedang diambil dari API, browser mungkin butuh waktu beberapa detik. Penting untuk memberi tahu pengguna bahwa data sedang dimuat (misal: tampilkan teks "Loading..." atau ikon spinner). Sembunyikan spinner setelah data berhasil diambil atau jika terjadi error.
- Penanganan Error:
Apa yang terjadi jika API tidak merespons, ada masalah jaringan, atau data yang dikirim tidak sesuai? kamu harus siap:
- Tampilkan pesan error yang jelas kepada pengguna.
- Gunakan data default atau kosong agar chart tidak "rusak".
- Implementasikan mekanisme retry (coba lagi) jika itu adalah error sementara.
- Interval Refresh Data:
Untuk dashboard yang menampilkan data real-time atau sering berubah, kamu bisa mengatur agar data di-refresh secara otomatis setiap beberapa menit menggunakan setInterval().
setInterval(async () => {
console.log("Memperbarui data chart...");
const updatedSales = await fetchDataFromAPI('sales/month');
if (updatedSales) {
// updateChart(updatedSales);
}
// Lakukan hal yang sama untuk chart profit
}, 5 * 60 * 1000); // Refresh setiap 5 menit (5 * 60 detik * 1000 ms)
⭐ Kustomisasi Lanjutan: Tampilan Lebih Kaya
Anda sudah tahu dasar kustomisasi, tapi Chart.js dan ApexCharts punya banyak fitur tersembunyi yang bisa membuat chart kamu lebih informatif dan menarik.
1. Kustomisasi Lanjutan pada Chart.js (Donut Chart):
- Custom Plugins: Ini adalah fitur paling canggih di Chart.js. kamu bisa membuat "plugin" sendiri untuk menambahkan fungsi atau visualisasi yang tidak ada secara bawaan. Contohnya, teks di tengah Donut Chart yang sudah kita buat sebenarnya bisa diimplementasikan sebagai plugin Chart.js untuk modularitas yang lebih baik.
- Contoh: Menambahkan Teks Kustom di Tengah (sebagai Plugin)
// Dalam konfigurasi Chart.js Anda
plugins: [
{
id: 'centerText',
beforeDraw: function(chart) {
// Kode untuk menggambar teks di tengah
// Bisa diambil dari logic yang sudah ada di HTML/JS terpisah
// Ini lebih bersih dan reusabel
}
}
],
- Interaksi Kustom: kamu bisa menambahkan event listener ke elemen-elemen chart Chart.js untuk membuat interaksi yang lebih kompleks (misal: klik segmen donat untuk melihat detailnya di tabel lain).
2. Kustomisasi Lanjutan pada ApexCharts (Line Chart):
- Anotasi (Annotations): Sangat berguna untuk menandai peristiwa penting pada chart kamu (misal: peluncuran produk baru, promo besar, atau anomali data). Anotasi bisa berupa garis vertikal/horizontal atau teks di titik tertentu.
// Di options ApexCharts Anda annotations: { xaxis: [{ x: 'Jul', // Kategori di sumbu X borderColor: '#00E396', label: { borderColor: '#00E396', style: { color: '#fff', background: '#00E396', }, text: 'Product Launch', } }], // ... anotasi yaxis atau points }, - Zoom dan Pan: ApexCharts punya fitur zoom dan pan bawaan yang bisa diaktifkan untuk memungkinkan pengguna menjelajahi data dalam rentang waktu yang lebih detail.
// Di options ApexCharts Anda chart: { type: "area", toolbar: { show: true, // Tampilkan toolbar ApexCharts tools: { zoom: true, // Aktifkan zoom pan: true, // Aktifkan pan // ... lainnya } }, zoom: { enabled: true, // Aktifkan fungsi zoom }, }, - Multiple Series: kamu bisa menampilkan beberapa garis dalam satu chart (misal: profit kotor vs profit bersih, atau profit per wilayah) dengan menambahkan lebih banyak objek ke array
series.
⭐ Responsivitas: Tampilan di Berbagai Ukuran Layar
Dashboard kamu harus terlihat bagus tidak hanya di layar komputer besar, tetapi juga di tablet dan ponsel. Ini disebut responsivitas.
- Media Queries CSS: kamu sudah menggunakan Tailwind CSS yang sudah responsif secara default dengan kelas seperti
sm:,md:,lg:. kamu bisa menambahkan media queries kustom di CSS (style.css) untuk mengatur ulang tata letak atau ukuran elemen pada ukuran layar tertentu./* style.css */ @media (max-width: 768px) { /* Untuk layar di bawah 768px (misal: tablet, ponsel) */ .chart-container { padding: 1rem; /* Kurangi padding */ } .flex-container-dashboard { flex-direction: column; /* Ubah tata letak kolom menjadi baris di layar kecil */ } /* Sesuaikan ukuran font, margin, dll. */ } - Pengaturan
responsivepada Chart.js/ApexCharts:- Chart.js: kamu sudah menggunakan
responsive: truedanmaintainAspectRatio: false. Ini memastikan chart akan menyesuaikan ukurannya dengan wadah HTML-nya. - ApexCharts: Secara default, ApexCharts cukup responsif. kamu bisa mengatur lebar kontainer HTML (
<div id="profitTrendChart">) dengan CSS responsif, dan chart akan menyesuaikan diri.
- Chart.js: kamu sudah menggunakan
- Pengujian di Berbagai Perangkat: Gunakan developer tools di browser kamu (mode responsive design) atau uji langsung di berbagai perangkat fisik untuk memastikan semua terlihat baik.
⭐ Performa: Menangani Data Besar dengan Cepat
Jika dashboard kamu akan menampilkan data yang sangat besar (ribuan atau jutaan titik data), performa bisa menjadi masalah.
- Paginasi atau Infinite Scrolling: Jangan memuat semua data sekaligus! Tarik data sebagian-sebagian (misal: 1000 data terbaru) atau terapkan paginasi (halaman 1, halaman 2) atau infinite scrolling (memuat data saat pengguna menggulir ke bawah).
- Agregasi Data di Backend: Jika kamu menampilkan tren bulanan dari jutaan transaksi harian, minta backend untuk "meringkas" (mengagregasi) data tersebut menjadi total bulanan sebelum dikirim ke frontend. Jangan biarkan frontend melakukan semua kalkulasi berat.
- Debouncing / Throttling Event Listeners: Jika ada banyak event yang bisa memicu pembaruan chart (misal: resizing jendela browser), gunakan debouncing atau throttling. Ini akan membatasi seberapa sering fungsi pembaruan chart dipanggil, menghindari kinerja yang lambat.
- Debouncing: Fungsi hanya akan dijalankan setelah jeda waktu tertentu (misal: 300ms) setelah event terakhir terjadi.
- Throttling: Fungsi hanya akan dijalankan paling banyak sekali dalam periode waktu tertentu.
- Server-Side Rendering (SSR) atau Static Site Generation (SSG): Untuk dashboard yang sangat kompleks atau banyak pengunjung, pertimbangkan framework seperti React/Next.js atau Vue/Nuxt.js yang bisa merender halaman di sisi server. Ini mempercepat initial load karena pengguna langsung menerima HTML yang sudah terisi, bukan JavaScript kosong yang harus memuat data lagi.
⭐ Aksesibilitas: Dashboard untuk Semua Orang
Membuat dashboard yang mudah diakses oleh semua orang, termasuk mereka yang memiliki disabilitas, adalah praktik terbaik.
- Atribut ARIA (Accessible Rich Internet Applications): Ini adalah atribut HTML khusus yang memberikan informasi tambahan kepada teknologi asistif (seperti screen reader).
- **Untuk Chart Canvas (
<canvas>):**HTMLrole="img": Memberi tahu screen reader bahwa ini adalah gambar.aria-label="Nama chart yang deskriptif": Berikan deskripsi singkat tentang chart (misal: "Diagram batang penjualan bulanan").aria-describedby="ID_dari_tabel_atau_deskripsi_teks": Hubungkan chart dengan deskripsi teks yang lebih panjang atau tabel data di halaman yang sama. Ini sangat penting karena screen reader tidak bisa "melihat" chart.
<canvas id="myDoughnutChart" role="img" aria-label="Donut Chart Penjualan per Kategori" aria-describedby="sales-data-table"></canvas> <div id="sales-data-table" style="display:none;"> <table> <caption>Data Penjualan per Kategori Bulan Ini</caption> <thead> <tr><th>Kategori</th><th>Nilai Penjualan</th></tr> </thead> <tbody> <tr><td>Electronic</td><td>$50,000</td></tr> <tr><td>Furniture</td><td>$30,000</td></tr> </tbody> </table> </div> - Untuk Dropdown (
<select>):- Pastikan memiliki
<label>yang terhubung denganfor="ID_dropdown_nya". - Gunakan
aria-labelledbyjika labelnya bukan elemen<label>standar.
- Pastikan memiliki
- Navigasi Keyboard: Pastikan semua elemen interaktif (dropdown, tombol) bisa diakses dan digunakan hanya dengan keyboard (menggunakan tombol
Tab,Enter,Spacebar). - Kontras Warna: Pastikan kombinasi warna teks dan latar belakang memiliki kontras yang cukup tinggi agar mudah dibaca, terutama untuk pengguna dengan gangguan penglihatan. Gunakan alat pemeriksa kontras warna.
- Teks Alternatif (Alt Text) untuk Gambar: kamu sudah melakukannya untuk panah SVG, pastikan semua gambar (termasuk ikon) memiliki
alttext yang deskriptif.
Dengan menerapkan tips-tips ini, dashboard kamu tidak hanya akan terlihat mengesankan, tetapi juga akan menjadi aplikasi web yang lebih tangguh, efisien, dan dapat diakses oleh semua pengguna.
Studi Kasus & Sumber Belajar Terpercaya ( BuildWithAngga )

Bila kamu mau belajar lebih dalam dan lebih lanjut lagi aku saranin mengikuti kelas dari BuildWithAngga. BuildWithAngga punya pendekatan pembelajaran yang cukup beda dibanding platform belajar coding lainnya, terutama buat pemula dan orang yang suka belajar visual. Berikut beberapa hal yang bikin mereka menonjol:
⭐ Belajar dari Real Project, Bukan Teori Doang
Di BuildWithAngga, kamu gak cuma belajar sintaks, tapi langsung bikin project nyata kayak:
- Website portfolio modern
- Aplikasi booking seperti Tokopedia Travel
- Landing page profesional
- UI design pakai Figma
➡️ Jadi kamu langsung lihat hasilnya, bukan cuma hafalin kode.
⭐ Visual Interaktif & UI Keren
Mereka bener-bener fokus ke desain antarmuka yang kece:
- Kelas banyak yang berfokus pada Frontend (HTML, CSS, Tailwind, React)
- Desainnya modern dan sesuai tren industri
- Belajar coding sekaligus belajar taste desain
Cocok banget buat kamu yang pengin kerja sebagai UI/UX Developer.
⭐ Materi Up-to-date & Fokus ke Industri
BuildWithAngga ngikutin tren teknologi terbaru:
- Tailwind CSS, Next.js, Laravel 10
- Vercel deployment, GitHub versioning
- Animasi interaktif, Responsive Web Design
➡️ Gak belajar hal yang "jadul" dan kurang relevan.
⭐ Penjelasan Simpel, Bahasa Indonesia
Semua materi pakai bahasa Indonesia dengan gaya yang santai, receh tapi dalam, cocok banget buat kamu yang bosen dengan pembelajaran kaku dan textbook.
➡️ Gak bikin stres dan lebih mudah dipahami, terutama buat pemula.
⭐ Mentoring & Sertifikat Karier
- Bisa dapet sertifikat resmi
- Ada career mentoring buat bantu kamu masuk dunia kerja
- Kelas premium biasanya dilengkapi dengan review dari mentor
➡️ Jadi bukan sekadar belajar, tapi juga disiapkan untuk kerja.
Kalau kamu suka gaya belajar yang langsung "terjun ke lapangan", visual menarik, dan gampang dipahami, BuildWithAngga jelas beda dan cocok untuk kamu yang mau serius masuk dunia kreatif & digital.
Kesimpulan

Selamat! Kita telah menempuh perjalanan yang menarik dalam membangun sebuah dashboard interaktif dari nol.
⭐ Ringkasan Pencapaian:
Anda telah berhasil membangun sebuah dashboard yang kuat dan dinamis, mampu memvisualisasikan dua metrik bisnis krusial: data penjualan dan tren profit. Mari kita rekap pencapaian utama Anda:
- Dashboard Berbasis HTML/CSS (dengan Tailwind CSS): kamu telah menciptakan struktur dasar dashboard yang bersih dan responsif, memastikan tata letak yang menarik secara visual.
- Visualisasi Penjualan dengan Chart.js (Donut Chart):
- Anda sukses membuat Donut Chart yang menampilkan proporsi penjualan per kategori produk.
- Yang lebih penting, kamu berhasil membuatnya interaktif, memungkinkan pengguna untuk melihat data harian, mingguan, bulanan, kuartalan, hingga tahunan hanya dengan memilih dari dropdown.
- Anda juga menambahkan informasi total penjualan dan kunjungan, serta mengatur tampilan visual yang menarik seperti pola garis pada segmen "Electronic".
- Visualisasi Profit dengan ApexCharts (Line Chart):
- Anda berhasil mengintegrasikan Line Chart untuk menampilkan tren profit dari waktu ke waktu.
- Chart ini juga dibuat dinamis, memungkinkan perubahan rentang waktu dengan mudah.
- Anda menambahkan indikator pertumbuhan profit dengan persentase dan panah yang berubah arah serta warna, memberikan umpan balik instan tentang kondisi profit.
⭐ Manfaat Visualisasi Data yang Dinamis dan Mudah Dipahami:
Mengubah angka-angka mentah menjadi grafik yang interaktif seperti ini memberikan banyak manfaat:
- Pemahaman Cepat: Daripada menelusuri baris demi baris spreadsheet, grafik memungkinkan kamu menangkap tren, anomali, dan pola data hanya dalam hitungan detik.
- Pengambilan Keputusan Lebih Baik: Dengan wawasan yang jelas tentang kinerja penjualan dan profit, kamu dapat membuat keputusan bisnis yang lebih tepat dan berbasis data. Apakah perlu fokus pada produk tertentu? Periode mana yang paling menguntungkan? Semua terjawab visual.
- Komunikasi Efektif: Data yang divisualisasikan jauh lebih mudah dikomunikasikan kepada tim, manajemen, atau pemangku kepentingan lainnya, bahkan bagi mereka yang bukan ahli data.
- Identifikasi Masalah & Peluang: Grafik dinamis memungkinkan kamu dengan cepat menemukan lonjakan penjualan, penurunan profit yang tidak biasa, atau peluang pertumbuhan yang mungkin terlewat jika hanya melihat angka.
⭐ Potensi untuk Eksplorasi Lebih Lanjut dan Aplikasi di Proyek kamu Sendiri:
Apa yang telah kamu bangun ini hanyalah awal! Dashboard yang kamu ciptakan adalah fondasi yang kokoh untuk berbagai kemungkinan:
- Integrasi Data Nyata: Langkah selanjutnya yang paling penting adalah menghubungkan dashboard kamu ke sumber data backend yang sebenarnya, seperti database produk, sistem penjualan, atau API keuangan.
- Visualisasi Tambahan: kamu bisa menambahkan lebih banyak jenis chart (misal: bar chart untuk perbandingan antar produk, scatter plot untuk korelasi) dan metrik lain yang relevan dengan kebutuhan kamu (misal: jumlah pelanggan baru, biaya operasional, stok barang).
- Fitur Interaktif Lanjutan: Pertimbangkan fitur seperti filter data yang lebih kompleks, kemampuan untuk mengunduh chart sebagai gambar, atau bahkan kustomisasi tampilan oleh pengguna.
- Peningkatan UI/UX: Terus sempurnakan tampilan dan pengalaman pengguna agar dashboard semakin intuitif dan menyenangkan untuk digunakan.
- Aplikasi Lebih Luas: Prinsip-prinsip yang kamu pelajari di sini (mengelola data, menggunakan pustaka chart, membangun interaktivitas) dapat diterapkan pada berbagai proyek web lainnya, baik itu situs e-commerce, portal berita, atau aplikasi manajemen internal.
Semoga panduan ini memberikan kamu pemahaman yang kuat dan menginspirasi kamu untuk terus berkreasi dan mengeksplorasi dunia visualisasi data yang tak terbatas. Selamat berkarya!