สาเหตุที่คุณไม่เห็นช่องติ๊ก (Checkboxes) และกราฟไม่ขึ้น มีจุดผิดพลาดเล็กน้อยในเชิงเทคนิค 2-3 จุดครับ:
- ปัญหาช่องว่างใน HTML: ในโค้ดที่คุณเขียน
<div id="yearCheckboxes">...</div>มีการขึ้นบรรทัดใหม่หรือช่องว่างอยู่ข้างใน ทำให้เงื่อนไขcontainer.innerHTML === ""เป็น false (เพราะมันมีช่องว่าง ไม่ได้ว่างเปล่าจริงๆ) ช่องติ๊กเลยไม่ถูกสร้างครับ - ID กราฟไม่ครบ: ใน HTML ที่ส่งมามีแค่
premiumChartแต่ใน JS มีการเรียกyearlyChartถ้าหา ID นี้ไม่เจอ โค้ดจะหยุดทำงาน (Error) ทำให้กราฟไม่ขึ้นทั้งคู่ครับ - ข้อมูลเริ่มต้น (dataList): หากตอนเปิดโปรแกรมมา
dataListยังว่างอยู่ (ยังไม่ได้โหลดจาก Local Storage หรือ JSON) ลูปที่สร้าง Checkbox จะไม่ทำงานครับ
วิธีแก้ไข (ให้ก๊อปปี้ส่วนนี้ไปทับของเดิมครับ)
1. ส่วน HTML (ตรวจสอบว่ามี Canvas ครบทั้ง 2 อัน)
ตรวจสอบให้แน่ใจว่าในส่วนแสดงกราฟ มี ID ครบตามนี้:
HTML
<div class="mb-3 p-2 border rounded bg-white">
<label class="fw-bold me-2">เลือกปีที่จะแสดงในกราฟเส้น:</label>
<div id="yearCheckboxes" class="d-flex flex-wrap gap-3"></div>
</div>
<div class="row">
<div class="col-md-12 mb-4">
<canvas id="premiumChart"></canvas>
</div>
<div class="col-md-12">
<canvas id="yearlyChart"></canvas>
</div>
</div>
2. แก้ไขฟังก์ชัน renderPremiumChart (ปรับปรุงตรรกะการสร้าง Checkbox)
ผมปรับให้มันเช็คจำนวนลูกข้างในแทนการเช็ค string ว่าว่างหรือไม่ เพื่อความแม่นยำครับ:
JavaScript
function renderPremiumChart() {
const canvas = document.getElementById('premiumChart');
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (myPremiumChart) myPremiumChart.destroy();
// 1. หาปีทั้งหมดที่มีในข้อมูล dataList
const allYears = [...new Set(dataList.map(d => d.date.substring(0, 4)))].sort();
// 2. จัดการ Checkboxes
const container = document.getElementById('yearCheckboxes');
if (container) {
// ถ้าจำนวน Checkbox ไม่เท่ากับจำนวนปีที่มี (เช่น มีปีใหม่เพิ่มเข้ามา) ให้สร้างใหม่
const existingCheckboxes = container.querySelectorAll('.year-chk');
if (existingCheckboxes.length !== allYears.length && allYears.length > 0) {
container.innerHTML = ""; // ล้างอันเก่า
allYears.forEach(y => {
container.innerHTML += `
<div class="form-check">
<input class="form-check-input year-chk" type="checkbox" value="${y}" id="chk${y}" checked onchange="renderPremiumChart()">
<label class="form-check-label" for="chk${y}">${y}</label>
</div>`;
});
}
}
// 3. กรองเฉพาะปีที่ถูก "ติ๊กเลือก"
const selectedYears = Array.from(document.querySelectorAll('.year-chk:checked')).map(cb => cb.value);
// ถ้าไม่ได้ติ๊กซักปี ให้จบการทำงาน
if (selectedYears.length === 0) return;
// 4. เตรียมข้อมูล Dataset
const colors = ['#4e73df', '#1cc88a', '#36b9cc', '#f6c23e', '#e74a3b', '#858796'];
const datasets = selectedYears.map((year, index) => {
const monthlyData = new Array(12).fill(0);
dataList.filter(d => d.date.startsWith(year)).forEach(d => {
const m = parseInt(d.date.substring(5, 7)) - 1;
monthlyData[m] += parseFloat(d.premium || 0);
});
return {
label: `ปี ${year}`,
data: monthlyData,
borderColor: colors[index % colors.length],
backgroundColor: 'transparent',
borderWidth: 2,
tension: 0.3
};
});
myPremiumChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'],
datasets: datasets
},
options: { responsive: true }
});
}
3. แก้ไขฟังก์ชัน renderYearlyChart (เพิ่ม Error Handling)
เพิ่มการเช็คว่ามีตัวแปร dataList หรือไม่ เพื่อป้องกันกราฟพังตอนไม่มีข้อมูล:
JavaScript
function renderYearlyChart() {
const canvas = document.getElementById('yearlyChart');
if (!canvas) return; // ป้องกัน Error ถ้าหา ID ไม่เจอ
const ctx = canvas.getContext('2d');
if (myYearlyChart) myYearlyChart.destroy();
if (!dataList || dataList.length === 0) return;
const yearlyTotals = {};
dataList.forEach(d => {
const year = d.date.substring(0, 4);
yearlyTotals[year] = (yearlyTotals[year] || 0) + parseFloat(d.premium || 0);
});
const sortedYears = Object.keys(yearlyTotals).sort();
const dataValues = sortedYears.map(y => yearlyTotals[y]);
myYearlyChart = new Chart(ctx, {
type: 'bar',
data: {
labels: sortedYears,
datasets: [{
label: 'ยอด Premium รวมรายปี',
data: dataValues,
backgroundColor: '#4e73df'
}]
},
options: {
responsive: true,
plugins: { title: { display: true, text: 'เปรียบเทียบยอดรวมทุกปี' } }
}
});
}
จุดสำคัญที่ต้องตรวจสอบเพิ่ม:
เพื่อให้กราฟอัปเดตทันทีหลังจากโหลดไฟล์ JSON หรือเปิดหน้าเว็บ:
- ในฟังก์ชัน
loadFromLocalStorage: ต้องมีคำสั่งupdateAllCharts();อยู่ท้ายฟังก์ชัน - ในฟังก์ชัน
loadFromJSONFile: (จุดที่คุณแก้ในรอบก่อน) ต้องเปลี่ยนจากrenderDataToTable(dataList, latestYear);เป็นการเรียกupdateAllCharts();แทน เพื่อให้มันไปสร้าง Checkboxes ของปีใหม่ๆ ที่มากับไฟล์ JSON ครับ
ทดสอบ: เมื่อคุณรันโค้ดใหม่ ให้ลองกด อัปโหลด JSON ดูอีกครั้ง ระบบจะไปอ่านปีทั้งหมดในไฟล์แล้วสร้าง Checkbox ขึ้นมาให้โดยอัตโนมัติครับ