如何使用 "datum" 在 Vega 中放置 x 轴标签?

How to put x-axis labels in Vega using "datum"?

在 Vega 中,我想在 x 轴标签中放置一个表达式,其中包含来自“参考”列的数据。我只能为所有值放置一个固定标签(第 67 行注释),但是当我尝试在文本中放置表达式“datum.reference”时,我做不到(第 68 行)。你可以帮帮我吗?非常感谢您

代码如下:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",

  "width": 400,  
  "height": 200,
  "padding": 5,   
  "autosize": "pad",  

  "data": [
    {
      "name": "table",
      "values": [
        {"category": "A", "amount": 28, "reference": "ref1"},
        {"category": "B", "amount": 55, "reference": "ref2"},
        {"category": "C", "amount": 43, "reference": "ref3"},
        {"category": "D", "amount": 91, "reference": "ref1"},
        {"category": "E", "amount": 81, "reference": "ref4"},
        {"category": "F", "amount": 53, "reference": "ref5"},
        {"category": "G", "amount": 19, "reference": "ref6"},
        {"category": "H", "amount": 87, "reference": "ref7"}
      ]
    }
  ],

  "signals": [
    {
      "name": "tooltip",
      "value": {},
      "on": [
        {"events": "rect:mouseover", "update": "datum"},
        {"events": "rect:mouseout",  "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",
    "title": "X-Axis",
    "encode": {
      "ticks": {
        "update": {
          "stroke": {"value": "steelblue"}
        }
      },
      "labels": {
        "interactive": true,
        "update": {
          //"text": {"value": "x_label"},       // Line 67: This is fine
          "text": {"expr": "datum.reference"},  // Line 68: Here, I have the problem
          "fill": {"value": "steelblue"},
          "angle": {"value": 50},
          "fontSize": {"value": 14},
          "align": {"value": "left"},
          "baseline": {"value": "middle"},
          "dx": {"value": 3}
        },
        "hover": {
          "fill": {"value": "firebrick"}
        }
      },
      "title": {
        "update": {
          "fontSize": {"value": 16}
        }
      },
      "domain": {
        "update": {
          "stroke": {"value": "#333"},
          "strokeWidth": {"value": 1.5}
        }
      }
    }


  },

    { "orient": "left", 
    "scale": "yscale",
    "title": "Y-Axis", 
    "tickCount": 4,"offset": 6 }
  ],

  "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": "isNaN(tooltip.amount)", "value": 0},
            {"value": 1}
          ]
        }
      }
    }
  ]
}
```

首先,Vega axis中的“datum”不引用数据集“table”中的任何项目。相反,Vega axis 使用内部生成的数据集,该数据集基于为该轴定义的 scale

参见Vega documentation for "axis"。该文档还指出(没有给出示例):

Custom text can be defined using the "text" property for labels. For example, one could define an ordinal scale that serves as a lookup table from axis values to axis label text.

这是一个示例,说明如何为此目的使用查找数据集和 scale。请注意,“category”的所有值必须是唯一的,“reference”的所有值必须是唯一的。

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",

  "width": 400,  
  "height": 200,
  "padding": 5,   
  "autosize": "pad",  

  "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}
      ]
    },

    {
      "name": "data_lookup",
      "values": [
        {"category": "A", "reference": "ref1"},
        {"category": "B", "reference": "ref2"},
        {"category": "C", "reference": "ref3"},
        {"category": "D", "reference": "ref10"},
        {"category": "E", "reference": "ref4"},
        {"category": "F", "reference": "ref5"},
        {"category": "G", "reference": "ref6"},
        {"category": "H", "reference": "ref7"}
      ]
    }
  ],

  "signals": [
    {
      "name": "tooltip",
      "value": {},
      "on": [
        {"events": "rect:mouseover", "update": "datum"},
        {"events": "rect:mouseout",  "update": "{}"}
      ]
    }
  ],

  "scales": [
    {
      "name": "scale_lookup",
      "type": "ordinal",
      "domain": {"data": "data_lookup", "field": "category"},
      "range": {"data": "data_lookup", "field": "reference"}
    },
    {
      "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",
    "title": "X-Axis",
    "encode": {
      "ticks": {
        "update": {
          "stroke": {"value": "steelblue"}
        }
      },
      "labels": {
        "interactive": true,
        "update": {

         "text": {"signal": "scale('scale_lookup', datum.value)"},

          "fill": {"value": "steelblue"},
          "angle": {"value": 50},
          "fontSize": {"value": 14},
          "align": {"value": "left"},
          "baseline": {"value": "middle"},
          "dx": {"value": 3}
        },
        "hover": {
          "fill": {"value": "firebrick"}
        }
      },
      "title": {
        "update": {
          "fontSize": {"value": 16}
        }
      },
      "domain": {
        "update": {
          "stroke": {"value": "#333"},
          "strokeWidth": {"value": 1.5}
        }
      }
    }


  },

    { "orient": "left", 
    "scale": "yscale",
    "title": "Y-Axis", 
    "tickCount": 4,"offset": 6 }
  ],

  "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": "isNaN(tooltip.amount)", "value": 0},
            {"value": 1}
          ]
        }
      }
    }
  ]
}

View in Vega online editor.

我已经用非常简单的方法解决了这个问题。只需创建一个连接两个字段的转换,然后使用该新列来表示数据。无论如何,非常感谢您提供我觉得非常有趣和有用的其他解决方案。

这里我提供我想要实现的代码

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",

  "width": 400,  
  "height": 200,
  "padding": 5,   
  "autosize": "pad",  

  "data": [
    {
      "name": "table",
      "values": [
        {"category": "A", "amount": 28, "reference": "ref1"},
        {"category": "B", "amount": 55, "reference": "ref2"},
        {"category": "C", "amount": 43, "reference": "ref3"},
        {"category": "D", "amount": 91, "reference": "ref1"},
        {"category": "E", "amount": 81, "reference": "ref4"},
        {"category": "F", "amount": 53, "reference": "ref5"},
        {"category": "G", "amount": 19, "reference": "ref6"},
        {"category": "H", "amount": 87, "reference": "ref7"}
      ],

      "transform":[
      {"type": "formula",
      "expr": "datum.category + ' (' + datum.reference + ')' ",
      "as": "category(ref)"}
    ]
    },

    
  ],

  "signals": [
    {
      "name": "tooltip",
      "value": {},
      "on": [
        {"events": "rect:mouseover", "update": "datum"},
        {"events": "rect:mouseout",  "update": "{}"}
      ]
    }
  ],

  "scales": [
    {
      "name": "xscale",
      "type": "band",
      "domain": {"data": "table", "field": "category(ref)"},
      "range": "width",
      "padding": 0.05,
      "round": true
    },
    {
      "name": "yscale",
      "domain": {"data": "table", "field": "amount"},
      "nice": true,
      "range": "height"
    }
  ],

"axes": [
  {
    "orient": "bottom",
    "scale": "xscale",
    "title": "X-Axis",
    "encode": {
      "ticks": {
        "update": {
          "stroke": {"value": "steelblue"}
        }
      },
      "labels": {
        "interactive": true,
        "update": {
          "fill": {"value": "steelblue"},
           "angle": {"value": 50},
          "fontSize": {"value": 14},
          "align": {"value": "left"},
          "baseline": {"value": "middle"},
          "dx": {"value": 3}
        },
        "hover": {
          "fill": {"value": "firebrick"}
        }
      },
      "title": {
        "update": {
          "fontSize": {"value": 16}
        }
      },
      "domain": {
        "update": {
          "stroke": {"value": "#333"},
          "strokeWidth": {"value": 1.5}
        }
      }
    }


  },

    { "orient": "left", 
    "scale": "yscale",
    "title": "Y-Axis", 
    "tickCount": 4,"offset": 6 }
  ],

  "marks": [
    {
      "type": "rect",
      "from": {"data":"table"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "category(ref)"},
          "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": "isNaN(tooltip.amount)", "value": 0},
            {"value": 1}
          ]
        }
      }
    }
  ]
}