Search code examples
javascriptdata-visualizationvega-litevega

Visualisation with Vega Lite : "emoji undefined"


I'm trying to reproduce a visualisation in Vega Lite (https://vega.github.io/vega-lite/examples/isotype_bar_chart_emoji.html). Instead of the animals emoji, I chose emoji to symbolise energy source. However my code does not work, looks like Vega does not recognise the emojis as it labels : "undefined". How can I help vega so it uses emojis as logos ?

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "config": {"view": {"stroke": ""}},
  "width": 800,
  "height": 200,
  "data": {
    "values": [
{"continent": "Africa", "share": "coal"},
{"continent": "Africa", "share": "coal"},
{"continent": "Africa", "share": "gas"},
{"continent": "Europe", "share": "gas"},
{"continent": "Europe", "share": "gas"},
{"continent": "Europe", "share": "hydro"},
{"continent": "Europe", "share": "nuclear"},
{"continent": "Europe", "share": "renewables"},
{"continent": "Europe", "share": "renewables"},
{"continent": "Europe", "share": "renewables"},
{"continent": "Europe", "share": "renewables"},
{"continent": "Europe", "share": "renewables"}
    ]
  },
  "transform": [
    {
      "calculate": "{'coal': '🏭', 'nuclear': '⚛️', 'oil': '🛢️','renewables':'♻️','gas':'⛽'}",
      "as": "emoji"
    },
    {"window": [{"op": "rank", "as": "rank"}], "groupby": ["continent", "share"]}
  ],
  "mark": {"type": "text", "baseline": "middle"},
  "encoding": {
    "x": {"field": "rank", "type": "ordinal", "axis": null},
    "y": {"field": "share", "type": "nominal", "axis": null, "sort": null},
    "row": {"field": "continent", "header": {"title": ""}},
    "text": {"field": "emoji", "type": "nominal"},
    "size": {"value": 65}
  }
}

Solution

  • The transform calculate was not proper, you can use the datum to access the field from your data and depending on the condition provide the emoji value. Refer the below code or the editor

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "config": {"view": {"stroke": ""}},
      "width": 800,
      "height": 200,
      "data": {
        "values": [
          {"continent": "Africa", "share": "coal"},
          {"continent": "Africa", "share": "coal"},
          {"continent": "Africa", "share": "gas"},
          {"continent": "Europe", "share": "gas"},
          {"continent": "Europe", "share": "gas"},
          {"continent": "Europe", "share": "hydro"},
          {"continent": "Europe", "share": "nuclear"},
          {"continent": "Europe", "share": "renewables"},
          {"continent": "Europe", "share": "renewables"},
          {"continent": "Europe", "share": "renewables"},
          {"continent": "Europe", "share": "renewables"},
          {"continent": "Europe", "share": "renewables"}
        ]
      },
      "transform": [
        {
          "calculate": "datum.share == 'coal' ?  '🏭' : datum.share == 'nuclear' ? '⚛️' : datum.share == 'oil' ? '🛢️' : datum.share == 'renewables' ?'♻️' : '⛽'",
          "as": "emoji"
        },
        {
          "window": [{"op": "rank", "as": "rank"}],
          "groupby": ["continent", "share"]
        }
      ],
      "mark": {"type": "text", "baseline": "middle"},
      "encoding": {
        "x": {"field": "rank", "type": "ordinal", "axis": null},
        "y": {"field": "share", "type": "nominal", "axis": null, "sort": null},
        "row": {"field": "continent", "header": {"title": ""}},
        "text": {"field": "emoji", "type": "nominal"},
        "size": {"value": 65}
      }
    }
    

    or simple adding this line to your current code will also resolve the issue:

    {
      "calculate": "{'coal': '🏭', 'nuclear': '⚛️', 'oil': '🛢️','renewables':'♻️','gas':'⛽', 'hydro': '🏭',}[datum.share]",
      "as": "emoji"
    }