jsonchartsvisualizationvega-litevega

Label wrapping with stacked bar charts


I'm attempting to split the label on the x axis in a vega-lite stacked bar chart so that the text wraps. Using the below, while the text does wrap, the rest of the chart breaks in a confusing way.

(Ignore that the data is nonsense, this is only for illustration purposes.)

{
  "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
  "height": "container",
  "width": 300,
  "data": {
    "values": [
      {
        "age": 25,
        "gender": "F",
        "address": "927 Bay Parkway",
      },
      {
        "age": 25,
        "gender": "M",
        "address": "927 Bay Parkway",
      },
      {
        "age": 33,
        "gender": "F",
        "address": "685 School Lane",
      },
      {
        "age": 33,
        "gender": "M",
        "address": "685 School Lane",
      }
    ]
  },
  "autosize": {"contains": "padding", "type": "fit", "resize": true},
  "transform": [{"calculate": "split(datum.address, ' ')", "as": "address"}],
  "layer": [
    {
      "mark": {"type": "bar"},
      "encoding": {
        "y": {
          "field": "age",
          "type": "quantitative",
          "axis": {"title": "sum_balance"}
        },
        "x": {
          "field": "address",
          "type": "ordinal",
          "axis": {
            "title": "Name",
            "labelAngle": -45,
            "labelFontSize": 12,
            "labelLimit": 60
          }
        },
        "color": {"field": "gender"}
      },
      "selection": {"brush": {"type": "interval"}}
    }
  ]
}

The stacks are all janky in a way I can't make sense of:

The rendered chart with the broken stacking.

You can also see this in the online vega editor.

If I remove the transform, the stacking works but the labels aren't wrapped. If I remove the M entries from the data, the chart renders correctly just for F data. It's only when I both stack and wrap that there's a problem.

My hypothesis is that there's some kind of object equality being used for grouping for the stacked bar charts and so each array of strings for the title are being seen as different groups... but I'm not sure how to validate or work around that issue.

Is there a way to work around this? And what exactly is happening here?


Solution

  • You are passing an array to a band scale so results will be unpredictable. I'm surprised it works at all to be honest.

    enter image description here

    enter image description here

    The fix is to use a label expression.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "height": "container",
      "width": 300,
      "data": {
        "values": [
          {"age": 25, "gender": "F", "address": "927 Bay Parkway"},
          {"age": 25, "gender": "M", "address": "927 Bay Parkway"},
          {"age": 33, "gender": "F", "address": "685 School Lane"},
          {"age": 33, "gender": "M", "address": "685 School Lane"}
        ]
      },
      "autosize": {"contains": "padding", "type": "fit", "resize": true},
    
      "layer": [
        {
          "mark": {"type": "bar"},
          "encoding": {
            "y": {
              "field": "age",
              "type": "quantitative",
              "axis": {"title": "sum_balance"}
            },
            "x": {
              "field": "address",
              "type": "ordinal",
              "axis": {
                "title": "Name",
                "labelAngle": -45,
                "labelFontSize": 12,
                "labelLimit": 60,
                "labelExpr": "split(datum.label, ' ')"
              }
            },
            "color": {"field": "gender"}
          }
        }
      ]
    }