@uwdata/mosaic-spec 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mosaic-schema.json +192673 -0
- package/dist/mosaic-spec.js +5077 -5774
- package/dist/mosaic-spec.min.js +23 -23
- package/dist/types/ast/ASTNode.d.ts +26 -0
- package/dist/types/ast/DataNode.d.ts +60 -0
- package/dist/types/ast/ExpressionNode.d.ts +15 -0
- package/dist/types/ast/HConcatNode.d.ts +10 -0
- package/dist/types/ast/HSpaceNode.d.ts +11 -0
- package/dist/types/ast/InputNode.d.ts +8 -0
- package/dist/types/ast/LiteralNode.d.ts +7 -0
- package/dist/types/ast/OptionsNode.d.ts +10 -0
- package/dist/types/ast/ParamNode.d.ts +9 -0
- package/dist/types/ast/ParamRefNode.d.ts +8 -0
- package/dist/types/ast/PlotAttributeNode.d.ts +18 -0
- package/dist/types/ast/PlotFromNode.d.ts +9 -0
- package/dist/types/ast/PlotInteractorNode.d.ts +8 -0
- package/dist/types/ast/PlotLegendNode.d.ts +10 -0
- package/dist/types/ast/PlotMarkNode.d.ts +10 -0
- package/dist/types/ast/PlotNode.d.ts +11 -0
- package/dist/types/ast/SelectionNode.d.ts +12 -0
- package/dist/types/ast/SpecNode.d.ts +10 -0
- package/dist/types/ast/TransformNode.d.ts +13 -0
- package/dist/types/ast/VConcatNode.d.ts +10 -0
- package/dist/types/ast/VSpaceNode.d.ts +11 -0
- package/dist/types/ast-to-dom.d.ts +38 -0
- package/dist/types/ast-to-esm.d.ts +64 -0
- package/dist/types/config/components.d.ts +4 -0
- package/dist/types/config/extensions.d.ts +9 -0
- package/dist/types/config/inputs.d.ts +5 -0
- package/dist/types/config/plots.d.ts +34 -0
- package/dist/types/config/transforms.d.ts +4 -0
- package/dist/types/constants.d.ts +30 -0
- package/dist/types/index.d.ts +29 -0
- package/dist/types/parse-spec.d.ts +86 -0
- package/dist/types/spec/CSSStyles.d.ts +3 -0
- package/dist/types/spec/Data.d.ts +165 -0
- package/dist/types/spec/Expression.d.ts +27 -0
- package/dist/types/spec/HConcat.d.ts +8 -0
- package/dist/types/spec/HSpace.d.ts +9 -0
- package/dist/types/spec/Input.d.ts +207 -0
- package/dist/types/spec/Param.d.ts +51 -0
- package/dist/types/spec/Plot.d.ts +14 -0
- package/dist/types/spec/PlotAttribute.d.ts +1522 -0
- package/dist/types/spec/PlotFrom.d.ts +20 -0
- package/dist/types/spec/PlotInteractor.d.ts +8 -0
- package/dist/types/spec/PlotLegend.d.ts +68 -0
- package/dist/types/spec/PlotMark.d.ts +27 -0
- package/dist/types/spec/PlotTypes.d.ts +293 -0
- package/dist/types/spec/Spec.d.ts +52 -0
- package/dist/types/spec/Transform.d.ts +314 -0
- package/dist/types/spec/VConcat.d.ts +8 -0
- package/dist/types/spec/VSpace.d.ts +9 -0
- package/dist/types/spec/interactors/Highlight.d.ts +37 -0
- package/dist/types/spec/interactors/Interval1D.d.ts +63 -0
- package/dist/types/spec/interactors/Interval2D.d.ts +46 -0
- package/dist/types/spec/interactors/Nearest.d.ts +44 -0
- package/dist/types/spec/interactors/PanZoom.d.ts +58 -0
- package/dist/types/spec/interactors/Toggle.d.ts +59 -0
- package/dist/types/spec/marks/Area.d.ts +139 -0
- package/dist/types/spec/marks/Arrow.d.ts +94 -0
- package/dist/types/spec/marks/Axis.d.ts +281 -0
- package/dist/types/spec/marks/Bar.d.ts +150 -0
- package/dist/types/spec/marks/Cell.d.ts +57 -0
- package/dist/types/spec/marks/Contour.d.ts +23 -0
- package/dist/types/spec/marks/Delaunay.d.ts +86 -0
- package/dist/types/spec/marks/DenseLine.d.ts +27 -0
- package/dist/types/spec/marks/Density.d.ts +121 -0
- package/dist/types/spec/marks/Dot.d.ts +133 -0
- package/dist/types/spec/marks/ErrorBar.d.ts +82 -0
- package/dist/types/spec/marks/Frame.d.ts +21 -0
- package/dist/types/spec/marks/Geo.d.ts +53 -0
- package/dist/types/spec/marks/Hexbin.d.ts +30 -0
- package/dist/types/spec/marks/Hexgrid.d.ts +25 -0
- package/dist/types/spec/marks/Image.d.ts +89 -0
- package/dist/types/spec/marks/Line.d.ts +82 -0
- package/dist/types/spec/marks/Link.d.ts +60 -0
- package/dist/types/spec/marks/Marks.d.ts +905 -0
- package/dist/types/spec/marks/Raster.d.ts +124 -0
- package/dist/types/spec/marks/Rect.d.ts +166 -0
- package/dist/types/spec/marks/Regression.d.ts +58 -0
- package/dist/types/spec/marks/Rule.d.ts +100 -0
- package/dist/types/spec/marks/Text.d.ts +110 -0
- package/dist/types/spec/marks/Tick.d.ts +61 -0
- package/dist/types/spec/marks/Vector.d.ts +99 -0
- package/dist/types/util.d.ts +12 -0
- package/jsconfig.json +10 -0
- package/package.json +14 -9
- package/src/ast/ASTNode.js +23 -2
- package/src/ast/DataNode.js +79 -21
- package/src/ast/HSpaceNode.js +1 -1
- package/src/ast/InputNode.js +1 -2
- package/src/ast/ParamNode.js +1 -2
- package/src/ast/PlotAttributeNode.js +1 -2
- package/src/ast/PlotInteractorNode.js +1 -2
- package/src/ast/PlotLegendNode.js +1 -2
- package/src/ast/PlotMarkNode.js +3 -2
- package/src/ast/TransformNode.js +1 -2
- package/src/ast/VSpaceNode.js +1 -1
- package/src/ast-to-dom.js +9 -3
- package/src/ast-to-esm.js +41 -12
- package/src/config/inputs.js +1 -0
- package/src/config/plots.js +4 -0
- package/src/config/transforms.js +6 -0
- package/src/index.js +4 -0
- package/src/parse-spec.js +38 -5
- package/src/spec/CSSStyles.ts +9 -0
- package/src/spec/Data.ts +184 -0
- package/src/spec/Expression.ts +31 -0
- package/src/spec/HConcat.ts +9 -0
- package/src/spec/HSpace.ts +9 -0
- package/src/spec/Input.ts +204 -0
- package/src/spec/Param.ts +68 -0
- package/src/spec/Plot.ts +15 -0
- package/src/spec/PlotAttribute.ts +1783 -0
- package/src/spec/PlotFrom.ts +23 -0
- package/src/spec/PlotInteractor.ts +25 -0
- package/src/spec/PlotLegend.ts +70 -0
- package/src/spec/PlotMark.ts +53 -0
- package/src/spec/PlotTypes.ts +519 -0
- package/src/spec/Spec.ts +70 -0
- package/src/spec/Transform.ts +446 -0
- package/src/spec/VConcat.ts +9 -0
- package/src/spec/VSpace.ts +9 -0
- package/src/spec/interactors/Highlight.ts +38 -0
- package/src/spec/interactors/Interval1D.ts +67 -0
- package/src/spec/interactors/Interval2D.ts +48 -0
- package/src/spec/interactors/Nearest.ts +48 -0
- package/src/spec/interactors/PanZoom.ts +65 -0
- package/src/spec/interactors/Toggle.ts +65 -0
- package/src/spec/marks/Area.ts +154 -0
- package/src/spec/marks/Arrow.ts +108 -0
- package/src/spec/marks/Axis.ts +305 -0
- package/src/spec/marks/Bar.ts +160 -0
- package/src/spec/marks/Cell.ts +62 -0
- package/src/spec/marks/Contour.ts +25 -0
- package/src/spec/marks/Delaunay.ts +95 -0
- package/src/spec/marks/DenseLine.ts +30 -0
- package/src/spec/marks/Density.ts +145 -0
- package/src/spec/marks/Dot.ts +152 -0
- package/src/spec/marks/ErrorBar.ts +91 -0
- package/src/spec/marks/Frame.ts +23 -0
- package/src/spec/marks/Geo.ts +58 -0
- package/src/spec/marks/Hexbin.ts +34 -0
- package/src/spec/marks/Hexgrid.ts +27 -0
- package/src/spec/marks/Image.ts +101 -0
- package/src/spec/marks/Line.ts +93 -0
- package/src/spec/marks/Link.ts +70 -0
- package/src/spec/marks/Marks.ts +1088 -0
- package/src/spec/marks/Raster.ts +145 -0
- package/src/spec/marks/Rect.ts +183 -0
- package/src/spec/marks/Regression.ts +63 -0
- package/src/spec/marks/Rule.ts +113 -0
- package/src/spec/marks/Text.ts +127 -0
- package/src/spec/marks/Tick.ts +69 -0
- package/src/spec/marks/Vector.ts +113 -0
- package/src/util.js +8 -0
- package/tsconfig.json +11 -0
- package/LICENSE +0 -47
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ParamRef } from '../Param.js';
|
|
2
|
+
import { FrameAnchor } from '../PlotTypes.js';
|
|
3
|
+
import { ChannelValue, ChannelValueSpec, MarkData, MarkOptions } from './Marks.js';
|
|
4
|
+
/**
|
|
5
|
+
* The built-in vector shape implementations; one of:
|
|
6
|
+
*
|
|
7
|
+
* - *arrow* - a straight line with an open arrowhead at the end (↑)
|
|
8
|
+
* - *spike* - an isosceles triangle with a flat base (▲)
|
|
9
|
+
*/
|
|
10
|
+
export type VectorShapeName = 'arrow' | 'spike';
|
|
11
|
+
/** How to draw a vector: either a named shape or a custom implementation. */
|
|
12
|
+
export type VectorShape = VectorShapeName;
|
|
13
|
+
/** Options for the vector mark. */
|
|
14
|
+
export interface VectorOptions extends MarkOptions {
|
|
15
|
+
/**
|
|
16
|
+
* The horizontal position of the vector’s anchor point; an optional channel
|
|
17
|
+
* bound to the *x* scale. Default depends on the **frameAnchor**.
|
|
18
|
+
*/
|
|
19
|
+
x?: ChannelValueSpec;
|
|
20
|
+
/**
|
|
21
|
+
* The vertical position of the vector’s anchor point; an optional channel
|
|
22
|
+
* bound to the *y* scale. Default depends on the **frameAnchor**.
|
|
23
|
+
*/
|
|
24
|
+
y?: ChannelValueSpec;
|
|
25
|
+
/**
|
|
26
|
+
* The vector shape’s radius, such as half the width of the *arrow*’s head or
|
|
27
|
+
* the *spike*’s base; a constant number in pixels. Defaults to 3.5 pixels.
|
|
28
|
+
*/
|
|
29
|
+
r?: number | ParamRef;
|
|
30
|
+
/**
|
|
31
|
+
* The vector’s length; either an optional channel bound to the *length* scale
|
|
32
|
+
* or a constant number in pixels. Defaults to 12 pixels.
|
|
33
|
+
*/
|
|
34
|
+
length?: ChannelValueSpec;
|
|
35
|
+
/**
|
|
36
|
+
* The vector’s orientation (rotation angle); either a constant number in
|
|
37
|
+
* degrees clockwise, or an optional channel (with no associated scale).
|
|
38
|
+
* Defaults to 0 degrees with the vector pointing up.
|
|
39
|
+
*/
|
|
40
|
+
rotate?: ChannelValue;
|
|
41
|
+
/** The shape of the vector; a constant. Defaults to *arrow*. */
|
|
42
|
+
shape?: VectorShape | ParamRef;
|
|
43
|
+
/**
|
|
44
|
+
* The vector’s position along its orientation relative to its anchor point; a
|
|
45
|
+
* constant. Assuming a default **rotate** angle of 0°, one of:
|
|
46
|
+
*
|
|
47
|
+
* - *start* - from [*x*, *y*] to [*x*, *y* - *l*]
|
|
48
|
+
* - *middle* (default) - from [*x*, *y* + *l* / 2] to [*x*, *y* - *l* / 2]
|
|
49
|
+
* - *end* - from [*x*, *y* + *l*] to [*x*, *y*]
|
|
50
|
+
*
|
|
51
|
+
* where [*x*, *y*] is the vector’s anchor point and *l* is the vector’s
|
|
52
|
+
* (possibly scaled) length in pixels.
|
|
53
|
+
*/
|
|
54
|
+
anchor?: 'start' | 'middle' | 'end' | ParamRef;
|
|
55
|
+
/**
|
|
56
|
+
* The vector’s frame anchor, to default **x** and **y** relative to the
|
|
57
|
+
* frame; a constant representing one of the frame corners (*top-left*,
|
|
58
|
+
* *top-right*, *bottom-right*, *bottom-left*), sides (*top*, *right*,
|
|
59
|
+
* *bottom*, *left*), or *middle* (default). Has no effect if both **x**
|
|
60
|
+
* and **y** are specified.
|
|
61
|
+
*/
|
|
62
|
+
frameAnchor?: FrameAnchor | ParamRef;
|
|
63
|
+
}
|
|
64
|
+
/** The vector mark. */
|
|
65
|
+
export interface Vector extends MarkData, VectorOptions {
|
|
66
|
+
/**
|
|
67
|
+
* A vector mark.
|
|
68
|
+
*
|
|
69
|
+
* If none of **frameAnchor**, **x**, and **y** are specified, then **x** and
|
|
70
|
+
* **y** default to accessors assuming that *data* contains tuples [[*x₀*,
|
|
71
|
+
* *y₀*], [*x₁*, *y₁*], [*x₂*, *y₂*], …]
|
|
72
|
+
*/
|
|
73
|
+
mark: 'vector';
|
|
74
|
+
}
|
|
75
|
+
/** The vectorX mark. */
|
|
76
|
+
export interface VectorX extends MarkData, VectorOptions {
|
|
77
|
+
/**
|
|
78
|
+
* Like vector, but **x** instead defaults to the identity function and **y**
|
|
79
|
+
* defaults to null, assuming that *data* is an array of numbers [*x₀*, *x₁*,
|
|
80
|
+
* *x₂*, …].
|
|
81
|
+
*/
|
|
82
|
+
mark: 'vectorX';
|
|
83
|
+
}
|
|
84
|
+
/** The vectorY mark. */
|
|
85
|
+
export interface VectorY extends MarkData, VectorOptions {
|
|
86
|
+
/**
|
|
87
|
+
* Like vector, but **y** instead defaults to the identity function and **x**
|
|
88
|
+
* defaults to null, assuming that *data* is an array of numbers [*y₀*, *y₁*,
|
|
89
|
+
* *y₂*, …].
|
|
90
|
+
*/
|
|
91
|
+
mark: 'vectorY';
|
|
92
|
+
}
|
|
93
|
+
/** The spike mark. */
|
|
94
|
+
export interface Spike extends MarkData, VectorOptions {
|
|
95
|
+
/**
|
|
96
|
+
* Like vector, but with default *options* suitable for drawing a spike map.
|
|
97
|
+
*/
|
|
98
|
+
mark: 'spike';
|
|
99
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function paramRef(value: any): any;
|
|
2
|
+
export function paramStr(value: any): any;
|
|
3
|
+
export function toParamRef(name: any): string;
|
|
4
|
+
export function toArray(value: any): any[];
|
|
5
|
+
export function isArray(value: any): boolean;
|
|
6
|
+
export function isObject(value: any): boolean;
|
|
7
|
+
export function isNumber(value: any): boolean;
|
|
8
|
+
export function isNumberOrString(value: any): boolean;
|
|
9
|
+
export function isString(value: any): boolean;
|
|
10
|
+
export function isFunction(value: any): boolean;
|
|
11
|
+
export function error(message: any, data: any): void;
|
|
12
|
+
export function isoparse(string: any, fallback: any): any;
|
package/jsconfig.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwdata/mosaic-spec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Declarative specification of Mosaic-powered applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mosaic",
|
|
@@ -16,22 +16,27 @@
|
|
|
16
16
|
"module": "src/index.js",
|
|
17
17
|
"jsdelivr": "dist/mosaic-spec.min.js",
|
|
18
18
|
"unpkg": "dist/mosaic-spec.min.js",
|
|
19
|
+
"types": "dist/types/index.d.ts",
|
|
19
20
|
"repository": {
|
|
20
21
|
"type": "git",
|
|
21
22
|
"url": "https://github.com/uwdata/mosaic.git"
|
|
22
23
|
},
|
|
23
24
|
"scripts": {
|
|
24
25
|
"prebuild": "rimraf dist && mkdir dist",
|
|
25
|
-
"build": "node ../../esbuild.js mosaic-spec",
|
|
26
|
-
"lint": "eslint src test
|
|
27
|
-
"
|
|
26
|
+
"build": "npm run types && node ../../esbuild.js mosaic-spec",
|
|
27
|
+
"lint": "eslint src test",
|
|
28
|
+
"types": "tsc -p tsconfig.json && npm run schema",
|
|
29
|
+
"schema": "ts-json-schema-generator -f tsconfig.json -p src/spec/Spec.ts -t Spec --no-type-check --no-ref-encode --functions hide > dist/mosaic-schema.json",
|
|
30
|
+
"pretest": "npm run prebuild && npm run types",
|
|
31
|
+
"test": "mocha 'test/**/*-test.js' && tsc -p jsconfig.json",
|
|
32
|
+
"version": "cd ../.. && npm run docs:schema",
|
|
28
33
|
"prepublishOnly": "npm run test && npm run lint && npm run build"
|
|
29
34
|
},
|
|
30
35
|
"dependencies": {
|
|
31
|
-
"@uwdata/mosaic-core": "^0.
|
|
32
|
-
"@uwdata/mosaic-sql": "^0.
|
|
33
|
-
"@uwdata/vgplot": "^0.
|
|
34
|
-
"
|
|
36
|
+
"@uwdata/mosaic-core": "^0.9.0",
|
|
37
|
+
"@uwdata/mosaic-sql": "^0.9.0",
|
|
38
|
+
"@uwdata/vgplot": "^0.9.0",
|
|
39
|
+
"ts-json-schema-generator": "^2.2.0"
|
|
35
40
|
},
|
|
36
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "89bb9b0dfa747aed691eaeba35379525a6764c61"
|
|
37
42
|
}
|
package/src/ast/ASTNode.js
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for Mosaic spec AST nodes.
|
|
3
|
+
*/
|
|
1
4
|
export class ASTNode {
|
|
2
5
|
constructor(type, children = null) {
|
|
6
|
+
/** @type {string} */
|
|
3
7
|
this.type = type;
|
|
8
|
+
/** @type {ASTNode[] | null} */
|
|
4
9
|
this.children = children;
|
|
5
10
|
}
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Instantiate this AST node to use in a live web application.
|
|
14
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
15
|
+
* @returns {*} The instantiated value of this node.
|
|
16
|
+
*/
|
|
17
|
+
instantiate(ctx) { // eslint-disable-line no-unused-vars
|
|
18
|
+
// @ts-ignore
|
|
8
19
|
throw Error('instantiate not implemented');
|
|
9
20
|
}
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Generate ESM code for this AST node.
|
|
24
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
25
|
+
* @returns {string|void} The generated ESM code for the node.
|
|
26
|
+
*/
|
|
27
|
+
codegen(ctx) { // eslint-disable-line no-unused-vars
|
|
28
|
+
// @ts-ignore
|
|
12
29
|
return Error('codegen not implemented');
|
|
13
30
|
}
|
|
14
31
|
|
|
32
|
+
/**
|
|
33
|
+
* @returns {*} This AST node in JSON specification format.
|
|
34
|
+
*/
|
|
15
35
|
toJSON() {
|
|
36
|
+
// @ts-ignore
|
|
16
37
|
return Error('toJSON not implemented');
|
|
17
38
|
}
|
|
18
39
|
}
|
package/src/ast/DataNode.js
CHANGED
|
@@ -10,6 +10,7 @@ export const CSV_DATA = 'csv';
|
|
|
10
10
|
export const JSON_DATA = 'json';
|
|
11
11
|
export const SPATIAL_DATA = 'spatial';
|
|
12
12
|
|
|
13
|
+
// @ts-ignore
|
|
13
14
|
const dataFormats = new Map([
|
|
14
15
|
[TABLE_DATA, parseTableData],
|
|
15
16
|
[PARQUET_DATA, parseParquetData],
|
|
@@ -18,16 +19,40 @@ const dataFormats = new Map([
|
|
|
18
19
|
[SPATIAL_DATA, parseSpatialData]
|
|
19
20
|
]);
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Parse a data definition spec.
|
|
24
|
+
* @param {string} name The name of the dataset
|
|
25
|
+
* @param {import('../spec/Data.js').DataDefinition} spec The data definition spec.
|
|
26
|
+
* @param {import('../parse-spec.js').ParseContext} ctx The parser context.
|
|
27
|
+
* @returns {DataNode} a parsed data definition AST node
|
|
28
|
+
*/
|
|
21
29
|
export function parseData(name, spec, ctx) {
|
|
22
|
-
|
|
23
|
-
if (dataFormats.has(
|
|
24
|
-
const parse = dataFormats.get(
|
|
25
|
-
return parse(name,
|
|
30
|
+
const def = resolveDataSpec(spec);
|
|
31
|
+
if (dataFormats.has(def.type)) {
|
|
32
|
+
const parse = dataFormats.get(def.type);
|
|
33
|
+
return parse(name, def, ctx);
|
|
26
34
|
} else {
|
|
27
35
|
ctx.error(`Unrecognized data format type.`, spec);
|
|
28
36
|
}
|
|
29
37
|
}
|
|
30
38
|
|
|
39
|
+
function resolveDataSpec(spec) {
|
|
40
|
+
if (isArray(spec)) spec = { type: 'json', data: spec };
|
|
41
|
+
if (isString(spec)) spec = { type: 'table', query: spec };
|
|
42
|
+
return { ...spec, type: inferType(spec) };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function inferType(spec) {
|
|
46
|
+
return spec.type
|
|
47
|
+
|| fileExtension(spec.file)
|
|
48
|
+
|| 'table';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function fileExtension(file) {
|
|
52
|
+
const idx = file?.lastIndexOf('.');
|
|
53
|
+
return idx > 0 ? file.slice(idx + 1) : null;
|
|
54
|
+
}
|
|
55
|
+
|
|
31
56
|
function parseTableData(name, spec, ctx) {
|
|
32
57
|
// eslint-disable-next-line no-unused-vars
|
|
33
58
|
const { query, type, ...options } = spec;
|
|
@@ -61,23 +86,6 @@ function parseSpatialData(name, spec, ctx) {
|
|
|
61
86
|
return new SpatialDataNode(name, file, parseOptions(options, ctx));
|
|
62
87
|
}
|
|
63
88
|
|
|
64
|
-
function resolveDataSpec(spec) {
|
|
65
|
-
if (isArray(spec)) spec = { type: 'json', data: spec };
|
|
66
|
-
if (isString(spec)) spec = { type: 'table', query: spec };
|
|
67
|
-
return { ...spec, type: inferType(spec) };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function inferType(spec) {
|
|
71
|
-
return spec.type
|
|
72
|
-
|| fileExtension(spec.file)
|
|
73
|
-
|| 'table';
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function fileExtension(file) {
|
|
77
|
-
const idx = file?.lastIndexOf('.');
|
|
78
|
-
return idx > 0 ? file.slice(idx + 1) : null;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
89
|
function resolveFileURL(file, baseURL) {
|
|
82
90
|
return baseURL ? new URL(file, baseURL).toString() : file;
|
|
83
91
|
}
|
|
@@ -100,19 +108,39 @@ export class QueryDataNode extends DataNode {
|
|
|
100
108
|
super(name, format);
|
|
101
109
|
}
|
|
102
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Instantiate a table creation query.
|
|
113
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
114
|
+
* @returns {string|void} The instantiated query.
|
|
115
|
+
*/
|
|
103
116
|
instantiateQuery(ctx) {
|
|
104
117
|
ctx.error('instantiateQuery not implemented');
|
|
105
118
|
}
|
|
106
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Code generate a table creation query.
|
|
122
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
123
|
+
* @returns {string|void} The generated query code.
|
|
124
|
+
*/
|
|
107
125
|
codegenQuery(ctx) {
|
|
108
126
|
ctx.error('codegenQuery not implemented');
|
|
109
127
|
}
|
|
110
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Instantiate this AST node to use in a live web application.
|
|
131
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
132
|
+
* @returns {*} The instantiated value of this node.
|
|
133
|
+
*/
|
|
111
134
|
instantiate(ctx) {
|
|
112
135
|
const query = this.instantiateQuery(ctx);
|
|
113
136
|
if (query) return query;
|
|
114
137
|
}
|
|
115
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Generate ESM code for this AST node.
|
|
141
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
142
|
+
* @returns {string|void} The generated ESM code for the node.
|
|
143
|
+
*/
|
|
116
144
|
codegen(ctx) {
|
|
117
145
|
const query = this.codegenQuery(ctx);
|
|
118
146
|
if (query) return query;
|
|
@@ -126,6 +154,11 @@ export class TableDataNode extends QueryDataNode {
|
|
|
126
154
|
this.options = options;
|
|
127
155
|
}
|
|
128
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Instantiate a table creation query.
|
|
159
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
160
|
+
* @returns {string|void} The instantiated query.
|
|
161
|
+
*/
|
|
129
162
|
instantiateQuery(ctx) {
|
|
130
163
|
const { name, query, options } = this;
|
|
131
164
|
if (query) {
|
|
@@ -133,6 +166,11 @@ export class TableDataNode extends QueryDataNode {
|
|
|
133
166
|
}
|
|
134
167
|
}
|
|
135
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Code generate a table creation query.
|
|
171
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
172
|
+
* @returns {string|void} The generated query code.
|
|
173
|
+
*/
|
|
136
174
|
codegenQuery(ctx) {
|
|
137
175
|
const { name, query, options } = this;
|
|
138
176
|
if (query) {
|
|
@@ -154,6 +192,11 @@ export class FileDataNode extends QueryDataNode {
|
|
|
154
192
|
this.options = options;
|
|
155
193
|
}
|
|
156
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Instantiate a table creation query.
|
|
197
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
198
|
+
* @returns {string|void} The instantiated query.
|
|
199
|
+
*/
|
|
157
200
|
instantiateQuery(ctx) {
|
|
158
201
|
const { name, method, file, options } = this;
|
|
159
202
|
const url = resolveFileURL(file, ctx.baseURL);
|
|
@@ -161,6 +204,11 @@ export class FileDataNode extends QueryDataNode {
|
|
|
161
204
|
return ctx.api[method](name, url, opt);
|
|
162
205
|
}
|
|
163
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Code generate a table creation query.
|
|
209
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
210
|
+
* @returns {string|void} The generated query code.
|
|
211
|
+
*/
|
|
164
212
|
codegenQuery(ctx) {
|
|
165
213
|
const { name, method, file, options } = this;
|
|
166
214
|
const url = resolveFileURL(file, ctx.baseURL);
|
|
@@ -205,11 +253,21 @@ export class LiteralJSONDataNode extends QueryDataNode {
|
|
|
205
253
|
this.options = options;
|
|
206
254
|
}
|
|
207
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Instantiate a table creation query.
|
|
258
|
+
* @param {import('../ast-to-dom.js').InstantiateContext} ctx The instantiation context.
|
|
259
|
+
* @returns {string|void} The instantiated query.
|
|
260
|
+
*/
|
|
208
261
|
instantiateQuery(ctx) {
|
|
209
262
|
const { name, data, options } = this;
|
|
210
263
|
return ctx.api.loadObjects(name, data, options.instantiate(ctx));
|
|
211
264
|
}
|
|
212
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Code generate a table creation query.
|
|
268
|
+
* @param {import('../ast-to-esm.js').CodegenContext} ctx The code generator context.
|
|
269
|
+
* @returns {string|void} The generated query code.
|
|
270
|
+
*/
|
|
213
271
|
codegenQuery(ctx) {
|
|
214
272
|
const { name, data, options } = this;
|
|
215
273
|
const opt = options ? ',' + options.codegen(ctx) : '';
|
package/src/ast/HSpaceNode.js
CHANGED
package/src/ast/InputNode.js
CHANGED
package/src/ast/ParamNode.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isArray, isObject } from '../util.js';
|
|
1
|
+
import { isArray, isObject, isoparse } from '../util.js';
|
|
3
2
|
import { ASTNode } from './ASTNode.js';
|
|
4
3
|
import { CROSSFILTER, INTERSECT, PARAM, SINGLE, UNION, VALUE } from '../constants.js';
|
|
5
4
|
import { SelectionNode } from './SelectionNode.js';
|
package/src/ast/PlotMarkNode.js
CHANGED
|
@@ -41,9 +41,10 @@ export class PlotMarkNode extends ASTNode {
|
|
|
41
41
|
|
|
42
42
|
instantiate(ctx) {
|
|
43
43
|
const { name, data, options } = this;
|
|
44
|
-
const fn = ctx.api[name];
|
|
45
44
|
const opt = options.instantiate(ctx);
|
|
46
|
-
return data
|
|
45
|
+
return data
|
|
46
|
+
? ctx.api[name](data.instantiate(ctx), opt)
|
|
47
|
+
: ctx.api[name](opt);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
codegen(ctx) {
|
package/src/ast/TransformNode.js
CHANGED
|
@@ -41,8 +41,7 @@ export class TransformNode extends ASTNode {
|
|
|
41
41
|
const { name, args, options } = this;
|
|
42
42
|
const { distinct, orderby, partitionby, rows, range } = options;
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
let expr = fn(...args);
|
|
44
|
+
let expr = ctx.api[name](...args);
|
|
46
45
|
if (distinct) {
|
|
47
46
|
expr = expr.distinct();
|
|
48
47
|
}
|
package/src/ast/VSpaceNode.js
CHANGED
package/src/ast-to-dom.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { Param, Selection } from '@uwdata/mosaic-core';
|
|
1
2
|
import { createAPIContext, loadExtension } from '@uwdata/vgplot';
|
|
2
3
|
import { SpecNode } from './ast/SpecNode.js';
|
|
3
4
|
import { resolveExtensions } from './config/extensions.js';
|
|
4
5
|
import { error } from './util.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* Generate running web application (DOM content) for a Mosaic spec AST.
|
|
8
|
+
* Generate a running web application (DOM content) for a Mosaic spec AST.
|
|
8
9
|
* @param {SpecNode} ast Mosaic AST root node.
|
|
9
10
|
* @param {object} [options] Instantiation options.
|
|
10
11
|
* @param {string} [options.baseURL] The base URL for loading data files.
|
|
11
|
-
* @
|
|
12
|
-
*
|
|
12
|
+
* @param {any[]} [options.plotDefaults] Array of default plot attributes.
|
|
13
|
+
* @param {Map<string, Param>} [options.params] A map of predefined Params/Selections.
|
|
14
|
+
* @returns {Promise<{
|
|
15
|
+
* element: HTMLElement | SVGSVGElement;
|
|
16
|
+
* params: Map<string, Param | Selection>;
|
|
17
|
+
* }>} A Promise to an object with the resulting
|
|
18
|
+
* DOM element, and a map of named parameters (Param and Selection instances).
|
|
13
19
|
*/
|
|
14
20
|
export async function astToDOM(ast, options) {
|
|
15
21
|
const { data, params, plotDefaults } = ast;
|
package/src/ast-to-esm.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
import { SpecNode } from './ast/SpecNode.js';
|
|
2
2
|
import { resolveExtensions } from './config/extensions.js';
|
|
3
|
-
import { error, isArray, isObject, isString, toParamRef } from './util.js';
|
|
3
|
+
import { error, isArray, isObject, isString, toArray, toParamRef } from './util.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Generate ESM code for a Mosaic spec AST.
|
|
7
7
|
* @param {SpecNode} ast Mosaic AST root node.
|
|
8
8
|
* @param {object} [options] Code generation options.
|
|
9
|
-
* @param {string} [options.namespace='vg'] The vgplot API namespace object.
|
|
10
9
|
* @param {string} [options.baseURL] The base URL for loading data files.
|
|
10
|
+
* @param {string} [options.connector] A database connector to initialize.
|
|
11
|
+
* Valid values are 'wasm', 'socket', and 'rest'.
|
|
12
|
+
* If undefined, no connector code is generated.
|
|
13
|
+
* @param {string} [options.namespace='vg'] The vgplot API namespace object.
|
|
11
14
|
* @param {number} [options.depth=0] The starting indentation depth.
|
|
12
|
-
* @param {Map<string,string>} [options.imports] A Map of ESM
|
|
13
|
-
* include in generated code. Keys are packages (e.g.,
|
|
14
|
-
* and values indicate what to import (e.g., '* as vg').
|
|
15
|
+
* @param {Map<string,string|string[]>} [options.imports] A Map of ESM
|
|
16
|
+
* imports to include in generated code. Keys are packages (e.g.,
|
|
17
|
+
* '@uwdata/vgplot') and values indicate what to import (e.g., '* as vg').
|
|
18
|
+
* @param {string|string[]} [options.preamble] Code to include after imports.
|
|
15
19
|
* @returns {string} Generated ESM code using the vgplot API.
|
|
16
20
|
*/
|
|
17
|
-
export function astToESM(ast, options) {
|
|
21
|
+
export function astToESM(ast, options = {}) {
|
|
18
22
|
const { root, data, params, plotDefaults } = ast;
|
|
19
|
-
const
|
|
23
|
+
const { preamble, ...ctxOptions } = options;
|
|
24
|
+
const ctx = new CodegenContext({ plotDefaults, ...ctxOptions });
|
|
20
25
|
|
|
21
26
|
// generate package imports
|
|
22
27
|
const importsCode = [];
|
|
@@ -24,10 +29,16 @@ export function astToESM(ast, options) {
|
|
|
24
29
|
importsCode.push(
|
|
25
30
|
isString(methods)
|
|
26
31
|
? `import ${methods} from "${pkg}";`
|
|
32
|
+
// @ts-ignore
|
|
27
33
|
: `import { ${methods.join(', ')} } from "${pkg}";`
|
|
28
34
|
);
|
|
29
35
|
}
|
|
30
36
|
|
|
37
|
+
// preamble code comes directly after imports
|
|
38
|
+
const preambleCode = preamble
|
|
39
|
+
? toArray(preamble).map(s => `${ctx.tab()}${s}`)
|
|
40
|
+
: [];
|
|
41
|
+
|
|
31
42
|
// generate database connector code
|
|
32
43
|
const connectorCode = [];
|
|
33
44
|
if (ctx.connector) {
|
|
@@ -82,6 +93,8 @@ export function astToESM(ast, options) {
|
|
|
82
93
|
return [
|
|
83
94
|
...importsCode,
|
|
84
95
|
...maybeNewline(importsCode),
|
|
96
|
+
...preambleCode,
|
|
97
|
+
...maybeNewline(preambleCode),
|
|
85
98
|
...connectorCode,
|
|
86
99
|
...maybeNewline(connectorCode),
|
|
87
100
|
...dataCode,
|
|
@@ -95,12 +108,26 @@ export function astToESM(ast, options) {
|
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
export class CodegenContext {
|
|
111
|
+
/**
|
|
112
|
+
* Create a new code generator context.
|
|
113
|
+
* @param {object} [options] Code generation options.
|
|
114
|
+
* @param {*} [options.plotDefaults] Default attributes to apply to all plots.
|
|
115
|
+
* @param {string} [options.baseURL] The base URL for loading data files.
|
|
116
|
+
* @param {string} [options.connector] A database connector to initialize.
|
|
117
|
+
* Valid values are 'wasm', 'socket', and 'rest'.
|
|
118
|
+
* If undefined, no connector code is generated.
|
|
119
|
+
* @param {string} [options.namespace='vg'] The vgplot API namespace object.
|
|
120
|
+
* @param {number} [options.depth=0] The starting indentation depth.
|
|
121
|
+
* @param {Map<string,string|string[]>} [options.imports] A Map of ESM
|
|
122
|
+
* imports to include in generated code. Keys are packages (e.g.,
|
|
123
|
+
* '@uwdata/vgplot') and values indicate what to import (e.g., '* as vg').
|
|
124
|
+
*/
|
|
98
125
|
constructor({
|
|
99
|
-
plotDefaults =
|
|
126
|
+
plotDefaults = undefined,
|
|
100
127
|
namespace = 'vg',
|
|
101
|
-
connector =
|
|
128
|
+
connector = undefined,
|
|
102
129
|
imports = new Map([['@uwdata/vgplot', '* as vg']]),
|
|
103
|
-
baseURL =
|
|
130
|
+
baseURL = undefined,
|
|
104
131
|
depth = 0
|
|
105
132
|
} = {}) {
|
|
106
133
|
this.plotDefaults = plotDefaults;
|
|
@@ -113,9 +140,11 @@ export class CodegenContext {
|
|
|
113
140
|
|
|
114
141
|
addImport(pkg, method) {
|
|
115
142
|
if (!this.imports.has(pkg)) {
|
|
116
|
-
this.imports.set(pkg, []);
|
|
143
|
+
this.imports.set(pkg, [method]);
|
|
144
|
+
} else {
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
this.imports.get(pkg).push(method);
|
|
117
147
|
}
|
|
118
|
-
this.imports.get(pkg).push(method);
|
|
119
148
|
}
|
|
120
149
|
|
|
121
150
|
setImports(pkg, all) {
|
package/src/config/inputs.js
CHANGED
package/src/config/plots.js
CHANGED
|
@@ -19,6 +19,7 @@ export function plotNames({
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Names of attribute directive functions.
|
|
22
|
+
* @returns {Set<string>}
|
|
22
23
|
*/
|
|
23
24
|
export function plotAttributeNames(overrides = []) {
|
|
24
25
|
return new Set([
|
|
@@ -29,6 +30,7 @@ export function plotAttributeNames(overrides = []) {
|
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Names interactor directive functions.
|
|
33
|
+
* @returns {Set<string>}
|
|
32
34
|
*/
|
|
33
35
|
export function plotInteractorNames(overrides = []) {
|
|
34
36
|
return new Set([
|
|
@@ -39,6 +41,7 @@ export function plotInteractorNames(overrides = []) {
|
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* Names of legend directive functions.
|
|
44
|
+
* @returns {Set<string>}
|
|
42
45
|
*/
|
|
43
46
|
export function plotLegendNames(overrides = []) {
|
|
44
47
|
return new Set([
|
|
@@ -49,6 +52,7 @@ export function plotLegendNames(overrides = []) {
|
|
|
49
52
|
|
|
50
53
|
/**
|
|
51
54
|
* Names of mark directive functions.
|
|
55
|
+
* @returns {Set<string>}
|
|
52
56
|
*/
|
|
53
57
|
export function plotMarkNames(overrides = []) {
|
|
54
58
|
return new Set([
|