bluenote10
bluenote10

Reputation: 26709

How to work with primitive values in inline data?

In general inline data in vega-lite is supposed to have a form like this:

"data": {
  "values": [
    {"first column": "A", "second column": 28, "third column": 32}, 
    {"first column": "B", "second column": 55, "third column": 94}, 
    {"first column": "C", "second column": 43, "third column": 21},
    ...
  ]
}

I'm trying to find out if inline data can be specified more concisely by "transposing" the data. This would avoid the excessive repeating of the field names, i.e.:

"data": {
  "values": [
    {"first column": ["A", "B", "C"]}, 
    {"second column": [28, 55, 43]}, 
    {"third column": [32, 94, 21]},
    ...
  ]
}

The documentation of inline data vaguely mentions for the values field:

This can be an array of objects or primitive values or a string. Arrays of primitive values are ingested as objects with a data property.

So all I can do is e.g. "values": ["A", "B", "C"].

How can I make use of such primitive inline data? The data only has a single field data, which is not enough to plot on an x + y axis. Is there also an auto-generated id field that can be used in an axis encoding? Or is it possible to combine multiple primitive inline data sets into a data set with multiple (named) fields?

Is the compact data variant possible with standard vega?

Upvotes: 1

Views: 326

Answers (2)

dominik
dominik

Reputation: 5935

Once https://github.com/vega/vega-lite/pull/3822 has been merged, you can use the flatten transform for this. See https://vega.github.io/vega/docs/transforms/flatten/ for the Vega equivalent.

Input

[
  {"key": "alpha", "foo": [1, 2],    "bar": ["A", "B"]},
  {"key": "beta",  "foo": [3, 4, 5], "bar": ["C", "D"]}
]

Output

[
  {"key": "alpha", "foo": 1, "bar": "A"},
  {"key": "alpha", "foo": 2, "bar": "B"},
  {"key": "beta",  "foo": 3, "bar": "C"},
  {"key": "beta",  "foo": 4, "bar": "D"},
  {"key": "beta",  "foo": 5, "bar": null}
]

Upvotes: 2

Jose Jimenez
Jose Jimenez

Reputation: 240

You can use the compressed data, but you have to expand it first. The configuration information for vega-lite is just javascript so you can use a function like:

  expand_data = compressed => {
  const expanded = [];
  const keys = compressed.map( r => Object.keys(r)[0]);
  const keys_count = compressed.length; 
  const row_count = compressed[0][keys[0]].length;
  for (let i = 0; i< row_count; i++) {
    const new_row = {};
    for (let j = 0; j < keys_count; j++) {
      new_row[keys[j]] = compressed[j][keys[j]][i]
    }
    expanded.push(new_row);
  }
  return expanded;
}

to take the data from the compressed inline data to the version of the data vega-lite expects.

See a working example I created:

https://beta.observablehq.com/@jjimenez/using-different-data-formats-with-vega-lite

When they say "arrays of primitive objects are ingested as objects with a data property" I think they mean that the following code would work:

let apple = { label: 'apple', data: { size: 'small', weight: 12, color: 'red'} };
let orange = { label: 'orange', data: {size: 'small', weight: 13, color: 'orange'}};
let melon = {label: 'melon', data: {size: 'large', weight: 50, color: 'green' }};

... values: [apple, orange, melon]

apple, orange, and melon could also have other properties or functions attached.

I've added a primatives chart to the notebook.

Upvotes: 2

Related Questions