Search code examples
powerbivisualizationpowerbi-desktopvega-litedeneb

Vega lite tooltip when hovering stacked bar text marks


With text marks on stacked bar charts, is there a way to avoid duplicating the tooltip code so that the tool tip is the same when hovering over the text marks?

Example adjusted from here. Note the custom tooltip which shows only gender. If I don't repeat this code for the text mark, it shows a different tooltip when hovering. This gets inelegant with a complex tooltip.

Hovering over a bar:

Hovering a bar

Hovering over the text:

Hovering a text mark

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": { "url": "data/population.json"},
  "transform": [
    {"filter": "datum.year == 2000"},
    {"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"}
  ],
  "height": {"step": 17},
  "encoding": {
    "y": {"field": "age"}
  },
  "layer": [{
    "mark": {"type": "bar", "tooltip": true},
    "encoding": {
      "x": {
        "aggregate": "sum", "field": "people",
        "title": "population",
        "stack":  "normalize"
      },
      "color": {
        "field": "gender",
        "scale": {"range": ["#675193", "#ca8861"]}
      },
      "tooltip": [
        {   
          "field": "gender",
          "type": "nominal",
          "title": "Gender"}
      ]
    }
  }, {
    "mark": {"type": "text", "opacity": 0.9, "color": "white", "tooltip": true},
    "encoding": {
      "x": {
        "aggregate": "sum", "field": "people",
        "title": "population",
        "stack":  "normalize",
        "bandPosition": 0.5
      },
      "text": {
        "aggregate": "sum", "field": "people",
        "title": "population"
      },
      "detail": {
        "field": "gender"
      }
    }
  }]
}

More generally, it would be good to find some guidance where code needs to be repeated and where it can be defined once and reused.


Solution

  • Just elevate the encoding for the custom tooltip then it will be reused across marks. I don't think VL has an attribute for "interactive" which is what is used in Vega.

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {"url": "data/population.json"},
      "transform": [
        {"filter": "datum.year == 2000"},
        {"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"}
      ],
      "height": {"step": 17},
      "encoding": {
        "tooltip": [{"field": "gender", "type": "nominal", "title": "Gender"}],
        "y": {"field": "age"}
      },
      "layer": [
        {
          "mark": {"type": "bar", "tooltip": true},
          "encoding": {
            "x": {
              "aggregate": "sum",
              "field": "people",
              "title": "population",
              "stack": "normalize"
            },
            "color": {"field": "gender", "scale": {"range": ["#675193", "#ca8861"]}}
          }
        },
        {
          "mark": {
            "type": "text",
            "opacity": 0.9,
            "color": "white",
            "tooltip": true
          },
          "encoding": {
            "x": {
              "aggregate": "sum",
              "field": "people",
              "title": "population",
              "stack": "normalize",
              "bandPosition": 0.5
            },
            "text": {"aggregate": "sum", "field": "people", "title": "population"},
            "detail": {"field": "gender"}
          }
        }
      ]
    }