หลังจากได้ทั้งทฤษฎี เอา Matrix มาสลับ column ใน database แนวนอนแนวตั้ง และ flowchart UML: สลับตารางแนวนอนและตารางแนวตั้ง ก็ได้เวลาที่จะเขียน code ว่ามันทำงานถูกต้องมั๋ย กันจริง ๆ ทั้งเปลี่ยนตารางเป็นแนวนอนแนวตั้ง โดยใช้ base ที่ web programmer ทุกคนน่าจะคุ้นคือ HTML, JavaScript, CSS
table_Matrix_ reshaping.html
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>Dynamic Matrix Reshaper</title>
<style>
body { font-family: 'Chakra Petch', sans-serif; padding: 20px; background-color: #f0f2f5; }
.container { max-width: 1000px; margin: auto; background: white; padding: 25px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
.config-panel { display: flex; gap: 20px; margin-bottom: 20px; padding: 20px; background: #e9ecef; border-radius: 10px; flex-wrap: wrap; }
.box { border: 1px solid #dee2e6; padding: 15px; border-radius: 8px; flex: 1; min-width: 250px; }
table { border-collapse: collapse; width: 100%; table-layout: fixed; margin-top: 10px; }
td { border: 1px solid #adb5bd; padding: 8px; text-align: center; font-size: 13px; height: 35px; background: white; transition: 0.3s; }
.active-src { background-color: #ffd600 !important; font-weight: bold; transform: scale(1.05); z-index: 10; }
.active-tar { background-color: #007bff !important; color: white; }
.done-tar { background-color: #28a745 !important; color: white; }
.moved { opacity: 0.3; background: #e9ecef; }
input { width: 50px; padding: 5px; text-align: center; border-radius: 4px; border: 1px solid #ced4da; }
button { padding: 10px 20px; background: #212529; color: white; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; }
button:disabled { background: #6c757d; }
.total-badge { background: #007bff; color: white; padding: 2px 8px; border-radius: 10px; }
</style>
</head>
<body>
<div class="container">
<h2>Matrix Reshaping Simulator</h2>
<div class="config-panel">
<div class="box">
<strong>1. Source Matrix (ต้นทาง)</strong><br><br>
Rows: <input type="number" id="sRow" value="3" oninput="updateTotal()"> x
Cols: <input type="number" id="sCol" value="8" oninput="updateTotal()"><br>
Total Cells: <span id="totalBadge" class="total-badge">24</span>
</div>
<div class="box">
<strong>2. Target Matrix (ปลายทาง)</strong><br><br>
Rows: <input type="number" id="tRow" value="6" oninput="autoCalc('row')"> x
Cols: <input type="number" id="tCol" value="4" oninput="autoCalc('col')"><br>
<small id="warn" style="color: green;">✓ มิติถูกต้อง</small>
</div>
<div style="display: flex; align-items: center;">
<button id="startBtn" onclick="runSimulation()">เริ่มการย้ายข้อมูล</button>
</div>
</div>
<div id="status" style="margin-bottom: 15px; font-weight: bold; color: #495057;">สถานะ: พร้อมใช้งาน</div>
<h4>Source Table:</h4>
<table id="sourceTable"></table>
<h4>Target Table:</h4>
<table id="targetTable"></table>
</div>
<script>
let totalCells = 24;
function updateTotal() {
const r = parseInt(document.getElementById('sRow').value) || 1;
const c = parseInt(document.getElementById('sCol').value) || 1;
totalCells = r * c;
document.getElementById('totalBadge').textContent = totalCells;
autoCalc('row'); // ปรับ target ตาม total ใหม่
renderSource(r, c);
}
function autoCalc(type) {
const tRow = document.getElementById('tRow');
const tCol = document.getElementById('tCol');
const warn = document.getElementById('warn');
const btn = document.getElementById('startBtn');
let r = parseInt(tRow.value) || 1;
let c = parseInt(tCol.value) || 1;
if (type === 'row') {
c = Math.floor(totalCells / r);
tCol.value = c;
} else {
r = Math.floor(totalCells / c);
tRow.value = r;
}
if (r * c === totalCells) {
warn.textContent = "✓ มิติถูกต้อง";
warn.style.color = "green";
btn.disabled = false;
} else {
warn.textContent = `✗ ไม่ลงตัว (ขาด/เกิน ${Math.abs(totalCells - (r*c))} ช่อง)`;
warn.style.color = "red";
btn.disabled = true;
}
}
function renderSource(r, c) {
const table = document.getElementById('sourceTable');
table.innerHTML = "";
let count = 1;
for (let i = 0; i < r; i++) {
let row = table.insertRow();
for (let j = 0; j < c; j++) {
let cell = row.insertCell();
cell.id = `s-${count-1}`;
cell.textContent = "C" + count;
count++;
}
}
}
const sleep = (ms) => new Promise(res => setTimeout(res, ms));
async function runSimulation() {
const btn = document.getElementById('startBtn');
const status = document.getElementById('status');
const tR = parseInt(document.getElementById('tRow').value);
const tC = parseInt(document.getElementById('tCol').value);
const targetTable = document.getElementById('targetTable');
btn.disabled = true;
targetTable.innerHTML = "";
renderSource(parseInt(document.getElementById('sRow').value), parseInt(document.getElementById('sCol').value));
// สร้างตารางเป้าหมายเปล่า
for (let i = 0; i < tR; i++) {
let row = targetTable.insertRow();
for (let j = 0; j < tC; j++) {
let cell = row.insertCell();
cell.id = `t-${i}-${j}`;
}
}
let k = 0;
// ลำดับการทำงานตาม Flowchart: วนลูปตามโครงสร้างใหม่
for (let r = 0; r < tR; r++) {
for (let c = 0; c < tC; c++) {
if (k >= totalCells) break;
status.innerHTML = `ขั้นตอน: หยิบ C${k+1} ไปวางที่ [แถว ${r+1}, คอลัมน์ ${c+1}]`;
const sCell = document.getElementById(`s-${k}`);
const tCell = document.getElementById(`t-${r}-${c}`);
sCell.classList.add('active-src');
tCell.classList.add('active-tar');
await sleep(1000); // หน่วงเวลา 1 วินาทีตามที่ขอ
tCell.textContent = sCell.textContent;
tCell.classList.replace('active-tar', 'done-tar');
sCell.classList.remove('active-src');
sCell.classList.add('moved');
k++;
}
}
status.innerHTML = "🏁 เสร็จสิ้นการ Reshape ข้อมูลทั้งหมด!";
btn.disabled = false;
}
// Initial render
updateTotal();
</script>
</body>
</html>
มี Animation เล็ก ๆ ช้า ๆ ให้เห็นการทำงานด้วย ถ้าสมัยเรียนมีสื่อการสอนแบบนี้ คงจะดีไม่น้อย ไม่มองข้ามว่า เรียนเรียนคณิตศาสตร์เรื่องนี้ไปทำไม
อ่านเพิ่มเติม