十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

纯HTML+CSS+JS可视化大屏源码:ECharts自适应缩放与动效实战

纯HTML+CSS+JS可视化大屏源码:ECharts自适应缩放与动效实战 简介数据可视化作为企业运营监控与决策展示的核心手段正被广泛应用于展厅演示、指挥中心和数据驾驶舱等场景。前端图表库ECharts以其丰富的图表类型和灵活的配置成为构建大屏的首选工具。然而实际开发中常面临布局错位、图表空白、动效卡顿等痛点。本文分享一套基于纯HTML、CSS和JavaScript实现的深色科技风大屏源码无需框架和后端双击即可运行。重点拆解CSS Grid三行布局、ECharts主题定制与发光动效、数字滚动、列表轮播以及基于1920x1080设计稿的等比缩放自适应方案并给出数据替换、部署和避坑指南。适合需要快速搭建可视化大屏的前端工程师和运维人员参考。 做可视化大屏这几年我前前后后折腾过不下二十套模板今天分享的这套“大屏系列九”是最近比较满意的一套HTML可视化大屏源码。它没有用React、Vue也没有依赖后端服务把整个项目丢到浏览器里就能跑起来适合做展厅演示、运营监控、数据驾驶舱这类场景。如果你正在找一套能快速出效果、又能按自己需求改数据的可视化大屏这篇文章应该能帮上忙。我会把整套源码的设计思路、核心代码、踩坑过程全部拆开讲包括布局怎么搭、ECharts怎么调、动效怎么做、分辨率怎么适配以及我在实际项目里遇到过的几个比较隐蔽的问题。很多细节不是官方文档里能直接看到的属于“自己写一遍才知道”的那种经验。1. 这套可视化大屏到底解决了什么问题1.1 项目定位与“系列九”的设计语言“大屏系列九”是我做的一个可视化大屏模板系列里的第九个版本。和前面几套不一样这一版的设计语言更偏向“深色科技风”整体以深蓝和青色为主搭配霓虹描边、玻璃拟态卡片、轻微光晕和流动线条视觉冲击力比常规的后台图表强很多。很多刚接触可视化大屏的朋友会有一个误区觉得只要图标好看就是大屏了。其实不是大屏第一眼要解决的是“信息层次”问题。这个系列九的源码核心不是把页面做得花里胡哨而是用“视觉重心引导”的方式让看屏的人一进来就知道先看中间再看两侧最后扫底部滚动条。这一点后面我会结合布局详细说。这套源码是纯 HTML CSS JavaScript 实现的图表部分用 ECharts 5地图场景用的是 GeoJSON 数据如果你不需要地图可以直接去掉那部分代码。所有数据都放在独立的 JS 文件里模拟了实时刷新所以不需要后端接口也能跑出“动态数据”的效果。因为整个项目没有构建步骤所以交付给同事、客户或者放到演示机器上都非常方便。1.2 适用场景和核心能力这套大屏适合三类场景一是展厅或接待区的大屏展示需要长时间无人值守循环播放二是企业内部运营监控中心比如设备状态、订单量、告警信息等实时数据三是临时性的数据汇报和汇报大屏比如季度回顾、活动数据复盘。核心能力包括六个模块顶部标题区带流光线条和渐变文字可以显示主标题、副标题、时间日期。左侧指标卡三个KPI数字卡片带动态数字滚动效果适合放“今日订单”“销售额”“转化率”这类关键指标。右侧排名列表滚动展示排行榜或告警信息支持自动轮播和鼠标悬停暂停。中间主图区大尺寸折线图 玫瑰图/柱状图组合用于展示趋势和占比。底部扩展区横向放置两个图表和一个地图/热力区域具体内容可按需替换。自适应缩放基于 1920x1080 设计稿通过 JS 计算等比缩放投到异形分辨率上也不会错位。这套源码在设计时就把“可替换性”放在首位。我特意把所有图表数据集中到一个 data.js 文件里你想改成自己的数据基本只需要修改这一个文件不需要在 echarts 配置里一个个找。这种设计在后期交接时非常省心后面我会详细讲怎么替换。2. 整体设计与技术方案怎么选2.1 页面骨架三行布局与flex/grid的取舍大屏页面和普通后台页面最大的区别在于“一屏展示”和“视觉面积大”。普通后台能滚动重点是把信息放全大屏不能随便滚动重点是把最重要的信息放在最容易被看到的位置。这个系列九的骨架我采用的是三行结构顶部标题栏占约10%高度中间主内容区占约75%高度底部数据区占约15%高度。中间主内容区又分成左、中、右三列左列和右列宽度略窄放指标和列表中列最宽放核心趋势图。实现上我用的是 CSS Grid。最开始我试过 flex 布局但发现 flex 在多行多列混排时要写很多嵌套和宽度计算而 Grid 只需要定义好 container 的 grid-template-columns 和 grid-template-rows内部元素自动对齐修改列宽也非常直观。当然如果你对 Grid 不熟用 flex 也能实现只是代码会更啰嗦。核心布局代码大致这样.screen { display: grid; grid-template-rows: 10% 75% 15%; grid-template-columns: 1fr; width: 1920px; height: 1080px; transform-origin: left top; overflow: hidden; } .main-area { display: grid; grid-template-columns: 22% 56% 22%; gap: 12px; padding: 0 16px; min-height: 0; }这里需要特别留意一个细节Grid 的子项目在内容过多时默认会撑大单元格导致页面出现滚动条。我建议在涉及图表的容器上加上min-height: 0并给图表容器设置明确的height: 100%否则 ECharts 经常计算不到正确的容器高度。2.2 图表选型为什么继续用ECharts可视化大屏常用的图表库无非 ECharts、Chart.js、AntV G2、D3.js 这几个。D3 灵活但开发效率低Chart.js 简单但复杂组合图支持偏弱AntV 生态也不错但上手成本略高。这套源码我继续选 ECharts 5核心原因有三个。一是 ECharts 的暗色主题和特效支持最省事。大屏基本都是深色背景ECharts 里一个dark主题再加上areaStyle渐变、lineStyle渐变色效果就出来了不需要自己写太多 SVG 特效。二是组件丰富。地图、饼图、玫瑰图、雷达图、仪表盘、漏斗图都有而且在同一个页面里多个图表实例不会互相干扰。像这个系列九里我同时用了折线图、柱状图、玫瑰图、环形图和地图ECharts 都能稳定扛住。三是配置结构清晰。ECharts 的 option 就是一个纯对象数据变化时调用setOption({ ... })就能平滑更新非常适合做定时刷新。从 CDN 引入 ECharts 的方式也值得提一下。我建议在本地下载一个echarts.min.js不要直接依赖线上 CDN。因为大屏展示环境经常是没有外网的或者网络波动导致图表加载失败。把echarts.min.js放到js/目录下用相对路径引入最稳。2.3 为什么坚持不用Vue或React这个项目我故意不用 Vue 或 React虽然我对这两个框架很熟。原因也很现实可视化大屏项目的交付对象往往不是纯前端团队可能是做数据的数据同学、做业务的运营同学或者集成商的项目实施。他们拿到的源码最好能直接双击打开不需要npm install、不需要node_modules、不需要构建工具。纯静态的 HTML CSS JS 是最低门槛的交付形态。另外大屏页面本身状态并不复杂没有复杂的组件树和路由用框架反而增加体积和调试成本。ECharts 实例管理和定时器清理用原生 JS 写也足够清晰。等到你确实需要把大屏嵌入某个后台系统时再把这套纯静态代码包一层组件也不难。当然纯静态也有劣势比如没有热更新、浏览器缓存问题需要自己处理。我的习惯是开发阶段用 VSCode 的 Live Server 插件做本地服务改代码后自动刷新交付阶段直接用 Nginx 托管静态文件一行配置搞定。3. 核心模块拆解与实现细节3.1 顶部标题栏的流光线条与渐变文字大屏的顶部标题栏是门面不能只放一行白字。这个版本我做了三层效果背景渐变色块、文字渐变、底部流光线条。渐变文字用的是background-clip: text把背景渐变裁剪到文字上文字本身变成透明视觉上就会出现蓝紫渐变。核心代码如下.title { font-size: 42px; font-weight: 700; letter-spacing: 8px; background: linear-gradient(90deg, #00d4ff, #7b2ff7, #00d4ff); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: titleFlow 4s linear infinite; } keyframes titleFlow { 0% { background-position: 0% 0; } 100% { background-position: 200% 0; } }注意background-size: 200% 100%这是为了让背景色块宽度是文字视觉宽度的两倍动画移动起来才有“流光”效果。没有这一行的话渐变背景会自动铺满整个文字区域看不出流动感。标题两侧的装饰线条我用的是伪元素::before和::after配合border-bottom和透明度渐变形成一条延伸出去的发光横线。如果你觉得光效不够强可以再加一层filter: drop-shadow()但要注意别用太多否则 GPU 压力会翻倍。3.2 KPI指标卡的数字滚动效果KPI 卡片上的数字如果直接从 A 跳到 B会显得很生硬。这个项目里我给数字加了一个“滚动”效果本质不是 CSS 动画而是用requestAnimationFrame做逐帧插值。实现思路很简单设定一个起始值和一个目标值在一段时间内逐步更新当前值并渲染到页面上。比如 600ms 内从 0 滚到 12830每次刷新根据时间比例计算当前数值再用toLocaleString()格式化上千分位。为了让代码有通用性我封装了一个小函数function animateNumber(el, start, end, duration) { const startTime performance.now(); function update(currentTime) { const progress Math.min((currentTime - startTime) / duration, 1); const eased 1 - Math.pow(1 - progress, 3); el.textContent Math.round(start (end - start) * eased).toLocaleString(); if (progress 1) requestAnimationFrame(update); } requestAnimationFrame(update); }这里我用了一个三次缓出函数1 - Math.pow(1 - progress, 3)目的是让数字“先快后慢”视觉上更像机械仪表盘的转动。如果你想要匀速滚动直接把eased progress就行。需要注意定时刷新数据时不要让多个动画互相抢占。我的做法是每次创建新动画前先取消上一次的requestAnimationFrame用一个全局变量存当前动画 ID。否则页面在切后台再切回来后动画叠加会非常卡。3.3 ECharts图表配置要点这套大屏里的图表主要用了四种折线图、柱状图、玫瑰图、环形图。每个图表的配置我都没有用默认样式而是围绕“深色科技风”重新定制了配色。统一设置文本颜色和分割线颜色很关键。我可以直接设置 ECharts 全局的文本样式和线样式不用每张图重复写echarts.registerTheme(darkBlue, { textStyle: { color: #cfeafc }, title: { textStyle: { color: #e5f3ff } }, legend: { textStyle: { color: #9cc9e8 } }, categoryAxis: { axisLine: { lineStyle: { color: #1f3b58 } }, axisLabel: { color: #9cc9e8 } }, valueAxis: { splitLine: { lineStyle: { color: rgba(31, 59, 88, 0.6) } }, axisLabel: { color: #9cc9e8 } } });然后在初始化图表时传入主题名称const chart echarts.init(document.getElementById(chartMain), darkBlue);折线图的高阶细节是区域渐变和光晕。折线下方填充一个从蓝到透明的渐变折线本身加shadowBlur和shadowColor这样在暗色背景下会有一种“发光线条”的感觉series: [{ type: line, smooth: true, symbol: circle, symbolSize: 6, lineStyle: { width: 3, color: #00d4ff, shadowColor: rgba(0, 212, 255, 0.6), shadowBlur: 12 }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: rgba(0, 212, 255, 0.35) }, { offset: 1, color: rgba(0, 212, 255, 0) } ]) } }]玫瑰图要注意的是如果数据量太多扇区之间可以加一点borderColor和borderWidth不然同一色系会粘在一起。这个版本我用的色板是#00d4ff、#3a7bd5、#7b2ff7、#00ffd1、#ffbd45五种颜色基本能满足百分之八十的大屏场景。3.4 滚动列表与自动轮播左右两侧的排行榜或告警列表如果信息条数超过容器高度就需要滚动。直接给列表容器加overflow-y: auto是最简单的但滚动条会显示出来不够美观。这个版本里我做了两种滚动方案。一种是 CSS 不断上移整个列表内容把ul放在一个固定高度的容器里用transform: translateY(-50%)加上循环动画实现无缝滚动。但这种方式有个问题列表内容只有两部分拼接动画循环点处理不好容易闪跳。另一种是 JS 控制的逐条滚动每 2 秒向上移动一条滚动到末尾后回到第一条。这种方法实现起来比较直观而且可以随时暂停。核心逻辑是记住当前index更新ul的margin-top或transformsetInterval(() { index; if (index list.children.length) index 0; list.style.transform translateY(-${index * itemHeight}px); }, 2000);我实际用的是第二种因为它的行为更可控鼠标悬停暂停也很容易做。注意itemHeight不要用offsetHeight实时取否则滚动过程中会抖动应该在数据渲染完成后统一计算一次。4. 实操从零跑通这套大屏源码4.1 完整目录结构和文件准备拿到源码后你首先会看到一个标准的前端项目目录screen9/ ├── index.html ├── css/ │ ├── style.css │ └── reset.css ├── js/ │ ├── echarts.min.js │ ├── data.js │ ├── charts.js │ ├── screen.js │ └── mock.js └── assets/ ├── logo.png └── bg.pngindex.html是页面入口style.css是样式reset.css做浏览器默认样式重置。data.js存放所有模拟数据和标题、颜色、指标名称等配置charts.js负责初始化所有 ECharts 实例screen.js负责布局缩放、数字滚动、列表轮播和整体初始化顺序mock.js用来模拟定时更新数据。建议所有 JS 都放在/body前面引入顺序是echarts.min.js、data.js、charts.js、screen.js因为screen.js里会调用 charts 的初始化函数如果文件顺序颠倒会报错。如果你不需要地图去掉相关 JS 和对应 DOM 区块即可。如果不需要 mock 实时刷新也可以直接删掉mock.js不会影响整体展示。4.2 快速替换成自己的项目数据替换数据是这个项目最容易踩坑的地方也是价值最高的地方。我在data.js里把所有可变信息集中定义const SCREEN_CONFIG { title: 城市运营指挥中心, subtitle: Data Visualization Screen, kpi: [ { label: 今日订单量, value: 12830 }, { label: 销售额万元, value: 735.6 }, { label: 实时转化率, value: 3.26% } ], charts: { lineData: {...}, barData: [...], roseData: [...], mapData: [...] }, ranking: [...] };这样替换数据时只需要改SCREEN_CONFIG里的值charts.js里通过data.js的全局变量读取配置不需要改动 ECharts option 结构。比如你要把“今日订单量”从 12830 改成 50000直接在SCREEN_CONFIG.kpi[0].value改一下就行页面会自动适配数字滚动。但要注意KPI 卡片里的值有字符串型百分比也有数字型金额格式不一样。我在取值时判断了一下typeof。如果你的指标类型不同比如金额要显示两位小数那要在screen.js的数字格式化函数里做一下分支处理否则会出现 12830 显示成 “12830” 而 3.26% 被toLocaleString()转成 “3.26” 的问题。4.3 部署方式和自适应缩放方案纯静态源码的部署非常简单Nginx 下加一段配置即可server { listen 8080; root /var/www/screen9; index index.html; }然后访问http://ip:8080/index.html就能看到大屏。如果公司内网没有域名IP 访问也可以。自适应缩放是这块最重要的实操点。我采用的是业界比较常用的“设计稿 等比缩放”方案设计稿固定为 1920x1080页面加载后用实际屏幕宽高除以 1920 和 1080取较小值作为缩放比例对根节点.screen应用transform: scale()并且用transform-origin: left top锁定左上角再用left: 50%; top: 50%做居中调整。核心代码如下function resizeScreen() { const designWidth 1920; const designHeight 1080; const ratio Math.min( window.innerWidth / designWidth, window.innerHeight / designHeight ); const screen document.querySelector(.screen); screen.style.transform scale(${ratio}); screen.style.left ${(window.innerWidth - designWidth * ratio) / 2}px; screen.style.top ${(window.innerHeight - designHeight * ratio) / 2}px; } window.addEventListener(resize, resizeScreen); resizeScreen();如果只用scale而不做居中处理在超宽屏或超高屏上大屏会偏向一侧。加了left/top居中后两边会露出黑边或背景纹理视觉上是平衡的。另一种方案是用 rem vw 做响应式但图表内的字体、间距、坐标轴刻度很麻烦容易对不齐所以我更推荐这种整体缩放方案。5. 常见问题与避坑指南5.1 图表不显示或空白这个是大屏项目里出现频率最高的一个问题。常见原因有三个。第一个是容器高度为 0。ECharts 初始化时如果父容器没有高度或高度是auto图表就渲染不出来。解决办法是给每个图表容器设置固定的高度比如height: 300px或者height: 100%同时父级要有明确的height和min-height: 0。第二个是 JS 引入顺序错误。ECharts 的init执行时echarts.min.js还没加载完就会报echarts is not defined。检查一下 script 标签顺序确保 echarts 库最先加载。第三个是容器是隐藏状态比如display: none时初始化ECharts 拿到的宽度和高度都是 0。如果图表放在了 Tab 切换或弹窗里需要在切换到可见状态后再调用chart.resize()或者延迟初始化。5.2 不同分辨率下错位大屏项目最常见的坑是自己电脑上 1920 分辨率一切正常拿到客户的 1366 屏幕就错位了。这个问题几乎都是因为布局用了固定 px 而没有做整体缩放。如果你用了transform: scale(比例)方案要注意监听resize事件后重新计算。还有一个隐藏问题如果你在大屏页面里使用了window.innerWidth来获取宽度而浏览器窗口不是全屏状态工具条、侧边栏都会影响结果。所以在演示时最好让浏览器进入全屏或者用window.outerWidth和window.outerHeight加上黑边补偿。如果目标环境有固定分辨率比如 3840x2160 的 4K 屏建议把设计稿宽度改成 3840或者在缩放比例计算后额外乘一个设备像素比相关的系数。不然整体会被拉伸得发虚。5.3 动效卡顿与内存泄漏大屏长时间运行后卡顿是很典型的问题。主要原因有三个一是 ECharts 实例重复创建没有销毁二是setInterval没清理页面卸载后还在跑三是 CSS 动画太多重叠了 transform、filter、box-shadow 等属性。我在screen.js里做了几个保护措施。首先在页面visibilitychange事件里当页面隐藏时暂停所有定时器显示时再恢复这样能减少后台运行时对 CPU 的占用。其次在beforeunload时调用echarts.init返回实例的dispose()方法把所有图表实例销毁避免浏览器内存泄漏。CSS 动画的性能优化也很重要。尽量让动画只作用于transform和opacity因为这两个属性可以由 GPU 加速不会强制重排。像box-shadow闪烁、filter: blur这类效果虽然好看但元素数量一多就会卡我在模板里只保留在顶栏和小面积修饰上。5.4 数据刷新时页面闪烁定时刷新数据时如果直接重新初始化图表页面会有明显的闪烁和跳动。正确做法是复用同一个 ECharts 实例调用setOption并设置notMerge: true而不是重新init。function updateChart(chartInstance, newOption) { chartInstance.setOption(newOption, true); }我遇到过一个问题由于每次 setOption 时都传入了完整的 option图表动画会重新执行导致视觉上“闪一下”。如果是数据量大的实时大屏可以在更新时把全局的animation临时设为false等更新完成后再恢复true。比如折线图实时刷新时只更新series[0].data同时设animation: false画出来的效果就是平滑接续的不会闪。最后再分享一点个人体会做了这么多套大屏模板我自己最深刻的感受是大屏源码的核心不是“炫技”而是“可控”。所谓好看必须建立在稳定运行和数据可替换的基础上。系列九这套模板我刻意把数据和 UI 分离把主题色抽成 CSS 变量把图表配置统一成一副可配置的 JSON这些设计比某一张图表的样式更值钱。后续如果你要把大屏接到真实接口我也建议保留这种“集中配置”的思路把请求地址、轮询间隔、数据字段映射都放在同一个配置模块里不要散落在各个图表配置中。这样以后换数据源、换指标口径你只需要改一小段代码整个大屏就活了。本文还有配套的精品资源点击获取
返回列表