Here's an example of a chart created using Vega:
You can create this chart by running this Vega specification:
Let's break this step by step. First, we define the width and height of the visualisation in pixels. By default, Vega uses a 500px x 500px rectangle. This code sets it to 600px x 400px. We also set the padding to 0. This prevents Vega from adding extra space on the side for labels. We don't need these for maps. See visualisation properties
"width": 600, // Width of the visual in pixels "height": 400, // Height of the visual in pixels "padding": 0, // Padding of the visual in pixels
We then load the data. Vega supports different data formats such as JSON, CSV, etc. For maps, we use TopoJSON. Here, we've used the sample World map provided along with TopoJSON. A TopoJSON file can contain multiple "features". This particular map has a feature called "countries" that we want. All of this is stored in the dataset named "world" — a reference we will be using later.
"data": [{ "name": "world", // Name of the dataset "url": "data/world-110m.json", // Location to load from "format": { "type": "topojson", // Dataset is parsed as TopoJSON "feature": "countries" // "countries" feature is extracted
The TopoJSON file has a hierarchical structure representing the boundaries and regions of each country. These need to be converted into positions for a path. These are done through transformations. There are two kinds of transforms: data transforms (which modify the data, like grouping, filtering, etc.) and visual transforms (which create data for drawing visuals, like treemap rectangle positions, map paths, etc.)
In this case, we use the geopath visual transform that converts TopoJSON into paths. This is fairly representative of how Vega works. There are a set of data formats. We use a series of transforms to convert them into other formats before drawing them.
"transform": [{ // The "world" dataset is transformed "type": "geopath" // using "geopath", which converts a }] // topojson feature into paths
The "marks" section defines how each data element we have is drawn. After the geopath transform, the "world" dataset has an array of paths data. These are drawn using the "path" type which creates renders the path and stores it in a field called layout_path
.
"marks": [ // The marks / visuals to be drawn here { "type": "path", // is a path that "from": {"data": "world"}, // takes data from the "world" dataset
The properties of the path can be adjusted at 3 different points: when it is created ("enter"
), when it is redrawn ("update"
) and when it is removed ("exit"
). Here, when the path is created, its path, fill and stroke attributes are set.
"properties": { // Set these properties for paths "enter": { // when they are created. "path": {"field": "layout_path"}, // Path based on layout_field "fill": {"value": "steelblue"}, // Shapes filled in blue "stroke": {"value": "#fff"} // with a white border.
This was a minimal example that shows how to create a map. Using these concepts, try the following: