// ============================================================
// DATA
// ============================================================
const annualData = [
{year:2003, sales:67478, trims:"DX, EX", colors:6, sc_est:0, fwd_pct:50, awd_pct:50, manual_pct:20, auto_pct:80, conf:"HIGH"},
{year:2004, sales:59227, trims:"DX, LX, EX", colors:6, sc_est:0, fwd_pct:48, awd_pct:52, manual_pct:18, auto_pct:82, conf:"HIGH"},
{year:2005, sales:56262, trims:"LX, EX", colors:8, sc_est:0, fwd_pct:48, awd_pct:52, manual_pct:15, auto_pct:85, conf:"HIGH"},
{year:2006, sales:51829, trims:"LX, EX, EX-P", colors:7, sc_est:0, fwd_pct:48, awd_pct:52, manual_pct:13, auto_pct:87, conf:"HIGH"},
{year:2007, sales:35218, trims:"LX, EX, EX-P, SC", colors:8, sc_est:3522, fwd_pct:52, awd_pct:48, manual_pct:12, auto_pct:88, conf:"HIGH"},
{year:2008, sales:26447, trims:"LX, EX, EX-P, SC", colors:9, sc_est:3967, fwd_pct:55, awd_pct:45, manual_pct:11, auto_pct:89, conf:"HIGH"},
{year:2009, sales:14884, trims:"LX, EX, SC", colors:8, sc_est:2530, fwd_pct:57, awd_pct:43, manual_pct:10, auto_pct:90, conf:"HIGH"},
{year:2010, sales:14247, trims:"LX, EX, SC", colors:9, sc_est:2565, fwd_pct:58, awd_pct:42, manual_pct:4, auto_pct:96, conf:"HIGH"},
{year:2011, sales:11534, trims:"LX, EX", colors:7, sc_est:0, fwd_pct:50, awd_pct:50, manual_pct:0, auto_pct:100, conf:"HIGH"},
];
const colorData = [
{name:"Alabaster Silver Metallic", code:"NH700M", family:"Silver", years:"2006–2011", num_years:6, restriction:"All trims", rarity:"Very Common", est_total:"~130,000", desirability:"Low", hex:"#CAC9C6", sc_only:false},
{name:"Atomic Blue Metallic", code:"B537M", family:"Blue", years:"2006–2008", num_years:3, restriction:"LX, EX only", rarity:"Uncommon", est_total:"~22,000", desirability:"Moderate", hex:"#6E91AA", sc_only:false},
{name:"Cargo Khaki", code:"YR547", family:"Tan/Beige", years:"2005 only", num_years:1, restriction:"DX, LX, EX", rarity:"Rare", est_total:"~2,800", desirability:"Moderate", hex:"#8B7355", sc_only:false},
{name:"Citrus Fire Metallic", code:"YR579M", family:"Orange", years:"2009–2011", num_years:3, restriction:"LX, EX only", rarity:"Common", est_total:"~10,000", desirability:"Moderate", hex:"#C8600A", sc_only:false},
{name:"Crystal Black Pearl", code:"NH731P", family:"Black", years:"2009–2011", num_years:3, restriction:"LX, EX only", rarity:"Common", est_total:"~12,000", desirability:"High", hex:"#1E1E1C", sc_only:false},
{name:"Eternal Blue Pearl", code:"B96P", family:"Blue", years:"2003 only", num_years:1, restriction:"DX, LX, EX", rarity:"Very Rare", est_total:"~11,000", desirability:"Very High", hex:"#044996", sc_only:false},
{name:"Fiji Blue Pearl", code:"B529P", family:"Blue", years:"2004–2005", num_years:2, restriction:"DX, LX, EX", rarity:"Uncommon", est_total:"~23,000", desirability:"Moderate", hex:"#2F3964", sc_only:false},
{name:"Galapagos Green Metallic", code:"G511M", family:"Green", years:"2003–2005", num_years:3, restriction:"DX, LX, EX", rarity:"Common", est_total:"~30,000", desirability:"Very High", hex:"#99AC70", sc_only:false},
{name:"Galaxy Gray Metallic", code:"NH701M", family:"Gray", years:"2007–2008", num_years:2, restriction:"LX, EX, SC", rarity:"Uncommon", est_total:"~12,000", desirability:"Moderate", hex:"#A99D87", sc_only:false},
{name:"Kiwi Metallic", code:"GY25M", family:"Green", years:"2006–2008", num_years:3, restriction:"LX, EX only", rarity:"Uncommon", est_total:"~18,000", desirability:"Moderate", hex:"#738115", sc_only:false},
{name:"Magnesium Metallic", code:"NH675M", family:"Gray", years:"2005 only", num_years:1, restriction:"DX, LX, EX", rarity:"Rare", est_total:"~2,800", desirability:"Moderate", hex:"#8C8C8C", sc_only:false},
{name:"Midnight Red Pearl", code:"R538P", family:"Red", years:"2009–2010 SC only", num_years:2, restriction:"SC only", rarity:"Very Rare", est_total:"~1,000", desirability:"Very High", hex:"#5C1010", sc_only:true},
{name:"Nighthawk Black Pearl", code:"B92P", family:"Black", years:"2003–2008", num_years:6, restriction:"All trims", rarity:"Very Common", est_total:"~100,000", desirability:"Moderate", hex:"#0A0A0A", sc_only:false},
{name:"Omni Blue Pearl", code:"B562P", family:"Blue", years:"2009–2011", num_years:3, restriction:"LX, EX only", rarity:"Common", est_total:"~9,000", desirability:"Very High", hex:"#7B8C7A", sc_only:false},
{name:"Polished Metal Metallic", code:"NH737M", family:"Gray", years:"2009–2011", num_years:3, restriction:"LX, EX only", rarity:"Common", est_total:"~9,000", desirability:"Moderate", hex:"#615F55", sc_only:false},
{name:"Rallye Red", code:"R513", family:"Red", years:"2005–2006", num_years:2, restriction:"DX, LX, EX", rarity:"Uncommon", est_total:"~17,000", desirability:"Moderate", hex:"#9C0C0C", sc_only:false},
{name:"Root Beer Metallic", code:"YR569M", family:"Brown", years:"2007–2008 SC only", num_years:2, restriction:"SC only", rarity:"Very Rare", est_total:"~1,500", desirability:"Very High", hex:"#61481D", sc_only:true},
{name:"Royal Blue Pearl", code:"B536P", family:"Blue", years:"2008–2010", num_years:3, restriction:"SC only 2008; all 2009–10", rarity:"Rare", est_total:"~5,000", desirability:"High", hex:"#1F0F63", sc_only:false},
{name:"Satin Silver Metallic", code:"NH623M", family:"Silver", years:"2003–2005", num_years:3, restriction:"DX, LX, EX", rarity:"Common", est_total:"~30,000", desirability:"Low", hex:"#C0C0C0", sc_only:false},
{name:"Shoreline Mist Metallic", code:"YR528M", family:"Tan/Beige", years:"2003–2004", num_years:2, restriction:"DX, LX, EX", rarity:"Uncommon", est_total:"~20,000", desirability:"Low", hex:"#B8A898", sc_only:false},
{name:"Sunset Orange Pearl", code:"YR539P", family:"Orange", years:"2003–2005", num_years:3, restriction:"DX, LX, EX", rarity:"Common", est_total:"~30,000", desirability:"Very High", hex:"#D2691E", sc_only:false},
{name:"Taffeta White", code:"NH578", family:"White", years:"2010–2011", num_years:2, restriction:"LX, EX only", rarity:"Uncommon", est_total:"~5,000", desirability:"Moderate", hex:"#F1F3DB", sc_only:false},
{name:"Tango Red Pearl", code:"R525P", family:"Red", years:"2006–2011", num_years:6, restriction:"LX, EX only", rarity:"Common", est_total:"~50,000", desirability:"Moderate", hex:"#9E2222", sc_only:false},
{name:"Tangerine Metallic", code:"YR5863M", family:"Orange", years:"2006–2008", num_years:3, restriction:"LX, EX only", rarity:"Uncommon", est_total:"~18,000", desirability:"Moderate", hex:"#E07B39", sc_only:false},
];
// ============================================================
// DATABASE RECORDS (embedded from JSON)
// ============================================================
let allRecords = [];
let filteredRecords = [];
let currentPage = 1;
const PAGE_SIZE = 50;
let sortCol = "rarity_score";
let sortDir = "desc";
// Fetch the JSON data
fetch("honda_element_master_data.json")
.then(r => r.json())
.then(data => {
allRecords = data.records;
filteredRecords = [...allRecords];
populateColorFilter();
applyFilters();
renderRarityIndex();
})
.catch(() => {
// Fallback: show message
document.getElementById("main-tbody").innerHTML = '
| Please serve this file from a local server or open honda_element_master_data.json alongside this file. |
';
});
// ============================================================
// ANNUAL SUMMARY
// ============================================================
function renderAnnualSummary() {
const maxSales = Math.max(...annualData.map(r => r.sales));
const tbody = document.getElementById("annual-tbody");
let html = "";
let totalSales = 0, totalSC = 0, totalFWD = 0, totalAWD = 0, totalManual = 0, totalAuto = 0;
annualData.forEach(row => {
const fwd = Math.round(row.sales * row.fwd_pct / 100);
const awd = Math.round(row.sales * row.awd_pct / 100);
const manual = Math.round(row.sales * row.manual_pct / 100);
const auto = Math.round(row.sales * row.auto_pct / 100);
const barWidth = (row.sales / maxSales * 100).toFixed(1);
totalSales += row.sales; totalSC += row.sc_est;
totalFWD += fwd; totalAWD += awd; totalManual += manual; totalAuto += auto;
html += `
| ${row.year} |
${row.sales.toLocaleString()} |
|
${row.trims} |
${row.colors} |
${row.sc_est > 0 ? "~" + row.sc_est.toLocaleString() : "N/A"} |
~${fwd.toLocaleString()} (${row.fwd_pct}%) |
~${awd.toLocaleString()} (${row.awd_pct}%) |
${manual > 0 ? "~" + manual.toLocaleString() + " (" + row.manual_pct + "%)" : "None"} |
~${auto.toLocaleString()} (${row.auto_pct}%) |
${row.conf} |
`;
});
// Total row
html += `
| TOTAL |
${totalSales.toLocaleString()} |
| | |
~${totalSC.toLocaleString()} |
~${totalFWD.toLocaleString()} |
~${totalAWD.toLocaleString()} |
~${totalManual.toLocaleString()} |
~${totalAuto.toLocaleString()} |
|
`;
tbody.innerHTML = html;
}
// ============================================================
// MASTER DATABASE
// ============================================================
function populateColorFilter() {
const colors = [...new Set(allRecords.map(r => r.color_name))].sort();
const sel = document.getElementById("filter-color");
colors.forEach(c => {
const opt = document.createElement("option");
opt.value = c; opt.textContent = c;
sel.appendChild(opt);
});
}
function applyFilters() {
const year = document.getElementById("filter-year").value;
const trim = document.getElementById("filter-trim").value;
const dt = document.getElementById("filter-drivetrain").value;
const tx = document.getElementById("filter-transmission").value;
const color = document.getElementById("filter-color").value;
const rarityMin = parseInt(document.getElementById("filter-rarity-min").value) || 1;
const search = document.getElementById("filter-search").value.toLowerCase();
const scColor = document.getElementById("filter-sc-color").value;
filteredRecords = allRecords.filter(r => {
if (year && r.year != year) return false;
if (trim && r.trim !== trim) return false;
if (dt && r.drivetrain !== dt) return false;
if (tx && r.transmission !== tx) return false;
if (color && r.color_name !== color) return false;
if (r.rarity_score < rarityMin) return false;
if (scColor === "yes" && !r.sc_only_color) return false;
if (scColor === "no" && r.sc_only_color) return false;
if (search) {
const haystack = (r.color_name + r.trim + r.notes + r.color_code).toLowerCase();
if (!haystack.includes(search)) return false;
}
return true;
});
// Sort
filteredRecords.sort((a, b) => {
let va = a[sortCol], vb = b[sortCol];
if (typeof va === "string") va = va.toLowerCase();
if (typeof vb === "string") vb = vb.toLowerCase();
if (va < vb) return sortDir === "asc" ? -1 : 1;
if (va > vb) return sortDir === "asc" ? 1 : -1;
return 0;
});
currentPage = 1;
document.getElementById("result-count").textContent = `Showing ${filteredRecords.length.toLocaleString()} records`;
renderTable();
renderPagination();
}
function sortTable(col) {
if (sortCol === col) {
sortDir = sortDir === "asc" ? "desc" : "asc";
} else {
sortCol = col;
sortDir = col === "rarity_score" || col === "estimated_production" ? "desc" : "asc";
}
// Update header classes
document.querySelectorAll("#main-table thead th").forEach(th => {
th.classList.remove("sort-asc", "sort-desc");
if (th.dataset.col === col) {
th.classList.add(sortDir === "asc" ? "sort-asc" : "sort-desc");
}
});
applyFilters();
}
function resetFilters() {
["filter-year","filter-trim","filter-drivetrain","filter-transmission","filter-color","filter-sc-color"].forEach(id => {
document.getElementById(id).value = "";
});
document.getElementById("filter-rarity-min").value = "";
document.getElementById("filter-search").value = "";
applyFilters();
}
function getRarityClass(score) {
if (score <= 20) return "rarity-1-20";
if (score <= 40) return "rarity-21-40";
if (score <= 60) return "rarity-41-60";
if (score <= 80) return "rarity-61-80";
return "rarity-81-100";
}
function getRarityLabel(score) {
if (score <= 20) return "Common";
if (score <= 40) return "Uncommon";
if (score <= 60) return "Notable";
if (score <= 80) return "Rare";
return "Very Rare";
}
const colorHexMap = {};
colorData.forEach(c => colorHexMap[c.code] = c.hex);
function renderTable() {
const start = (currentPage - 1) * PAGE_SIZE;
const end = start + PAGE_SIZE;
const pageRecords = filteredRecords.slice(start, end);
const tbody = document.getElementById("main-tbody");
if (pageRecords.length === 0) {
tbody.innerHTML = '| No records match the current filters. |
';
return;
}
let html = "";
pageRecords.forEach(r => {
const hex = colorHexMap[r.color_code] || "#cccccc";
const tags = [];
if (r.sc_only_color) tags.push('SC Color');
if (r.single_year_color) tags.push('Single Year');
if (r.transmission === "Manual") tags.push('Manual');
if (r.drivetrain === "AWD") tags.push('AWD');
html += `
| ${r.year} |
${r.trim} |
${r.drivetrain} |
${r.transmission} |
${r.color_name}
${r.color_code}
${tags.join("")}
|
~${r.estimated_production.toLocaleString()} |
${r.confidence_level} |
${r.rarity_score} — ${getRarityLabel(r.rarity_score)} |
${r.notes || ""} |
`;
});
tbody.innerHTML = html;
}
function renderPagination() {
const totalPages = Math.ceil(filteredRecords.length / PAGE_SIZE);
const pag = document.getElementById("pagination");
if (totalPages <= 1) { pag.innerHTML = ""; return; }
let html = "";
if (currentPage > 1) html += ``;
const start = Math.max(1, currentPage - 2);
const end = Math.min(totalPages, currentPage + 2);
if (start > 1) { html += ``; if (start > 2) html += `…`; }
for (let i = start; i <= end; i++) {
html += ``;
}
if (end < totalPages) { if (end < totalPages - 1) html += `…`; html += ``; }
if (currentPage < totalPages) html += ``;
html += `Page ${currentPage} of ${totalPages} (${filteredRecords.length.toLocaleString()} records)`;
pag.innerHTML = html;
}
function goPage(p) {
currentPage = p;
renderTable();
renderPagination();
document.getElementById("tab-database").scrollIntoView({behavior:"smooth", block:"start"});
}
// ============================================================
// COLOR GUIDE
// ============================================================
function renderColorGuide() {
const rarityFilter = document.getElementById("color-filter-rarity").value;
const familyFilter = document.getElementById("color-filter-family").value;
const scFilter = document.getElementById("color-filter-sc").value;
let colors = colorData.filter(c => {
if (rarityFilter && c.rarity !== rarityFilter) return false;
if (familyFilter && c.family !== familyFilter) return false;
if (scFilter === "yes" && !c.sc_only) return false;
if (scFilter === "no" && c.sc_only) return false;
return true;
});
const rarityOrder = {"Very Rare":0,"Rare":1,"Uncommon":2,"Common":3,"Very Common":4};
colors.sort((a,b) => rarityOrder[a.rarity] - rarityOrder[b.rarity]);
const rarityBadgeClass = {
"Very Rare": "rarity-81-100", "Rare": "rarity-61-80",
"Uncommon": "rarity-41-60", "Common": "rarity-21-40", "Very Common": "rarity-1-20"
};
const grid = document.getElementById("color-grid");
grid.innerHTML = colors.map(c => `
${c.name}
${c.code}
${c.rarity}
${c.years}
${c.family}
${c.sc_only ? 'SC Only' : ''}
Est. Total: ${c.est_total} |
Desirability: ${c.desirability}
Restriction: ${c.restriction}
`).join("");
}
// ============================================================
// RARITY INDEX
// ============================================================
function renderRarityIndex() {
const seen = new Set();
const top = [];
const sorted = [...allRecords].sort((a,b) => b.rarity_score - a.rarity_score);
for (const r of sorted) {
const key = `${r.year}-${r.trim}-${r.drivetrain}-${r.transmission}-${r.color_code}`;
if (!seen.has(key)) { seen.add(key); top.push(r); }
if (top.length >= 50) break;
}
const tbody = document.getElementById("rarity-tbody");
tbody.innerHTML = top.map((r, i) => {
const hex = colorHexMap[r.color_code] || "#cccccc";
const rankClass = i === 0 ? "rank-1" : i === 1 ? "rank-2" : i === 2 ? "rank-3" : "";
return `
| #${i+1} |
${r.year} |
${r.trim} |
${r.drivetrain} |
${r.transmission} |
${r.color_name} |
~${r.estimated_production.toLocaleString()} |
${r.rarity_score} |
`;
}).join("");
}
// ============================================================
// TABS
// ============================================================
function showTab(name) {
document.querySelectorAll(".tab-content").forEach(t => t.classList.remove("active"));
document.querySelectorAll(".tab-btn").forEach(b => b.classList.remove("active"));
document.getElementById("tab-" + name).classList.add("active");
event.target.classList.add("active");
}
// ============================================================
// INIT
// ============================================================
renderAnnualSummary();
renderColorGuide();