Search code examples
vega-litevega

Formatting and displaying data in Vega chart legends


I am trying to build a pie chart in vega lite where the legend has a formatted table-like structure, displaying the field name (Data N in example) and the data (40 etc. in screenshot) together.

Ideally this would also format appropriately when the Data field strings extend in value (essentially like table formatting)

Mocked up image of desired output here

I have been playing with the labelExpr function as part of the legend variable; however there doesn't seem an easy way to get the values into the legend, nor does there seem to be any options around formatting it?

My working example of the chart is here on vega editor

many thanks in advance!

{
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "description": "A simple pie chart with embedded data.",
    "data": {
        "values": [
            {
                "category": "Field1",
                "value": 40
            },
            {
                "category": "Field2",
                "value": 36
            },
            {
                "category": "Field3",
                "value": 10
            },
            {
                "category": "Field4",
                "value": 9
            },
            {
                "category": "Field5",
                "value": 4
            },
            {
                "category": "Field6",
                "value": 1
            }
        ]
    },
    "mark": "arc",
    "encoding": {
        "theta": {
            "field": "value",
            "type": "quantitative"
        },
        "color": {
            "field": "category",
            "type": "nominal",
            "sort": false,
            "legend": {
                "symbolType": "square",
                "labelFont": "Arial Narrow",
                "labelFontSize": 18,
                "labelExpr": "join([datum.label,' ',datum.value])"
            }
        }
    }
}

Solution

  • Here is an example solution in Vega (not Vega-Lite). Add a scale to lookup the data values:

     {
          "name": "scale_legend_values",
          "type": "ordinal",
          "domain": {"data": "data_table", "field": "category"},
          "range":  {"data": "data_table", "field": "amount"}
        }
    

    and use that scale in the legend label text:

      "legends": [
        {
          "labelFont": "Arial Narrow",
          "labelFontSize": 18,
          "symbolType": "square",
          "fill": "color",
          "title": "category",
          "encode": {
            "labels": {
              "update": {"text": {"signal": "datum.label + ' ' + scale('scale_legend_values', datum.label)"}}
            }
          }
        }
      ]
    

    View in Vega on-line editor

    enter image description here

    Complete Vega spec:

    {
      "$schema": "https://vega.github.io/schema/vega/v5.json",
      "description": "A simple pie chart with embedded data.",
      "background": "white",
      "padding": 5,
      "width": 200,
      "height": 200,
      "data": [
        {
          "name": "data_table",
          "values": [
            {"category": "Field1", "amount": 40},
            {"category": "Field2", "amount": 36},
            {"category": "Field3", "amount": 10},
            {"category": "Field4", "amount": 9},
            {"category": "Field5", "amount": 4},
            {"category": "Field6", "amount": 1}
          ],
          "transform": [
            {
              "type": "pie",
              "field": "amount"
            }
          ]
        }
      ],
      "marks": [
        {
          "name": "mark_arc",
          "type": "arc",
          "from": {"data": "data_table"},
          "encode": {
            "enter": {
              "fill": {"scale": "color", "field": "category"},
              "x": {"signal": "width / 2"},
              "y": {"signal": "height / 2"},
              "outerRadius": {"signal": "min(width,height) / 2"},
              "innerRadius": {"value": 0},
              "startAngle": {"field": "startAngle"},
              "endAngle": {"field": "endAngle"}
            }
          }
        }
      ],
      "scales": [
        {
          "name": "color",
          "type": "ordinal",
          "domain": {"data": "data_table", "field": "category"},
          "range":  {"scheme": "category20"}
        },
        {
          "name": "scale_legend_values",
          "type": "ordinal",
          "domain": {"data": "data_table", "field": "category"},
          "range":  {"data": "data_table", "field": "amount"}
        }
      ],
      "legends": [
        {
          "labelFont": "Arial Narrow",
          "labelFontSize": 18,
          "symbolType": "square",
          "fill": "color",
          "title": "category",
          "encode": {
            "labels": {
              "update": {"text": {"signal": "datum.label + ' ' + scale('scale_legend_values', datum.label)"}}
            }
          }
        }
      ]
    }