Radar diagram (Vega)

Vega has no radar chart type, so this builds one: a line mark over angles computed from the data. It is the clearest demonstration of what a grammar buys you.


#What this example shows

  • Angles computed with a formula transform.

  • A line mark closing back on itself.

  • Axis spokes drawn as rule marks.


#A worked example

Open it, edit it, or copy the source below.

Radar diagram (Vega)

The source, which you can paste into a new diagram and edit:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 320,
  "height": 320,
  "autosize": "none",
  "padding": 40,
  "signals": [
    {"name": "radius", "update": "width / 2 - 20"},
    {"name": "count", "value": 6}
  ],
  "data": [
    {
      "name": "values",
      "values": [
        {"axis": "Speed", "i": 0, "v": 85},
        {"axis": "Cost", "i": 1, "v": 60},
        {"axis": "Support", "i": 2, "v": 70},
        {"axis": "Ease", "i": 3, "v": 90},
        {"axis": "Security", "i": 4, "v": 65},
        {"axis": "Extensibility", "i": 5, "v": 55}
      ],
      "transform": [
        {"type": "formula", "as": "angle", "expr": "datum.i * 2 * PI / count - PI / 2"},
        {"type": "formula", "as": "x", "expr": "width / 2 + cos(datum.angle) * radius * datum.v / 100"},
        {"type": "formula", "as": "y", "expr": "height / 2 + sin(datum.angle) * radius * datum.v / 100"},
        {"type": "formula", "as": "lx", "expr": "width / 2 + cos(datum.angle) * (radius + 14)"},
        {"type": "formula", "as": "ly", "expr": "height / 2 + sin(datum.angle) * (radius + 14)"},
        {"type": "formula", "as": "sx", "expr": "width / 2 + cos(datum.angle) * radius"},
        {"type": "formula", "as": "sy", "expr": "height / 2 + sin(datum.angle) * radius"}
      ]
    }
  ],
  "marks": [
    {
      "type": "rule",
      "from": {"data": "values"},
      "encode": {"enter": {
        "x": {"signal": "width / 2"}, "y": {"signal": "height / 2"},
        "x2": {"field": "sx"}, "y2": {"field": "sy"},
        "stroke": {"value": "#cbd5e1"}
      }}
    },
    {
      "type": "line",
      "from": {"data": "values"},
      "encode": {"enter": {
        "x": {"field": "x"}, "y": {"field": "y"},
        "stroke": {"value": "#4c78a8"},
        "strokeWidth": {"value": 2},
        "fill": {"value": "#4c78a8"},
        "fillOpacity": {"value": 0.25},
        "interpolate": {"value": "linear-closed"}
      }}
    },
    {
      "type": "text",
      "from": {"data": "values"},
      "encode": {"enter": {
        "x": {"field": "lx"}, "y": {"field": "ly"},
        "text": {"field": "axis"},
        "align": {"value": "center"}, "baseline": {"value": "middle"},
        "fontSize": {"value": 11}
      }}
    }
  ]
}

#Making it your own

  • interpolate linear-closed is what joins the last point back to the first.

  • Change count if you change the number of axes, or the angles will be wrong.

  • Mermaid's radar-beta does this in six lines. Use Vega only when you need the control.



All the control, all the ceremony.