How Can I Apply Data Sources in Vega-Lite?
Using data in Vega-Lite is like using a powerful canvas where you can create delightful visualizations from different types of data sources. Whether you're drawing from a spreadsheet, a URL, or even generating your own data, Vega-Lite offers a range of options to make data visualization straightforward and fun.
Types of Data Sources
Inline Data
Inline data allows you to embed data directly into your visualization. It's super handy for small data sets or quick experiments.
Properties of inline data:
Property | Type | Description |
---|---|---|
values | Array | Required. The full data set, included inline. This can be an array of objects or primitive values, an object, or a string. Arrays of primitive values are ingested as objects with a data property. Strings are parsed according to the specified format type. |
name | String | Provide a placeholder name and bind data at runtime. |
format | DataFormat | An object that specifies the format for parsing the data. |
Example: Basic Inline Data
Here's how to create a bar chart using inline data with nine rows and two columns (a
and b
):
{
"data": {
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": 19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "nominal"},
"y": {"field": "b", "type": "quantitative"}
}
}
Example: Inline Data with Specified Format Type
In this example, we used inline CSV data with specified format type of "type": "csv"
{
"data": {
"values": "a,b\n1,4\n2,2\n3,1\n4,2",
"format": {
"type": "csv"
}
},
"mark": "point",
"encoding": {
"x": {"field": "a", "type": "quantitative"},
"y": {"field": "b", "type": "quantitative"}
}
}
Data from URL
Loading data from a URL is perfect when working with larger datasets stored online or in external servers.
Properties of data from URL:
Property | Type | Description |
---|---|---|
url | String | Required. An URL from which to load the data set. Use the format.type property to ensure the loaded data is correctly parsed. |
name | String | Provide a placeholder name and bind data at runtime. |
format | DataFormat | An object that specifies the format for parsing the data. |
Example: Data from URL
Here's how you can load data from a URL, in this case, data/cars.json
. note that the format type is impliciy "json"
by default.
{
"data": {"url": "data/cars.json"},
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"}
}
}
Named Data Sources
Named data sources can be defined and referenced by a specific name, which is useful when data needs to be updated dynamically.
Properties of named data sources:
Property | Type | Description |
---|---|---|
name | String | Required. Provide a placeholder name and bind data at runtime. New data may change the layout but Vega does not always resize the chart. To update the layout when the data updates, set autosize or explicitly use view.resize. |
format | DataFormat | An object that specifies the format for parsing the data. |
Here is an example to define a named data source myData
:
{
"data": {
"name": "myData"
}
}
Example: Update Data at Runtime
const spec = {
"data": {
"name": "myData",
"values": [
{"name": "B", "data": 55},
{"name": "C", "data": 43},
{"name": "D", "data": 91},
]
},
"mark": "bar",
"encoding": {
"x": {"field": "name", "type": "nominal"},
"y": {"field": "data", "type": "quantitative"}
}
};
vegaEmbed("#viz", spec).then(res =>
res.view
.insert("myData", [
{"name": "A", "data": 28},
{"name": "G", "data": 58},
{"name": "J", "data": 16},
])
.run()
);
DataFormat Object
Property | Type | Description |
---|---|---|
type | String | "json" | "csv" | "tsv" | "dsv" ; Default: "json" |
parse | Object | Null | If set to null, disable type inference based on the spec and only use type inference based on the data. Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of "number", "boolean", "date", or null (do not parse the field)). For example, "parse": {"modified_on": "date"} parses the modified_on field in each input record a Date value. For "date" , we parse data based using JavaScript's Date.parse() (opens in a new tab). For Specific date formats can be provided (e.g., {foo: "date:'%m%d%Y'"} ), using the d3-time-format syntax. UTC date format parsing is supported similarly (e.g., {foo: "utc:'%m%d%Y'"} ). See more about UTC time |
The DataFormat object tells Vega-Lite how to parse your data correctly. Here is some introduce to these formats:
JSON
Default format, read as row-oriented data.
Property | Type | Description |
---|---|---|
property | String | The JSON property containing the desired data. This parameter can be used when the loaded JSON file may have surrounding structure or meta-data. For example "property": "values.features" is equivalent to retrieving json.values.features from the loaded JSON object. |
Example:
{
"data": {
"url": "https://pub-2422ed4100b443659f588f2382cfc7b1.r2.dev/datasets/ds-cars-service.json",
"format": {
"type": "json",
"property": "dataSource"
}
},
"mark": "bar",
"encoding": {
"x": {"field": "name", "type": "nominal"},
"y": {"field": "data", "type": "quantitative"}
}
}
CSV
Load a comma-separated values (CSV) file. This format type does not support any additional properties.
TSV
Load a tab-separated values (TSV) file. This format type does not support any additional properties.
DSV
Load a delimited text file with a custom delimiter. This is a general version of CSV and TSV.
TopoJSON
Used for geographic data, converted to GeoJSON by Vega-Lite.
Use Case of parse
Property
This example used parse
property with value of {"b": "date"}
, it will parse the field b
with the JavaScript's Date.parse() (opens in a new tab).
{
"data": {
"values": [
{"a": "A", "b": "1970-1-1 00:01:10 GMT"},
{"a": "B", "b": "1970-1-1 00:20:00 GMT"},
{"a": "C", "b": "1970-1-1 00:08:30 GMT"},
],
"format": {
"parse": {
"b": "date"
}
}
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "nominal"},
"y": {"field": "b", "type": "quantitative"}
}
}
Data Generators
Sequence Generator
Generates numeric sequences.
Property | Type | Description |
---|---|---|
start | Number | Required. The starting value of the sequence (inclusive). |
stop | Number | Required. The ending value of the sequence (exclusive). |
step | Number | The step value between sequence entries; Default: 1 |
as | String | The name of the generated sequence field. Default: "data" |
This example creates a x sequence from 0 to 12.7 with a step of 0.1, it also uses a transform to calculate the sin(x)
for every x, then we get the sine wave in the range of 0 to 12.7.
{
"width": 300,
"height": 150,
"data": {
"sequence": {
"start": 0,
"stop": 12.7,
"step": 0.1,
"as": "x"
}
},
"transform": [
{
"calculate": "sin(datum.x)",
"as": "sin(x)"
}
],
"mark": "line",
"encoding": {
"x": {
"field": "x",
"type": "quantitative"
},
"y": {
"field": "sin(x)",
"type": "quantitative"
}
}
}
Graticule Generator
Creates a lattice of geographic coordinates. It can be specified with either a boolean true
value (indicating the default graticule) or a graticule property object:
Property | Type | Description |
---|---|---|
extent | Array | Sets both the major and minor extents to the same values. |
extentMajor | Array | The major extent of the graticule as a two-element array of coordinates. |
extentMinor | Array | The minor extent of the graticule as a two-element array of coordinates. |
precision | Number | The precision of the graticule in degrees; Default: 2.5 |
step | Array | Sets both the major and minor step angles to the same values. |
stepMajor | Array | The major step angles of the graticule; Default: [90, 360] |
stepMinor | Array | The minor step angles of the graticule; Default: [10, 10] |
Default Graticule Example:
{
"data": {
"graticule": true
},
"projection": {
"type": "orthographic"
},
"mark": {
"type": "geoshape"
}
}
Graticule Example with Rotation and Steps:
{
"data": {
"graticule": true,
"step": [ 15, 15 ]
},
"projection": {
"type": "orthographic",
"rotate": [ 0, -45, 0 ]
},
"mark": {
"type": "geoshape"
}
}
Sphere Generator
The sphere can be used as a background layer within a map to represent the extent of the Earth. It requires either a boolean true value or an empty object {}
as its sole property.
Example:
{
"data": {
"sphere": true
}
}
In this example, we created two layers, one is the sphere with yellow filled as the background, the other one is the [graticule] like the default graticule example.
Standalone Datasets
Vega-Lite supports top-level datasets
property, which is useful when the same data should be inlined in different places in the spec.
{
"datasets": {
"somedata": [
{"name": "A", "count": 28, "datetime": "1970-1-1 00:00:30 GMT"},
{"name": "B", "count": 55, "datetime": "1970-1-1 00:01:00 GMT"},
{"name": "C", "count": 43, "datetime": "1970-1-1 00:01:10 GMT"},
{"name": "D", "count": 91, "datetime": "1970-1-1 00:01:15 GMT"},
{"name": "E", "count": 81, "datetime": "1970-1-1 00:02:10 GMT"},
{"name": "F", "count": 53, "datetime": "1970-1-1 00:00:10 GMT"},
{"name": "G", "count": 19, "datetime": "1970-1-1 00:02:00 GMT"},
{"name": "H", "count": 87, "datetime": "1970-1-1 00:01:50 GMT"},
{"name": "I", "count": 52, "datetime": "1970-1-1 00:01:40 GMT"}
]
},
"hconcat": [
{
"data": {
"name": "somedata"
},
"mark": "bar",
"encoding": {
"x": {"field": "name", "type": "nominal"},
"y": {"field": "count", "type": "quantitative"}
}
},
{
"data": {
"name": "somedata",
"format": {
"parse": {
"datetime": "date"
}
}
},
"mark": "line",
"encoding": {
"x": {"field": "name", "type": "nominal"},
"y": {"field": "datetime", "type": "quantitative"}
}
}
]
}
FAQs
1. How to update the data dynamically?
As the Named Data Sources part, you can define a data source with a name
and use the Vega View API to update or modify it dynamically just like codes below:
const spec = {
data: {
"name": "myData",
"values": [
{"name": "A", "data": 55},
]
},
"mark": "bar",
"encoding": {
"x": {"field": "name", "type": "nominal"},
"y": {"field": "data", "type": "quantitative"}
}
};
vegaEmbed("#viz", spec).then(res => {
const loadedData = // do something to load data
res.view
.insert("myData", loadedData)
.run()
});
In this example, some of the chart data is loaded and rendered after the initial rendering.