/**
* 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();
}
}
}