user2694295
user2694295

Reputation: 390

vega lite expr reference mark column width

I have vertical column chart like this one

vertical column bar chart

The chart is set to fit into the container with 100% width. Column with in the chart is calculated responsively by vega to fit into the container.

In additional layer I'm rendering text value labels above the columns. And I need the label to be exactly above its corresponding column. To calculate the position of a label I'm using expression:

 "mark": {
        "dx": {"expr": "((datum.maxGroupCount-1)*-10)+(datum.index-1)*20"},
        "dy": -5,
        "fontSize": 9,
        "type": "text"
      }

Instead of the defined constant 20 in the dx expr I need to reference the actual column width so that the labels are rendered properly when size of the chart changes.

In the vega lite editor https://vega.github.io/editor/ you can see the actual column width in Data viewer tab when you select layer_0_marks.

Is it possible to reference the column width?

Upvotes: 0

Views: 354

Answers (1)

APB Reports
APB Reports

Reputation: 2451

You could setup the text marks in a dynamic way like this:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"category": "A", "group": "x", "value": 0.1},
      {"category": "A", "group": "y", "value": 0.6},
      {"category": "A", "group": "z", "value": 0.9},
      {"category": "B", "group": "x", "value": 0.7},
      {"category": "B", "group": "y", "value": 0.2},
      {"category": "B", "group": "z", "value": 1.1},
      {"category": "C", "group": "x", "value": 0.6},
      {"category": "C", "group": "y", "value": 0.1},
      {"category": "C", "group": "z", "value": 0.2}
    ]
  },
  "encoding": {
    "x": {"field": "category", "title": null},
    "y": {"field": "value", "type": "quantitative", "title": null},
    "xOffset": {"field": "group"},
    "color": {"field": "group"}
  },
  "layer": [
    {"mark": {"type": "bar"}},
    {
      "mark": {"type": "text", "dy": -7},
      "encoding": {
        "text": {"field": "value", "type": "quantitative"},
        "color": {"value": "black"}
      }
    },
    {
      "transform": [
        {
          "joinaggregate": [{"op": "max", "field": "value", "as": "total"}],
          "groupby": []
        },
        {"calculate": "datum.total * 1.1", "as": "max"}
      ],
      "mark": {"type": "point", "dy": -10},
      "encoding": {
        "y": {"field": "max", "type": "quantitative"},
        "color": {"value": "transparent"}
      }
    }
  ],
  "config": {}
}

I also added an additional point layer to extend the top of the chart for the largest value. I added 10% but you can change this.

Let me know if this was useful.

enter image description here

Upvotes: 1

Related Questions