多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Vega 可视化语法:用声明式 JSON 构建交互式可视化图表

Vega 可视化语法:用声明式 JSON 构建交互式可视化图表 Vega 可视化语法用声明式 JSON 构建交互式可视化图表【免费下载链接】vegaA visualization grammar.项目地址: https://gitcode.com/gh_mirrors/ve/vegaVega 是一个面向可视化领域的声明式语法visualization grammar你用 JSON 描述图表的视觉外观与交互行为Vega 的 JavaScript 运行时负责解析这份描述并生成基于 Canvas 或 SVG 的 Web 视图。本文以本仓库 docs/index.md 为核心结合源码与官方示例系统讲解 Vega 的规范结构、构建块数据、比例尺、标记、坐标轴、图例、投影、交互机制信号与事件流以及从 Web 部署到命令行渲染的完整使用方式。Vega 是什么声明式可视化语法Vega 的核心主张是可视化设计是一份数据而不是一段命令式绘图代码。正如 docs/index.md 所述Vega 是一种声明式语言用于创建、保存和共享交互式可视化设计。你可以用 JSON 描述一个可视化的外观与交互行为然后由 Vega 生成基于 Canvas 或 SVG 的 Web 视图。这种设计带来三个关键能力可计算生成规范specification是纯 JSON天然适合程序化生成可以作为新 API 和可视化分析工具的基础可保存可分享一份规范就是一个可移植的图表文件便于存储、传输与复用声明式而非命令式你描述画什么数据、比例尺、编码而不必关心怎么画逐帧绘制、事件绑定、坐标换算。从规范到视图运行时流水线Vega 的 JavaScript 运行时负责把 JSON 规范转化为可交互的视图。从仓库源码可以看到vega主包packages/vega/index.js对外导出了完整的能力parse解析规范、View视图组件、Dataflow数据流引擎、transforms数据变换、scale/scheme比例尺与配色、projection地图投影等同时聚合了 vega-parser、vega-runtime、vega-dataflow、vega-view、vega-scenegraph 等多个子包。一条典型的渲染链路是解析Parsevega.parse(spec)将 JSON 规范编译为数据流dataflow描述实例化视图Viewnew vega.View(...)基于数据流描述创建交互视图数据流处理Dataflow数据加载、变换、信号求值等算子以响应式图的形式执行场景图构建与渲染Scenegraph Renderer将编码结果组织为场景图最终输出到 Canvas 或 SVG。关于这条链路的细节官方教程 How Vega Works 有更深入的讲解见 docs/tutorials/index.md 中的教程列表。Vega 规范Specification的结构一份 Vega 规范就是一个 JSON 对象描述一个完整的交互式可视化设计。$schema字段声明所用规范版本顶层属性定义了视图的尺寸与元数据其余属性分别定义数据、比例尺、投影、坐标轴、图例、信号与标记。顶层属性属性类型说明$schemaURLVega schema 的 URL用于规范校验与编辑器提示descriptionString可视化的文本描述5.10 及以后版本中该值还会用作视图容器元素的aria-labelbackgroundColor|Signal整个视图的背景色默认透明width/heightNumber|Signal数据矩形绘图区的像素宽/高paddingNumber|Object|Signal视图四周的留白可用数字四边一致或{left:5,top:5,right:5,bottom:5}对象autosizeString|Object|Signal视图尺寸的确定方式详见下文configConfig标记、坐标轴、图例的默认视觉配置signalsSignal[]动态变量参数化可视化并驱动交互dataData[]数据集定义与变换管线scalesScale[]把数据值映射为视觉值坐标、颜色、尺寸projectionsProjection[]把经度, 纬度映射为投影后的 (x, y) 坐标axes/legendsAxis[] / Legend[]坐标轴与图例可视化比例尺映射titleTitle图表标题marksMark[]用矩形、线、符号等几何原语编码数据encodeEncode顶层 group 标记图表数据矩形的编码指令例如设置绘图区背景色usermetaObject可选元数据Vega 解析器会忽略它完整定义见 docs/docs/specification.md。autosize视图尺寸的三种确定方式视图的最终尺寸由width、height、padding以及坐标轴、图例、标题等内容的实际占用共同决定autosize控制这一过程的策略none不做自动尺寸调整总尺寸仅由 width/height/padding 决定默认总宽为width padding.left padding.right超出区域的内容会被裁剪pad默认自动扩大视图保证坐标轴、图例等所有内容可见总尺寸通常会超过指定的 width/height/paddingfit反向收缩绘图区以适配给定尺寸让坐标轴、图例、标题容纳在指定范围内若内容所需空间超过指定尺寸仍可能发生裁剪fit-x/fit-y仅调整宽度或高度以适配另一方向按pad处理。autosize还支持对象形式例如{type:fit,resize:true,contains:padding}resize表示每次视图更新时是否重新计算布局contains决定width/height是指绘图区尺寸content默认还是含 padding 的总尺寸padding。相关实现可参考 packages/vega-view/src/size.js尺寸逻辑与 docs/docs/api/view.md 中的View.resize方法。一个最小且完整的规范下面是仓库中真实存在的柱状图示例 docs/examples/bar-chart.vg.json 的完整骨架{ $schema: https://vega.github.io/schema/vega/v6.json, description: A basic bar chart example, with value labels shown upon pointer hover., width: 400, height: 200, padding: 5, data: [ { name: table, values: [ {category: A, amount: 28}, {category: B, amount: 55} ] } ], signals: [ { name: tooltip, value: {}, on: [ {events: rect:pointerover, update: datum}, {events: rect:pointerout, update: {}} ] } ], scales: [ { name: xscale, type: band, domain: {data: table, field: category}, range: width, padding: 0.05, round: true }, { name: yscale, domain: {data: table, field: amount}, nice: true, range: height } ], axes: [ { orient: bottom, scale: xscale }, { orient: left, scale: yscale } ], marks: [ { type: rect, from: {data: table}, encode: { enter: { x: {scale: xscale, field: category}, width: {scale: xscale, band: 1}, y: {scale: yscale, field: amount}, y2: {scale: yscale, value: 0} }, update: { fill: {value: steelblue} }, hover: { fill: {value: red} } } } ] }这份规范演示了 Vega 的全部核心构建块内联数据、响应式信号tooltip、带域的数据驱动比例尺、坐标轴以及带 enter/update/hover 编码集encode set的矩形标记。它也是 docs/tutorials/bar-chart 入门教程的起点。Vega bar chart 示例的渲染效果构建块从数据到图形数据加载与变换Data TransformsVega 的基本数据模型是表格型数据——类似电子表格或数据库表每条记录是一个标准 JavaScript 对象详见 docs/docs/data.md。数据集可以通过三种方式提供内联values、URL 加载url、或由其他数据集source派生。format属性声明解析格式支持json默认、csv、tsv、dsv和topojson并可用parse做自动或显式的类型推断如parse: {modified_on: date}。数据变换transform在渲染前对数据执行过滤、排序、聚合、布局等处理变换管线的输出即该数据集的值。例如从stocks派生按月过滤的子集{ name: index, source: stocks, transform: [ { type: filter, expr: month(datum.date) month(indexDate) } ] }全部可用变换可查阅 docs/docs/transforms.md在源码层面vega主包通过 packages/vega/index.js 聚合了来自 vega-transforms、vega-view-transforms、vega-geo、vega-force、vega-hierarchy、vega-regression、vega-voronoi、vega-wordcloud、vega-crossfilter 等子包中的变换实现。比例尺Scales比例尺把数据值数字、日期、类别等映射为视觉值像素、颜色、尺寸是视觉编码的基础详见 docs/docs/scales.md。Vega 内部基于 d3-scale 实现支持三类比例尺定量比例尺linear默认、log、pow、sqrt、symlog、time、utc、sequential离散比例尺ordinal、band、point离散化比例尺quantile、quantize、threshold、bin-ordinal。比例尺的domain可以是两元素数值数组连续数据的最小/最大值、类别数组或数据引用如{data: table, field: category}range则定义输出视觉值区间支持width、height、symbol、category等快捷常量及颜色方案。domainRaw属性可以直接用数组覆盖 domain常用于实现平移缩放等交互交互期间先用数据驱动 domain 初始化再根据用户输入修改。配色方案详见 docs/docs/schemes.md。坐标轴与图例Axes Legends坐标轴与图例负责可视化比例尺坐标轴呈现空间编码的比例尺映射如{orient:bottom,scale:xscale}图例则呈现颜色、形状、尺寸等非空间编码详见 docs/docs/axes.md 与 docs/docs/legends.md。它们是比例尺向读者传达信息的出口会自动根据比例尺 domain/range 生成刻度与标签。地图投影Projections投影把经度, 纬度坐标映射为平面 (x, y) 坐标是绘制地图的能力基础详见 docs/docs/projections.md。Vega 支持常见的等距、墨卡托、正交等多种投影类型并可通过 packages/vega-projection 与 packages/vega-projection-extended 扩展更多投影。图形标记Marks标记是可视化的基本视觉构件每种标记类型对应一种几何原语详见 docs/docs/marks.md类型用途arc圆弧如饼图、环形图的扇形area填充区域水平或垂直对齐image图片如图标或照片group容器可包含其他标记、局部数据/信号/比例尺用于子图与小多图line描边线常用于时序变化path任意路径或多边形SVG path 语法rect矩形如柱状图、时间线rule线段常用于轴刻度线与网格线shapepath 标记的特化版本用于快速绘制地图symbol绘图符号如圆、方块text文本标签可配置字体、对齐与角度trail可随数据改变粗细的线每个标记通常由输入数据的每条记录生成一个实例line/area例外。标记的视觉属性通过编码集encode set声明主要有三组enter数据首次处理、标记实例刚进入场景时求值update对所有现存非退出实例求值exit数据被移除、标记离开场景时求值另有可选的hover集鼠标悬停时应用移出后恢复update集。编码属性可以是常量、数据字段引用也可以是比例尺映射如{scale:xscale,field:category}。交互机制信号Signals与事件流Event StreamsVega 的交互模型由两个概念构成信号是参数化可视化的动态变量事件流是建模用户输入的主要手段。响应式信号信号的值是响应式的reactive它会随输入事件流、外部 API 调用或上游信号的变化而更新更新后的值自动传播到规范其余部分并触发重绘详见 docs/docs/signals.md。一个典型的信号定义{ name: indexDate, description: A date value that updates in response to mousemove., update: datetime(2005, 0, 1), on: [{events: mousemove, update: invert(xscale, x())}] }信号属性包括name唯一名称须为合法 JavaScript 标识符且不得使用保留名datum、event、item、parent、value初始值、update更新表达式可依赖其他信号实现级联更新、init一次性初始化表达式与update互斥、react是否随上游信号自动重算默认true、bind绑定到外部输入元素如滑块、下拉框、on事件处理器数组。Vega 还预置了一些内建信号width、height、padding、autosize及 5.10 的background会自动定义并可与顶层属性合并group 标记实例自动带有parent信号若定义名为cursor的信号其值会自动控制视图的 CSS 鼠标光标。事件流事件流捕获鼠标点击、触摸移动、定时器触发、信号更新等一连串输入事件匹配时触发对应的信号处理器详见 docs/docs/event-streams.md。事件流可以用多种方式定义事件流对象指明事件源source默认view可取值window、container、CSS 选择器等与事件类型选择器字符串便捷简写如rect:mouseover、click[event.shiftKey]、timer{1000}信号引用{signal: name}捕获信号更新比例尺引用{scale: xscale}捕获比例尺更新数组组合多个上述定义。对标记mark item支持的事件类型包括click、dblclick、mousedown、mousemove、mouseover、mouseout、mouseup、mousewheel、wheel、touchstart、touchmove、touchend、keydown、keypress、keyup、dragenter、dragleave、dragover等此外还有非 DOM 的timer事件按节流间隔触发以及container:resize事件配合containerSize()表达式实现响应式布局。交互实战hover 提示回到 docs/examples/bar-chart.vg.json它用tooltip信号 rect:pointerover/rect:pointerout事件流加上 text 标记对tooltip的引用实现了鼠标悬停显示数值标签的交互{ name: tooltip, value: {}, on: [ {events: rect:pointerover, update: datum}, {events: rect:pointerout, update: {}} ] }datum指向当前悬停的标记实例数据text 标记再用{signal: tooltip.amount}把标签内容绑定到信号上并通过fillOpacity条件编码实现悬停时显示、否则隐藏。部署与使用Vega 既可以在浏览器中部署交互式可视化也可以在服务端渲染静态 PNG/SVG 图片。完整说明见 docs/usage/index.md。浏览器部署最简单的做法是直接引入完整 bundlehead script srchttps://vega.github.io/vega/vega.min.js/script /head生产环境推荐使用 CDN如 jsDelivr或自托管若页面已单独使用 d3可改用不含重复 d3 模块的vega-core.min.js加载 TopoJSON 数据时还需引入 topojson-client。使用打包器时可直接import * as vega from vega。方式一Vega View API。vega.parse(spec)解析规范new vega.View(parsed, options)创建视图view.runAsync()执行渲染view new vega.View(vega.parse(spec), { renderer: canvas, // renderer (canvas or svg) container: #view, // parent DOM container hover: true // enable hover processing }); return view.runAsync();注意父容器内的既有内容会在视图初始化时被移除。View API 还支持流式数据更新、导出静态图片、访问内部数据用于调试详见 docs/docs/api/view.md。方式二Vega-Embed。更方便的辅助模块自动处理从 URL 加载规范、生成视图与标准配置并可附带导出图片和查看源码的链接vegaEmbed(#view, https://vega.github.io/vega/examples/bar-chart.vg.json);关于表达式与 CSP默认情况下 Vega 使用Function构造函数生成表达式函数不完全符合内容安全策略CSP如需 CSP 合规可使用替代的表达式解释器见 docs/usage/interpreter.md。命令行工具服务端静态渲染vega-cli包提供三个 Node.js 命令行工具vg2pdf、vg2png、vg2svg分别渲染 PDF、PNG、SVG 静态图片。输入输出文件均可省略——省略输入时从标准输入读取省略输出时写入标准输出可管道使用。vg2png test/specs-valid/bar.vg.json bar.png vg2svg -h test/specs-valid/bar.vg.json bar.svg vg2pdf test/specs-valid/arc.vg.json arc.pdf vg2png -s 2 test/specs-valid/bar.vg.json bar.png # 2 倍分辨率 vg2png -b test test/specs-valid/choropleth.vg.json choropleth.png # 指定数据加载基准目录常用参数-b/--base数据与图片加载的基准目录、-s/--scale分辨率缩放因子默认 1、-seed随机数种子用于可复现输出、-c/--configVega config 对象文件路径、-f/--format与-t/--timeFormat数字/时间格式 locale 文件、-l/--loglevelerror/warn/info/debug默认warn、-h/--header仅 vg2svg输出带 XML 头与 DOCTYPE。vega-cli依赖 node-canvas详见 packages/vega-cli。Node.js 服务端渲染在 Node.js 中同样使用 View API但应使用renderer: none且不提供 DOM 容器var vega require(vega); var view new vega.View(vega.parse(spec), {renderer: none}); view.toSVG().then(function(svg) { /* process svg string */ }); view.toCanvas().then(function(canvas) { /* node-canvas 实例 */ });生成 PNG 与精确测量字体度量需要安装 node-canvasvega包默认不依赖它需显式安装vega-cli则自带该依赖。学习路径与更上一层Vega-Lite入门教程从 docs/tutorials/bar-chart用交互式 tooltip 的柱状图入门开始进阶教程包括 axes legends、机场航线交互地图、以及讲解规范如何变成视图的 How Vega Works详见 docs/tutorials/index.md示例画廊浏览 docs/examples 中上百个可直接运行的.vg.json示例覆盖柱状图、散点图、地图、树图、力导向图等各类图表是学习规范写法的最佳素材文档体系从 docs/docs/specification.md 出发按需查阅 数据、变换、比例尺、标记、信号、事件流 等参考JavaScript API 参考见 docs/docs/api更高级的语言如果你需要快速生成常见统计图表可以基于 Vega 使用更上层的Vega-Lite声明式语言或用面向 Vega-Lite 的AltairPython API——它们最终都构建在 Vega 运行时之上。结语Vega 的价值在于把可视化语法化数据、比例尺、标记、交互都被抽象为可组合、可计算、可共享的 JSON 构件。无论你是想用声明式方式快速产出交互图表还是要构建面向可视化的新 API 与分析工具Vega 都提供了一套完整且经得起检验的基础设施。从本文的规范骨架出发配合 docs/examples 中的真实示例逐行研读是掌握这套语法最高效的路径。【免费下载链接】vegaA visualization grammar.项目地址: https://gitcode.com/gh_mirrors/ve/vega创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表