Search code examples
vegavega-lite

How to specify Rule Line with a single value in VegaLite?


It's possible to specify Rule as encoding over the data. But sometimes it's too verbose. Is there a shorter way to specify it with just a single number?

In example below I want to draw a horizontal line with y=1 and it requires me to specify a calculate transform. Wonder if it's possible with something more compact, like:

"layer": [
  ...,
  { "mark": { "type": "rule", "y": 1 }, // Specify ruler with just a single line
  ...
]

Playground

{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "transform":[
    { "calculate": "1", "as": "one" }
  ],
  "layer": [
    {
      "mark": { "type": "bar" },
      "encoding": {
        "x": { "field": "diff", "type": "quantitative" },
        "y": { "field": "diff", "type": "quantitative" }
      }
    },
    {
      "mark": { "type": "rule" },
      "encoding": {
        "y": { "field": "one", "type": "quantitative" }
      }
    }
  ],
  "data": {
    "values": [
      { "diff": 1 },
      { "diff": 2 },
      { "diff": 3 }
    ]
  }
}

Solution

  • You can specify a single value using the "value" field in the encoding; e.g.

    {
      "mark": { "type": "rule" },
      "encoding": {
        "y": { "value": 133 }
      }
    }
    

    (Playground)

    But be aware this value is a value in the axis domain, rather than in the data domain; i.e. it represents pixels from the top-left of the chart.

    If you want to specify a value in the data domain, there is no such shorthand. You have to either use a transform (as you did in your question) or define a new dataset for your layer. The most compact way of doing this, I think, is something like this:

    {
      "mark": { "type": "rule" },
      "data": {"values": {"y": 1}},
      "encoding": {
        "y": { "field": "y" }
      }
    }