PAYATHON 2026

Vega 如何在 checkbox 对应的 signal 为 false 时完整移除图例?

数据小陈

可以把图例放进数据驱动的 group,用 toggleOrigin 过滤 group 的数据。取消勾选时,数据变为空数组,group 实例及其内部图例随之移除;重新勾选时,group 和图例会重新创建,无需将 opacity 设为 0。

为什么散点颜色变了,图例还在?

原代码中,toggleOrigin 只用于散点的 stroke 条件判断。顶层 legends 仍声明了一个引用 color scale 的图例,所以散点改用 steelblue 后,图例不会自动消失。

Vega 支持在 group 内定义图例,也支持根据输入数据创建或移除 mark 实例。可以利用这两个机制实现条件图例。Legends 文档、Marks 文档

1. 给 checkbox 设置明确的初始值

在顶层 signals 中,将原来的 toggleOrigin 定义替换为:

{
  "name": "toggleOrigin",
  "value": false,
  "bind": {"input": "checkbox"}
}

false 表示初始不勾选。如果需要初始显示分类颜色和图例,改为 true。Signals 文档

2. 添加控制图例实例的数据集

在顶层 data 数组中追加以下对象,保留现有的 source_0 和 paintbrush_store:

{
  "name": "legendGate",
  "values": [{}],
  "transform": [
    {
      "type": "filter",
      "expr": "!!toggleOrigin"
    }
  ]
}

勾选时,过滤器保留唯一的数据对象;取消勾选时,将其过滤掉。signal 更新会传递给依赖它的 transform,无需手动调用 D3。Filter 文档、Signals 文档

3. 将图例移入条件 group

删除原来的顶层 legends,然后在顶层 marks 数组中追加以下 group。已有的散点 mark 保留:

{
  "name": "originLegendGroup",
  "type": "group",
  "from": {"data": "legendGate"},
  "encode": {
    "update": {
      "x": {"signal": "width + 18"},
      "y": {"value": 0}
    }
  },
  "legends": [
    {
      "stroke": "color",
      "symbolType": "circle",
      "title": "Origin",
      "orient": "none",
      "legendX": 0,
      "legendY": 0,
      "encode": {
        "symbols": {
          "update": {
            "fill": {"value": "transparent"},
            "opacity": {"value": 0.7}
          }
        }
      }
    }
  ]
}

group 有自己的坐标空间。这里将 group 放在绘图区右侧,用 orient: "none"、legendX 和 legendY 把图例定位在 group 原点。18 是示例间距,可以根据页面布局调整。Group Mark 文档、图例定位属性

原有的散点着色条件继续使用:

"stroke": [
  {"test": "!!toggleOrigin", "scale": "color", "field": "Origin"},
  {"value": "steelblue"}
]

这样,同一个 signal 同时控制散点颜色和图例 group 是否存在。

注意事项

  • 必须移除顶层的旧图例,否则它仍会显示。
  • 不要通过清空 color scale 的 domain 来隐藏图例,散点着色也依赖这个 scale。
  • group 移除后,内部图例实例也会移除。SVG 渲染器可能仍会保留用于组织 mark 的空包装节点,因此这种方式不保证删除所有相关的 <g> 元素。
  • 如果页面容器设置了固定宽度,图例消失后容器不会自动缩窄,需要另外处理容器样式和图表的 autosize 设置。
  • 原始代码缺少开头的 {,独立运行前需要补齐,还要确保 data/cars.json 的相对路径在实际页面中可访问。该方案依据 Vega 文档中的机制提出,尚未对这份完整配置进行运行验证。

备注:内容仅供参考。