/** * FeatureFilterUI - 特征筛选UI类 * 负责渲染和管理特征筛选面板的UI交互 */ class FeatureFilterUI { constructor(featureFilter, onFilterChange) { this.featureFilter = featureFilter; this.onFilterChange = onFilterChange; // 筛选变化时的回调函数 this.currentCategory = null; this.isExpanded = false; } /** * 初始化UI */ async init() { try { // 加载特征数据 await this.featureFilter.loadCategoryData(); const data = this.featureFilter.getCategoryData(); if (data && data.data) { // 渲染分类标签页 this.renderCategoryTabs(data.data); // 绑定事件 this.bindEvents(); console.log('✓ 特征筛选UI初始化完成'); } } catch (error) { console.error('✗ 特征筛选UI初始化失败:', error); } } /** * 渲染分类标签页 * @param {Array} categories - 分类数组 */ renderCategoryTabs(categories) { const container = document.getElementById('feature-categories'); if (!container) return; container.innerHTML = ''; categories.forEach((cat, index) => { const tab = document.createElement('button'); tab.className = 'category-tab'; tab.textContent = cat.category; tab.dataset.categoryKey = cat.key; // 默认选中第一个分类 if (index === 0) { tab.classList.add('active'); this.currentCategory = cat; } tab.addEventListener('click', () => { this.handleCategoryChange(cat, tab); }); container.appendChild(tab); }); // 渲染第一个分类的特征列表 if (categories.length > 0) { this.renderFeatureList(categories[0]); } } /** * 处理分类切换 * @param {Object} category - 分类对象 * @param {HTMLElement} tab - 标签元素 */ handleCategoryChange(category, tab) { // 更新标签激活状态 document.querySelectorAll('.category-tab').forEach(t => { t.classList.remove('active'); }); tab.classList.add('active'); // 更新当前分类 this.currentCategory = category; // 渲染该分类的特征列表 this.renderFeatureList(category); } /** * 渲染特征列表 * @param {Object} category - 分类对象 */ renderFeatureList(category) { const container = document.getElementById('feature-list'); if (!container) return; container.innerHTML = ''; if (!category || !category.list) return; category.list.forEach(feature => { const featureKey = `${category.category}_${feature.feature}`; const isSelected = this.featureFilter.selectedFeatures.has(featureKey); const item = document.createElement('label'); item.className = 'feature-item'; item.innerHTML = ` ${feature.feature} ${feature.num} ${feature.percent}% `; const checkbox = item.querySelector('input'); checkbox.addEventListener('change', (e) => { this.handleFeatureToggle( category.category, feature.feature, feature.items, e.target.checked ); }); container.appendChild(item); }); } /** * 处理特征选择切换 * @param {string} category - 分类名称 * @param {string} feature - 特征名称 * @param {Array} items - PFP编号数组 * @param {boolean} isChecked - 是否选中 */ handleFeatureToggle(category, feature, items, isChecked) { const featureKey = `${category}_${feature}`; if (isChecked) { this.featureFilter.selectFeature(category, feature, items); } else { this.featureFilter.deselectFeature(featureKey); } this.updateSelectedCount(); } /** * 更新已选特征数量显示 */ updateSelectedCount() { const countEl = document.getElementById('selected-count'); if (!countEl) return; const count = this.featureFilter.selectedFeatures.size; if (count > 0) { countEl.textContent = `(已选${count}项)`; countEl.style.display = 'inline'; } else { countEl.style.display = 'none'; } } /** * 切换面板展开/折叠 */ togglePanel() { const panel = document.getElementById('feature-filter-panel'); const toggle = document.getElementById('feature-filter-toggle'); if (!panel || !toggle) return; this.isExpanded = !this.isExpanded; if (this.isExpanded) { panel.style.display = 'block'; toggle.classList.add('expanded'); } else { panel.style.display = 'none'; toggle.classList.remove('expanded'); } } /** * 绑定所有事件 */ bindEvents() { // 折叠按钮 const toggleBtn = document.getElementById('feature-filter-toggle'); if (toggleBtn) { toggleBtn.addEventListener('click', () => { this.togglePanel(); }); } // 逻辑模式切换 const logicRadios = document.querySelectorAll('input[name="filter-logic"]'); logicRadios.forEach(radio => { radio.addEventListener('change', (e) => { this.featureFilter.setLogicMode(e.target.value); }); }); // 应用筛选按钮 const applyBtn = document.getElementById('apply-feature-filter'); if (applyBtn) { applyBtn.addEventListener('click', () => { if (this.onFilterChange) { this.onFilterChange(); } }); } // 清除筛选按钮 const clearBtn = document.getElementById('clear-feature-filter'); if (clearBtn) { clearBtn.addEventListener('click', () => { this.clearAllFilters(); }); } } /** * 清除所有筛选 */ clearAllFilters() { this.featureFilter.clearAllSelections(); this.updateSelectedCount(); // 重新渲染当前分类的特征列表 if (this.currentCategory) { this.renderFeatureList(this.currentCategory); } // 触发筛选变化回调 if (this.onFilterChange) { this.onFilterChange(); } } }