Mosaic Declarative Specifications
The mosaic-spec package enables declarative specification of Mosaic applications as JSON or YAML files. The package provides a specification parser, as well as generators to create either running applications or JavaScript code.
For example, below is an example of a declarative specification, in either YAML or equivalent JSON, for a simple line chart. The JavaScript and Python tabs show equivalent code that builds the same specification using the vgplot API in each language.
data:
aapl: { file: data/stocks.parquet, where: Symbol = 'AAPL' }
plot:
- mark: lineY
data: { from: aapl }
x: Date
y: Close
width: 680
height: 200{
"data": {
"aapl": {
"file": "data/stocks.parquet",
"where": "Symbol = 'AAPL'"
}
},
"plot": [
{
"mark": "lineY",
"data": {
"from": "aapl"
},
"x": "Date",
"y": "Close"
}
],
"width": 680,
"height": 200
}import * as vg from "@uwdata/vgplot";
await vg.coordinator().exec([
vg.loadParquet("aapl", "data/stocks.parquet", {where: "Symbol = 'AAPL'"})
]);
export default vg.plot(
vg.lineY(
vg.from("aapl"),
{x: "Date", y: "Close"}
),
vg.width(680),
vg.height(200)
);import vgplot as vg
aapl = vg.parquet("data/stocks.parquet", where="Symbol = 'AAPL'")
view = vg.plot(
vg.line_y(aapl, x="Date", y="Close"),
vg.width(680),
vg.height(200),
)Using a declarative specification, we can describe an application in a standard file format, enabling portability across platforms. The same spec can be authored as YAML/JSON or built programmatically with the vgplot API in either JavaScript or Python (see the Python API). For example, the Mosaic Jupyter widget uses this format to pass visualization and dashboard definitions from Python to the browser.
TIP
The TypeScript types in the @uwdata/mosaic-spec package provide comprehensive documentation of Mosaic declarative specifications.
Specification Format
Here is a slightly more complicated example, in which a dynamic Param value is added to the data before visualizing it.
meta:
title: Bias Parameter
description: >
Dynamically adjust queried values by adding a Param value.
The SQL expression is re-computed in the database upon updates.
data:
walk: { file: data/random-walk.parquet }
params:
point: 0
vconcat:
- input: slider
label: Bias
as: $point
min: 0
max: 1000
step: 1
- plot:
- mark: areaY
data: { from: walk }
x: t
y: { sql: v + $point }
fill: steelblue
width: 680
height: 200{
"meta": {
"title": "Bias Parameter",
"description": "Dynamically adjust queried values by adding a Param value. The SQL expression is re-computed in the database upon updates.\n"
},
"data": {
"walk": {
"file": "data/random-walk.parquet"
}
},
"params": {
"point": 0
},
"vconcat": [
{
"input": "slider",
"label": "Bias",
"as": "$point",
"min": 0,
"max": 1000,
"step": 1
},
{
"plot": [
{
"mark": "areaY",
"data": {
"from": "walk"
},
"x": "t",
"y": {
"sql": "v + $point"
},
"fill": "steelblue"
}
],
"width": 680,
"height": 200
}
]
}import * as vg from "@uwdata/vgplot";
await vg.coordinator().exec([
vg.loadParquet("walk", "data/random-walk.parquet")
]);
const $point = vg.Param.value(0);
export default vg.vconcat(
vg.slider({label: "Bias", as: $point, min: 0, max: 1000, step: 1}),
vg.plot(
vg.areaY(
vg.from("walk"),
{x: "t", y: vg.sql`v + ${$point}`, fill: "steelblue"}
),
vg.width(680),
vg.height(200)
)
);import vgplot as vg
walk = vg.parquet("data/random-walk.parquet")
point = vg.param(0)
view = vg.vconcat(
vg.slider(label="Bias", bind=point, min=0, max=1000, step=1),
vg.plot(
vg.area_y(walk, x="t", y=vg.sql("v + $point"), fill="steelblue"),
vg.width(680),
vg.height(200),
),
)The example above includes descriptive metadata, data and params definitions, and nested components: an input slider and plot are positioned using a vconcat layout. The plot uses a SQL expression that includes a Param reference ($point) to define a dynamic y encoding channel.
A declarative specification may include top-level definitions for:
meta: Metadata such as a title and description.config: Configuration settings, such as database extensions to load.data: Dataset definitions, such as files, queries, or inline data.params: Param & Selection definitions. All later Param references use a$prefix.plotDefaults: Default plot attributes to apply to all plot instances.
The rest of the spec consists of component definitions supported by the vgplot API, including plots, inputs, and layout components.
For more, see the Specification Format Reference.
Parser & Generators Format
The parseSpec() method parses a specification in JSON format into an abstract syntax tree (AST): a structured representation of the specification content that is more convenient to analyze and manipulate.
Given a parsed AST, the generator method astToDOM() instantiates a running web application, returning Mosaic-backed Document Object Model (DOM) elements that can be added to a web page.
Meanwhile, the astToESM() method instead generates JavaScript code, in the form of an ECMAScript Module (ESM), that uses the vgplot API. The JavaScript code listed in the examples above was generated using this method, and astToPython() similarly generates equivalent Python code for the vgplot Python API.
For more, see the Specification Parser & Generators Reference.