Graphic Walker
Graphic Walker Workflow DSL

Graphic Walker Workflow DSL

The Graphic Walker Workflow DSL is a domain-specific language (DSL) that defines steps of a workflow to calculate data for a chart. The DSL is a JSON object that contains a list of steps, each step is an object that contains a type and a set of properties.

Before the renderer generates the visualization, GraphicWalker applies an asynchronous workflow to compute the data to the view data which is directly used by the renderer. The computation workflow consists of a series of data queries, that describe how to compute the view data from the raw data. The computation workflow is not only used in the rendering phase, but also used in cases such as preview table, and filter editor when GraphicWalker requires the necessary statistics from the raw data.

Computation Workflow

The computation workflow contains 4 types of queries: filter query, transform query, view query, and sort query.

Filter Query (optional)

The filter query is used to filter the raw data. It contains a list of filter fields, each of which contains a filter rule.

type IFilterRule = (
    | {
        type: 'range';
        value: readonly [number, number];
    }
    | {
        type: 'temporal range';
        value: readonly [number, number];
    }
    | {
        type: 'one of';
        value: Array<any>;
    }
    | {
        type: 'not in';
        value: Array<any>;
    }
);
 
interface IFilterField {
    fid: string;
    rule: IFilterRule;
}
 
interface IFilterQuery {
    type: 'filter';
    filters: Array<IFilterField>;
}

The schema of the filter query is

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "enum": [
                "filter"
            ]
        },
        "filters": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "fid": {
                        "type": "string"
                    },
                    "rule": {
                        "type": "object",
                        "oneOf": [
                            {
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "range",
                                            "temporal range"
                                        ]
                                    },
                                    "value": {
                                        "type": "array",
                                        "items": {
                                            "type": "number"
                                        },
                                        "minItems": 2,
                                        "maxItems": 2
                                    }
                                },
                                "required": [
                                    "type",
                                    "value"
                                ]
                            },
                            {
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "one of",
                                            "not in"
                                        ]
                                    },
                                    "value": {
                                        "type": "array",
                                        "items": {
                                            "oneOf": [
                                                {
                                                    "type": "string"
                                                },
                                                {
                                                    "type": "number"
                                                }
                                            ]
                                        }
                                    }
                                },
                                "required": [
                                    "type",
                                    "value"
                                ]
                            }
                        ]
                    }
                },
                "required": [
                    "fid",
                    "rule"
                ]
            }
        }
    },
    "required": [
        "type",
        "filters"
    ]
}

Transform Query (optional)

The transform query is used to resolve the field calculations. It contains a list of transform fields, each of which contains an expression.

type IExpParameter = (
    | {
        type: 'field';
        value: string;
    }
    | {
        type: 'value';
        value: any; 
    }
    | {
        type: 'expression';
        value: IExpression;
    }
    | {
        type: 'constant';
        value: any;
    }
);
 
interface IExpression {
    op: 'bin' | 'log2' | 'log10' | 'one' | 'binCount' | 'dateTimeDrill' | 'dateTimeFeature' | 'log' | 'paint' | 'expr';
    params: IExpParameter[]; 
    as: string;
    num?:number;
}
 
interface ITransformField {
    key: string;
    expression: IExpression;
}
 
interface ITransformQuery {
    type: 'transform';
    transform: Array<ITransformField>;
}

The schema of the transform query is

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "op": {
            "type": "string",
            "enum": [
                "bin",
                "log2",
                "log10",
                "one",
                "binCount",
                "dateTimeDrill",
                "dateTimeFeature",
                "log",
                "paint",
                "expr"
            ]
        },
        "params": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/IExpParameter"
            }
        },
        "as": {
            "type": "string"
        },
        "num": {
            "type": "number"
        }
    },
    "required": [
        "op",
        "params",
        "as"
    ],
    "additionalProperties": false,
    "definitions": {
        "IExpParameter": {
            "anyOf": [
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "field"
                        },
                        "value": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "value"
                        },
                        "value": {}
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "expression"
                        },
                        "value": {
                            "$ref": "#/definitions/IExpression"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "constant"
                        },
                        "value": {}
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "format"
                        },
                        "value": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "offset"
                        },
                        "value": {
                            "type": "number"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "map"
                        },
                        "value": {
                            "$ref": "#/definitions/IPaintMap"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "sql"
                        },
                        "value": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "newmap"
                        },
                        "value": {
                            "$ref": "#/definitions/IPaintMapV2"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "const": "displayOffset"
                        },
                        "value": {
                            "type": "number"
                        }
                    },
                    "required": [
                        "type",
                        "value"
                    ],
                    "additionalProperties": false
                }
            ]
        },
        "IExpression": {
            "type": "object",
            "properties": {
                "op": {
                    "type": "string",
                    "enum": [
                        "bin",
                        "log2",
                        "log10",
                        "one",
                        "binCount",
                        "dateTimeDrill",
                        "dateTimeFeature",
                        "log",
                        "paint",
                        "expr"
                    ]
                },
                "params": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/IExpParameter"
                    }
                },
                "as": {
                    "type": "string"
                },
                "num": {
                    "type": "number"
                }
            },
            "required": [
                "op",
                "params",
                "as"
            ],
            "additionalProperties": false
        },
        "IPaintMap": {
            "type": "object",
            "properties": {
                "x": {
                    "type": "string",
                    "description": "fid of x"
                },
                "y": {
                    "type": "string",
                    "description": "fid of y"
                },
                "domainX": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    },
                    "minItems": 2,
                    "maxItems": 2
                },
                "domainY": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    },
                    "minItems": 2,
                    "maxItems": 2
                },
                "mapwidth": {
                    "type": "number",
                    "description": "width"
                },
                "map": {
                    "type": "string",
                    "description": "a bit map, compressed array of UInt8[mapwidth][mapwidth]"
                },
                "dict": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "color": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "color"
                        ],
                        "additionalProperties": false
                    },
                    "description": "map values"
                },
                "usedColor": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                }
            },
            "required": [
                "x",
                "y",
                "domainX",
                "domainY",
                "mapwidth",
                "map",
                "dict",
                "usedColor"
            ],
            "additionalProperties": false,
            "deprecated": true
        },
        "IPaintMapV2": {
            "type": "object",
            "properties": {
                "facets": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/IPaintMapFacet"
                    }
                },
                "dict": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "color": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "color"
                        ],
                        "additionalProperties": false
                    }
                },
                "usedColor": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                }
            },
            "required": [
                "facets",
                "dict",
                "usedColor"
            ],
            "additionalProperties": false
        },
        "IPaintMapFacet": {
            "type": "object",
            "properties": {
                "dimensions": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/IPaintDimension"
                    }
                },
                "map": {
                    "type": "string",
                    "description": "a bit map, compressed array of UInt8[dimensions.reduce((x,d) => x * d.domain.width, 1)]"
                },
                "usedColor": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                }
            },
            "required": [
                "dimensions",
                "map",
                "usedColor"
            ],
            "additionalProperties": false
        },
        "IPaintDimension": {
            "type": "object",
            "properties": {
                "fid": {
                    "type": "string"
                },
                "joinPath": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/IJoinPath"
                    }
                },
                "dataset": {
                    "type": "string"
                },
                "domain": {
                    "anyOf": [
                        {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "const": "nominal"
                                },
                                "value": {
                                    "type": "array",
                                    "items": {}
                                },
                                "width": {
                                    "type": "number"
                                }
                            },
                            "required": [
                                "type",
                                "value",
                                "width"
                            ],
                            "additionalProperties": false
                        },
                        {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "const": "quantitative"
                                },
                                "value": {
                                    "type": "array",
                                    "items": {
                                        "type": "number"
                                    },
                                    "minItems": 2,
                                    "maxItems": 2
                                },
                                "width": {
                                    "type": "number"
                                }
                            },
                            "required": [
                                "type",
                                "value",
                                "width"
                            ],
                            "additionalProperties": false
                        }
                    ]
                }
            },
            "required": [
                "fid",
                "domain"
            ],
            "additionalProperties": false
        },
        "IJoinPath": {
            "type": "object",
            "properties": {
                "from": {
                    "type": "string"
                },
                "fid": {
                    "type": "string"
                },
                "to": {
                    "type": "string"
                },
                "tid": {
                    "type": "string"
                }
            },
            "required": [
                "from",
                "fid",
                "to",
                "tid"
            ],
            "additionalProperties": false
        }
    }
}

View Query (required)

The view query is used to shape the data into a view data. It contains a list of view queries, each of which contains a view-level operation. A workflow must contain at least one view-level operation, which describes the structure of the view data.

At the moment, there are 3 view-level operations: aggregate, fold, and raw.

Aggregate Query

Use the aggregate operation in the view query when you want the data to be aggregated. The aggregate operation contains a list of measures to be aggregated by a specified aggregation function with the group-by fields.

type IAggregator = 'sum' | 'count' | 'max' | 'min' | 'mean' | 'median' | 'variance' | 'stdev';
 
interface IAggQuery {
    op: 'aggregate';
    groupBy: string[];
    measures: {
        field: string;
        agg: IAggregator;
        asFieldKey: string;
    }[];
}

Raw Query

Use the raw operation in the view query when you want the data not to be aggregated. The raw operation contains a list of fields to be included in the view data.

interface IRawQuery {
    op: 'raw';
    fields: string[];
}

An aggregate query will be

type IViewQuery = IAggQuery | IRawQuery;
 
interface IViewQuery {
    type: 'view';
    query: Array<IViewQuery>;
}

The schema of the view query is

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "enum": [
                "view"
            ]
        },
        "query": {
            "type": "array",
            "items": {
                "oneOf": [
                    {
                        "type": "object",
                        "properties": {
                            "op": {
                                "type": "string",
                                "enum": [
                                    "aggregate"
                                ]
                            },
                            "groupBy": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "measures": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "field": {
                                            "type": "string"
                                        },
                                        "agg": {
                                            "type": "string",
                                            "enum": [
                                                "sum",
                                                "count",
                                                "max",
                                                "min",
                                                "mean",
                                                "median",
                                                "variance",
                                                "stdev"
                                            ]
                                        },
                                        "asFieldKey": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "field",
                                        "agg",
                                        "asFieldKey"
                                    ]
                                }
                            }
                        },
                        "required": [
                            "op",
                            "groupBy",
                            "measures"
                        ]
                    },
                    {
                        "type": "object",
                        "properties": {
                            "op": {
                                "type": "string",
                                "enum": [
                                    "raw"
                                ]
                            },
                            "fields": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            }
                        },
                        "required": [
                            "op",
                            "fields"
                        ]
                    }
                ]
            }
        }
    },
    "required": [
        "type",
        "query"
    ]
}

Sort Query (optional)

The filter query is used to sort the result data. It contains a list of fields to be used for sort, and excepted sorting order.

export interface ISortWorkflowStep {
    type: 'sort';
    sort: 'ascending' | 'descending';
    by: string[];
}

The schema of the sort query is

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "enum": [
                "sort"
            ]
        },
        "sort": {
            "type": "string",
            "enum": [
                "ascending",
                "descending"
            ]
        },
        "by": {
            "type": "array",
            "items": {
                "type": "string",
            }
        }
    },
    "required": [
        "type",
        "sort",
        "by"
    ]
}

Computation Request

GraphicWalker regards a computation as a request. A computation function, including HTTP service, must follow the protocol of the request.

Payload

export interface IDataQueryPayload {
    workflow: IDataQueryWorkflowStep[];
    limit?: number;
    offset?: number;
}

Return Value

export interface IRow {
    [key: string]: any;
}
declare const result: IRow[];

Computation Function

export type IComputationFunction = (payload: IDataQueryPayload) => Promise<IRow[]>;