
简介面向计算机设计大赛参赛者与信息可视化学习者这份获奖源码包以中国野生动物保护为主题完整展现从多源数据收集、处理到地图、图表、动画展示的实现链路既可作为赛题方案参考也适合动手拆解实战从数据接入到视觉呈现形成完整项目闭环。压缩包共67个文件、约85.4MB核心包括16个html页面模块、14个js脚本承载ECharts绘图与交互逻辑、7个css样式控制风格另含多张png与jpg格式的图表素材以及4个mp4演示视频和1份README说明目录按页面功能组织便于定位和复用。已有263人学习下载。内容完整呈现获奖项目的页面拆分、可视化配置与素材组织方式读者可快速复用中国地图、图表动画等技术点配套演示视频可辅助还原页面运行效果对准备比赛或想提升前端表达能力的开发者有直接借鉴价值也可作为课程设计与毕业设计的参考模板。1. 中国野生动物保护可视化一个大赛项目源码里的信息可视化工程思维如果你打开这份【中国大学生计算机设计大赛信息可视化赛道】获奖项目源码第一眼会看到满屏的 HTML 文件和几十个 JS、CSS 文件这不是一个简单的前端作业而是一个把地理数据、统计图表、大屏交互、多页面叙事揉在一起的完整信息可视化作品。项目以中国野生动物保护为主题用 ECharts 绘制地图与图表用一套多页面结构承载从数据概览到区域详情的讲述逻辑值得拆解的不仅是怎么画图更是如何把一个抽象的保护议题转化成用户能看的、能点的、能感受到的可视化流程。适合读这篇的人要参加信息可视化或计算机设计大赛的选手想找一个成熟 ECharts 大屏项目做参考的工程师以及手里有野生动物数据但不知道怎么落成可视化产品的开发者。下面的分析全部基于源码目录结构和常见 ECharts 大屏实现路径我会带你从架构、数据、地图、适配、交互五个角度逐层拆开最后给你一套可复用的改造方法。2. 多页面可视化架构ECharts 大屏项目的文件组织与页面叙事逻辑2.1 源码文件结构里的分层思路先看压缩包里出现的高频文件one.html到ten.html十个 HTML 页面、page2.html、page3.html、example.html、index.html以及css、js、img、data四个核心目录。这种命名方式说明项目是按页面导航来组织的不是单页应用而是多个独立 HTML 页面通过链接或 JS 跳转串联成一个完整故事线。这种多页面结构非常适合信息可视化大赛作品。它有几个好处一是每个页面主题聚焦可以独立开发和调试二是页面切换时视觉冲击力强不像 SPA 那么平淡三是评审演示时不需要频繁等待异步加载。缺点是全局状态共享需要额外设计比如主题色、地图缩放级别、滚动状态通常用 localStorage 或 URL 参数解决。从目录看js下既有echarts.min.js、china.js这样的库文件也有innnn.js、fundation.js、index2.js、area_echarts.js这样的业务脚本说明作者把图表初始化、地图配置、数据请求拆成了多个模块。data目录里是nei.js、inde.js这类数据文件直接以 JS 变量形式存在不请求后端适合大赛现场演示的离线环境。2.2 页面叙事流程设计信息可视化项目不是把图表堆在页面上而是要让用户按顺序理解一个故事。从one.html、two.html到ten.html以及last2.html、top.html可以推断出大致叙事线先是大屏首页展示总览index 或 top再分主题进入具体图表页面最后可能是结语页。每个页面用style1.css、style2.css、page2.css、page3.css等独立样式说明页面之间视觉基调一致但局部差异较大。对比常见的大赛获奖项目这种叙事顺序通常遵循「总览 → 分区域 → 分物种 → 趋势 → 保护措施」的逻辑。比如一个页面展示中国地图上野生动物的分布热度另一个页面展示具体物种数量变化再用一个页面展示各保护区的覆盖范围。这种设计在答辩时特别容易讲清楚从宏观地理到微观细节评审跟着走一遍就理解了数据价值。下面用一个表格梳理这套项目中可能存在的页面分工和对应的可视化角色页面文件常见可视化角色承载的数据类型one.html全国概览大屏总物种数、保护级别统计two.html 至 five.html分类专题展示哺乳类、鸟类、爬行类等six.html 至 nine.html区域/省份分析行政区划分布、保护区数据ten.html趋势与对比逐年数量变化、多指标折线/柱状last2.html总结与展望综合指标、政策信息page2/page3辅助详情页具体数据表、图片集2.3 为什么用 ECharts 而不是其他可视化库项目里核心绘图库是echarts.min.js和echarts-plain-map.js配合china.js地图数据文件。选择 ECharts 的原因从工程角度非常好解释首先它能直接注册中国地图 JSON 并支持 geo 坐标系其次visualMap组件直接把数值映射到颜色省去了自己计算颜色插值的代码第三它的dispatchAction可以触发高亮、展示动画适合大屏演示的舞台效果。如果你熟悉 D3.js 或 AntV会发现 ECharts 的声明式配置更接近“配置即图表”源码里大部分业务 JS 都是在拼option对象。这也是大赛项目最合适的方案——你不需要从头实现绘制逻辑把精力放在数据分析和交互设计上。china.js这个文件实际就是中国地图的 GeoJSON 数据经过 ECharts 转换后的注册代码里面包含各省份的边界坐标和名称。在后面的章节里我会重点拆china.js怎么用因为很多人在多页面项目里重复注册地图导致冲突或者地图数据没加载就执行setOption导致空白。这些坑在大赛现场出过很多次。3. 中国地图与物种数据绑定visualMap 配置、地图注册和坐标数据处理3.1 注册中国地图的三条关键命令项目中的china.js不是 ECharts 标准文件它是把中国地图 GeoJSON 数据封装成echarts.registerMap(china, {...})形式的脚本。在任何一个页面使用地图之前必须先加载这个文件否则map: china的配置会失效。我一般会在每个页面的底部引入并在业务脚本里加一个判断// 确认地图已注册避免 setOption 时找不到地图 if (echarts.getMap(china)) { console.log(china map registered); } else { console.error(china map not found, check china.js loaded); } initChinaEchart();逻辑说明echarts.getMap(china)返回地图对象如果为 undefined说明china.js没有被正确加载或者加载顺序排在初始化脚本之后。比赛中经常出现把业务 JS 放在 head 里而china.js放在 body 底部初始化脚本执行时地图还没注册此时setOption里引用map: china就会在控制台报错页面地图区域空白。参数说明registerMap的第一个参数是地图名字必须和series里map字段一致第二个参数是 GeoJSON 对象第三个参数可选用于指定区域名称是否需要特殊处理。实际项目中china.js文件往往体积很大约 200KB 到 500KB所以它不应该和echarts.min.js合并压缩要保持单独文件路径方便浏览器缓存。3.2 用 visualMap 把野生动物数量映射到颜色核心可视化逻辑在area_echarts.js或index2.js这类脚本里。下面是一段典型的中国地图分布配置与项目里常见的做法一致var option { tooltip: { trigger: item, formatter: function (params) { if (params.value) { return params.name br/物种数量 params.value; } return params.name br/暂无数据; } }, visualMap: { min: 0, max: 800, left: left, top: bottom, text: [高, 低], calculable: true, inRange: { color: [#e0f3f8, #abd9e9, #74add1, #4575b4, #313695] } }, series: [{ name: 重点保护物种, type: map, map: china, roam: true, label: { show: true, fontSize: 10 }, data: [ { name: 四川, value: 320 }, { name: 云南, value: 480 }, { name: 青海, value: 260 } ] }] }; chinaChart.setOption(option);逻辑说明visualMap会把series.data中每个数据项的value映射到inRange.color数组对应的颜色区间。数据值越大颜色越深直观表达保护物种集中区域。roam: true允许地图缩放和平移在展示西部高密度区域时可以手动放大这是大屏演示中常用的交互。label.show控制省份名称是否显示数据点多的页面建议设为false并用tooltip承接细节避免文字遮挡地图边界。参数说明visualMap的min和max不必严格等于数据最大最小值可以适当放大比如最大 600 的全国数据设置成max: 800否则颜色会过早饱和。calculable: true会在左下角生成一个可拖拽的滑块演示时评委可以直接拖动滑块筛选数值区间这个细节在大赛现场很加分。inRange的颜色数组顺序是从小到大建议使用同一个色相渐变不要用红黄绿这种多色相因为野生动物保护主题需要严肃氛围蓝色系或绿色系更合适。3.3 离散型数据展示不同保护级别的分布如果数据不是连续数值而是类似“一级保护动物 12 种二级保护动物 58 种”这种分类统计继续用visualMap就不合适了。项目里很可能用piecewise分段视觉映射来处理配置如下visualMap: { type: piecewise, splitNumber: 3, pieces: [ { min: 50, label: 极危物种聚集区 }, { min: 20, max: 49, label: 重点分布区 }, { min: 0, max: 19, label: 一般分布区 } ], inRange: { color: [#d73027, #fc8d59, #fee08b] } }逻辑说明pieces数组定义了三个区间每个区间有独立的标签和颜色。省份数据值落入哪个区间就显示哪个颜色。这种方式比连续的visualMap更适合保护级别的分类表达同时可以把标签写到图例上避免右侧小滑块造成误解。参数说明splitNumber和pieces二选一即可。如果只想分三段直接写splitNumber: 3会自动均匀切分但如果数据分布不均匀比如大部分省份都是个位数只有四川 500自动切分会导致所有省份都显示同一个颜色此时必须用pieces手动设边界。另外type: piecewise时min、max字段不需要写写了也会被忽略。3.4 地图初始化时最常见的三个空白问题项目里有test.js、innnn.js等测试调试脚本说明作者也是在不断排错中整理的。地图页面出现空白一般有几种原因第一容器没有高度。ECharts 初始化之前div的 CSS 必须有明确的height否则图表高度为 0。大屏项目里常见做法是给地图容器设置position: absolute; top: 0; left: 0; width: 100%; height: 100%;并且父容器也要有高度不能只依赖vh。第二地图数据加载异步问题。china.js是同步脚本但如果用模块加载器或者延迟加载可能registerMap还没执行完就setOption。解决办法是用window.addEventListener(load, initChart)或直接在业务脚本开头检查echarts.getMap(china)。第三省份名称不匹配。china.js里注册的名称是标准简称比如“内蒙古”“新疆”如果数据里写的是“内蒙古自治区”或“新疆维吾尔自治区”ECharts 无法自动匹配会显示该省份无数据。在拼接数据前建议先用Object.keys(echarts.getMap(china).geoJson.features)打印所有可用名称再映射自己的数据。4. 高速大屏适配与样式基础rem.js 原理、LESS 变量和网格布局4.1 为什么大屏项目都会带一个 rem.js 或 vw/vh 适配脚本源码里有rem.js还有一个DS-DIGIT.TTF字体这两个东西组合起来就是大屏可视化的标配。rem.js的核心逻辑是监听窗口大小变化动态计算根元素的font-size让页面里所有使用rem单位的元素按比例缩放。而DS-DIGIT是数码管风格的数字字体用在数据仪表盘上很有科技感和普通中文字体搭配时需要注意基线对齐。一个典型的rem.js实现大致是这样的(function (doc, win) { var docEl doc.documentElement; var resizeEvt orientationchange in window ? orientationchange : resize; var recalc function () { var clientWidth docEl.clientWidth; if (!clientWidth) return; // 以设计稿宽度 1920 为基准1rem 100px docEl.style.fontSize 100 * (clientWidth / 1920) px; }; if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener(DOMContentLoaded, recalc, false); })(document, window);逻辑说明这段代码把根元素font-size绑定到视口宽度。设计稿是 1920 宽当浏览器宽度是 1920 时1rem 100px宽度缩到 1280 时1rem 66.7px整个页面等比缩小。这种方式最适合演示大屏因为无论投屏还是笔记本预览所有模块都会保持相对位置。参数说明基准宽度不一定非要 1920如果项目设计稿是 1366就改成100 * (clientWidth / 1366)。注意100这个倍率是为了方便计算stylewidth: 3rem就等于300px设计稿像素。但rem缩放不适合文字过小的页面因为缩小到 768 宽度时1rem变小文字可能小于 12px容易出现锯齿所以一些固定描述文字建议继续用px写死。4.2 用 LESS 变量统一大屏主题色项目里有index.less和多个 CSS 文件。LESS 文件在大赛项目里起的主要作用是抽离主题变量。比如整个可视化作品主色调是深蓝背景加亮青点缀那么可以这样定义bg-deep: #0a1e3f; bg-panel: rgba(6, 30, 60, 0.8); text-main: #cde1ff; text-highlight: #24d5e8; border-glow: #1a6fb5; .container-panel { background: bg-panel; border: 1px solid border-glow; box-shadow: 0 0 20px fade(border-glow, 30%); color: text-main; .title { color: text-highlight; font-family: DS-DIGIT, sans-serif; } }逻辑说明LESS 变量编译成 CSS 后所有用到bg-panel的地方统一替换。改主题时只需改变量定义不用搜遍全部样式。源码里有很多style1.css、style2.css等文件说明每个页面可能各自定义了一套变量但同一个大屏应该保持主色一致否则页面跳转会非常突兀。参数说明fade(border-glow, 30%)是 LESS 内置函数生成带有透明度的边框光晕比手写rgba(26, 111, 181, 0.3)更直观。如果要适配暗色大屏背景建议用rgba而不是纯色这样如果底图切到展示视频时面板不会完全遮挡背景。4.3 布局把控从绝对定位到网格布局的取舍大屏页面常见的两块内容左边是多个小图标面板中间是大地图右边是数据滚动列表。源码里的page2.html、page3.html应该就是这样布局。我看过很多参赛项目最容易出的问题是绝对定位嵌套太多导致分辨率改变时面板互相重叠。一种稳妥做法是使用 CSS Grid 布局给大屏页面搭一个 12 列网格.dashboard { display: grid; grid-template-columns: repeat(12, 1fr); grid-template-rows: 60px 1fr 40px; gap: 10px; height: 100vh; padding: 10px; } .map-panel { grid-column: 3 / 11; grid-row: 2 / 3; } .left-panel { grid-column: 1 / 3; grid-row: 2 / 3; } .right-panel { grid-column: 11 / 13; grid-row: 2 / 3; }逻辑说明左右面板各占 2 列中间地图占 8 列这样在 16:9 屏幕上比例协调。左侧列表显示各省数据右侧放图例和趋势小图中间地图区域最大。比绝对定位的优势在于即使浏览器窗口不是正好 16:9Grid 也会自动压缩拉伸各区域不会出现大面积黑边。参数说明grid-template-rows: 60px 1fr 40px里的1fr代表中间区域占据剩余所有空间这是自适应最关键的写法。如果项目里仍然用绝对定位建议至少给地图容器设置calc(100vh - 100px)防止溢出。另外不要在 Grid 容器直接加overflow: hidden否则弹窗或 tooltip 可能被截断。5. 多页面跳转、图表动画与视频资源的整合技巧5.1 页面导航逻辑从 one.html 到 ten.html 的传递参数十个页面之间需要保持数据状态一致源码里没有明显看到后端所以大概率用 URL 查询参数或 localStorage 传递当前选中的省份、时间点等信息。一个简单但有效的实现方式是在top.html或index.html里加全局导航按钮点击时跳转到对应的专题页function goToPage(pageName, province) { var baseUrl pageName .html; var params []; if (province) { params.push(province encodeURIComponent(province)); } // 可扩展其他业务参数 location.href params.length ? baseUrl ? params.join() : baseUrl; }逻辑说明点击某个省份的柱状图时比如在one.html里点击“四川”可以跳转到three.html?province四川然后three.html的脚本读取URLSearchParams并把图表数据切换为四川的物种数据。这样就实现了多页面之间的联动不需要刷新重新请求所有数据。参数说明encodeURIComponent是必须的因为省份名称包含中文直接拼在 URL 上虽然浏览器会自动编码但在某些服务器环境可能出错。读取时用new URLSearchParams(window.location.search).get(province)这比手动解析?和更安全。如果页面间共享的数据太多比如用户选择了一个年份范围建议把这些值打包成一个 JSON 存到localStorage页面加载后统一读取。5.2 ECharts 动画的触发和定制项目里echarts.min.js自带进场动画首次setOption时柱状图会从底部弹出地图区域颜色会渐变填充。但多页面跳转之间如果希望动画重新播放可以在页面显示后主动调用chart.clear()再setOption// 页面切换后重置图表确保动画重新播放 window.addEventListener(focus, function () { if (window.speciesChart) { window.speciesChart.clear(); window.speciesChart.setOption(buildOption(currentData)); } });逻辑说明clear()会清空当前画布和动画状态setOption会重新执行初始化逻辑视觉上就像是页面重新加载了一次。这里把buildOption封装成函数而不是直接存option对象是因为不同页码需要展示不同的数据切片每次重绘都要基于最新的数据。参数说明还可以用chart.setOption(option, true)第二个参数设为true强制合并模式而不是替换模式适合只更新部分数据时保留其他配置。在大屏展示中animationDurationUpdate控制数据更新动画时长默认 300ms如果数据切换频繁可以调短到 100ms避免图表长时间处于变化中。5.3 视频文件在页面中的嵌入方式和坑压缩包里出现了1.mp4、2.mp4、3.mp4和video.mp4这在信息可视化大赛里通常用做背景视频或场景过渡。常见做法是把视频当作全屏背景上面覆盖半透明面板video classbg-video autoplay muted loop playsinline source srcvideo.mp4 typevideo/mp4 /video.bg-video { position: fixed; right: 0; bottom: 0; min-width: 100%; min-height: 100%; width: auto; height: auto; z-index: -1; object-fit: cover; }逻辑说明autoplay让视频自动播放muted静音loop循环playsinline避免移动端全屏。背景视频的层级放在所有面板之下面板用半透明背景色让视频从缝隙中透出增强沉浸感。注意如果视频体积过大比如超过 10MB页面加载会很慢建议用preloadmetadata或者只在前几页引入。参数说明object-fit: cover会让视频铺满容器并裁剪掉超出部分保证 16:9 视频在任意屏幕下不变形。但z-index: -1在部分旧浏览器里可能被父容器遮挡更稳妥的方式是设置position: fixed; z-index: 0;同时让所有内容容器position: relative; z-index: 1;。6. 把获奖项目改造成自己的可视化模板数据替换、模块拆分与提效验证拿到这份源码不建议直接打开就在上面改数据更高效的方式是先把它当模板确认几个关键边界再动手替换。我先讲验证核心链路的方法打开one.html和example.html确认地图能正常渲染再从控制台打印echarts.getMap(china)看地图对象是否完整如果这一步通过说明整个多页面框架没有依赖未知环境。接下来把数据替换抽象成三步。第一步打开data目录里的nei.js或inde.js它们通常定义一个全局变量如var wildlifeData { ... }你把自己整理的数据按同样的键名填充即可。第二步在业务 JS 中找到data: [{ name: 四川, value: 320 }]这部分把数组替换成从变量读取。第三步检查visualMap的min和max根据新数据的最大值调整否则颜色会失去区分度。替换时建议保留页面框架只改中间图表逻辑。比如ten.html如果是一个趋势折线图你可以把野生动物年度数量换成任意时间序列数据但保持xAxis、yAxis、tooltip配置不动这样可以在半小时内生成一个全新的可视化大屏。要特别注意折线图的时间格式如果原来数据是2019整数年份而你换成2019-01-01字符串必须把xAxis.type改为time否则会按类别显示。如果要进一步模块化可以把每个页面的数据配置、图表初始化、事件绑定拆成三个文件data.js、chart.js、event.js。项目里现在的innnn.js、fundation.js、test.js职责有些混杂新人接手时不好定位。你可以在自己的项目中建立一个src目录里面按页面建子目录每个子目录维护自己的图表实例引用数组页面销毁时统一调用dispose()释放内存避免在 SPA 环境里切换页面时图表不消失。最后验证一个具体技巧在大屏演示时如果地图数据点过多导致渲染卡顿可以把visualMap的calculable设为false并把series里的label关闭如果仍然卡说明 GeoJSON 精度太高可以把china.js里的坐标精度降为三位小数体积减少一半视觉上完全看不出差别。这套模板的优势在于它是真实参赛作品代码里包含了很多比赛现场才会遇到的调试痕迹你顺着这些痕迹能看到一个信息可视化项目从零到演示的完整路径这是普通教程和 demo 给不了的价值。本文还有配套的精品资源点击获取