Search code examples
vegavega-lite

Sort axis by another field in Vega Lite


I'm trying to sort ordinal data on the x axis by a different field from the one I'm using as a label. Both fields (I'll call them 'sortable' and 'nonsortable') are one-to-one, meaning one is computed from the other and there will never be an instance when one 'sortable' value will correspond to two different 'nonsortable' values, and vice versa.

I tried two approaches:

  1. Changing the sort order to use a different field like this:
...
x: {
  field: 'nonsortable',
  sort: {
    field: 'sortable',
    op: 'count',
  },
},
...

I wasn't sure which aggregate operation to use, but since the two fields are one-to-one, that shouldn't matter right?

This changed the order in a way that I don't understand, but it certainly didn't sort the axis by the 'sortable' field as intended.

  1. Changing the label to a different field like this:
...
x: {
  field: 'sortable',
  axis: {
    labelExpr: 'datum.nonsortable',
  },
}
...

This didn't work at all. I think maybe I misunderstood how the label expressions work.

Is there another way to do this, or maybe a way salvage one of these attempts?


Solution

  • If no aggregation is required, you should pass the sort attribute without an aggregate. For example (vega editor link):

    {
      "data": {
        "values": [
          {"sortable": 5, "nonsortable": "five"},
          {"sortable": 2, "nonsortable": "two"},
          {"sortable": 3, "nonsortable": "three"},
          {"sortable": 1, "nonsortable": "one"},
          {"sortable": 4, "nonsortable": "four"}
        ]
      },
      "mark": "point",
      "encoding": {
        "x": {
          "type": "nominal",
          "field": "nonsortable",
          "sort": {"field": "sortable"}
        }
      }
    }
    

    enter image description here