311 lines
11 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
initializeNavigation();
initializeFilters();
initializeSearch();
initializeVariablesTable();
initializeSectionsTree();
initializeModal();
});
let currentTab = 'overview';
let filteredVariables = [];
function initializeNavigation() {
const navButtons = document.querySelectorAll('.nav-btn');
const tabContents = document.querySelectorAll('.tab-content');
navButtons.forEach(btn => {
btn.addEventListener('click', function() {
const tabName = this.getAttribute('data-tab');
navButtons.forEach(b => b.classList.remove('active'));
tabContents.forEach(t => t.classList.remove('active'));
this.classList.add('active');
document.getElementById(`tab-${tabName}`).classList.add('active');
currentTab = tabName;
});
});
}
function initializeFilters() {
const filterCheckboxes = document.querySelectorAll('.filters input[type="checkbox"]');
filterCheckboxes.forEach(checkbox => {
checkbox.addEventListener('change', applyFilters);
});
}
function applyFilters() {
const showCore = document.getElementById('filter-core').checked;
const showHard = document.getElementById('filter-hard').checked;
const showSoft = document.getElementById('filter-soft').checked;
const selectedPriorities = [];
document.querySelectorAll('.filter-priority:checked').forEach(cb => {
selectedPriorities.push(parseInt(cb.value));
});
filteredVariables = window.appData.variables.filter(variable => {
if (!showCore && variable.category === 'core_value') return false;
if (!showHard && variable.is_hard_constraint) return false;
if (!showSoft && !variable.is_hard_constraint && variable.category === 'factor') return false;
if (variable.priority_level && !selectedPriorities.includes(variable.priority_level)) {
return false;
}
return true;
});
renderVariablesTable(filteredVariables);
}
function initializeSearch() {
const searchInput = document.getElementById('search-input');
const searchFilter = document.getElementById('search-filter');
let searchTimeout;
searchInput.addEventListener('input', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
performSearch(this.value, searchFilter.value);
}, 300);
});
searchFilter.addEventListener('change', function() {
performSearch(searchInput.value, this.value);
});
}
function performSearch(query, filterType) {
query = query.toLowerCase().trim();
if (!query) {
applyFilters();
return;
}
const results = window.appData.variables.filter(variable => {
if (filterType === 'all' || filterType === 'variables') {
const searchableText = `${variable.name} ${variable.description}`.toLowerCase();
return searchableText.includes(query);
}
return false;
});
if (filterType === 'variables' || filterType === 'all') {
renderVariablesTable(results);
}
}
function initializeVariablesTable() {
const variables = window.appData.variables || [];
renderVariablesTable(variables);
document.getElementById('sort-name').addEventListener('click', () => sortVariables('name'));
document.getElementById('sort-freq').addEventListener('click', () => sortVariables('frequency'));
document.getElementById('sort-coeff').addEventListener('click', () => sortVariables('coefficient'));
}
function renderVariablesTable(variables) {
const container = document.getElementById('variables-table');
container.innerHTML = '';
if (!variables || variables.length === 0) {
container.innerHTML = '<div style="padding: 2rem; text-align: center; color: var(--text-secondary);">No variables found</div>';
return;
}
variables.forEach(variable => {
const row = document.createElement('div');
row.className = 'variable-row';
row.innerHTML = `
<div class="name">${variable.name}</div>
<div class="category">${variable.category}</div>
<div class="priority">
${variable.priority_level ? `<span class="priority-badge priority-${variable.priority_level}">${variable.priority_level}</span>` : '-'}
</div>
<div class="frequency">${variable.frequency}</div>
<div class="coefficient">${variable.coefficient_score.toFixed(3)}</div>
`;
row.addEventListener('click', () => showVariableDetail(variable));
container.appendChild(row);
});
}
function sortVariables(field) {
const sorted = [...filteredVariables].sort((a, b) => {
if (field === 'name') {
return a.name.localeCompare(b.name);
} else if (field === 'frequency') {
return b.frequency - a.frequency;
} else if (field === 'coefficient') {
return b.coefficient_score - a.coefficient_score;
}
return 0;
});
renderVariablesTable(sorted);
}
function initializeSectionsTree() {
const sections = window.appData.sections || [];
const container = document.getElementById('sections-tree');
if (!sections || sections.length === 0) {
container.innerHTML = '<div style="color: var(--text-secondary);">No sections available</div>';
return;
}
const treeData = buildSectionTree(sections);
renderSectionTree(treeData, container);
}
function buildSectionTree(sections) {
const sectionMap = new Map();
const roots = [];
sections.forEach(section => {
sectionMap.set(section.id, { ...section, children: [] });
});
sections.forEach(section => {
if (section.path && section.path.includes('/')) {
const parentPath = section.path.substring(0, section.path.lastIndexOf('/'));
const parent = sections.find(s => s.path === parentPath);
if (parent) {
sectionMap.get(parent.id)?.children.push(sectionMap.get(section.id));
}
} else {
roots.push(sectionMap.get(section.id));
}
});
return roots;
}
function renderSectionTree(tree, container, level = 0) {
tree.forEach(section => {
const div = document.createElement('div');
div.className = `section-item level-${level}`;
div.innerHTML = `
<div class="section-title">${section.title}</div>
${section.content ? `<div class="section-content">${section.content.substring(0, 200)}...</div>` : ''}
`;
container.appendChild(div);
if (section.children && section.children.length > 0) {
renderSectionTree(section.children, container, level + 1);
}
});
}
function initializeModal() {
const modal = document.getElementById('variable-detail-modal');
const closeBtn = modal.querySelector('.close');
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
});
window.addEventListener('click', (e) => {
if (e.target === modal) {
modal.style.display = 'none';
}
});
}
function showVariableDetail(variable) {
const modal = document.getElementById('variable-detail-modal');
const detailContainer = document.getElementById('variable-detail');
let html = `
<div class="detail-header">
<h3>${variable.name}</h3>
${variable.priority_level ? `<span class="priority-badge priority-${variable.priority_level}">Priority ${variable.priority_level}</span>` : ''}
</div>
<div class="detail-section">
<h4>Description</h4>
<p>${variable.description || 'No description available'}</p>
</div>
<div class="detail-section">
<h4>Category</h4>
<p>${variable.category}</p>
</div>
<div class="detail-section">
<h4>Statistics</h4>
<p><strong>Frequency:</strong> ${variable.frequency}</p>
<p><strong>Coefficient Score:</strong> ${variable.coefficient_score.toFixed(3)}</p>
<p><strong>Hard Constraint:</strong> ${variable.is_hard_constraint ? 'Yes' : 'No'}</p>
</div>
<div class="detail-section">
<h4>Principal Assignment</h4>
<p>${variable.principal_assignment || 'Not specified'}</p>
</div>
`;
if (variable.mentions && variable.mentions.length > 0) {
html += `
<div class="detail-section">
<h4>Mentions in Document (${variable.mentions.length})</h4>
<div class="mentions-list">
${variable.mentions.slice(0, 5).map(mention => `
<div class="mention-item">
<div><strong>${mention.section_title || 'Section'}</strong></div>
<div class="mention-context">${mention.context}</div>
</div>
`).join('')}
${variable.mentions.length > 5 ? `<p style="color: var(--text-secondary);">... and ${variable.mentions.length - 5} more mentions</p>` : ''}
</div>
</div>
`;
}
if (variable.related_variables && variable.related_variables.length > 0) {
html += `
<div class="detail-section">
<h4>Related Variables</h4>
<ul>
${variable.related_variables.slice(0, 5).map(rel => `
<li>${rel.name} (${rel.relationship}, weight: ${rel.weight})</li>
`).join('')}
</ul>
</div>
`;
}
detailContainer.innerHTML = html;
modal.style.display = 'block';
}
function initializeOverviewStats() {
const stats = window.appData.charts?.overview_stats || {};
const container = document.getElementById('overview-stats');
const statsData = [
{ label: 'Total Variables', value: stats.total_variables || 0 },
{ label: 'Total Sentences', value: stats.total_sentences || 0 },
{ label: 'Total Tokens', value: stats.total_tokens || 0 },
{ label: 'Unique Tokens', value: stats.unique_tokens || 0 }
];
container.innerHTML = statsData.map(stat => `
<div class="stat-card">
<div class="value">${stat.value.toLocaleString()}</div>
<div class="label">${stat.label}</div>
</div>
`).join('');
}
document.addEventListener('DOMContentLoaded', function() {
if (window.appData.charts) {
initializeOverviewStats();
}
});