CoolFace
Apppublic

timoxiliu/word-cloud

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
script.js1218 linesDownload Raw Back to root
1// 工具函数:防抖函数2function debounce(func, wait) {3    let timeout;4    return function executedFunction(...args) {5        const later = () => {6            clearTimeout(timeout);7            func(...args);8        };9        clearTimeout(timeout);10        timeout = setTimeout(later, wait);11    };12}13 14// AI技术关键词数据15const techTerms = {16    "生成式AI": { value: 20, category: "核心技术" },17    "大语言模型": { value: 18, category: "核心技术" },18    "Gemini": { value: 17, category: "模型产品" },19    "GPT-5": { value: 16, category: "模型产品" },20    "DeepSeek": { value: 15, category: "模型产品" },21    "多模态": { value: 15, category: "核心技术" },22    "Agent": { value: 14, category: "应用技术" },23    "混合推理": { value: 14, category: "算法技术" },24    "512K上下文": { value: 13, category: "技术指标" },25    "视频生成": { value: 13, category: "应用技术" },26    "3D建模": { value: 12, category: "应用技术" },27    "智能体": { value: 12, category: "应用技术" },28    "开源": { value: 11, category: "生态发展" },29    "端侧AI": { value: 11, category: "部署方式" },30    "实时翻译": { value: 10, category: "应用技术" },31    "无代码": { value: 10, category: "开发工具" },32    "私有化部署": { value: 9, category: "部署方式" },33    "算力优化": { value: 9, category: "技术优化" },34    "语音助手": { value: 9, category: "应用产品" },35    "决策智能": { value: 8, category: "算法技术" },36    "Transformer": { value: 8, category: "算法架构" },37    "神经网络": { value: 7, category: "算法架构" },38    "机器学习": { value: 7, category: "基础技术" },39    "深度学习": { value: 7, category: "基础技术" },40    "计算机视觉": { value: 6, category: "基础技术" },41    "知识图谱": { value: 6, category: "数据技术" },42    "模式识别": { value: 5, category: "基础技术" },43    "API": { value: 5, category: "开发工具" },44    "边缘计算": { value: 8, category: "部署方式" },45    "联邦学习": { value: 7, category: "算法技术" },46    "强化学习": { value: 6, category: "算法技术" },47    "自监督学习": { value: 6, category: "算法技术" },48    "量子计算": { value: 5, category: "前沿技术" },49    "脑机接口": { value: 4, category: "前沿技术" }50};51 52// 颜色配置53const colors = [54    '#3b82f6', '#8b5cf6', '#ec4899', '#06b6d4', '#10b981', 55    '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4', '#10b981',56    '#f59e0b', '#ef4444', '#6366f1', '#14b8a6', '#f97316'57];58 59// 应用场景数据60const applicationData = [61    { name: '教育科研', value: 25, color: '#3b82f6' },62    { name: '医疗健康', value: 22, color: '#10b981' },63    { name: '智能制造', value: 18, color: '#f59e0b' },64    { name: '金融服务', value: 15, color: '#eab308' },65    { name: '自动驾驶', value: 12, color: '#8b5cf6' },66    { name: '内容创作', value: 8, color: '#ec4899' }67];68 69// 技术成熟度数据70const maturityData = [71    { name: '机器学习', value: 95 },72    { name: '深度学习', value: 90 },73    { name: '计算机视觉', value: 88 },74    { name: '自然语言处理', value: 85 },75    { name: '语音识别', value: 82 },76    { name: '强化学习', value: 75 },77    { name: '生成式AI', value: 70 },78    { name: '多模态AI', value: 65 },79    { name: '量子AI', value: 35 },80    { name: '脑机接口', value: 25 }81];82 83// 趋势发展数据84const trendData = {85    categories: ['2020', '2021', '2022', '2023', '2024', '2025', '2026'],86    series: [87        {88            name: '大语言模型',89            data: [10, 25, 45, 70, 85, 95, 98],90            color: '#3b82f6'91        },92        {93            name: '多模态AI',94            data: [5, 15, 30, 50, 70, 85, 92],95            color: '#8b5cf6'96        },97        {98            name: 'Agent应用',99            data: [2, 8, 20, 40, 65, 80, 90],100            color: '#ec4899'101        },102        {103            name: '端侧AI',104            data: [8, 18, 35, 55, 75, 88, 95],105            color: '#10b981'106        },107        {108            name: '量子AI',109            data: [1, 3, 8, 15, 25, 40, 60],110            color: '#f59e0b'111        }112    ]113};114 115// 全局变量116let wordCloudChart = null;117let applicationChart = null;118let maturityChart = null;119let trendChart = null;120 121// 页面加载完成后初始化122document.addEventListener('DOMContentLoaded', function() {123    // 记录初始屏幕宽度124    window.lastWidth = window.innerWidth;125    126    initializeCharts();127    initializeInteractions();128    initializeAnimations();129});130 131// 初始化图表132function initializeCharts() {133    initWordCloud();134    initApplicationChart();135    initMaturityChart();136    initTrendChart();137}138 139// 初始化词云图140function initWordCloud() {141    try {142        // 检查必要的依赖是否已加载143        if (typeof echarts === 'undefined') {144            throw new Error('ECharts 库未加载');145        }146        147        // 检查词云插件是否已加载148        if (!echarts.registerMap && !echarts.getMap) {149            console.warn('词云插件可能未完全加载,尝试继续初始化...');150        }151        152        const chartDom = document.getElementById('wordCloudChart');153        if (!chartDom) {154            throw new Error('词云图容器元素未找到');155        }156 157        // 确保容器有足够的尺寸158        if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {159            console.warn('词云图容器尺寸为0,等待DOM完全渲染...');160            setTimeout(() => initWordCloud(), 100);161            return;162        }163 164        wordCloudChart = echarts.init(chartDom);165        166        // 获取设备类型和屏幕尺寸(先定义,后使用)167        const screenWidth = window.innerWidth;168        const isMobile = screenWidth < 640;169        const isTablet = screenWidth >= 640 && screenWidth < 1024;170        const isDesktop = screenWidth >= 1024;171        172        // 转换数据格式,根据屏幕大小过滤数据173        let filteredTerms = Object.entries(techTerms);174        175        // 根据屏幕大小过滤数据量176        if (isMobile) {177            // 移动端只显示热度最高的20个词汇178            filteredTerms = filteredTerms179                .sort(([,a], [,b]) => b.value - a.value)180                .slice(0, 20);181        } else if (isTablet) {182            // 平板显示热度最高的25个词汇183            filteredTerms = filteredTerms184                .sort(([,a], [,b]) => b.value - a.value)185                .slice(0, 25);186        }187        188        const wordCloudData = filteredTerms.map(([name, data]) => ({189            name: name,190            value: data.value,191            textStyle: {192                color: colors[Math.floor(Math.random() * colors.length)]193            }194        }));195        196        // 根据设备类型调整参数197        let gridSize, sizeRange, rotationRange, rotationStep;198        199        if (isMobile) {200            gridSize = 3;201            sizeRange = [6, 28];202            rotationRange = [-30, 30];203            rotationStep = 30;204        } else if (isTablet) {205            gridSize = 5;206            sizeRange = [8, 40];207            rotationRange = [-45, 45];208            rotationStep = 15;209        } else {210            gridSize = 8;211            sizeRange = [12, 60];212            rotationRange = [-60, 60];213            rotationStep = 15;214        }215 216        // 尝试使用词云图,如果失败则使用备用方案217        let option;218        219        try {220            option = {221                backgroundColor: 'transparent',222                tooltip: {223                    show: true,224                    backgroundColor: 'rgba(15, 23, 42, 0.9)',225                    borderColor: 'rgba(59, 130, 246, 0.3)',226                    textStyle: {227                        color: '#ffffff',228                        fontSize: isMobile ? 12 : 14229                    },230                    padding: isMobile ? [6, 8] : [10, 12],231                    formatter: function(params) {232                        const category = techTerms[params.name]?.category || '未分类';233                        const fontSize = isMobile ? '12px' : '14px';234                        return `<div style="padding: ${isMobile ? '4px' : '8px'};">235                            <div style="font-weight: bold; color: #3b82f6; font-size: ${fontSize};">${params.name}</div>236                            <div style="margin-top: 4px; color: #94a3b8; font-size: ${isMobile ? '11px' : '13px'};">分类: ${category}</div>237                            <div style="color: #94a3b8; font-size: ${isMobile ? '11px' : '13px'};">热度: ${params.value}</div>238                        </div>`;239                    }240                },241                series: [{242                    type: 'wordCloud',243                    gridSize: gridSize,244                    sizeRange: sizeRange,245                    rotationRange: rotationRange,246                    rotationStep: rotationStep,247                    shape: 'circle',248                    width: '100%',249                    height: '100%',250                    drawOutOfBound: false,251                    layoutAnimation: true,252                    textStyle: {253                        fontFamily: 'Inter, sans-serif',254                        fontWeight: isMobile ? 'normal' : 'bold'255                    },256                    emphasis: {257                        focus: 'self',258                        textStyle: {259                            shadowBlur: isMobile ? 5 : 10,260                            shadowColor: '#3b82f6'261                        }262                    },263                    data: wordCloudData264                }]265            };266            267            wordCloudChart.setOption(option);268            269        } catch (wordCloudError) {270            console.warn('词云图插件不可用,使用备用散点图方案:', wordCloudError);271            272            // 备用方案:使用散点图模拟词云效果273            option = {274                backgroundColor: 'transparent',275                tooltip: {276                    show: true,277                    backgroundColor: 'rgba(15, 23, 42, 0.9)',278                    borderColor: 'rgba(59, 130, 246, 0.3)',279                    textStyle: {280                        color: '#ffffff',281                        fontSize: isMobile ? 12 : 14282                    },283                    formatter: function(params) {284                        const category = techTerms[params.data.name]?.category || '未分类';285                        return `<div style="padding: 8px;">286                            <div style="font-weight: bold; color: #3b82f6;">${params.data.name}</div>287                            <div style="margin-top: 4px; color: #94a3b8;">分类: ${category}</div>288                            <div style="color: #94a3b8;">热度: ${params.data.value}</div>289                        </div>`;290                    }291                },292                xAxis: { show: false, min: 0, max: 100 },293                yAxis: { show: false, min: 0, max: 100 },294                series: [{295                    type: 'scatter',296                    symbolSize: function(data) {297                        return Math.max(isMobile ? 20 : 30, data.value * (isMobile ? 2 : 3));298                    },299                    label: {300                        show: true,301                        formatter: '{@name}',302                        fontSize: function(params) {303                            return Math.max(isMobile ? 10 : 12, params.data.value * 0.8);304                        },305                        color: function(params) {306                            return colors[params.dataIndex % colors.length];307                        },308                        fontWeight: 'bold'309                    },310                    itemStyle: {311                        opacity: 0.1312                    },313                    data: wordCloudData.map((item, index) => ({314                        name: item.name,315                        value: [316                            Math.random() * 80 + 10,317                            Math.random() * 80 + 10,318                            item.value319                        ]320                    }))321                }]322            };323            324            wordCloudChart.setOption(option);325        }326        327        // 添加触摸设备优化328        if ('ontouchstart' in window) {329            // 触摸设备特殊处理330            wordCloudChart.on('click', function(params) {331                if (params.componentType === 'series') {332                    // 触摸设备点击反馈333                    const element = document.getElementById('wordCloudChart');334                    element.style.transform = 'scale(0.98)';335                    setTimeout(() => {336                        element.style.transform = 'scale(1)';337                    }, 150);338                }339            });340        }341 342        // 响应式处理将在全局处理函数中统一处理343 344    } catch (error) {345        console.error('词云图初始化失败:', error);346        // 显示错误信息并提供重试功能347        const chartDom = document.getElementById('wordCloudChart');348        if (chartDom) {349            chartDom.innerHTML = `350                <div class="flex items-center justify-center h-full text-gray-400">351                    <div class="text-center">352                        <i class="fas fa-sync-alt text-4xl mb-4 text-blue-400"></i>353                        <div class="text-lg font-medium mb-2">词云图正在加载中...</div>354                        <div class="text-sm mb-4">如果长时间未显示,请点击重试</div>355                        <button onclick="retryWordCloud()" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors duration-200">356                            <i class="fas fa-redo mr-2"></i>重新加载357                        </button>358                    </div>359                </div>360            `;361        }362        363        // 3秒后自动重试一次364        setTimeout(() => {365            if (chartDom && chartDom.innerHTML.includes('词云图正在加载中')) {366                retryWordCloud();367            }368        }, 3000);369    }370}371 372// 初始化应用分布图373function initApplicationChart() {374    try {375        const chartDom = document.getElementById('applicationChart');376        if (!chartDom) return;377 378        applicationChart = echarts.init(chartDom);379 380        const option = {381            backgroundColor: 'transparent',382            tooltip: {383                trigger: 'item',384                backgroundColor: 'rgba(15, 23, 42, 0.9)',385                borderColor: 'rgba(59, 130, 246, 0.3)',386                textStyle: {387                    color: '#ffffff'388                },389                formatter: '{b}: {c}% ({d}%)'390            },391            legend: {392                orient: window.innerWidth < 768 ? 'horizontal' : 'vertical',393                left: window.innerWidth < 768 ? 'center' : 'left',394                top: window.innerWidth < 768 ? 'top' : 'center',395                bottom: window.innerWidth < 768 ? 'auto' : 'auto',396                textStyle: {397                    color: '#94a3b8',398                    fontSize: window.innerWidth < 768 ? 10 : 12399                }400            },401            series: [402                {403                    type: 'pie',404                    radius: window.innerWidth < 768 ? ['30%', '60%'] : ['40%', '70%'],405                    center: window.innerWidth < 768 ? ['50%', '60%'] : ['60%', '50%'],406                    avoidLabelOverlap: false,407                    itemStyle: {408                        borderRadius: 8,409                        borderColor: 'rgba(15, 23, 42, 0.8)',410                        borderWidth: 2411                    },412                    label: {413                        show: false,414                        position: 'center'415                    },416                    emphasis: {417                        label: {418                            show: true,419                            fontSize: 16,420                            fontWeight: 'bold',421                            color: '#ffffff'422                        },423                        itemStyle: {424                            shadowBlur: 10,425                            shadowOffsetX: 0,426                            shadowColor: 'rgba(59, 130, 246, 0.5)'427                        }428                    },429                    labelLine: {430                        show: false431                    },432                    data: applicationData433                }434            ]435        };436 437        applicationChart.setOption(option);438 439        // 添加触摸设备优化440        if ('ontouchstart' in window) {441            // 触摸设备特殊处理442            wordCloudChart.on('click', function(params) {443                if (params.componentType === 'series') {444                    // 触摸设备点击反馈445                    const element = document.getElementById('wordCloudChart');446                    element.style.transform = 'scale(0.98)';447                    setTimeout(() => {448                        element.style.transform = 'scale(1)';449                    }, 150);450                }451            });452        }453 454        // 响应式处理将在全局处理函数中统一处理455 456    } catch (error) {457        console.error('应用分布图初始化失败:', error);458    }459}460 461// 初始化成熟度图表462function initMaturityChart() {463    try {464        const chartDom = document.getElementById('maturityChart');465        if (!chartDom) return;466 467        maturityChart = echarts.init(chartDom);468 469        const option = {470            backgroundColor: 'transparent',471            tooltip: {472                trigger: 'axis',473                backgroundColor: 'rgba(15, 23, 42, 0.9)',474                borderColor: 'rgba(59, 130, 246, 0.3)',475                textStyle: {476                    color: '#ffffff'477                },478                axisPointer: {479                    type: 'shadow'480                }481            },482            grid: {483                left: '3%',484                right: '4%',485                bottom: '3%',486                containLabel: true487            },488            xAxis: {489                type: 'value',490                max: 100,491                axisLine: {492                    lineStyle: {493                        color: '#374151'494                    }495                },496                axisLabel: {497                    color: '#94a3b8',498                    formatter: '{value}%'499                },500                splitLine: {501                    lineStyle: {502                        color: '#374151'503                    }504                }505            },506            yAxis: {507                type: 'category',508                data: maturityData.map(item => item.name),509                axisLine: {510                    lineStyle: {511                        color: '#374151'512                    }513                },514                axisLabel: {515                    color: '#94a3b8'516                }517            },518            series: [519                {520                    type: 'bar',521                    data: maturityData.map((item, index) => ({522                        value: item.value,523                        itemStyle: {524                            color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [525                                { offset: 0, color: colors[index % colors.length] + '40' },526                                { offset: 1, color: colors[index % colors.length] }527                            ]),528                            borderRadius: [0, 4, 4, 0]529                        }530                    })),531                    barWidth: '60%',532                    label: {533                        show: true,534                        position: 'right',535                        color: '#ffffff',536                        formatter: '{c}%'537                    }538                }539            ]540        };541 542        maturityChart.setOption(option);543 544        window.addEventListener('resize', function() {545            if (maturityChart) {546                maturityChart.resize();547            }548        });549 550    } catch (error) {551        console.error('成熟度图表初始化失败:', error);552    }553}554 555// 初始化趋势图表556function initTrendChart() {557    try {558        const chartDom = document.getElementById('trendChart');559        if (!chartDom) return;560 561        trendChart = echarts.init(chartDom);562 563        const option = {564            backgroundColor: 'transparent',565            tooltip: {566                trigger: 'axis',567                backgroundColor: 'rgba(15, 23, 42, 0.9)',568                borderColor: 'rgba(59, 130, 246, 0.3)',569                textStyle: {570                    color: '#ffffff'571                }572            },573            legend: {574                data: trendData.series.map(s => s.name),575                textStyle: {576                    color: '#94a3b8'577                },578                top: 20579            },580            grid: {581                left: '3%',582                right: '4%',583                bottom: '3%',584                top: '15%',585                containLabel: true586            },587            xAxis: {588                type: 'category',589                boundaryGap: false,590                data: trendData.categories,591                axisLine: {592                    lineStyle: {593                        color: '#374151'594                    }595                },596                axisLabel: {597                    color: '#94a3b8'598                }599            },600            yAxis: {601                type: 'value',602                max: 100,603                axisLine: {604                    lineStyle: {605                        color: '#374151'606                    }607                },608                axisLabel: {609                    color: '#94a3b8',610                    formatter: '{value}%'611                },612                splitLine: {613                    lineStyle: {614                        color: '#374151'615                    }616                }617            },618            series: trendData.series.map(s => ({619                name: s.name,620                type: 'line',621                smooth: true,622                data: s.data,623                lineStyle: {624                    color: s.color,625                    width: 3626                },627                itemStyle: {628                    color: s.color,629                    borderWidth: 2,630                    borderColor: '#ffffff'631                },632                areaStyle: {633                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [634                        { offset: 0, color: s.color + '40' },635                        { offset: 1, color: s.color + '10' }636                    ])637                },638                emphasis: {639                    focus: 'series'640                }641            }))642        };643 644        trendChart.setOption(option);645 646        window.addEventListener('resize', function() {647            if (trendChart) {648                trendChart.resize();649            }650        });651 652    } catch (error) {653        console.error('趋势图表初始化失败:', error);654    }655}656 657// 初始化交互功能658function initializeInteractions() {659    // 词云刷新功能660    const refreshBtn = document.getElementById('refreshWordCloud');661    if (refreshBtn) {662        refreshBtn.addEventListener('click', function() {663            if (wordCloudChart) {664                // 重新生成颜色665                const wordCloudData = Object.entries(techTerms).map(([name, data]) => ({666                    name: name,667                    value: data.value,668                    textStyle: {669                        color: colors[Math.floor(Math.random() * colors.length)]670                    }671                }));672 673                wordCloudChart.setOption({674                    series: [{675                        data: wordCloudData676                    }]677                });678 679                // 按钮动画680                refreshBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>刷新中...';681                setTimeout(() => {682                    refreshBtn.innerHTML = '<i class="fas fa-sync-alt mr-2"></i>刷新';683                }, 1000);684            }685        });686    }687 688    // 词云下载功能689    const downloadBtn = document.getElementById('downloadWordCloud');690    if (downloadBtn) {691        downloadBtn.addEventListener('click', function() {692            if (wordCloudChart) {693                const url = wordCloudChart.getDataURL({694                    type: 'png',695                    pixelRatio: 2,696                    backgroundColor: '#0f172a'697                });698                699                const link = document.createElement('a');700                link.download = 'AI_2025_WordCloud.png';701                link.href = url;702                link.click();703 704                // 下载提示705                downloadBtn.innerHTML = '<i class="fas fa-check mr-2"></i>已下载';706                setTimeout(() => {707                    downloadBtn.innerHTML = '<i class="fas fa-download mr-2"></i>下载';708                }, 2000);709            }710        });711    }712 713    // 导航平滑滚动714    const navLinks = document.querySelectorAll('.nav-link');715    navLinks.forEach(link => {716        link.addEventListener('click', function(e) {717            e.preventDefault();718            const targetId = this.getAttribute('href');719            const targetElement = document.querySelector(targetId);720            if (targetElement) {721                targetElement.scrollIntoView({722                    behavior: 'smooth',723                    block: 'start'724                });725            }726        });727    });728 729    // 返回顶部按钮730    const backToTopBtn = document.getElementById('backToTop');731    if (backToTopBtn) {732        backToTopBtn.addEventListener('click', function() {733            window.scrollTo({734                top: 0,735                behavior: 'smooth'736            });737        });738    }739}740 741// 初始化动画效果742function initializeAnimations() {743    // 滚动进度指示器744    const scrollProgress = document.getElementById('scrollProgress');745    const backToTopBtn = document.getElementById('backToTop');746 747    window.addEventListener('scroll', function() {748        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;749        const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;750        const scrollPercent = (scrollTop / scrollHeight) * 100;751 752        if (scrollProgress) {753            scrollProgress.style.width = scrollPercent + '%';754        }755 756        // 返回顶部按钮显示/隐藏757        if (backToTopBtn) {758            if (scrollTop > 300) {759                backToTopBtn.classList.remove('opacity-0', 'invisible');760                backToTopBtn.classList.add('opacity-100', 'visible');761            } else {762                backToTopBtn.classList.add('opacity-0', 'invisible');763                backToTopBtn.classList.remove('opacity-100', 'visible');764            }765        }766    });767 768    // 卡片悬浮动画769    const techCards = document.querySelectorAll('.tech-card');770    techCards.forEach(card => {771        card.addEventListener('mouseenter', function() {772            this.style.transform = 'translateY(-5px) scale(1.02)';773        });774 775        card.addEventListener('mouseleave', function() {776            this.style.transform = 'translateY(0) scale(1)';777        });778    });779 780    // 应用展示卡片动画781    const applicationCards = document.querySelectorAll('.application-showcase');782    applicationCards.forEach(card => {783        card.addEventListener('mouseenter', function() {784            const img = this.querySelector('img');785            if (img) {786                img.style.transform = 'scale(1.05)';787            }788        });789 790        card.addEventListener('mouseleave', function() {791            const img = this.querySelector('img');792            if (img) {793                img.style.transform = 'scale(1)';794            }795        });796    });797 798    // 趋势卡片动画799    const trendCards = document.querySelectorAll('.trend-card');800    trendCards.forEach(card => {801        card.addEventListener('mouseenter', function() {802            this.style.transform = 'scale(1.02)';803            this.style.boxShadow = '0 10px 30px rgba(59, 130, 246, 0.2)';804        });805 806        card.addEventListener('mouseleave', function() {807            this.style.transform = 'scale(1)';808            this.style.boxShadow = 'none';809        });810    });811 812    // 创新指标动画813    const innovationMetrics = document.querySelectorAll('.innovation-metric');814    innovationMetrics.forEach(metric => {815        metric.addEventListener('mouseenter', function() {816            this.style.transform = 'translateY(-2px)';817            this.style.borderColor = 'rgba(59, 130, 246, 0.6)';818        });819 820        metric.addEventListener('mouseleave', function() {821            this.style.transform = 'translateY(0)';822            this.style.borderColor = 'rgba(59, 130, 246, 0.3)';823        });824    });825 826    // 页面加载动画827    const observer = new IntersectionObserver((entries) => {828        entries.forEach(entry => {829            if (entry.isIntersecting) {830                entry.target.style.opacity = '1';831                entry.target.style.transform = 'translateY(0)';832            }833        });834    }, {835        threshold: 0.1,836        rootMargin: '0px 0px -50px 0px'837    });838 839    // 观察所有需要动画的元素840    const animatedElements = document.querySelectorAll('.tech-card, .application-showcase, .trend-card, .innovation-metric');841    animatedElements.forEach(el => {842        el.style.opacity = '0';843        el.style.transform = 'translateY(20px)';844        el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';845        observer.observe(el);846    });847}848 849// 统一的响应式处理850function handleResize() {851    const currentWidth = window.innerWidth;852    853    // 重新初始化词云图表以适应新的屏幕尺寸854    if (wordCloudChart) {855        // 检查是否需要重新初始化(屏幕尺寸类别发生变化)856        const wasMobile = window.lastWidth < 640;857        const wasTablet = window.lastWidth >= 640 && window.lastWidth < 1024;858        const isMobile = currentWidth < 640;859        const isTablet = currentWidth >= 640 && currentWidth < 1024;860        861        // 如果设备类型发生变化,重新初始化862        if ((wasMobile !== isMobile) || (wasTablet !== isTablet)) {863            wordCloudChart.dispose();864            initWordCloud();865        } else {866            // 否则只调整大小867            wordCloudChart.resize();868        }869    }870    871    if (applicationChart) {872        applicationChart.dispose();873        initApplicationChart();874    }875    876    if (maturityChart) {877        maturityChart.resize();878    }879    880    if (trendChart) {881        trendChart.resize();882    }883    884    // 记录当前宽度885    window.lastWidth = currentWidth;886}887 888// 词云图重试函数889function retryWordCloud() {890    console.log('重试加载词云图...');891    const chartDom = document.getElementById('wordCloudChart');892    if (chartDom) {893        // 显示加载状态894        chartDom.innerHTML = `895            <div class="flex items-center justify-center h-full text-gray-400">896                <div class="text-center">897                    <i class="fas fa-spinner fa-spin text-4xl mb-4 text-blue-400"></i>898                    <div class="text-lg font-medium">正在重新加载词云图...</div>899                </div>900            </div>901        `;902        903        // 销毁现有图表实例904        if (wordCloudChart) {905            wordCloudChart.dispose();906            wordCloudChart = null;907        }908        909        // 延迟重新初始化,确保DOM更新完成910        setTimeout(() => {911            try {912                initWordCloud();913            } catch (error) {914                console.error('重试加载词云图失败:', error);915                chartDom.innerHTML = `916                    <div class="flex items-center justify-center h-full text-gray-400">917                        <div class="text-center">918                            <i class="fas fa-exclamation-triangle text-4xl mb-4 text-red-400"></i>919                            <div class="text-lg font-medium mb-2">词云图加载失败</div>920                            <div class="text-sm mb-4">请检查网络连接或刷新页面</div>921                            <button onclick="location.reload()" class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors duration-200">922                                <i class="fas fa-refresh mr-2"></i>刷新页面923                            </button>924                        </div>925                    </div>926                `;927            }928        }, 500);929    }930}931 932// 添加响应式监听933window.addEventListener('resize', debounce(handleResize, 300));934 935// 工具函数:格式化数字936function formatNumber(num) {937    if (num >= 1000000) {938        return (num / 1000000).toFixed(1) + 'M';939    } else if (num >= 1000) {940        return (num / 1000).toFixed(1) + 'K';941    }942    return num.toString();943}944 945// 工具函数:生成随机颜色946function getRandomColor() {947    return colors[Math.floor(Math.random() * colors.length)];948}949 950// 这个handleResize已经在前面定义了,删除重复声明951 952// 错误处理953window.addEventListener('error', function(e) {954    console.error('页面错误:', e.error);955});956 957// 页面卸载时清理资源958window.addEventListener('beforeunload', function() {959    if (wordCloudChart) {960        wordCloudChart.dispose();961        wordCloudChart = null;962    }963    if (applicationChart) {964        applicationChart.dispose();965        applicationChart = null;966    }967    if (maturityChart) {968        maturityChart.dispose();969        maturityChart = null;970    }971    if (trendChart) {972        trendChart.dispose();973        trendChart = null;974    }975});976 977// 初始化导航功能978function initNavigation() {979    // 平滑滚动到指定区域980    function smoothScrollTo(targetId) {981        const target = document.getElementById(targetId);982        if (target) {983            const navHeight = 64; // 导航栏高度984            const targetPosition = target.offsetTop - navHeight;985            986            window.scrollTo({987                top: targetPosition,988                behavior: 'smooth'989            });990        }991    }992 993    // 绑定导航链接点击事件994    const navLinks = document.querySelectorAll('.nav-link');995    navLinks.forEach(link => {996        link.addEventListener('click', function(e) {997            e.preventDefault();998            const href = this.getAttribute('href');999            if (href && href.startsWith('#')) {1000                const targetId = href.substring(1);1001                smoothScrollTo(targetId);1002            }1003        });1004    });1005 1006    // 高亮当前区域的导航链接1007    function updateActiveNavLink() {1008        const sections = document.querySelectorAll('section[id]');1009        const navHeight = 64;1010        let currentSection = '';1011 1012        sections.forEach(section => {1013            const sectionTop = section.offsetTop - navHeight - 50;1014            const sectionBottom = sectionTop + section.offsetHeight;1015            1016            if (window.scrollY >= sectionTop && window.scrollY < sectionBottom) {1017                currentSection = section.id;1018            }1019        });1020 1021        navLinks.forEach(link => {1022            const href = link.getAttribute('href');1023            if (href && href.startsWith('#')) {1024                const targetId = href.substring(1);1025                if (targetId === currentSection) {1026                    link.classList.add('text-blue-400');1027                    link.classList.remove('text-gray-300');1028                } else {1029                    link.classList.add('text-gray-300');1030                    link.classList.remove('text-blue-400');1031                }1032            }1033        });1034    }1035 1036    // 监听滚动事件更新导航高亮1037    window.addEventListener('scroll', debounce(updateActiveNavLink, 100));1038    1039    // 初始化时更新一次1040    updateActiveNavLink();1041}1042 1043// 初始化移动端菜单1044function initMobileMenu() {1045    const mobileMenuBtn = document.getElementById('mobileMenuBtn');1046    const mobileMenu = document.getElementById('mobileMenu');1047    const mobileMenuLinks = mobileMenu.querySelectorAll('a');1048    1049    if (!mobileMenuBtn || !mobileMenu) {1050        console.warn('移动端菜单元素未找到');1051        return;1052    }1053    1054    // 切换菜单显示/隐藏1055    mobileMenuBtn.addEventListener('click', function() {1056        const isHidden = mobileMenu.classList.contains('hidden');1057        1058        if (isHidden) {1059            mobileMenu.classList.remove('hidden');1060            mobileMenuBtn.innerHTML = '<i class="fas fa-times text-xl"></i>';1061        } else {1062            mobileMenu.classList.add('hidden');1063            mobileMenuBtn.innerHTML = '<i class="fas fa-bars text-xl"></i>';1064        }1065    });1066    1067    // 点击菜单链接时关闭菜单1068    mobileMenuLinks.forEach(link => {1069        link.addEventListener('click', function() {1070            mobileMenu.classList.add('hidden');1071            mobileMenuBtn.innerHTML = '<i class="fas fa-bars text-xl"></i>';1072        });1073    });1074    1075    // 点击页面其他地方时关闭菜单1076    document.addEventListener('click', function(event) {1077        if (!mobileMenuBtn.contains(event.target) && !mobileMenu.contains(event.target)) {1078            mobileMenu.classList.add('hidden');1079            mobileMenuBtn.innerHTML = '<i class="fas fa-bars text-xl"></i>';1080        }1081    });1082    1083    // 窗口大小改变时关闭移动端菜单1084    window.addEventListener('resize', function() {1085        if (window.innerWidth >= 768) {1086            mobileMenu.classList.add('hidden');1087            mobileMenuBtn.innerHTML = '<i class="fas fa-bars text-xl"></i>';1088        }1089    });1090}1091 1092// 统一的响应式处理1093function handleResize() {1094    const currentWidth = window.innerWidth;1095    1096    // 重新初始化词云图表以适应新的屏幕尺寸1097    if (wordCloudChart) {1098        // 检查是否需要重新初始化(屏幕尺寸类别发生变化)1099        const wasMobile = window.lastWidth < 640;1100        const wasTablet = window.lastWidth >= 640 && window.lastWidth < 1024;1101        const isMobile = currentWidth < 640;1102        const isTablet = currentWidth >= 640 && currentWidth < 1024;1103        1104        // 如果设备类型发生变化,重新初始化1105        if ((wasMobile !== isMobile) || (wasTablet !== isTablet)) {1106            wordCloudChart.dispose();1107            initWordCloud();1108        } else {1109            // 否则只调整大小1110            wordCloudChart.resize();1111        }1112    }1113    1114    if (applicationChart) {1115        applicationChart.dispose();1116        initApplicationChart();1117    }1118    1119    if (maturityChart) {1120        maturityChart.resize();1121    }1122    1123    if (trendChart) {1124        trendChart.resize();1125    }1126    1127    // 记录当前宽度1128    window.lastWidth = currentWidth;1129}1130 1131// 词云图重试函数1132function retryWordCloud() {1133    console.log('重试加载词云图...');1134    const chartDom = document.getElementById('wordCloudChart');1135    if (chartDom) {1136        // 显示加载状态1137        chartDom.innerHTML = `1138            <div class="flex items-center justify-center h-full text-gray-400">1139                <div class="text-center">1140                    <i class="fas fa-spinner fa-spin text-4xl mb-4 text-blue-400"></i>1141                    <div class="text-lg font-medium">正在重新加载词云图...</div>1142                </div>1143            </div>1144        `;1145        1146        // 销毁现有图表实例1147        if (wordCloudChart) {1148            wordCloudChart.dispose();1149            wordCloudChart = null;1150        }1151        1152        // 延迟重新初始化,确保DOM更新完成1153        setTimeout(() => {1154            try {1155                initWordCloud();1156            } catch (error) {1157                console.error('重试加载词云图失败:', error);1158                chartDom.innerHTML = `1159                    <div class="flex items-center justify-center h-full text-gray-400">1160                        <div class="text-center">1161                            <i class="fas fa-exclamation-triangle text-4xl mb-4 text-red-400"></i>1162                            <div class="text-lg font-medium mb-2">词云图加载失败</div>1163                            <div class="text-sm mb-4">请检查网络连接或刷新页面</div>1164                            <button onclick="location.reload()" class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors duration-200">1165                                <i class="fas fa-refresh mr-2"></i>刷新页面1166                            </button>1167                        </div>1168                    </div>1169                `;1170            }1171        }, 500);1172    }1173}1174 1175// 添加响应式监听1176window.addEventListener('resize', debounce(handleResize, 300));1177 1178// 页面加载完成后初始化所有功能1179document.addEventListener('DOMContentLoaded', function() {1180    console.log('页面加载完成,开始初始化...');1181    1182    try {1183        // 初始化所有图表1184        initWordCloud();1185        initApplicationChart();1186        initMaturityChart();1187        initTrendChart();1188        1189        // 初始化滚动进度1190        initScrollProgress();1191        1192        // 初始化导航功能1193        initNavigation();1194        1195        // 初始化交互功能1196        initializeInteractions();1197        1198        // 初始化移动端菜单1199        initMobileMenu();1200        

Showing the first 1,200 of 1218 lines. Download the file for the rest.