You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vega-Lite如何让图例仅展示有对应数据的自定义色阶条目

问题场景
  • 仪表板内部署饼图、散点图、柱状图等多类图表,所有图表统一使用指定维度做颜色编码,因此预先定义了一套全图表复用的自定义色阶
  • 默认逻辑下每个图表的图例都会展示色阶配置的全部条目,但部分色值对应的分类在当前图表数据集中无对应数据点,实际仅需展示存在有效数据的条目
  • 需要可复用的Vega-Lite通用方案,对接不同数据集时自动过滤图例中无数据的分类条目,同时保持预设的「分类-颜色」固定映射关系不发生错位

存在冗余条目的图例效果

原始示例代码:

const EEKData = {
  "values": [
    {EEK: "A+", Energieträger: "Wärmepumpe", frequency: 1},
    {EEK: "A", Energieträger: "Gas", frequency: 16},
    {EEK: "A", Energieträger: "Wärmepumpe", frequency: 5},
    {EEK: "A", Energieträger: "Fernwärme", frequency: 7},
    {EEK: "B", Energieträger: "Fernwärme", frequency: 14},
    {EEK: "C", Energieträger: "Wärmepumpe", frequency: 201},
    {EEK: "D", Energieträger: "Wärmepumpe", frequency: 248},
    {EEK: "E", Energieträger: "Wärmepumpe", frequency: 210},
    {EEK: "F", Energieträger: "Wärmepumpe", frequency: 200},
    {EEK: "H", Energieträger: "Gas", frequency: 28}
  ]
};

const custom_scale = {
  "domain": ["Fernwärme", "Gas", "Gas dezentral", "BHKW", "Pellet", "Öl", "Wärmepumpe", "Elektro-Nachtspeicher", "Sonstiges"],
  "range": ["#0070C0", "#ED6011", "#FF0900", "#C00025", "#843C0C", "#000000", "#70AD47", "#6C7406", "#595959"]
};

const spec = {
  data: {name: 'values'},
  mark: {type: 'bar', size: 20, opacity: 1},
  encoding: {
    x: {
      field: 'EEK', 
      type: 'nominal', 
      sort: ["A+", "A", "B", "C", "D", "E", "F", "G", "H"], 
      title: null, 
      axis: {labelAngle: 0}
    },
    y: {field: 'frequency', type: 'quantitative', title: null},
    color: {field: 'Energieträger', type: 'nominal', scale: custom_scale},
  }
};

return <VegaLite
  spec={spec}
  data={EEKData}
/>
解决方案

核心问题出在硬编码了色阶的domain为全部分类列表,Vega-Lite会默认将domain内的所有值展示在图例中,和数据集内是否存在对应值无关。
不需要额外做数据集过滤,也不需要针对单个图表写定制逻辑,直接调整自定义色阶的定义方式即可实现全局复用:

  • 将原来按顺序对应的domain+range数组,改写为分类名到颜色值的键值对映射对象,去掉硬编码的domain配置,让Vega-Lite自动从当前数据集提取实际存在的分类作为色阶domain
  • 如果需要保持图例、色值的固定排序顺序,在scale和legend配置中传入预设的分类顺序数组即可
  • 该方案兼容所有图表类型(饼图、散点图、柱状图等),切换数据集时会自动识别存在的分类,过滤无数据的图例项,且颜色映射永远不会错位

调整后的代码如下:

const EEKData = {
  "values": [
    {EEK: "A+", Energieträger: "Wärmepumpe", frequency: 1},
    {EEK: "A", Energieträger: "Gas", frequency: 16},
    {EEK: "A", Energieträger: "Wärmepumpe", frequency: 5},
    {EEK: "A", Energieträger: "Fernwärme", frequency: 7},
    {EEK: "B", Energieträger: "Fernwärme", frequency: 14},
    {EEK: "C", Energieträger: "Wärmepumpe", frequency: 201},
    {EEK: "D", Energieträger: "Wärmepumpe", frequency: 248},
    {EEK: "E", Energieträger: "Wärmepumpe", frequency: 210},
    {EEK: "F", Energieträger: "Wärmepumpe", frequency: 200},
    {EEK: "H", Energieträger: "Gas", frequency: 28}
  ]
};

// 改为键值对形式的颜色映射,去掉硬编码domain
const customColorMap = {
  "Fernwärme": "#0070C0",
  "Gas": "#ED6011",
  "Gas dezentral": "#FF0900",
  "BHKW": "#C00025",
  "Pellet": "#843C0C",
  "Öl": "#000000",
  "Wärmepumpe": "#70AD47",
  "Elektro-Nachtspeicher": "#6C7406",
  "Sonstiges": "#595959"
};
// 预设的分类排序顺序,全图表复用
const categoryOrder = ["Fernwärme", "Gas", "Gas dezentral", "BHKW", "Pellet", "Öl", "Wärmepumpe", "Elektro-Nachtspeicher", "Sonstiges"];

const spec = {
  data: {name: 'values'},
  mark: {type: 'bar', size: 20, opacity: 1},
  encoding: {
    x: {
      field: 'EEK', 
      type: 'nominal', 
      sort: ["A+", "A", "B", "C", "D", "E", "F", "G", "H"], 
      title: null, 
      axis: {labelAngle: 0}
    },
    y: {field: 'frequency', type: 'quantitative', title: null},
    color: {
      field: 'Energieträger', 
      type: 'nominal',
      scale: {
        range: customColorMap,
        sort: categoryOrder // 保持分类颜色排序和预设一致
      },
      legend: {
        sort: categoryOrder // 保持图例条目顺序和预设一致
      }
    },
  }
};

return <VegaLite
  spec={spec}
  data={EEKData}
/>

调整后示例数据集仅存在Fernwärme、Gas、Wärmepumpe三个有效分类,图例将仅展示这三个条目,其余无数据的分类会自动隐藏。切换其他数据集时,新增的存在数据的分类会自动按预设颜色展示在图例中,无需修改代码。

兼容说明:如果使用5.0以下的低版本Vega-Lite不支持range传对象,可以通过transform.aggregate提前聚合当前数据集的有效分类,将scale.domain绑定到聚合结果即可,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Eilema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:18:19