Highcharts.js คือไลบรารี JavaScript ที่ได้รับความนิยมอย่างสูงสำหรับสร้างกราฟและแผนภูมิแบบโต้ตอบ (Interactive) บนหน้าเว็บไซต์ พัฒนาขึ้นโดยบริษัท Highsoft จากนอร์เวย์ จุดเด่นของ Highcharts คือความง่ายในการใช้งาน เอกสารประกอบที่ละเอียดและเข้าใจง่าย และรองรับกราฟหลากหลายประเภท ตั้งแต่กราฟเส้น, กราฟแท่ง, กราฟวงกลม ไปจนถึงกราฟที่มีความซับซ้อนสูงอย่าง Gantt charts และ Maps
ด้วยความสามารถในการปรับแต่งที่ยืดหยุ่นและการทำงานร่วมกับเฟรมเวิร์กสมัยใหม่ได้ดี เช่น React, Angular, และ Vue.js ทำให้ Highcharts เป็นเครื่องมือที่ทรงพลังสำหรับนักพัฒนาในการนำเสนอข้อมูลที่ซับซ้อนให้อยู่ในรูปแบบที่สวยงามและเข้าใจง่าย
สำหรับนักศึกษาที่มีพื้นฐาน HTML, Bootstrap 5, และ JQuery/AJAX อยู่แล้ว การเรียนรู้ Highcharts จะเป็นก้าวสำคัญในการยกระดับการแสดงผลข้อมูลในโปรเจกต์ของตนเอง จากตารางข้อมูลธรรมดาไปสู่ Dashboard ที่สามารถวิเคราะห์ข้อมูลเชิงลึกได้
การเริ่มต้นใช้งาน Highcharts นั้นตรงไปตรงมา โดยวิธีที่ง่ายที่สุดสำหรับผู้เริ่มต้นคือการเรียกใช้งานไลบรารีผ่าน Content Delivery Network (CDN)
เราสามารถเพิ่ม Highcharts เข้าไปในโปรเจกต์ได้โดยการเพิ่มแท็ก <script> ในส่วน <head> ของไฟล์ HTML ดังนี้
<!-- 1. JQuery (จำเป็นสำหรับตัวอย่างบางส่วน) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- 2. Highcharts Core -->
<script src="https://code.highcharts.com/highcharts.js"></script>
<!-- 3. Highcharts Modules (ถ้าต้องการใช้งานฟีเจอร์เสริม) -->
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
จากโค้ดด้านบน เราได้เรียกใช้ไฟล์หลักของ Highcharts และโมดูลเสริม 2 ตัวคือ exporting.js สำหรับการส่งออกกราฟเป็นรูปภาพหรือ PDF และ accessibility.js เพื่อให้ผู้ใช้งานที่มีความบกพร่องสามารถเข้าถึงข้อมูลในกราฟได้ง่ายขึ้น
ในการแสดงผลกราฟ เราจำเป็นต้องมี Element บนหน้าเว็บเพื่อใช้เป็น "พื้นที่" สำหรับวาดกราฟ โดยทั่วไปเราจะใช้ <div> ที่มี id เฉพาะ
<!DOCTYPE html>
<html lang="th">
<head>
<title>My First Highcharts Chart</title>
<!-- ... script tags from above ... -->
</head>
<body>
<!-- พื้นที่สำหรับแสดงกราฟ -->
<div id="chart-container" style="width:100%; height:400px;"></div>
<script>
// โค้ด JavaScript สำหรับสร้างกราฟจะอยู่ที่นี่
</script>
</body>
</html>
เมื่อเตรียมหน้าเว็บพร้อมแล้ว เราสามารถสร้างกราฟแรกได้ด้วยฟังก์ชัน Highcharts.chart() โดยส่งพารามิเตอร์ 2 ตัว คือ id ของ container และอ็อบเจ็กต์การกำหนดค่า (Configuration Object) ซึ่งเป็นหัวใจสำคัญของ Highcharts
Highcharts.chart('chart-container', {
chart: {
type: 'column' // ประเภทของกราฟ
},
title: {
text: 'ยอดขายผลไม้รายเดือน' // ชื่อหัวข้อของกราฟ
},
xAxis: {
categories: ['ม.ค.', 'ก.พ.', 'มี.ค.'] // ป้ายกำกับแกน X
},
yAxis: {
title: {
text: 'จำนวน (ผล)' // ชื่อแกน Y
}
},
series: [{
name: 'แอปเปิ้ล',
data: [120, 150, 130] // ข้อมูลของ Series ที่ 1
}, {
name: 'ส้ม',
data: [80, 90, 110] // ข้อมูลของ Series ที่ 2
}]
});
โค้ดนี้จะสร้างกราฟแท่งเปรียบเทียบยอดขายแอปเปิ้ลและส้มใน 3 เดือนแรกของปี
ใน Lab นี้ เราจะฝึกดึงข้อมูลคุณภาพอากาศ (PM2.5) จาก API ภายนอกด้วย AJAX และนำมาแสดงผลเป็นกราฟเส้น (Line Chart) เพื่อติดตามแนวโน้มของค่าฝุ่นในช่วงเวลาต่างๆ ซึ่งเป็นทักษะสำคัญในการสร้าง Dashboard สำหรับติดตามข้อมูล
เราจะใช้ข้อมูลจาก AirVisual ซึ่งเป็นบริการข้อมูลคุณภาพอากาศทั่วโลก หรือ Air4Thai ในตัวอย่างนี้ เราจะจำลองการตอบกลับของ API เพื่อให้ง่ายต่อการเรียนรู้ โดยโครงสร้างข้อมูล JSON ที่ได้รับจะมีลักษณะดังนี้:
[
{
DATETIMEDATA: "2026-01-06",
AQI: "50",
PM25: "25.0",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2026-01-05",
AQI: "64",
PM25: "28.5",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2026-01-04",
AQI: "50",
PM25: "25.0",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2026-01-03",
AQI: "44",
PM25: "22.6",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2026-01-02",
AQI: "83",
PM25: "33.2",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2026-01-01",
AQI: "139",
PM25: "51.8",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
},
{
DATETIMEDATA: "2025-12-31",
AQI: "95",
PM25: "36.3",
PM10: "-1",
CO: "-1",
O3: "-1",
SO2: "-1",
NO2: "-1"
}
]
ข้อมูลที่เราสนใจคือ PM25 หรือ PM10 หรือ AQI
เราจะใช้ JQuery AJAX ในการดึงข้อมูล และแปลงให้อยู่ในรูปแบบที่ Highcharts ในที่นี้เรามีไฟล์ js/pm25.js ซึ่งมีฟังก์ชันที่ใช้เรียกข้อมูลอยู่แล้วดังนี้
function fetchAirQualityData(station) {
$.ajax({
url: 'http://air4thai.com/forweb/getStationData.php?stationID=' + station, // Replace with actual API endpoint
method: 'GET',
beforeSend: function() {
console.log("Fetching air quality data...");
},
success: function(data) {
console.log("Data fetched successfully:", data);
console.log("AQI:", data[0].AQI);
console.log("PM2.5:", data[0].PM25);
console.log("PM10:", data[0].PM10);
console.log("Data Time:", data[0].DATETIMEDATA);
$('#_station').text(station);
$('#aqi-value').text(data[0].AQI);
$('#pm25-value').text(data[0].PM25);
$('#pm10-value').text(data[0].PM10);
$('#data-time').text(data[0].DATETIMEDATA);
// Process and display the data on the webpage
let aqiValue = parseInt(data[0].AQI);
setAQICardColor(aqiValue, '#aqiCard');
},
error: function(error) {
console.error("Error fetching data:", error);
}
});
}
ก่อนอื่นให้เราปรับแต่ง div ในหน้า index.html ของเราให้พร้อมก่อน โดยการปรับแต่งข้อมูลทั้งหมดให้เป็นดังนี้
<!DOCTYPE html>
<html lang="th">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous" />
<title>Frontend Framework class</title>
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider" /></li>
<li>
<a class="dropdown-item" href="#">Something else here</a>
</li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
<button class="btn btn-outline-success" type="submit">
Search
</button>
</form>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-3" style="padding: 10px">
<div id="aqiCard" class="card h-100" style="background-color: white">
<!-- h-100 ทำให้การ์ดทุกใบสูงเท่ากัน -->
<div align="center">
<img src="images/air-quality.png" style="width: 100px; height: 100px; margin: 10px" class="card-img-top" />
</div>
<div class="card-body">
<h6>สถานีตรวจวัด: <font id="_station">...</font></h6>
<h5 class="card-title">AQI: <font id="aqi-value">...</font></h5>
<p class="card-text">
PM2.5: <font id="pm25-value">45</font> µg/m³<br />
PM10: <font id="pm10-value">80</font> µg/m³<br />
ข้อมูล ณ <font id="data-time">...</font>
</p>
<a href="#" class="btn btn-primary">ดูรายละเอียด</a>
</div>
</div>
</div>
<div class="col-lg-9 col-md-9" style="padding: 10px">
<div class="card h-100">
<!-- h-100 ทำให้การ์ดทุกใบสูงเท่ากัน -->
<div id="chartPM"></div>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<!-- Highcharts -->
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<script src="https://code.highcharts.com/themes/adaptive.js"></script>
<script src="js/pm25.js"></script>
</body>
</html>สังเกต <div id="chartPM"></div> ซึ่งเป็นส่วนสำคัญในการอ้างอิงถึงในลำดับถัดไป
ในไฟล์ js/pm25.js ให้ทำการเพิ่มฟังก์ชันต่อไปนี้
function createChartPm() {
Highcharts.chart('chartPM', {
chart: {
type: 'line'
},
title: {
text: 'แนวโน้มค่าคุณภาพอากาศ (PM25, PM10)'
},
subtitle: {
text: 'Source: ' + '<a href="http://air4thai.com/" target="_blank">Air4Thai</a>'
},
xAxis: {
categories: [
'2025-12-31',
'2025-01-01',
'2025-01-02',
'2025-01-03',
'2025-01-04',
'2025-01-05',
'2025-01-06'
]
},
yAxis: {
title: {
text: 'µg/m³'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: true
}
},
series: [{
name: 'PM2.5',
data: [16.0, 18.2, 23.1, 27.9, 32.2, 36.4, 39.8]
}, {
name: 'PM10',
data: [17.0, 18.2, 25.1, 32.9, 36.2, 38.4, 38.8]
}]
});
}และเพิ่มเติม ในส่วนของ AJAX ที่เราเรียกใช้ในส่วนของ success event ดังนี้
ในส่วนของ success event ให้ทำการเพิ่มคำสั่ง createChartPm(); เพื่อประมวลผลค่า AQI และเรียกฟังก์ชันสร้างกราฟดังนี้:
let aqiValue = parseInt(data[0].AQI);
setAQICardColor(aqiValue, '#aqiCard');
//ส่วนที่เพิ่มเติม
createChartPm();createChartPm();
ทดลองรันดู ผลลัพธ์จะต้องได้กราฟดังรูป

เมื่อได้กราฟดังกล่าวแล้ว ขั้นตอนต่อไปเราต้องนำข้อมูลที่ได้จาก Air4Thai มาใช้งานจริง ๆ โดยสามารถจัดเตรียมข้อมูลก่อนได้ด้วยฟังก์ชัน preparePmChartData(); และส่วนของตัวแปรอื่น ๆ ที่เกี่ยวข้อง
ทั้งนี้ source code ส่วนสมบูรณ์ได้ดังนี้
// pm25.js
$(document).ready(function () {
console.log("DOM is ready!");
fetchAirQualityData('19t'); // สถานีที่ 19
});
var dataDate = [];
var dataPm25 = [];
var dataPm10 = [];
function fetchAirQualityData(station) {
$.ajax({
url: 'http://air4thai.com/forweb/getStationData.php?stationID=' + station,
method: 'GET',
beforeSend: function () {
console.log("Fetching air quality data...");
},
success: function (data) {
console.log("Data fetched successfully:", data);
$('#_station').text(station);
$('#aqi-value').text(data[0].AQI);
$('#pm25-value').text(data[0].PM25);
$('#pm10-value').text(data[0].PM10);
$('#data-time').text(data[0].DATETIMEDATA);
let aqiValue = parseInt(data[0].AQI);
setAQICardColor(aqiValue, '#aqiCard');
preparePmChartData(data);
createChartPm();
},
error: function (error) {
console.error("Error fetching data:", error);
}
});
}
function setAQICardColor(aqi, cardSelector) {
let bgColor = '';
let textColor = '#000';
if (aqi <= 50) {
bgColor = '#00e400'; // Green
} else if (aqi <= 100) {
bgColor = '#ffff00'; // Yellow
} else if (aqi <= 150) {
bgColor = '#ff7e00'; // Orange
} else if (aqi <= 200) {
bgColor = '#ff0000'; // Red
textColor = '#fff';
} else if (aqi <= 300) {
bgColor = '#8f3f97'; // Purple
textColor = '#fff';
} else {
bgColor = '#7e0023'; // Maroon
textColor = '#fff';
}
$(cardSelector).css({
'background-color': bgColor,
'color': textColor
});
}
function createChartPm() {
Highcharts.chart('chartPM', {
chart: {
type: 'line'
},
title: {
text: 'แนวโน้มค่าคุณภาพอากาศ (PM25, PM10)'
},
subtitle: {
text: 'Source: ' + '<a href="http://air4thai.com/" target="_blank">Air4Thai</a>'
},
xAxis: {
categories: dataDate
},
yAxis: {
title: {
text: 'µg/m³'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: true
}
},
series: [{
name: 'PM2.5',
data: dataPm25
}, {
name: 'PM10',
data: dataPm10
}]
});
}
function preparePmChartData(apiData) {
dataDate = [];
dataPm25 = [];
dataPm10 = [];
// เรียงข้อมูลจากเก่า → ใหม่ (Highcharts อ่านง่าย)
apiData.sort((a, b) => new Date(a.DATETIMEDATA) - new Date(b.DATETIMEDATA));
apiData.forEach(item => {
dataDate.push(item.DATETIMEDATA);
dataPm25.push(item.PM25 !== "-1" ? parseFloat(item.PM25) : null);
dataPm10.push(item.PM10 !== "-1" ? parseFloat(item.PM10) : null);
});
}เมื่อข้อมูลพร้อมแล้ว เราจะนำไปสร้างกราฟเส้นแบบ Spline (เส้นโค้ง) เพื่อให้ดูสวยงาม พร้อมทั้งกำหนดแกน X ให้เป็นรูปแบบเวลา (datetime)
Lab นี้จะเน้นการสร้างกราฟวงกลม (Pie Chart) เพื่อแสดงสัดส่วนของข้อมูล ซึ่งมักใช้ในรายงานสรุป เช่น สัดส่วนยอดขายตามประเภทสินค้า หรือส่วนแบ่งการตลาด เราจะเรียนรู้วิธีการเตรียมข้อมูลจากฝั่ง Backend (จำลองด้วย PHP) และนำมาแสดงผล
กราฟวงกลมต้องการข้อมูลในรูปแบบเฉพาะ คือ Array ของอ็อบเจ็กต์ที่มี property name และ y เราสามารถเขียนสคริปต์ PHP เพื่อดึงข้อมูลจากฐานข้อมูลและแปลงเป็น JSON ในรูปแบบนี้ได้
ตัวอย่างไฟล์ get_sales_data.php:
<?php
// ตั้งค่า Header ให้เป็น JSON
header('Content-Type: application/json');
// จำลองการเชื่อมต่อฐานข้อมูลและดึงข้อมูล
// ในสถานการณ์จริง จะเป็นการ query จาก MySQL
$db_result = [
['product_type' => 'เครื่องเขียน', 'total_sales' => 45000],
['product_type' => 'อุปกรณ์ IT', 'total_sales' => 78000],
['product_type' => 'หนังสือ', 'total_sales' => 32000],
['product_type' => 'อื่นๆ', 'total_sales' => 15000]
];
$data_for_chart = [];
foreach ($db_result as $row) {
$data_for_chart[] = [
'name' => $row['product_type'],
'y' => (int)$row['total_sales']
];
}
// ส่งข้อมูลกลับในรูปแบบ JSON
echo json_encode($data_for_chart);
?>
สคริปต์นี้จะสร้าง JSON output ที่มีโครงสร้างดังนี้ ซึ่งพร้อมสำหรับ Highcharts Pie Chart:
[
{"name":"เครื่องเขียน","y":45000},
{"name":"อุปกรณ์ IT","y":78000},
{"name":"หนังสือ","y":32000},
{"name":"อื่นๆ","y":15000}
]
ฝั่ง Frontend เราจะใช้ $.getJSON เพื่อดึงข้อมูลจาก PHP script แล้วนำไปใส่ใน series.data ของ Pie Chart
Lab สุดท้ายนี้ท้าทายที่สุด คือการสร้างกราฟที่อัปเดตข้อมูลเองโดยอัตโนมัติ (Live/Real-time Chart) เหมาะสำหรับการแสดงผลข้อมูลที่เปลี่ยนแปลงตลอดเวลา เช่น ราคาหุ้น, อุณหภูมิจากเซ็นเซอร์, หรือจำนวนผู้ใช้งานออนไลน์
หลักการคือการสร้างฟังก์ชันที่ดึงข้อมูลใหม่จากเซิร์ฟเวอร์เป็นระยะๆ ผ่าน AJAX จากนั้นใช้เมธอด series.addPoint() ของ Highcharts เพื่อเพิ่มจุดข้อมูลใหม่เข้าไปในกราฟ และอาจจะลบจุดข้อมูลที่เก่าที่สุดออกไปเพื่อให้กราฟเลื่อนไปข้างหน้า
load: เมื่อกราฟโหลดเสร็จ ให้เรียกฟังก์ชันสำหรับดึงข้อมูลครั้งแรกfetch หรือ $.ajax) เพื่อขอข้อมูลใหม่จากเซิร์ฟเวอร์series.addPoint(newPoint, true, true) เพื่อเพิ่มจุดใหม่
true) คือการสั่งให้วาดกราฟใหม่ (redraw)true) คือการสั่งให้ลบจุดแรกสุดออก (shift)setTimeout(requestData, 2000) เพื่อเรียกตัวเองซ้ำในอีก 2 วินาทีเราจะสร้างกราฟจำลองการอ่านค่าอุณหภูมิจากเซ็นเซอร์ ซึ่งจะมีการอัปเดตทุกๆ 2 วินาที
ผ่าน 3 Labs นี้ เราได้เรียนรู้ตั้งแต่พื้นฐานการใช้งาน Highcharts ไปจนถึงการประยุกต์ใช้กับข้อมูลจริง ทั้งข้อมูลจาก API, ข้อมูลจาก Backend และข้อมูลแบบ Real-time ซึ่งเป็นทักษะที่จำเป็นอย่างยิ่งในการพัฒนาระบบที่มีการแสดงผลข้อมูลที่ซับซ้อน
หัวใจสำคัญคือการทำความเข้าใจโครงสร้างของ Configuration Object และการเตรียมข้อมูลให้ถูกต้องตามที่กราฟแต่ละประเภทต้องการ นักศึกษาสามารถศึกษาเพิ่มเติมและดูตัวอย่างกราฟประเภทอื่นๆ ได้จากแหล่งข้อมูลทางการของ Highcharts:
ขอให้สนุกกับการสร้างสรรค์ Data Visualization ด้วย Highcharts.js!