Vega结合Vega Embed实现可视化响应式宽高屏幕适配的方法
Vega Embed 两类响应式可视化实现方案
两类适配效果不需要额外第三方工具,只需要配合CSS容器规则、Vega本身的容器适配属性、简单的resize监听即可实现,两类效果分别存为独立HTML文件即可。
第一类:宽高完全适配屏幕的可视化
实现逻辑:
- 清除页面默认边距,将html、body、图表挂载容器的宽高都设为100%占满屏幕,隐藏溢出内容避免出现滚动条
- Vega JSON配置中不要写死width、height固定值,将两个参数都设为
"container",让图表自动匹配父容器尺寸 - 监听窗口resize事件,尺寸变化时调用Vega视图实例的resize方法重绘,避免图表拉伸变形
对应独立HTML文件代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>全尺寸适配Vega图表</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html, body, #vis { width: 100%; height: 100vh; overflow: hidden; } </style> <!-- 提前将vega、vega-lite、vega-embed的JS文件下载到本地js目录引用即可 --> <script src="js/vega.min.js"></script> <script src="js/vega-lite.min.js"></script> <script src="js/vega-embed.min.js"></script> </head> <body> <div id="vis"></div> <script> // 自定义Vega JSON配置,宽高设为container匹配容器 const chartSpec = { "$schema": "https://vega.github.io/schema/vega/v5.json", "width": "container", "height": "container", "padding": 10, // 以下为示例配置,可替换为自己的业务数据、标记、比例尺配置 "data": [{"name": "table", "values": [{"x":1,"y":28},{"x":2,"y":55},{"x":3,"y":43}]}], "scales": [ {"name":"xscale","type":"band","domain":{"data":"table","field":"x"},"range":"width","padding":0.1}, {"name":"yscale","type":"linear","domain":{"data":"table","field":"y"},"range":"height"} ], "axes": [{"orient":"bottom","scale":"xscale"},{"orient":"left","scale":"yscale"}], "marks": [{"type":"rect","from":{"data":"table"},"encode":{"enter":{"x":{"scale":"xscale","field":"x"},"width":{"scale":"xscale","band":1},"y":{"scale":"yscale","field":"y"},"y2":{"scale":"yscale","value":0},"fill":{"value":"steelblue"}}}}] }; let chartView; // 初始化渲染图表 vegaEmbed('#vis', chartSpec, {renderer: 'canvas'}).then(result => { chartView = result.view; }); // 监听窗口尺寸变化触发重绘 window.addEventListener('resize', () => { if (chartView) chartView.resize().run(); }); </script> </body> </html>
第二类:仅高度响应屏幕、宽度固定的可视化
实现逻辑:
- 图表挂载容器设置固定宽度(可根据业务需求自定义像素值),高度设为100vh占满屏幕高度,可根据需求设置水平居中、偏移等布局样式
- Vega JSON配置中width写固定数值(和容器宽度匹配,记得减去内边距占位),height参数设为
"container"匹配容器高度 - 同样添加resize监听,屏幕高度变化时自动重绘,宽度变化时因为容器宽度固定,图表尺寸不会受影响
对应独立HTML文件代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>仅高度响应Vega图表</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; min-height: 100vh; } #vis { /* 固定宽度,不随屏幕宽度变化 */ width: 800px; /* 高度完全适配屏幕高度 */ height: 100vh; margin: 0 auto; /* 可选:让固定宽度的图表水平居中 */ } </style> <!-- 本地引用三个依赖库,和第一个文件可复用同一份资源 --> <script src="js/vega.min.js"></script> <script src="js/vega-lite.min.js"></script> <script src="js/vega-embed.min.js"></script> </head> <body> <div id="vis"></div> <script> // Vega配置:宽度写固定值,高度设为container匹配容器高度 const chartSpec = { "$schema": "https://vega.github.io/schema/vega/v5.json", "width": 780, // 比容器宽度小20px,给padding留位置 "height": "container", "padding": 10, // 以下为示例配置,可替换为自己的业务数据、标记、比例尺配置 "data": [{"name": "table", "values": [{"x":1,"y":28},{"x":2,"y":55},{"x":3,"y":43}]}], "scales": [ {"name":"xscale","type":"band","domain":{"data":"table","field":"x"},"range":"width","padding":0.1}, {"name":"yscale","type":"linear","domain":{"data":"table","field":"y"},"range":"height"} ], "axes": [{"orient":"bottom","scale":"xscale"},{"orient":"left","scale":"yscale"}], "marks": [{"type":"rect","from":{"data":"table"},"encode":{"enter":{"x":{"scale":"xscale","field":"x"},"width":{"scale":"xscale","band":1},"y":{"scale":"yscale","field":"y"},"y2":{"scale":"yscale","value":0},"fill":{"value":"coral"}}}}] }; let chartView; vegaEmbed('#vis', chartSpec, {renderer: 'canvas'}).then(result => { chartView = result.view; }); window.addEventListener('resize', () => { if (chartView) chartView.resize().run(); }); </script> </body> </html>
注意事项
- 配置响应维度时不要写死固定像素值,否则会覆盖容器适配规则
- 渲染模式可按需切换canvas/svg,适配逻辑完全不受影响
- 全尺寸适配页面务必设置容器
overflow: hidden,避免默认边距导致出现滚动条 - 两个独立HTML文件可复用同一份本地存储的vega、vega-lite、vega-embed依赖文件,不需要重复存储
内容的提问来源于stack exchange,提问作者user2373145
相关产品推荐
相关产品推荐

