Cara Menggambar Grafik Menggunakan JavaScript dan Canvas HTML5
Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)



Dalam tutorial ini, saya akan menunjukkan cara menggunakan JavaScript dan canvas sebagai sarana untuk menampilkan informasi numerik dalam bentuk diagram lingkaran dan diagram donat.
Ada cara yang lebih mudah untuk membuat grafik daripada mengkodekannya dari awal, misalnya pustaka grafik lengkap ini dari CodeCanyon.



Tapi jika Anda ingin tahu apa yang terjadi di balik layar di pustaka seperti ini, bacalah terus.
Apa itu Diagram Lingkaran?
Bagan adalah alat statistik yang digunakan untuk menerangkan data numerik secara grafis. Diagram lingkaran menampilkan data numerik sebagai lingkaran yang dibagi menjadi irisan-irisan. Ukuran masing-masing potongan sebanding dengan nilai numerik yang dimilikinya.
Apa itu Diagram Donat?
Singkatnya, diagram donat adalah variasi pada diagram lingkaran. Perbedaannya adalah irisan dipotong menuju pusat pie sehingga hanya bingkai yang terlihat. Dengan cara ini, bagan itu terlihat seperti donat dan oleh karena itulah namanya.
Mulai Menggambar dengan Canvas
Sebelum menggambar diagram lingkaran, kita akan melihat pada menggambar bagian-bagiannya. Kita akan melihat bagaimana kita bisa menggunakan komponen canvas dan JavaScript untuk menggambar:
- sebuah garis
- sebuah busur (bagian dari lingkaran)
- sebuah bentuk yang berisi warna
Untuk mulai menggambar menggunakan canvas HTML5, kita perlu membuat beberapa hal:
- Satu folder untuk menyimpan file proyek; mari kita sebut folder ini
piechart-tutorial
. - Satu file HTML
index.html
di dalam folderpiechart-tutorial
. File ini akan berisi kode HTML. - Satu file
script.js
di dalam folderpiechart-tutorial
. File ini akan berisi kode JavaScript kita.
Kita akan menjaga hal-hal sangat sederhana dan menambahkan kode berikut di dalam index.html
:
1 |
<html>
|
2 |
<body>
|
3 |
<canvas id="myCanvas"></canvas> |
4 |
<script type="text/javascript" src="script.js"></script> |
5 |
</body>
|
6 |
</html>
|
Kita memiliki elemen <canvas>
dengan ID myCanvas
sehingga kita bisa mereferensikannya dalam kode JS kita. Kita kemudian memuat kode JS melalui tag <script>
.
Di dalam script.js
, kode JS pertama akan mendapatkan referensi ke canvas dan kemudian mengatur lebar dan tingginya. Untuk menggambar di canvas, kita hanya memerlukan referensi ke konteks 2D yang berisi semua metode menggambar.
1 |
var myCanvas = document.getElementById("myCanvas"); |
2 |
myCanvas.width = 300; |
3 |
myCanvas.height = 300; |
4 |
|
5 |
var ctx = myCanvas.getContext("2d"); |
Setelah kita menyiapkan canvas dan juga mereferensikan ke canvas menggambar, mari kita definisikan beberapa fungsi JavaScript yang bisa kita gunakan kembali saat menggambar diagram lingkaran. Kita akan menambahkan fungsi di file script.js kita.
1 |
function drawLine(ctx, startX, startY, endX, endY){ |
2 |
ctx.beginPath(); |
3 |
ctx.moveTo(startX,startY); |
4 |
ctx.lineTo(endX,endY); |
5 |
ctx.stroke(); |
6 |
}
|
Fungsi drawLine
mengambil lima parameter:
-
ctx
: mengacu pada konteks gambar -
startX
: koordinat X dari titik awal garis -
startY
: koordinat Y dari titik awal garis
-
endX
: koordinat X dari titik akhir garis
-
endY
: koordinat Y dari titik akhir garis
Kita mulai menggambar garis dengan memanggil beginPath()
. Ini menginformasikan konteks gambar bahwa kita mulai menggambar sesuatu yang baru di atas canvas. Kita menggunakan moveTo()
untuk mengatur titik awal, panggilan lineTo()
untuk menunjukkan titik akhir, dan kemudian benar-benar menggambar dengan memanggil stroke()
.
Sekarang mari kita lihat bagaimana kita bisa menggambar bagian lingkaran, juga disebut busur.
1 |
function drawArc(ctx, centerX, centerY, radius, startAngle, endAngle){ |
2 |
ctx.beginPath(); |
3 |
ctx.arc(centerX, centerY, radius, startAngle, endAngle); |
4 |
ctx.stroke(); |
5 |
}
|
Fungsi drawArc
mengambil enam parameter:
-
ctx
: mengacu pada konteks gambar -
centerX
: koordinat X dari pusat lingkaran -
centerY
: koordinat Y dari pusat lingkaran -
radius
: koordinat X dari titik akhir garis -
startAngle
: sudut awal di radian dimana bagian lingkaran dimulai -
endAngle
: sudut akhir radian di mana bagian lingkaran berakhir
Kita telah melihat cara menggambar garis dan cara menggambar busur, jadi sekarang mari kita lihat cara menggambar bentuk yang berwarna. Karena tujuan kita adalah menggambar diagram lingkaran yang terdiri dari irisan-irisan, mari buat fungsi yang menggambar potongan lingkaran.
1 |
function drawPieSlice(ctx,centerX, centerY, radius, startAngle, endAngle, color ){ |
2 |
ctx.fillStyle = color; |
3 |
ctx.beginPath(); |
4 |
ctx.moveTo(centerX,centerY); |
5 |
ctx.arc(centerX, centerY, radius, startAngle, endAngle); |
6 |
ctx.closePath(); |
7 |
ctx.fill(); |
8 |
}
|
Fungsi drawPieSlice
mengambil tujuh parameter:
-
ctx
: mengacu pada konteks gambar -
centerX
: koordinat X dari pusat lingkaran -
centerY
: koordinat Y dari pusat lingkaran -
radius
: koordinat X dari titik akhir garis -
startAngle
: sudut awal di radian dimana bagian lingkaran dimulai -
endAngle
: sudut akhir radian di mana bagian lingkaran berakhir -
color
: warna yang digunakan untuk mengisi potongan
Berikut adalah contoh untuk memanggil tiga fungsi:
1 |
drawLine(_ctx,100,100,200,200); |
2 |
drawArc(_ctx, 150,150,150, 0, Math.PI/3); |
3 |
drawPieSlice(_ctx, 150,150,150, Math.PI/2, Math.PI/2 + Math.PI/4, '#ff0000'); |
Ini akan menghasilkan hasil ini:



Sekarang kita memiliki semua alat yang diperlukan untuk menggambar diagram lingkaran, jadi mari kita lihat bagaimana kita menggunakannya bersama-sama.
Menggambar Diagram Lingkaran
Secara konsep, setiap diagram memiliki dua bagian utama:
- Model data yang berisi data numerik untuk diwakili. Ini terstruktur dalam format yang khusus terhadap jenis diagram.
- Representasi grafisnya adalah bagaimana data numerik dalam model data digambarkan oleh elemen visual sesuai dengan beberapa peraturan dalam bentuk rumus matematika.
Model Data Diagram Lingkaran
Cara yang paling umum dari menyusun model data untuk diagram lingkaran adalah serangkaian kategori dan nilai yang sesuai, di mana masing-masing kategori dan nilai dikaitkan dengan potongan lingkaran.
Sebagai contoh, model data diagram lingkaran yang menampilkan jumlah vinyl yang telah dikelompokkan menurut genre akan terlihat seperti:
- Classical music: 10
- Alternative rock: 14
- Pop: 2
- Jazz: 12
Kita bisa menambahkan objek JS ke file script.js
untuk menyimpan data model seperti ini:
1 |
var myVinyls = { |
2 |
"Classical music": 10, |
3 |
"Alternative rock": 14, |
4 |
"Pop": 2, |
5 |
"Jazz": 12 |
6 |
};
|
Representasi Grafis Diagram Lingkaran
Diagram lingkaran menggunakan lingkaran untuk menampilkan informasi dalam model data dengan membaginya menjadi irisan-irisan. Setiap irisan sesuai dengan kategori dari model data, dan ukuran potongannya sebanding dengan nilai kategori.
Koleksi kecil saya dari 38 vinyl memiliki empat kategori. Setiap kategori akan mendapatkan sepotong pie chart sebanding dengan jumlah vinyl dalam kategori tersebut.
Tapi bagaimana kita mengukur ukuran potongannya? Itu mudah—kita melakukannya dengan sudut di ujung irisan. Yang harus kita ketahui adalah bahwa lingkaran penuh sesuai dengan sudut 360 derajat
atau 2 * PI
. Jadi setengah lingkaran akan menjadi 180 derajat
atau PI
, seperempat 90 derajat
atau PI/2
, dan seterusnya.
Untuk menentukan sudut untuk setiap slice kategori, kita menggunakan rumus:
sudut potongan = 2 * PI * nilai kategori / nilai total
Menurut rumus ini, sepuluh vinyl classical music akan mendapatkan sudut iris kira-kira 0,526 * PI atau 94 derajat.
Mari kita menggambar. Untuk ini kita akan menggunakan kelas JavaScript yang akan kita beri nama Piechart
. Constructor akan menerima satu argumen opsi, sebuah objek yang berisi yang berikut ini:
- canvas: mengacu ke canvas dimana kita ingin menggambar diagram lingkaran
- data: mengacu pada objek yang memegang model data
- colors: array yang memegang warna-warna yang ingin kita gunakan untuk setiap irisan
Kelas Piechart
juga berisi satu metode draw()
yang menggambarkan diagram sebenarnya.
1 |
var Piechart = function(options){ |
2 |
this.options = options; |
3 |
this.canvas = options.canvas; |
4 |
this.ctx = this.canvas.getContext("2d"); |
5 |
this.colors = options.colors; |
6 |
|
7 |
this.draw = function(){ |
8 |
var total_value = 0; |
9 |
var color_index = 0; |
10 |
for (var categ in this.options.data){ |
11 |
var val = this.options.data[categ]; |
12 |
total_value += val; |
13 |
}
|
14 |
|
15 |
var start_angle = 0; |
16 |
for (categ in this.options.data){ |
17 |
val = this.options.data[categ]; |
18 |
var slice_angle = 2 * Math.PI * val / total_value; |
19 |
|
20 |
drawPieSlice( |
21 |
this.ctx, |
22 |
this.canvas.width/2, |
23 |
this.canvas.height/2, |
24 |
Math.min(this.canvas.width/2,this.canvas.height/2), |
25 |
start_angle, |
26 |
start_angle+slice_angle, |
27 |
this.colors[color_index%this.colors.length] |
28 |
);
|
29 |
|
30 |
start_angle += slice_angle; |
31 |
color_index++; |
32 |
}
|
33 |
|
34 |
}
|
35 |
}
|
Kelas dimulai dengan menyimpan options
yang diberikan sebagai parameter. Ini menyimpan referensi canvas
dan menciptakan konteks gambar juga disimpan sebagai anggota kelas. Kemudian ia menyimpan array colors
yang disampaikan sebagai opsi.
Bagian selanjutnya adalah yang paling konsisten, fungsi draw()
. Ini akan menarik data dari model data. Pertama, menghitung jumlah semua nilai dalam model data. Kemudian, untuk setiap kategori dalam model data kita menerapkan rumus yang disebutkan di atas untuk menghitung sudut potongan lingkaran. Akhirnya kita menggunakan fungsi drawPieSlice()
menggunakan pusat canvas sebagai pusat potongan. Untuk radius kita menggunakan nilai minimum antara setengah dari lebar canvas dan setengah dari tinggi canvas karena kita tidak ingin lingkaran kita keluar dari canvas.
Kita juga memberi offset sudut awal dan akhir irisan setiap kali kita menggambar kategori, jika tidak, irisannya akan tumpang tindih.
Untuk menggunakan kelas, kita harus membuat sebuah instance dan kemudian memanggil metode draw()
pada objek yang dibuat.
1 |
var myPiechart = new Piechart( |
2 |
{
|
3 |
canvas:myCanvas, |
4 |
data:myVinyls, |
5 |
colors:["#fde23e","#f16e23", "#57d9ff","#937e88"] |
6 |
}
|
7 |
);
|
8 |
myPiechart.draw(); |
Dan hasilnya terlihat seperti ini



Menggambar Diagram Donat
Kita telah melihat cara menggambar diagram lingkaran. Kita juga tahu bahwa diagram donat berbeda hanya dengan memiliki lubang di tengah diagram. Bagaimana kita menggambar lubangnya? Kita bisa menggambar lingkaran putih di atas pie chart.
Mari kita ubah kode kelas Piechart
untuk melakukan itu.
1 |
var Piechart = function(options){ |
2 |
this.options = options; |
3 |
this.canvas = options.canvas; |
4 |
this.ctx = this.canvas.getContext("2d"); |
5 |
this.colors = options.colors; |
6 |
|
7 |
this.draw = function(){ |
8 |
var total_value = 0; |
9 |
var color_index = 0; |
10 |
for (var categ in this.options.data){ |
11 |
var val = this.options.data[categ]; |
12 |
total_value += val; |
13 |
}
|
14 |
|
15 |
var start_angle = 0; |
16 |
for (categ in this.options.data){ |
17 |
val = this.options.data[categ]; |
18 |
var slice_angle = 2 * Math.PI * val / total_value; |
19 |
|
20 |
drawPieSlice( |
21 |
this.ctx, |
22 |
this.canvas.width/2, |
23 |
this.canvas.height/2, |
24 |
Math.min(this.canvas.width/2,this.canvas.height/2), |
25 |
start_angle, |
26 |
start_angle+slice_angle, |
27 |
this.colors[color_index%this.colors.length] |
28 |
);
|
29 |
|
30 |
start_angle += slice_angle; |
31 |
color_index++; |
32 |
}
|
33 |
|
34 |
//drawing a white circle over the chart
|
35 |
//to create the doughnut chart
|
36 |
if (this.options.doughnutHoleSize){ |
37 |
drawPieSlice( |
38 |
this.ctx, |
39 |
this.canvas.width/2, |
40 |
this.canvas.height/2, |
41 |
this.options.doughnutHoleSize * Math.min(this.canvas.width/2,this.canvas.height/2), |
42 |
0, |
43 |
2 * Math.PI, |
44 |
"#ff0000" |
45 |
);
|
46 |
}
|
47 |
|
48 |
}
|
49 |
}
|
Kode tambahannya terlihat pada parameter options
untuk variabel anggota doughnutHoleSize
. Jika ini tidak ada dalam opsi maka kode tersebut akan menggambar diagram lingkaran seperti sebelumnya, tapi jika memang ada maka lingkaran putih digambar dengan pusat yang sama dengan diagram lingkaran.
Jari-jari lingkaran ditentukan dengan mengalikan radius diagram lingkaran dan nilai doughnutHoleSize
. Ini harus berupa angka antara 0 dan 1, di mana 0 akan menghasilkan diagram lingkaran dan nilai yang lebih tinggi dari 0 akan menghasilkan donat dengan lubang lebih besar dan lebih besar, 1 membuat diagram tidak terlihat.
Untuk menggambar diagram donat dengan ukuran lubang setengah dari diagram, kita perlu menggunakan doughnutHoleSize
sebesar 0.5 dan membuat panggilan berikut:
1 |
var myDougnutChart = new Piechart( |
2 |
{
|
3 |
canvas:myCanvas, |
4 |
data:myVinyls, |
5 |
colors:["#fde23e","#f16e23", "#57d9ff","#937e88"], |
6 |
doughnutHoleSize:0.5 |
7 |
}
|
8 |
);
|
9 |
myDougnutChart.draw(); |
Dan inilah hasilnya:



Menambahkan Label dan Legenda Diagram
Diagram lingkaran dan diagram donat kita terlihat cukup bagus, namun kita dapat membuatnya lebih baik dengan menambahkan dua hal:
- value labels: menunjukkan persentase yang sesuai dengan setiap irisan
- legenda diagram: menunjukkan kategori dan warna yang sesuai dalam diagram
Biasanya, nilai yang terkait dengan irisan direpresentasikan sebagai nilai persentase yang dihitung sebagai 100 * nilai yang terkait dengan nilai potongan / total
, dengan keseluruhan lingkaran mewakili 100%
.
Sebagai contoh, dalam kasus data sampel kita, vinyl dengan classical music akan mewakili sekitar 26%
. Alangkah baiknya bisa menulis nilai itu pada potongan yang sesuai. Untuk melakukannya, kita akan menggunakan fungsi fillText(text,x,y)
dari konteks gambar. Fungsi ini mengambil tiga parameter: teks beserta koordinat x
dan y
.
Bagaimana kita menghitung koordinat x
dan y
untuk menempatkan teks? Kita harus menggunakan beberapa pengetahuan geometri dan sesuatu yang disebut koordinat kutub. Pada dasarnya, koordinat kutub menggunakan radius dan sudut untuk menentukan posisi sebuah titik. Dua rumus yang akan kita gunakan adalah:
x = R * cos(angle)
y = R * sin(angle)
Kita akan menerapkan dua rumus ini untuk menempatkan teks di tengah lingkaran sepanjang radius diagram lingkaran dan setengah di sekitar sudut untuk setiap irisan lingkaran. Untuk melakukannya, kita perlu memodifikasi kelas Piechart
dan menambahkan kode berikut tepat setelah blok if (this.options.doughnutHoleSize){...}
:
1 |
...
|
2 |
start_angle = 0; |
3 |
for (categ in this.options.data){ |
4 |
val = this.options.data[categ]; |
5 |
slice_angle = 2 * Math.PI * val / total_value; |
6 |
var pieRadius = Math.min(this.canvas.width/2,this.canvas.height/2); |
7 |
var labelX = this.canvas.width/2 + (pieRadius / 2) * Math.cos(start_angle + slice_angle/2); |
8 |
var labelY = this.canvas.height/2 + (pieRadius / 2) * Math.sin(start_angle + slice_angle/2); |
9 |
|
10 |
if (this.options.doughnutHoleSize){ |
11 |
var offset = (pieRadius * this.options.doughnutHoleSize ) / 2; |
12 |
labelX = this.canvas.width/2 + (offset + pieRadius / 2) * Math.cos(start_angle + slice_angle/2); |
13 |
labelY = this.canvas.height/2 + (offset + pieRadius / 2) * Math.sin(start_angle + slice_angle/2); |
14 |
}
|
15 |
|
16 |
var labelText = Math.round(100 * val / total_value); |
17 |
this.ctx.fillStyle = "white"; |
18 |
this.ctx.font = "bold 20px Arial"; |
19 |
this.ctx.fillText(labelText+"%", labelX,labelY); |
20 |
start_angle += slice_angle; |
21 |
}
|
22 |
...
|
Kode berjalan di atas setiap irisan, menghitung persentase, menghitung posisi, dan menggunakan metode fillText()
untuk menggambarnya di diagram. Kita telah menggunakan properti fillStyle
untuk mengatur warna teks menjadi putih dan properti font
untuk mengatur ukuran, gaya dan font family dari label. Penting juga untuk dicatat bahwa jika diagram adalah diagram donat dan doughnutHoleSize
ditetapkan, maka label akan terdorong ke arah tepi bagan agar dipusatkan pada potongan donat.
Dan inilah bagaimana diagram yang dihasilkan terlihat dengan label nilai:



Untuk melengkapi diagram kita, hal terakhir yang akan kita tambahkan adalah legenda diagram. Legenda diagram kita akan menampilkan kategori model data kita dan warna yang digunakan untuk potongan yang sesuai. Pertama kita harus membuat beberapa modifikasi pada file index.html
kita dengan menambahkan tag <div>
yang akan menyimpan elemen legenda kita.
1 |
<html>
|
2 |
<body>
|
3 |
<canvas id="myCanvas"></canvas> |
4 |
<div id="myLegend"></div> |
5 |
<script type="text/javascript" src="script.js"></script> |
6 |
</body>
|
7 |
</html>
|
Kemudian di script.js
kita tambahkan kode yang membuat konten elemen legenda. Kita menambahkan kode ini di akhir fungsi draw()
dari kelas Piechart
:
1 |
...
|
2 |
if (this.options.legend){ |
3 |
color_index = 0; |
4 |
var legendHTML = ""; |
5 |
for (categ in this.options.data){ |
6 |
legendHTML += "<div><span style='display:inline-block;width:20px;background-color:"+this.colors[color_index++]+";'> </span> "+categ+"</div>"; |
7 |
}
|
8 |
this.options.legend.innerHTML = legendHTML; |
9 |
}
|
10 |
...
|
Kode tersebut mencari elemen legend
yang disampaikan melalui parameter options
. Jika salah satu disediakan, elemen ini diisi dengan kode HTML yang berisi kotak berwarna dan nama kategori model data.
Kita juga perlu membuat perubahan seperti yang kita panggil penggambaran diagram lingkaran kita seperti ini:
1 |
var myLegend = document.getElementById("myLegend"); |
2 |
|
3 |
var myDougnutChart = new Piechart( |
4 |
{
|
5 |
canvas:myCanvas, |
6 |
data:myVinyls, |
7 |
colors:["#fde23e","#f16e23", "#57d9ff","#937e88"], |
8 |
legend:myLegend |
9 |
}
|
10 |
);
|
11 |
myDougnutChart.draw(); |
Dan inilah diagram dan legenda diagram yang dihasilkan:



Selamat
Kita telah melihat bahwa menggambar diagram menggunakan canvas HTML5 sebenarnya tidak terlalu sulit. Ini hanya membutuhkan sedikit matematika dan sedikit pengetahuan JavaScript. Anda sekarang memiliki semua yang Anda butuhkan untuk menggambar diagram lingkaran dan diagram donat Anda sendiri.
Jika Anda menginginkan solusi cepat dan mudah untuk tidak hanya membuat diagram lingkaran dan diagram donat tapi juga banyak jenis diagram lainnya, Anda dapat men-download Infographic Charts and Graphics HTML Tags Library atau plugin WordPress pasangannya Charts and Graphs WordPress Visual Designer.