SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>字母频率分析工具</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3b82f6',
                        secondary: '#f97316',
                        neutral: '#64748b',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .transition-smooth {
                transition: all 0.3s ease;
            }
            .shadow-soft {
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            }
        }
    </style>
</head>
<body class="bg-gray-50 min-h-screen flex flex-col">
    <!-- 顶部导航栏 -->
    <header class="bg-white shadow-sm sticky top-0 z-50">
        <div class="container mx-auto px-4 py-4 flex justify-between items-center">
            <div class="flex items-center space-x-2">
                <i class="fa fa-bar-chart text-primary text-2xl"></i>
                <h1 class="text-xl md:text-2xl font-bold text-gray-800">字母频率分析工具</h1>
            </div>
            <nav>
                <ul class="flex space-x-6">
                    <li><a href="#" class="text-gray-600 hover:text-primary transition-smooth"><i class="fa fa-home mr-1"></i>首页</a></li>
                    <li><a href="#" class="text-gray-600 hover:text-primary transition-smooth"><i class="fa fa-info-circle mr-1"></i>关于</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <!-- 主内容区 -->
    <main class="flex-grow container mx-auto px-4 py-8">
        <!-- 介绍卡片 -->
        <div class="bg-white rounded-xl shadow-soft p-6 mb-8 transform hover:scale-[1.01] transition-smooth">
            <h2 class="text-xl font-bold text-gray-800 mb-3 flex items-center">
                <i class="fa fa-info-circle text-primary mr-2"></i>工具介绍
            </h2>
            <p class="text-gray-600 leading-relaxed">
                这个工具可以帮助你分析文本文件中各个字母的出现频率。只需上传一个文本文件,系统就会自动统计每个字母(区分大小写)的出现次数,并计算其在文本中的百分比。分析结果将以图表和表格的形式展示,便于你直观了解文本的字母分布特征。
            </p>
        </div>

        <!-- 文件上传区 -->
        <div class="bg-white rounded-xl shadow-soft p-6 mb-8">
            <h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
                <i class="fa fa-upload text-primary mr-2"></i>上传文件
            </h2>
            <div id="file-drop-area" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center cursor-pointer hover:border-primary transition-smooth">
                <input type="file" id="file-input" class="hidden" accept=".txt,.pdf,.docx,.rtf">
                <i class="fa fa-file-text-o text-4xl text-gray-400 mb-4"></i>
                <p class="text-gray-500 mb-2">拖放文件到这里,或</p>
                <button id="browse-btn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-4 rounded-lg transition-smooth">
                    <i class="fa fa-folder-open mr-2"></i>浏览文件
                </button>
                <p class="text-xs text-gray-400 mt-4">支持的格式:.txt, .pdf, .docx, .rtf</p>
            </div>
            <div id="file-info" class="hidden mt-4 p-4 bg-gray-50 rounded-lg">
                <div class="flex items-center justify-between">
                    <div class="flex items-center">
                        <i class="fa fa-file-text-o text-primary mr-3"></i>
                        <div>
                            <p id="file-name" class="font-medium text-gray-800 truncate max-w-md"></p>
                            <p id="file-size" class="text-sm text-gray-500"></p>
                        </div>
                    </div>
                    <button id="remove-file" class="text-gray-400 hover:text-red-500 transition-smooth">
                        <i class="fa fa-times-circle text-xl"></i>
                    </button>
                </div>
            </div>
            <button id="analyze-btn" class="mt-6 bg-secondary hover:bg-secondary/90 text-white font-medium py-2 px-6 rounded-lg transition-smooth disabled:opacity-50 disabled:cursor-not-allowed hidden">
                <i class="fa fa-bar-chart mr-2"></i>开始分析
            </button>
        </div>

        <!-- 分析结果区 -->
        <div id="results-section" class="hidden">
            <!-- 结果概览 -->
            <div class="bg-white rounded-xl shadow-soft p-6 mb-8">
                <h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
                    <i class="fa fa-line-chart text-primary mr-2"></i>分析结果概览
                </h2>
                <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <p class="text-sm text-gray-500 mb-1">总字符数</p>
                        <p id="total-chars" class="text-2xl font-bold text-gray-800">0</p>
                    </div>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <p class="text-sm text-gray-500 mb-1">字母总数</p>
                        <p id="total-letters" class="text-2xl font-bold text-gray-800">0</p>
                    </div>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <p class="text-sm text-gray-500 mb-1">处理时间</p>
                        <p id="processing-time" class="text-2xl font-bold text-gray-800">0 ms</p>
                    </div>
                </div>
            </div>

            <!-- 图表展示区 -->
            <div class="bg-white rounded-xl shadow-soft p-6 mb-8">
                <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-4">
                    <h2 class="text-xl font-bold text-gray-800 flex items-center">
                        <i class="fa fa-pie-chart text-primary mr-2"></i>字母频率分布
                    </h2>
                    <div class="mt-2 md:mt-0 flex space-x-2">
                        <button id="show-all-btn" class="bg-primary/10 hover:bg-primary/20 text-primary font-medium py-1 px-3 rounded-lg text-sm transition-smooth">
                            全部字母
                        </button>
                        <button id="show-top10-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-1 px-3 rounded-lg text-sm transition-smooth">
                            前10个
                        </button>
                        <select id="chart-type" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-1 px-3 rounded-lg text-sm transition-smooth">
                            <option value="bar">柱状图</option>
                            <option value="pie">饼图</option>
                        </select>
                    </div>
                </div>
                <div class="w-full h-[400px]">
                    <canvas id="frequency-chart"></canvas>
                </div>
            </div>

            <!-- 详细数据表格 -->
            <div class="bg-white rounded-xl shadow-soft p-6 mb-8">
                <div class="flex justify-between items-center mb-4">
                    <h2 class="text-xl font-bold text-gray-800 flex items-center">
                        <i class="fa fa-table text-primary mr-2"></i>详细数据
                    </h2>
                    <div class="flex items-center">
                        <div class="relative mr-2">
                            <input type="text" id="search-input" placeholder="搜索字母..." class="pl-8 pr-4 py-1 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary">
                            <i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                        </div>
                        <div class="relative">
                            <select id="sort-select" class="pl-3 pr-8 py-1 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary appearance-none bg-white">
                                <option value="letter-asc">按字母排序 (A-Z)</option>
                                <option value="letter-desc">按字母排序 (Z-A)</option>
                                <option value="frequency-asc">按频率排序 (低-高)</option>
                                <option value="frequency-desc">按频率排序 (高-低)</option>
                            </select>
                            <i class="fa fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"></i>
                        </div>
                    </div>
                </div>
                <div class="overflow-x-auto">
                    <table class="min-w-full divide-y divide-gray-200">
                        <thead class="bg-gray-50">
                            <tr>
                                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                    字母
                                </th>
                                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                    出现次数
                                </th>
                                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                    频率 (%)
                                </th>
                                <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                    可视化
                                </th>
                            </tr>
                        </thead>
                        <tbody id="frequency-table-body" class="bg-white divide-y divide-gray-200">
                            <!-- 表格内容将通过 JavaScript 动态填充 -->
                        </tbody>
                    </table>
                </div>
                <div id="no-results" class="hidden py-8 text-center text-gray-500">
                    <i class="fa fa-search-minus text-3xl mb-2"></i>
                    <p>没有找到匹配的结果</p>
                </div>
                <div id="loading-table" class="hidden py-8 text-center text-gray-500">
                    <i class="fa fa-circle-o-notch fa-spin text-3xl mb-2"></i>
                    <p>加载数据中...</p>
                </div>
            </div>

            <!-- 原始文本预览 -->
            <div class="bg-white rounded-xl shadow-soft p-6 mb-8">
                <div class="flex justify-between items-center mb-4">
                    <h2 class="text-xl font-bold text-gray-800 flex items-center">
                        <i class="fa fa-file-text-o text-primary mr-2"></i>原始文本预览
                    </h2>
                    <div class="flex space-x-2">
                        <button id="expand-text-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-1 px-3 rounded-lg text-sm transition-smooth">
                            <i class="fa fa-expand mr-1"></i>展开全部
                        </button>
                        <button id="copy-text-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-1 px-3 rounded-lg text-sm transition-smooth">
                            <i class="fa fa-copy mr-1"></i>复制文本
                        </button>
                    </div>
                </div>
                <div id="text-preview-container" class="relative">
                    <div id="text-preview" class="bg-gray-50 p-4 rounded-lg max-h-60 overflow-y-auto font-mono text-sm">
                        <!-- 文本内容将通过 JavaScript 动态填充 -->
                    </div>
                    <div id="text-gradient" class="absolute bottom-0 left-0 right-0 h-16 bg-gradient-to-t from-gray-50 to-transparent pointer-events-none"></div>
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-gray-800 text-white py-8">
        <div class="container mx-auto px-4">
            <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
                <div>
                    <h3 class="text-lg font-bold mb-4">字母频率分析工具</h3>
                    <p class="text-gray-400 text-sm">
                        这是一个简单实用的文本分析工具,可以帮助你了解文本中各字母的分布情况,适用于语言学习、文本分析等场景。
                    </p>
                </div>
                <div>
                    <h3 class="text-lg font-bold mb-4">快速链接</h3>
                    <ul class="space-y-2 text-sm">
                        <li><a href="#" class="text-gray-400 hover:text-white transition-smooth">首页</a></li>
                        <li><a href="#" class="text-gray-400 hover:text-white transition-smooth">使用指南</a></li>
                        <li><a href="#" class="text-gray-400 hover:text-white transition-smooth">关于我们</a></li>
                    </ul>
                </div>
                <div>
                    <h3 class="text-lg font-bold mb-4">联系我们</h3>
                    <ul class="space-y-2 text-sm">
                        <li class="flex items-center">
                            <i class="fa fa-envelope-o text-gray-400 mr-2"></i>
                            <a href="mailto:contact@example.com" class="text-gray-400 hover:text-white transition-smooth">contact@example.com</a>
                        </li>
                        <li class="flex items-center">
                            <i class="fa fa-github text-gray-400 mr-2"></i>
                            <a href="#" class="text-gray-400 hover:text-white transition-smooth">GitHub</a>
                        </li>
                    </ul>
                </div>
            </div>
            <div class="border-t border-gray-700 mt-8 pt-6 text-center text-gray-400 text-sm">
                <p>&copy; 2025 字母频率分析工具. 保留所有权利.</p>
            </div>
        </div>
    </footer>

    <!-- 加载中模态框 -->
    <div id="loading-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-lg p-6 max-w-sm w-full">
            <div class="text-center">
                <div class="inline-block animate-spin rounded-full h-12 w-12 border-4 border-primary border-t-transparent mb-4"></div>
                <h3 class="text-lg font-bold text-gray-800 mb-2">正在分析文本</h3>
                <p class="text-gray-600" id="loading-message">请稍候,正在处理你的文件...</p>
            </div>
        </div>
    </div>

    <!-- 成功提示模态框 -->
    <div id="success-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-lg p-6 max-w-sm w-full">
            <div class="text-center">
                <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 text-green-500 mb-4">
                    <i class="fa fa-check text-2xl"></i>
                </div>
                <h3 class="text-lg font-bold text-gray-800 mb-2">操作成功</h3>
                <p class="text-gray-600" id="success-message">文本已成功复制到剪贴板</p>
                <button id="close-success-modal" class="mt-4 bg-primary hover:bg-primary/90 text-white font-medium py-2 px-4 rounded-lg transition-smooth">
                    确定
                </button>
            </div>
        </div>
    </div>

    <script>
        // 全局变量
        let fileContent = '';
        let frequencyData = [];
        let chart = null;
        let isTextExpanded = false;

        // DOM 元素
        const fileDropArea = document.getElementById('file-drop-area');
        const fileInput = document.getElementById('file-input');
        const browseBtn = document.getElementById('browse-btn');
        const fileInfo = document.getElementById('file-info');
        const fileName = document.getElementById('file-name');
        const fileSize = document.getElementById('file-size');
        const removeFile = document.getElementById('remove-file');
        const analyzeBtn = document.getElementById('analyze-btn');
        const resultsSection = document.getElementById('results-section');
        const totalChars = document.getElementById('total-chars');
        const totalLetters = document.getElementById('total-letters');
        const processingTime = document.getElementById('processing-time');
        const frequencyChart = document.getElementById('frequency-chart');
        const frequencyTableBody = document.getElementById('frequency-table-body');
        const textPreview = document.getElementById('text-preview');
        const expandTextBtn = document.getElementById('expand-text-btn');
        const copyTextBtn = document.getElementById('copy-text-btn');
        const textGradient = document.getElementById('text-gradient');
        const loadingModal = document.getElementById('loading-modal');
        const loadingMessage = document.getElementById('loading-message');
        const successModal = document.getElementById('success-modal');
        const successMessage = document.getElementById('success-message');
        const closeSuccessModal = document.getElementById('close-success-modal');
        const searchInput = document.getElementById('search-input');
        const sortSelect = document.getElementById('sort-select');
        const showAllBtn = document.getElementById('show-all-btn');
        const showTop10Btn = document.getElementById('show-top10-btn');
        const chartType = document.getElementById('chart-type');
        const noResults = document.getElementById('no-results');
        const loadingTable = document.getElementById('loading-table');

        // 初始化事件监听
        function initEventListeners() {
            // 文件上传相关
            browseBtn.addEventListener('click', () => fileInput.click());
            fileInput.addEventListener('change', handleFileSelect);
            fileDropArea.addEventListener('dragover', handleDragOver);
            fileDropArea.addEventListener('dragleave', handleDragLeave);
            fileDropArea.addEventListener('drop', handleDrop);
            removeFile.addEventListener('click', removeSelectedFile);
            analyzeBtn.addEventListener('click', analyzeText);
            
            // 文本预览相关
            expandTextBtn.addEventListener('click', toggleTextExpansion);
            copyTextBtn.addEventListener('click', copyTextToClipboard);
            closeSuccessModal.addEventListener('click', () => successModal.classList.add('hidden'));
            
            // 结果过滤和排序
            searchInput.addEventListener('input', filterTable);
            sortSelect.addEventListener('change', sortTable);
            showAllBtn.addEventListener('click', showAllLetters);
            showTop10Btn.addEventListener('click', showTop10Letters);
            chartType.addEventListener('change', updateChart);
        }

        // 处理文件选择
        function handleFileSelect(e) {
            const file = e.target.files[0];
            if (file) {
                handleFile(file);
            }
        }

        // 处理拖放事件
        function handleDragOver(e) {
            e.preventDefault();
            fileDropArea.classList.add('border-primary', 'bg-primary/5');
        }

        function handleDragLeave() {
            fileDropArea.classList.remove('border-primary', 'bg-primary/5');
        }

        function handleDrop(e) {
            e.preventDefault();
            fileDropArea.classList.remove('border-primary', 'bg-primary/5');
            
            const file = e.dataTransfer.files[0];
            if (file) {
                handleFile(file);
            }
        }

        // 处理文件
        function handleFile(file) {
            // 验证文件类型
            const allowedTypes = ['text/plain', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/rtf'];
            if (!allowedTypes.includes(file.type) && !file.name.endsWith('.txt') && !file.name.endsWith('.pdf') && !file.name.endsWith('.docx') && !file.name.endsWith('.rtf')) {
                alert('请上传有效的文本文件 (.txt, .pdf, .docx, .rtf)');
                return;
            }

            // 显示文件信息
            fileName.textContent = file.name;
            fileSize.textContent = formatFileSize(file.size);
            fileInfo.classList.remove('hidden');
            analyzeBtn.classList.remove('hidden');

            // 读取文件内容
            const reader = new FileReader();
            reader.onload = function(e) {
                // 检查文件类型
                if (file.type === 'text/plain' || file.name.endsWith('.txt')) {
                    fileContent = e.target.result;
                } else {
                    // 对于非纯文本文件,提供一个通用消息
                    fileContent = `[${file.type === 'application/pdf' ? 'PDF文件' : file.type === 'application/msword' || file.name.endsWith('.docx') ? 'Word文档' : 'RTF文件'}] 无法直接预览内容`;
                }
            };
            reader.readAsText(file);
        }

        // 移除选中的文件
        function removeSelectedFile() {
            fileInput.value = '';
            fileInfo.classList.add('hidden');
            analyzeBtn.classList.add('hidden');
            resultsSection.classList.add('hidden');
            fileContent = '';
            fileDropArea.classList.remove('border-primary', 'bg-primary/5');
        }

        // 分析文本
        function analyzeText() {
            if (!fileContent) return;

            // 显示加载模态框
            loadingMessage.textContent = '正在分析文本...';
            loadingModal.classList.remove('hidden');

            // 模拟加载延迟,实际应用中可以移除
            setTimeout(() => {
                // 分析文本
                const startTime = performance.now();
                frequencyData = analyzeFrequency(fileContent);
                const endTime = performance.now();

                // 更新结果
                updateResults(frequencyData, endTime - startTime);

                // 隐藏加载模态框
                loadingModal.classList.add('hidden');

                // 显示结果区域
                resultsSection.classList.remove('hidden');

                // 平滑滚动到结果区域
                resultsSection.scrollIntoView({ behavior: 'smooth' });
            }, 800);
        }

        // 分析字母频率
        function analyzeFrequency(text) {
            const frequency = {};
            let total = 0;

            // 统计每个字符的出现次数
            for (let char of text) {
                // 只考虑字母
                if (/[a-zA-Z]/.test(char)) {
                    frequency[char] = (frequency[char] || 0) + 1;
                    total++;
                }
            }

            // 转换为数组并计算频率百分比
            const frequencyArray = Object.keys(frequency).map(char => ({
                letter: char,
                count: frequency[char],
                frequency: (frequency[char] / total * 100).toFixed(2)
            }));

            // 按频率降序排序
            frequencyArray.sort((a, b) => b.count - a.count);

            return frequencyArray;
        }

        // 更新结果显示
        function updateResults(data, time) {
            // 更新概览信息
            totalChars.textContent = fileContent.length;
            totalLetters.textContent = data.reduce((sum, item) => sum + item.count, 0);
            processingTime.textContent = `${time.toFixed(0)} ms`;

            // 更新文本预览
            textPreview.textContent = fileContent.length > 1000 ? fileContent.substring(0, 1000) + '...' : fileContent;
            isTextExpanded = false;
            updateTextPreviewUI();

            // 更新图表
            updateChart();

            // 更新表格
            updateTable(data);
        }

        // 更新文本预览UI
        function updateTextPreviewUI() {
            if (isTextExpanded || fileContent.length <= 1000) {
                textGradient.classList.add('hidden');
                expandTextBtn.innerHTML = '<i class="fa fa-compress mr-1"></i>收起';
            } else {
                textGradient.classList.remove('hidden');
                expandTextBtn.innerHTML = '<i class="fa fa-expand mr-1"></i>展开全部';
            }
        }

        // 切换文本展开/收起状态
        function toggleTextExpansion() {
            isTextExpanded = !isTextExpanded;
            
            if (isTextExpanded) {
                textPreview.textContent = fileContent;
            } else {
                textPreview.textContent = fileContent.length > 1000 ? fileContent.substring(0, 1000) + '...' : fileContent;
            }
            
            updateTextPreviewUI();
        }

        // 复制文本到剪贴板
        function copyTextToClipboard() {
            navigator.clipboard.writeText(fileContent)
                .then(() => {
                    successMessage.textContent = '文本已成功复制到剪贴板';
                    successModal.classList.remove('hidden');
                })
                .catch(err => {
                    console.error('复制失败: ', err);
                    successMessage.textContent = '复制失败,请手动复制';
                    successModal.classList.remove('hidden');
                });
        }

        // 更新图表
        function updateChart() {
            // 销毁现有图表
            if (chart) {
                chart.destroy();
            }

            // 获取数据
            let displayData = [...frequencyData];
            if (showTop10Btn.classList.contains('bg-primary/10')) {
                displayData = displayData.slice(0, 10);
            }

            // 准备图表数据
            const labels = displayData.map(item => item.letter);
            const counts = displayData.map(item => item.count);
            const frequencies = displayData.map(item => parseFloat(item.frequency));

            // 设置图表配置
            const ctx = frequencyChart.getContext('2d');
            const isBarChart = chartType.value === 'bar';
            
            chart = new Chart(ctx, {
                type: isBarChart ? 'bar' : 'pie',
                data: isBarChart ? {
                    labels: labels,
                    datasets: [{
                        label: '出现次数',
                        data: counts,
                        backgroundColor: 'rgba(59, 130, 246, 0.7)',
                        borderColor: 'rgba(59, 130, 246, 1)',
                        borderWidth: 1
                    }, {
                        label: '频率 (%)',
                        data: frequencies,
                        backgroundColor: 'rgba(249, 115, 22, 0.7)',
                        borderColor: 'rgba(249, 115, 22, 1)',
                        borderWidth: 1,
                        yAxisID: 'y1'
                    }]
                } : {
                    labels: labels,
                    datasets: [{
                        data: frequencies,
                        backgroundColor: [
                            'rgba(59, 130, 246, 0.7)',
                            'rgba(249, 115, 22, 0.7)',
                            'rgba(16, 185, 129, 0.7)',
                            'rgba(139, 92, 246, 0.7)',
                            'rgba(236, 72, 153, 0.7)',
                            'rgba(245, 158, 11, 0.7)',
                            'rgba(220, 38, 38, 0.7)',
                            'rgba(37, 99, 235, 0.7)',
                            'rgba(16, 185, 129, 0.7)',
                            'rgba(239, 68, 68, 0.7)',
                            'rgba(124, 58, 237, 0.7)',
                            'rgba(21, 128, 61, 0.7)',
                            'rgba(249, 115, 22, 0.7)',
                            'rgba(37, 99, 235, 0.7)',
                            'rgba(16, 185, 129, 0.7)',
                            'rgba(239, 68, 68, 0.7)',
                            'rgba(124, 58, 237, 0.7)',
                            'rgba(21, 128, 61, 0.7)',
                            'rgba(249, 115, 22, 0.7)',
                            'rgba(37, 99, 235, 0.7)',
                            'rgba(16, 185, 129, 0.7)',
                            'rgba(239, 68, 68, 0.7)',
                            'rgba(124, 58, 237, 0.7)',
                            'rgba(21, 128, 61, 0.7)'
                        ],
                        borderWidth: 1
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: isBarChart ? 'top' : 'right',
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    if (isBarChart) {
                                        const label = context.dataset.label || '';
                                        const value = context.datasetIndex === 0 ? 
                                            context.parsed.y : 
                                            context.parsed.y.toFixed(2) + '%';
                                        return `${label}: ${value}`;
                                    } else {
                                        const label = context.label || '';
                                        const value = context.raw.toFixed(2);
                                        return `${label}: ${value}%`;
                                    }
                                }
                            }
                        }
                    },
                    scales: isBarChart ? {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: '出现次数'
                            }
                        },
                        y1: {
                            beginAtZero: true,
                            position: 'right',
                            title: {
                                display: true,
                                text: '频率 (%)'
                            },
                            grid: {
                                drawOnChartArea: false,
                            }
                        }
                    } : {}
                }
            });
        }

        // 更新表格
        function updateTable(data) {
            // 清空表格
            frequencyTableBody.innerHTML = '';
            noResults.classList.add('hidden');
            
            // 显示加载状态
            loadingTable.classList.remove('hidden');
            
            // 模拟加载延迟,实际应用中可以移除
            setTimeout(() => {
                // 隐藏加载状态
                loadingTable.classList.add('hidden');
                
                // 填充表格
                if (data.length === 0) {
                    noResults.classList.remove('hidden');
                    return;
                }
                
                data.forEach((item, index) => {
                    const row = document.createElement('tr');
                    row.className = index % 2 === 0 ? 'bg-white' : 'bg-gray-50';
                    
                    // 计算条形图宽度
                    const maxFrequency = Math.max(...data.map(d => parseFloat(d.frequency)));
                    const barWidth = (parseFloat(item.frequency) / maxFrequency * 100) + '%';
                    
                    row.innerHTML = `
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="flex items-center">
                                <div class="w-8 h-8 flex items-center justify-center bg-primary/10 text-primary rounded-full mr-3">
                                    <span class="font-medium">${item.letter}</span>
                                </div>
                                <span class="font-medium text-gray-900">${item.letter}</span>
                            </div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <span class="text-gray-900">${item.count}</span>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <span class="text-gray-900">${item.frequency}</span>
                        </td>
                        <td class="px-6 py-4">
                            <div class="w-full bg-gray-200 rounded-full h-2.5">
                                <div class="bg-primary h-2.5 rounded-full" style="width: ${barWidth}"></div>
                            </div>
                        </td>
                    `;
                    
                    frequencyTableBody.appendChild(row);
                });
            }, 300);
        }

        // 过滤表格
        function filterTable() {
            const searchTerm = searchInput.value.toLowerCase();
            const filteredData = frequencyData.filter(item => 
                item.letter.toLowerCase().includes(searchTerm)
            );
            
            updateTable(filteredData);
        }

        // 排序表格
        function sortTable() {
            const sortBy = sortSelect.value;
            let sortedData = [...frequencyData];
            
            switch (sortBy) {
                case 'letter-asc':
                    sortedData.sort((a, b) => a.letter.localeCompare(b.letter));
                    break;
                case 'letter-desc':
                    sortedData.sort((a, b) => b.letter.localeCompare(a.letter));
                    break;
                case 'frequency-asc':
                    sortedData.sort((a, b) => parseFloat(a.frequency) - parseFloat(b.frequency));
                    break;
                case 'frequency-desc':
                    sortedData.sort((a, b) => parseFloat(b.frequency) - parseFloat(a.frequency));
                    break;
            }
            
            updateTable(sortedData);
        }

        // 显示全部字母
        function showAllLetters() {
            showAllBtn.classList.remove('bg-gray-100', 'hover:bg-gray-200', 'text-gray-700');
            showAllBtn.classList.add('bg-primary/10', 'hover:bg-primary/20', 'text-primary');
            
            showTop10Btn.classList.remove('bg-primary/10', 'hover:bg-primary/20', 'text-primary');
            showTop10Btn.classList.add('bg-gray-100', 'hover:bg-gray-200', 'text-gray-700');
            
            updateTable(frequencyData);
            updateChart();
        }

        // 显示前10个字母
        function showTop10Letters() {
            showTop10Btn.classList.remove('bg-gray-100', 'hover:bg-gray-200', 'text-gray-700');
            showTop10Btn.classList.add('bg-primary/10', 'hover:bg-primary/20', 'text-primary');
            
            showAllBtn.classList.remove('bg-primary/10', 'hover:bg-primary/20', 'text-primary');
            showAllBtn.classList.add('bg-gray-100', 'hover:bg-gray-200', 'text-gray-700');
            
            const top10Data = frequencyData.slice(0, 10);
            updateTable(top10Data);
            updateChart();
        }

        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        // 初始化应用
        function initApp() {
            initEventListeners();
            console.log('应用已初始化');
        }

        // 页面加载完成后初始化应用
        document.addEventListener('DOMContentLoaded', initApp);
    </script>
</body>
</html>