Tobia
Tobia

Reputation: 18811

Vega-lite: customize axis style based on selection

I'm trying to customize the style of axis labels based on a selection, meaning whether the label is included in a selection or not.

Starting from this demo spec (Open the Chart in the Vega Editor) the selection works as expected, highlighting the selected bar:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "data": {
    "values": [
      { "model": "Sedan",                 "sales": 12 },
      { "model": "Coupe",                 "sales": 10 },
      { "model": "Sports car",            "sales": 35 },
      { "model": "Station wagon",         "sales": 69 },
      { "model": "Hatchback",             "sales": 91 },
      { "model": "Convertible",           "sales": 53 },
      { "model": "Sport-utility vehicle", "sales": 14 },
      { "model": "Minivan",               "sales": 48 }
    ]
  },
  "mark": "bar",
  "selection": {
    "select_model": { "type": "single", "fields": ["model"] }
  },
  "encoding": {
    "y": { "field": "model" },
    "x": { "field": "sales", "type": "quantitative" },
    "fillOpacity": {
      "value": 0.3,
      "condition": { "selection": "select_model", "value": 1 }
    }
  }
}

enter image description here

But I would like to highlight the axis labels too (and maybe accept clicks on them? I'm not sure if that's possible)

If I try to replace the Y encoding with this:

"y": { 
  "field": "model",
  "axis": {
    "labelOpacity": {
      "value": 0.3,
      "condition": { 
        "test": { "selection": "select_model" }, 
        "value": 1 
      }
    }
  }
}

I get the following error:

Cannot read property 'getSelectionComponent' of null

What am I doing wrong?

Upvotes: 1

Views: 727

Answers (1)

jakevdp
jakevdp

Reputation: 86310

The reason your approach did not work is because scale labels are never contained in selections. You can accomplish what you want by explicitly testing if the label is present in the selected values using a vega expression. It might look something like this:

      "axis": {
        "labelOpacity": {
          "value": 0.3,
          "condition": {
            "test": "indexof(select_model.model || [], datum.value) >= 0",
            "value": 1
          }
        }
      }

This is the full result (view in editor):

{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "data": {
    "values": [
      {"model": "Sedan", "sales": 12},
      {"model": "Coupe", "sales": 10},
      {"model": "Sports car", "sales": 35},
      {"model": "Station wagon", "sales": 69},
      {"model": "Hatchback", "sales": 91},
      {"model": "Convertible", "sales": 53},
      {"model": "Sport-utility vehicle", "sales": 14},
      {"model": "Minivan", "sales": 48}
    ]
  },
  "mark": "bar",
  "selection": {
    "select_model": {"type": "single", "fields": ["model"], "empty": "none"}
  },
  "transform": [
    {"calculate": "indexof(select_model.model || [], 'Hatchback')", "as": "Val"}
  ],
  "encoding": {
    "y": {
      "field": "model",
      "axis": {
        "labelOpacity": {
          "value": 0.3,
          "condition": {
            "test": "indexof(select_model.model || [], datum.value) >= 0",
            "value": 1
          }
        }
      }
    },
    "x": {"field": "sales", "type": "quantitative"},
    "fillOpacity": {
      "value": 0.3,
      "condition": {"selection": "select_model", "value": 1}
    }
  }
}

enter image description here

Upvotes: 1

Related Questions