• January 3, 2026

    สาเหตุที่คุณไม่เห็นช่องติ๊ก (Checkboxes) และกราฟไม่ขึ้น มีจุดผิดพลาดเล็กน้อยในเชิงเทคนิค 2-3 จุดครับ:

    1. ปัญหาช่องว่างใน HTML: ในโค้ดที่คุณเขียน <div id="yearCheckboxes">...</div> มีการขึ้นบรรทัดใหม่หรือช่องว่างอยู่ข้างใน ทำให้เงื่อนไข container.innerHTML === "" เป็น false (เพราะมันมีช่องว่าง ไม่ได้ว่างเปล่าจริงๆ) ช่องติ๊กเลยไม่ถูกสร้างครับ
    2. ID กราฟไม่ครบ: ใน HTML ที่ส่งมามีแค่ premiumChart แต่ใน JS มีการเรียก yearlyChart ถ้าหา ID นี้ไม่เจอ โค้ดจะหยุดทำงาน (Error) ทำให้กราฟไม่ขึ้นทั้งคู่ครับ
    3. ข้อมูลเริ่มต้น (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 หรือเปิดหน้าเว็บ:

    1. ในฟังก์ชัน loadFromLocalStorage: ต้องมีคำสั่ง updateAllCharts(); อยู่ท้ายฟังก์ชัน
    2. ในฟังก์ชัน loadFromJSONFile: (จุดที่คุณแก้ในรอบก่อน) ต้องเปลี่ยนจาก renderDataToTable(dataList, latestYear); เป็นการเรียก updateAllCharts(); แทน เพื่อให้มันไปสร้าง Checkboxes ของปีใหม่ๆ ที่มากับไฟล์ JSON ครับ

    ทดสอบ: เมื่อคุณรันโค้ดใหม่ ให้ลองกด อัปโหลด JSON ดูอีกครั้ง ระบบจะไปอ่านปีทั้งหมดในไฟล์แล้วสร้าง Checkbox ขึ้นมาให้โดยอัตโนมัติครับ



เวอไนน์ไอคอร์ส

ประหยัดเวลากว่า 100 เท่า!






เวอไนน์เว็บไซต์⚡️
สร้างเว็บไซต์ ดูแลเว็บไซต์

Categories