├── .eslintrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── bin
└── rollup
├── docs
├── data
│ ├── 7zip.png
│ ├── airports.csv
│ ├── barley.json
│ ├── budgets.json
│ ├── cars.json
│ ├── chart.json
│ ├── driving.json
│ ├── ffox.png
│ ├── flare.json
│ ├── flights-200k.json
│ ├── flights-airport.csv
│ ├── gapminder.json
│ ├── gimp.png
│ ├── iris.json
│ ├── jobs.json
│ ├── lotsa_points.json
│ ├── miserables.json
│ ├── monarchs.json
│ ├── movies.json
│ ├── normal-2d.json
│ ├── population.json
│ ├── seattle-temps.csv
│ ├── sp500.csv
│ ├── stocks.csv
│ ├── unemployment.tsv
│ ├── us-10m.json
│ ├── weather.json
│ ├── wheat.json
│ └── world-110m.json
├── group.html
├── image-output.html
├── index.html
├── prefacet.html
├── spec.html
├── spec
│ ├── airports.vg.json
│ ├── arc.vg.json
│ ├── area.vg.json
│ ├── bar-hover-label.vg.json
│ ├── bar-rangestep.vg.json
│ ├── bar.vg.json
│ ├── barley.vg.json
│ ├── budget-forecasts.vg.json
│ ├── chart-rangestep.vg.json
│ ├── chart.vg.json
│ ├── choropleth.vg.json
│ ├── crossfilter-multi.vg.json
│ ├── crossfilter.vg.json
│ ├── density.vg.json
│ ├── dimpvis.vg.json
│ ├── driving.vg.json
│ ├── error.vg.json
│ ├── falkensee.vg.json
│ ├── force-beeswarm.vg.json
│ ├── force-network.vg.json
│ ├── gradient.vg.json
│ ├── grouped-bar.vg.json
│ ├── heatmap-lines.vg.json
│ ├── heatmap.vg.json
│ ├── histogram.vg.json
│ ├── horizon.vg.json
│ ├── images.vg.json
│ ├── jobs.vg.json
│ ├── legends.vg.json
│ ├── lifelines.vg.json
│ ├── map-bind.vg.json
│ ├── map.vg.json
│ ├── matrix-reorder.vg.json
│ ├── movies-sort.vg.json
│ ├── nested-plot.vg.json
│ ├── overview-detail.vg.json
│ ├── panzoom.vg.json
│ ├── parallel-coords.vg.json
│ ├── playfair.vg.json
│ ├── population.vg.json
│ ├── scale.vg.json
│ ├── scatter-plot.vg.json
│ ├── shift-select.vg.json
│ ├── splom-inner.vg.json
│ ├── splom-outer.vg.json
│ ├── stacked-area.vg.json
│ ├── stacked-bar.vg.json
│ ├── stocks-index.vg.json
│ ├── tree-radial.vg.json
│ ├── treemap.vg.json
│ ├── violin-plot.vg.json
│ ├── weather.vg.json
│ └── wordcloud.vg.json
└── specs.json
├── index.js
├── package.json
├── scripts
└── lotsa_points.py
├── src
├── WebGLRenderer.js
├── marks
│ ├── arc.js
│ ├── area.js
│ ├── group.js
│ ├── image.js
│ ├── index.js
│ ├── line.js
│ ├── markItemPath.js
│ ├── markMultiItemPath.js
│ ├── path.js
│ ├── rect.js
│ ├── rule.js
│ ├── shape.js
│ ├── symbol.js
│ └── text.js
├── path
│ ├── geometryForItem.js
│ ├── geometryForPath.js
│ ├── geometryForShape.js
│ └── shapes.js
└── util
│ ├── color.js
│ ├── drawGeometry.js
│ ├── image.js
│ ├── inherits.js
│ ├── matrix.js
│ ├── resize.js
│ └── webgl.js
├── test
├── index.html
├── resources
│ ├── generate-tests.js
│ ├── image0.png
│ ├── image1.png
│ ├── image2.png
│ ├── marks.json
│ ├── png
│ │ ├── marks-arc_15.1.png
│ │ ├── marks-arc_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-area-breaks_15.1.png
│ │ ├── marks-area-breaks_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-area-h_15.1.png
│ │ ├── marks-area-h_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-area-trail_15.1.png
│ │ ├── marks-area-trail_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-area-v_15.1.png
│ │ ├── marks-area-v_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-group_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-image_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-line-1_15.1.png
│ │ ├── marks-line-1_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-line-2_15.1.png
│ │ ├── marks-line-2_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-line-breaks_15.1.png
│ │ ├── marks-line-breaks_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-path-clear_17.1.png
│ │ ├── marks-path-clear_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-path_15.1.png
│ │ ├── marks-path_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-rect_15.1.png
│ │ ├── marks-rect_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-rule_15.1.png
│ │ ├── marks-rule_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-symbol_15.1.png
│ │ ├── marks-symbol_f3263d_acbc327b1175928155d3e050.png
│ │ ├── marks-text_15.1.png
│ │ ├── marks-text_f3263d_acbc327b1175928155d3e050.png
│ │ ├── scenegraph-barley_15.1.png
│ │ ├── scenegraph-barley_f3263d_acbc327b1175928155d3e050.png
│ │ ├── scenegraph-defs2_f3263d_acbc327b1175928155d3e050.png
│ │ ├── scenegraph-defs_f3263d_acbc327b1175928155d3e050.png
│ │ └── scenegraph-rect_f3263d_acbc327b1175928155d3e050.png
│ ├── scenegraph-barley.json
│ ├── scenegraph-defs.json
│ ├── scenegraph-defs2.json
│ └── scenegraph-rect.json
├── test-selenium-down.sh
├── test-selenium-up.sh
├── test-server-down.sh
├── test-server-up.sh
└── webgl-renderer-test.js
└── wdio.conf.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | parserOptions:
2 | sourceType: "module"
3 |
4 | env:
5 | es6: true
6 | browser: true
7 | node: true
8 |
9 | extends:
10 | "eslint:recommended"
11 |
12 | rules:
13 | no-cond-assign: 0
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .server.log
3 | .server.pid
4 | .selenium.log
5 | .selenium.pid
6 | build/
7 | node_modules
8 | npm-debug.log
9 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | build/*.zip
2 | test/
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: required
3 | dist: trusty
4 |
5 |
6 | node_js:
7 | - '5.10'
8 |
9 | addons:
10 | firefox: latest
11 | apt:
12 | packages:
13 | - mesa-utils
14 | - xvfb
15 | - libosmesa6
16 |
17 | - libgif-dev
18 | - libpng-dev
19 |
20 | - freeglut3-dev
21 | - libxmu-dev
22 | - libxi-dev
23 | - libxxf86vm-dev
24 | - libxrandr-dev
25 |
26 | cache:
27 | directories:
28 | - node_modules
29 |
30 | before_install:
31 | - npm prune
32 |
33 | before_script:
34 | - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
35 | - sudo dpkg -i google-chrome-stable_current_amd64.deb
36 | - sudo ln -s /usr/lib/x86_64-linux-gnu/libOSMesa.so.6 /opt/google/chrome/libosmesa.so
37 | - export DISPLAY=:99.0
38 | - sh -e /etc/init.d/xvfb start
39 | - sleep 3 # give xvfb some time to start
40 |
41 | script:
42 | - npm install
43 | - npm run build
44 | - npm run test
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, Kitware, Inc.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its contributors
15 | may be used to endorse or promote products derived from this software
16 | without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | WebGL renderer for [Vega](https://vega.github.io/vega)
2 | ======================================================
3 |
4 | [Demo](https://vega.github.io/vega-webgl-renderer)
5 |
6 | Major features
7 | --------------
8 |
9 | * Implements nearly all Vega scene graph components as WebGL primitives. Falls
10 | back to 2D Canvas rendering for text and gradient fills, which are drawn to
11 | a WebGL texture and overlaid on the view.
12 | * Custom shaders for Rect and Symbol marks, enabling greater scalability
13 | (to the hundreds of thousands) beyond Canvas and SVG renderers. See the
14 | "scale" example in the demo (Note: Do not attempt that example with the
15 | SVG renderer, it will lock your browser for a while).
16 |
17 | Usage
18 | -----
19 |
20 | Use this scaffolding to get started using the WebGL renderer. Instead of being
21 | directly usable after loading Vega, as the SVG and Canvas renderers are,
22 | the WebGL renderer is a plugin which requires the inclusion of an additional
23 | JavaScript library.
24 |
25 | The WebGL renderer requires Vega 3.0 (currently in beta).
26 |
27 | ```html
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 |
44 | ```
45 |
46 | Build
47 | -----
48 |
49 | ```
50 | npm install
51 | npm run build
52 | ```
53 |
54 | Test
55 | ----
56 |
57 | Testing requires that the Selenium server is running with the Chrome driver installed.
58 | To run all tests:
59 |
60 | ```
61 | npm run test
62 | ```
63 |
64 | To just run the linter:
65 |
66 | ```
67 | npm run lint
68 | ```
69 |
70 | Contributing
71 | ------------
72 |
73 | Please try it out and let us know how it works for you.
74 | Bug reports, feature and improvement ideas, and PRs welcome.
75 |
76 | This code is built and maintained by the [Kitware](http://www.kitware.com)
77 | [Resonant](http://resonant.kitware.com) team in collaboration with the
78 | [UW Interactive Data Lab](https://idl.cs.washington.edu/). The work is supported
79 | by the DARPA AFRL [XDATA](http://opencatalog.darpa.mil/XDATA.html) program.
80 |
81 | Known issues
82 | ------------
83 |
84 | * Line dashes are not supported (see "barley", "nested-plot", "map-bind" examples).
85 | * Triangulation of trails is known to be buggy and leave holes at internal nodes.
86 | * Custom symbol shapes are not supported.
87 | * Triangulation of geometry sometimes results in spurious offshoots.
88 |
89 | Notes
90 | -----
91 |
92 | There is one minor change to [extrude-polyline](https://github.com/mattdesl/extrude-polyline/compare/master...jeffbaumes:closed-path)
93 | which hacks in a way to close mitered strokes, which has not been merged upstream.
94 |
--------------------------------------------------------------------------------
/bin/rollup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var rollup = require('rollup'),
4 | resolve = require('rollup-plugin-node-resolve'),
5 | commonjs = require('rollup-plugin-commonjs'),
6 | output = 'vega-webgl-renderer.js';
7 |
8 | var modules = [
9 | 'd3-color',
10 | 'vega-scenegraph'
11 | ];
12 |
13 | var module_globals = {
14 | 'd3-color': 'd3',
15 | 'vega-scenegraph': 'vega'
16 | };
17 |
18 | rollup.rollup({
19 | entry: 'index.js',
20 | external: modules,
21 | plugins: [
22 | resolve(),
23 | commonjs()
24 | ]
25 | }).then(function(bundle) {
26 | return bundle.write({
27 | format: 'umd',
28 | moduleName: 'vega',
29 | globals: module_globals,
30 | dest: 'build/' + output
31 | });
32 | }).then(function() {
33 | console.warn('↳ build/' + output);
34 | }).catch(abort);
35 |
36 | function abort(error) {
37 | console.error(error.stack);
38 | }
39 |
--------------------------------------------------------------------------------
/docs/data/7zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/docs/data/7zip.png
--------------------------------------------------------------------------------
/docs/data/driving.json:
--------------------------------------------------------------------------------
1 | [
2 | {"side": "left", "year": 1956, "miles": 3675, "gas": 2.38},
3 | {"side": "right", "year": 1957, "miles": 3706, "gas": 2.40},
4 | {"side": "bottom", "year": 1958, "miles": 3766, "gas": 2.26},
5 | {"side": "top", "year": 1959, "miles": 3905, "gas": 2.31},
6 | {"side": "right", "year": 1960, "miles": 3935, "gas": 2.27},
7 | {"side": "bottom", "year": 1961, "miles": 3977, "gas": 2.25},
8 | {"side": "right", "year": 1962, "miles": 4085, "gas": 2.22},
9 | {"side": "bottom", "year": 1963, "miles": 4218, "gas": 2.12},
10 | {"side": "bottom", "year": 1964, "miles": 4369, "gas": 2.11},
11 | {"side": "bottom", "year": 1965, "miles": 4538, "gas": 2.14},
12 | {"side": "top", "year": 1966, "miles": 4676, "gas": 2.14},
13 | {"side": "bottom", "year": 1967, "miles": 4827, "gas": 2.14},
14 | {"side": "right", "year": 1968, "miles": 5038, "gas": 2.13},
15 | {"side": "right", "year": 1969, "miles": 5207, "gas": 2.07},
16 | {"side": "right", "year": 1970, "miles": 5376, "gas": 2.01},
17 | {"side": "bottom", "year": 1971, "miles": 5617, "gas": 1.93},
18 | {"side": "bottom", "year": 1972, "miles": 5973, "gas": 1.87},
19 | {"side": "right", "year": 1973, "miles": 6154, "gas": 1.90},
20 | {"side": "left", "year": 1974, "miles": 5943, "gas": 2.34},
21 | {"side": "bottom", "year": 1975, "miles": 6111, "gas": 2.31},
22 | {"side": "bottom", "year": 1976, "miles": 6389, "gas": 2.32},
23 | {"side": "top", "year": 1977, "miles": 6630, "gas": 2.36},
24 | {"side": "bottom", "year": 1978, "miles": 6883, "gas": 2.23},
25 | {"side": "left", "year": 1979, "miles": 6744, "gas": 2.68},
26 | {"side": "left", "year": 1980, "miles": 6672, "gas": 3.30},
27 | {"side": "right", "year": 1981, "miles": 6732, "gas": 3.30},
28 | {"side": "right", "year": 1982, "miles": 6835, "gas": 2.92},
29 | {"side": "right", "year": 1983, "miles": 6943, "gas": 2.66},
30 | {"side": "right", "year": 1984, "miles": 7130, "gas": 2.48},
31 | {"side": "right", "year": 1985, "miles": 7323, "gas": 2.36},
32 | {"side": "left", "year": 1986, "miles": 7558, "gas": 1.76},
33 | {"side": "top", "year": 1987, "miles": 7770, "gas": 1.76},
34 | {"side": "bottom", "year": 1988, "miles": 8089, "gas": 1.68},
35 | {"side": "left", "year": 1989, "miles": 8397, "gas": 1.75},
36 | {"side": "top", "year": 1990, "miles": 8529, "gas": 1.88},
37 | {"side": "right", "year": 1991, "miles": 8535, "gas": 1.78},
38 | {"side": "right", "year": 1992, "miles": 8662, "gas": 1.69},
39 | {"side": "left", "year": 1993, "miles": 8855, "gas": 1.60},
40 | {"side": "bottom", "year": 1994, "miles": 8909, "gas": 1.59},
41 | {"side": "bottom", "year": 1995, "miles": 9150, "gas": 1.60},
42 | {"side": "top", "year": 1996, "miles": 9192, "gas": 1.67},
43 | {"side": "right", "year": 1997, "miles": 9416, "gas": 1.65},
44 | {"side": "bottom", "year": 1998, "miles": 9590, "gas": 1.39},
45 | {"side": "right", "year": 1999, "miles": 9687, "gas": 1.50},
46 | {"side": "top", "year": 2000, "miles": 9717, "gas": 1.89},
47 | {"side": "left", "year": 2001, "miles": 9699, "gas": 1.77},
48 | {"side": "bottom", "year": 2002, "miles": 9814, "gas": 1.64},
49 | {"side": "right", "year": 2003, "miles": 9868, "gas": 1.86},
50 | {"side": "left", "year": 2004, "miles": 9994, "gas": 2.14},
51 | {"side": "left", "year": 2005, "miles": 10067, "gas": 2.53},
52 | {"side": "right", "year": 2006, "miles": 10037, "gas": 2.79},
53 | {"side": "right", "year": 2007, "miles": 10025, "gas": 2.95},
54 | {"side": "left", "year": 2008, "miles": 9880, "gas": 3.31},
55 | {"side": "bottom", "year": 2009, "miles": 9657, "gas": 2.38},
56 | {"side": "left", "year": 2010, "miles": 9596, "gas": 2.61}
57 | ]
--------------------------------------------------------------------------------
/docs/data/ffox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/docs/data/ffox.png
--------------------------------------------------------------------------------
/docs/data/gimp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/docs/data/gimp.png
--------------------------------------------------------------------------------
/docs/data/monarchs.json:
--------------------------------------------------------------------------------
1 | [
2 | {"name":"Elizabeth","start":1565,"end":1603,"index":0},
3 | {"name":"James I","start":1603,"end":1625,"index":1},
4 | {"name":"Charles I","start":1625,"end":1649,"index":2},
5 | {"name":"Cromwell","start":1649,"end":1660,"commonwealth":true,"index":3},
6 | {"name":"Charles II","start":1660,"end":1685,"index":4},
7 | {"name":"James II","start":1685,"end":1689,"index":5},
8 | {"name":"W&M","start":1689,"end":1702,"index":6},
9 | {"name":"Anne","start":1702,"end":1714,"index":7},
10 | {"name":"George I","start":1714,"end":1727,"index":8},
11 | {"name":"George II","start":1727,"end":1760,"index":9},
12 | {"name":"George III","start":1760,"end":1820,"index":10},
13 | {"name":"George IV","start":1820,"end":1820,"index":11}
14 | ]
--------------------------------------------------------------------------------
/docs/data/sp500.csv:
--------------------------------------------------------------------------------
1 | date,price
2 | Jan 1 2000,1394.46
3 | Feb 1 2000,1366.42
4 | Mar 1 2000,1498.58
5 | Apr 1 2000,1452.43
6 | May 1 2000,1420.6
7 | Jun 1 2000,1454.6
8 | Jul 1 2000,1430.83
9 | Aug 1 2000,1517.68
10 | Sep 1 2000,1436.51
11 | Oct 1 2000,1429.4
12 | Nov 1 2000,1314.95
13 | Dec 1 2000,1320.28
14 | Jan 1 2001,1366.01
15 | Feb 1 2001,1239.94
16 | Mar 1 2001,1160.33
17 | Apr 1 2001,1249.46
18 | May 1 2001,1255.82
19 | Jun 1 2001,1224.38
20 | Jul 1 2001,1211.23
21 | Aug 1 2001,1133.58
22 | Sep 1 2001,1040.94
23 | Oct 1 2001,1059.78
24 | Nov 1 2001,1139.45
25 | Dec 1 2001,1148.08
26 | Jan 1 2002,1130.2
27 | Feb 1 2002,1106.73
28 | Mar 1 2002,1147.39
29 | Apr 1 2002,1076.92
30 | May 1 2002,1067.14
31 | Jun 1 2002,989.82
32 | Jul 1 2002,911.62
33 | Aug 1 2002,916.07
34 | Sep 1 2002,815.28
35 | Oct 1 2002,885.76
36 | Nov 1 2002,936.31
37 | Dec 1 2002,879.82
38 | Jan 1 2003,855.7
39 | Feb 1 2003,841.15
40 | Mar 1 2003,848.18
41 | Apr 1 2003,916.92
42 | May 1 2003,963.59
43 | Jun 1 2003,974.5
44 | Jul 1 2003,990.31
45 | Aug 1 2003,1008.01
46 | Sep 1 2003,995.97
47 | Oct 1 2003,1050.71
48 | Nov 1 2003,1058.2
49 | Dec 1 2003,1111.92
50 | Jan 1 2004,1131.13
51 | Feb 1 2004,1144.94
52 | Mar 1 2004,1126.21
53 | Apr 1 2004,1107.3
54 | May 1 2004,1120.68
55 | Jun 1 2004,1140.84
56 | Jul 1 2004,1101.72
57 | Aug 1 2004,1104.24
58 | Sep 1 2004,1114.58
59 | Oct 1 2004,1130.2
60 | Nov 1 2004,1173.82
61 | Dec 1 2004,1211.92
62 | Jan 1 2005,1181.27
63 | Feb 1 2005,1203.6
64 | Mar 1 2005,1180.59
65 | Apr 1 2005,1156.85
66 | May 1 2005,1191.5
67 | Jun 1 2005,1191.33
68 | Jul 1 2005,1234.18
69 | Aug 1 2005,1220.33
70 | Sep 1 2005,1228.81
71 | Oct 1 2005,1207.01
72 | Nov 1 2005,1249.48
73 | Dec 1 2005,1248.29
74 | Jan 1 2006,1280.08
75 | Feb 1 2006,1280.66
76 | Mar 1 2006,1294.87
77 | Apr 1 2006,1310.61
78 | May 1 2006,1270.09
79 | Jun 1 2006,1270.2
80 | Jul 1 2006,1276.66
81 | Aug 1 2006,1303.82
82 | Sep 1 2006,1335.85
83 | Oct 1 2006,1377.94
84 | Nov 1 2006,1400.63
85 | Dec 1 2006,1418.3
86 | Jan 1 2007,1438.24
87 | Feb 1 2007,1406.82
88 | Mar 1 2007,1420.86
89 | Apr 1 2007,1482.37
90 | May 1 2007,1530.62
91 | Jun 1 2007,1503.35
92 | Jul 1 2007,1455.27
93 | Aug 1 2007,1473.99
94 | Sep 1 2007,1526.75
95 | Oct 1 2007,1549.38
96 | Nov 1 2007,1481.14
97 | Dec 1 2007,1468.36
98 | Jan 1 2008,1378.55
99 | Feb 1 2008,1330.63
100 | Mar 1 2008,1322.7
101 | Apr 1 2008,1385.59
102 | May 1 2008,1400.38
103 | Jun 1 2008,1280
104 | Jul 1 2008,1267.38
105 | Aug 1 2008,1282.83
106 | Sep 1 2008,1166.36
107 | Oct 1 2008,968.75
108 | Nov 1 2008,896.24
109 | Dec 1 2008,903.25
110 | Jan 1 2009,825.88
111 | Feb 1 2009,735.09
112 | Mar 1 2009,797.87
113 | Apr 1 2009,872.81
114 | May 1 2009,919.14
115 | Jun 1 2009,919.32
116 | Jul 1 2009,987.48
117 | Aug 1 2009,1020.62
118 | Sep 1 2009,1057.08
119 | Oct 1 2009,1036.19
120 | Nov 1 2009,1095.63
121 | Dec 1 2009,1115.1
122 | Jan 1 2010,1073.87
123 | Feb 1 2010,1104.49
124 | Mar 1 2010,1140.45
125 |
--------------------------------------------------------------------------------
/docs/data/weather.json:
--------------------------------------------------------------------------------
1 | [{"day":"M","record":{"high":62,"low":15},"normal":{"high":50,"low":38},"actual":{"high":48,"low":36},"id":0},{"day":"T","record":{"high":62,"low":23},"normal":{"high":50,"low":38},"actual":{"high":50,"low":40},"id":1},{"day":"W","record":{"high":61,"low":20},"normal":{"high":50,"low":38},"actual":{"high":55,"low":36},"id":2},{"day":"T","record":{"high":67,"low":21},"normal":{"high":50,"low":38},"actual":{"high":51,"low":33},"id":3},{"day":"F","record":{"high":61,"low":23},"normal":{"high":50,"low":38},"actual":{"high":50,"low":30},"id":4},{"day":"S","record":{"high":67,"low":20},"normal":{"high":50,"low":38},"forecast":{"high":{"high":53,"low":49},"low":{"high":40,"low":35}},"id":5},{"day":"S","record":{"high":63,"low":23},"normal":{"high":50,"low":39},"forecast":{"high":{"high":55,"low":49},"low":{"high":42,"low":37}},"id":6},{"day":"M","record":{"high":61,"low":26},"normal":{"high":51,"low":39},"forecast":{"high":{"high":53,"low":49},"low":{"high":43,"low":40}},"id":7},{"day":"T","record":{"high":61,"low":24},"normal":{"high":51,"low":39},"forecast":{"high":{"high":52,"low":46},"low":{"high":44,"low":40}},"id":8},{"day":"W","record":{"high":63,"low":20},"normal":{"high":51,"low":39},"forecast":{"high":{"high":53,"low":46},"low":{"high":43,"low":38}},"id":9}]
--------------------------------------------------------------------------------
/docs/data/wheat.json:
--------------------------------------------------------------------------------
1 | [
2 | {"year":"1565","wheat":41,"wages":5},
3 | {"year":"1570","wheat":45,"wages":5.05},
4 | {"year":"1575","wheat":42,"wages":5.08},
5 | {"year":"1580","wheat":49,"wages":5.12},
6 | {"year":"1585","wheat":41.5,"wages":5.15},
7 | {"year":"1590","wheat":47,"wages":5.25},
8 | {"year":"1595","wheat":64,"wages":5.54},
9 | {"year":"1600","wheat":27,"wages":5.61},
10 | {"year":"1605","wheat":33,"wages":5.69},
11 | {"year":"1610","wheat":32,"wages":5.78},
12 | {"year":"1615","wheat":33,"wages":5.94},
13 | {"year":"1620","wheat":35,"wages":6.01},
14 | {"year":"1625","wheat":33,"wages":6.12},
15 | {"year":"1630","wheat":45,"wages":6.22},
16 | {"year":"1635","wheat":33,"wages":6.3},
17 | {"year":"1640","wheat":39,"wages":6.37},
18 | {"year":"1645","wheat":53,"wages":6.45},
19 | {"year":"1650","wheat":42,"wages":6.5},
20 | {"year":"1655","wheat":40.5,"wages":6.6},
21 | {"year":"1660","wheat":46.5,"wages":6.75},
22 | {"year":"1665","wheat":32,"wages":6.8},
23 | {"year":"1670","wheat":37,"wages":6.9},
24 | {"year":"1675","wheat":43,"wages":7},
25 | {"year":"1680","wheat":35,"wages":7.3},
26 | {"year":"1685","wheat":27,"wages":7.6},
27 | {"year":"1690","wheat":40,"wages":8},
28 | {"year":"1695","wheat":50,"wages":8.5},
29 | {"year":"1700","wheat":30,"wages":9},
30 | {"year":"1705","wheat":32,"wages":10},
31 | {"year":"1710","wheat":44,"wages":11},
32 | {"year":"1715","wheat":33,"wages":11.75},
33 | {"year":"1720","wheat":29,"wages":12.5},
34 | {"year":"1725","wheat":39,"wages":13},
35 | {"year":"1730","wheat":26,"wages":13.3},
36 | {"year":"1735","wheat":32,"wages":13.6},
37 | {"year":"1740","wheat":27,"wages":14},
38 | {"year":"1745","wheat":27.5,"wages":14.5},
39 | {"year":"1750","wheat":31,"wages":15},
40 | {"year":"1755","wheat":35.5,"wages":15.7},
41 | {"year":"1760","wheat":31,"wages":16.5},
42 | {"year":"1765","wheat":43,"wages":17.6},
43 | {"year":"1770","wheat":47,"wages":18.5},
44 | {"year":"1775","wheat":44,"wages":19.5},
45 | {"year":"1780","wheat":46,"wages":21},
46 | {"year":"1785","wheat":42,"wages":23},
47 | {"year":"1790","wheat":47.5,"wages":25.5},
48 | {"year":"1795","wheat":76,"wages":27.5},
49 | {"year":"1800","wheat":79,"wages":28.5},
50 | {"year":"1805","wheat":81,"wages":29.5},
51 | {"year":"1810","wheat":99,"wages":30},
52 | {"year":"1815","wheat":78},
53 | {"year":"1820","wheat":54}
54 | ]
--------------------------------------------------------------------------------
/docs/group.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Vega Group Test
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/docs/image-output.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Vega Image Output Test
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
73 |
74 |
--------------------------------------------------------------------------------
/docs/prefacet.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Vega PreFacet Test
5 |
6 |
10 |
11 |
12 |
13 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/docs/spec.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Vega Spec Test
5 |
6 |
24 |
25 |
26 |
37 |
38 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/docs/spec/arc.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 400,
4 | "height": 400,
5 |
6 | "data": [
7 | {
8 | "name": "table",
9 | "values": [12, 23, 47, 6, 52, 19],
10 | "transform": [{"type": "pie", "field": "data"}]
11 | }
12 | ],
13 |
14 | "scales": [
15 | {
16 | "name": "r",
17 | "type": "sqrt",
18 | "domain": {"data": "table", "field": "data"},
19 | "zero": true,
20 | "range": [20, 100]
21 | }
22 | ],
23 |
24 | "marks": [
25 | {
26 | "type": "arc",
27 | "from": {"data": "table"},
28 | "encode": {
29 | "enter": {
30 | "x": {"field": {"group": "width"}, "mult": 0.5},
31 | "y": {"field": {"group": "height"}, "mult": 0.5},
32 | "startAngle": {"field": "startAngle"},
33 | "endAngle": {"field": "endAngle"},
34 | "innerRadius": {"value": 20},
35 | "outerRadius": {"scale": "r", "field": "data"},
36 | "stroke": {"value": "#fff"}
37 | },
38 | "update": {
39 | "fill": {"value": "#ccc"}
40 | },
41 | "hover": {
42 | "fill": {"value": "pink"}
43 | }
44 | }
45 | },
46 |
47 | {
48 | "type": "text",
49 | "from": {"data": "table"},
50 | "encode": {
51 | "enter": {
52 | "x": {"field": {"group": "width"}, "mult": 0.5},
53 | "y": {"field": {"group": "height"}, "mult": 0.5},
54 | "radius": {"scale": "r", "field": "data", "offset": 8},
55 | "theta": {"signal": "(datum.startAngle + datum.endAngle)/2"},
56 | "fill": {"value": "#000"},
57 | "align": {"value": "center"},
58 | "baseline": {"value": "middle"},
59 | "text": {"field": "data"}
60 | }
61 | }
62 | }
63 | ]
64 | }
--------------------------------------------------------------------------------
/docs/spec/area.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "table",
10 | "values": [
11 | {"u": 1, "v": 28}, {"u": 2, "v": 55},
12 | {"u": 3, "v": 43}, {"u": 4, "v": 91},
13 | {"u": 5, "v": 81}, {"u": 6, "v": 53},
14 | {"u": 7, "v": 19}, {"u": 8, "v": 87},
15 | {"u": 9, "v": 52}, {"u": 10, "v": 48},
16 | {"u": 11, "v": 24}, {"u": 12, "v": 49},
17 | {"u": 13, "v": 87}, {"u": 14, "v": 66},
18 | {"u": 15, "v": 17}, {"u": 16, "v": 27},
19 | {"u": 17, "v": 68}, {"u": 18, "v": 16},
20 | {"u": 19, "v": 49}, {"u": 20, "v": 15}
21 | ]
22 | }
23 | ],
24 |
25 | "scales": [
26 | {
27 | "name": "xscale",
28 | "type": "linear",
29 | "range": "width",
30 | "zero": false,
31 | "domain": {"data": "table", "field": "u"}
32 | },
33 | {
34 | "name": "yscale",
35 | "type": "linear",
36 | "range": "height",
37 | "nice": true,
38 | "zero": true,
39 | "domain": {"data": "table", "field": "v"}
40 | }
41 | ],
42 |
43 | "axes": [
44 | {"orient": "bottom", "scale": "xscale", "tickCount": 20},
45 | {"orient": "left", "scale": "yscale"}
46 | ],
47 |
48 | "marks": [
49 | {
50 | "type": "area",
51 | "from": {"data": "table"},
52 | "encode": {
53 | "enter": {
54 | "interpolate": {"value": "monotone"},
55 | "x": {"scale": "xscale", "field": "u"},
56 | "y": {"scale": "yscale", "field": "v"},
57 | "y2": {"scale": "yscale", "value": 0},
58 | "fill": {"value": "steelblue"}
59 | },
60 | "update": {
61 | "fillOpacity": {"value": 1}
62 | },
63 | "hover": {
64 | "fillOpacity": {"value": 0.5}
65 | }
66 | }
67 | }
68 | ]
69 | }
--------------------------------------------------------------------------------
/docs/spec/bar-hover-label.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 400,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "signals": [
8 | {
9 | "name": "label",
10 | "value": {"x": 0, "y": 0},
11 | "on": [
12 | {"events": "rect:mouseover", "update": "datum"},
13 | {"events": "rect:mouseout", "update": "{x:0, y:0}"}
14 | ]
15 | }
16 | ],
17 |
18 | "data": [
19 | {
20 | "name": "table",
21 | "values": [
22 | {"x": 1, "y": 28}, {"x": 2, "y": 55},
23 | {"x": 3, "y": 43}, {"x": 4, "y": 91},
24 | {"x": 5, "y": 81}, {"x": 6, "y": 53},
25 | {"x": 7, "y": 19}, {"x": 8, "y": 87},
26 | {"x": 9, "y": 52}, {"x": 10, "y": 48},
27 | {"x": 11, "y": 24}, {"x": 12, "y": 49},
28 | {"x": 13, "y": 87}, {"x": 14, "y": 66},
29 | {"x": 15, "y": 17}, {"x": 16, "y": 27},
30 | {"x": 17, "y": 68}, {"x": 18, "y": 16},
31 | {"x": 19, "y": 49}, {"x": 20, "y": 15}
32 | ]
33 | }
34 | ],
35 |
36 | "scales": [
37 | {
38 | "name": "xscale",
39 | "type": "band",
40 | "range": "width",
41 | "domain": {"data": "table", "field": "x"}
42 | },
43 | {
44 | "name": "yscale",
45 | "type": "linear",
46 | "range": "height",
47 | "domain": {"data": "table", "field": "y"},
48 | "nice": true
49 | }
50 | ],
51 |
52 | "axes": [
53 | {"orient": "bottom", "scale": "xscale"},
54 | {"orient": "left", "scale": "yscale"}
55 | ],
56 |
57 | "marks": [
58 | {
59 | "type": "rect",
60 | "from": {"data": "table"},
61 | "encode": {
62 | "enter": {
63 | "x": {"scale": "xscale", "field": "x", "offset":1},
64 | "width": {"scale": "xscale", "band": 1, "offset":-1},
65 | "y": {"scale": "yscale", "field": "y"},
66 | "y2": {"scale": "yscale", "value": 0}
67 | },
68 | "update": {
69 | "fill": [
70 | {"test": "datum === label", "value": "red"},
71 | {"value": "steelblue"}
72 | ]
73 | }
74 | }
75 | },
76 | {
77 | "type": "text",
78 | "encode": {
79 | "enter": {
80 | "align": {"value": "center"},
81 | "fill": {"value": "#333"}
82 | },
83 | "update": {
84 | "x": {"scale": "xscale", "signal": "label.x", "band": 0.5},
85 | "y": {"scale": "yscale", "signal": "label.y", "offset": -5},
86 | "text": {"signal": "label.y"},
87 | "fillOpacity": [
88 | {"test": "!label._id", "value": 0},
89 | {"value": 1}
90 | ]
91 | }
92 | }
93 | }
94 | ]
95 | }
96 |
--------------------------------------------------------------------------------
/docs/spec/bar-rangestep.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "height": 200,
4 | "padding": 5,
5 |
6 | "signals": [
7 | {
8 | "name": "step", "value": 20,
9 | "bind": {"type": "range", "min": 0, "max": 40, "step": 1}
10 | },
11 | {
12 | "name": "inner", "value": 0.1,
13 | "bind": {"type": "range", "min": 0, "max": 1}
14 | },
15 | {
16 | "name": "outer", "value": 0.1,
17 | "bind": {"type": "range", "min": 0, "max": 1}
18 | },
19 | {
20 | "name": "count", "value": 10,
21 | "bind": {"type": "range", "min": 0, "max": 20, "step": 1}
22 | },
23 | {
24 | "name": "round", "value": false,
25 | "bind": {"type": "checkbox"}
26 | },
27 | {
28 | "name": "width",
29 | "update": "ceil(step * bandspace(count, inner, outer))"
30 | }
31 | ],
32 |
33 | "data": [
34 | {
35 | "name": "table",
36 | "values": [
37 | {"u": 1, "v": 91}, {"u": 2, "v": 55},
38 | {"u": 3, "v": 43}, {"u": 4, "v": 28},
39 | {"u": 5, "v": 81}, {"u": 6, "v": 53},
40 | {"u": 7, "v": 19}, {"u": 8, "v": 87},
41 | {"u": 9, "v": 52}, {"u": 10, "v": 48},
42 | {"u": 11, "v": 24}, {"u": 12, "v": 49},
43 | {"u": 13, "v": 87}, {"u": 14, "v": 66},
44 | {"u": 15, "v": 17}, {"u": 16, "v": 27},
45 | {"u": 17, "v": 68}, {"u": 18, "v": 16},
46 | {"u": 19, "v": 49}, {"u": 20, "v": 15}
47 | ],
48 | "transform": [
49 | { "type": "filter", "expr": "datum.u <= count" }
50 | ]
51 | }
52 | ],
53 |
54 | "scales": [
55 | {
56 | "name": "xscale",
57 | "type": "band",
58 | "rangeStep": {"signal": "step"},
59 | "paddingInner": {"signal": "inner"},
60 | "paddingOuter": {"signal": "outer"},
61 | "round": {"signal": "round"},
62 | "domain": {"data": "table", "field": "u"}
63 | },
64 | {
65 | "name": "yscale",
66 | "type": "linear",
67 | "range": "height",
68 | "domain": [0, 100],
69 | "zero": true,
70 | "nice": true
71 | }
72 | ],
73 |
74 | "axes": [
75 | {"orient": "bottom", "scale": "xscale", "offset": 2},
76 | {"orient": "left", "scale": "yscale", "offset": 4}
77 | ],
78 |
79 | "marks": [
80 | {
81 | "type": "rect",
82 | "from": {"data": "table"},
83 | "encode": {
84 | "enter": {
85 | "y": {"scale": "yscale", "field": "v"},
86 | "y2": {"scale": "yscale", "value": 0},
87 | "fill": {"value": "steelblue"}
88 | },
89 | "update": {
90 | "x": {"scale": "xscale", "field": "u"},
91 | "width": {"scale": "xscale", "band": 1}
92 | }
93 | }
94 | }
95 | ]
96 | }
--------------------------------------------------------------------------------
/docs/spec/bar.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 400,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "table",
10 | "values": [
11 | {"u": 1, "v": 28}, {"u": 2, "v": 55},
12 | {"u": 3, "v": 43}, {"u": 4, "v": 91},
13 | {"u": 5, "v": 81}, {"u": 6, "v": 53},
14 | {"u": 7, "v": 19}, {"u": 8, "v": 87},
15 | {"u": 9, "v": 52}, {"u": 10, "v": 48},
16 | {"u": 11, "v": 24}, {"u": 12, "v": 49},
17 | {"u": 13, "v": 87}, {"u": 14, "v": 66},
18 | {"u": 15, "v": 17}, {"u": 16, "v": 27},
19 | {"u": 17, "v": 68}, {"u": 18, "v": 16},
20 | {"u": 19, "v": 49}, {"u": 20, "v": 15}
21 | ]
22 | }
23 | ],
24 |
25 | "scales": [
26 | {
27 | "name": "xscale",
28 | "type": "band",
29 | "range": "width",
30 | "domain": {"data": "table", "field": "u"}
31 | },
32 | {
33 | "name": "yscale",
34 | "type": "linear",
35 | "range": "height",
36 | "domain": {"data": "table", "field": "v"},
37 | "zero": true,
38 | "nice": true
39 | }
40 | ],
41 |
42 | "axes": [
43 | {"orient": "bottom", "scale": "xscale"},
44 | {"orient": "left", "scale": "yscale"}
45 | ],
46 |
47 | "marks": [
48 | {
49 | "type": "rect",
50 | "from": {"data": "table"},
51 | "encode": {
52 | "enter": {
53 | "x": {"scale": "xscale", "field": "u", "offset": 1},
54 | "width": {"scale": "xscale", "band": 1, "offset": -1},
55 | "y": {"scale": "yscale", "field": "v"},
56 | "y2": {"scale": "yscale", "value": 0}
57 | },
58 | "update": {
59 | "fill": {"value": "steelblue"}
60 | },
61 | "hover": {
62 | "fill": {"value": "red"}
63 | }
64 | }
65 | }
66 | ]
67 | }
--------------------------------------------------------------------------------
/docs/spec/barley.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 200,
4 | "padding": 5,
5 |
6 | "signals": [
7 | {"name": "offset", "value": 15},
8 | {"name": "cellHeight", "value": 100},
9 | {"name": "height", "update": "6 * (offset + cellHeight)"}
10 | ],
11 |
12 | "data": [
13 | {
14 | "name": "barley",
15 | "url": "data/barley.json"
16 | }
17 | ],
18 |
19 | "scales": [
20 | {
21 | "name": "gscale",
22 | "type": "band",
23 | "range": [0, {"signal": "height"}],
24 | "round": true,
25 | "domain": {
26 | "data": "barley",
27 | "field": "site",
28 | "sort": {
29 | "field": "yield",
30 | "op": "median",
31 | "order": "descending"
32 | }
33 | }
34 | },
35 | {
36 | "name": "xscale",
37 | "type": "linear",
38 | "nice": true,
39 | "range": "width",
40 | "round": true,
41 | "domain": {"data": "barley", "field": "yield"}
42 | },
43 | {
44 | "name": "cscale",
45 | "type": "ordinal",
46 | "scheme": "category10",
47 | "domain": {"data": "barley", "field": "year"}
48 | }
49 | ],
50 |
51 | "axes": [
52 | {"orient": "bottom", "scale": "xscale"}
53 | ],
54 |
55 | "legends": [
56 | {
57 | "stroke": "cscale",
58 | "title": "Year",
59 | "padding": 4,
60 | "encode": {
61 | "symbols": {
62 | "enter": {
63 | "strokeWidth": {"value": 2},
64 | "size": {"value": 50}
65 | }
66 | }
67 | }
68 | }
69 | ],
70 |
71 | "marks": [
72 | {
73 | "name": "site",
74 | "type": "group",
75 |
76 | "from": {
77 | "facet": {
78 | "data": "barley",
79 | "name": "sites",
80 | "groupby": "site"
81 | }
82 | },
83 |
84 | "encode": {
85 | "enter": {
86 | "y": {"scale": "gscale", "field": "site", "offset": {"signal": "offset"}},
87 | "height": {"signal": "cellHeight"},
88 | "width": {"signal": "width"},
89 | "stroke": {"value": "#ccc"}
90 | }
91 | },
92 |
93 | "scales": [
94 | {
95 | "name": "yscale",
96 | "type": "point",
97 | "range": [0, {"signal": "cellHeight"}],
98 | "padding": 1,
99 | "round": true,
100 | "domain": {
101 | "data": "barley",
102 | "field": "variety",
103 | "sort": {
104 | "field": "yield",
105 | "op": "median",
106 | "order": "descending"
107 | }
108 | }
109 | }
110 | ],
111 |
112 | "axes": [
113 | {
114 | "orient": "left",
115 | "scale": "yscale",
116 | "tickSize": 0,
117 | "domain": false,
118 | "grid": true,
119 | "encode": {
120 | "grid": {
121 | "enter": {"strokeDash": {"value": [3,3]}}
122 | }
123 | }
124 | },
125 | {
126 | "orient": "right",
127 | "scale": "yscale",
128 | "tickSize": 0,
129 | "domain": false
130 | }
131 | ],
132 |
133 | "marks": [
134 | {
135 | "type": "symbol",
136 | "from": {"data": "sites"},
137 | "encode": {
138 | "enter": {
139 | "x": {"scale": "xscale", "field": "yield"},
140 | "y": {"scale": "yscale", "field": "variety"},
141 | "stroke": {"scale": "cscale", "field": "year"},
142 | "strokeWidth": {"value": 2},
143 | "size": {"value": 50}
144 | }
145 | }
146 | }
147 | ]
148 | },
149 |
150 | {
151 | "type": "text",
152 | "from": {"data": "site"},
153 | "encode": {
154 | "enter": {
155 | "x": {"field": "width", "mult": 0.5},
156 | "y": {"field": "y"},
157 | "fontSize": {"value": 11},
158 | "fontWeight": {"value": "bold"},
159 | "text": {"field": "datum.site"},
160 | "align": {"value": "center"},
161 | "baseline": {"value": "bottom"},
162 | "fill": {"value": "#000"}
163 | }
164 | }
165 | }
166 | ]
167 | }
--------------------------------------------------------------------------------
/docs/spec/choropleth.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 960,
4 | "height": 500,
5 | "autosize": "none",
6 |
7 | "data": [
8 | {
9 | "name": "unemp",
10 | "url": "data/unemployment.tsv",
11 | "format": {"type": "tsv", "parse": "auto"}
12 | },
13 | {
14 | "name": "counties",
15 | "url": "data/us-10m.json",
16 | "format": {"type": "topojson", "feature": "counties"},
17 | "transform": [
18 | { "type": "lookup", "from": "unemp", "key": "id", "fields": ["id"], "as": ["unemp"] },
19 | { "type": "filter", "expr": "datum.unemp != null" }
20 | ]
21 | }
22 | ],
23 |
24 | "projections": [
25 | {
26 | "name": "projection",
27 | "type": "albersUsa"
28 | }
29 | ],
30 |
31 | "scales": [
32 | {
33 | "name": "color",
34 | "type": "quantize",
35 | "domain": [0, 0.15],
36 | "range": ["#f7fbff", "#deebf7", "#c6dbef", "#9ecae1", "#6baed6",
37 | "#4292c6", "#2171b5", "#08519c", "#08306b"]
38 | }
39 | ],
40 |
41 | "marks": [
42 | {
43 | "type": "shape",
44 | "from": {"data": "counties"},
45 | "encode": {
46 | "update": { "fill": {"scale": "color", "field": "unemp.rate"} },
47 | "hover": { "fill": {"value": "red"} }
48 | },
49 | "transform": [
50 | { "type": "geoshape", "projection": "projection" }
51 | ]
52 | }
53 | ]
54 | }
--------------------------------------------------------------------------------
/docs/spec/density.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 100,
5 | "padding": 5,
6 |
7 | "signals": [
8 | { "name": "bandwidth", "value": 0,
9 | "bind": {"type": "range", "min": 0, "max": 0.1, "step": 0.001} },
10 | { "name": "steps", "value": 100,
11 | "bind": {"type": "range", "min": 10, "max": 500, "step": 1} },
12 | { "name": "method", "value": "pdf",
13 | "bind": {"type": "radio", "options": ["pdf", "cdf"]} }
14 | ],
15 |
16 | "data": [
17 | {
18 | "name": "points",
19 | "url": "data/normal-2d.json"
20 | },
21 | {
22 | "name": "summary",
23 | "source": "points",
24 | "transform": [
25 | {
26 | "type": "aggregate",
27 | "fields": ["u", "u"],
28 | "ops": ["mean", "stdev"],
29 | "as": ["mean", "stdev"]
30 | }
31 | ]
32 | },
33 | {
34 | "name": "density",
35 | "source": "points",
36 | "transform": [
37 | {
38 | "type": "density",
39 | "extent": {"signal": "domain('xscale')"},
40 | "steps": {"signal": "steps"},
41 | "method": {"signal": "method"},
42 | "distribution": {
43 | "function": "kde",
44 | "field": "u",
45 | "bandwidth": {"signal": "bandwidth"}
46 | }
47 | }
48 | ]
49 | },
50 | {
51 | "name": "normal",
52 | "transform": [
53 | {
54 | "type": "density",
55 | "extent": {"signal": "domain('xscale')"},
56 | "steps": {"signal": "steps"},
57 | "method": {"signal": "method"},
58 | "distribution": {
59 | "function": "normal",
60 | "mean": {"signal": "tuples('summary')[0].mean"},
61 | "stdev": {"signal": "tuples('summary')[0].stdev"}
62 | }
63 | }
64 | ]
65 | }
66 | ],
67 |
68 | "scales": [
69 | {
70 | "name": "xscale",
71 | "type": "linear",
72 | "range": "width",
73 | "domain": {"data": "points", "field": "u"},
74 | "nice": true
75 | },
76 | {
77 | "name": "yscale",
78 | "type": "linear",
79 | "range": "height", "round": true,
80 | "domain": {
81 | "fields": [
82 | {"data": "density", "field": "density"},
83 | {"data": "normal", "field": "density"}
84 | ]
85 | }
86 | },
87 | {
88 | "name": "color",
89 | "type": "ordinal",
90 | "domain": ["Normal Estimate", "Kernel Density Estimate"],
91 | "range": ["#444", "steelblue"]
92 | }
93 | ],
94 |
95 | "axes": [
96 | {"orient": "bottom", "scale": "xscale", "zindex": 1}
97 | ],
98 |
99 | "legends": [
100 | {"orient": "top-left", "fill": "color", "offset": 0, "zindex": 1}
101 | ],
102 |
103 | "marks": [
104 | {
105 | "type": "area",
106 | "from": {"data": "density"},
107 | "encode": {
108 | "update": {
109 | "x": {"scale": "xscale", "field": "value"},
110 | "y": {"scale": "yscale", "field": "density"},
111 | "y2": {"scale": "yscale", "value": 0},
112 | "fill": {"signal": "scale('color', 'Kernel Density Estimate')"}
113 | }
114 | }
115 | },
116 | {
117 | "type": "line",
118 | "from": {"data": "normal"},
119 | "encode": {
120 | "update": {
121 | "x": {"scale": "xscale", "field": "value"},
122 | "y": {"scale": "yscale", "field": "density"},
123 | "stroke": {"signal": "scale('color', 'Normal Estimate')"},
124 | "strokeWidth": {"value": 2}
125 | }
126 | }
127 | },
128 | {
129 | "type": "rect",
130 | "from": {"data": "points"},
131 | "encode": {
132 | "enter": {
133 | "x": {"scale": "xscale", "field": "u"},
134 | "width": {"value": 1},
135 | "y": {"value": 25, "offset": {"signal": "height"}},
136 | "height": {"value": 5},
137 | "fill": {"value": "steelblue"},
138 | "fillOpacity": {"value": 0.4}
139 | }
140 | }
141 | }
142 | ]
143 | }
--------------------------------------------------------------------------------
/docs/spec/driving.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "height": 500,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "drive",
10 | "url": "data/driving.json"
11 | }
12 | ],
13 |
14 | "scales": [
15 | {
16 | "name": "x",
17 | "type": "linear",
18 | "domain": {"data": "drive", "field": "miles"},
19 | "range": "width",
20 | "nice": true,
21 | "zero": false,
22 | "round": true
23 | },
24 | {
25 | "name": "y",
26 | "type": "linear",
27 | "domain": {"data": "drive", "field": "gas"},
28 | "range": "height",
29 | "nice": true,
30 | "zero": false,
31 | "round": true
32 | },
33 | {
34 | "name": "align",
35 | "type": "ordinal",
36 | "domain": ["left", "right", "top", "bottom"],
37 | "range": ["right", "left", "center", "center"]
38 | },
39 | {
40 | "name": "base",
41 | "type": "ordinal",
42 | "domain": ["left", "right", "top", "bottom"],
43 | "range": ["middle", "middle", "bottom", "top"]
44 | },
45 | {
46 | "name": "dx",
47 | "type": "ordinal",
48 | "domain": ["left", "right", "top", "bottom"],
49 | "range": [-7, 6, 0, 0]
50 | },
51 | {
52 | "name": "dy",
53 | "type": "ordinal",
54 | "domain": ["left", "right", "top", "bottom"],
55 | "range": [1, 1, -5, 6]
56 | }
57 | ],
58 |
59 | "axes": [
60 | {
61 | "orient": "top",
62 | "scale": "x",
63 | "tickCount": 5,
64 | "tickSize": 0,
65 | "grid": true,
66 | "domain": false,
67 | "encode": {
68 | "domain": {
69 | "enter": { "stroke": {"value": "transparent"} }
70 | },
71 | "labels": {
72 | "enter": {
73 | "align": {"value": "left"},
74 | "baseline": {"value": "top"},
75 | "fontSize": {"value": 12},
76 | "fontWeight": {"value": "bold"}
77 | }
78 | }
79 | }
80 | },
81 | {
82 | "orient": "left",
83 | "scale": "y",
84 | "tickCount": 5,
85 | "tickSize": 0,
86 | "grid": true,
87 | "domain": false,
88 | "format": "$0.2f",
89 | "encode": {
90 | "domain": {
91 | "enter": {"stroke": {"value": "transparent"}}
92 | },
93 | "labels": {
94 | "enter": {
95 | "align": {"value": "left"},
96 | "baseline": {"value": "bottom"},
97 | "fontSize": {"value": 12},
98 | "fontWeight": {"value": "bold"}
99 | }
100 | }
101 | }
102 | }
103 | ],
104 |
105 | "marks": [
106 | {
107 | "type": "line",
108 | "from": {"data": "drive"},
109 | "encode": {
110 | "enter": {
111 | "interpolate": {"value": "cardinal"},
112 | "x": {"scale": "x", "field": "miles"},
113 | "y": {"scale": "y", "field": "gas"},
114 | "stroke": {"value": "#000"},
115 | "strokeWidth": {"value": 3}
116 | }
117 | }
118 | },
119 | {
120 | "type": "symbol",
121 | "from": {"data": "drive"},
122 | "encode": {
123 | "enter": {
124 | "x": {"scale": "x", "field": "miles"},
125 | "y": {"scale": "y", "field": "gas"},
126 | "fill": {"value": "#fff"},
127 | "stroke": {"value": "#000"},
128 | "strokeWidth": {"value": 1},
129 | "size": {"value": 49}
130 | }
131 | }
132 | },
133 | {
134 | "type": "text",
135 | "from": {"data": "drive"},
136 | "encode": {
137 | "enter": {
138 | "x": {"scale": "x", "field": "miles"},
139 | "y": {"scale": "y", "field": "gas"},
140 | "dx": {"scale": "dx", "field": "side"},
141 | "dy": {"scale": "dy", "field": "side"},
142 | "fill": {"value": "#000"},
143 | "text": {"field": "year"},
144 | "align": {"scale": "align", "field": "side"},
145 | "baseline": {"scale": "base", "field": "side"}
146 | }
147 | }
148 | }
149 | ]
150 | }
--------------------------------------------------------------------------------
/docs/spec/error.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 400,
4 | "height": 100,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "aggregate",
10 | "values": [
11 | {"label": "Category A", "mean": 1, "lo": 0, "hi": 2},
12 | {"label": "Category B", "mean": 2, "lo": 1.5, "hi": 2.5},
13 | {"label": "Category C", "mean": 3, "lo": 1.7, "hi": 4.3},
14 | {"label": "Category D", "mean": 4, "lo": 3, "hi": 5},
15 | {"label": "Category E", "mean": 5, "lo": 4.1, "hi": 5.9}
16 | ]
17 | }
18 | ],
19 |
20 | "scales": [
21 | {
22 | "name": "y",
23 | "type": "band",
24 | "range": "height",
25 | "domain": {"data": "aggregate", "field": "label"},
26 | "zero": true
27 | },
28 | {
29 | "name": "x",
30 | "type": "linear",
31 | "domain": {"data": "aggregate", "field": "hi"},
32 | "range": [100, 400],
33 | "nice": true, "zero": true
34 | }
35 | ],
36 |
37 | "axes": [
38 | {"orient": "bottom", "scale": "x", "tickCount": 6}
39 | ],
40 |
41 | "marks": [
42 | {
43 | "type": "text",
44 | "from": {"data": "aggregate"},
45 | "encode": {
46 | "enter": {
47 | "x": {"value": 0},
48 | "y": {"scale": "y", "field": "label"},
49 | "baseline": {"value": "middle"},
50 | "fill": {"value": "#000"},
51 | "text": {"field": "label"},
52 | "font": {"value": "Helvetica Neue"},
53 | "fontSize": {"value": 13}
54 | }
55 | }
56 | },
57 | {
58 | "type": "rect",
59 | "from": {"data": "aggregate"},
60 | "encode": {
61 | "enter": {
62 | "x": {"scale": "x", "field": "lo"},
63 | "x2": {"scale": "x", "field": "hi"},
64 | "y": {"scale": "y", "field": "label", "offset": -1},
65 | "height": {"value": 1},
66 | "fill": {"value": "#888"}
67 | }
68 | }
69 | },
70 | {
71 | "type": "symbol",
72 | "from": {"data": "aggregate"},
73 | "encode": {
74 | "enter": {
75 | "x": {"scale": "x", "field": "mean"},
76 | "y": {"scale": "y", "field": "label"},
77 | "size": {"value": 40},
78 | "fill": {"value": "#000"}
79 | }
80 | }
81 | }
82 | ]
83 | }
--------------------------------------------------------------------------------
/docs/spec/force-beeswarm.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "height": 100,
5 | "padding": {"left": 5, "right": 5, "top": 0, "bottom": 20},
6 | "autosize": "none",
7 |
8 | "signals": [
9 | { "name": "cx", "update": "width / 2" },
10 | { "name": "cy", "update": "height / 2" },
11 | { "name": "radius", "value": 8, "bind": {"type": "range", "min": 2, "max": 15, "step": 1} },
12 | { "name": "collide", "value": 1, "bind": {"type": "range", "min": 1, "max": 10, "step": 1} },
13 | { "name": "gravityX", "value": 0.2, "bind": {"type": "range", "min": 0, "max": 1} },
14 | { "name": "gravityY", "value": 0.1, "bind": {"type": "range", "min": 0, "max": 1} },
15 | { "name": "static", "value": true, "bind": {"type": "checkbox"} }
16 | ],
17 |
18 | "data": [
19 | {
20 | "name": "people",
21 | "url": "data/miserables.json",
22 | "format": {"type": "json", "property": "nodes"}
23 | }
24 | ],
25 |
26 | "scales": [
27 | {
28 | "name": "xscale",
29 | "type": "band",
30 | "domain": {
31 | "data": "people",
32 | "field": "group",
33 | "sort": true
34 | },
35 | "range": "width"
36 | },
37 | {
38 | "name": "color",
39 | "type": "ordinal",
40 | "scheme": "category20c"
41 | }
42 | ],
43 |
44 | "axes": [
45 | { "orient": "bottom", "scale": "xscale" }
46 | ],
47 |
48 | "marks": [
49 | {
50 | "name": "nodes",
51 | "type": "symbol",
52 | "from": {"data": "people"},
53 | "encode": {
54 | "enter": {
55 | "fill": {"scale": "color", "field": "group"},
56 | "xfocus": {"scale": "xscale", "field": "group", "band": 0.5},
57 | "yfocus": {"signal": "cy"}
58 | },
59 | "update": {
60 | "size": {"signal": "pow(2 * radius, 2)"},
61 | "stroke": {"value": "white"},
62 | "strokeWidth": {"value": 1},
63 | "zindex": {"value": 0}
64 | },
65 | "hover": {
66 | "stroke": {"value": "purple"},
67 | "strokeWidth": {"value": 3},
68 | "zindex": {"value": 1}
69 | }
70 | },
71 | "transform": [
72 | {
73 | "type": "force",
74 | "iterations": 300,
75 | "static": {"signal": "static"},
76 | "forces": [
77 | {"force": "collide", "iterations": {"signal": "collide"}, "radius": {"signal": "radius"}},
78 | {"force": "x", "x": "xfocus", "strength": {"signal": "gravityX"}},
79 | {"force": "y", "y": "yfocus", "strength": {"signal": "gravityY"}}
80 | ]
81 | }
82 | ]
83 | }
84 | ]
85 | }
86 |
--------------------------------------------------------------------------------
/docs/spec/force-network.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "height": 500,
5 | "padding": 0,
6 | "autosize": "none",
7 |
8 | "signals": [
9 | { "name": "cx", "update": "width / 2" },
10 | { "name": "cy", "update": "height / 2" },
11 | { "name": "nodeRadius", "value": 8,
12 | "bind": {"type": "range", "min": 1, "max": 50, "step": 1} },
13 | { "name": "nodeCharge", "value": -30,
14 | "bind": {"type": "range", "min":-100, "max": 10, "step": 1} },
15 | { "name": "linkDistance", "value": 30,
16 | "bind": {"type": "range", "min": 5, "max": 100, "step": 1} },
17 | { "name": "static", "value": true,
18 | "bind": {"type": "checkbox"} },
19 | {
20 | "description": "State variable for active node fix status.",
21 | "name": "fix", "value": 0,
22 | "on": [
23 | {
24 | "events": "symbol:mouseout[!event.buttons], window:mouseup",
25 | "update": "0"
26 | },
27 | {
28 | "events": "symbol:mouseover",
29 | "update": "fix || 1"
30 | },
31 | {
32 | "events": "[symbol:mousedown, window:mouseup] > window:mousemove!",
33 | "update": "2", "force": true
34 | }
35 | ]
36 | },
37 | {
38 | "description": "Graph node most recently interacted with.",
39 | "name": "node", "value": null,
40 | "on": [
41 | {
42 | "events": "symbol:mouseover",
43 | "update": "fix === 1 ? item() : node"
44 | }
45 | ]
46 | },
47 | {
48 | "description": "Flag to restart Force simulation upon data changes.",
49 | "name": "restart", "value": false,
50 | "on": [
51 | {"events": {"signal": "fix"}, "update": "fix > 1"}
52 | ]
53 | }
54 | ],
55 |
56 | "data": [
57 | {
58 | "name": "node-data",
59 | "url": "data/miserables.json",
60 | "format": {"type": "json", "property": "nodes"}
61 | },
62 | {
63 | "name": "link-data",
64 | "url": "data/miserables.json",
65 | "format": {"type": "json", "property": "links"}
66 | }
67 | ],
68 |
69 | "scales": [
70 | {
71 | "name": "color",
72 | "type": "ordinal",
73 | "scheme": "category20c"
74 | }
75 | ],
76 |
77 | "marks": [
78 | {
79 | "name": "nodes",
80 | "type": "symbol",
81 | "zindex": 1,
82 |
83 | "from": {"data": "node-data"},
84 | "on": [
85 | {
86 | "trigger": "fix",
87 | "modify": "node",
88 | "values": "fix === 1 ? {fx:node.x, fy:node.y} : {fx:x(), fy:y()}"
89 | },
90 | {
91 | "trigger": "!fix",
92 | "modify": "node", "values": "{fx: null, fy: null}"
93 | }
94 | ],
95 |
96 | "encode": {
97 | "enter": {
98 | "fill": {"scale": "color", "field": "group"},
99 | "stroke": {"value": "white"}
100 | },
101 | "update": {
102 | "size": {"signal": "2 * nodeRadius * nodeRadius"},
103 | "cursor": {"value": "pointer"}
104 | }
105 | },
106 |
107 | "transform": [
108 | {
109 | "type": "force",
110 | "iterations": 300,
111 | "restart": {"signal": "restart"},
112 | "static": {"signal": "static"},
113 | "forces": [
114 | {"force": "center", "x": {"signal": "cx"}, "y": {"signal": "cy"}},
115 | {"force": "collide", "radius": {"signal": "nodeRadius"}},
116 | {"force": "nbody", "strength": {"signal": "nodeCharge"}},
117 | {"force": "link", "links": "link-data", "distance": {"signal": "linkDistance"}}
118 | ]
119 | }
120 | ]
121 | },
122 | {
123 | "type": "path",
124 | "from": {"data": "link-data"},
125 | "interactive": false,
126 | "encode": {
127 | "update": {
128 | "stroke": {"value": "#ccc"},
129 | "strokeWidth": {"value": 0.5}
130 | }
131 | },
132 | "transform": [
133 | {
134 | "type": "linkpath", "shape": "line",
135 | "sourceX": "datum.source.x", "sourceY": "datum.source.y",
136 | "targetX": "datum.target.x", "targetY": "datum.target.y"
137 | }
138 | ]
139 | }
140 | ]
141 | }
142 |
--------------------------------------------------------------------------------
/docs/spec/gradient.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 300,
4 | "height": 15,
5 | "padding": 5,
6 |
7 | "scales": [
8 | {
9 | "name": "color",
10 | "type": "sequential",
11 | "scheme": "viridis",
12 | "domain": [0, 100]
13 | }
14 | ],
15 |
16 | "marks": [
17 | {
18 | "type": "rect",
19 | "encode": {
20 | "update": {
21 | "width": {"signal": "width"},
22 | "height": {"signal": "height"},
23 | "fill": {"gradient": "color"}
24 | }
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/docs/spec/grouped-bar.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 300,
4 | "height": 240,
5 |
6 | "data": [
7 | {
8 | "name": "table",
9 | "values": [
10 | {"category":"A", "position":0, "value":0.1},
11 | {"category":"A", "position":1, "value":0.6},
12 | {"category":"A", "position":2, "value":0.9},
13 | {"category":"A", "position":3, "value":0.4},
14 | {"category":"B", "position":0, "value":0.7},
15 | {"category":"B", "position":1, "value":0.2},
16 | {"category":"B", "position":2, "value":1.1},
17 | {"category":"B", "position":3, "value":0.8},
18 | {"category":"C", "position":0, "value":0.6},
19 | {"category":"C", "position":1, "value":0.1},
20 | {"category":"C", "position":2, "value":0.2},
21 | {"category":"C", "position":3, "value":0.7}
22 | ]
23 | }
24 | ],
25 |
26 | "scales": [
27 | {
28 | "name": "yscale",
29 | "type": "band",
30 | "domain": {"data": "table", "field": "category"},
31 | "range": "height",
32 | "padding": 0.2
33 | },
34 | {
35 | "name": "xscale",
36 | "type": "linear",
37 | "domain": {"data": "table", "field": "value"},
38 | "range": "width",
39 | "round": true,
40 | "zero": true,
41 | "nice": true
42 | },
43 | {
44 | "name": "color",
45 | "type": "ordinal",
46 | "domain": {"data": "table", "field": "position"},
47 | "scheme": "category20"
48 | }
49 | ],
50 |
51 | "axes": [
52 | {"orient": "left", "scale": "yscale", "tickSize": 0, "labelPadding": 4, "zindex": 1},
53 | {"orient": "bottom", "scale": "xscale"}
54 | ],
55 |
56 | "marks": [
57 | {
58 | "type": "group",
59 |
60 | "from": {
61 | "facet": {
62 | "data": "table",
63 | "name": "facet",
64 | "groupby": "category"
65 | }
66 | },
67 |
68 | "encode": {
69 | "enter": {
70 | "y": {"scale": "yscale", "field": "category"}
71 | }
72 | },
73 |
74 | "signals": [
75 | {"name": "height", "update": "bandwidth('yscale')"}
76 | ],
77 |
78 | "scales": [
79 | {
80 | "name": "pos",
81 | "type": "band",
82 | "range": "height",
83 | "domain": {"data": "facet", "field": "position"}
84 | }
85 | ],
86 |
87 | "marks": [
88 | {
89 | "name": "bars",
90 | "from": {"data": "facet"},
91 | "type": "rect",
92 | "encode": {
93 | "enter": {
94 | "y": {"scale": "pos", "field": "position"},
95 | "height": {"scale": "pos", "band": 1},
96 | "x": {"scale": "xscale", "field": "value"},
97 | "x2": {"scale": "xscale", "value": 0},
98 | "fill": {"scale": "color", "field": "position"}
99 | }
100 | }
101 | },
102 | {
103 | "type": "text",
104 | "from": {"data": "bars"},
105 | "encode": {
106 | "enter": {
107 | "x": {"field": "x2", "offset": -5},
108 | "y": {"field": "y", "offset": {"field": "height", "mult": 0.5}},
109 | "fill": {"value": "white"},
110 | "align": {"value": "right"},
111 | "baseline": {"value": "middle"},
112 | "text": {"field": "datum.value"}
113 | }
114 | }
115 | }
116 | ]
117 | }
118 | ]
119 | }
--------------------------------------------------------------------------------
/docs/spec/heatmap-lines.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "padding": 5,
5 |
6 | "signals": [
7 | {"name": "rangeStep", "value": 25},
8 | {"name": "height", "update": "rangeStep * 24"}
9 | ],
10 |
11 | "data": [
12 | {
13 | "name": "temperature",
14 | "url": "data/seattle-temps.csv",
15 | "format": {"type": "csv", "parse": {"temp": "number", "date": "date"}},
16 | "transform": [
17 | {"type": "formula", "as": "hour", "expr": "hours(datum.date)"},
18 | { "type": "formula", "as": "date",
19 | "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))"}
20 | ]
21 | }
22 | ],
23 |
24 | "scales": [
25 | {
26 | "name": "row",
27 | "type": "band",
28 | "domain": [
29 | 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
30 | 0, 1, 2, 3, 4, 5
31 | ],
32 | "rangeStep": {"signal": "rangeStep"}
33 | },
34 | {
35 | "name": "x",
36 | "type": "time",
37 | "domain": {"data": "temperature", "field": "date"},
38 | "range": "width"
39 | },
40 | {
41 | "name": "y",
42 | "type": "linear", "zero": false,
43 | "domain": {"data": "temperature", "field": "temp"},
44 | "range": [{"signal": "rangeStep"}, 1]
45 | }
46 | ],
47 |
48 | "axes": [
49 | {"orient": "bottom", "scale": "x", "domain": false, "title": "Month"},
50 | {
51 | "orient": "left", "scale": "row", "domain": false, "title": "Hour",
52 | "tickSize": 0,
53 | "encode": {
54 | "labels": {
55 | "update": {
56 | "text": {"signal": "datum.value === 0 ? 'Midnight' : datum.value === 12 ? 'Noon' : datum.value < 12 ? datum.value + ':00 am' : (datum.value - 12) + ':00 pm'"}
57 | }
58 | }
59 | }
60 | }
61 | ],
62 |
63 | "marks": [
64 | {
65 | "type": "group",
66 | "from": {
67 | "facet": {
68 | "name": "hour",
69 | "data": "temperature",
70 | "groupby": "hour"
71 | }
72 | },
73 | "encode": {
74 | "enter": {
75 | "x": {"value": 0},
76 | "y": {"scale": "row", "field": "hour"},
77 | "width": {"signal": "width"},
78 | "height": {"signal": "rangeStep"}
79 | }
80 | },
81 | "marks": [
82 | {
83 | "type": "area",
84 | "from": {"data": "hour"},
85 | "encode": {
86 | "enter": {
87 | "x": {"scale": "x", "field": "date"},
88 | "y": {"scale": "y", "field": "temp"},
89 | "y2": {"signal": "rangeStep"}
90 | }
91 | }
92 | }
93 | ]
94 | },
95 | {
96 | "type": "text",
97 | "encode": {
98 | "enter": {
99 | "x": {"value": 0},
100 | "y": {"value": -4},
101 | "text": {"value": "Seattle Annual Temperatures"},
102 | "baseline": {"value": "bottom"},
103 | "fontSize": {"value": 14},
104 | "fontWeight": {"value": "bold"},
105 | "fill": {"value": "black"}
106 | }
107 | }
108 | }
109 | ]
110 | }
--------------------------------------------------------------------------------
/docs/spec/heatmap.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "height": 500,
5 | "padding": 5,
6 |
7 | "signals": [
8 | {
9 | "name": "palette", "value": "Plasma",
10 | "bind": {
11 | "type": "select",
12 | "options": [
13 | "Viridis",
14 | "Magma",
15 | "Inferno",
16 | "Plasma",
17 | "Cubehelix",
18 | "Rainbow",
19 | "Warm",
20 | "Cool",
21 | "Blues",
22 | "Greens",
23 | "Greys",
24 | "Purples",
25 | "Reds",
26 | "Oranges",
27 | "BrownBlueGreen",
28 | "PurpleGreen",
29 | "PinkYellowGreen",
30 | "PurpleOrange",
31 | "RedBlue",
32 | "RedGrey",
33 | "RedYellowBlue",
34 | "RedYellowGreen",
35 | "BlueGreen",
36 | "BluePurple",
37 | "GreenBlue",
38 | "OrangeRed",
39 | "PurpleBlueGreen",
40 | "PurpleBlue",
41 | "PurpleRed",
42 | "RedPurple",
43 | "YellowGreenBlue",
44 | "YellowGreen",
45 | "YellowOrangeBrown",
46 | "YellowOrangeRed"
47 | ]
48 | }
49 | },
50 | {
51 | "name": "reverse", "value": false, "bind": {"type": "checkbox"}
52 | }
53 | ],
54 |
55 | "data": [
56 | {
57 | "name": "temperature",
58 | "url": "data/seattle-temps.csv",
59 | "format": {"type": "csv", "parse": {"temp": "number", "date": "date"}},
60 | "transform": [
61 | {"type": "formula", "as": "hour", "expr": "hours(datum.date)"},
62 | { "type": "formula", "as": "date",
63 | "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))"}
64 | ]
65 | }
66 | ],
67 |
68 | "scales": [
69 | {
70 | "name": "x",
71 | "type": "time",
72 | "domain": {"data": "temperature", "field": "date"},
73 | "range": "width"
74 | },
75 | {
76 | "name": "y",
77 | "type": "band",
78 | "domain": [
79 | 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
80 | 0, 1, 2, 3, 4, 5
81 | ],
82 | "range": "height"
83 | },
84 | {
85 | "name": "color",
86 | "type": "sequential",
87 | "scheme": {"signal": "palette"},
88 | "domain": {"data": "temperature", "field": "temp"},
89 | "reverse": {"signal": "reverse"},
90 | "zero": false, "nice": false
91 | }
92 | ],
93 |
94 | "axes": [
95 | {"orient": "bottom", "scale": "x", "domain": false, "title": "Month"},
96 | {
97 | "orient": "left", "scale": "y", "domain": false, "title": "Hour",
98 | "encode": {
99 | "labels": {
100 | "update": {
101 | "text": {"signal": "datum.value === 0 ? 'Midnight' : datum.value === 12 ? 'Noon' : datum.value < 12 ? datum.value + ':00 am' : (datum.value - 12) + ':00 pm'"}
102 | }
103 | }
104 | }
105 | }
106 | ],
107 |
108 | "legends": [
109 | {"fill": "color", "type": "gradient", "title": "Avg. Temp (°F)"}
110 | ],
111 |
112 | "marks": [
113 | {
114 | "type": "rect",
115 | "from": {"data": "temperature"},
116 | "encode": {
117 | "enter": {
118 | "x": {"scale": "x", "field": "date"},
119 | "width": {"value": 5},
120 | "y": {"scale": "y", "field": "hour"},
121 | "height": {"scale": "y", "band": 1}
122 | },
123 | "update": {
124 | "fill": {"scale": "color", "field": "temp"}
125 | }
126 | }
127 | },
128 | {
129 | "type": "text",
130 | "encode": {
131 | "enter": {
132 | "x": {"value": 0},
133 | "y": {"value": -4},
134 | "text": {"value": "Seattle Annual Temperatures"},
135 | "baseline": {"value": "bottom"},
136 | "fontSize": {"value": 14},
137 | "fontWeight": {"value": "bold"},
138 | "fill": {"value": "black"}
139 | }
140 | }
141 | }
142 | ]
143 | }
--------------------------------------------------------------------------------
/docs/spec/histogram.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 100,
5 | "padding": 5,
6 |
7 | "signals": [
8 | { "name": "binOffset", "value": 0,
9 | "bind": {"type": "range", "min": -0.1, "max": 0.1} },
10 | { "name": "binStep", "value": 0.1,
11 | "bind": {"type": "range", "min": 0.001, "max": 0.4, "step": 0.001} },
12 | { "name": "extent", "update": "[binOffset, 2+binOffset]" }
13 | ],
14 |
15 | "data": [
16 | {
17 | "name": "points",
18 | "url": "data/normal-2d.json"
19 | },
20 | {
21 | "name": "binned",
22 | "source": "points",
23 | "transform": [
24 | {
25 | "type": "bin", "field": "u",
26 | "extent": {"signal": "extent"},
27 | "step": {"signal": "binStep"},
28 | "nice": false
29 | },
30 | {
31 | "type": "aggregate",
32 | "key": "bin0", "groupby": ["bin0", "bin1"],
33 | "fields": ["bin0"], "ops": ["count"], "as": ["count"]
34 | }
35 | ]
36 | }
37 | ],
38 |
39 | "scales": [
40 | {
41 | "name": "xscale",
42 | "type": "linear",
43 | "range": "width",
44 | "domain": [-1, 1]
45 | },
46 | {
47 | "name": "yscale",
48 | "type": "linear",
49 | "range": "height", "round": true,
50 | "domain": {"data": "binned", "field": "count"},
51 | "zero": true, "nice": true
52 | }
53 | ],
54 |
55 | "axes": [
56 | {"orient": "bottom", "scale": "xscale", "zindex": 1},
57 | {"orient": "left", "scale": "yscale", "tickCount": 5, "zindex": 1}
58 | ],
59 |
60 | "marks": [
61 | {
62 | "type": "rect",
63 | "from": {"data": "binned"},
64 | "encode": {
65 | "update": {
66 | "x": {"scale": "xscale", "field": "bin0"},
67 | "x2": {"scale": "xscale", "field": "bin1",
68 | "offset": {"signal": "binStep > 0.02 ? -0.5 : 0"}},
69 | "y": {"scale": "yscale", "field": "count"},
70 | "y2": {"scale": "yscale", "value": 0},
71 | "fill": {"value": "steelblue"}
72 | },
73 | "hover": { "fill": {"value": "firebrick"} }
74 | }
75 | },
76 | {
77 | "type": "rect",
78 | "from": {"data": "points"},
79 | "encode": {
80 | "enter": {
81 | "x": {"scale": "xscale", "field": "u"},
82 | "width": {"value": 1},
83 | "y": {"value": 25, "offset": {"signal": "height"}},
84 | "height": {"value": 5},
85 | "fill": {"value": "steelblue"},
86 | "fillOpacity": {"value": 0.4}
87 | }
88 | }
89 | }
90 | ]
91 | }
--------------------------------------------------------------------------------
/docs/spec/horizon.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 50,
5 |
6 | "signals": [
7 | {
8 | "name": "layers",
9 | "value": 2,
10 | "on": [{"events": "mousedown!", "update": "1 + (layers % 4)"}]
11 | },
12 | {
13 | "name": "vheight",
14 | "update": "height * layers"
15 | },
16 | {
17 | "name": "opacity",
18 | "update": "pow(layers, -2/3)"
19 | }
20 | ],
21 |
22 | "data": [
23 | {
24 | "name": "layer_indices",
25 | "values": [0, 1, 2, 3],
26 | "transform": [
27 | {"type": "filter", "expr": "datum.data < layers"},
28 | {"type": "formula", "expr": "datum.data * -height", "as": "offset"}
29 | ]
30 | },
31 | {
32 | "name": "table",
33 | "values": [
34 | {"x": 1, "y": 28}, {"x": 2, "y": 55},
35 | {"x": 3, "y": 43}, {"x": 4, "y": 91},
36 | {"x": 5, "y": 81}, {"x": 6, "y": 53},
37 | {"x": 7, "y": 19}, {"x": 8, "y": 87},
38 | {"x": 9, "y": 52}, {"x": 10, "y": 48},
39 | {"x": 11, "y": 24}, {"x": 12, "y": 49},
40 | {"x": 13, "y": 87}, {"x": 14, "y": 66},
41 | {"x": 15, "y": 17}, {"x": 16, "y": 27},
42 | {"x": 17, "y": 68}, {"x": 18, "y": 16},
43 | {"x": 19, "y": 49}, {"x": 20, "y": 15}
44 | ]
45 | }
46 | ],
47 |
48 | "scales": [
49 | {
50 | "name": "x",
51 | "type": "linear",
52 | "range": "width",
53 | "zero": false, "round": true,
54 | "domain": {"data": "table", "field": "x"}
55 | },
56 | {
57 | "name": "y",
58 | "type": "linear",
59 | "range": [{"signal":"vheight"}, 0],
60 | "nice": true, "zero": true,
61 | "domain": {"data": "table", "field": "y"}
62 | }
63 | ],
64 |
65 | "axes": [
66 | {"orient": "bottom", "scale": "x", "tickCount": 20}
67 | ],
68 |
69 | "marks": [
70 | {
71 | "type": "group",
72 | "encode": {
73 | "update": {
74 | "width": {"field": {"group": "width"}},
75 | "height": {"field": {"group": "height"}},
76 | "clip": {"value": true}
77 | }
78 | },
79 | "marks": [
80 | {
81 | "type": "group",
82 | "from": {"data": "layer_indices"},
83 | "encode": {
84 | "update": {
85 | "y": {"field": "offset"}
86 | }
87 | },
88 | "marks": [
89 | {
90 | "type": "area",
91 | "from": {"data": "table"},
92 | "encode": {
93 | "enter": {
94 | "interpolate": {"value": "monotone"},
95 | "x": {"scale": "x", "field": "x"},
96 | "fill": {"value": "steelblue"}
97 | },
98 | "update": {
99 | "y": {"scale": "y", "field": "y"},
100 | "y2": {"scale": "y", "value": 0},
101 | "fillOpacity": {"signal": "opacity"}
102 | }
103 | }
104 | }
105 | ]
106 | }
107 | ]
108 | }
109 | ]
110 | }
--------------------------------------------------------------------------------
/docs/spec/images.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 200,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "data",
10 | "values": [
11 | {"x": 0.5, "y": 0.5, "img": "data/ffox.png"},
12 | {"x": 1.5, "y": 1.5, "img": "data/gimp.png"},
13 | {"x": 2.5, "y": 2.5, "img": "data/7zip.png"}
14 | ]
15 | }
16 | ],
17 |
18 | "scales": [
19 | {
20 | "name": "x",
21 | "type": "linear",
22 | "domain": [0, 3],
23 | "range": "width"
24 | },
25 | {
26 | "name": "y",
27 | "type": "linear",
28 | "domain": [0, 3],
29 | "range": "height"
30 | }
31 | ],
32 |
33 | "axes": [
34 | {"orient": "bottom", "scale": "x", "tickCount": 5},
35 | {"orient": "left", "scale": "y", "tickCount": 5}
36 | ],
37 |
38 | "marks": [
39 | {
40 | "type": "image",
41 | "from": {"data": "data"},
42 | "encode": {
43 | "enter": {
44 | "url": {"field": "img"},
45 | "width": {"value": 50},
46 | "height": {"value": 50},
47 | "x": {"scale": "x", "field": "x"},
48 | "y": {"scale": "y", "field": "y"},
49 | "align": {"value": "center"},
50 | "baseline": {"value": "middle"}
51 | },
52 | "update": {
53 | "opacity": {"value": 1.0}
54 | },
55 | "hover": {
56 | "opacity": {"value": 0.5}
57 | }
58 | }
59 | }
60 | ]
61 | }
--------------------------------------------------------------------------------
/docs/spec/jobs.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 800,
4 | "height": 500,
5 | "padding": 5,
6 |
7 | "signals": [
8 | {
9 | "name": "sex", "value": "all",
10 | "bind": {"type": "radio", "options": ["men", "women", "all"]}
11 | },
12 | {
13 | "name": "query", "value": "",
14 | "on": [
15 | {"events": "area:click!", "update": "datum.job"},
16 | {"events": "dblclick!", "update": "''"}
17 | ],
18 | "bind": {"type": "text", "placeholder": "search", "autocomplete": "off"}
19 | }
20 | ],
21 |
22 | "data": [
23 | {
24 | "name": "jobs",
25 | "url": "data/jobs.json",
26 | "transform": [
27 | {
28 | "type": "filter",
29 | "expr": "(sex === 'all' || datum.sex === sex) && (!query || test(regexp(query,'i'), datum.job))"
30 | },
31 | {
32 | "type": "stack",
33 | "field": "perc",
34 | "groupby": ["year"],
35 | "sort": {
36 | "field": ["job", "sex"],
37 | "order": ["descending", "descending"]
38 | }
39 | }
40 | ]
41 | },
42 | {
43 | "name": "series",
44 | "source": "jobs",
45 | "transform": [
46 | {
47 | "type": "aggregate",
48 | "groupby": ["job", "sex"],
49 | "fields": ["perc", "perc"],
50 | "ops": ["sum", "argmax"],
51 | "as": ["sum", "argmax"]
52 | }
53 | ]
54 | },
55 | {
56 | "name": "years",
57 | "source": "jobs",
58 | "transform": [
59 | {
60 | "type": "aggregate",
61 | "groupby": ["year"],
62 | "fields": ["perc"], "ops": ["sum"], "as": ["sum"]
63 | }
64 | ]
65 | }
66 | ],
67 |
68 | "scales": [
69 | {
70 | "name": "x",
71 | "type": "linear",
72 | "range": "width",
73 | "zero": false, "round": true,
74 | "domain": {"data": "jobs", "field": "year"}
75 | },
76 | {
77 | "name": "y",
78 | "type": "linear",
79 | "range": "height", "round": true, "zero": true,
80 | "domain": {"data": "years", "field": "sum"}
81 | },
82 | {
83 | "name": "color",
84 | "type": "ordinal",
85 | "domain": ["men", "women"],
86 | "range": ["#33f", "#f33"]
87 | },
88 | {
89 | "name": "alpha",
90 | "type": "linear", "zero": true,
91 | "domain": {"data": "series", "field": "sum"},
92 | "range": [0.4, 0.8]
93 | },
94 | {
95 | "name": "font",
96 | "type": "sqrt",
97 | "range": [0, 20], "round": true, "zero": true,
98 | "domain": {"data": "series", "field": "argmax.perc"}
99 | },
100 | {
101 | "name": "opacity",
102 | "type": "quantile",
103 | "range": [0, 0, 0, 0, 0, 0.1, 0.2, 0.4, 0.7, 1.0],
104 | "domain": {"data": "series", "field": "argmax.perc"}
105 | },
106 | {
107 | "name": "align",
108 | "type": "quantize",
109 | "range": ["left", "center", "right"], "zero": false,
110 | "domain": [1730, 2130]
111 | },
112 | {
113 | "name": "offset",
114 | "type": "quantize",
115 | "range": [6, 0, -6], "zero": false,
116 | "domain": [1730, 2130]
117 | }
118 | ],
119 |
120 | "axes": [
121 | {
122 | "orient": "bottom", "scale": "x", "format": "d", "tickCount": 15
123 | },
124 | {
125 | "orient": "right", "scale": "y", "format": "%",
126 | "grid": true, "domain": false, "tickSize": 12,
127 | "encode": {
128 | "grid": {"enter": {"stroke": {"value": "#ccc"}}},
129 | "ticks": {"enter": {"stroke": {"value": "#ccc"}}}
130 | }
131 | }
132 | ],
133 |
134 | "marks": [
135 | {
136 | "type": "group",
137 | "from": {
138 | "data": "series",
139 | "facet": {
140 | "name": "facet",
141 | "data": "jobs",
142 | "groupby": ["job", "sex"]
143 | }
144 | },
145 |
146 | "marks": [
147 | {
148 | "type": "area",
149 | "from": {"data": "facet"},
150 | "encode": {
151 | "update": {
152 | "x": {"scale": "x", "field": "year"},
153 | "y": {"scale": "y", "field": "y0"},
154 | "y2": {"scale": "y", "field": "y1"},
155 | "fill": {"scale": "color", "field": "sex"},
156 | "fillOpacity": {"scale": "alpha", "field": {"parent": "sum"}}
157 | },
158 | "hover": {
159 | "fillOpacity": {"value": 0.2}
160 | }
161 | }
162 | }
163 | ]
164 | },
165 | {
166 | "type": "text",
167 | "from": {"data": "series"},
168 | "interactive": false,
169 | "encode": {
170 | "update": {
171 | "x": {"scale": "x", "field": "argmax.year"},
172 | "dx": {"scale": "offset", "field": "argmax.year"},
173 | "y": {"signal": "scale('y', 0.5 * (datum.argmax.y0 + datum.argmax.y1))"},
174 | "fill": {"value": "#000"},
175 | "fillOpacity": {"scale": "opacity", "field": "argmax.perc"},
176 | "fontSize": {"scale": "font", "field": "argmax.perc", "offset": 5},
177 | "text": {"field": "job"},
178 | "align": {"scale": "align", "field": "argmax.year"},
179 | "baseline": {"value": "middle"}
180 | }
181 | }
182 | }
183 | ]
184 | }
--------------------------------------------------------------------------------
/docs/spec/legends.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 0,
4 | "height": 0,
5 | "padding": 5,
6 |
7 | "scales": [
8 | {
9 | "name": "sequence",
10 | "type": "sequential",
11 | "scheme": "viridis",
12 | "domain": [0, 100]
13 | },
14 | {
15 | "name": "stops",
16 | "type": "linear",
17 | "range": ["#f00", "#a44", "#666", "#4a4", "#0f0"],
18 | "domain": [-100, -35, 0, 35, 100]
19 | }
20 | ],
21 |
22 | "legends": [
23 | {
24 | "type": "gradient",
25 | "fill": "sequence",
26 | "orient": "left",
27 | "title": "Gradient",
28 | "offset": 0
29 | },
30 | {
31 | "type": "gradient",
32 | "stroke": "stops",
33 | "orient": "left",
34 | "title": "Multi-Stop",
35 | "offset": 0
36 | },
37 | {
38 | "type": "symbol",
39 | "stroke": "sequence",
40 | "orient": "right",
41 | "title": "Sequence",
42 | "encode": {
43 | "symbols": {
44 | "interactive": true,
45 | "update": {"fill": {"value": "transparent"}},
46 | "hover": {"fill": {"value": "#ccc"}}
47 | },
48 | "labels": {
49 | "interactive": true,
50 | "update": {"fill": {"value": "#000"}, "fontWeight": {"value": null}},
51 | "hover": {"fill": {"value": "firebrick"}, "fontWeight": {"value": "bold"}}
52 | }
53 | }
54 | },
55 | {
56 | "type": "symbol",
57 | "fill": "stops",
58 | "orient": "right",
59 | "title": "Stops",
60 | "values": [-100, -35, 0, 35, 100]
61 | }
62 | ]
63 | }
--------------------------------------------------------------------------------
/docs/spec/lifelines.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 80,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "people",
10 | "values": [
11 | {
12 | "label": "Washington",
13 | "born": -7506057600000,
14 | "died": -5366196000000,
15 | "enter": -5701424400000,
16 | "leave": -5453884800000
17 | },
18 | {
19 | "label": "Adams",
20 | "born": -7389766800000,
21 | "died": -4528285200000,
22 | "enter": -5453884800000,
23 | "leave": -5327740800000
24 | },
25 | {
26 | "label": "Jefferson",
27 | "born": -7154586000000,
28 | "died": -4528285200000,
29 | "enter": -5327740800000,
30 | "leave": -5075280000000
31 | },
32 | {
33 | "label": "Madison",
34 | "born": -6904544400000,
35 | "died": -4213184400000,
36 | "enter": -5075280000000,
37 | "leave": -4822819200000
38 | },
39 | {
40 | "label": "Monroe",
41 | "born": -6679904400000,
42 | "died": -4370518800000,
43 | "enter": -4822819200000,
44 | "leave": -4570358400000
45 | }
46 | ]
47 | },
48 | {
49 | "name": "events",
50 | "format": {"type":"json", "parse":{"when":"date"}},
51 | "values": [
52 | { "name":"Decl. of Independence", "when":"July 4, 1776" },
53 | { "name":"U.S. Constitution", "when":"3/4/1789" },
54 | { "name":"Louisiana Purchase", "when":"April 30, 1803" },
55 | { "name":"Monroe Doctrine", "when":"Dec 2, 1823" }
56 | ]
57 | }
58 | ],
59 |
60 | "scales": [
61 | {
62 | "name": "yscale",
63 | "type": "band",
64 | "range": [0, {"signal": "height"}],
65 | "domain": {"data": "people", "field": "label"}
66 | },
67 | {
68 | "name": "xscale",
69 | "type": "time",
70 | "range": "width",
71 | "round": true,
72 | "domain": {"data": "people", "fields": ["born", "died"]}
73 | }
74 | ],
75 |
76 | "axes": [
77 | {"orient": "bottom", "scale": "xscale"}
78 | ],
79 |
80 | "marks": [
81 | {
82 | "type": "text",
83 | "from": {"data": "events"},
84 | "encode": {
85 | "enter": {
86 | "x": {"scale": "xscale", "field": "when"},
87 | "y": {"value": -10},
88 | "angle": {"value": -25},
89 | "fill": {"value": "#000"},
90 | "text": {"field": "name"},
91 | "font": {"value": "Helvetica Neue"},
92 | "fontSize": {"value": 10}
93 | }
94 | }
95 | },
96 | {
97 | "type": "rect",
98 | "from": {"data": "events"},
99 | "encode": {
100 | "enter": {
101 | "x": {"scale": "xscale", "field": "when"},
102 | "y": {"value": -8},
103 | "width": {"value": 1},
104 | "height": {"field": {"group": "height"}, "offset": 8},
105 | "fill": {"value": "#888"}
106 | }
107 | }
108 | },
109 | {
110 | "type": "text",
111 | "from": {"data": "people"},
112 | "encode": {
113 | "enter": {
114 | "x": {"scale": "xscale", "field": "born"},
115 | "y": {"scale": "yscale", "field": "label", "offset": -3},
116 | "fill": {"value": "#000"},
117 | "text": {"field": "label"},
118 | "font": {"value": "Helvetica Neue"},
119 | "fontSize": {"value": 10}
120 | }
121 | }
122 | },
123 | {
124 | "type": "rect",
125 | "from": {"data": "people"},
126 | "encode": {
127 | "enter": {
128 | "x": {"scale": "xscale", "field": "born"},
129 | "x2": {"scale": "xscale", "field": "died"},
130 | "y": {"scale": "yscale", "field": "label"},
131 | "height": {"value": 2},
132 | "fill": {"value": "#557"}
133 | }
134 | }
135 | },
136 | {
137 | "type": "rect",
138 | "from": {"data": "people"},
139 | "encode": {
140 | "enter": {
141 | "x": {"scale": "xscale", "field": "enter"},
142 | "x2": {"scale": "xscale", "field": "leave"},
143 | "y": {"scale": "yscale", "field": "label", "offset":-1},
144 | "height": {"value": 4},
145 | "fill": {"value": "#e44"}
146 | }
147 | }
148 | }
149 | ]
150 | }
--------------------------------------------------------------------------------
/docs/spec/map-bind.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 900,
4 | "height": 500,
5 | "autosize": "none",
6 |
7 | "encode": {
8 | "update": {
9 | "fill": {"signal": "background"}
10 | }
11 | },
12 |
13 | "signals": [
14 | {
15 | "name": "type",
16 | "value": "mercator",
17 | "bind": {
18 | "type": "select",
19 | "options": [
20 | "albers",
21 | "albersUsa",
22 | "azimuthalEqualArea",
23 | "azimuthalEquidistant",
24 | "conicConformal",
25 | "conicEqualArea",
26 | "conicEquidistant",
27 | "equirectangular",
28 | "gnomonic",
29 | "mercator",
30 | "orthographic",
31 | "stereographic",
32 | "transverseMercator"
33 | ]
34 | }
35 | },
36 | { "name": "scale", "value": 150,
37 | "bind": {"type": "range", "min": 50, "max": 2000, "step": 1} },
38 | { "name": "rotate0", "value": 0,
39 | "bind": {"type": "range", "min": -180, "max": 180, "step": 1} },
40 | { "name": "rotate1", "value": 0,
41 | "bind": {"type": "range", "min": -90, "max": 90, "step": 1} },
42 | { "name": "rotate2", "value": 0,
43 | "bind": {"type": "range", "min": -180, "max": 180, "step": 1} },
44 | { "name": "center0", "value": 0,
45 | "bind": {"type": "range", "min": -180, "max": 180, "step": 1} },
46 | { "name": "center1", "value": 0,
47 | "bind": {"type": "range", "min": -90, "max": 90, "step": 1} },
48 | { "name": "translate0", "update": "width / 2" },
49 | { "name": "translate1", "update": "height / 2" },
50 |
51 | { "name": "graticuleDash", "value": 0,
52 | "bind": {"type": "radio", "options": [0, 3, 5, 10]} },
53 | { "name": "borderWidth", "value": 1,
54 | "bind": {"type": "text"} },
55 | { "name": "background", "value": "#ffffff",
56 | "bind": {"type": "color"} },
57 | { "name": "invert", "value": false,
58 | "bind": {"type": "checkbox"} }
59 | ],
60 |
61 | "projections": [
62 | {
63 | "name": "projection",
64 | "type": {"signal": "type"},
65 | "scale": {"signal": "scale"},
66 | "rotate": [
67 | {"signal": "rotate0"},
68 | {"signal": "rotate1"},
69 | {"signal": "rotate2"}
70 | ],
71 | "center": [
72 | {"signal": "center0"},
73 | {"signal": "center1"}
74 | ],
75 | "translate": [
76 | {"signal": "translate0"},
77 | {"signal": "translate1"}
78 | ]
79 | }
80 | ],
81 |
82 | "data": [
83 | {
84 | "name": "world",
85 | "url": "data/world-110m.json",
86 | "format": {
87 | "type": "topojson",
88 | "feature": "countries"
89 | }
90 | },
91 | {
92 | "name": "graticule",
93 | "transform": [
94 | { "type": "graticule" }
95 | ]
96 | }
97 | ],
98 |
99 | "marks": [
100 | {
101 | "type": "shape",
102 | "from": {"data": "graticule"},
103 | "encode": {
104 | "update": {
105 | "strokeWidth": {"value": 1},
106 | "strokeDash": {"signal": "[+graticuleDash, +graticuleDash]"},
107 | "stroke": {"signal": "invert ? '#444' : '#ddd'"},
108 | "fill": {"value": null}
109 | }
110 | },
111 | "transform": [
112 | { "type": "geoshape", "projection": "projection" }
113 | ]
114 | },
115 | {
116 | "type": "shape",
117 | "from": {"data": "world"},
118 | "encode": {
119 | "update": {
120 | "strokeWidth": {"signal": "+borderWidth"},
121 | "stroke": {"signal": "invert ? '#777' : '#bbb'"},
122 | "fill": {"signal": "invert ? '#fff' : '#000'"},
123 | "zindex": {"value": 0}
124 | },
125 | "hover": {
126 | "strokeWidth": {"signal": "+borderWidth + 1"},
127 | "stroke": {"value": "firebrick"},
128 | "zindex": {"value": 1}
129 | }
130 | },
131 | "transform": [
132 | { "type": "geoshape", "projection": "projection" }
133 | ]
134 | }
135 | ]
136 | }
--------------------------------------------------------------------------------
/docs/spec/map.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 900,
4 | "height": 500,
5 | "autosize": "none",
6 |
7 | "signals": [
8 | { "name": "tx", "update": "width / 2" },
9 | { "name": "ty", "update": "height / 2" },
10 | {
11 | "name": "scale",
12 | "value": 150,
13 | "on": [{
14 | "events": {"type": "wheel", "consume": true},
15 | "update": "clamp(scale * pow(1.0005, -event.deltaY * pow(16, event.deltaMode)), 150, 3000)"
16 | }]
17 | },
18 | {
19 | "name": "angles",
20 | "value": [0, 0],
21 | "on": [{
22 | "events": "mousedown",
23 | "update": "[rotateX, centerY]"
24 | }]
25 | },
26 | {
27 | "name": "cloned",
28 | "value": null,
29 | "on": [{
30 | "events": "mousedown",
31 | "update": "copy('projection')"
32 | }]
33 | },
34 | {
35 | "name": "start",
36 | "value": null,
37 | "on": [{
38 | "events": "mousedown",
39 | "update": "invert(cloned, xy())"
40 | }]
41 | },
42 | {
43 | "name": "drag", "value": null,
44 | "on": [{
45 | "events": "[mousedown, window:mouseup] > window:mousemove",
46 | "update": "invert(cloned, xy())"
47 | }]
48 | },
49 | {
50 | "name": "delta", "value": null,
51 | "on": [{
52 | "events": {"signal": "drag"},
53 | "update": "[drag[0] - start[0], start[1] - drag[1]]"
54 | }]
55 | },
56 | {
57 | "name": "rotateX", "value": 0,
58 | "on": [{
59 | "events": {"signal": "delta"},
60 | "update": "angles[0] + delta[0]"
61 | }]
62 | },
63 | {
64 | "name": "centerY", "value": 0,
65 | "on": [{
66 | "events": {"signal": "delta"},
67 | "update": "clamp(angles[1] + delta[1], -60, 60)"
68 | }]
69 | }
70 | ],
71 |
72 | "projections": [
73 | {
74 | "name": "projection",
75 | "type": "mercator",
76 | "scale": {"signal": "scale"},
77 | "rotate": [{"signal": "rotateX"}, 0, 0],
78 | "center": [0, {"signal": "centerY"}],
79 | "translate": [{"signal": "tx"}, {"signal": "ty"}]
80 | }
81 | ],
82 |
83 | "data": [
84 | {
85 | "name": "world",
86 | "url": "data/world-110m.json",
87 | "format": {
88 | "type": "topojson",
89 | "feature": "countries"
90 | }
91 | },
92 | {
93 | "name": "graticule",
94 | "transform": [
95 | { "type": "graticule", "step": [15, 15] }
96 | ]
97 | }
98 | ],
99 |
100 | "marks": [
101 | {
102 | "type": "shape",
103 | "from": {"data": "graticule"},
104 | "encode": {
105 | "enter": {
106 | "strokeWidth": {"value": 1},
107 | "stroke": {"value": "#ddd"},
108 | "fill": {"value": null}
109 | }
110 | },
111 | "transform": [
112 | { "type": "geoshape", "projection": "projection" }
113 | ]
114 | },
115 | {
116 | "type": "shape",
117 | "from": {"data": "world"},
118 | "encode": {
119 | "enter": {
120 | "strokeWidth": {"value": 0.5},
121 | "stroke": {"value": "#bbb"},
122 | "fill": {"value": "#e5e8d3"}
123 | }
124 | },
125 | "transform": [
126 | { "type": "geoshape", "projection": "projection" }
127 | ]
128 | }
129 | ]
130 | }
--------------------------------------------------------------------------------
/docs/spec/matrix-reorder.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 770,
4 | "height": 770,
5 | "padding": 2,
6 |
7 | "signals": [
8 | { "name": "cellSize", "value": 10 },
9 | { "name": "width", "update": "span(range('position'))" },
10 | { "name": "height", "update": "width" },
11 | {
12 | "name": "src", "value": {},
13 | "on": [
14 | {"events": "text:mousedown", "update": "datum"},
15 | {"events": "window:mouseup", "update": "{}"}
16 | ]
17 | },
18 | {
19 | "name": "dest", "value": {},
20 | "on": [
21 | {
22 | "events": "[text:mousedown, window:mouseup] > text:mouseover",
23 | "update": "src._id != null ? datum : dest"
24 | },
25 | {"events": "text:mouseout", "update": "{}"}
26 | ]
27 | },
28 | {"name": "destOrder", "update": "dest.order"},
29 | {"name": "dragging", "update": "src._id && dest._id"}
30 | ],
31 |
32 | "data": [
33 | {
34 | "name": "nodes",
35 | "url": "data/miserables.json",
36 | "format": {"type": "json", "property": "nodes"},
37 | "transform": [
38 | { "type": "collect", "sort": {"field": "group"} },
39 | { "type": "rank", "as": "order" },
40 | {
41 | "type": "formula", "as": "order",
42 | "expr": "dragging && datum === dest ? src.order : datum.order"
43 | },
44 | {
45 | "type": "formula", "as": "order",
46 | "expr": "dragging && datum === src ? destOrder : datum.order"
47 | }
48 | ]
49 | },
50 | {
51 | "name": "edges",
52 | "url": "data/miserables.json",
53 | "format": {"type": "json", "property": "links"},
54 | "transform": [
55 | {
56 | "type": "lookup", "from": "nodes", "key": "index",
57 | "fields": ["source", "target"], "as": ["sourceNode", "targetNode"]
58 | },
59 | {
60 | "type": "formula",
61 | "as": "group",
62 | "expr": "datum.sourceNode.group === datum.targetNode.group ? datum.sourceNode.group : -1"
63 | }
64 | ]
65 | },
66 | {
67 | "name": "cross",
68 | "source": "nodes",
69 | "transform": [
70 | { "type": "cross" }
71 | ]
72 | }
73 | ],
74 |
75 | "scales": [
76 | {
77 | "name": "position",
78 | "type": "band",
79 | "domain": {"data": "nodes", "field": "order", "sort": true},
80 | "rangeStep": {"signal": "cellSize"}
81 | },
82 | {
83 | "name": "color",
84 | "type": "ordinal",
85 | "scheme": "category20",
86 | "domain": {"data": "nodes", "field": "group"}
87 | },
88 | {
89 | "name": "labels",
90 | "type": "ordinal",
91 | "domain": {"data": "nodes", "field": "order"},
92 | "range": {"data": "nodes", "field": "name"}
93 | }
94 | ],
95 |
96 | "marks": [
97 | {
98 | "type": "rect",
99 | "from": {"data": "cross"},
100 | "encode": {
101 | "update": {
102 | "x": {"scale": "position", "field": "a.order"},
103 | "y": {"scale": "position", "field": "b.order"},
104 | "width": {"scale": "position", "band": 1, "offset": -1},
105 | "height": {"scale": "position", "band": 1, "offset": -1},
106 | "fill": [
107 | {"test": "datum.a === src || datum.b === src", "value": "#ddd"},
108 | {"value": "#f5f5f5"}
109 | ]
110 | }
111 | }
112 | },
113 | {
114 | "type": "rect",
115 | "from": {"data": "edges"},
116 | "encode": {
117 | "update": {
118 | "x": {"scale": "position", "field": "sourceNode.order"},
119 | "y": {"scale": "position", "field": "targetNode.order"},
120 | "width": {"scale": "position", "band": 1, "offset": -1},
121 | "height": {"scale": "position", "band": 1, "offset": -1},
122 | "fill": {"scale": "color", "field": "group"}
123 | }
124 | }
125 | },
126 | {
127 | "type": "rect",
128 | "from": {"data": "edges"},
129 | "encode": {
130 | "update": {
131 | "x": {"scale": "position", "field": "targetNode.order"},
132 | "width": {"scale": "position", "band": 1, "offset": -1},
133 | "y": {"scale": "position", "field": "sourceNode.order"},
134 | "height": {"scale": "position", "band": 1, "offset": -1},
135 | "fill": {"scale": "color", "field": "group"}
136 | }
137 | }
138 | },
139 | {
140 | "type": "text",
141 | "from": {"data": "nodes"},
142 | "encode": {
143 | "update": {
144 | "x": {"scale": "position", "field": "order"},
145 | "y": {"offset": -2},
146 | "dy": {"scale": "position", "band": 0.5},
147 | "text": {"field": "name"},
148 | "fontSize": {"value": 10},
149 | "angle": {"value": -90},
150 | "align": {"value": "left"},
151 | "baseline": {"value": "middle"},
152 | "fill": [
153 | {"test": "datum === src", "value": "steelblue"},
154 | {"value": "black"}
155 | ]
156 | }
157 | }
158 | },
159 | {
160 | "type": "text",
161 | "from": {"data": "nodes"},
162 | "encode": {
163 | "update": {
164 | "x": {"offset": -2},
165 | "y": {"scale": "position", "field": "order"},
166 | "dy": {"scale": "position", "band": 0.5},
167 | "text": {"field": "name"},
168 | "fontSize": {"value": 10},
169 | "align": {"value": "right"},
170 | "baseline": {"value": "middle"},
171 | "fill": [
172 | {"test": "datum === src", "value": "steelblue"},
173 | {"value": "black"}
174 | ]
175 | }
176 | }
177 | }
178 | ]
179 | }
180 |
--------------------------------------------------------------------------------
/docs/spec/movies-sort.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 15,
4 | "padding": 5,
5 | "autosize": "pad",
6 |
7 | "config": {
8 | "axisLeft": {
9 | "titleX": -5,
10 | "titleY": -2,
11 | "titleAlign": "right",
12 | "titleAngle": 0,
13 | "titleBaseline": "bottom"
14 | }
15 | },
16 |
17 | "signals": [
18 | {
19 | "name": "cellSize",
20 | "value": 15
21 | },
22 | {
23 | "name": "height",
24 | "update": "cellSize * extent[1]"
25 | },
26 | {
27 | "name": "sortop",
28 | "value": "count",
29 | "bind": {"type": "radio", "options": ["count", "min"]}
30 | },
31 | {
32 | "name": "sortorder",
33 | "value": "descending",
34 | "bind": {"type": "radio", "options": ["ascending", "descending"]}
35 | }
36 | ],
37 |
38 | "data": [
39 | {
40 | "name": "source",
41 | "url": "data/movies.json"
42 | },
43 | {
44 | "name": "layout",
45 | "source": "source",
46 | "transform": [
47 | {
48 | "type": "aggregate",
49 | "fields": ["Title"],
50 | "ops": ["distinct"],
51 | "signal": "aggregate"
52 | },
53 | {
54 | "type": "extent",
55 | "field": "distinct_Title",
56 | "signal": "extent"
57 | }
58 | ]
59 | }
60 | ],
61 |
62 | "marks": [
63 | {
64 | "type": "symbol",
65 | "from": {"data": "source"},
66 | "encode": {
67 | "update": {
68 | "x": {"value": 10},
69 | "y": {"scale": "y", "field": "Title"},
70 | "size": {"value": 36},
71 | "shape": {"value": "circle"},
72 | "strokeWidth": {"value": 1.5},
73 | "opacity": {"value": 0.7},
74 | "stroke": {"value": "steelblue"},
75 | "fill": {"value": "transparent"}
76 | },
77 | "hover": {
78 | "stroke": {"value": "firebrick"},
79 | "cursor": {"value": "pointer"}
80 | }
81 | }
82 | }
83 | ],
84 |
85 | "scales": [
86 | {
87 | "name": "y",
88 | "type": "point",
89 | "domain": {
90 | "data": "source",
91 | "field": "Title",
92 | "sort": {
93 | "field": "Title",
94 | "op": {"signal": "sortop"},
95 | "order": {"signal": "sortorder"}
96 | }
97 | },
98 | "rangeStep": {"signal": "cellSize"},
99 | "padding": 0.5
100 | }
101 | ],
102 |
103 | "axes": [
104 | {
105 | "scale": "y",
106 | "orient": "left",
107 | "title": "Film Title",
108 | "encode": {
109 | "labels": {
110 | "interactive": true,
111 | "title": {
112 | "update": {
113 | "x": {"value": -5},
114 | "y": {"value": -2},
115 | "align": {"value": "right"},
116 | "baseline": {"value": "bottom"},
117 | "angle": {"value": 0}
118 | }
119 | },
120 | "enter": {
121 | "text": {"signal": "truncate(datum.label, 25)"}
122 | },
123 | "update": {
124 | "fill": {"value": "black"}
125 | },
126 | "hover": {
127 | "fill": {"value": "firebrick"},
128 | "cursor": {"value": "pointer"}
129 | }
130 | }
131 | }
132 | }
133 | ]
134 | }
--------------------------------------------------------------------------------
/docs/spec/nested-plot.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 300,
4 | "padding": 5,
5 | "autosize": "pad",
6 |
7 | "encode": {
8 | "enter": {
9 | "fill": {"value": "transparent"},
10 | "strokeWidth": {"value": 1},
11 | "stroke": {"value": "#888"}
12 | },
13 | "update": {
14 | "strokeDash": {"value": [3, 3]}
15 | },
16 | "hover": {
17 | "strokeDash": {"value": []}
18 | }
19 | },
20 |
21 | "signals": [
22 | {
23 | "name": "rangeStep", "value": 20,
24 | "bind": {"type": "range", "min": 5, "max": 50, "step": 1}
25 | },
26 | {
27 | "name": "innerPadding", "value": 0.1,
28 | "bind": {"type": "range", "min": 0, "max": 1}
29 | },
30 | {
31 | "name": "outerPadding", "value": 0.2,
32 | "bind": {"type": "range", "min": 0, "max": 1}
33 | },
34 | {
35 | "name": "height",
36 | "update": "trellisExtent[1]"
37 | }
38 | ],
39 |
40 | "data": [
41 | {
42 | "name": "tuples",
43 | "values": [
44 | {"a": 0, "b": "a", "c": 6.3},
45 | {"a": 0, "b": "a", "c": 4.2},
46 | {"a": 0, "b": "b", "c": 6.8},
47 | {"a": 0, "b": "c", "c": 5.1},
48 | {"a": 1, "b": "b", "c": 4.4},
49 | {"a": 2, "b": "b", "c": 3.5},
50 | {"a": 2, "b": "c", "c": 6.2}
51 | ],
52 | "transform": [
53 | {
54 | "type": "aggregate",
55 | "groupby": ["a", "b"],
56 | "fields": ["c"],
57 | "ops": ["average"],
58 | "as": ["c"]
59 | }
60 | ]
61 | },
62 | {
63 | "name": "trellis",
64 | "source": "tuples",
65 | "transform": [
66 | {
67 | "type": "aggregate",
68 | "groupby": ["a"]
69 | },
70 | {
71 | "type": "formula", "as": "span",
72 | "expr": "rangeStep * bandspace(datum.count, innerPadding, outerPadding)"
73 | },
74 | {
75 | "type": "stack",
76 | "field": "span"
77 | },
78 | {
79 | "type": "extent",
80 | "field": "y1",
81 | "signal": "trellisExtent"
82 | }
83 | ]
84 | }
85 | ],
86 |
87 | "scales": [
88 | {
89 | "name": "xscale",
90 | "domain": {"data": "tuples", "field": "c"},
91 | "nice": true,
92 | "zero": true,
93 | "round": true,
94 | "range": "width"
95 | },
96 | {
97 | "name": "color",
98 | "type": "ordinal",
99 | "scheme": "category10",
100 | "domain": {"data": "trellis", "field": "a"}
101 | }
102 | ],
103 |
104 | "axes": [
105 | { "orient": "bottom", "scale": "xscale", "domain": true }
106 | ],
107 |
108 | "marks": [
109 | {
110 | "type": "group",
111 |
112 | "from": {
113 | "data": "trellis",
114 | "facet": {
115 | "name": "faceted_tuples",
116 | "data": "tuples",
117 | "groupby": "a"
118 | }
119 | },
120 |
121 | "encode": {
122 | "enter": {
123 | "x": {"value": 0},
124 | "width": {"signal": "width"}
125 | },
126 | "update": {
127 | "y": {"field": "y0"},
128 | "y2": {"field": "y1"}
129 | }
130 | },
131 |
132 | "scales": [
133 | {
134 | "name": "yscale",
135 | "type": "band",
136 | "paddingInner": {"signal": "innerPadding"},
137 | "paddingOuter": {"signal": "outerPadding"},
138 | "round": true,
139 | "domain": {"data": "faceted_tuples", "field": "b"},
140 | "rangeStep": {"signal": "rangeStep"}
141 | }
142 | ],
143 |
144 | "axes": [
145 | { "orient": "left", "scale": "yscale",
146 | "tick": false, "domain": false, "labelPadding": 4 }
147 | ],
148 |
149 | "marks": [
150 | {
151 | "type": "rect",
152 | "from": {"data": "faceted_tuples"},
153 | "encode": {
154 | "enter": {
155 | "x": {"value": 0},
156 | "x2": {"scale": "xscale", "field": "c"},
157 | "fill": {"scale": "color", "field": "a"},
158 | "strokeWidth": {"value": 2}
159 | },
160 | "update": {
161 | "y": {"scale": "yscale", "field": "b"},
162 | "height": {"scale": "yscale", "band": 1},
163 | "stroke": {"value": null},
164 | "zindex": {"value": 0}
165 | },
166 | "hover": {
167 | "stroke": {"value": "firebrick"},
168 | "zindex": {"value": 1}
169 | }
170 | }
171 | }
172 | ]
173 | }
174 | ]
175 | }
--------------------------------------------------------------------------------
/docs/spec/parallel-coords.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 700,
4 | "height": 400,
5 | "padding": 5,
6 |
7 | "config": {
8 | "axisY": {
9 | "titleX": -2,
10 | "titleY": 410,
11 | "titleAngle": 0,
12 | "titleAlign": "right",
13 | "titleBaseline": "top"
14 | }
15 | },
16 |
17 | "data": [
18 | {
19 | "name": "cars",
20 | "url": "data/cars.json",
21 | "transform": [
22 | {"type": "filter", "expr": "datum.Horsepower && datum.Miles_per_Gallon"}
23 | ]
24 | },
25 | {
26 | "name": "fields",
27 | "values": [
28 | "Cylinders",
29 | "Displacement",
30 | "Weight_in_lbs",
31 | "Horsepower",
32 | "Acceleration",
33 | "Miles_per_Gallon",
34 | "Year"
35 | ]
36 | }
37 | ],
38 |
39 | "scales": [
40 | {
41 | "name": "ord", "type": "point",
42 | "range": "width", "round": true,
43 | "domain": {"data": "fields", "field": "data"}
44 | },
45 | {
46 | "name": "Cylinders", "type": "linear",
47 | "range": "height", "zero": false, "nice": true,
48 | "domain": {"data": "cars", "field": "Cylinders"}
49 | },
50 | {
51 | "name": "Displacement", "type": "linear",
52 | "range": "height", "zero": false, "nice": true,
53 | "domain": {"data": "cars", "field": "Displacement"}
54 | },
55 | {
56 | "name": "Weight_in_lbs", "type": "linear",
57 | "range": "height", "zero": false, "nice": true,
58 | "domain": {"data": "cars", "field": "Weight_in_lbs"}
59 | },
60 | {
61 | "name": "Horsepower", "type": "linear",
62 | "range": "height", "zero": false, "nice": true,
63 | "domain": {"data": "cars", "field": "Horsepower"}
64 | },
65 | {
66 | "name": "Acceleration", "type": "linear",
67 | "range": "height", "zero": false, "nice": true,
68 | "domain": {"data": "cars", "field": "Acceleration"}
69 | },
70 | {
71 | "name": "Miles_per_Gallon", "type": "linear",
72 | "range": "height", "zero": false, "nice": true,
73 | "domain": {"data": "cars", "field": "Miles_per_Gallon"}
74 | },
75 | {
76 | "name": "Year", "type": "linear",
77 | "range": "height", "zero": false, "nice": true,
78 | "domain": {"data": "cars", "field": "Year"}
79 | }
80 | ],
81 |
82 | "axes": [
83 | {
84 | "orient": "left", "zindex": 1,
85 | "scale": "Cylinders", "title": "Cylinders",
86 | "offset": {"scale": "ord", "value": "Cylinders", "mult": -1}
87 | },
88 | {
89 | "orient": "left", "zindex": 1,
90 | "scale": "Displacement", "title": "Displacement",
91 | "offset": {"scale": "ord", "value": "Displacement", "mult": -1}
92 | },
93 | {
94 | "orient": "left", "zindex": 1,
95 | "scale": "Weight_in_lbs", "title": "Weight_in_lbs",
96 | "offset": {"scale": "ord", "value": "Weight_in_lbs", "mult": -1}
97 | },
98 | {
99 | "orient": "left", "zindex": 1,
100 | "scale": "Horsepower", "title": "Horsepower",
101 | "offset": {"scale": "ord", "value": "Horsepower", "mult": -1}
102 | },
103 | {
104 | "orient": "left", "zindex": 1,
105 | "scale": "Acceleration", "title": "Acceleration",
106 | "offset": {"scale": "ord", "value": "Acceleration", "mult": -1}
107 | },
108 | {
109 | "orient": "left", "zindex": 1,
110 | "scale": "Miles_per_Gallon", "title": "Miles_per_Gallon",
111 | "offset": {"scale": "ord", "value": "Miles_per_Gallon", "mult": -1}
112 | },
113 | {
114 | "orient": "left", "zindex": 1,
115 | "scale": "Year", "title": "Year", "format": "d",
116 | "offset": {"scale": "ord", "value": "Year", "mult": -1}
117 | }
118 | ],
119 |
120 | "marks": [
121 | {
122 | "type": "group",
123 | "from": {"data": "cars"},
124 | "marks": [
125 | {
126 | "type": "line",
127 | "from": {"data": "fields"},
128 | "encode": {
129 | "enter": {
130 | "x": {"scale": "ord", "field": "data"},
131 | "y": {
132 | "scale": {"datum": "data"},
133 | "field": {"parent": {"datum": "data"}}
134 | },
135 | "stroke": {"value": "steelblue"},
136 | "strokeWidth": {"value": 1.01},
137 | "strokeOpacity": {"value": 0.3}
138 | }
139 | }
140 | }
141 | ]
142 | }
143 | ]
144 | }
--------------------------------------------------------------------------------
/docs/spec/playfair.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 900,
4 | "height": 465,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "wheat",
10 | "url": "data/wheat.json"
11 | },
12 | {
13 | "name": "wheat-filtered",
14 | "source": "wheat",
15 | "transform": [
16 | { "type": "filter", "expr": "!!datum.wages" }
17 | ]
18 | },
19 | {
20 | "name": "monarchs",
21 | "url": "data/monarchs.json",
22 | "transform": [
23 | {
24 | "type": "formula",
25 | "expr": "((!datum.commonwealth && datum.index % 2) ? -1: 1) * 2 + 95",
26 | "as": "offset"
27 | }
28 | ]
29 | }
30 | ],
31 |
32 | "scales": [
33 | {
34 | "name": "x",
35 | "type": "linear",
36 | "range": "width",
37 | "domain": [1565, 1825],
38 | "zero": false
39 | },
40 | {
41 | "name": "y",
42 | "type": "linear",
43 | "range": "height",
44 | "zero": true,
45 | "domain": {"data": "wheat", "field": "wheat"}
46 | },
47 | {
48 | "name": "c",
49 | "type": "ordinal",
50 | "range": ["black", "white"],
51 | "domain": {"data": "monarchs", "field": "commonwealth"}
52 | }
53 | ],
54 |
55 | "axes": [
56 | {
57 | "orient": "bottom",
58 | "scale": "x",
59 | "tickCount": 5,
60 | "format": "04d"
61 | },
62 | {
63 | "orient": "right",
64 | "scale": "y",
65 | "grid": true,
66 | "domain": false,
67 | "zindex": 1,
68 | "tickCount": 5,
69 | "offset": 5,
70 | "tickSize": 0,
71 | "encode": {
72 | "grid": {
73 | "enter": {
74 | "stroke": {"value": "#fff"},
75 | "strokeWidth": {"value": 1},
76 | "strokeOpacity": {"value": 0.25}
77 | }
78 | },
79 | "labels": {
80 | "enter": {
81 | "fontStyle": {"value": "italic"}
82 | }
83 | }
84 | }
85 | }
86 | ],
87 |
88 | "marks": [
89 | {
90 | "type": "rect",
91 | "from": {"data": "wheat"},
92 | "encode": {
93 | "enter": {
94 | "x": {"scale": "x", "field": "year"},
95 | "width": {"value": 17},
96 | "y": {"scale": "y", "field": "wheat"},
97 | "y2": {"scale": "y", "value": 0},
98 | "fill": {"value": "#aaa"},
99 | "stroke": {"value": "#5d5d5d"},
100 | "strokeWidth": {"value": 0.25}
101 | }
102 | }
103 | },
104 | {
105 | "type": "area",
106 | "from": {"data": "wheat-filtered"},
107 | "encode": {
108 | "enter": {
109 | "interpolate": {"value": "linear"},
110 | "x": {"scale": "x", "field": "year"},
111 | "y": {"scale": "y", "field": "wages"},
112 | "y2": {"scale": "y", "value": 0},
113 | "fill": {"value": "#B3D9E6"},
114 | "fillOpacity": {"value": 0.8}
115 | }
116 | }
117 | },
118 | {
119 | "type": "line",
120 | "from": {"data": "wheat-filtered"},
121 | "encode": {
122 | "enter": {
123 | "interpolate": {"value": "linear"},
124 | "x": {"scale": "x", "field": "year"},
125 | "y": {"scale": "y", "field": "wages"},
126 | "stroke": {"value": "#ff7e79"},
127 | "strokeWidth": {"value": 3}
128 | }
129 | }
130 | },
131 | {
132 | "type": "line",
133 | "from": {"data": "wheat-filtered"},
134 | "encode": {
135 | "enter": {
136 | "interpolate": {"value": "linear"},
137 | "x": {"scale": "x", "field": "year"},
138 | "y": {"scale": "y", "field": "wages"},
139 | "stroke": {"value": "#000"},
140 | "strokeWidth": {"value": 1}
141 | }
142 | }
143 | },
144 | {
145 | "name" : "monarch_rects",
146 | "type": "rect",
147 | "from": {"data": "monarchs"},
148 | "encode": {
149 | "enter": {
150 | "x": {"scale": "x", "field": "start"},
151 | "x2": {"scale": "x", "field": "end"},
152 | "y": {"scale": "y", "value": 95},
153 | "y2": {"scale": "y", "field": "offset"},
154 | "fill": {"scale": "c", "field": "commonwealth"},
155 | "stroke": {"value": "#000"},
156 | "strokeWidth": {"value": 2}
157 | }
158 | }
159 | },
160 | {
161 | "type": "text",
162 | "from": {"data": "monarch_rects"},
163 | "encode": {
164 | "enter": {
165 | "x": {"field": "x"},
166 | "dx": {"field": "width", "mult": 0.5},
167 | "y": {"field": "y2", "offset": 14},
168 | "text": {"field": "datum.name"},
169 | "align": {"value": "center"},
170 | "fill": {"value": "black"},
171 | "font": {"value": "Helvetica Neue"},
172 | "fontSize": {"value": 10},
173 | "fontStyle": {"value": "italic"}
174 | }
175 | }
176 | }
177 | ]
178 | }
--------------------------------------------------------------------------------
/docs/spec/population.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "height": 400,
4 | "padding": 5,
5 |
6 | "signals": [
7 | { "name": "chartWidth", "value": 300 },
8 | { "name": "chartPad", "value": 20 },
9 | { "name": "width", "update": "2 * chartWidth + chartPad" },
10 | { "name": "year", "value": 2000,
11 | "bind": {"type": "range", "min": 1850, "max": 2000, "step": 10} }
12 | ],
13 |
14 | "data": [
15 | {
16 | "name": "population",
17 | "url": "data/population.json"
18 | },
19 | {
20 | "name": "popYear",
21 | "source": "population",
22 | "transform": [
23 | {"type": "filter", "expr": "datum.year == year"}
24 | ]
25 | },
26 | {
27 | "name": "males",
28 | "source": "popYear",
29 | "transform": [
30 | {"type": "filter", "expr": "datum.sex == 1"}
31 | ]
32 | },
33 | {
34 | "name": "females",
35 | "source": "popYear",
36 | "transform": [
37 | {"type": "filter", "expr": "datum.sex == 2"}
38 | ]
39 | },
40 | {
41 | "name": "ageGroups",
42 | "source": "population",
43 | "transform": [
44 | { "type": "aggregate", "groupby": ["age"] }
45 | ]
46 | }
47 | ],
48 |
49 | "scales": [
50 | {
51 | "name": "y",
52 | "type": "band",
53 | "range": [{"signal": "height"}, 0],
54 | "round": true,
55 | "domain": {"data": "ageGroups", "field": "age"}
56 | },
57 | {
58 | "name": "c",
59 | "type": "ordinal",
60 | "domain": [1, 2],
61 | "range": ["#1f77b4", "#e377c2"]
62 | }
63 | ],
64 |
65 | "marks": [
66 | {
67 | "type": "text",
68 | "interactive": false,
69 | "from": {"data": "ageGroups"},
70 | "encode": {
71 | "enter": {
72 | "x": {"signal": "chartWidth + chartPad / 2"},
73 | "y": {"scale": "y", "field": "age", "band": 0.5},
74 | "text": {"field": "age"},
75 | "baseline": {"value": "middle"},
76 | "align": {"value": "center"},
77 | "fill": {"value": "#000"}
78 | }
79 | }
80 | },
81 | {
82 | "type": "group",
83 |
84 | "encode": {
85 | "update": {
86 | "x": {"value": 0},
87 | "height": {"signal": "height"}
88 | }
89 | },
90 |
91 | "scales": [
92 | {
93 | "name": "x",
94 | "type": "linear",
95 | "range": [{"signal": "chartWidth"}, 0],
96 | "nice": true, "zero": true,
97 | "domain": {"data": "population", "field": "people"}
98 | }
99 | ],
100 |
101 | "axes": [
102 | {"orient": "bottom", "scale": "x", "format": "s"}
103 | ],
104 |
105 | "marks": [
106 | {
107 | "type": "rect",
108 | "from": {"data": "females"},
109 | "encode": {
110 | "enter": {
111 | "x": {"scale": "x", "field": "people"},
112 | "x2": {"scale": "x", "value": 0},
113 | "y": {"scale": "y", "field": "age"},
114 | "height": {"scale": "y", "band": 1, "offset": -1},
115 | "fillOpacity": {"value": 0.6},
116 | "fill": {"scale": "c", "field": "sex"}
117 | }
118 | }
119 | }
120 | ]
121 | },
122 | {
123 | "type": "group",
124 |
125 | "encode": {
126 | "update": {
127 | "x": {"signal": "chartWidth + chartPad"},
128 | "height": {"signal": "height"}
129 | }
130 | },
131 |
132 | "scales": [
133 | {
134 | "name": "x",
135 | "type": "linear",
136 | "range": [0, {"signal": "chartWidth"}],
137 | "nice": true, "zero": true,
138 | "domain": {"data": "population", "field": "people"}
139 | }
140 | ],
141 |
142 | "axes": [
143 | {"orient": "bottom", "scale": "x", "format": "s"}
144 | ],
145 |
146 | "marks": [
147 | {
148 | "type": "rect",
149 | "from": {"data": "males"},
150 | "encode": {
151 | "enter": {
152 | "x": {"scale": "x", "field": "people"},
153 | "x2": {"scale": "x", "value": 0},
154 | "y": {"scale": "y", "field": "age"},
155 | "height": {"scale": "y", "band": 1, "offset": -1},
156 | "fillOpacity": {"value": 0.6},
157 | "fill": {"scale": "c", "field": "sex"}
158 | }
159 | }
160 | }
161 | ]
162 | }
163 | ]
164 | }
165 |
--------------------------------------------------------------------------------
/docs/spec/scatter-plot.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "width": 200,
3 | "height": 200,
4 | "padding": 5,
5 | "autosize": "pad",
6 |
7 | "data": [
8 | {
9 | "name": "source",
10 | "url": "data/cars.json",
11 | "transform": [
12 | {
13 | "type": "filter",
14 | "expr": "datum['Horsepower'] != null && datum['Miles_per_Gallon'] != null && datum['Acceleration'] != null"
15 | }
16 | ]
17 | }
18 | ],
19 |
20 | "scales": [
21 | {
22 | "name": "x",
23 | "type": "linear",
24 | "round": true,
25 | "nice": true,
26 | "zero": true,
27 | "domain": {"data": "source", "field": "Horsepower"},
28 | "range": [0,200]
29 | },
30 | {
31 | "name": "y",
32 | "type": "linear",
33 | "round": true,
34 | "nice": true,
35 | "zero": true,
36 | "domain": {"data": "source", "field": "Miles_per_Gallon"},
37 | "range": [200,0]
38 | },
39 | {
40 | "name": "size",
41 | "type": "linear",
42 | "round": true,
43 | "nice": false,
44 | "zero": true,
45 | "domain": {"data": "source", "field": "Acceleration"},
46 | "range": [4,361]
47 | }
48 | ],
49 |
50 | "axes": [
51 | {
52 | "scale": "x",
53 | "grid": true,
54 | "domain": false,
55 | "orient": "bottom",
56 | "tickCount": 5,
57 | "title": "Horsepower"
58 | },
59 | {
60 | "scale": "y",
61 | "grid": true,
62 | "domain": false,
63 | "orient": "left",
64 | "titlePadding": 5,
65 | "title": "Miles_per_Gallon"
66 | }
67 | ],
68 |
69 | "legends": [
70 | {
71 | "size": "size",
72 | "title": "Acceleration",
73 | "format": "s",
74 | "encode": {
75 | "symbols": {
76 | "update": {
77 | "strokeWidth": {"value": 2},
78 | "opacity": {"value": 0.5},
79 | "stroke": {"value": "#4682b4"},
80 | "shape": {"value": "circle"}
81 | }
82 | }
83 | }
84 | }
85 | ],
86 |
87 | "marks": [
88 | {
89 | "name": "marks",
90 | "type": "symbol",
91 | "from": {"data": "source"},
92 | "encode": {
93 | "update": {
94 | "x": {"scale": "x", "field": "Horsepower"},
95 | "y": {"scale": "y", "field": "Miles_per_Gallon"},
96 | "size": {"scale": "size", "field": "Acceleration"},
97 | "shape": {"value": "circle"},
98 | "strokeWidth": {"value": 2},
99 | "opacity": {"value": 0.5},
100 | "stroke": {"value": "#4682b4"},
101 | "fill": {"value": "transparent"}
102 | }
103 | }
104 | }
105 | ]
106 | }
--------------------------------------------------------------------------------
/docs/spec/shift-select.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 600,
4 | "height": 300,
5 | "padding": 10,
6 |
7 | "signals": [
8 | {
9 | "name": "shift",
10 | "value": false,
11 | "on": [
12 | {
13 | "events": {"marktype": "rect", "type": "click"},
14 | "update": "event.shiftKey",
15 | "force": true
16 | }
17 | ]
18 | },
19 | {
20 | "name": "clicked",
21 | "value": null,
22 | "on": [
23 | {
24 | "events": {"marktype": "rect", "type": "click"},
25 | "update": "datum",
26 | "force": true
27 | }
28 | ]
29 | }
30 | ],
31 |
32 | "data": [
33 | {
34 | "name": "values",
35 | "values": [
36 | {"x": 0, "y": 28},
37 | {"x": 1, "y": 43},
38 | {"x": 2, "y": 99},
39 | {"x": 3, "y": 56},
40 | {"x": 4, "y": 38},
41 | {"x": 5, "y": 83},
42 | {"x": 6, "y": 69},
43 | {"x": 7, "y": 24}
44 | ]
45 | },
46 | {
47 | "name": "selected",
48 | "on": [
49 | {"trigger": "!shift", "remove": true},
50 | {"trigger": "!shift && clicked", "insert": "clicked"},
51 | {"trigger": "shift && clicked", "toggle": "clicked"}
52 | ]
53 | }
54 | ],
55 |
56 | "scales": [
57 | {
58 | "name": "xscale",
59 | "type": "band",
60 | "range": "width",
61 | "round": true,
62 | "domain": {"data": "values", "field": "x"}
63 | },
64 | {
65 | "name": "yscale",
66 | "type": "linear",
67 | "range": "height",
68 | "round": true,
69 | "domain": {"data": "values", "field": "y"},
70 | "zero": true,
71 | "nice": true
72 | }
73 | ],
74 |
75 | "axes": [
76 | {
77 | "scale": "yscale",
78 | "orient": "left",
79 | "tickCount": 5,
80 | "zindex": 1
81 | },
82 | {
83 | "scale": "xscale",
84 | "orient": "bottom",
85 | "zindex": 1
86 | }
87 | ],
88 |
89 | "marks": [
90 | {
91 | "type": "rect",
92 | "from": {"data": "values"},
93 | "encode": {
94 | "enter": {
95 | "x": {"scale": "xscale", "field": "x"},
96 | "width": {"scale": "xscale", "band": 1},
97 | "y": {"scale": "yscale", "field": "y"},
98 | "y2": {"scale": "yscale", "value": 0}
99 | },
100 | "update": {
101 | "fill": [
102 | {"test": "indata('selected', '_id', datum._id)", "value": "steelblue"},
103 | {"value": "#ccc"}
104 | ]
105 | }
106 | }
107 | }
108 | ]
109 | }
--------------------------------------------------------------------------------
/docs/spec/stacked-area.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "table",
10 | "values": [
11 | {"x": 0, "y": 28, "c":0}, {"x": 0, "y": 55, "c":1},
12 | {"x": 1, "y": 43, "c":0}, {"x": 1, "y": 91, "c":1},
13 | {"x": 2, "y": 81, "c":0}, {"x": 2, "y": 53, "c":1},
14 | {"x": 3, "y": 19, "c":0}, {"x": 3, "y": 87, "c":1},
15 | {"x": 4, "y": 52, "c":0}, {"x": 4, "y": 48, "c":1},
16 | {"x": 5, "y": 24, "c":0}, {"x": 5, "y": 49, "c":1},
17 | {"x": 6, "y": 87, "c":0}, {"x": 6, "y": 66, "c":1},
18 | {"x": 7, "y": 17, "c":0}, {"x": 7, "y": 27, "c":1},
19 | {"x": 8, "y": 68, "c":0}, {"x": 8, "y": 16, "c":1},
20 | {"x": 9, "y": 49, "c":0}, {"x": 9, "y": 15, "c":1}
21 | ],
22 | "transform": [
23 | {
24 | "type": "stack",
25 | "groupby": ["x"],
26 | "sort": {"field": "c"},
27 | "field": "y"
28 | }
29 | ]
30 | },
31 | {
32 | "name": "stats",
33 | "source": "table",
34 | "transform": [
35 | {
36 | "type": "aggregate",
37 | "groupby": ["x"], "fields": ["y"], "ops": ["sum"]
38 | }
39 | ]
40 | }
41 | ],
42 |
43 | "scales": [
44 | {
45 | "name": "x",
46 | "type": "point",
47 | "range": "width",
48 | "domain": {"data": "table", "field": "x"}
49 | },
50 | {
51 | "name": "y",
52 | "type": "linear",
53 | "range": "height",
54 | "nice": true, "zero": true,
55 | "domain": {"data": "stats", "field": "sum_y"}
56 | },
57 | {
58 | "name": "color",
59 | "type": "ordinal",
60 | "scheme": "category10",
61 | "domain": {"data": "table", "field": "c"}
62 | }
63 | ],
64 |
65 | "axes": [
66 | {"orient": "bottom", "scale": "x", "zindex": 1},
67 | {"orient": "left", "scale": "y", "zindex": 1}
68 | ],
69 |
70 | "marks": [
71 | {
72 | "type": "group",
73 | "from": {
74 | "facet": {
75 | "name": "series",
76 | "data": "table",
77 | "groupby": "c"
78 | }
79 | },
80 | "marks": [
81 | {
82 | "type": "area",
83 | "from": {"data": "series"},
84 | "encode": {
85 | "enter": {
86 | "interpolate": {"value": "monotone"},
87 | "x": {"scale": "x", "field": "x"},
88 | "y": {"scale": "y", "field": "y0"},
89 | "y2": {"scale": "y", "field": "y1"},
90 | "fill": {"scale": "color", "field": "c"}
91 | },
92 | "update": {
93 | "fillOpacity": {"value": 1}
94 | },
95 | "hover": {
96 | "fillOpacity": {"value": 0.5}
97 | }
98 | }
99 | }
100 | ]
101 | }
102 | ]
103 | }
--------------------------------------------------------------------------------
/docs/spec/stacked-bar.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 500,
4 | "height": 200,
5 | "padding": 5,
6 |
7 | "data": [
8 | {
9 | "name": "table",
10 | "values": [
11 | {"x": 0, "y": 28, "c":0}, {"x": 0, "y": 55, "c":1},
12 | {"x": 1, "y": 43, "c":0}, {"x": 1, "y": 91, "c":1},
13 | {"x": 2, "y": 81, "c":0}, {"x": 2, "y": 53, "c":1},
14 | {"x": 3, "y": 19, "c":0}, {"x": 3, "y": 87, "c":1},
15 | {"x": 4, "y": 52, "c":0}, {"x": 4, "y": 48, "c":1},
16 | {"x": 5, "y": 24, "c":0}, {"x": 5, "y": 49, "c":1},
17 | {"x": 6, "y": 87, "c":0}, {"x": 6, "y": 66, "c":1},
18 | {"x": 7, "y": 17, "c":0}, {"x": 7, "y": 27, "c":1},
19 | {"x": 8, "y": 68, "c":0}, {"x": 8, "y": 16, "c":1},
20 | {"x": 9, "y": 49, "c":0}, {"x": 9, "y": 15, "c":1}
21 | ],
22 | "transform": [
23 | {
24 | "type": "stack",
25 | "groupby": ["x"],
26 | "sort": {"field": "c"},
27 | "field": "y"
28 | }
29 | ]
30 | },
31 | {
32 | "name": "stats",
33 | "source": "table",
34 | "transform": [
35 | {
36 | "type": "aggregate",
37 | "groupby": ["x"], "fields": ["y"], "ops": ["sum"]
38 | }
39 | ]
40 | }
41 | ],
42 |
43 | "scales": [
44 | {
45 | "name": "x",
46 | "type": "band",
47 | "range": "width",
48 | "domain": {"data": "table", "field": "x"}
49 | },
50 | {
51 | "name": "y",
52 | "type": "linear",
53 | "range": "height",
54 | "nice": true, "zero": true,
55 | "domain": {"data": "stats", "field": "sum_y"}
56 | },
57 | {
58 | "name": "color",
59 | "type": "ordinal",
60 | "scheme": "category10",
61 | "domain": {"data": "table", "field": "c"}
62 | }
63 | ],
64 |
65 | "axes": [
66 | {"orient": "bottom", "scale": "x", "zindex": 1},
67 | {"orient": "left", "scale": "y", "zindex": 1}
68 | ],
69 |
70 | "marks": [
71 | {
72 | "type": "rect",
73 | "from": {"data": "table"},
74 | "encode": {
75 | "enter": {
76 | "x": {"scale": "x", "field": "x"},
77 | "width": {"scale": "x", "band": 1, "offset": -1},
78 | "y": {"scale": "y", "field": "y0"},
79 | "y2": {"scale": "y", "field": "y1"},
80 | "fill": {"scale": "color", "field": "c"}
81 | },
82 | "update": {
83 | "fillOpacity": {"value": 1}
84 | },
85 | "hover": {
86 | "fillOpacity": {"value": 0.5}
87 | }
88 | }
89 | }
90 | ]
91 | }
--------------------------------------------------------------------------------
/docs/spec/stocks-index.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 650,
4 | "height": 300,
5 | "padding": 5,
6 | "autosize": "fit",
7 |
8 | "signals": [
9 | {
10 | "name": "indexDate",
11 | "update": "time('Jan 1 2005')",
12 | "on": [
13 | {
14 | "events": "mousemove",
15 | "update": "invert('x', clamp(x(), 0, width))"
16 | }
17 | ]
18 | },
19 | {
20 | "name": "maxDate",
21 | "update": "time('Mar 1 2010')"
22 | }
23 | ],
24 |
25 | "data": [
26 | {
27 | "name": "stocks",
28 | "url": "data/stocks.csv",
29 | "format": {"type": "csv", "parse": {"price":"number", "date":"date"}}
30 | },
31 | {
32 | "name": "index",
33 | "source": "stocks",
34 | "transform": [
35 | {
36 | "type": "filter",
37 | "expr": "month(datum.date) == month(indexDate) && year(datum.date) == year(indexDate)"
38 | }
39 | ]
40 | },
41 | {
42 | "name": "indexed_stocks",
43 | "source": "stocks",
44 | "transform": [
45 | {
46 | "type": "lookup", "from": "index", "key": "symbol",
47 | "fields": ["symbol"], "as": ["index"], "default": {"price": 0}
48 | },
49 | {
50 | "type": "formula",
51 | "as": "indexed_price",
52 | "expr": "datum.index.price > 0 ? (datum.price - datum.index.price)/datum.index.price : 0"
53 | }
54 | ]
55 | }
56 | ],
57 |
58 | "scales": [
59 | {
60 | "name": "x",
61 | "type": "time",
62 | "domain": {"data": "stocks", "field": "date"},
63 | "range": "width"
64 | },
65 | {
66 | "name": "y",
67 | "type": "linear",
68 | "domain": {"data": "indexed_stocks", "field": "indexed_price"},
69 | "nice": true, "zero": true,
70 | "range": "height"
71 | },
72 | {
73 | "name": "color",
74 | "type": "ordinal",
75 | "scheme": "category10",
76 | "domain": {"data": "stocks", "field": "symbol"}
77 | }
78 | ],
79 |
80 | "axes": [
81 | {"orient": "left", "scale": "y", "grid": true, "format": "%"}
82 | ],
83 |
84 | "marks": [
85 | {
86 | "type": "group",
87 | "from": {
88 | "facet": {
89 | "name": "series",
90 | "data": "indexed_stocks",
91 | "groupby": "symbol"
92 | }
93 | },
94 | "data": [
95 | {
96 | "name": "label",
97 | "source": "series",
98 | "transform": [
99 | { "type": "filter", "expr": "datum.date == maxDate" }
100 | ]
101 | }
102 | ],
103 | "marks": [
104 | {
105 | "type": "line",
106 | "from": {"data": "series"},
107 | "encode": {
108 | "update": {
109 | "x": {"scale": "x", "field": "date"},
110 | "y": {"scale": "y", "field": "indexed_price"},
111 | "stroke": {"scale": "color", "field": "symbol"},
112 | "strokeWidth": {"value": 2}
113 | }
114 | }
115 | },
116 | {
117 | "type": "text",
118 | "from": {"data": "label"},
119 | "encode": {
120 | "update": {
121 | "x": {"scale": "x", "field": "date", "offset": 2},
122 | "y": {"scale": "y", "field": "indexed_price"},
123 | "fill": {"scale": "color", "field": "symbol"},
124 | "text": {"field": "symbol"},
125 | "baseline": {"value": "middle"}
126 | }
127 | }
128 | }
129 | ]
130 | },
131 | {
132 | "type": "rule",
133 | "encode": {
134 | "update": {
135 | "x": {"field": {"group": "x"}},
136 | "x2": {"field": {"group": "width"}},
137 | "y": {"scale": "y", "value": 0, "offset": 0.5},
138 | "stroke": {"value": "black"},
139 | "strokeWidth": {"value": 1}
140 | }
141 | }
142 | },
143 | {
144 | "type": "rule",
145 | "encode": {
146 | "update": {
147 | "x": {"scale": "x", "signal": "indexDate", "offset": 0.5},
148 | "y": {"value": 0},
149 | "y2": {"field": {"group": "height"}},
150 | "stroke": {"value": "red"}
151 | }
152 | }
153 | },
154 | {
155 | "type": "text",
156 | "encode": {
157 | "update": {
158 | "x": {"scale": "x", "signal": "indexDate"},
159 | "y2": {"field": {"group": "height"}, "offset": 15},
160 | "align": {"value": "center"},
161 | "text": {"signal": "timeFormat(indexDate, '%b %Y')"},
162 | "fill": {"value": "red"}
163 | }
164 | }
165 | }
166 | ]
167 | }
--------------------------------------------------------------------------------
/docs/spec/tree-radial.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 810,
4 | "height": 810,
5 | "padding": 20,
6 |
7 | "signals": [
8 | {
9 | "name": "labels", "value": true,
10 | "bind": {"type": "checkbox"}
11 | },
12 | {
13 | "name": "radius", "value": 330,
14 | "bind": {"type": "range", "min": 20, "max": 600}
15 | },
16 | {
17 | "name": "angle", "value": 360,
18 | "bind": {"type": "range", "min": 0, "max": 360, "step": 1}
19 | },
20 | {
21 | "name": "layout", "value": "tidy",
22 | "bind": {"type": "radio", "options": ["tidy", "cluster"]}
23 | },
24 | {
25 | "name": "links", "value": "line",
26 | "bind": {
27 | "type": "radio",
28 | "options": ["line", "curve", "diagonal", "orthogonal"]
29 | }
30 | },
31 | { "name": "originX", "update": "width / 2" },
32 | { "name": "originY", "update": "height / 2" }
33 | ],
34 |
35 | "data": [
36 | {
37 | "name": "tree",
38 | "url": "data/flare.json",
39 | "transform": [
40 | {
41 | "type": "stratify",
42 | "key": "id",
43 | "parentKey": "parent"
44 | },
45 | {
46 | "type": "tree",
47 | "method": {"signal": "layout"},
48 | "size": [{"signal": "angle"}, {"signal": "radius"}],
49 | "as": ["degrees", "radius", "depth", "children"]
50 | },
51 | {
52 | "type": "formula",
53 | "expr": "PI * (datum.degrees / 180 - 0.5)",
54 | "as": "angle"
55 | }
56 | ]
57 | },
58 | {
59 | "name": "links",
60 | "source": "tree",
61 | "transform": [
62 | { "type": "treelinks" },
63 | {
64 | "type": "linkpath",
65 | "shape": {"signal": "links"}, "orient": "radial",
66 | "sourceX": "source.angle", "sourceY": "source.radius",
67 | "targetX": "target.angle", "targetY": "target.radius"
68 | }
69 | ]
70 | }
71 | ],
72 |
73 | "scales": [
74 | {
75 | "name": "color",
76 | "type": "sequential", "scheme": "magma",
77 | "domain": {"data": "tree", "field": "depth"},
78 | "zero": true
79 | }
80 | ],
81 |
82 | "marks": [
83 | {
84 | "type": "path",
85 | "from": {"data": "links"},
86 | "encode": {
87 | "update": {
88 | "x": {"signal": "originX"},
89 | "y": {"signal": "originY"},
90 | "path": {"field": "path"},
91 | "stroke": {"value": "#ccc"}
92 | }
93 | }
94 | },
95 | {
96 | "type": "symbol",
97 | "from": {"data": "tree"},
98 | "encode": {
99 | "update": {
100 | "x": {"signal": "originX + datum.radius * cos(datum.angle)"},
101 | "y": {"signal": "originY + datum.radius * sin(datum.angle)"},
102 | "size": {"value": 100},
103 | "stroke": {"value": "#fff"},
104 | "fill": {"scale": "color", "field": "depth"}
105 | }
106 | }
107 | },
108 | {
109 | "type": "text",
110 | "from": {"data": "tree"},
111 | "encode": {
112 | "update": {
113 | "x": {"signal": "originX + datum.radius * cos(datum.angle)"},
114 | "y": {"signal": "originY + datum.radius * sin(datum.angle)"},
115 | "dx": {"signal": "(datum.degrees >= 180 ? -1 : 1) * 6"},
116 | "text": {"field": "name"},
117 | "fontSize": {"value": 9},
118 | "angle": {"signal": "datum.degrees >= 180 ? datum.degrees - 270 : datum.degrees - 90"},
119 | "align": {"signal": "datum.degrees >= 180 ? 'right' : 'left'"},
120 | "baseline": {"value": "middle"},
121 | "opacity": {"signal": "labels ? 1 : 0"}
122 | }
123 | }
124 | }
125 | ]
126 | }
--------------------------------------------------------------------------------
/docs/spec/treemap.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 960,
4 | "height": 500,
5 | "padding": 2.5,
6 | "autosize": "none",
7 |
8 | "data": [
9 | {
10 | "name": "tree",
11 | "url": "data/flare.json",
12 | "transform": [
13 | {
14 | "type": "stratify",
15 | "key": "id",
16 | "parentKey": "parent"
17 | },
18 | {
19 | "type": "treemap",
20 | "field": "size",
21 | "sort": {"field": "value"},
22 | "round": true,
23 | "size": [{"signal": "width"}, {"signal": "height"}]
24 | }
25 | ]
26 | },
27 | {
28 | "name": "nodes",
29 | "source": "tree",
30 | "transform": [{ "type": "filter", "expr": "datum.children" }]
31 | },
32 | {
33 | "name": "leaves",
34 | "source": "tree",
35 | "transform": [{ "type": "filter", "expr": "!datum.children" }]
36 | }
37 | ],
38 |
39 | "scales": [
40 | {
41 | "name": "color",
42 | "type": "ordinal",
43 | "range": [
44 | "#3182bd", "#6baed6", "#9ecae1", "#c6dbef", "#e6550d",
45 | "#fd8d3c", "#fdae6b", "#fdd0a2", "#31a354", "#74c476",
46 | "#a1d99b", "#c7e9c0", "#756bb1", "#9e9ac8", "#bcbddc",
47 | "#dadaeb", "#636363", "#969696", "#bdbdbd", "#d9d9d9"
48 | ]
49 | },
50 | {
51 | "name": "size",
52 | "type": "ordinal",
53 | "domain": [0, 1, 2, 3],
54 | "range": [256, 28, 20, 14]
55 | },
56 | {
57 | "name": "opacity",
58 | "type": "ordinal",
59 | "domain": [0, 1, 2, 3],
60 | "range": [0.15, 0.5, 0.8, 1.0]
61 | }
62 | ],
63 |
64 | "marks": [
65 | {
66 | "type": "rect",
67 | "from": {"data": "nodes"},
68 | "interactive": false,
69 | "encode": {
70 | "enter": {
71 | "x": {"field": "x0"},
72 | "y": {"field": "y0"},
73 | "x2": {"field": "x1"},
74 | "y2": {"field": "y1"},
75 | "fill": {"scale": "color", "field": "name"}
76 | }
77 | }
78 | },
79 | {
80 | "type": "rect",
81 | "from": {"data": "leaves"},
82 | "encode": {
83 | "enter": {
84 | "x": {"field": "x0"},
85 | "y": {"field": "y0"},
86 | "x2": {"field": "x1"},
87 | "y2": {"field": "y1"},
88 | "stroke": {"value": "#fff"}
89 | },
90 | "update": {
91 | "fill": {"value": "transparent"}
92 | },
93 | "hover": {
94 | "fill": {"value": "red"}
95 | }
96 | }
97 | },
98 | {
99 | "type": "text",
100 | "from": {"data": "nodes"},
101 | "interactive": false,
102 | "encode": {
103 | "enter": {
104 | "x": {"signal": "0.5 * (datum.x0 + datum.x1)"},
105 | "y": {"signal": "0.5 * (datum.y0 + datum.y1)"},
106 | "font": {"value": "Helvetica Neue"},
107 | "align": {"value": "center"},
108 | "baseline": {"value": "middle"},
109 | "fill": {"value": "#000"},
110 | "text": {"field": "name"},
111 | "fontSize": {"scale": "size", "field": "depth"},
112 | "fillOpacity": {"scale": "opacity", "field": "depth"}
113 | }
114 | }
115 | }
116 | ]
117 | }
118 |
--------------------------------------------------------------------------------
/docs/spec/violin-plot.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "height": 500,
4 | "padding": 5,
5 |
6 | "config": {
7 | "axisBand": {
8 | "bandPosition": 1,
9 | "tickExtra": true
10 | }
11 | },
12 |
13 | "signals": [
14 | { "name": "fields",
15 | "value": ["petalWidth", "petalLength", "sepalWidth", "sepalLength"] },
16 | { "name": "plotWidth", "value": 60 },
17 | { "name": "width", "update": "(plotWidth + 10) * length(fields)"},
18 | { "name": "bandwidth", "value": 0,
19 | "bind": {"type": "range", "min": 0, "max": 0.5, "step": 0.005} },
20 | { "name": "steps", "value": 100,
21 | "bind": {"type": "range", "min": 10, "max": 500, "step": 1} }
22 | ],
23 |
24 | "data": [
25 | {
26 | "name": "iris",
27 | "url": "data/iris.json",
28 | "transform": [
29 | {
30 | "type": "fold",
31 | "fields": {"signal": "fields"},
32 | "as": ["organ", "value"]
33 | }
34 | ]
35 | }
36 | ],
37 |
38 | "scales": [
39 | {
40 | "name": "layout",
41 | "type": "band",
42 | "range": "width",
43 | "domain": {"data": "iris", "field": "organ"}
44 | },
45 | {
46 | "name": "yscale",
47 | "type": "linear",
48 | "range": "height", "round": true,
49 | "domain": {"data": "iris", "field": "value"},
50 | "zero": true, "nice": true
51 | },
52 | {
53 | "name": "color",
54 | "type": "ordinal",
55 | "scheme": "category20"
56 | }
57 | ],
58 |
59 | "axes": [
60 | {"orient": "bottom", "scale": "layout", "zindex": 1},
61 | {"orient": "left", "scale": "yscale", "tickCount": 5, "zindex": 1}
62 | ],
63 |
64 | "marks": [
65 | {
66 | "type": "group",
67 | "from": {
68 | "facet": {
69 | "data": "iris",
70 | "name": "organs",
71 | "groupby": "organ"
72 | }
73 | },
74 |
75 | "encode": {
76 | "enter": {
77 | "xc": {"scale": "layout", "field": "organ", "band": 0.5},
78 | "width": {"signal": "plotWidth"},
79 | "height": {"signal": "height"}
80 | }
81 | },
82 |
83 | "data": [
84 | {
85 | "name": "density",
86 | "transform": [
87 | {
88 | "type": "density",
89 | "steps": {"signal": "steps"},
90 | "distribution": {
91 | "function": "kde",
92 | "from": "organs",
93 | "field": "value",
94 | "bandwidth": {"signal": "bandwidth"}
95 | }
96 | },
97 | {
98 | "type": "stack",
99 | "groupby": ["value"],
100 | "field": "density",
101 | "offset": "center",
102 | "as": ["x0", "x1"]
103 | }
104 | ]
105 | },
106 | {
107 | "name": "summary",
108 | "source": "organs",
109 | "transform": [
110 | {
111 | "type": "aggregate",
112 | "fields": ["value", "value", "value"],
113 | "ops": ["q1", "median", "q3"],
114 | "as": ["q1", "median", "q3"]
115 | }
116 | ]
117 | }
118 | ],
119 |
120 | "scales": [
121 | {
122 | "name": "xscale",
123 | "type": "linear",
124 | "range": [0, {"signal": "plotWidth"}],
125 | "domain": {"data": "density", "field": "density"}
126 | }
127 | ],
128 |
129 | "marks": [
130 | {
131 | "type": "area",
132 | "from": {"data": "density"},
133 | "encode": {
134 | "enter": {
135 | "orient": {"value": "horizontal"},
136 | "fill": {"scale": "color", "field": {"parent": "organ"}}
137 | },
138 | "update": {
139 | "y": {"scale": "yscale", "field": "value"},
140 | "x": {"scale": "xscale", "field": "x0"},
141 | "x2": {"scale": "xscale", "field": "x1"}
142 | }
143 | }
144 | },
145 | {
146 | "type": "rect",
147 | "from": {"data": "summary"},
148 | "encode": {
149 | "enter": {
150 | "fill": {"value": "black"},
151 | "width": {"value": 1}
152 | },
153 | "update": {
154 | "xc": {"signal": "plotWidth / 2", "offset": -0.5},
155 | "y": {"scale": "yscale", "field": "q1"},
156 | "y2": {"scale": "yscale", "field": "q3"}
157 | }
158 | }
159 | },
160 | {
161 | "type": "rect",
162 | "from": {"data": "summary"},
163 | "encode": {
164 | "enter": {
165 | "fill": {"value": "black"},
166 |
167 | "height": {"value": 2}
168 | },
169 | "update": {
170 | "xc": {"signal": "plotWidth / 2"},
171 | "width": {"value": 8},
172 | "y": {"scale": "yscale", "field": "median"}
173 | }
174 | }
175 | }
176 | ]
177 | }
178 | ]
179 | }
--------------------------------------------------------------------------------
/docs/spec/weather.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "width": 250,
4 | "height": 200,
5 |
6 | "data": [
7 | {
8 | "name": "weather",
9 | "url": "data/weather.json"
10 | },
11 | {
12 | "name": "actual",
13 | "source": "weather",
14 | "transform": [{"type":"filter", "expr":"datum.actual"}]
15 | },
16 | {
17 | "name": "forecast",
18 | "source": "weather",
19 | "transform": [{"type":"filter", "expr":"datum.forecast"}]
20 | }
21 | ],
22 |
23 | "scales": [
24 | {
25 | "name": "x",
26 | "type": "band",
27 | "range": "width",
28 | "padding": 0.1, "round": true,
29 | "domain": {"data": "weather", "field": "id"}
30 | },
31 | {
32 | "name": "y",
33 | "type": "linear",
34 | "range": "height",
35 | "nice": true, "zero": false, "round": true,
36 | "domain": {
37 | "data": "weather",
38 | "fields": ["record.low", "record.high"]
39 | }
40 | }
41 | ],
42 |
43 | "axes": [
44 | {
45 | "orient": "right",
46 | "scale": "y",
47 | "tickCount": 3,
48 | "tickSize": 0,
49 | "labelPadding": 0,
50 | "grid": true,
51 | "domain": false,
52 | "zindex": 1,
53 | "encode": {
54 | "grid": {"enter": {"stroke": {"value": "white"}}}
55 | }
56 | }
57 | ],
58 |
59 | "marks": [
60 | {
61 | "type": "text",
62 | "from": {"data": "weather"},
63 | "encode": {
64 | "enter": {
65 | "x": {"scale": "x", "field": "id"},
66 | "dx": {"scale": "x", "band": 0.5},
67 | "y": {"value": 0},
68 | "fill": {"value": "#000"},
69 | "text": {"field": "day"},
70 | "align": {"value": "center"},
71 | "baseline": {"value": "bottom"}
72 | }
73 | }
74 | },
75 | {
76 | "type": "rect",
77 | "from": {"data": "weather"},
78 | "encode": {
79 | "enter": {
80 | "x": {"scale": "x", "field": "id"},
81 | "width": {"scale": "x", "band": 1, "offset": -1},
82 | "y": {"scale": "y", "field": "record.low"},
83 | "y2": {"scale": "y", "field": "record.high"},
84 | "fill": {"value": "#ccc"}
85 | }
86 | }
87 | },
88 | {
89 | "type": "rect",
90 | "from": {"data": "weather"},
91 | "encode": {
92 | "enter": {
93 | "x": {"scale": "x", "field": "id"},
94 | "width": {"scale": "x", "band": 1, "offset": -1},
95 | "y": {"scale": "y", "field": "normal.low"},
96 | "y2": {"scale": "y", "field": "normal.high"},
97 | "fill": {"value": "#999"}
98 | }
99 | }
100 | },
101 | {
102 | "type": "rect",
103 | "from": {"data": "actual"},
104 | "encode": {
105 | "enter": {
106 | "x": {"scale": "x", "field": "id", "offset": 4},
107 | "width": {"scale": "x", "band": 1, "offset": -8},
108 | "y": {"scale": "y", "field": "actual.low"},
109 | "y2": {"scale": "y", "field": "actual.high"},
110 | "fill": {"value": "#000"}
111 | }
112 | }
113 | },
114 | {
115 | "type": "rect",
116 | "from": {"data": "forecast"},
117 | "encode": {
118 | "enter": {
119 | "x": {"scale": "x", "field": "id", "offset": 9},
120 | "width": {"scale": "x", "band": 1, "offset": -18},
121 | "y": {"scale": "y", "field": "forecast.low.low"},
122 | "y2": {"scale": "y", "field": "forecast.high.high"},
123 | "fill": {"value": "#000"}
124 | }
125 | }
126 | },
127 | {
128 | "type": "rect",
129 | "from": {"data": "forecast"},
130 | "encode": {
131 | "enter": {
132 | "x": {"scale": "x", "field": "id", "offset": 4},
133 | "width": {"scale": "x", "band": 1, "offset": -8},
134 | "y": {"scale": "y", "field": "forecast.low.low"},
135 | "y2": {"scale": "y", "field": "forecast.low.high"},
136 | "fill": {"value": "#000"}
137 | }
138 | }
139 | },
140 | {
141 | "type": "rect",
142 | "from": {"data": "forecast"},
143 | "encode": {
144 | "enter": {
145 | "x": {"scale": "x", "field": "id", "offset": 4},
146 | "width": {"scale": "x", "band": 1, "offset": -8},
147 | "y": {"scale": "y", "field": "forecast.high.low"},
148 | "y2": {"scale": "y", "field": "forecast.high.high"},
149 | "fill": {"value": "#000"}
150 | }
151 | }
152 | }
153 | ]
154 | }
155 |
--------------------------------------------------------------------------------
/docs/spec/wordcloud.vg.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {"language": "vega", "version": "3.0"},
3 | "name": "wordcloud",
4 | "width": 800,
5 | "height": 400,
6 | "padding": 0,
7 |
8 | "data": [
9 | {
10 | "name": "table",
11 | "values": [
12 | "Declarative visualization grammars can accelerate development, facilitate retargeting across platforms, and allow language-level optimizations. However, existing declarative visualization languages are primarily concerned with visual encoding, and rely on imperative event handlers for interactive behaviors. In response, we introduce a model of declarative interaction design for data visualizations. Adopting methods from reactive programming, we model low-level events as composable data streams from which we form higher-level semantic signals. Signals feed predicates and scale inversions, which allow us to generalize interactive selections at the level of item geometry (pixels) into interactive queries over the data domain. Production rules then use these queries to manipulate the visualization’s appearance. To facilitate reuse and sharing, these constructs can be encapsulated as named interactors: standalone, purely declarative specifications of interaction techniques. We assess our model’s feasibility and expressivity by instantiating it with extensions to the Vega visualization grammar. Through a diverse range of examples, we demonstrate coverage over an established taxonomy of visualization interaction techniques.",
13 | "We present Reactive Vega, a system architecture that provides the first robust and comprehensive treatment of declarative visual and interaction design for data visualization. Starting from a single declarative specification, Reactive Vega constructs a dataflow graph in which input data, scene graph elements, and interaction events are all treated as first-class streaming data sources. To support expressive interactive visualizations that may involve time-varying scalar, relational, or hierarchical data, Reactive Vega’s dataflow graph can dynamically re-write itself at runtime by extending or pruning branches in a data-driven fashion. We discuss both compile- and run-time optimizations applied within Reactive Vega, and share the results of benchmark studies that indicate superior interactive performance to both D3 and the original, non-reactive Vega system.",
14 | "We present Vega-Lite, a high-level grammar that enables rapid specification of interactive data visualizations. Vega-Lite combines a traditional grammar of graphics, providing visual encoding rules and a composition algebra for layered and multi-view displays, with a novel grammar of interaction. Users specify interactive semantics by composing selections. In Vega-Lite, a selection is an abstraction that defines input event processing, points of interest, and a predicate function for inclusion testing. Selections parameterize visual encodings by serving as input data, defining scale extents, or by driving conditional logic. The Vega-Lite compiler automatically synthesizes requisite data flow and event handling logic, which users can override for further customization. In contrast to existing reactive specifications, Vega-Lite selections decompose an interaction design into concise, enumerable semantic units. We evaluate Vega-Lite through a range of examples, demonstrating succinct specification of both customized interaction methods and common techniques such as panning, zooming, and linked selection."
15 | ],
16 | "transform": [
17 | {
18 | "type": "countpattern",
19 | "field": "data",
20 | "case": "upper",
21 | "pattern": "[\\w']{3,}",
22 | "stopwords": "(i|me|my|myself|we|us|our|ours|ourselves|you|your|yours|yourself|yourselves|he|him|his|himself|she|her|hers|herself|it|its|itself|they|them|their|theirs|themselves|what|which|who|whom|whose|this|that|these|those|am|is|are|was|were|be|been|being|have|has|had|having|do|does|did|doing|will|would|should|can|could|ought|i'm|you're|he's|she's|it's|we're|they're|i've|you've|we've|they've|i'd|you'd|he'd|she'd|we'd|they'd|i'll|you'll|he'll|she'll|we'll|they'll|isn't|aren't|wasn't|weren't|hasn't|haven't|hadn't|doesn't|don't|didn't|won't|wouldn't|shan't|shouldn't|can't|cannot|couldn't|mustn't|let's|that's|who's|what's|here's|there's|when's|where's|why's|how's|a|an|the|and|but|if|or|because|as|until|while|of|at|by|for|with|about|against|between|into|through|during|before|after|above|below|to|from|up|upon|down|in|out|on|off|over|under|again|further|then|once|here|there|when|where|why|how|all|any|both|each|few|more|most|other|some|such|no|nor|not|only|own|same|so|than|too|very|say|says|said|shall)"
23 | },
24 | {
25 | "type": "formula", "as": "angle",
26 | "expr": "[-45, 0, 45][~~(random() * 3)]"
27 | },
28 | {
29 | "type": "formula", "as": "weight",
30 | "expr": "if(datum.text=='VEGA', 600, 300)"
31 | }
32 | ]
33 | }
34 | ],
35 |
36 | "scales": [
37 | {
38 | "name": "color",
39 | "type": "ordinal",
40 | "range": ["#d5a928", "#652c90", "#939597"]
41 | }
42 | ],
43 |
44 | "marks": [
45 | {
46 | "type": "text",
47 | "from": {"data": "table"},
48 | "encode": {
49 | "enter": {
50 | "text": {"field": "text"},
51 | "align": {"value": "center"},
52 | "baseline": {"value": "alphabetic"},
53 | "fill": {"scale": "color", "field": "text"}
54 | },
55 | "update": {
56 | "fillOpacity": {"value": 1}
57 | },
58 | "hover": {
59 | "fillOpacity": {"value": 0.5}
60 | }
61 | },
62 | "transform": [
63 | {
64 | "type": "wordcloud",
65 | "size": [800, 400],
66 | "text": {"field": "text"},
67 | "rotate": {"field": "datum.angle"},
68 | "font": "Helvetica Neue",
69 | "fontSize": {"field": "datum.count"},
70 | "fontWeight": {"field": "datum.weight"},
71 | "fontSizeRange": [12, 56],
72 | "padding": 2
73 | }
74 | ]
75 | }
76 | ]
77 | }
--------------------------------------------------------------------------------
/docs/specs.json:
--------------------------------------------------------------------------------
1 | [
2 | "airports",
3 | "arc",
4 | "area",
5 | "bandsize",
6 | "bar",
7 | "bar-hover-label",
8 | "barley",
9 | "budget-forecasts",
10 | "chart",
11 | "choropleth",
12 | "crossfilter",
13 | "crossfilter-multi",
14 | "density",
15 | "dimpvis",
16 | "driving",
17 | "error",
18 | "falkensee",
19 | "force-network",
20 | "force-beeswarm",
21 | "gradient",
22 | "grouped-bar",
23 | "heatmap",
24 | "heatmap-lines",
25 | "histogram",
26 | "horizon",
27 | "images",
28 | "jobs",
29 | "legends",
30 | "lifelines",
31 | "map",
32 | "map-bind",
33 | "matrix-reorder",
34 | "movies-sort",
35 | "nested",
36 | "overview-detail",
37 | "panzoom",
38 | "parallel-coords",
39 | "playfair",
40 | "population",
41 | "shift-select",
42 | "splom-inner",
43 | "splom-outer",
44 | "stacked-area",
45 | "stacked-bar",
46 | "stocks-index",
47 | "tree-radial",
48 | "treemap",
49 | "violin-plot",
50 | "weather",
51 | "wordcloud"
52 | ]
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import {CanvasHandler, renderModule} from 'vega-scenegraph';
2 | import {default as WebGLRenderer} from './src/WebGLRenderer';
3 |
4 | // Patch CanvasHandler
5 | CanvasHandler.prototype.context = function() {
6 | return this._canvas.getContext('2d') || this._canvas._textCanvas.getContext('2d');
7 | };
8 |
9 | renderModule('webgl', {handler: CanvasHandler, renderer: WebGLRenderer});
10 |
11 | export {WebGLRenderer};
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vega-webgl-renderer",
3 | "version": "1.0.0-beta.2",
4 | "description": "Vega WebGL renderer.",
5 | "license": "BSD-3-Clause",
6 | "author": {
7 | "name": "Jeffrey Baumes",
8 | "url": "http://www.kitware.com/company/team/baumes.html"
9 | },
10 | "contributors": [],
11 | "main": "build/vega-webgl-renderer.js",
12 | "module": "index",
13 | "jsnext:main": "index",
14 | "repository": {
15 | "type": "git",
16 | "url": "http://github.com/jeffbaumes/vega-webgl-renderer.git"
17 | },
18 | "scripts": {
19 | "prebuild": "rm -rf build && mkdir build",
20 | "build": "bin/rollup",
21 | "postbuild": "uglifyjs build/vega-webgl-renderer.js -c -m -o build/vega-webgl-renderer.min.js",
22 | "test:server": "sh test/test-server-up.sh >.server.log",
23 | "test:server:down": "sh test/test-server-down.sh",
24 | "test:selenium": "sh test/test-selenium-up.sh >.selenium.log",
25 | "test:selenium:down": "sh test/test-selenium-down.sh",
26 | "lint": "eslint index.js src test",
27 | "test": "result=true; selenium-standalone install; npm run test:server:down; npm run test:selenium:down; npm run test:server && npm run test:selenium && sleep 5 && wdio wdio.conf.js && npm run lint || result=false; npm run test:server:down; npm run test:selenium:down; ${result}",
28 | "prepublish": "npm run build",
29 | "postpublish": "git push && git push --tags && zip -j build/vega-webgl-renderer.zip -- LICENSE README.md build/vega-webgl-renderer.js build/vega-webgl-renderer.min.js"
30 | },
31 | "dependencies": {
32 | "d3-color": "1",
33 | "extrude-polyline": "^1.0.6",
34 | "parse-svg-path": "^0.1.2",
35 | "simplify-path": "^1.1.0",
36 | "svg-path-contours": "^2.0.0",
37 | "triangulate-contours": "^1.0.2",
38 | "vega-scenegraph": ">=2.0.0-beta"
39 | },
40 | "devDependencies": {
41 | "eslint": "2",
42 | "form-data": "^2.1.2",
43 | "glob": "^7.1.1",
44 | "http-server": "^0.9.0",
45 | "rollup": "0.36",
46 | "rollup-plugin-commonjs": "^5.0.5",
47 | "rollup-plugin-node-resolve": "^2.0.0",
48 | "selenium-standalone": "^5.9.0",
49 | "uglify-js": "2",
50 | "wdio-dot-reporter": "0.0.6",
51 | "wdio-mocha-framework": "^0.5.4",
52 | "webdriverio": "^4.4.0"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/scripts/lotsa_points.py:
--------------------------------------------------------------------------------
1 | import json
2 | import random
3 |
4 | data = [{'u': random.random(), 'v': random.random()} for i in range(100000)]
5 |
6 | print json.dumps(data)
7 |
8 |
--------------------------------------------------------------------------------
/src/marks/arc.js:
--------------------------------------------------------------------------------
1 | import {arc} from '../path/shapes';
2 | import markItemPath from './markItemPath';
3 |
4 | export default markItemPath('arc', arc);
5 |
--------------------------------------------------------------------------------
/src/marks/area.js:
--------------------------------------------------------------------------------
1 | import {area} from '../path/shapes';
2 | import markMultiItemPath from './markMultiItemPath';
3 |
4 | export default markMultiItemPath('area', area);
5 |
--------------------------------------------------------------------------------
/src/marks/group.js:
--------------------------------------------------------------------------------
1 | import {sceneVisit as visit} from 'vega-scenegraph';
2 | import {rectangleGL} from '../path/shapes';
3 | import geometryForItem from '../path/geometryForItem';
4 | import drawGeometry from '../util/drawGeometry';
5 |
6 | function drawGL(context, scene, bounds) {
7 | var renderer = this;
8 |
9 | visit(scene, function(group) {
10 | var gx = group.x || 0,
11 | gy = group.y || 0,
12 | w = group.width || 0,
13 | h = group.height || 0,
14 | offset, oldClip;
15 |
16 | // setup graphics context
17 | context._tx += gx;
18 | context._ty += gy;
19 | context._textContext.save();
20 | context._textContext.translate(gx, gy);
21 |
22 | // draw group background
23 | if (context._fullRedraw || group._dirty || !group._geom || group._geom.deleted) {
24 | offset = group.stroke ? 0.5 : 0;
25 | var shapeGeom = rectangleGL(context, group, offset, offset);
26 | group._geom = geometryForItem(context, group, shapeGeom);
27 | }
28 | drawGeometry(group._geom, context, group);
29 |
30 | // set clip and bounds
31 | if (group.clip) {
32 | oldClip = context._clip;
33 | context._clip = [
34 | context._origin[0] + context._tx,
35 | context._origin[1] + context._ty,
36 | context._origin[0] + context._tx + w,
37 | context._origin[1] + context._ty + h
38 | ];
39 | }
40 | if (bounds) bounds.translate(-gx, -gy);
41 |
42 | // draw group contents
43 | visit(group, function(item) {
44 | renderer.draw(context, item, bounds);
45 | });
46 |
47 | // restore graphics context
48 | if (bounds) bounds.translate(gx, gy);
49 | if (group.clip) {
50 | context._clip = oldClip;
51 | }
52 |
53 | context._tx -= gx;
54 | context._ty -= gy;
55 | context._textContext.restore();
56 | });
57 | }
58 |
59 | export default {
60 | type: 'group',
61 | drawGL: drawGL
62 | };
63 |
--------------------------------------------------------------------------------
/src/marks/image.js:
--------------------------------------------------------------------------------
1 | import {sceneVisit as visit} from 'vega-scenegraph';
2 | import {loadImageAndCreateTextureInfo} from '../util/image';
3 |
4 | function getImage(item, renderer) {
5 | var image = item.image;
6 | if (!image || image.url !== item.url) {
7 | image = {loaded: false, width: 0, height: 0};
8 | renderer.loadImage(item.url).then(function(image) {
9 | item.image = image;
10 | item.image.url = item.url;
11 | });
12 | }
13 | return image;
14 | }
15 |
16 | function imageXOffset(align, w) {
17 | return align === 'center' ? w / 2 : align === 'right' ? w : 0;
18 | }
19 |
20 | function imageYOffset(baseline, h) {
21 | return baseline === 'middle' ? h / 2 : baseline === 'bottom' ? h : 0;
22 | }
23 |
24 | function drawGL(context, scene, bounds) {
25 | var renderer = this;
26 |
27 | visit(scene, function(item) {
28 | if (bounds && !bounds.intersects(item.bounds)) return; // bounds check
29 |
30 | var image = getImage(item, renderer),
31 | x = item.x || 0,
32 | y = item.y || 0,
33 | w = item.width || image.width || 0,
34 | h = item.height || image.height || 0;
35 |
36 | x -= imageXOffset(item.align, w);
37 | y -= imageYOffset(item.baseline, h);
38 |
39 | if (image.loaded) {
40 | var imgInfo = loadImageAndCreateTextureInfo(context, image);
41 | imgInfo.x = x + context._tx + context._origin[0];
42 | imgInfo.y = y + context._ty + context._origin[1];
43 | imgInfo.w = w;
44 | imgInfo.h = h;
45 | context._images.push(imgInfo);
46 | }
47 | });
48 | }
49 |
50 | export default {
51 | type: 'image',
52 | drawGL: drawGL
53 | };
54 |
--------------------------------------------------------------------------------
/src/marks/index.js:
--------------------------------------------------------------------------------
1 | import arc from './arc';
2 | import area from './area';
3 | import group from './group';
4 | import image from './image';
5 | import line from './line';
6 | import path from './path';
7 | import rect from './rect';
8 | import rule from './rule';
9 | import shape from './shape';
10 | import symbol from './symbol';
11 | import text from './text';
12 |
13 | export default {
14 | arc: arc,
15 | area: area,
16 | group: group,
17 | image: image,
18 | line: line,
19 | path: path,
20 | rect: rect,
21 | rule: rule,
22 | shape: shape,
23 | symbol: symbol,
24 | text: text
25 | };
26 |
--------------------------------------------------------------------------------
/src/marks/line.js:
--------------------------------------------------------------------------------
1 | import {line} from '../path/shapes';
2 | import markMultiItemPath from './markMultiItemPath';
3 |
4 | export default markMultiItemPath('line', line);
5 |
--------------------------------------------------------------------------------
/src/marks/markItemPath.js:
--------------------------------------------------------------------------------
1 | import {sceneVisit as visit} from 'vega-scenegraph';
2 | import drawGeometry from '../util/drawGeometry';
3 | import geometryForItem from '../path/geometryForItem';
4 |
5 | export default function(type, shape) {
6 |
7 | function drawGL(context, scene, bounds) {
8 | visit(scene, function(item) {
9 | if (bounds && !bounds.intersects(item.bounds)) return; // bounds check
10 |
11 | var x = item.x || 0,
12 | y = item.y || 0,
13 | shapeGeom;
14 |
15 | context._tx += x;
16 | context._ty += y;
17 |
18 | if (context._fullRedraw || item._dirty || !item._geom || item._geom.deleted) {
19 | shapeGeom = shape(context, item);
20 | item._geom = geometryForItem(context, item, shapeGeom);
21 | }
22 | drawGeometry(item._geom, context, item);
23 |
24 | context._tx -= x;
25 | context._ty -= y;
26 | });
27 | }
28 |
29 | return {
30 | type: type,
31 | drawGL: drawGL
32 | };
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/marks/markMultiItemPath.js:
--------------------------------------------------------------------------------
1 | import drawGeometry from '../util/drawGeometry';
2 | import geometryForItem from '../path/geometryForItem';
3 |
4 | export default function(type, shape) {
5 |
6 | function drawGL(context, scene, bounds) {
7 | if (scene.items.length && (!bounds || bounds.intersects(scene.bounds))) {
8 | var item = scene.items[0];
9 | var dirty = false;
10 | for (var i = 0; i < scene.items.length; i++) {
11 | if (scene.items[i]._dirty) {
12 | dirty = true;
13 | break;
14 | }
15 | }
16 | if (context._fullRedraw || dirty || !item._geom || item._geom.deleted) {
17 | var shapeGeom = shape(context, scene.items);
18 | item._geom = geometryForItem(context, item, shapeGeom);
19 | }
20 | drawGeometry(item._geom, context, item);
21 | }
22 | }
23 |
24 | return {
25 | type: type,
26 | drawGL: drawGL
27 | };
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/marks/path.js:
--------------------------------------------------------------------------------
1 | import {sceneVisit as visit} from 'vega-scenegraph';
2 | import drawGeometry from '../util/drawGeometry';
3 | import geometryForPath from '../path/geometryForPath';
4 | import geometryForItem from '../path/geometryForItem';
5 |
6 | function drawGL(context, scene) {
7 | visit(scene, function(item) {
8 | var path = item.path;
9 | if (path == null) return true;
10 |
11 | var x = item.x || 0,
12 | y = item.y || 0;
13 |
14 | context._tx += x;
15 | context._ty += y;
16 |
17 | if (context._fullRedraw || item._dirty || !item._geom || item._geom.deleted) {
18 | var shapeGeom = geometryForPath(context, path);
19 | item._geom = geometryForItem(context, item, shapeGeom);
20 | }
21 | drawGeometry(item._geom, context, item);
22 |
23 | context._tx -= x;
24 | context._ty -= y;
25 | });
26 | }
27 |
28 | export default {
29 | type: 'path',
30 | drawGL: drawGL
31 | };
32 |
--------------------------------------------------------------------------------
/src/marks/rule.js:
--------------------------------------------------------------------------------
1 | import {sceneVisit as visit} from 'vega-scenegraph';
2 | import drawGeometry from '../util/drawGeometry';
3 | import geometryForItem from '../path/geometryForItem';
4 |
5 | function drawGL(context, scene, bounds) {
6 | visit(scene, function(item) {
7 | var x1, y1, x2, y2, shapeGeom;
8 | if (bounds && !bounds.intersects(item.bounds)) return; // bounds check
9 | if (context._fullRedraw || item._dirty || !item._geom || item._geom.deleted) {
10 | x1 = item.x || 0;
11 | y1 = item.y || 0;
12 | x2 = item.x2 != null ? item.x2 : x1;
13 | y2 = item.y2 != null ? item.y2 : y1;
14 | shapeGeom = {
15 | lines: [[[x1, y1], [x2, y2]]],
16 | closed: false
17 | };
18 | shapeGeom.key = JSON.stringify(shapeGeom.lines);
19 | item._geom = geometryForItem(context, item, shapeGeom);
20 | }
21 | drawGeometry(item._geom, context, item);
22 | });
23 | }
24 |
25 | export default {
26 | type: 'rule',
27 | drawGL: drawGL
28 | };
29 |
--------------------------------------------------------------------------------
/src/marks/shape.js:
--------------------------------------------------------------------------------
1 | import {shape} from '../path/shapes';
2 | import markItemPath from './markItemPath';
3 |
4 | export default markItemPath('shape', shape);
5 |
--------------------------------------------------------------------------------
/src/marks/text.js:
--------------------------------------------------------------------------------
1 | import {Marks as marks} from 'vega-scenegraph';
2 |
3 | function drawGL(context, scene, bounds) {
4 | marks.text.draw(context._textContext, scene, bounds);
5 | }
6 |
7 | export default {
8 | type: 'text',
9 | drawGL: drawGL
10 | };
11 |
--------------------------------------------------------------------------------
/src/path/geometryForItem.js:
--------------------------------------------------------------------------------
1 | import color from '../util/color';
2 | import extrude from 'extrude-polyline';
3 |
4 | export default function(context, item, shapeGeom) {
5 | var lw = (lw = item.strokeWidth) != null ? lw : 1,
6 | lc = (lc = item.strokeCap) != null ? lc : 'butt';
7 | var strokeMeshes = [];
8 | var i, len, c, li, ci, mesh, triangles = [], colors = [], cell, p1, p2, p3, mp, mc, mcl,
9 | triangleBuffer, colorBuffer, n = 0, fill = false, stroke = false;
10 | var opacity = item.opacity == null ? 1 : item.opacity;
11 | var fillOpacity = opacity * (item.fillOpacity==null ? 1 : item.fillOpacity);
12 | var strokeOpacity = opacity * (item.strokeOpacity==null ? 1 : item.strokeOpacity),
13 | strokeExtrude,
14 | z = shapeGeom.z || 0,
15 | st = shapeGeom.triangles,
16 | val;
17 |
18 | if (item.fill === 'transparent') {
19 | fillOpacity = 0;
20 | }
21 | if (item.fill && fillOpacity > 0) {
22 | fill = true;
23 | n = st ? st.length / 9 : 0;
24 | }
25 |
26 | if (item.stroke === 'transparent') {
27 | strokeOpacity = 0;
28 | }
29 | if (lw > 0 && item.stroke && strokeOpacity > 0) {
30 | stroke = true;
31 | strokeExtrude = extrude({
32 | thickness: lw,
33 | cap: lc,
34 | join: 'miter',
35 | miterLimit: 1,
36 | closed: !!shapeGeom.closed
37 | });
38 | for (li = 0; li < shapeGeom.lines.length; li++) {
39 | mesh = strokeExtrude.build(shapeGeom.lines[li]);
40 | strokeMeshes.push(mesh);
41 | n += mesh.cells.length;
42 | }
43 | }
44 |
45 | triangles = new Float32Array(n * 3 * 3);
46 | colors = new Float32Array(n * 3 * 4);
47 |
48 | if (fill) {
49 | c = color(context, item, item.fill);
50 | for (i = 0, len = st.length; i < len; i += 3) {
51 | triangles[i ] = st[i ];
52 | triangles[i + 1] = st[i + 1];
53 | triangles[i + 2] = st[i + 2];
54 | }
55 | for (i = 0, len = st.length / 3; i < len; i++) {
56 | colors[i*4 ] = c[0];
57 | colors[i*4 + 1] = c[1];
58 | colors[i*4 + 2] = c[2];
59 | colors[i*4 + 3] = fillOpacity;
60 | }
61 | }
62 |
63 | if (stroke) {
64 | c = color(context, item, item.stroke);
65 | i = fill ? st.length / 3 : 0;
66 | for (li = 0; li < strokeMeshes.length; li++) {
67 | mesh = strokeMeshes[li],
68 | mp = mesh.positions,
69 | mc = mesh.cells,
70 | mcl = mesh.cells.length;
71 | for (ci = 0; ci < mcl; ci++) {
72 | cell = mc[ci];
73 | p1 = mp[cell[0]];
74 | p2 = mp[cell[1]];
75 | p3 = mp[cell[2]];
76 | triangles[i*3 ] = p1[0];
77 | triangles[i*3 + 1] = p1[1];
78 | triangles[i*3 + 2] = z;
79 | colors[i*4 ] = c[0];
80 | colors[i*4 + 1] = c[1];
81 | colors[i*4 + 2] = c[2];
82 | colors[i*4 + 3] = strokeOpacity;
83 | i++;
84 |
85 | triangles[i*3 ] = p2[0];
86 | triangles[i*3 + 1] = p2[1];
87 | triangles[i*3 + 2] = z;
88 | colors[i*4 ] = c[0];
89 | colors[i*4 + 1] = c[1];
90 | colors[i*4 + 2] = c[2];
91 | colors[i*4 + 3] = strokeOpacity;
92 | i++;
93 |
94 | triangles[i*3 ] = p3[0];
95 | triangles[i*3 + 1] = p3[1];
96 | triangles[i*3 + 2] = z;
97 | colors[i*4 ] = c[0];
98 | colors[i*4 + 1] = c[1];
99 | colors[i*4 + 2] = c[2];
100 | colors[i*4 + 3] = strokeOpacity;
101 | i++;
102 | }
103 | }
104 | }
105 |
106 | triangleBuffer = context.createBuffer();
107 | context.bindBuffer(context.ARRAY_BUFFER, triangleBuffer);
108 | context.bufferData(context.ARRAY_BUFFER, triangles, context.STATIC_DRAW);
109 |
110 | colorBuffer = context.createBuffer();
111 | context.bindBuffer(context.ARRAY_BUFFER, colorBuffer);
112 | context.bufferData(context.ARRAY_BUFFER, colors, context.STATIC_DRAW);
113 |
114 | val = {
115 | triangleBuffer: triangleBuffer,
116 | colorBuffer: colorBuffer,
117 | numTriangles: n
118 | };
119 |
120 | if (item._geom) {
121 | if (item._geom.triangleBuffer) {
122 | context.deleteBuffer(item._geom.triangleBuffer);
123 | }
124 | if (item._geom.colorBuffer) {
125 | context.deleteBuffer(item._geom.colorBuffer);
126 | }
127 | }
128 |
129 | return val;
130 | }
131 |
--------------------------------------------------------------------------------
/src/path/geometryForPath.js:
--------------------------------------------------------------------------------
1 | import parse from 'parse-svg-path';
2 | import simplify from 'simplify-path';
3 | import contours from 'svg-path-contours';
4 | import triangulate from 'triangulate-contours';
5 |
6 | export default function(context, path, threshold) {
7 | var key = path;
8 | if (context._pathCache[key]) {
9 | context._pathCacheHit++;
10 | return context._pathCache[key];
11 | }
12 | context._pathCacheMiss++;
13 |
14 | threshold = threshold || 1.0;
15 | if (!path) {
16 | return {lines: [], triangles: [], closed: false, z: 0};
17 | }
18 |
19 | // get a list of polylines/contours from svg contents
20 | var lines = contours(parse(path)), tri;
21 |
22 | // simplify the contours before triangulation
23 | lines = lines.map(function(path) {
24 | return simplify(path, threshold);
25 | });
26 |
27 | // triangluate can fail in some corner cases
28 | try {
29 | tri = triangulate(lines);
30 | }
31 | catch(e) {
32 | // console.log('Could not triangulate the following path:');
33 | // console.log(path);
34 | // console.log(e);
35 | tri = {positions: [], cells: []};
36 | }
37 |
38 | var z = context._randomZ ? 0.25*(Math.random() - 0.5) : 0;
39 |
40 | var triangles = [];
41 | var tcl = tri.cells.length,
42 | tc = tri.cells,
43 | tp = tri.positions;
44 | for (var ci = 0; ci < tcl; ci++) {
45 | var cell = tc[ci];
46 | var p1 = tp[cell[0]];
47 | var p2 = tp[cell[1]];
48 | var p3 = tp[cell[2]];
49 | triangles.push(p1[0], p1[1], z, p2[0], p2[1], z, p3[0], p3[1], z);
50 | }
51 |
52 | var geom = {
53 | lines: lines,
54 | triangles: triangles,
55 | closed: path.endsWith('Z'),
56 | z: z,
57 | key: key
58 | };
59 |
60 | context._pathCache[key] = geom;
61 | context._pathCacheSize++;
62 | if (context._pathCacheSize > 10000) {
63 | context._pathCache = {};
64 | context._pathCacheSize = 0;
65 | }
66 | return geom;
67 | }
68 |
--------------------------------------------------------------------------------
/src/path/geometryForShape.js:
--------------------------------------------------------------------------------
1 | import geometryForItem from './geometryForItem';
2 |
3 | export default function(context, item, shape, keyFunc) {
4 | var key = keyFunc(item), shapeGeom, val, v;
5 |
6 | if (context._shapeCache[key]) {
7 | context._shapeCacheHit++;
8 | return context._shapeCache[key];
9 | }
10 | context._shapeCacheMiss++;
11 |
12 | shapeGeom = shape(context, item);
13 | val = geometryForItem(context, item, shapeGeom);
14 |
15 | if (context._shapeCacheSize > 10000) {
16 | for (v in context._shapeCache) {
17 | if (context._shapeCache.hasOwnProperty(v)) {
18 | context.deleteBuffer(context._shapeCache[v].triangleBuffer);
19 | context.deleteBuffer(context._shapeCache[v].colorBuffer);
20 | context._shapeCache[v].deleted = true;
21 | }
22 | }
23 | context._lastColorBuffer = null;
24 | context._lastTriangleBuffer = null;
25 | context._shapeCache = {};
26 | context._shapeCacheSize = 0;
27 | }
28 | context._shapeCache[key] = val;
29 | context._shapeCacheSize++;
30 |
31 | return val;
32 | }
33 |
--------------------------------------------------------------------------------
/src/path/shapes.js:
--------------------------------------------------------------------------------
1 | import {pathCurves, pathSymbols, pathRectangle, pathTrail} from 'vega-scenegraph';
2 |
3 | import geometryForPath from './geometryForPath';
4 |
5 | import {
6 | arc as d3_arc,
7 | symbol as d3_symbol,
8 | area as d3_area,
9 | line as d3_line
10 | } from 'd3-shape';
11 |
12 | function x(item) { return item.x || 0; }
13 | function y(item) { return item.y || 0; }
14 | function w(item) { return item.width || 0; }
15 | function wh(item) { return item.width || item.height || 1; }
16 | function h(item) { return item.height || 0; }
17 | function xw(item) { return (item.x || 0) + (item.width || 0); }
18 | function yh(item) { return (item.y || 0) + (item.height || 0); }
19 | function cr(item) { return item.cornerRadius || 0; }
20 | function pa(item) { return item.padAngle || 0; }
21 | function def(item) { return !(item.defined === false); }
22 | function size(item) { return item.size == null ? 64 : item.size; }
23 | function type(item) { return pathSymbols(item.shape || 'circle'); }
24 |
25 | var arcShape = d3_arc().cornerRadius(cr).padAngle(pa),
26 | areavShape = d3_area().x(x).y1(y).y0(yh).defined(def),
27 | areahShape = d3_area().y(y).x1(x).x0(xw).defined(def),
28 | lineShape = d3_line().x(x).y(y).defined(def),
29 | trailShape = pathTrail().x(x).y(y).defined(def).size(wh),
30 | rectShape = pathRectangle().x(x).y(y).width(w).height(h).cornerRadius(cr),
31 | rectShapeGL = pathRectangle().x(0).y(0).width(w).height(h).cornerRadius(cr),
32 | symbolShape = d3_symbol().type(type).size(size);
33 |
34 | export function arc(context, item) {
35 | if (!context || context.arc) {
36 | return arcShape.context(context)(item);
37 | }
38 | return geometryForPath(context, arcShape.context(null)(item), 0.1);
39 | }
40 |
41 | export function area(context, items) {
42 | var item = items[0],
43 | interp = item.interpolate || 'linear',
44 | s = (interp === 'trail' ? trailShape
45 | : (item.orient === 'horizontal' ? areahShape : areavShape)
46 | .curve(pathCurves(interp, item.orient, item.tension))
47 | )
48 | if (!context || context.arc) {
49 | return s.context(context)(items);
50 | }
51 | return geometryForPath(context, s.context(null)(items), 0.1);
52 | }
53 |
54 | export function shape(context, item) {
55 | var s = item.mark.shape || item.shape;
56 | if (!context || context.arc) {
57 | return s.context(context)(item);
58 | }
59 | return geometryForPath(context, s.context(null)(item), 0.1);
60 | }
61 |
62 | export function line(context, items) {
63 | var item = items[0],
64 | interp = item.interpolate || 'linear',
65 | s = lineShape.curve(pathCurves(interp, item.orient, item.tension));
66 | if (!context || context.arc) {
67 | return s.context(context)(items);
68 | }
69 | return geometryForPath(context, s.context(null)(items));
70 | }
71 |
72 | export function rectangle(context, item, x, y) {
73 | return rectShape.context(context)(item, x, y);
74 | }
75 |
76 | export function rectangleGL(context, item, x, y) {
77 | return geometryForPath(context, rectShapeGL.context(null)(item, x, y), 0.1);
78 | }
79 |
80 | export function symbol(context, item) {
81 | if (!context || context.arc) {
82 | return symbolShape.context(context)(item);
83 | }
84 | return geometryForPath(context, symbolShape.context(null)(item), 0.1);
85 | }
86 |
--------------------------------------------------------------------------------
/src/util/color.js:
--------------------------------------------------------------------------------
1 | import {color} from 'd3-color';
2 |
3 | var cache = {};
4 |
5 | export default function(context, item, value) {
6 | if (!value) {
7 | return [1.0, 1.0, 1.0];
8 | }
9 | if (value.id) {
10 | // TODO: support gradients
11 | return [1.0, 1.0, 1.0];
12 | }
13 | if (cache[value]) {
14 | return cache[value];
15 | }
16 | var rgb = color(value).rgb();
17 | cache[value] = [rgb.r / 255, rgb.g / 255, rgb.b / 255];
18 | return cache[value];
19 | }
20 |
--------------------------------------------------------------------------------
/src/util/drawGeometry.js:
--------------------------------------------------------------------------------
1 | export default function(geom, gl, item) {
2 | var opacity = item.opacity == null ? 1 : item.opacity,
3 | tx = gl._tx + gl._origin[0],
4 | ty = gl._ty + gl._origin[1];
5 |
6 | if (opacity <= 0) return;
7 | if (geom.numTriangles === 0) return;
8 |
9 | gl.useProgram(gl._shaderProgram);
10 |
11 | gl.bindBuffer(gl.ARRAY_BUFFER, geom.triangleBuffer);
12 | gl.vertexAttribPointer(gl._coordLocation, 3, gl.FLOAT, false, 0, 0);
13 | gl.enableVertexAttribArray(gl._coordLocation);
14 | gl._lastTriangleBuffer = geom.triangleBuffer;
15 |
16 | gl.bindBuffer(gl.ARRAY_BUFFER, geom.colorBuffer);
17 | gl.vertexAttribPointer(gl._colorLocation, 4, gl.FLOAT, false, 0, 0);
18 | gl.enableVertexAttribArray(gl._colorLocation);
19 | gl._lastColorBuffer = geom.colorBuffer;
20 |
21 | gl.uniform2fv(gl._offsetLocation, [tx, ty]);
22 | gl.uniform4fv(gl._clipLocation, gl._clip);
23 |
24 | gl.drawArrays(gl.TRIANGLES, 0, geom.numTriangles * 3);
25 | }
26 |
--------------------------------------------------------------------------------
/src/util/image.js:
--------------------------------------------------------------------------------
1 | import {multiply} from './matrix';
2 |
3 | // Adapted from https://github.com/greggman/webgl-fundamentals
4 | //
5 | // BSD license follows:
6 | //
7 | // Copyright 2012, Gregg Tavares.
8 | // All rights reserved.
9 | //
10 | // Redistribution and use in source and binary forms, with or without
11 | // modification, are permitted provided that the following conditions are
12 | // met:
13 | //
14 | // * Redistributions of source code must retain the above copyright
15 | // notice, this list of conditions and the following disclaimer.
16 | // * Redistributions in binary form must reproduce the above
17 | // copyright notice, this list of conditions and the following disclaimer
18 | // in the documentation and/or other materials provided with the
19 | // distribution.
20 | // * Neither the name of Gregg Tavares. nor the names of his
21 | // contributors may be used to endorse or promote products derived from
22 | // this software without specific prior written permission.
23 | //
24 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 |
36 | // creates a texture info { width: w, height: h, texture: tex }
37 | export function loadImageAndCreateTextureInfo(gl, img) {
38 | var tex = gl.createTexture();
39 | gl.bindTexture(gl.TEXTURE_2D, tex);
40 | // Fill the texture with a 1x1 blue pixel.
41 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
42 | new Uint8Array([0, 0, 255, 255]));
43 | // let's assume all images are not a power of 2
44 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
45 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
46 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
47 | var textureInfo = {texture: tex};
48 | textureInfo.width = img.width;
49 | textureInfo.height = img.height;
50 | gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
51 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
52 | return textureInfo;
53 | }
54 |
55 | export function drawImage(gl, texInfo, matrix) {
56 | gl.bindTexture(gl.TEXTURE_2D, texInfo.texture);
57 | gl.useProgram(gl._imageShaderProgram);
58 | gl.bindBuffer(gl.ARRAY_BUFFER, gl._imagePositionBuffer);
59 | gl.enableVertexAttribArray(gl._imagePositionLocation);
60 | gl.vertexAttribPointer(gl._imagePositionLocation, 2, gl.FLOAT, false, 0, 0);
61 | gl.bindBuffer(gl.ARRAY_BUFFER, gl._imageTexcoordBuffer);
62 | gl.enableVertexAttribArray(gl._imageTexcoordLocation);
63 | gl.vertexAttribPointer(gl._imageTexcoordLocation, 2, gl.FLOAT, false, 0, 0);
64 | var preMatrix = [
65 | texInfo.w, 0, 0, 0,
66 | 0, texInfo.h, 0, 0,
67 | 0, 0, 1, 0,
68 | texInfo.x, texInfo.y, 0, 1
69 | ];
70 | matrix = multiply(matrix, preMatrix);
71 | gl.uniformMatrix4fv(gl._imageMatrixLocation, false, matrix);
72 | gl.uniform1i(gl._imageTextureLocation, 0);
73 | gl.drawArrays(gl.TRIANGLES, 0, 6);
74 | }
75 |
--------------------------------------------------------------------------------
/src/util/inherits.js:
--------------------------------------------------------------------------------
1 | export default function(child, parent) {
2 | var proto = (child.prototype = Object.create(parent.prototype));
3 | proto.constructor = child;
4 | return proto;
5 | }
6 |
--------------------------------------------------------------------------------
/src/util/matrix.js:
--------------------------------------------------------------------------------
1 |
2 | export function multiply(a, b) {
3 | var ind = [
4 | 0,0,4,1,8,2,12,3,
5 | 1,0,5,1,9,2,13,3,
6 | 2,0,6,1,10,2,14,3,
7 | 3,0,7,1,11,2,15,3,
8 | 0,4,4,5,8,6,12,7,
9 | 1,4,5,5,9,6,13,7,
10 | 2,4,6,5,10,6,14,7,
11 | 3,4,7,5,11,6,15,7,
12 | 0,8,4,9,8,10,12,11,
13 | 1,8,5,9,9,10,13,11,
14 | 2,8,6,9,10,10,14,11,
15 | 3,8,7,9,11,10,15,11,
16 | 0,12,4,13,8,14,12,15,
17 | 1,12,5,13,9,14,13,15,
18 | 2,12,6,13,10,14,14,15,
19 | 3,12,7,13,11,14,15,15
20 | ];
21 | var c = [
22 | 0, 0, 0, 0,
23 | 0, 0, 0, 0,
24 | 0, 0, 0, 0,
25 | 0, 0, 0, 0
26 | ];
27 | for (var i = 0; i < ind.length/2; i++) {
28 | c[Math.floor(i/4)] += a[ind[2*i]] * b[ind[2*i+1]];
29 | }
30 | return c;
31 | }
32 |
33 | export function perspective(fieldOfViewInRadians, aspect, near, far) {
34 | var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewInRadians);
35 | var rangeInv = 1.0 / (near - far);
36 |
37 | return [
38 | f / aspect, 0, 0, 0,
39 | 0, f, 0, 0,
40 | 0, 0, (near + far) * rangeInv, -1,
41 | 0, 0, near * far * rangeInv * 2, 0
42 | ];
43 | }
44 |
45 | export function rotateX(a) {
46 | return [
47 | 1, 0, 0, 0,
48 | 0, Math.cos(a), Math.sin(a), 0,
49 | 0, -Math.sin(a), Math.cos(a), 0,
50 | 0, 0, 0, 1
51 | ];
52 | }
53 |
54 | export function rotateY(a) {
55 | return [
56 | Math.cos(a), 0, -Math.sin(a), 0,
57 | 0, 1, 0, 0,
58 | Math.sin(a), 0, Math.cos(a), 0,
59 | 0, 0, 0, 1
60 | ];
61 | }
62 |
63 | export function rotateZ(a) {
64 | return [
65 | Math.cos(a), Math.sin(a), 0, 0,
66 | -Math.sin(a), Math.cos(a), 0, 0,
67 | 0, 0, 1, 0,
68 | 0, 0, 0, 1
69 | ];
70 | }
71 |
72 | export function translate(x, y, z) {
73 | return [
74 | 1, 0, 0, 0,
75 | 0, 1, 0, 0,
76 | 0, 0, 1, 0,
77 | x, y, z, 1
78 | ];
79 | }
80 |
--------------------------------------------------------------------------------
/src/util/resize.js:
--------------------------------------------------------------------------------
1 | export var devicePixelRatio = typeof window !== 'undefined'
2 | ? window.devicePixelRatio || 1 : 1;
3 |
4 | export default function(canvas, width, height, origin) {
5 | var scale = typeof HTMLElement !== 'undefined'
6 | && canvas instanceof HTMLElement
7 | && canvas.parentNode != null;
8 |
9 | var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'),
10 | ratio = scale ? devicePixelRatio : 1;
11 |
12 | canvas.width = width * ratio;
13 | canvas.height = height * ratio;
14 |
15 | gl._textCanvas.width = width * ratio;
16 | gl._textCanvas.height = height * ratio;
17 | gl._textContext.pixelRatio = ratio;
18 | gl._textContext.setTransform(
19 | ratio, 0, 0, ratio,
20 | ratio * origin[0],
21 | ratio * origin[1]
22 | );
23 |
24 | if (ratio !== 1) {
25 | canvas.style.width = width + 'px';
26 | canvas.style.height = height + 'px';
27 | }
28 |
29 | gl.lineWidth(ratio);
30 |
31 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
32 |
33 | gl._origin = origin;
34 | gl._ratio = ratio;
35 | gl._clip = [0, 0, canvas.width / gl._ratio, canvas.height / gl._ratio];
36 |
37 | return canvas;
38 | }
39 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 | Vega WebGL renderer test suite
3 |
4 |
5 |
6 |
7 |
8 | Vega WebGL renderer test suite page.
9 |
10 |
--------------------------------------------------------------------------------
/test/resources/generate-tests.js:
--------------------------------------------------------------------------------
1 | module.exports = false;
2 |
--------------------------------------------------------------------------------
/test/resources/image0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/image0.png
--------------------------------------------------------------------------------
/test/resources/image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/image1.png
--------------------------------------------------------------------------------
/test/resources/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/image2.png
--------------------------------------------------------------------------------
/test/resources/png/marks-arc_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-arc_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-arc_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-arc_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-breaks_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-breaks_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-breaks_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-breaks_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-h_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-h_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-h_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-h_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-trail_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-trail_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-trail_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-trail_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-v_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-v_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-area-v_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-area-v_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-group_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-group_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-image_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-image_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-1_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-1_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-1_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-1_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-2_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-2_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-2_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-2_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-breaks_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-breaks_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-line-breaks_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-line-breaks_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-path-clear_17.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-path-clear_17.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-path-clear_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-path-clear_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-path_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-path_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-path_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-path_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-rect_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-rect_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-rect_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-rect_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-rule_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-rule_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-rule_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-rule_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-symbol_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-symbol_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-symbol_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-symbol_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/marks-text_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-text_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/marks-text_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/marks-text_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/scenegraph-barley_15.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/scenegraph-barley_15.1.png
--------------------------------------------------------------------------------
/test/resources/png/scenegraph-barley_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/scenegraph-barley_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/scenegraph-defs2_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/scenegraph-defs2_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/scenegraph-defs_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/scenegraph-defs_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/png/scenegraph-rect_f3263d_acbc327b1175928155d3e050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vega/vega-webgl-renderer/f81aa1c19b2840423bf1026b9ebd759144c305bb/test/resources/png/scenegraph-rect_f3263d_acbc327b1175928155d3e050.png
--------------------------------------------------------------------------------
/test/resources/scenegraph-defs.json:
--------------------------------------------------------------------------------
1 | {
2 | "marktype": "group",
3 | "interactive": false,
4 | "items": [
5 | {
6 | "x": 1,
7 | "y": 1,
8 | "width": 100,
9 | "height": 100,
10 | "clip": true,
11 | "fill": {
12 | "id": "gradient_foo",
13 | "type": "linear",
14 | "stops": [
15 | {"offset": 0.0, "color": "red"},
16 | {"offset": 0.5, "color": "green"},
17 | {"offset": 1.0, "color": "blue"}
18 | ],
19 | "x1": 0,
20 | "x2": 1,
21 | "y1": 0,
22 | "y2": 0
23 | }
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/test/resources/scenegraph-defs2.json:
--------------------------------------------------------------------------------
1 | {
2 | "marktype": "group",
3 | "interactive": false,
4 | "items": [
5 | {
6 | "x": 1,
7 | "y": 1,
8 | "width": 100,
9 | "height": 100,
10 | "clip": false,
11 | "fill": "red"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/resources/scenegraph-rect.json:
--------------------------------------------------------------------------------
1 | {
2 | "marktype": "group",
3 | "interactive": false,
4 | "items": [
5 | {
6 | "width": 400,
7 | "height": 200,
8 | "clip": true,
9 | "items": [
10 | {
11 | "marktype": "rect",
12 | "interactive": true,
13 | "items": [
14 | {"x": 0, "y": 144, "width": 99, "height": 56, "fill": "steelblue"},
15 | {"x": 100, "y": 90, "width": 99, "height": 110, "fill": "steelblue"},
16 | {"x": 200, "y": 114, "width": 99, "height": 86, "fill": "steelblue"},
17 | {"x": 300, "y": 18, "width": 99, "height": 182, "fill": "steelblue"}
18 | ]
19 | }
20 | ]
21 | }
22 | ]
23 | }
--------------------------------------------------------------------------------
/test/test-selenium-down.sh:
--------------------------------------------------------------------------------
1 | if [ -e .selenium.pid ]; then
2 | pid=$(cat .selenium.pid)
3 | kill ${pid}
4 | rm .selenium.pid
5 | fi
6 |
--------------------------------------------------------------------------------
/test/test-selenium-up.sh:
--------------------------------------------------------------------------------
1 | if [ -e .selenium.pid ]; then
2 | echo "Selenium server seems to already be running (PID $(cat .selenium.pid))" >&2
3 | exit 1
4 | fi
5 | selenium-standalone start &
6 | echo $! > .selenium.pid
7 |
--------------------------------------------------------------------------------
/test/test-server-down.sh:
--------------------------------------------------------------------------------
1 | if [ -e .server.pid ]; then
2 | pid=$(cat .server.pid)
3 | kill ${pid}
4 | rm .server.pid
5 | fi
6 |
--------------------------------------------------------------------------------
/test/test-server-up.sh:
--------------------------------------------------------------------------------
1 | if [ -e .server.pid ]; then
2 | echo "Server seems to already be running (PID $(cat .server.pid))" >&2
3 | exit 1
4 | fi
5 | http-server -p 9821 . &
6 | echo $! > .server.pid
7 |
--------------------------------------------------------------------------------