Files
programming-fengshui/js/main.js
T
tiennm99 e1ac51c31f feat: focus modern grid on TIOBE Top 20 with 'Xem tất cả' expand toggle
Default view shows only TIOBE-ranked languages (19 chips total) for a cleaner
first impression. A single button at the top of the modern panel toggles to
the full 664-language list. Card counts now read 'X TIOBE · Y khác'. Chips
of TIOBE-ranked languages get a slightly heavier border to stand out.

- js/tiobe-top.js: TIOBE Top 20 (April 2026) keyed by GH Linguist names
- js/main.js: tag entries with rank, sort TIOBE-first then alphabetical
- js/render-elements.js: chip distinction + view-toggle mount
- index.html: view-toggle slot + updated disclaimer
- style.css: .chip-tiobe / .chip-other / .view-toggle-btn rules
2026-04-27 09:24:25 +07:00

60 lines
2.3 KiB
JavaScript

import { classify } from './classify-element.js';
import { renderGrid, renderError, renderDebugPanel, isBorderline, mountViewToggle } from './render-elements.js';
import { TIOBE_TOP } from './tiobe-top.js';
const HEX_RE = /^#[0-9a-fA-F]{6}$/;
const LEGEND_TEXT =
'Phân loại theo tông màu HSL: đỏ/tím/cam đậm → HOẢ, xanh lá/cyan → MỘC, xanh dương → THUỶ, vàng/nâu → THỔ, trắng/xám sáng → KIM.';
async function init() {
const gridEl = document.getElementById('element-grid');
const legendEl = document.querySelector('#panel-modern .legend');
const elementsSection = document.querySelector('#panel-modern .elements');
const debugEl = document.getElementById('debug-panel');
try {
const res = await fetch('./data/github-colors.json');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
const buckets = { kim: [], moc: [], thuy: [], hoa: [], tho: [] };
const skipped = [];
const borderline = [];
for (const [name, entry] of Object.entries(data)) {
const color = entry && entry.color;
if (!color || !HEX_RE.test(color)) {
skipped.push({ name });
continue;
}
const element = classify(color);
const rank = TIOBE_TOP[name] || null;
buckets[element].push({ name, color, rank });
if (isBorderline(color)) borderline.push({ name, color, element });
}
for (const key of Object.keys(buckets)) {
buckets[key].sort((a, b) => {
if (a.rank && b.rank) return a.rank - b.rank;
if (a.rank) return -1;
if (b.rank) return 1;
return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
});
}
renderGrid(buckets, gridEl);
mountViewToggle(document.getElementById('view-toggle'), document.querySelector('#panel-modern .elements'));
if (legendEl) legendEl.textContent = LEGEND_TEXT;
renderDebugPanel({ skipped, borderline }, debugEl);
} catch (err) {
console.error('[programming-fengshui] failed to render modern grid:', err);
renderError(`Không tải được dữ liệu màu (${err.message}). Mở qua HTTP server thay vì file://.`, elementsSection);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}