UNPKG

compassql

Version:

CompassQL visualization query language

186 lines (134 loc) 7.64 kB
# CompassQL CompassQL is a visualization query language that powers chart specifications and recommendations in [Voyager 2](https://github.com/vega/voyager2). As described in our [vision paper](https://idl.cs.washington.edu/papers/compassql) and [Voyager 2](https://idl.cs.washington.edu/papers/voyager2) paper, a CompassQL query is a JSON object that contains the following components: - **Specification** (`spec`) for describing a collection of queried visualizations. This `spec`'s syntax follows a structure similar to [Vega-Lite](https://vega.github.io/vega-lite)'s single view specification. However, `spec` in CompassQL can have *enumeration specifiers* (or *wildcards*) describing properties that can be enumerated.<sup>1</sup> - **Grouping/Nesting** method names (`groupBy` and `nest`) for grouping queried visualizations into groups or hierarchical groups. - **Ranking** method names (`orderBy` and `chooseBy`) for ordering queried visualizations or choose a top visualization from the collection. - **Config** (`config`) for customizing query parameters. Internally, CompassQL engine contains a collection of constraints for enumerating a set of candidate visualizations based on the input specification, and methods for grouping and ranking visualization. For example, the following CompassQL query has one wildcard for the `mark` property. The system will automatically generate different marks and choose the top visual encodings based on the effectiveness score. ``` { "spec": { "data": {"url": "data/cars.json"}, "mark": "?", "encodings": [ { "channel": "x", "aggregate": "mean", "field": "Horsepower", "type": "quantitative" },{ "channel": "y", "field": "Cylinders", "type": "ordinal" } ] }, "chooseBy": "effectiveness" } ``` The [`examples/specs`](https://github.com/vega/compassql/tree/master/examples/specs) directory contains a number of example CompassQL queries. To understand more about the structure of a CompassQL Query, look at [the `Query` interface declaration](https://github.com/vega/compassql/blob/master/src/query/query.ts). - A query's `spec` property implements `SpecQuery` interface, which follows the same structure as [Vega-Lite](https://github.com/vega/vega-lite)'s `UnitSpec` (single view specification) but most of `SpecQuery`'s properties have `-Query` suffixes to hint that its instance is a query that can contain wildcards to describe a collection of specifications. - Since multiple encoding channels can be a wildcard, the `encoding` object in Vega-Lite is flatten as `encodings` which is an array of Encoding in CompassQL's `spec`. ## Usage Given a row-based array of data object, here are the steps to use CompassQL: 1) Specify a query config (or use an empty object to use the default configs) ```js var opt = {}; // Use all default query configs ``` For all query configuration properties, see [`src/config.ts`](https://github.com/vega/compassql/blob/master/src/config.ts). 2) Build a data schema. ```js var schema = cql.schema.build(data); ``` The `data` property is a row-based array of data objects where each object represents a row in the data table (e.g., `[{"a": 1, "b":2}, {"a": 2, "b": 3}]`). You can reuse the same schema for querying the same dataset multiple times. 3) Specify a query. For example, this is a query for automatically selecting a mark: ```js var query = { "spec": { "data": {"url": "node_modules/vega-datasets/data/cars.json"}, "mark": "?", "encodings": [ { "channel": "x", "aggregate": "mean", "field": "Horsepower", "type": "quantitative" },{ "channel": "y", "field": "Cylinders", "type": "ordinal" } ] }, "chooseBy": "effectiveness" }; ``` 4) Execute a CompassQL `query`. ```js var output = cql.recommend(query, schema); var result = output.result; // recommendation result ``` The `result` object is an instance of [`SpecQueryModelGroup` (`ResultGroup<SpecQueryModel>`)](https://github.com/vega/compassql/blob/master/src/resultgroup.ts), which is a root of the output ordered tree. Its `items` property can be either an array of `SpecQueryModel` or an array of `SpecQueryModelGroup` (for hierarchical groupings). The `SpecQueryModel` is an class instance of a `SpecQuery` with helper methods. Note that, in the result, all of spec query models are completely enumerated and there would be no wildcard left. 5) Convert instances of `SpecQueryModel` in the tree, using `SpecQueryModel`'s `toSpec()` class method and the `mapLeaves` method. ```js var vlTree = cql.result.mapLeaves(result, function(item) { return item.toSpec(); }); ``` 6) Now you can use the result. In this case, the tree has only 2 levels (the root and leaves). We can just get the top visualization by accessing the 0-th item. For a full source code, please see [`index.html`](https://github.com/vega/compassql/blob/master/index.html). ```js var topVlSpec = vlTree.items[0]; ``` # Note for Developers - The root file of our project is `src/cql.ts`, which defines the top-level namespace `cql` for the compiled files. Other files under `src/` reflect namespace structure. All methods for `cql.xxx` will be in either `src/xxx.ts` or `src/xxx/xxx.ts`. For example, `cql.util.*` methods are in `src/util.ts`, `cql.query` is in `src/query/query.ts`. - TODO: constraints - List in Vy2 paper supplement.. ## Development Instructions You can install dependencies with: ```sh yarn install ``` You can use the following npm commands such as ``` npm run build npm run lint npm run test npm run cover // see test coverage (see coverage/lcov-report/index.html) npm run watch // watcher that build, lint, and test npm run test-debug // useful for debugging unit-test with vscode npm run clean // useful for wiping out js files that's created from other branch ``` (See package.json for Full list of commands.) To play with latest CompassQL in the vega-editor, use branch [`cql-vl3` in kanitw's fork](http://github.com/kanitw/vega-editor/), which has been updated to use Vega-Lite 3, Vega 5, and CompassQL ^0.21.1. (For CompassQL 0.7 or older, use branch [`compassql`](https://github.com/vega/vega-editor/tree/compassql), which uses Vega-Lite 1.x). Make sure to link CompassQL to the editor ``` cd COMPASSQL_DIR npm link cd VEGA_EDITOR_DIR npm run vendor -- -l compassql ``` (You might want to [link your local version of Vega-Lite](https://github.com/vega/vega-editor/tree/compassql#local-testing--debugging) as well.) ## Main API The main method is `cql.recommend`, which is in `src/recommend.ts`. ## Directory Structure - `examples` - Example CompassQL queries - `examples/specs` – All JSON files for CompassQL queries - `examples/cql-examples.json` - A json files listing all CompasssQL examples that should be shown in Vega-editor. - `src/` - Main source code directory. - `src/cql.ts` is the root file for CompassQL codebase that exports the global `cql` object. Other files under `src/` reflect namespace structure. - All interface for CompassQL syntax should be declared at the top-level of the `src/` folder. - `test/` - Code for unit testing. `test`'s structure reflects `src`'s' directory structure. For example, `test/constraint/` test files inside `src/constraint/`. - `typings/` - TypeScript typing declaration for dependencies. Some of them are downloaded from the TypeStrong community. ## Pro-Tip - When you add a new source file to the project, don't forget to the file to `files` in `tsconfig.json`.