Research Unit · Faculty of Medicine · NU

นายทินกรณ์
หาญณรงค์

หน่วยบริหารและจัดการงานวิจัย · คณะแพทยศาสตร์ มหาวิทยาลัยนเรศวร

พัฒนาระบบ Research Dashboard สำหรับวิเคราะห์ผลงานวิจัย รางวัลตีพิมพ์ และทุนวิจัย ปีงบประมาณ 2567–2569 เชื่อมต่อกับ Google Sheets เพื่อให้ข้อมูลอัปเดตอัตโนมัติโดยไม่ต้องแก้โค้ด

4
เวอร์ชัน Dashboard
194
รายการบทความ (68–69)
3
ปีงบประมาณ
28
กราฟใน Dashboard
📊 เปิด Research Dashboard
เลื่อนลงเพื่ออ่านรายละเอียด

Research Dashboard
คณะแพทยศาสตร์ มน.

📊
Interactive Dashboard
ไฟล์ HTML ไฟล์เดียวที่รวม CSS และ JavaScript ครบถ้วน แสดง 28 กราฟแบบ Interactive พร้อม Filter 5 ตัว ทำงานได้ทันทีใน Browser ไม่ต้องติดตั้งอะไรเพิ่ม
✅ พร้อมใช้งาน
🔗
Google Sheets Integration
เชื่อมต่อกับ Google Sheets ผ่าน Apps Script Web API ข้อมูลอัปเดตอัตโนมัติเมื่อกรอกใน Sheets ไม่ต้องแก้ไขโค้ด HTML อีกเลยหลังตั้งค่าครั้งแรก
⏳ รอตั้งค่า URL
🔬
CEU & IRB Analysis
รองรับการวิเคราะห์เปรียบเทียบโครงการที่เข้า CEU consultation กับโครงการที่ไม่เข้า โดยติดตาม CEUDate, IRBNo, IRBDate ในระบบ Sheet เดียวรองรับหลายปีงบประมาณ
⏳ รอกรอกข้อมูล
📑
Reward vs Publication Split
แยกวิเคราะห์ 3 มิติชัดเจน: บทความตีพิมพ์ทั้งหมด / ผลงานที่รับรางวัล (col16+17) / ค่าตีพิมพ์ OA (col18) ไม่ปนกันอีกต่อไป
✅ พร้อมใช้งาน

จาก Excel
ถึง Live Dashboard

Phase 1 — Data Analysis
อ่านและวิเคราะห์ข้อมูลจาก Excel 3 ปี
อ่านไฟล์ Excel ปีงบประมาณ 2567, 2568, 2569 ด้วย Python (openpyxl) วิเคราะห์โครงสร้าง 6 Sheets และ mapping คอลัมน์ทั้งหมด พบข้อมูล 103 บทความ (2569), 91 บทความ (2568) และ 30 บทความ (2567 จาก KPI) พร้อมสรุป Quartile, ฐานข้อมูล, ภาควิชา และงบประมาณ
Python openpyxl 3 ไฟล์ Excel 6 Sheets/ไฟล์
Phase 2 — Dashboard v1.0
สร้าง Dashboard Dark Theme แรก
สร้าง Single-file HTML Dashboard ด้วย Chart.js ธีมสีเข้ม (Dark Mode) พร้อม Filter และตาราง มี KPI 6 ตัว กราฟ 9 ชนิด และตาราง 2 แท็บ ข้อมูลฝังตรงใน JavaScript (Hardcoded)
Chart.js 4.4 Single HTML Dark Theme 103 records
Phase 3 — Theme & UX
เปลี่ยนเป็น Warm Light Theme ตามที่ต้องการ
ปรับธีมจาก Dark เป็น Warm Light (ครีม-น้ำตาลอบอุ่น) เปลี่ยน Accent color เป็น Burnt Sienna (#b85c20) ปรับ Badge, Border, Shadow ให้นุ่มนวลและเป็นมืออาชีพ ไม่มี Inline Event Handlers — ผูกทุก Event ผ่าน addEventListener
Warm Light Theme Burnt Sienna IBM Plex Sans Thai No Inline Handlers
Phase 4 — Multi-Year
ขยายเป็น 3 ปีงบประมาณ
เพิ่ม Year Panel 4 แท็บ (ภาพรวม / 69 / 68 / 67) เปรียบเทียบ Trend 3 ปีในกราฟเดียว เพิ่มข้อมูล D68 (91 records) และ D67 จาก KPI รายเดือน รวม 194 รายการ พร้อม Filter ข้ามปีได้
4 Year Panels 194 records Cross-year Filter Trend Comparison
Phase 5 — Google Sheets API
เชื่อมต่อ Google Sheets แบบอัตโนมัติ
สร้าง Code.gs (Apps Script) อ่านข้อมูลจาก Sheet จริง Dashboard โหลดข้อมูลผ่าน fetch() เมื่อเปิดหน้า มี Fallback Data เผื่อกรณี offline หรือยังไม่ตั้งค่า URL มีปุ่ม 🔄 โหลดข้อมูลใหม่ และ Status Banner แบบ Real-time
Google Apps Script fetch() API Fallback Data CORS
Phase 6 — CEU & IRB
เพิ่มระบบวิเคราะห์ CEU Consultation & IRB
เพิ่มคอลัมน์ IRBNo, IRBDate, CEUDate ใน Excel Template Code.gs ส่ง has_irb, has_ceu flags พร้อม ceu_rate%, irb_rate% Dashboard แสดง KPI 4 ตัว + คำแนะนำการวิเคราะห์ CEU vs Non-CEU พร้อมรายการ Confounders ที่ต้องควบคุมในการวิเคราะห์
IRBNo/IRBDate CEUDate has_ceu flag CEU KPI
Phase 7 — Multi-Year Sheet
Sheet เดียวรองรับหลายปี (Approach 2+3)
ออกแบบ Sheet ทุนวิจัย69 ใหม่ รองรับหลายปีในชีทเดียว แบ่งด้วย Group Header "◆ ปีงบประมาณ XXXX" (Approach 3) เพิ่มคอลัมน์ M "ปีงบประมาณ" override (Approach 2) Code.gs อ่านปีงบ 3 ระดับ: col M → Group Header → รหัสโครงการ เพิ่มฟังก์ชัน diagnoseYearDetection() ตรวจสอบ
Approach 2+3 3-level Year Detection SUMIF Formula diagnose fn
Phase 8 — v4.00 Rebuild
แยก Reward vs Publication + Rebuild ทั้งระบบ
วิเคราะห์ความแตกต่างระหว่างบทความตีพิมพ์ / รางวัล / ค่าตีพิมพ์ OA Code.gs: เพิ่ม getPubSplit(), getReward(), getOA() และ _buildRecord() Dashboard: Segment Switcher 3 มิติ, ตาราง 4 แท็บ, กราฟขนาดเหมาะสม Dept Filter อัตโนมัติ, Badge ใหม่ (🏆 รางวัล / 💳 OA / รางวัล+OA)
getPubSplit() Segment Switcher 4 Table Tabs 28 Charts

ปัญหาที่พบ
และวิธีแก้ไข

❌ ปัญหา: switchYear is not defined
ฟังก์ชัน JavaScript ถูกเรียกผ่าน onclick="switchYear()" แบบ Inline แต่ฟังก์ชันโหลดไม่ทันก่อน DOM ready ทำให้ Browser หาฟังก์ชันไม่เจอและ Dashboard ไม่ทำงาน
✅ แก้ไข: ย้ายทุก Event ไปใน DOMContentLoaded
เอา inline onclick ออกทั้งหมด แล้วผูก Event ทุกตัว ผ่าน addEventListener ใน DOMContentLoaded แทน ทำให้ฟังก์ชันทุกตัวพร้อมก่อนผู้ใช้กด
❌ ปัญหา: Cannot read properties of undefined (toLocaleString)
API ส่งฟิลด์ชื่อ budget_yr และ source แต่ Dashboard อ่านเป็น budget และ src ทำให้ได้ undefined แล้วพังเมื่อเรียก .toLocaleString()
✅ แก้ไข: Normalizer ในขั้นตอน loadFromSheets
เพิ่ม normalizer function แปลง field จาก API ก่อนเก็บ พร้อม safeNum() และ safeStr() ป้องกัน null, undefined, string-number ทุกกรณี
❌ ปัญหา: Dashboard ถูกตัดกลาง (heredoc)
ใช้ Shell heredoc << 'HTMLEOF' เขียนไฟล์ HTML ขนาดใหญ่ แต่ตัวแบ่งข้อความถูกตัดกลาง ทำให้ไฟล์ไม่สมบูรณ์ JS ไม่ครบ Dashboard แสดงผลไม่ได้
✅ แก้ไข: เขียนด้วย Python open().write()
เปลี่ยนมาใช้ Python open(path,'w').write(html) ไม่มีปัญหา escape character หรือขนาดไฟล์ พร้อม validation script ตรวจสอบ canvas/mk() matching ทุกครั้ง
❌ ปัญหา: fmtDate ใน loop (strict mode)
Code.gs v1 ประกาศ function fmtDate(v){...} ภายใน for loop ซึ่งผิด strict mode ของ V8 engine ทำให้ Apps Script อาจ Error ใน runtime
✅ แก้ไข: เปลี่ยนเป็น var expression
เปลี่ยนเป็น var fmtDate = function(v){...} ซึ่งเป็น function expression ที่ถูกต้องใน loop และเพิ่ม safeStr(), safeNum() เป็น top-level helper ใช้ได้ทุกฟังก์ชัน
❌ ปัญหา: แยกปีงบประมาณไม่ได้ใน Sheet เดียว
เมื่อรวมโครงการหลายปีใน Sheet เดียว Code.gs ไม่รู้ว่า แต่ละโครงการอยู่ปีไหน โดยเฉพาะโครงการที่รหัสไม่มีปีฝังอยู่ เช่น AMGEN-001 หรือ IQVIA-2568-001
✅ แก้ไข: 3-Level Year Detection (Approach 2+3)
อ่านปีงบ 3 ระดับตามลำดับความสำคัญ: col M (กรอกโดยตรง) → ◆ ปีงบประมาณ XXXX (Group Header) → รหัสโครงการ R2569xxx เพิ่ม year_source field และ diagnoseYearDetection()

สิ่งที่ส่งมอบ
และตรวจสอบแล้ว

53
รายการ Validation ผ่านทั้งหมด
28
กราฟ (canvas ↔ mk() matched)
0
Inline Event Handlers เหลืออยู่
10
Functions ใน Code.gs v4.00
19
Functions ใน Dashboard HTML
4
ไฟล์ส่งมอบพร้อมใช้งาน
ไฟล์
Version
สถานะ
ขนาด
iram-kpi-dashboard.html
Dashboard หลัก · 4 Panels · 28 Charts · Google Sheets API
v4.00
✅ พร้อมใช้
80 KB · 999 lines
Code.gs
Apps Script API · getPub / getReward / getOA / getPubSplit / getProj
v4.00
✅ พร้อม Deploy
19 KB · 438 lines
research_dashboard_template.xlsx
Excel Template · 6 Sheets · IRBNo/IRBDate/CEUDate/FiscalYear
✅ พร้อมใช้
22 KB
setup_guide.html
คู่มือตั้งค่า 5 ขั้นตอน · แก้ปัญหาที่พบบ่อย
✅ พร้อมใช้
11 KB
Code.gs (ก่อนหน้า)
v2.00, v3.00 — archived
v2–v3
🔄 Superseded

ขั้นตอนถัดไป
และแผนในอนาคต

ระยะสั้น · ทันที
🔗 เชื่อมต่อระบบจริง
  • อัปโหลด Excel ขึ้น Google Sheets ตั้งชื่อ Sheet ให้ตรง
  • วาง Code.gs ใน Apps Script และรัน testAPI() ทดสอบ
  • Deploy เป็น Web App (Execute as: Me, Access: Anyone)
  • Copy URL ใส่ใน SHEETS_API_URL ของ Dashboard
  • ทดสอบปุ่ม 🔄 โหลดข้อมูลใหม่ ให้แสดงแบนเนอร์เขียว
ระยะกลาง · 1–3 เดือน
📊 วิเคราะห์ CEU
  • กรอก CEUDate (col L) ให้ครบทุกโครงการ
  • กรอก IRBDate (col K) ให้ครบ
  • นำข้อมูลปี 2568 เพิ่มใน Sheet ทุนวิจัย69
  • วิเคราะห์ CEU vs Non-CEU Publication Rate
  • Propensity Score Matching ควบคุม Confounders
  • Time-to-publication: IRBDate → วันตีพิมพ์
ระยะยาว · 3–6 เดือน
🚀 ขยายระบบ
  • เพิ่มข้อมูลปีงบประมาณ 2570 เมื่อมี
  • Dashboard ปี 2570 อัปเดตอัตโนมัติจาก Sheets
  • เพิ่ม Sheet "การนำเสนอผลงาน" ใน Template
  • วิเคราะห์ Dose-Response: จำนวนครั้ง CEU vs Quality
  • พิจารณา Streamlit Cloud สำหรับ Multi-user access
  • GitHub Actions อัปเดต JSON อัตโนมัติทุกสัปดาห์

Tech Stack

📊 Chart.js 4.4
🐍 Python 3 + openpyxl
📝 Google Apps Script
📄 Google Sheets API
🎨 IBM Plex Sans Thai
Vanilla JavaScript (ES5)
🗂 openpyxl (Excel)
🌐 Single-file HTML
🔗 fetch() Web API
📐 CSS Grid + Custom Properties