资讯动态

Vega 柱状图示例全解析:从数据编码到悬停 Tooltip 的完整规范拆解

发布时间:2026/9/23 9:04:41 来源:尧图企业网站定制
数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载本篇指南围绕 Vega 官方示例 bar-chart.vg.json 展开一个仅 95 行 JSON 的柱状图规范却完整覆盖了数据声明、band/linear 双尺度映射、坐标轴、rect 与 text 双重标记、以及基于信号signal的悬停高亮与数值 Tooltip 交互。读完本文你将能够逐行理解 Vega 顶层规范的结构掌握enter/update/hover编码集、band尺度与生产规则production rules的用法并具备把任意结构相似的数据改造成可交互柱状图的能力。对应的完整教程位于 docs/tutorials/bar-chart/index.md本文以其为核心骨架并结合 packages/vega-scale、packages/vega-parser 等源码做纵深解读。示例规范一览先通读完整的 Vega 规范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}, {category: C, amount: 43}, {category: D, amount: 91}, {category: E, amount: 81}, {category: F, amount: 53}, {category: G, amount: 19}, {category: H, amount: 87} ] } ], 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} } } }, { type: text, encode: { enter: { align: {value: center}, baseline: {value: bottom}, fill: {value: #333} }, update: { x: {scale: xscale, signal: tooltip.category, band: 0.5}, y: {scale: yscale, signal: tooltip.amount, offset: -2}, text: {signal: tooltip.amount}, fillOpacity: [ {test: datum tooltip, value: 0}, {value: 1} ] } } } ] }规范由六大顶层组件构成可视化尺寸、数据、信号、尺度、坐标轴、标记。下面逐一拆解。可视化尺寸width、height、padding 与 autosizewidth: 400, height: 200, padding: 5, autosize: padwidth/height定义的是数据矩形data rectangle的大小即数据绘图区域坐标轴、图例等额外组件会占用更多空间。padding定义图表内容与视图边界之间的留白。autosize决定最终图表尺寸如何确定pad默认额外扩展空间以容纳所有标记包括坐标轴、图例数据矩形大小不变。若标记超出数据矩形边界视图组件可能变得很大。fit尝试将整张图数据矩形、坐标轴、图例但不含 padding放入给定的width/height内Vega 会收缩数据矩形来容纳坐标轴与图例某些情况下如图例过高可能发生裁剪。none禁用自动尺寸调整总尺寸仅由widthheightpadding决定。从源码看autosize、padding、width、height都属于内建信号built-in signals。在 packages/vega-parser/src/parsers/view.js 的collectSignals中它们被统一收集优先取顶层 spec 属性值未定义时才回落到 config 中的对应配置随后布局阶段由ViewLayout运算符同文件 L54-L60消费autosize信号完成最终布局。这意味着autosize等属性既可以直接写死也可以声明为信号引用实现动态尺寸。数据内联 values、URL 与数据变换data: [ { name: table, values: [ {category: A, amount: 28}, {category: B, amount: 55}, {category: C, amount: 43}, {category: D, amount: 91}, {category: E, amount: 81}, {category: F, amount: 53}, {category: G, amount: 19}, {category: H, amount: 87} ] } ]data是数据定义数组每个数据集合必须有唯一的name。本示例使用values直接内联定义数据每条记录包含字符串字段category类别标签与数值字段amount数值。Vega 中的数据来源有三种方式三者只能选其一values直接内联url从网络加载支持 JSON、CSV 等格式source由先前定义的数据集派生例如经变换得到的新数据集。数据集还可通过transform属性挂接一系列数据变换过滤、聚合、布局等。关于数据与变换的完整说明见 docs/docs/data.md 与 docs/docs/transforms.md。尺度band 尺度与线性尺度的分工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 } ]尺度scale将数据值映射为视觉值像素位置、颜色等。本示例定义了两个尺度xscaleband 尺度type: band显式指定为序数 band 尺度将有序的类别域A–H映射到水平像素范围。range: width是 Vega 提供的便捷写法等价于[0, 400]由画布宽度决定。padding: 0.05在条带之间加入 5% 的间隔round: true让柱条对齐到像素边界避免亚像素模糊。yscale线性尺度未显式写type因为linear是默认类型见 packages/vega-scale/src/scales/types.js 中Linear linear的定义。其域取自amount字段的最小/最大值range: height等价于[200, 0]Y 轴方向反转。nice: true让域值更“友好”——例如原始域[0, 94.345]会被圆整为[0, 100]刻度更易读。关于 band 尺度的底层行为可参考 packages/vega-scale/src/scales/scaleBand.js它基于 d3 的序数尺度扩展而来通过paddingInner/paddingOuterpadding会同时设置二者计算step与bandwidthround为真时对步长、起点与带宽取整见该文件 L27-L36。band: 1即取满整个条带宽度若改用band: 0.5则只取条带的一半。补充说明每个尺度必须有唯一名称嵌套在group标记内的尺度可以重名覆盖已定义尺度属高级用法。domain既可以是静态值数组也可以像本例一样从数据动态求取。默认情况下定量尺度会自动包含 0如需禁用在尺度定义中加入zero: false。range也可显式定义为数组二元数值数组用于空间映射更长的数组如[#ffa804, ...]十六进制色值可用于序数尺度的自定义调色板。坐标轴最小定义与定制技巧axes: [ { orient: bottom, scale: xscale }, { orient: left, scale: yscale } ]坐标轴用于将尺度可视化为刻度与标签。一条轴定义最少需要两个属性orient方位与scale所可视化的尺度。这里底部为 xscale左侧为 yscale。教程中还演示了进一步的定制对应 docs/tutorials/bar-chart/bar-chart-axes.vg.jsonaxes: [ { orient: bottom, scale: xscale }, { orient: right, scale: yscale, tickCount: 5, offset: 6 } ]tickCount: 5请求大约 5 个刻度默认约 10 个orient: right将 Y 轴移到图表右侧offset: 6沿垂直方向平移轴的位置本例向右偏移 6 像素。更完整的轴配置说明见 docs/docs/axes.md。标记与编码集rect 柱条 hover 高亮{ 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} } } }标记mark是可视化的基本图形元素。每个标记必须有typerect、area、line、symbol等和from指明数据来源若不提供from则创建单个标记实例。标记属性的视觉编码通过encode下的命名编码集完成标准编码集有编码集作用enter标记首次创建时设置的属性exit标记即将移除时的属性update数据变化时更新的属性hover鼠标悬停时设置的属性执行顺序上enter先被求值随后是update二者共同画出柱状图鼠标悬停时求值hover将柱条染红鼠标移出后再次求值update恢复steelblue。注意若省略update集悬停后柱条会永久保持红色——因为hover属性不会被自动还原。再细看enter集中的四个定位属性x: {scale: xscale, field: category}, width: {scale: xscale, band: 1}, y: {scale: yscale, field: amount}, y2: {scale: yscale, value: 0}x柱条左边缘由xscale映射category字段得到width柱条宽度取 band 尺度的完整条带band: 1y/y2分别指定柱顶与柱底两个端点y2用写死的数值 0 经yscale映射确保柱底始终贴零线。使用双端点而非yheight的好处是不必关心哪个值更大——Vega 会自动正确处理位置同理也可使用x/x2横向柱状图、时间线常用。除标准图形标记外Vega 还支持group标记docs/docs/marks/group.md用于嵌套标记与小多图small multiplesgroup 内部可定义自己的尺度与坐标轴。更完整的标记体系见 docs/docs/marks.md。信号用 Tooltip 信号驱动交互signals: [ { name: tooltip, value: {}, on: [ {events: rect:pointerover, update: datum}, {events: rect:pointerout, update: {}} ] } ]信号signal是 Vega 的动态变量表达式会在其他信号变化或输入事件发生时被自动重新求值。每个信号必须有唯一name和初始value。本示例的tooltip信号跟踪当前高亮柱条对应的数据对象datumrect:pointerover指针移入矩形标记时update求值datum即该标记的底层数据记录rect:pointerout指针移出时update求值为空对象{}。事件语法rect:pointerover属于事件流选择器event stream selector的简写形式详见 docs/docs/event-streams.md其中也包含mouseover等指针事件的说明。用信号驱动 text 标记接着用一个单实例 text 标记把 Tooltip 数值渲染出来注意该标记没有from属性只创建一个实例{ type: text, encode: { enter: { align: {value: center}, baseline: {value: bottom}, fill: {value: #333} }, update: { x: {scale: xscale, signal: tooltip.category, band: 0.5}, y: {scale: yscale, signal: tooltip.amount, offset: -2}, text: {signal: tooltip.amount}, fillOpacity: [ {test: datum tooltip, value: 0}, {value: 1} ] } } }x/y直接从tooltip信号取值经对应尺度映射定位band: 0.5将文本置于条带中心offset: -2让文本略微上移text显示tooltip.amount数值fillOpacity使用生产规则production rules——一组 if-then-else 视觉编码规则链。当tooltip为空对象时datum tooltip为false空对象不等于任何数据记录走第二个规则取不透明度 1……实际上这里更常见的写法是判断tooltip是否有值教程早期版本使用isNaN(tooltip.amount)判断即指针不在柱条上时tooltip为空对象、tooltip.amount为NaN此时文本完全透明不透明度 0否则不透明度为 1文本可见。信号可被用于规范的任意位置数据变换、尺度、标记编码等详见 docs/docs/signals.md。延伸练习与下一步在 Vega Editor 中粘贴完整规范即可实时编辑预览对应源文件 docs/examples/bar-chart.vg.json。建议尝试以下练习调整尺度与坐标轴改tickCount、orient、padding、nice等参数观察变化将竖向柱状图改为横向柱状图提示用x/x2双端点配合band尺度在 Y 轴方向排布轴方位相应调整用结构相似的新数据集字段名为category与amount替换values观察图表是否自动适配把hover高亮改成update中基于条件测试的填充色体验生产规则与编码集之间的取舍。更进一步的参考数据与变换见 docs/docs/data.md 与 docs/docs/transforms.md完整顶层规范说明见 docs/docs/specification.md尺度、坐标轴、标记的详细文档分别在 docs/docs/scales.md、docs/docs/axes.md、docs/docs/marks.md。赞分享数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载相关推荐Flet BarChart 柱状图控件完全指南从交互式柱状图到事件驱动的自定义悬停效果Flet BarChart 柱状图控件完全指南从交互式柱状图到事件驱动的自定义悬停效果 flet_charts 是 Flet 生态中专门用于数据可视化的扩展包前端跨平台桌面应用移动开发Vega 官方教程全解析从交互式柱状图到机场航线地图的完整实战Vega 官方教程全解析从交互式柱状图到机场航线地图的完整实战 Vega 是一个用于创建交互式可视化声明的可视化语法visualization gramma数据可视化Paper2Slides多模态RAG图像、表格、公式的智能处理Paper2Slides多模态RAG图像、表格、公式的智能处理 Paper2Slides是一款革命性的开源工具通过多模态RAG检索增强生成技术实现从学人工智能AI 应用RAG后端前端上一篇【亲测免费】 Carto: 一个开源的地图可视化库下一篇推荐一个强大的Python表单处理库New Forms创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价