Bar graph added.

This commit is contained in:
prabhatdev
2020-07-28 00:48:25 +05:30
parent d0a6e2667d
commit 194b41124d
3468 changed files with 640611 additions and 169 deletions

27
node_modules/vega-scenegraph/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2015-2018, University of Washington Interactive Data Lab
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

55
node_modules/vega-scenegraph/README.md generated vendored Normal file
View File

@@ -0,0 +1,55 @@
# vega-scenegraph
[Vega](https://github.com/vega/vega) scenegraph and renderers.
Renderers and event handlers for Vega's mark-based scenegraph. This package supports both pixel-based (canvas) and vector graphics (SVG) output. Renderers can either (re-)draw a complete scene or perform incremental re-rendering for a set of provided "dirty" items. A fast SVG string renderer is also provided to generate static SVG for export.
The [node-canvas](https://github.com/Automattic/node-canvas) library is used for server-side canvas rendering and bounds calculation. Node-canvas requires the native Cairo graphics library and may attempt to compile native code as part of the installation process. In some instances this may result in installation hiccups. Should you run into issues, you are likely to resolve them more quickly if you first search for help regarding node-canvas (as opposed to vega-scenegraph) installation. However, node-canvas is not a strict dependency, and is not needed for SVG rendering. Bounds calculation can be performed without node-canvas, though in the case of text marks the resulting bounds may be inaccurate due to approximate text size calculations.
## Scenegraph Definition
The Vega scenegraph is a hierarchical (tree) data structure. The levels of the tree alternate between an enclosing *mark* definition and contained sets of mark instances called *items*.
For example, here is a simple scenegraph containing three rectangles:
```json
{
"marktype": "rect",
"items": [
{"x": 0, "y": 0, "width": 50, "height": 50, "fill": "steelblue"},
{"x": 100, "y": 50, "width": 50, "height": 50, "fill": "firebrick"},
{"x": 50, "y": 100, "width": 50, "height": 50, "fill": "forestgreen"}
]
}
```
The supported mark types are rectangles (`rect`), plotting symbols (`symbol`), general paths or polygons (`path`), circular arcs (`arc`), filled areas (`area`), lines (`line`), images (`image`), text labels (`text`), and chart gridlines or rules (`rule`). Each item has a set of supported properties (`x`, `y`, `width`, `fill`, and so on) appropriate to the mark type.
Scenegraphs may also contain `group` marks, which serve as containers for other marks. For example, a top-level group mark may look like:
```json
{
"marktype": "group",
"items": [
{
"x": 0,
"y": 0,
"width": 200,
"height": 200,
"items": [...] // array of contained mark instances
}
]
}
```
In this example, the group *mark* contains only a single group *item*. In practice, a group mark may contain any number of group items, for example to describe a scene with multiple layers or sub-plots.
For more information regarding supported mark properties, please see the [Vega marks documentation](https://vega.github.io/vega/docs/marks/).
## Scenegraph Serialization
The top-level export of this package includes `fromJSON` and `toJSON` methods to support scenegraph serialization. The `fromJSON` method expects a JSON string as input (similar to the examples listed above). It will then add additional parent pointers to the tree structure. For example, each item will have a `mark` property pointing to its parent mark, and each mark will have a `group` property pointing to its parent group (if any). The `toJSON` method maps a scenegraph instance to a JSON string, stripping any parent pointers or other non-standard properties.
## Test Suite
The vega-scengraph test suite compares rendered output for both Canvas (PNG) and SVG (text) renderers. Due to differences among platforms, pixel-level rendering by node-canvas can differ across operating systems. As a result, some test cases may break when running on a system other than Mac OS X (our standard platform for testing). If you are running on Linux or Windows and experience test failures, it does not necessarily indicate an issue with vega-scenegraph. In such cases, we recommend running the node-canvas test-server (`npm run test-server` from the node-canvas repository) to compare server-side and client-side rendering.

File diff suppressed because one or more lines are too long

5340
node_modules/vega-scenegraph/build/vega-scenegraph.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

68
node_modules/vega-scenegraph/index.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
import {resetSVGGradientId} from './src/Gradient';
import {resetSVGClipId} from './src/util/svg/clip';
export {default as Bounds} from './src/Bounds';
export {default as Gradient} from './src/Gradient';
export {default as GroupItem} from './src/GroupItem';
export {default as ResourceLoader} from './src/ResourceLoader';
export {default as Item} from './src/Item';
export {default as Scenegraph} from './src/Scenegraph';
export {default as Handler} from './src/Handler';
export {default as Renderer} from './src/Renderer';
export {default as CanvasHandler} from './src/CanvasHandler';
export {default as CanvasRenderer} from './src/CanvasRenderer';
export {default as SVGHandler} from './src/SVGHandler';
export {default as SVGRenderer} from './src/SVGRenderer';
export {default as SVGStringRenderer} from './src/SVGStringRenderer';
export {RenderType, renderModule} from './src/modules';
export {intersect} from './src/intersect';
export {default as Marks} from './src/marks/index';
export {default as boundClip} from './src/bound/boundClip';
export {default as boundContext} from './src/bound/boundContext';
export {default as boundStroke} from './src/bound/boundStroke';
export {default as boundItem} from './src/bound/boundItem';
export {default as boundMark} from './src/bound/boundMark';
export {default as pathCurves} from './src/path/curves';
export {default as pathSymbols} from './src/path/symbols';
export {default as pathRectangle} from './src/path/rectangle';
export {default as pathTrail} from './src/path/trail';
export {default as pathParse} from './src/path/parse';
export {default as pathRender} from './src/path/render';
export {default as point} from './src/util/point';
export {domCreate, domFind, domChild, domClear} from './src/util/dom';
export {openTag, closeTag} from './src/util/tags';
export {
font,
fontFamily,
fontSize,
lineHeight,
multiLineOffset,
textMetrics
} from './src/util/text';
export {sceneEqual, pathEqual} from './src/util/equal';
export {sceneToJSON, sceneFromJSON} from './src/util/serialize';
export {
intersectPath,
intersectPoint,
intersectRule,
intersectBoxLine
} from './src/util/intersect';
export {
zorder as sceneZOrder,
visit as sceneVisit,
pickVisit as scenePickVisit
} from './src/util/visit';
// deprecated, remove in next major version
export {resetSVGClipId} from './src/util/svg/clip';
export function resetSVGDefIds() {
resetSVGClipId();
resetSVGGradientId();
}

68
node_modules/vega-scenegraph/package.json generated vendored Normal file
View File

@@ -0,0 +1,68 @@
{
"_from": "vega-scenegraph@~4.8.3",
"_id": "vega-scenegraph@4.8.3",
"_inBundle": false,
"_integrity": "sha512-2GznqXm/py7/XX9juohFbLYQTKxHY5VNRZLHc0bL35Nd7lShKeOlHY9uVkHw2FoLLCz78UcXFminWM8lddvGxw==",
"_location": "/vega-scenegraph",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "vega-scenegraph@~4.8.3",
"name": "vega-scenegraph",
"escapedName": "vega-scenegraph",
"rawSpec": "~4.8.3",
"saveSpec": null,
"fetchSpec": "~4.8.3"
},
"_requiredBy": [
"/vega",
"/vega-functions",
"/vega-view",
"/vega-view-transforms"
],
"_resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.8.3.tgz",
"_shasum": "11b557019175ec5ddc258c3a5eb7371e64cec5e1",
"_spec": "vega-scenegraph@~4.8.3",
"_where": "/home/prabhatdev/Documents/opensource/gitHubStats/waka-readme-stats/node_modules/vega",
"author": {
"name": "Jeffrey Heer",
"url": "http://idl.cs.washington.edu"
},
"bugs": {
"url": "https://github.com/vega/vega/issues"
},
"bundleDependencies": false,
"dependencies": {
"d3-path": "^1.0.9",
"d3-shape": "^1.3.7",
"vega-canvas": "^1.2.2",
"vega-loader": "^4.3.0",
"vega-scale": "^7.0.0",
"vega-util": "^1.14.0"
},
"deprecated": false,
"description": "Vega scenegraph and renderers.",
"gitHead": "8fe8d36961c128df8300e6bc4fe6aac1e537bbe0",
"homepage": "https://github.com/vega/vega#readme",
"license": "BSD-3-Clause",
"main": "build/vega-scenegraph.js",
"module": "index",
"name": "vega-scenegraph",
"repository": {
"type": "git",
"url": "git+https://github.com/vega/vega.git"
},
"scripts": {
"build": "yarn rollup && yarn schema",
"postbuild": "terser build/vega-scenegraph.js -c -m -o build/vega-scenegraph.min.js",
"postpublish": "git push && git push --tags",
"prebuild": "rimraf build && mkdir build",
"prepublishOnly": "yarn test && yarn build",
"pretest": "yarn prebuild && yarn rollup && yarn schema",
"rollup": "rollup -f umd -g d3-path:d3,d3-shape:d3,vega-canvas:vega,vega-loader:vega,vega-scale:vega,vega-util:vega -n vega -o build/vega-scenegraph.js -- index.js",
"schema": "node schema > build/vega-scenegraph-schema.json",
"test": "tape -r ./test/__init__ 'test/**/*-test.js'"
},
"version": "4.8.3"
}

421
node_modules/vega-scenegraph/schema.js generated vendored Normal file
View File

@@ -0,0 +1,421 @@
function duplicate(_) {
return JSON.parse(JSON.stringify(_));
}
function extend(_) {
for (var x, k, i=1, len=arguments.length; i<len; ++i) {
x = arguments[i];
for (k in x) { _[k] = x[k]; }
}
return _;
}
function build(strict) {
const schema = duplicate(BASE);
for (const type in MARKS) {
buildMark(type, schema.refs, strict);
}
return schema;
}
function buildMark(type, refs, strict) {
const mark = duplicate(MARK_BASE);
mark.properties.marktype.enum = [ type ];
mark.properties.items.items.$ref += type;
if (strict) mark.additionalProperties = false;
const item = duplicate(ITEM_BASE);
extend(item.properties, MARKS[type].properties || {});
if (strict) item.additionalProperties = false;
refs.mark.oneOf.push({$ref: '#/refs/mark-' + type});
refs['mark-'+type] = mark;
refs['item-'+type] = item;
}
function svg_path() {
// Based on http://www.w3.org/TR/SVG/paths.html#PathDataBNF
const wsp = '[ \t\r\f]*',
csp = '([ \t\r\f]+,?[ \t\r\f]*|,[ \t\r\f]*)?',
sep = csp + '?',
pos = '[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?',
num = '[-+]?' + pos,
nseq = num + '(' + sep + num + ')*',
p = num + sep + num,
p2 = p + sep + p,
p3 = p + '(' + sep + p + '){2}',
pseq = p + '(' + sep + p + ')*',
arc = pos + sep + pos + sep + num + csp + '[01]' + sep + '[01]' + sep + p,
m = '[Mm]' + wsp + pseq,
lt = '[LlTt]' + wsp + pseq,
hv = '[HhVv]' + wsp + nseq,
c = '[Cc]' + wsp + p3 + '(' + sep + p3 + ')*',
qs = '[QqSs]' + wsp + p2 + '(' + sep + p2 + ')*',
a = '[Aa]' + wsp + arc + '(' + sep + arc + ')*',
z = '[Zz]',
draw = '(' + [z, lt, hv, c, qs, a].join('|') + ')',
move = m + wsp + '(' + draw + '(' + sep + draw + ')*' + ')?',
path = wsp + '(' + move + '(' + sep + move + ')*' + ')?' + wsp;
return path;
}
const COLOR_NAMES = 'aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen';
function css_color_names() {
return COLOR_NAMES.split('|').map(
name => name.split('')
.map(c => `[${c.toUpperCase()}${c.toLowerCase()}]`)
.join('')
).join('|');
}
const BASE = {
'$schema': 'http://json-schema.org/draft-06/schema#',
'title': 'Vega scenegraph',
'description': 'Vega scenegraph model.',
'oneOf': [ { '$ref': '#/refs/mark' } ],
'refs': {
'mark': { 'oneOf': [] },
'path': {
'type': 'string',
'pattern': '^' + svg_path() + '$'
},
'paint': {
'oneOf': [
{ '$ref': '#/refs/color' },
{ '$ref': '#/refs/linearGradient' },
{ '$ref': '#/refs/radialGradient' }
]
},
'color': {
'oneOf': [
{
'type': 'string',
'pattern': '^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$'
},
{
'type': 'string',
'pattern': '^rgb\\([ \t\f]*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(,[ \t\f]*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){2}[ \t\f]*\\)$'
},
{
'type': 'string',
'pattern': '^rgb\\([ \t\f]*([0-9]|[1-9][0-9]|100)%(,[ \t\f]*([0-9]|[1-9][0-9]|100)%){2}[ \t\f]*\\)$'
},
{
'type': 'string',
'pattern': '^hsl\\([ \t\f]*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9]|3[0-5][0-9]|360)(,[ \t\f]*([0-9]|[1-9][0-9]|100)%){2}[ \t\f]*\\)$'
},
{
'type': 'string',
'pattern': '^(' + css_color_names() + ')$'
}
]
},
'gradientStop': {
'type': 'object',
'properties': {
'offset': { 'type': 'number' },
'color': { '$ref': '#/refs/color' }
},
'required': ['offset', 'color']
},
'linearGradient': {
'type': 'object',
'properties': {
'gradient': { 'enum': [ 'linear' ] },
'id': { 'type': 'string' },
'x1': { 'type': 'number' },
'y1': { 'type': 'number' },
'x2': { 'type': 'number' },
'y2': { 'type': 'number' },
'stops': {
'type': 'array',
'items': { '$ref': '#/refs/gradientStop' }
}
},
'required': ['gradient', 'stops'],
'additionalProperties': false
},
'radialGradient': {
'type': 'object',
'properties': {
'gradient': { 'enum': [ 'radial' ] },
'id': { 'type': 'string' },
'x1': { 'type': 'number' },
'y1': { 'type': 'number' },
'r1': { 'type': 'number' },
'x2': { 'type': 'number' },
'y2': { 'type': 'number' },
'r2': { 'type': 'number' },
'stops': {
'type': 'array',
'items': { '$ref': '#/refs/gradientStop' }
}
},
'required': ['gradient', 'stops'],
'additionalProperties': false
}
}
};
const MARK_BASE = {
'type': 'object',
'properties': {
'marktype': { 'enum': null },
'name': { 'type': 'string' },
'role': { 'type': 'string' },
'description': { 'type': 'string' },
'aria': { 'type': 'boolean' },
'interactive': { 'type': 'boolean', 'default': true },
'items': {
'type': 'array',
'items': { '$ref': '#/refs/item-' }
},
'zindex': { 'type': 'number' }
},
'required': [ 'marktype' ]
};
const BLEND_MODE = [
null,
'multiply',
'screen',
'overlay',
'darken',
'lighten',
'color-dodge',
'color-burn',
'hard-light',
'soft-light',
'difference',
'exclusion',
'hue',
'saturation',
'color',
'luminosity'
];
const ITEM_BASE = {
'type': 'object',
'properties': {
'x': { 'type': 'number' },
'y': { 'type': 'number' },
'width': { 'type': 'number' },
'height': { 'type': 'number' },
'blend': { 'enum': BLEND_MODE, 'default': null },
'opacity': { 'type': 'number', 'default': 1 },
'fill': { '$ref': '#/refs/paint' },
'fillOpacity': { 'type': 'number', 'default': 1 },
'stroke': { '$ref': '#/refs/paint' },
'strokeOpacity': { 'type': 'number', 'default': 1 },
'strokeWidth': { 'type': 'number', 'default': 1 },
'strokeCap': { 'enum': [ 'butt', 'cap', 'round' ], 'default': 'butt' },
'strokeJoin': { 'enum': [ 'miter', 'round', 'bevel' ], 'default': 'miter' },
'strokeMiterLimit': { 'type': 'number' },
'strokeDash': { 'type': 'array', 'items': { 'type': 'number' } },
'strokeDashOffset': { 'type': 'number', 'default': 0 },
'zindex': { 'type': 'number' },
'cursor': { 'type': 'string' },
'href': { 'type': 'string', 'format': 'uri-reference' },
'tooltip': {},
'description': { 'type': 'string' },
'aria': { 'type': 'boolean' },
'ariaRole': { 'type': 'string' },
'ariaRoleDescription': { 'type': 'string' }
}
};
const AREA_INTERPOLATE = [
'basis',
'cardinal',
'catmull-rom',
'linear',
'monotone',
'natural',
'step',
'step-after',
'step-before'
];
const LINE_INTERPOLATE = [
'basis',
'basis-closed',
'basis-open',
'bundle',
'cardinal',
'cardinal-closed',
'cardinal-open',
'catmull-rom',
'catmull-rom-closed',
'catmull-rom-open',
'linear',
'linear-closed',
'monotone',
'natural',
'step',
'step-after',
'step-before'
];
const TEXT_BASELINE = [
'alphabetic',
'top',
'middle',
'bottom',
'line-top',
'line-bottom'
];
const TEXT_FONT_WEIGHT = [
'normal',
'bold',
'bolder',
'lighter',
100,
200,
300,
400,
500,
600,
700,
800,
900
];
const MARKS = {
'group': {
'properties': {
'clip': { 'type': 'boolean' },
'cornerRadius': { 'type': 'number' },
'cornerRadiusTopLeft': { 'type': 'number' },
'cornerRadiusTopRight': { 'type': 'number' },
'cornerRadiusBottomRight': { 'type': 'number' },
'cornerRadiusBottomLeft': { 'type': 'number' },
'items': { 'type': 'array', 'items': { '$ref': '#/refs/mark' } },
'strokeForeground': { 'type': 'boolean' },
'strokeOffset': { 'type': 'number' }
}
},
'arc': {
'properties': {
'startAngle': { 'type': 'number' },
'endAngle': { 'type': 'number' },
'padAngle': { 'type': 'number' },
'innerRadius': { 'type': 'number' },
'outerRadius': { 'type': 'number' },
'cornerRadius': { 'type': 'number' }
}
},
'area': {
'properties': {
'defined': { 'type': 'boolean' },
'interpolate': { 'enum': AREA_INTERPOLATE },
'tension': { 'type': 'number' },
'orient': { 'enum': [ 'horizontal', 'vertical' ] }
}
},
'image': {
'properties': {
'url': { 'type': 'string', 'format': 'uri-reference' },
'aspect': { 'type': 'boolean', 'default': true },
'smooth': { 'type': 'boolean', 'default': true },
'align': {
'enum': [ 'left', 'center', 'right' ],
'default': 'left'
},
'baseline': {
'enum': [ 'top', 'middle', 'bottom' ],
'default': 'top'
}
}
},
'line': {
'properties': {
'defined': { 'type': 'boolean' },
'interpolate': { 'enum': LINE_INTERPOLATE },
'tension': { 'type': 'number' },
'orient': { 'enum': [ 'horizontal', 'vertical' ] },
'size': { 'type': 'number' }
}
},
'path': {
'properties': {
'angle': { 'type': 'number' },
'path': { '$ref': '#/refs/path' },
'scaleX': { 'type': 'number' },
'scaleY': { 'type': 'number' }
}
},
'rect': {
'properties': {
'cornerRadius': { 'type': 'number' },
'cornerRadiusTopLeft': { 'type': 'number' },
'cornerRadiusTopRight': { 'type': 'number' },
'cornerRadiusBottomRight': { 'type': 'number' },
'cornerRadiusBottomLeft': { 'type': 'number' }
}
},
'rule': {
'properties': {
'x2': { 'type': 'number' },
'y2': { 'type': 'number' }
}
},
'symbol': {
'properties': {
'angle': { 'type': 'number', 'default': 0 },
'size': { 'type': 'number', 'default': 100 },
'shape': { 'type': 'string' }
}
},
'text': {
'properties': {
'text': {
'oneOf': [
{ 'type': 'string' },
{ 'type': 'array', 'items': { 'type': 'string' } }
]
},
'limit': { 'type': 'number', 'default': 0 },
'lineHeight': { 'type': 'number' },
'dir': { 'type': 'string', 'default': 'ltr' },
'ellipsis': { 'type': 'string', 'default': '\u2026' },
'align': {
'enum': [ 'left', 'center', 'right' ],
'default': 'left'
},
'baseline': {
'enum': TEXT_BASELINE,
'default': 'alphabetic'
},
'angle': { 'type': 'number', 'default': 0 },
'theta': { 'type': 'number', 'default': 0 },
'radius': { 'type': 'number', 'default': 0 },
'dx': { 'type': 'number', 'default': 0 },
'dy': { 'type': 'number', 'default': 0 },
'font': { 'type': 'string', 'default': 'sans-serif' },
'fontSize': { 'type': 'number' },
'fontStyle': {
'enum': [ 'normal', 'italic', 'oblique' ],
'default': 'normal'
},
'fontWeight': {
'enum': TEXT_FONT_WEIGHT,
'default': 'normal'
},
'fontVariant': {
'enum': [ 'normal', 'small-caps' ],
'default': 'normal'
}
}
},
'trail': {
'properties': {
'defined': { 'type': 'boolean' },
'size': { 'type': 'number', 'default': 1 }
}
}
};
const schema = build(true);
process.stdout.write(JSON.stringify(schema, null, 2));

178
node_modules/vega-scenegraph/src/Bounds.js generated vendored Normal file
View File

@@ -0,0 +1,178 @@
export default function Bounds(b) {
this.clear();
if (b) this.union(b);
}
var prototype = Bounds.prototype;
prototype.clone = function() {
return new Bounds(this);
};
prototype.clear = function() {
this.x1 = +Number.MAX_VALUE;
this.y1 = +Number.MAX_VALUE;
this.x2 = -Number.MAX_VALUE;
this.y2 = -Number.MAX_VALUE;
return this;
};
prototype.empty = function() {
return (
this.x1 === +Number.MAX_VALUE &&
this.y1 === +Number.MAX_VALUE &&
this.x2 === -Number.MAX_VALUE &&
this.y2 === -Number.MAX_VALUE
);
};
prototype.equals = function(b) {
return (
this.x1 === b.x1 &&
this.y1 === b.y1 &&
this.x2 === b.x2 &&
this.y2 === b.y2
);
};
prototype.set = function(x1, y1, x2, y2) {
if (x2 < x1) {
this.x2 = x1;
this.x1 = x2;
} else {
this.x1 = x1;
this.x2 = x2;
}
if (y2 < y1) {
this.y2 = y1;
this.y1 = y2;
} else {
this.y1 = y1;
this.y2 = y2;
}
return this;
};
prototype.add = function(x, y) {
if (x < this.x1) this.x1 = x;
if (y < this.y1) this.y1 = y;
if (x > this.x2) this.x2 = x;
if (y > this.y2) this.y2 = y;
return this;
};
prototype.expand = function(d) {
this.x1 -= d;
this.y1 -= d;
this.x2 += d;
this.y2 += d;
return this;
};
prototype.round = function() {
this.x1 = Math.floor(this.x1);
this.y1 = Math.floor(this.y1);
this.x2 = Math.ceil(this.x2);
this.y2 = Math.ceil(this.y2);
return this;
};
prototype.scale = function(s) {
this.x1 *= s;
this.y1 *= s;
this.x2 *= s;
this.y2 *= s;
return this;
};
prototype.translate = function(dx, dy) {
this.x1 += dx;
this.x2 += dx;
this.y1 += dy;
this.y2 += dy;
return this;
};
prototype.rotate = function(angle, x, y) {
const p = this.rotatedPoints(angle, x, y);
return this.clear()
.add(p[0], p[1])
.add(p[2], p[3])
.add(p[4], p[5])
.add(p[6], p[7]);
};
prototype.rotatedPoints = function(angle, x, y) {
var {x1, y1, x2, y2} = this,
cos = Math.cos(angle),
sin = Math.sin(angle),
cx = x - x*cos + y*sin,
cy = y - x*sin - y*cos;
return [
cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy,
cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy,
cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy,
cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy
];
};
prototype.union = function(b) {
if (b.x1 < this.x1) this.x1 = b.x1;
if (b.y1 < this.y1) this.y1 = b.y1;
if (b.x2 > this.x2) this.x2 = b.x2;
if (b.y2 > this.y2) this.y2 = b.y2;
return this;
};
prototype.intersect = function(b) {
if (b.x1 > this.x1) this.x1 = b.x1;
if (b.y1 > this.y1) this.y1 = b.y1;
if (b.x2 < this.x2) this.x2 = b.x2;
if (b.y2 < this.y2) this.y2 = b.y2;
return this;
};
prototype.encloses = function(b) {
return b && (
this.x1 <= b.x1 &&
this.x2 >= b.x2 &&
this.y1 <= b.y1 &&
this.y2 >= b.y2
);
};
prototype.alignsWith = function(b) {
return b && (
this.x1 == b.x1 ||
this.x2 == b.x2 ||
this.y1 == b.y1 ||
this.y2 == b.y2
);
};
prototype.intersects = function(b) {
return b && !(
this.x2 < b.x1 ||
this.x1 > b.x2 ||
this.y2 < b.y1 ||
this.y1 > b.y2
);
};
prototype.contains = function(x, y) {
return !(
x < this.x1 ||
x > this.x2 ||
y < this.y1 ||
y > this.y2
);
};
prototype.width = function() {
return this.x2 - this.x1;
};
prototype.height = function() {
return this.y2 - this.y1;
};

208
node_modules/vega-scenegraph/src/CanvasHandler.js generated vendored Normal file
View File

@@ -0,0 +1,208 @@
import Handler from './Handler';
import Marks from './marks/index';
import {
ClickEvent, DragEnterEvent, DragLeaveEvent, DragOverEvent, Events,
HrefEvent, MouseDownEvent, MouseMoveEvent, MouseOutEvent, MouseOverEvent,
MouseWheelEvent, TooltipHideEvent, TooltipShowEvent,
TouchEndEvent, TouchMoveEvent, TouchStartEvent
} from './util/events';
import point from './util/point';
import {domFind} from './util/dom';
import {inherits} from 'vega-util';
export default function CanvasHandler(loader, tooltip) {
Handler.call(this, loader, tooltip);
this._down = null;
this._touch = null;
this._first = true;
this._events = {};
}
const prototype = inherits(CanvasHandler, Handler);
prototype.initialize = function(el, origin, obj) {
this._canvas = el && domFind(el, 'canvas');
// add minimal events required for proper state management
[ClickEvent, MouseDownEvent, MouseMoveEvent, MouseOutEvent, DragLeaveEvent]
.forEach(type => eventListenerCheck(this, type));
return Handler.prototype.initialize.call(this, el, origin, obj);
};
const eventBundle = type => (
type === TouchStartEvent ||
type === TouchMoveEvent ||
type === TouchEndEvent
)
? [TouchStartEvent, TouchMoveEvent, TouchEndEvent]
: [type];
// lazily add listeners to the canvas as needed
function eventListenerCheck(handler, type) {
eventBundle(type).forEach(_ => addEventListener(handler, _));
}
function addEventListener(handler, type) {
const canvas = handler.canvas();
if (canvas && !handler._events[type]) {
handler._events[type] = 1;
canvas.addEventListener(type, handler[type]
? evt => handler[type](evt)
: evt => handler.fire(type, evt)
);
}
}
// return the backing canvas instance
prototype.canvas = function() {
return this._canvas;
};
// retrieve the current canvas context
prototype.context = function() {
return this._canvas.getContext('2d');
};
// supported events
prototype.events = Events;
function move(moveEvent, overEvent, outEvent) {
return function(evt) {
const a = this._active,
p = this.pickEvent(evt);
if (p === a) {
// active item and picked item are the same
this.fire(moveEvent, evt); // fire move
} else {
// active item and picked item are different
if (!a || !a.exit) {
// fire out for prior active item
// suppress if active item was removed from scene
this.fire(outEvent, evt);
}
this._active = p; // set new active item
this.fire(overEvent, evt); // fire over for new active item
this.fire(moveEvent, evt); // fire move for new active item
}
};
}
function inactive(type) {
return function(evt) {
this.fire(type, evt);
this._active = null;
};
}
// to keep old versions of firefox happy
prototype.DOMMouseScroll = function(evt) {
this.fire(MouseWheelEvent, evt);
};
prototype.mousemove = move(MouseMoveEvent, MouseOverEvent, MouseOutEvent);
prototype.dragover = move(DragOverEvent, DragEnterEvent, DragLeaveEvent);
prototype.mouseout = inactive(MouseOutEvent);
prototype.dragleave = inactive(DragLeaveEvent);
prototype.mousedown = function(evt) {
this._down = this._active;
this.fire(MouseDownEvent, evt);
};
prototype.click = function(evt) {
if (this._down === this._active) {
this.fire(ClickEvent, evt);
this._down = null;
}
};
prototype.touchstart = function(evt) {
this._touch = this.pickEvent(evt.changedTouches[0]);
if (this._first) {
this._active = this._touch;
this._first = false;
}
this.fire(TouchStartEvent, evt, true);
};
prototype.touchmove = function(evt) {
this.fire(TouchMoveEvent, evt, true);
};
prototype.touchend = function(evt) {
this.fire(TouchEndEvent, evt, true);
this._touch = null;
};
// fire an event
prototype.fire = function(type, evt, touch) {
const a = touch ? this._touch : this._active,
h = this._handlers[type];
// set event type relative to scenegraph items
evt.vegaType = type;
// handle hyperlinks and tooltips first
if (type === HrefEvent && a && a.href) {
this.handleHref(evt, a, a.href);
} else if (type === TooltipShowEvent || type === TooltipHideEvent) {
this.handleTooltip(evt, a, type !== TooltipHideEvent);
}
// invoke all registered handlers
if (h) {
for (let i=0, len=h.length; i<len; ++i) {
h[i].handler.call(this._obj, evt, a);
}
}
};
// add an event handler
prototype.on = function(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
if (i < 0) {
eventListenerCheck(this, type);
(h[name] || (h[name] = [])).push({
type: type,
handler: handler
});
}
return this;
};
// remove an event handler
prototype.off = function(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
if (i >= 0) {
h.splice(i, 1);
}
return this;
};
prototype.pickEvent = function(evt) {
const p = point(evt, this._canvas),
o = this._origin;
return this.pick(this._scene, p[0], p[1], p[0] - o[0], p[1] - o[1]);
};
// find the scenegraph item at the current mouse position
// x, y -- the absolute x, y mouse coordinates on the canvas element
// gx, gy -- the relative coordinates within the current group
prototype.pick = function(scene, x, y, gx, gy) {
const g = this.context(),
mark = Marks[scene.marktype];
return mark.pick.call(this, g, scene, x, y, gx, gy);
};

149
node_modules/vega-scenegraph/src/CanvasRenderer.js generated vendored Normal file
View File

@@ -0,0 +1,149 @@
import Renderer from './Renderer';
import Bounds from './Bounds';
import marks from './marks/index';
import {domClear} from './util/dom';
import clip from './util/canvas/clip';
import resize from './util/canvas/resize';
import {canvas} from 'vega-canvas';
import {error, inherits} from 'vega-util';
export default function CanvasRenderer(loader) {
Renderer.call(this, loader);
this._options = {};
this._redraw = false;
this._dirty = new Bounds();
this._tempb = new Bounds();
}
const prototype = inherits(CanvasRenderer, Renderer),
base = Renderer.prototype;
prototype.initialize = function(el, width, height, origin, scaleFactor, options) {
this._options = options || {};
this._canvas = this._options.externalContext
? null
: canvas(1, 1, this._options.type); // instantiate a small canvas
if (el && this._canvas) {
domClear(el, 0).appendChild(this._canvas);
this._canvas.setAttribute('class', 'marks');
}
// this method will invoke resize to size the canvas appropriately
return base.initialize.call(this, el, width, height, origin, scaleFactor);
};
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
if (this._canvas) {
// configure canvas size and transform
resize(this._canvas, this._width, this._height,
this._origin, this._scale, this._options.context);
} else {
// external context needs to be scaled and positioned to origin
const ctx = this._options.externalContext;
if (!ctx) error('CanvasRenderer is missing a valid canvas or context');
ctx.scale(this._scale, this._scale);
ctx.translate(this._origin[0], this._origin[1]);
}
this._redraw = true;
return this;
};
prototype.canvas = function() {
return this._canvas;
};
prototype.context = function() {
return this._options.externalContext
|| (this._canvas ? this._canvas.getContext('2d') : null);
};
prototype.dirty = function(item) {
let b = this._tempb.clear().union(item.bounds),
g = item.mark.group;
while (g) {
b.translate(g.x || 0, g.y || 0);
g = g.mark.group;
}
this._dirty.union(b);
};
function clipToBounds(g, b, origin) {
// expand bounds by 1 pixel, then round to pixel boundaries
b.expand(1).round();
// align to base pixel grid in case of non-integer scaling (#2425)
if (g.pixelRatio % 1) {
b.scale(g.pixelRatio).round().scale(1 / g.pixelRatio);
}
// to avoid artifacts translate if origin has fractional pixels
b.translate(-(origin[0] % 1), -(origin[1] % 1));
// set clip path
g.beginPath();
g.rect(b.x1, b.y1, b.width(), b.height());
g.clip();
return b;
}
const viewBounds = (origin, width, height) => new Bounds()
.set(0, 0, width, height)
.translate(-origin[0], -origin[1]);
prototype._render = function(scene) {
const g = this.context(),
o = this._origin,
w = this._width,
h = this._height,
db = this._dirty,
vb = viewBounds(o, w, h);
// setup
g.save();
const b = this._redraw || db.empty()
? (this._redraw = false, vb.expand(1))
: clipToBounds(g, vb.intersect(db), o);
this.clear(-o[0], -o[1], w, h);
// render
this.draw(g, scene, b);
// takedown
g.restore();
db.clear();
return this;
};
prototype.draw = function(ctx, scene, bounds) {
const mark = marks[scene.marktype];
if (scene.clip) clip(ctx, scene);
mark.draw.call(this, ctx, scene, bounds);
if (scene.clip) ctx.restore();
};
prototype.clear = function(x, y, w, h) {
const opt = this._options,
g = this.context();
if (opt.type !== 'pdf' && !opt.externalContext) {
// calling clear rect voids vector output in pdf mode
// and could remove external context content (#2615)
g.clearRect(x, y, w, h);
}
if (this._bgcolor != null) {
g.fillStyle = this._bgcolor;
g.fillRect(x, y, w, h);
}
};

62
node_modules/vega-scenegraph/src/Gradient.js generated vendored Normal file
View File

@@ -0,0 +1,62 @@
var gradient_id = 0;
export function resetSVGGradientId() {
gradient_id = 0;
}
export const patternPrefix = 'p_';
export function isGradient(value) {
return value && value.gradient;
}
export function gradientRef(g, defs, base) {
let id = g.id,
type = g.gradient,
prefix = type === 'radial' ? patternPrefix : '';
// check id, assign default values as needed
if (!id) {
id = g.id = 'gradient_' + (gradient_id++);
if (type === 'radial') {
g.x1 = get(g.x1, 0.5);
g.y1 = get(g.y1, 0.5);
g.r1 = get(g.r1, 0);
g.x2 = get(g.x2, 0.5);
g.y2 = get(g.y2, 0.5);
g.r2 = get(g.r2, 0.5);
prefix = patternPrefix;
} else {
g.x1 = get(g.x1, 0);
g.y1 = get(g.y1, 0);
g.x2 = get(g.x2, 1);
g.y2 = get(g.y2, 0);
}
}
// register definition
defs[id] = g;
// return url reference
return 'url(' + (base || '') + '#' + prefix + id + ')';
}
function get(val, def) {
return val != null ? val : def;
}
export default function(p0, p1) {
var stops = [], gradient;
return gradient = {
gradient: 'linear',
x1: p0 ? p0[0] : 0,
y1: p0 ? p0[1] : 0,
x2: p1 ? p1[0] : 1,
y2: p1 ? p1[1] : 0,
stops: stops,
stop: function(offset, color) {
stops.push({offset: offset, color: color});
return gradient;
}
};
}

9
node_modules/vega-scenegraph/src/GroupItem.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import Item from './Item';
import {inherits} from 'vega-util';
export default function GroupItem(mark) {
Item.call(this, mark);
this.items = (this.items || []);
}
inherits(GroupItem, Item);

202
node_modules/vega-scenegraph/src/Handler.js generated vendored Normal file
View File

@@ -0,0 +1,202 @@
import {domCreate} from './util/dom';
import resolveItem from './util/resolveItem';
import {loader} from 'vega-loader';
/**
* Create a new Handler instance.
* @param {object} [customLoader] - Optional loader instance for
* href URL sanitization. If not specified, a standard loader
* instance will be generated.
* @param {function} [customTooltip] - Optional tooltip handler
* function for custom tooltip display.
* @constructor
*/
export default function Handler(customLoader, customTooltip) {
this._active = null;
this._handlers = {};
this._loader = customLoader || loader();
this._tooltip = customTooltip || defaultTooltip;
}
// The default tooltip display handler.
// Sets the HTML title attribute on the visualization container.
function defaultTooltip(handler, event, item, value) {
handler.element().setAttribute('title', value || '');
}
const prototype = Handler.prototype;
/**
* Initialize a new Handler instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {object} [obj] - Optional context object that should serve as
* the "this" context for event callbacks.
* @return {Handler} - This handler instance.
*/
prototype.initialize = function(el, origin, obj) {
this._el = el;
this._obj = obj || null;
return this.origin(origin);
};
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
prototype.element = function() {
return this._el;
};
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
prototype.canvas = function() {
return this._el && this._el.firstChild;
};
/**
* Get / set the origin coordinates of the visualization.
*/
prototype.origin = function(origin) {
if (arguments.length) {
this._origin = origin || [0, 0];
return this;
} else {
return this._origin.slice();
}
};
/**
* Get / set the scenegraph root.
*/
prototype.scene = function(scene) {
if (!arguments.length) return this._scene;
this._scene = scene;
return this;
};
/**
* Add an event handler. Subclasses should override this method.
*/
prototype.on = function(/*type, handler*/) {};
/**
* Remove an event handler. Subclasses should override this method.
*/
prototype.off = function(/*type, handler*/) {};
/**
* Utility method for finding the array index of an event handler.
* @param {Array} h - An array of registered event handlers.
* @param {string} type - The event type.
* @param {function} handler - The event handler instance to find.
* @return {number} - The handler's array index or -1 if not registered.
*/
prototype._handlerIndex = function(h, type, handler) {
for (let i = h ? h.length : 0; --i>=0;) {
if (h[i].type === type && (!handler || h[i].handler === handler)) {
return i;
}
}
return -1;
};
/**
* Returns an array with registered event handlers.
* @param {string} [type] - The event type to query. Any annotations
* are ignored; for example, for the argument "click.foo", ".foo" will
* be ignored and the method returns all "click" handlers. If type is
* null or unspecified, this method returns handlers for all types.
* @return {Array} - A new array containing all registered event handlers.
*/
prototype.handlers = function(type) {
const h = this._handlers, a = [];
if (type) {
a.push.apply(a, h[this.eventName(type)]);
} else {
for (const k in h) { a.push.apply(a, h[k]); }
}
return a;
};
/**
* Parses an event name string to return the specific event type.
* For example, given "click.foo" returns "click"
* @param {string} name - The input event type string.
* @return {string} - A string with the event type only.
*/
prototype.eventName = function(name) {
const i = name.indexOf('.');
return i < 0 ? name : name.slice(0, i);
};
/**
* Handle hyperlink navigation in response to an item.href value.
* @param {Event} event - The event triggering hyperlink navigation.
* @param {Item} item - The scenegraph item.
* @param {string} href - The URL to navigate to.
*/
prototype.handleHref = function(event, item, href) {
this._loader
.sanitize(href, {context:'href'})
.then(opt => {
const e = new MouseEvent(event.type, event),
a = domCreate(null, 'a');
for (const name in opt) a.setAttribute(name, opt[name]);
a.dispatchEvent(e);
})
.catch(function() { /* do nothing */ });
};
/**
* Handle tooltip display in response to an item.tooltip value.
* @param {Event} event - The event triggering tooltip display.
* @param {Item} item - The scenegraph item.
* @param {boolean} show - A boolean flag indicating whether
* to show or hide a tooltip for the given item.
*/
prototype.handleTooltip = function(event, item, show) {
if (item && item.tooltip != null) {
item = resolveItem(item, event, this.canvas(), this._origin);
const value = (show && item && item.tooltip) || null;
this._tooltip.call(this._obj, this, event, item, value);
}
};
/**
* Returns the size of a scenegraph item and its position relative
* to the viewport.
* @param {Item} item - The scenegraph item.
* @return {object} - A bounding box object (compatible with the
* DOMRect type) consisting of x, y, width, heigh, top, left,
* right, and bottom properties.
*/
prototype.getItemBoundingClientRect = function(item) {
const el = this.canvas();
if (!el) return;
const rect = el.getBoundingClientRect(),
origin = this._origin,
bounds = item.bounds,
width = bounds.width(),
height = bounds.height();
let x = bounds.x1 + origin[0] + rect.left,
y = bounds.y1 + origin[1] + rect.top;
// translate coordinate for each parent group
while (item.mark && (item = item.mark.group)) {
x += item.x || 0;
y += item.y || 0;
}
// return DOMRect-compatible bounding box
return {
x, y, width, height,
left: x, top: y, right: x + width, bottom: y + height
};
};

6
node_modules/vega-scenegraph/src/Item.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import Bounds from './Bounds';
export default function Item(mark) {
this.mark = mark;
this.bounds = (this.bounds || new Bounds());
}

183
node_modules/vega-scenegraph/src/Renderer.js generated vendored Normal file
View File

@@ -0,0 +1,183 @@
import ResourceLoader from './ResourceLoader';
/**
* Create a new Renderer instance.
* @param {object} [loader] - Optional loader instance for
* image and href URL sanitization. If not specified, a
* standard loader instance will be generated.
* @constructor
*/
export default function Renderer(loader) {
this._el = null;
this._bgcolor = null;
this._loader = new ResourceLoader(loader);
}
var prototype = Renderer.prototype;
/**
* Initialize a new Renderer instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {number} width - The coordinate width of the display, in pixels.
* @param {number} height - The coordinate height of the display, in pixels.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance.
*/
prototype.initialize = function(el, width, height, origin, scaleFactor) {
this._el = el;
return this.resize(width, height, origin, scaleFactor);
};
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
prototype.element = function() {
return this._el;
};
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
prototype.canvas = function() {
return this._el && this._el.firstChild;
};
/**
* Get / set the background color.
*/
prototype.background = function(bgcolor) {
if (arguments.length === 0) return this._bgcolor;
this._bgcolor = bgcolor;
return this;
};
/**
* Resize the display.
* @param {number} width - The new coordinate width of the display, in pixels.
* @param {number} height - The new coordinate height of the display, in pixels.
* @param {Array<number>} origin - The new origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance;
*/
prototype.resize = function(width, height, origin, scaleFactor) {
this._width = width;
this._height = height;
this._origin = origin || [0, 0];
this._scale = scaleFactor || 1;
return this;
};
/**
* Report a dirty item whose bounds should be redrawn.
* This base class method does nothing. Subclasses that perform
* incremental should implement this method.
* @param {Item} item - The dirty item whose bounds should be redrawn.
*/
prototype.dirty = function(/*item*/) {
};
/**
* Render an input scenegraph, potentially with a set of dirty items.
* This method will perform an immediate rendering with available resources.
* The renderer may also need to perform image loading to perform a complete
* render. This process can lead to asynchronous re-rendering of the scene
* after this method returns. To receive notification when rendering is
* complete, use the renderAsync method instead.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Renderer} - This renderer instance.
*/
prototype.render = function(scene) {
var r = this;
// bind arguments into a render call, and cache it
// this function may be subsequently called for async redraw
r._call = function() { r._render(scene); };
// invoke the renderer
r._call();
// clear the cached call for garbage collection
// async redraws will stash their own copy
r._call = null;
return r;
};
/**
* Internal rendering method. Renderer subclasses should override this
* method to actually perform rendering.
* @param {object} scene - The root mark of a scenegraph to render.
*/
prototype._render = function(/*scene*/) {
// subclasses to override
};
/**
* Asynchronous rendering method. Similar to render, but returns a Promise
* that resolves when all rendering is completed. Sometimes a renderer must
* perform image loading to get a complete rendering. The returned
* Promise will not resolve until this process completes.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Promise} - A Promise that resolves when rendering is complete.
*/
prototype.renderAsync = function(scene) {
var r = this.render(scene);
return this._ready
? this._ready.then(function() { return r; })
: Promise.resolve(r);
};
/**
* Internal method for asynchronous resource loading.
* Proxies method calls to the ImageLoader, and tracks loading
* progress to invoke a re-render once complete.
* @param {string} method - The method name to invoke on the ImageLoader.
* @param {string} uri - The URI for the requested resource.
* @return {Promise} - A Promise that resolves to the requested resource.
*/
prototype._load = function(method, uri) {
var r = this,
p = r._loader[method](uri);
if (!r._ready) {
// re-render the scene when loading completes
var call = r._call;
r._ready = r._loader.ready()
.then(function(redraw) {
if (redraw) call();
r._ready = null;
});
}
return p;
};
/**
* Sanitize a URL to include as a hyperlink in the rendered scene.
* This method proxies a call to ImageLoader.sanitizeURL, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string to sanitize.
* @return {Promise} - A Promise that resolves to the sanitized URL.
*/
prototype.sanitizeURL = function(uri) {
return this._load('sanitizeURL', uri);
};
/**
* Requests an image to include in the rendered scene.
* This method proxies a call to ImageLoader.loadImage, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string of the image.
* @return {Promise} - A Promise that resolves to the loaded Image.
*/
prototype.loadImage = function(uri) {
return this._load('loadImage', uri);
};

79
node_modules/vega-scenegraph/src/ResourceLoader.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
import {image} from 'vega-canvas';
import {loader} from 'vega-loader';
import {hasOwnProperty} from 'vega-util';
export default function ResourceLoader(customLoader) {
this._pending = 0;
this._loader = customLoader || loader();
}
var prototype = ResourceLoader.prototype;
prototype.pending = function() {
return this._pending;
};
function increment(loader) {
loader._pending += 1;
}
function decrement(loader) {
loader._pending -= 1;
}
prototype.sanitizeURL = function(uri) {
var loader = this;
increment(loader);
return loader._loader.sanitize(uri, {context:'href'})
.then(function(opt) {
decrement(loader);
return opt;
})
.catch(function() {
decrement(loader);
return null;
});
};
prototype.loadImage = function(uri) {
const loader = this,
Image = image();
increment(loader);
return loader._loader
.sanitize(uri, {context: 'image'})
.then(function(opt) {
const url = opt.href;
if (!url || !Image) throw {url: url};
const img = new Image();
// set crossOrigin only if cors is defined; empty string sets anonymous mode
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin
const cors = hasOwnProperty(opt, 'crossOrigin') ? opt.crossOrigin : 'anonymous';
if (cors != null) img.crossOrigin = cors;
// attempt to load image resource
img.onload = () => decrement(loader);
img.onerror = () => decrement(loader);
img.src = url;
return img;
})
.catch(function(e) {
decrement(loader);
return {complete: false, width: 0, height: 0, src: e && e.url || ''};
});
};
prototype.ready = function() {
var loader = this;
return new Promise(function(accept) {
function poll(value) {
if (!loader.pending()) accept(value);
else setTimeout(function() { poll(true); }, 10);
}
poll(false);
});
};

83
node_modules/vega-scenegraph/src/SVGHandler.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
import Handler from './Handler';
import {domFind} from './util/dom';
import {HrefEvent, TooltipHideEvent, TooltipShowEvent} from './util/events';
import {inherits} from 'vega-util';
export default function SVGHandler(loader, tooltip) {
Handler.call(this, loader, tooltip);
const h = this;
h._hrefHandler = listener(h, (evt, item) => {
if (item && item.href) h.handleHref(evt, item, item.href);
});
h._tooltipHandler = listener(h, (evt, item) => {
h.handleTooltip(evt, item, evt.type !== TooltipHideEvent);
});
}
const prototype = inherits(SVGHandler, Handler);
prototype.initialize = function(el, origin, obj) {
let svg = this._svg;
if (svg) {
svg.removeEventListener(HrefEvent, this._hrefHandler);
svg.removeEventListener(TooltipShowEvent, this._tooltipHandler);
svg.removeEventListener(TooltipHideEvent, this._tooltipHandler);
}
this._svg = svg = el && domFind(el, 'svg');
if (svg) {
svg.addEventListener(HrefEvent, this._hrefHandler);
svg.addEventListener(TooltipShowEvent, this._tooltipHandler);
svg.addEventListener(TooltipHideEvent, this._tooltipHandler);
}
return Handler.prototype.initialize.call(this, el, origin, obj);
};
prototype.canvas = function() {
return this._svg;
};
// wrap an event listener for the SVG DOM
const listener = (context, handler) => evt => {
let item = evt.target.__data__;
item = Array.isArray(item) ? item[0] : item;
evt.vegaType = evt.type;
handler.call(context._obj, evt, item);
};
// add an event handler
prototype.on = function(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
if (i < 0) {
const x = {
type,
handler,
listener: listener(this, handler)
};
(h[name] || (h[name] = [])).push(x);
if (this._svg) {
this._svg.addEventListener(name, x.listener);
}
}
return this;
};
// remove an event handler
prototype.off = function(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
if (i >= 0) {
if (this._svg) {
this._svg.removeEventListener(name, h[i].listener);
}
h.splice(i, 1);
}
return this;
};

613
node_modules/vega-scenegraph/src/SVGRenderer.js generated vendored Normal file
View File

@@ -0,0 +1,613 @@
import Renderer from './Renderer';
import {gradientRef, isGradient, patternPrefix} from './Gradient';
import marks from './marks/index';
import {ariaItemAttributes, ariaMarkAttributes} from './util/aria';
import {cssClass, domChild, domClear, domCreate} from './util/dom';
import {closeTag, openTag} from './util/tags';
import {fontFamily, fontSize, lineHeight, textLines, textValue} from './util/text';
import {visit} from './util/visit';
import clip from './util/svg/clip';
import metadata from './util/svg/metadata';
import {rootAttributes, styles} from './util/svg/styles';
import {inherits, isArray} from 'vega-util';
const RootIndex = 0,
ns = metadata.xmlns;
export default function SVGRenderer(loader) {
Renderer.call(this, loader);
this._dirtyID = 0;
this._dirty = [];
this._svg = null;
this._root = null;
this._defs = null;
}
var prototype = inherits(SVGRenderer, Renderer);
var base = Renderer.prototype;
prototype.initialize = function(el, width, height, padding) {
// create the svg definitions cache
this._defs = {
gradient: {},
clipping: {}
};
if (el) {
this._svg = domChild(el, 0, 'svg', ns);
this._svg.setAttribute('class', 'marks');
domClear(el, 1);
// set the svg root group
this._root = domChild(this._svg, RootIndex, 'g', ns);
for (const attr in rootAttributes) {
this._root.setAttribute(attr, rootAttributes[attr]);
}
// ensure no additional child elements
domClear(this._svg, RootIndex + 1);
}
// set background color if defined
this.background(this._bgcolor);
return base.initialize.call(this, el, width, height, padding);
};
prototype.background = function(bgcolor) {
if (arguments.length && this._svg) {
this._svg.style.setProperty('background-color', bgcolor);
}
return base.background.apply(this, arguments);
};
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
if (this._svg) {
this._svg.setAttribute('width', this._width * this._scale);
this._svg.setAttribute('height', this._height * this._scale);
this._svg.setAttribute('viewBox', '0 0 ' + this._width + ' ' + this._height);
this._root.setAttribute('transform', 'translate(' + this._origin + ')');
}
this._dirty = [];
return this;
};
prototype.canvas = function() {
return this._svg;
};
prototype.svg = function() {
if (!this._svg) return null;
var attr = {
class: 'marks',
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: '0 0 ' + this._width + ' ' + this._height
};
for (var key in metadata) {
attr[key] = metadata[key];
}
var bg = !this._bgcolor ? ''
: (openTag('rect', {
width: this._width,
height: this._height,
fill: this._bgcolor
}) + closeTag('rect'));
return openTag('svg', attr)
+ (this._defs.el ? this._defs.el.outerHTML : '')
+ bg
+ this._root.outerHTML
+ closeTag('svg');
};
// -- Render entry point --
prototype._render = function(scene) {
// perform spot updates and re-render markup
if (this._dirtyCheck()) {
if (this._dirtyAll) this._resetDefs();
this.draw(this._root, scene);
domClear(this._root, 1);
}
this.updateDefs();
this._dirty = [];
++this._dirtyID;
return this;
};
// -- Manage SVG definitions ('defs') block --
prototype.updateDefs = function() {
const svg = this._svg,
defs = this._defs;
let el = defs.el,
index = 0;
for (const id in defs.gradient) {
if (!el) defs.el = (el = domChild(svg, RootIndex, 'defs', ns));
index = updateGradient(el, defs.gradient[id], index);
}
for (const id in defs.clipping) {
if (!el) defs.el = (el = domChild(svg, RootIndex, 'defs', ns));
index = updateClipping(el, defs.clipping[id], index);
}
// clean-up
if (el) {
index === 0
? (svg.removeChild(el), defs.el = null)
: domClear(el, index);
}
};
function updateGradient(el, grad, index) {
var i, n, stop;
if (grad.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
var pt = domChild(el, index++, 'pattern', ns);
pt.setAttribute('id', patternPrefix + grad.id);
pt.setAttribute('viewBox', '0,0,1,1');
pt.setAttribute('width', '100%');
pt.setAttribute('height', '100%');
pt.setAttribute('preserveAspectRatio', 'xMidYMid slice');
pt = domChild(pt, 0, 'rect', ns);
pt.setAttribute('width', '1');
pt.setAttribute('height', '1');
pt.setAttribute('fill', 'url(' + href() + '#' + grad.id + ')');
el = domChild(el, index++, 'radialGradient', ns);
el.setAttribute('id', grad.id);
el.setAttribute('fx', grad.x1);
el.setAttribute('fy', grad.y1);
el.setAttribute('fr', grad.r1);
el.setAttribute('cx', grad.x2);
el.setAttribute('cy', grad.y2);
el.setAttribute( 'r', grad.r2);
} else {
el = domChild(el, index++, 'linearGradient', ns);
el.setAttribute('id', grad.id);
el.setAttribute('x1', grad.x1);
el.setAttribute('x2', grad.x2);
el.setAttribute('y1', grad.y1);
el.setAttribute('y2', grad.y2);
}
for (i=0, n=grad.stops.length; i<n; ++i) {
stop = domChild(el, i, 'stop', ns);
stop.setAttribute('offset', grad.stops[i].offset);
stop.setAttribute('stop-color', grad.stops[i].color);
}
domClear(el, i);
return index;
}
function updateClipping(el, clip, index) {
var mask;
el = domChild(el, index, 'clipPath', ns);
el.setAttribute('id', clip.id);
if (clip.path) {
mask = domChild(el, 0, 'path', ns);
mask.setAttribute('d', clip.path);
} else {
mask = domChild(el, 0, 'rect', ns);
mask.setAttribute('x', 0);
mask.setAttribute('y', 0);
mask.setAttribute('width', clip.width);
mask.setAttribute('height', clip.height);
}
domClear(el, 1);
return index + 1;
}
prototype._resetDefs = function() {
var def = this._defs;
def.gradient = {};
def.clipping = {};
};
// -- Manage rendering of items marked as dirty --
prototype.dirty = function(item) {
if (item.dirty !== this._dirtyID) {
item.dirty = this._dirtyID;
this._dirty.push(item);
}
};
prototype.isDirty = function(item) {
return this._dirtyAll
|| !item._svg
|| item.dirty === this._dirtyID;
};
prototype._dirtyCheck = function() {
this._dirtyAll = true;
var items = this._dirty;
if (!items.length || !this._dirtyID) return true;
var id = ++this._dirtyID,
item, mark, type, mdef, i, n, o;
for (i=0, n=items.length; i<n; ++i) {
item = items[i];
mark = item.mark;
if (mark.marktype !== type) {
// memoize mark instance lookup
type = mark.marktype;
mdef = marks[type];
}
if (mark.zdirty && mark.dirty !== id) {
this._dirtyAll = false;
dirtyParents(item, id);
mark.items.forEach(function(i) { i.dirty = id; });
}
if (mark.zdirty) continue; // handle in standard drawing pass
if (item.exit) { // EXIT
if (mdef.nested && mark.items.length) {
// if nested mark with remaining points, update instead
o = mark.items[0];
if (o._svg) this._update(mdef, o._svg, o);
} else if (item._svg) {
// otherwise remove from DOM
o = item._svg.parentNode;
if (o) o.removeChild(item._svg);
}
item._svg = null;
continue;
}
item = (mdef.nested ? mark.items[0] : item);
if (item._update === id) continue; // already visited
if (!item._svg || !item._svg.ownerSVGElement) {
// ENTER
this._dirtyAll = false;
dirtyParents(item, id);
} else {
// IN-PLACE UPDATE
this._update(mdef, item._svg, item);
}
item._update = id;
}
return !this._dirtyAll;
};
function dirtyParents(item, id) {
for (; item && item.dirty !== id; item=item.mark.group) {
item.dirty = id;
if (item.mark && item.mark.dirty !== id) {
item.mark.dirty = id;
} else return;
}
}
// -- Construct & maintain scenegraph to SVG mapping ---
// Draw a mark container.
prototype.draw = function(el, scene, prev) {
if (!this.isDirty(scene)) return scene._svg;
var svg = this._svg,
mdef = marks[scene.marktype],
events = scene.interactive === false ? 'none' : null,
isGroup = mdef.tag === 'g',
sibling = null,
i = 0,
parent;
parent = bind(scene, el, prev, 'g', svg);
parent.setAttribute('class', cssClass(scene));
// apply aria attributes to parent container element
const aria = ariaMarkAttributes(scene);
for (const key in aria) setAttribute(parent, key, aria[key]);
if (!isGroup) {
setAttribute(parent, 'pointer-events', events);
}
setAttribute(parent, 'clip-path',
scene.clip ? clip(this, scene, scene.group) : null);
const process = item => {
const dirty = this.isDirty(item),
node = bind(item, parent, sibling, mdef.tag, svg);
if (dirty) {
this._update(mdef, node, item);
if (isGroup) recurse(this, node, item);
}
sibling = node;
++i;
};
if (mdef.nested) {
if (scene.items.length) process(scene.items[0]);
} else {
visit(scene, process);
}
domClear(parent, i);
return parent;
};
// Recursively process group contents.
function recurse(renderer, el, group) {
el = el.lastChild.previousSibling;
let prev, idx = 0;
visit(group, item => {
prev = renderer.draw(el, item, prev);
++idx;
});
// remove any extraneous DOM elements
domClear(el, 1 + idx);
}
// Bind a scenegraph item to an SVG DOM element.
// Create new SVG elements as needed.
function bind(item, el, sibling, tag, svg) {
let node = item._svg, doc;
// create a new dom node if needed
if (!node) {
doc = el.ownerDocument;
node = domCreate(doc, tag, ns);
item._svg = node;
if (item.mark) {
node.__data__ = item;
node.__values__ = {fill: 'default'};
// if group, create background, content, and foreground elements
if (tag === 'g') {
const bg = domCreate(doc, 'path', ns);
node.appendChild(bg);
bg.__data__ = item;
const cg = domCreate(doc, 'g', ns);
node.appendChild(cg);
cg.__data__ = item;
const fg = domCreate(doc, 'path', ns);
node.appendChild(fg);
fg.__data__ = item;
fg.__values__ = {fill: 'default'};
}
}
}
// (re-)insert if (a) not contained in SVG or (b) sibling order has changed
if (node.ownerSVGElement !== svg || siblingCheck(node, sibling)) {
el.insertBefore(node, sibling ? sibling.nextSibling : el.firstChild);
}
return node;
}
function siblingCheck(node, sibling) {
return node.parentNode
&& node.parentNode.childNodes.length > 1
&& node.previousSibling != sibling; // treat null/undefined the same
}
// -- Set attributes & styles on SVG elements ---
var element = null, // temp var for current SVG element
values = null; // temp var for current values hash
// Extra configuration for certain mark types
var mark_extras = {
group: function(mdef, el, item) {
const fg = element = el.childNodes[2];
values = fg.__values__;
mdef.foreground(emit, item, this);
values = el.__values__; // use parent's values hash
element = el.childNodes[1];
mdef.content(emit, item, this);
const bg = element = el.childNodes[0];
mdef.background(emit, item, this);
const value = item.mark.interactive === false ? 'none' : null;
if (value !== values.events) {
setAttribute(fg, 'pointer-events', value);
setAttribute(bg, 'pointer-events', value);
values.events = value;
}
if (item.strokeForeground && item.stroke) {
const fill = item.fill;
setAttribute(fg, 'display', null);
// set style of background
this.style(bg, item);
setAttribute(bg, 'stroke', null);
// set style of foreground
if (fill) item.fill = null;
values = fg.__values__;
this.style(fg, item);
if (fill) item.fill = fill;
// leave element null to prevent downstream styling
element = null;
} else {
// ensure foreground is ignored
setAttribute(fg, 'display', 'none');
}
},
image: function(mdef, el, item) {
if (item.smooth === false) {
setStyle(el, 'image-rendering', 'optimizeSpeed');
setStyle(el, 'image-rendering', 'pixelated');
} else {
setStyle(el, 'image-rendering', null);
}
},
text: function(mdef, el, item) {
let tl = textLines(item),
key, value, doc, lh;
if (isArray(tl)) {
// multi-line text
value = tl.map(_ => textValue(item, _));
key = value.join('\n'); // content cache key
if (key !== values.text) {
domClear(el, 0);
doc = el.ownerDocument;
lh = lineHeight(item);
value.forEach((t, i) => {
const ts = domCreate(doc, 'tspan', ns);
ts.__data__ = item; // data binding
ts.textContent = t;
if (i) {
ts.setAttribute('x', 0);
ts.setAttribute('dy', lh);
}
el.appendChild(ts);
});
values.text = key;
}
} else {
// single-line text
value = textValue(item, tl);
if (value !== values.text) {
el.textContent = value;
values.text = value;
}
}
setAttribute(el, 'font-family', fontFamily(item));
setAttribute(el, 'font-size', fontSize(item) + 'px');
setAttribute(el, 'font-style', item.fontStyle);
setAttribute(el, 'font-variant', item.fontVariant);
setAttribute(el, 'font-weight', item.fontWeight);
}
};
function setStyle(el, name, value) {
if (value !== values[name]) {
if (value == null) {
el.style.removeProperty(name);
} else {
el.style.setProperty(name, value + '');
}
values[name] = value;
}
}
prototype._update = function(mdef, el, item) {
// set dom element and values cache
// provides access to emit method
element = el;
values = el.__values__;
// apply aria-specific properties
ariaItemAttributes(emit, item);
// apply svg attributes
mdef.attr(emit, item, this);
// some marks need special treatment
const extra = mark_extras[mdef.type];
if (extra) extra.call(this, mdef, el, item);
// apply svg style attributes
// note: element may be modified by 'extra' method
if (element) this.style(element, item);
};
function emit(name, value, ns) {
// early exit if value is unchanged
if (value === values[name]) return;
// use appropriate method given namespace (ns)
if (ns) {
setAttributeNS(element, name, value, ns);
} else {
setAttribute(element, name, value);
}
// note current value for future comparison
values[name] = value;
}
function setAttribute(el, name, value) {
if (value != null) {
// if value is provided, update DOM attribute
el.setAttribute(name, value);
} else {
// else remove DOM attribute
el.removeAttribute(name);
}
}
function setAttributeNS(el, name, value, ns) {
if (value != null) {
// if value is provided, update DOM attribute
el.setAttributeNS(ns, name, value);
} else {
// else remove DOM attribute
el.removeAttributeNS(ns, name);
}
}
prototype.style = function(el, o) {
if (o == null) return;
for (const prop in styles) {
let value = prop === 'font' ? fontFamily(o) : o[prop];
if (value === values[prop]) continue;
const name = styles[prop];
if (value == null) {
el.removeAttribute(name);
} else {
if (isGradient(value)) {
value = gradientRef(value, this._defs.gradient, href());
}
el.setAttribute(name, value + '');
}
values[prop] = value;
}
};
function href() {
let loc;
return typeof window === 'undefined' ? ''
: (loc = window.location).hash ? loc.href.slice(0, -loc.hash.length)
: loc.href;
}

365
node_modules/vega-scenegraph/src/SVGStringRenderer.js generated vendored Normal file
View File

@@ -0,0 +1,365 @@
import Renderer from './Renderer';
import {gradientRef, isGradient, patternPrefix} from './Gradient';
import marks from './marks/index';
import {ariaItemAttributes, ariaMarkAttributes} from './util/aria';
import {cssClass} from './util/dom';
import {closeTag, openTag} from './util/tags';
import {fontFamily, fontSize, lineHeight, textLines, textValue} from './util/text';
import {visit} from './util/visit';
import clip from './util/svg/clip';
import metadata from './util/svg/metadata';
import {rootAttributes, styles} from './util/svg/styles';
import {extend, inherits, isArray} from 'vega-util';
export default function SVGStringRenderer(loader) {
Renderer.call(this, loader);
this._text = {
head: '',
bg: '',
root: '',
foot: '',
defs: '',
body: ''
};
this._defs = {
gradient: {},
clipping: {}
};
}
var prototype = inherits(SVGStringRenderer, Renderer);
var base = Renderer.prototype;
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
var o = this._origin,
t = this._text;
var attr = {
class: 'marks',
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: '0 0 ' + this._width + ' ' + this._height
};
for (var key in metadata) {
attr[key] = metadata[key];
}
t.head = openTag('svg', attr);
var bg = this._bgcolor;
if (bg === 'transparent' || bg === 'none') bg = null;
if (bg) {
t.bg = openTag('rect', {
width: this._width,
height: this._height,
fill: bg
}) + closeTag('rect');
} else {
t.bg = '';
}
t.root = openTag('g', extend(
{}, rootAttributes, {transform: 'translate(' + o + ')'}
));
t.foot = closeTag('g') + closeTag('svg');
return this;
};
prototype.background = function() {
var rv = base.background.apply(this, arguments);
if (arguments.length && this._text.head) {
this.resize(this._width, this._height, this._origin, this._scale);
}
return rv;
};
prototype.svg = function() {
var t = this._text;
return t.head + t.defs + t.bg + t.root + t.body + t.foot;
};
prototype._render = function(scene) {
this._text.body = this.mark(scene);
this._text.defs = this.buildDefs();
return this;
};
prototype.buildDefs = function() {
let defs = '', tag;
for (const id in this._defs.gradient) {
const def = this._defs.gradient[id],
stops = def.stops;
if (def.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
defs += openTag(tag = 'pattern', {
id: patternPrefix + id,
viewBox: '0,0,1,1',
width: '100%',
height: '100%',
preserveAspectRatio: 'xMidYMid slice'
});
defs += openTag('rect', {
width: '1',
height: '1',
fill: 'url(#' + id + ')'
}) + closeTag('rect');
defs += closeTag(tag);
defs += openTag(tag = 'radialGradient', {
id: id,
fx: def.x1,
fy: def.y1,
fr: def.r1,
cx: def.x2,
cy: def.y2,
r: def.r2
});
} else {
defs += openTag(tag = 'linearGradient', {
id: id,
x1: def.x1,
x2: def.x2,
y1: def.y1,
y2: def.y2
});
}
for (let i = 0; i < stops.length; ++i) {
defs += openTag('stop', {
offset: stops[i].offset,
'stop-color': stops[i].color
}) + closeTag('stop');
}
defs += closeTag(tag);
}
for (const id in this._defs.clipping) {
const def = this._defs.clipping[id];
defs += openTag('clipPath', {id: id});
if (def.path) {
defs += openTag('path', {
d: def.path
}) + closeTag('path');
} else {
defs += openTag('rect', {
x: 0,
y: 0,
width: def.width,
height: def.height
}) + closeTag('rect');
}
defs += closeTag('clipPath');
}
return defs ? (openTag('defs') + defs + closeTag('defs')) : '';
};
prototype.attr = function(scene, item, attrs, tag) {
const object = {},
emit = (name, value, ns, prefixed) => {
object[prefixed || name] = value;
};
// apply mark specific attributes
if (Array.isArray(attrs)) {
attrs.forEach(fn => fn(emit, item, this));
} else {
attrs(emit, item, this);
}
// apply style attributes
if (tag) {
applyStyles(object, item, scene, tag, this._defs);
}
return object;
};
prototype.href = function(item) {
var that = this,
href = item.href,
attr;
if (href) {
if (attr = that._hrefs && that._hrefs[href]) {
return attr;
} else {
that.sanitizeURL(href).then(attr => {
// rewrite to use xlink namespace
// note that this will be deprecated in SVG 2.0
attr['xlink:href'] = attr.href;
attr.href = null;
(that._hrefs || (that._hrefs = {}))[href] = attr;
});
}
}
return null;
};
prototype.mark = function(scene) {
const mdef = marks[scene.marktype],
tag = mdef.tag,
attrList = [ariaItemAttributes, mdef.attr];
let str = '';
// render opening group tag
str += openTag('g', extend(
{
'class': cssClass(scene),
'clip-path': scene.clip ? clip(this, scene, scene.group) : null
},
ariaMarkAttributes(scene),
{
'pointer-events': tag !== 'g' && scene.interactive === false ? 'none' : null
}
));
// render contained elements
const process = item => {
const href = this.href(item);
if (href) str += openTag('a', href);
str += openTag(
tag,
this.attr(scene, item, attrList, tag !== 'g' ? tag : null)
);
if (tag === 'text') {
const tl = textLines(item);
if (isArray(tl)) {
// multi-line text
const attrs = {x: 0, dy: lineHeight(item)};
for (let i=0; i<tl.length; ++i) {
str += openTag('tspan', i ? attrs: null)
+ escape_text(textValue(item, tl[i]))
+ closeTag('tspan');
}
} else {
// single-line text
str += escape_text(textValue(item, tl));
}
} else if (tag === 'g') {
const fore = item.strokeForeground,
fill = item.fill,
stroke = item.stroke;
if (fore && stroke) {
item.stroke = null;
}
str += openTag(
'path',
this.attr(scene, item, mdef.background, 'bgrect')
) + closeTag('path');
str += openTag('g', this.attr(scene, item, mdef.content))
+ this.markGroup(item)
+ closeTag('g');
if (fore && stroke) {
if (fill) item.fill = null;
item.stroke = stroke;
str += openTag(
'path',
this.attr(scene, item, mdef.foreground, 'bgrect')
) + closeTag('path');
if (fill) item.fill = fill;
} else {
str += openTag(
'path',
this.attr(scene, item, mdef.foreground, 'bgfore')
) + closeTag('path');
}
}
str += closeTag(tag);
if (href) str += closeTag('a');
};
if (mdef.nested) {
if (scene.items && scene.items.length) process(scene.items[0]);
} else {
visit(scene, process);
}
// render closing group tag
return str + closeTag('g');
};
prototype.markGroup = function(scene) {
let str = '';
visit(scene, item => { str += this.mark(item); });
return str;
};
function applyStyles(s, item, scene, tag, defs) {
if (item == null) return s;
if (tag === 'bgrect' && scene.interactive === false) {
s['pointer-events'] = 'none';
}
if (tag === 'bgfore') {
if (scene.interactive === false) {
s['pointer-events'] = 'none';
}
s.display = 'none';
if (item.fill !== null) return s;
}
if (tag === 'image' && item.smooth === false) {
s.style = 'image-rendering: optimizeSpeed; image-rendering: pixelated;';
}
if (tag === 'text') {
s['font-family'] = fontFamily(item);
s['font-size'] = fontSize(item) + 'px';
if (item.fontStyle) s['font-style'] = item.fontStyle;
if (item.fontVariant) s['font-variant'] = item.fontVariant;
if (item.fontWeight) s['font-weight'] = item.fontWeight;
}
for (const prop in styles) {
let value = item[prop];
const name = styles[prop];
if (value === 'transparent' && (name === 'fill' || name === 'stroke')) {
// transparent is not a legal SVG value
// we can skip it to rely on default 'none' instead
} else if (value != null) {
if (isGradient(value)) {
value = gradientRef(value, defs.gradient, '');
}
s[name] = value;
}
}
return s;
}
function escape_text(s) {
return s.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}

54
node_modules/vega-scenegraph/src/Scenegraph.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
import Bounds from './Bounds';
import GroupItem from './GroupItem';
import {sceneFromJSON, sceneToJSON} from './util/serialize';
export default function Scenegraph(scene) {
if (arguments.length) {
this.root = sceneFromJSON(scene);
} else {
this.root = createMark({
marktype: 'group',
name: 'root',
role: 'frame'
});
this.root.items = [new GroupItem(this.root)];
}
}
var prototype = Scenegraph.prototype;
prototype.toJSON = function(indent) {
return sceneToJSON(this.root, indent || 0);
};
prototype.mark = function(markdef, group, index) {
group = group || this.root.items[0];
var mark = createMark(markdef, group);
group.items[index] = mark;
if (mark.zindex) mark.group.zdirty = true;
return mark;
};
function createMark(def, group) {
const mark = {
bounds: new Bounds(),
clip: !!def.clip,
group: group,
interactive: def.interactive === false ? false : true,
items: [],
marktype: def.marktype,
name: def.name || undefined,
role: def.role || undefined,
zindex: def.zindex || 0
};
// add accessibility properties if defined
if (def.aria != null) {
mark.aria = def.aria;
}
if (def.description) {
mark.description = def.description;
}
return mark;
}

17
node_modules/vega-scenegraph/src/bound/boundClip.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
import Bounds from '../Bounds';
import boundContext from './boundContext';
import {isFunction} from 'vega-util';
var clipBounds = new Bounds();
export default function(mark) {
var clip = mark.clip;
if (isFunction(clip)) {
clip(boundContext(clipBounds.clear()));
} else if (clip) {
clipBounds.set(0, 0, mark.group.width, mark.group.height);
} else return;
mark.bounds.intersect(clipBounds);
}

119
node_modules/vega-scenegraph/src/bound/boundContext.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
import {Epsilon, HalfPi, Tau} from '../util/constants';
var bounds, lx, ly,
circleThreshold = Tau - 1e-8;
export default function context(_) {
bounds = _;
return context;
}
function noop() {}
function add(x, y) { bounds.add(x, y); }
function addL(x, y) { add(lx = x, ly = y); }
function addX(x) { add(x, bounds.y1); }
function addY(y) { add(bounds.x1, y); }
context.beginPath = noop;
context.closePath = noop;
context.moveTo = addL;
context.lineTo = addL;
context.rect = function(x, y, w, h) {
add(x + w, y + h);
addL(x, y);
};
context.quadraticCurveTo = function(x1, y1, x2, y2) {
quadExtrema(lx, x1, x2, addX);
quadExtrema(ly, y1, y2, addY);
addL(x2, y2);
};
function quadExtrema(x0, x1, x2, cb) {
const t = (x0 - x1) / (x0 + x2 - 2 * x1);
if (0 < t && t < 1) cb(x0 + (x1 - x0) * t);
}
context.bezierCurveTo = function(x1, y1, x2, y2, x3, y3) {
cubicExtrema(lx, x1, x2, x3, addX);
cubicExtrema(ly, y1, y2, y3, addY);
addL(x3, y3);
};
function cubicExtrema(x0, x1, x2, x3, cb) {
const a = x3 - x0 + 3 * x1 - 3 * x2,
b = x0 + x2 - 2 * x1,
c = x0 - x1;
let t0 = 0, t1 = 0, r;
// solve for parameter t
if (Math.abs(a) > Epsilon) {
// quadratic equation
r = b * b + c * a;
if (r >= 0) {
r = Math.sqrt(r);
t0 = (-b + r) / a;
t1 = (-b - r) / a;
}
} else {
// linear equation
t0 = 0.5 * c / b;
}
// calculate position
if (0 < t0 && t0 < 1) cb(cubic(t0, x0, x1, x2, x3));
if (0 < t1 && t1 < 1) cb(cubic(t1, x0, x1, x2, x3));
}
function cubic(t, x0, x1, x2, x3) {
const s = 1 - t, s2 = s * s, t2 = t * t;
return (s2 * s * x0) + (3 * s2 * t * x1) + (3 * s * t2 * x2) + (t2 * t * x3);
}
context.arc = function(cx, cy, r, sa, ea, ccw) {
// store last point on path
lx = r * Math.cos(ea) + cx;
ly = r * Math.sin(ea) + cy;
if (Math.abs(ea - sa) > circleThreshold) {
// treat as full circle
add(cx - r, cy - r);
add(cx + r, cy + r);
} else {
const update = a => add(r * Math.cos(a) + cx, r * Math.sin(a) + cy);
let s, i;
// sample end points
update(sa);
update(ea);
// sample interior points aligned with 90 degrees
if (ea !== sa) {
sa = sa % Tau; if (sa < 0) sa += Tau;
ea = ea % Tau; if (ea < 0) ea += Tau;
if (ea < sa) {
ccw = !ccw; // flip direction
s = sa; sa = ea; ea = s; // swap end-points
}
if (ccw) {
ea -= Tau;
s = sa - (sa % HalfPi);
for (i=0; i<4 && s>ea; ++i, s-=HalfPi) update(s);
} else {
s = sa - (sa % HalfPi) + HalfPi;
for (i=0; i<4 && s<ea; ++i, s=s+HalfPi) update(s);
}
}
}
};

10
node_modules/vega-scenegraph/src/bound/boundItem.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import Bounds from '../Bounds';
import marks from '../marks/index';
export default function(item, func, opt) {
var type = marks[item.mark.marktype],
bound = func || type.bound;
if (type.nested) item = item.mark;
return bound(item.bounds || (item.bounds = new Bounds()), item, opt);
}

38
node_modules/vega-scenegraph/src/bound/boundMark.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
import Bounds from '../Bounds';
import boundItem from './boundItem';
import marks from '../marks/index';
var DUMMY = {mark: null};
export default function(mark, bounds, opt) {
var type = marks[mark.marktype],
bound = type.bound,
items = mark.items,
hasItems = items && items.length,
i, n, item, b;
if (type.nested) {
if (hasItems) {
item = items[0];
} else {
// no items, fake it
DUMMY.mark = mark;
item = DUMMY;
}
b = boundItem(item, bound, opt);
bounds = bounds && bounds.union(b) || b;
return bounds;
}
bounds = bounds
|| mark.bounds && mark.bounds.clear()
|| new Bounds();
if (hasItems) {
for (i=0, n=items.length; i<n; ++i) {
bounds.union(boundItem(items[i], bound, opt));
}
}
return mark.bounds = bounds;
}

12
node_modules/vega-scenegraph/src/bound/boundStroke.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
export default function(bounds, item, miter) {
if (item.stroke && item.opacity !== 0 && item.strokeOpacity !== 0) {
const sw = item.strokeWidth != null ? +item.strokeWidth : 1;
bounds.expand(sw + (miter ? miterAdjustment(item, sw) : 0));
}
return bounds;
}
function miterAdjustment(item, strokeWidth) {
// TODO: more sophisticated adjustment? Or miter support in boundContext?
return item.strokeJoin && item.strokeJoin !== 'miter' ? 0 : strokeWidth;
}

78
node_modules/vega-scenegraph/src/intersect.js generated vendored Normal file
View File

@@ -0,0 +1,78 @@
import Marks from './marks/index';
import {error} from 'vega-util';
import Bounds from './Bounds';
export function intersect(scene, bounds, filter) {
const hits = [], // intersection results
box = new Bounds().union(bounds), // defensive copy
type = scene.marktype;
return type ? intersectMark(scene, box, filter, hits)
: type === 'group' ? intersectGroup(scene, box, filter, hits)
: error('Intersect scene must be mark node or group item.');
}
function intersectMark(mark, box, filter, hits) {
if (visitMark(mark, box, filter)) {
const items = mark.items,
type = mark.marktype,
n = items.length;
let i = 0;
if (type === 'group') {
for (; i<n; ++i) {
intersectGroup(items[i], box, filter, hits);
}
} else {
for (const test = Marks[type].isect; i<n; ++i) {
let item = items[i];
if (intersectItem(item, box, test)) hits.push(item);
}
}
}
return hits;
}
function visitMark(mark, box, filter) {
// process if bounds intersect and if
// (1) mark is a group mark (so we must recurse), or
// (2) mark is interactive and passes filter
return mark.bounds && box.intersects(mark.bounds) && (
mark.marktype === 'group' ||
mark.interactive !== false && (!filter || filter(mark))
);
}
function intersectGroup(group, box, filter, hits) {
// test intersect against group
// skip groups by default unless filter says otherwise
if ((filter && filter(group.mark)) &&
intersectItem(group, box, Marks.group.isect)) {
hits.push(group);
}
// recursively test children marks
// translate box to group coordinate space
const marks = group.items,
n = marks && marks.length;
if (n) {
const x = group.x || 0,
y = group.y || 0;
box.translate(-x, -y);
for (let i=0; i<n; ++i) {
intersectMark(marks[i], box, filter, hits);
}
box.translate(x, y);
}
return hits;
}
function intersectItem(item, box, test) {
// test bounds enclosure, bounds intersection, then detailed test
const bounds = item.bounds;
return box.encloses(bounds) || (box.intersects(bounds) && test(item, box));
}

4
node_modules/vega-scenegraph/src/marks/arc.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import {arc} from '../path/shapes';
import markItemPath from './markItemPath';
export default markItemPath('arc', arc);

5
node_modules/vega-scenegraph/src/marks/area.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import {area} from '../path/shapes';
import {pickArea} from '../util/pickPath';
import markMultiItemPath from './markMultiItemPath';
export default markMultiItemPath('area', area, pickArea);

202
node_modules/vega-scenegraph/src/marks/group.js generated vendored Normal file
View File

@@ -0,0 +1,202 @@
import {hasCornerRadius, rectangle} from '../path/shapes';
import boundStroke from '../bound/boundStroke';
import {intersectRect} from '../util/intersect';
import value from '../util/value';
import {pickVisit, visit} from '../util/visit';
import blend from '../util/canvas/blend';
import {clipGroup} from '../util/canvas/clip';
import fill from '../util/canvas/fill';
import stroke from '../util/canvas/stroke';
import {hitPath} from '../util/canvas/pick';
import clip from '../util/svg/clip';
import {translateItem} from '../util/svg/transform';
function offset(item) {
const sw = value(item.strokeWidth, 1);
return item.strokeOffset != null ? item.strokeOffset
: item.stroke && sw > 0.5 && sw < 1.5 ? 0.5 - Math.abs(sw - 1)
: 0;
}
function attr(emit, item) {
emit('transform', translateItem(item));
}
function emitRectangle(emit, item) {
const off = offset(item);
emit('d', rectangle(null, item, off, off));
}
function background(emit, item) {
emit('class', 'background');
emit('aria-hidden', true);
emitRectangle(emit, item);
}
function foreground(emit, item) {
emit('class', 'foreground');
emit('aria-hidden', true);
if (item.strokeForeground) {
emitRectangle(emit, item);
} else {
emit('d', '');
}
}
function content(emit, item, renderer) {
const url = item.clip ? clip(renderer, item, item) : null;
emit('clip-path', url);
}
function bound(bounds, group) {
if (!group.clip && group.items) {
const items = group.items, m = items.length;
for (let j=0; j<m; ++j) {
bounds.union(items[j].bounds);
}
}
if ((group.clip || group.width || group.height) && !group.noBound) {
bounds.add(0, 0).add(group.width || 0, group.height || 0);
}
boundStroke(bounds, group);
return bounds.translate(group.x || 0, group.y || 0);
}
function rectanglePath(context, group, x, y) {
const off = offset(group);
context.beginPath();
rectangle(context, group, (x || 0) + off, (y || 0) + off);
}
const hitBackground = hitPath(rectanglePath);
const hitForeground = hitPath(rectanglePath, false);
function draw(context, scene, bounds) {
visit(scene, group => {
const gx = group.x || 0,
gy = group.y || 0,
fore = group.strokeForeground,
opacity = group.opacity == null ? 1 : group.opacity;
// draw group background
if ((group.stroke || group.fill) && opacity) {
rectanglePath(context, group, gx, gy);
blend(context, group);
if (group.fill && fill(context, group, opacity)) {
context.fill();
}
if (group.stroke && !fore && stroke(context, group, opacity)) {
context.stroke();
}
}
// setup graphics context, set clip and bounds
context.save();
context.translate(gx, gy);
if (group.clip) clipGroup(context, group);
if (bounds) bounds.translate(-gx, -gy);
// draw group contents
visit(group, item => {
this.draw(context, item, bounds);
});
// restore graphics context
if (bounds) bounds.translate(gx, gy);
context.restore();
// draw group foreground
if (fore && group.stroke && opacity) {
rectanglePath(context, group, gx, gy);
blend(context, group);
if (stroke(context, group, opacity)) {
context.stroke();
}
}
});
}
function pick(context, scene, x, y, gx, gy) {
if (scene.bounds && !scene.bounds.contains(gx, gy) || !scene.items) {
return null;
}
const cx = x * context.pixelRatio,
cy = y * context.pixelRatio;
return pickVisit(scene, group => {
let hit, fore, ix, dx, dy, dw, dh, b, c;
// first hit test bounding box
b = group.bounds;
if (b && !b.contains(gx, gy)) return;
// passed bounds check, test rectangular clip
dx = group.x || 0;
dy = group.y || 0;
dw = dx + (group.width || 0);
dh = dy + (group.height || 0);
c = group.clip;
if (c && (gx < dx || gx > dw || gy < dy || gy > dh)) return;
// adjust coordinate system
context.save();
context.translate(dx, dy);
dx = gx - dx;
dy = gy - dy;
// test background for rounded corner clip
if (c && hasCornerRadius(group) && !hitBackground(context, group, cx, cy)) {
context.restore();
return null;
}
fore = group.strokeForeground;
ix = scene.interactive !== false;
// hit test against group foreground
if (ix && fore && group.stroke
&& hitForeground(context, group, cx, cy)) {
context.restore();
return group;
}
// hit test against contained marks
hit = pickVisit(group, mark => pickMark(mark, dx, dy)
? this.pick(mark, x, y, dx, dy)
: null
);
// hit test against group background
if (!hit && ix && (group.fill || (!fore && group.stroke))
&& hitBackground(context, group, cx, cy)) {
hit = group;
}
// restore state and return
context.restore();
return hit || null;
});
}
function pickMark(mark, x, y) {
return (mark.interactive !== false || mark.marktype === 'group')
&& mark.bounds && mark.bounds.contains(x, y);
}
export default {
type: 'group',
tag: 'g',
nested: false,
attr: attr,
bound: bound,
draw: draw,
pick: pick,
isect: intersectRect,
content: content,
background: background,
foreground: foreground
};

115
node_modules/vega-scenegraph/src/marks/image.js generated vendored Normal file
View File

@@ -0,0 +1,115 @@
import {visit} from '../util/visit';
import blend from '../util/canvas/blend';
import {pick} from '../util/canvas/pick';
import metadata from '../util/svg/metadata';
import {translate} from '../util/svg/transform';
import {truthy} from 'vega-util';
function getImage(item, renderer) {
var image = item.image;
if (!image || item.url && item.url !== image.url) {
image = {complete: false, width: 0, height: 0};
renderer.loadImage(item.url).then(image => {
item.image = image;
item.image.url = item.url;
});
}
return image;
}
function imageWidth(item, image) {
return item.width != null ? item.width
: !image || !image.width ? 0
: item.aspect !== false && item.height ? item.height * image.width / image.height
: image.width;
}
function imageHeight(item, image) {
return item.height != null ? item.height
: !image || !image.height ? 0
: item.aspect !== false && item.width ? item.width * image.height / image.width
: image.height;
}
function imageXOffset(align, w) {
return align === 'center' ? w / 2 : align === 'right' ? w : 0;
}
function imageYOffset(baseline, h) {
return baseline === 'middle' ? h / 2 : baseline === 'bottom' ? h : 0;
}
function attr(emit, item, renderer) {
const img = getImage(item, renderer),
w = imageWidth(item, img),
h = imageHeight(item, img),
x = (item.x || 0) - imageXOffset(item.align, w),
y = (item.y || 0) - imageYOffset(item.baseline, h),
i = !img.src && img.toDataURL ? img.toDataURL() : img.src || '';
emit('href', i, metadata['xmlns:xlink'], 'xlink:href');
emit('transform', translate(x, y));
emit('width', w);
emit('height', h);
emit('preserveAspectRatio', item.aspect === false ? 'none' : 'xMidYMid');
}
function bound(bounds, item) {
const img = item.image,
w = imageWidth(item, img),
h = imageHeight(item, img),
x = (item.x || 0) - imageXOffset(item.align, w),
y = (item.y || 0) - imageYOffset(item.baseline, h);
return bounds.set(x, y, x + w, y + h);
}
function draw(context, scene, bounds) {
visit(scene, item => {
if (bounds && !bounds.intersects(item.bounds)) return; // bounds check
let img = getImage(item, this),
w = imageWidth(item, img),
h = imageHeight(item, img),
x = (item.x || 0) - imageXOffset(item.align, w),
y = (item.y || 0) - imageYOffset(item.baseline, h),
opacity, ar0, ar1, t;
if (item.aspect !== false) {
ar0 = img.width / img.height;
ar1 = item.width / item.height;
if (ar0 === ar0 && ar1 === ar1 && ar0 !== ar1) {
if (ar1 < ar0) {
t = w / ar0;
y += (h - t) / 2;
h = t;
} else {
t = h * ar0;
x += (w - t) / 2;
w = t;
}
}
}
if (img.complete || img.toDataURL) {
blend(context, item);
context.globalAlpha = (opacity = item.opacity) != null ? opacity : 1;
context.imageSmoothingEnabled = item.smooth !== false;
context.drawImage(img, x, y, w, h);
}
});
}
export default {
type: 'image',
tag: 'image',
nested: false,
attr: attr,
bound: bound,
draw: draw,
pick: pick(),
isect: truthy, // bounds check is sufficient
get: getImage,
xOffset: imageXOffset,
yOffset: imageYOffset
};

27
node_modules/vega-scenegraph/src/marks/index.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
import arc from './arc';
import area from './area';
import group from './group';
import image from './image';
import line from './line';
import path from './path';
import rect from './rect';
import rule from './rule';
import shape from './shape';
import symbol from './symbol';
import text from './text';
import trail from './trail';
export default {
arc: arc,
area: area,
group: group,
image: image,
line: line,
path: path,
rect: rect,
rule: rule,
shape: shape,
symbol: symbol,
text: text,
trail: trail
};

5
node_modules/vega-scenegraph/src/marks/line.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import {line} from '../path/shapes';
import {pickLine} from '../util/pickPath';
import markMultiItemPath from './markMultiItemPath';
export default markMultiItemPath('line', line, pickLine);

53
node_modules/vega-scenegraph/src/marks/markItemPath.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import boundStroke from '../bound/boundStroke';
import context from '../bound/boundContext';
import {intersectPath} from '../util/intersect';
import {drawAll} from '../util/canvas/draw';
import {pickPath} from '../util/canvas/pick';
import {transformItem} from '../util/svg/transform';
import {DegToRad} from '../util/constants';
export default function(type, shape, isect) {
function attr(emit, item) {
emit('transform', transformItem(item));
emit('d', shape(null, item));
}
function bound(bounds, item) {
var x = item.x || 0,
y = item.y || 0;
shape(context(bounds), item);
boundStroke(bounds, item).translate(x, y);
if (item.angle) {
bounds.rotate(item.angle * DegToRad, x, y);
}
return bounds;
}
function draw(context, item) {
var x = item.x || 0,
y = item.y || 0,
a = item.angle || 0;
context.translate(x, y);
if (a) context.rotate(a *= DegToRad);
context.beginPath();
shape(context, item);
if (a) context.rotate(-a);
context.translate(-x, -y);
}
return {
type: type,
tag: 'path',
nested: false,
attr: attr,
bound: bound,
draw: drawAll(draw),
pick: pickPath(draw),
isect: isect || intersectPath(draw)
};
}

View File

@@ -0,0 +1,58 @@
import boundStroke from '../bound/boundStroke';
import context from '../bound/boundContext';
import {intersectPoint} from '../util/intersect';
import {drawOne} from '../util/canvas/draw';
import {hitPath} from '../util/canvas/pick';
export default function(type, shape, tip) {
function attr(emit, item) {
var items = item.mark.items;
if (items.length) emit('d', shape(null, items));
}
function bound(bounds, mark) {
var items = mark.items;
if (items.length === 0) {
return bounds;
} else {
shape(context(bounds), items);
return boundStroke(bounds, items[0]);
}
}
function draw(context, items) {
context.beginPath();
shape(context, items);
}
var hit = hitPath(draw);
function pick(context, scene, x, y, gx, gy) {
var items = scene.items,
b = scene.bounds;
if (!items || !items.length || b && !b.contains(gx, gy)) {
return null;
}
x *= context.pixelRatio;
y *= context.pixelRatio;
return hit(context, items, x, y) ? items[0] : null;
}
return {
type: type,
tag: 'path',
nested: true,
attr: attr,
bound: bound,
draw: drawOne(draw),
pick: pick,
isect: intersectPoint,
tip: tip
};
}

68
node_modules/vega-scenegraph/src/marks/path.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
import boundStroke from '../bound/boundStroke';
import context from '../bound/boundContext';
import pathParse from '../path/parse';
import pathRender from '../path/render';
import {intersectPath} from '../util/intersect';
import {drawAll} from '../util/canvas/draw';
import {pickPath} from '../util/canvas/pick';
import {transformItem} from '../util/svg/transform';
import {DegToRad} from '../util/constants';
function attr(emit, item) {
var sx = item.scaleX || 1,
sy = item.scaleY || 1;
if (sx !== 1 || sy !== 1) {
emit('vector-effect', 'non-scaling-stroke');
}
emit('transform', transformItem(item));
emit('d', item.path);
}
function path(context, item) {
var path = item.path;
if (path == null) return true;
var x = item.x || 0,
y = item.y || 0,
sx = item.scaleX || 1,
sy = item.scaleY || 1,
a = (item.angle || 0) * DegToRad,
cache = item.pathCache;
if (!cache || cache.path !== path) {
(item.pathCache = cache = pathParse(path)).path = path;
}
if (a && context.rotate && context.translate) {
context.translate(x, y);
context.rotate(a);
pathRender(context, cache, 0, 0, sx, sy);
context.rotate(-a);
context.translate(-x, -y);
} else {
pathRender(context, cache, x, y, sx, sy);
}
}
function bound(bounds, item) {
path(context(bounds), item)
? bounds.set(0, 0, 0, 0)
: boundStroke(bounds, item, true);
if (item.angle) {
bounds.rotate(item.angle * DegToRad, item.x || 0, item.y || 0);
}
return bounds;
}
export default {
type: 'path',
tag: 'path',
nested: false,
attr: attr,
bound: bound,
draw: drawAll(path),
pick: pickPath(path),
isect: intersectPath(path)
};

35
node_modules/vega-scenegraph/src/marks/rect.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
import boundStroke from '../bound/boundStroke';
import {rectangle} from '../path/shapes';
import {intersectRect} from '../util/intersect';
import {drawAll} from '../util/canvas/draw';
import {pickPath} from '../util/canvas/pick';
function attr(emit, item) {
emit('d', rectangle(null, item));
}
function bound(bounds, item) {
var x, y;
return boundStroke(bounds.set(
x = item.x || 0,
y = item.y || 0,
(x + item.width) || 0,
(y + item.height) || 0
), item);
}
function draw(context, item) {
context.beginPath();
rectangle(context, item);
}
export default {
type: 'rect',
tag: 'path',
nested: false,
attr: attr,
bound: bound,
draw: drawAll(draw),
pick: pickPath(draw),
isect: intersectRect
};

66
node_modules/vega-scenegraph/src/marks/rule.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import boundStroke from '../bound/boundStroke';
import {intersectRule} from '../util/intersect';
import {visit} from '../util/visit';
import blend from '../util/canvas/blend';
import {pick} from '../util/canvas/pick';
import stroke from '../util/canvas/stroke';
import {translateItem} from '../util/svg/transform';
function attr(emit, item) {
emit('transform', translateItem(item));
emit('x2', item.x2 != null ? item.x2 - (item.x || 0) : 0);
emit('y2', item.y2 != null ? item.y2 - (item.y || 0) : 0);
}
function bound(bounds, item) {
var x1, y1;
return boundStroke(bounds.set(
x1 = item.x || 0,
y1 = item.y || 0,
item.x2 != null ? item.x2 : x1,
item.y2 != null ? item.y2 : y1
), item);
}
function path(context, item, opacity) {
var x1, y1, x2, y2;
if (item.stroke && stroke(context, item, opacity)) {
x1 = item.x || 0;
y1 = item.y || 0;
x2 = item.x2 != null ? item.x2 : x1;
y2 = item.y2 != null ? item.y2 : y1;
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
return true;
}
return false;
}
function draw(context, scene, bounds) {
visit(scene, function(item) {
if (bounds && !bounds.intersects(item.bounds)) return; // bounds check
var opacity = item.opacity == null ? 1 : item.opacity;
if (opacity && path(context, item, opacity)) {
blend(context, item);
context.stroke();
}
});
}
function hit(context, item, x, y) {
if (!context.isPointInStroke) return false;
return path(context, item, 1) && context.isPointInStroke(x, y);
}
export default {
type: 'rule',
tag: 'line',
nested: false,
attr: attr,
bound: bound,
draw: draw,
pick: pick(hit),
isect: intersectRule
};

4
node_modules/vega-scenegraph/src/marks/shape.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import {shape} from '../path/shapes';
import markItemPath from './markItemPath';
export default markItemPath('shape', shape);

5
node_modules/vega-scenegraph/src/marks/symbol.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import {symbol} from '../path/shapes';
import {intersectPoint} from '../util/intersect';
import markItemPath from './markItemPath';
export default markItemPath('symbol', symbol, intersectPoint);

184
node_modules/vega-scenegraph/src/marks/text.js generated vendored Normal file
View File

@@ -0,0 +1,184 @@
import Bounds from '../Bounds';
import {DegToRad, HalfPi} from '../util/constants';
import {font, lineHeight, offset, textLines, textMetrics, textValue} from '../util/text';
import {intersectBoxLine} from '../util/intersect';
import {visit} from '../util/visit';
import blend from '../util/canvas/blend';
import fill from '../util/canvas/fill';
import {pick} from '../util/canvas/pick';
import stroke from '../util/canvas/stroke';
import {rotate, translate} from '../util/svg/transform';
import {isArray} from 'vega-util';
var textAlign = {
'left': 'start',
'center': 'middle',
'right': 'end'
};
var tempBounds = new Bounds();
function anchorPoint(item) {
var x = item.x || 0,
y = item.y || 0,
r = item.radius || 0, t;
if (r) {
t = (item.theta || 0) - HalfPi;
x += r * Math.cos(t);
y += r * Math.sin(t);
}
tempBounds.x1 = x;
tempBounds.y1 = y;
return tempBounds;
}
function attr(emit, item) {
var dx = item.dx || 0,
dy = (item.dy || 0) + offset(item),
p = anchorPoint(item),
x = p.x1,
y = p.y1,
a = item.angle || 0, t;
emit('text-anchor', textAlign[item.align] || 'start');
if (a) {
t = translate(x, y) + ' ' + rotate(a);
if (dx || dy) t += ' ' + translate(dx, dy);
} else {
t = translate(x + dx, y + dy);
}
emit('transform', t);
}
function bound(bounds, item, mode) {
var h = textMetrics.height(item),
a = item.align,
p = anchorPoint(item),
x = p.x1,
y = p.y1,
dx = item.dx || 0,
dy = (item.dy || 0) + offset(item) - Math.round(0.8*h), // use 4/5 offset
tl = textLines(item),
w;
// get dimensions
if (isArray(tl)) {
// multi-line text
h += lineHeight(item) * (tl.length - 1);
w = tl.reduce((w, t) => Math.max(w, textMetrics.width(item, t)), 0);
} else {
// single-line text
w = textMetrics.width(item, tl);
}
// horizontal alignment
if (a === 'center') {
dx -= (w / 2);
} else if (a === 'right') {
dx -= w;
} else {
// left by default, do nothing
}
bounds.set(dx+=x, dy+=y, dx+w, dy+h);
if (item.angle && !mode) {
bounds.rotate(item.angle * DegToRad, x, y);
} else if (mode === 2) {
return bounds.rotatedPoints(item.angle * DegToRad, x, y);
}
return bounds;
}
function draw(context, scene, bounds) {
visit(scene, function(item) {
var opacity = item.opacity == null ? 1 : item.opacity,
p, x, y, i, lh, tl, str;
if (bounds && !bounds.intersects(item.bounds) || // bounds check
opacity === 0 || item.fontSize <= 0 ||
item.text == null || item.text.length === 0) return;
context.font = font(item);
context.textAlign = item.align || 'left';
p = anchorPoint(item);
x = p.x1,
y = p.y1;
if (item.angle) {
context.save();
context.translate(x, y);
context.rotate(item.angle * DegToRad);
x = y = 0; // reset x, y
}
x += (item.dx || 0);
y += (item.dy || 0) + offset(item);
tl = textLines(item);
blend(context, item);
if (isArray(tl)) {
lh = lineHeight(item);
for (i=0; i<tl.length; ++i) {
str = textValue(item, tl[i]);
if (item.fill && fill(context, item, opacity)) {
context.fillText(str, x, y);
}
if (item.stroke && stroke(context, item, opacity)) {
context.strokeText(str, x, y);
}
y += lh;
}
} else {
str = textValue(item, tl);
if (item.fill && fill(context, item, opacity)) {
context.fillText(str, x, y);
}
if (item.stroke && stroke(context, item, opacity)) {
context.strokeText(str, x, y);
}
}
if (item.angle) context.restore();
});
}
function hit(context, item, x, y, gx, gy) {
if (item.fontSize <= 0) return false;
if (!item.angle) return true; // bounds sufficient if no rotation
// project point into space of unrotated bounds
var p = anchorPoint(item),
ax = p.x1,
ay = p.y1,
b = bound(tempBounds, item, 1),
a = -item.angle * DegToRad,
cos = Math.cos(a),
sin = Math.sin(a),
px = cos * gx - sin * gy + (ax - cos * ax + sin * ay),
py = sin * gx + cos * gy + (ay - sin * ax - cos * ay);
return b.contains(px, py);
}
function intersectText(item, box) {
var p = bound(tempBounds, item, 2);
return intersectBoxLine(box, p[0], p[1], p[2], p[3])
|| intersectBoxLine(box, p[0], p[1], p[4], p[5])
|| intersectBoxLine(box, p[4], p[5], p[6], p[7])
|| intersectBoxLine(box, p[2], p[3], p[6], p[7]);
}
export default {
type: 'text',
tag: 'text',
nested: false,
attr: attr,
bound: bound,
draw: draw,
pick: pick(hit),
isect: intersectText
};

5
node_modules/vega-scenegraph/src/marks/trail.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import {trail} from '../path/shapes';
import {pickTrail} from '../util/pickPath';
import markMultiItemPath from './markMultiItemPath';
export default markMultiItemPath('trail', trail, pickTrail);

43
node_modules/vega-scenegraph/src/modules.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
import CanvasHandler from './CanvasHandler';
import CanvasRenderer from './CanvasRenderer';
import SVGHandler from './SVGHandler';
import SVGRenderer from './SVGRenderer';
import SVGStringRenderer from './SVGStringRenderer';
var Canvas = 'canvas';
var PNG = 'png';
var SVG = 'svg';
var None = 'none';
export var RenderType = {
Canvas: Canvas,
PNG: PNG,
SVG: SVG,
None: None
};
var modules = {};
modules[Canvas] = modules[PNG] = {
renderer: CanvasRenderer,
headless: CanvasRenderer,
handler: CanvasHandler
};
modules[SVG] = {
renderer: SVGRenderer,
headless: SVGStringRenderer,
handler: SVGHandler
};
modules[None] = {};
export function renderModule(name, _) {
name = String(name || '').toLowerCase();
if (arguments.length > 1) {
modules[name] = _;
return this;
} else {
return modules[name];
}
}

107
node_modules/vega-scenegraph/src/path/arc.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
import {DegToRad, HalfPi, Tau} from '../util/constants';
export var segmentCache = {};
export var bezierCache = {};
var join = [].join;
// Copied from Inkscape svgtopdf, thanks!
export function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
var key = join.call(arguments);
if (segmentCache[key]) {
return segmentCache[key];
}
var th = rotateX * DegToRad;
var sin_th = Math.sin(th);
var cos_th = Math.cos(th);
rx = Math.abs(rx);
ry = Math.abs(ry);
var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5;
var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5;
var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry);
if (pl > 1) {
pl = Math.sqrt(pl);
rx *= pl;
ry *= pl;
}
var a00 = cos_th / rx;
var a01 = sin_th / rx;
var a10 = (-sin_th) / ry;
var a11 = (cos_th) / ry;
var x0 = a00 * ox + a01 * oy;
var y0 = a10 * ox + a11 * oy;
var x1 = a00 * x + a01 * y;
var y1 = a10 * x + a11 * y;
var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0);
var sfactor_sq = 1 / d - 0.25;
if (sfactor_sq < 0) sfactor_sq = 0;
var sfactor = Math.sqrt(sfactor_sq);
if (sweep == large) sfactor = -sfactor;
var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0);
var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0);
var th0 = Math.atan2(y0-yc, x0-xc);
var th1 = Math.atan2(y1-yc, x1-xc);
var th_arc = th1-th0;
if (th_arc < 0 && sweep === 1) {
th_arc += Tau;
} else if (th_arc > 0 && sweep === 0) {
th_arc -= Tau;
}
var segs = Math.ceil(Math.abs(th_arc / (HalfPi + 0.001)));
var result = [];
for (var i=0; i<segs; ++i) {
var th2 = th0 + i * th_arc / segs;
var th3 = th0 + (i+1) * th_arc / segs;
result[i] = [xc, yc, th2, th3, rx, ry, sin_th, cos_th];
}
return (segmentCache[key] = result);
}
export function bezier(params) {
var key = join.call(params);
if (bezierCache[key]) {
return bezierCache[key];
}
var cx = params[0],
cy = params[1],
th0 = params[2],
th1 = params[3],
rx = params[4],
ry = params[5],
sin_th = params[6],
cos_th = params[7];
var a00 = cos_th * rx;
var a01 = -sin_th * ry;
var a10 = sin_th * rx;
var a11 = cos_th * ry;
var cos_th0 = Math.cos(th0);
var sin_th0 = Math.sin(th0);
var cos_th1 = Math.cos(th1);
var sin_th1 = Math.sin(th1);
var th_half = 0.5 * (th1 - th0);
var sin_th_h2 = Math.sin(th_half * 0.5);
var t = (8/3) * sin_th_h2 * sin_th_h2 / Math.sin(th_half);
var x1 = cx + cos_th0 - t * sin_th0;
var y1 = cy + sin_th0 + t * cos_th0;
var x3 = cx + cos_th1;
var y3 = cy + sin_th1;
var x2 = x3 + t * sin_th1;
var y2 = y3 - t * cos_th1;
return (bezierCache[key] = [
a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
a00 * x3 + a01 * y3, a10 * x3 + a11 * y3
]);
}

105
node_modules/vega-scenegraph/src/path/curves.js generated vendored Normal file
View File

@@ -0,0 +1,105 @@
import {hasOwnProperty} from 'vega-util';
import {
curveBasis,
curveBasisClosed,
curveBasisOpen,
curveBundle,
curveCardinal,
curveCardinalClosed,
curveCardinalOpen,
curveCatmullRom,
curveCatmullRomClosed,
curveCatmullRomOpen,
curveLinear,
curveLinearClosed,
curveMonotoneX,
curveMonotoneY,
curveNatural,
curveStep,
curveStepAfter,
curveStepBefore
} from 'd3-shape';
var lookup = {
'basis': {
curve: curveBasis
},
'basis-closed': {
curve: curveBasisClosed
},
'basis-open': {
curve: curveBasisOpen
},
'bundle': {
curve: curveBundle,
tension: 'beta',
value: 0.85
},
'cardinal': {
curve: curveCardinal,
tension: 'tension',
value: 0
},
'cardinal-open': {
curve: curveCardinalOpen,
tension: 'tension',
value: 0
},
'cardinal-closed': {
curve: curveCardinalClosed,
tension: 'tension',
value: 0
},
'catmull-rom': {
curve: curveCatmullRom,
tension: 'alpha',
value: 0.5
},
'catmull-rom-closed': {
curve: curveCatmullRomClosed,
tension: 'alpha',
value: 0.5
},
'catmull-rom-open': {
curve: curveCatmullRomOpen,
tension: 'alpha',
value: 0.5
},
'linear': {
curve: curveLinear
},
'linear-closed': {
curve: curveLinearClosed
},
'monotone': {
horizontal: curveMonotoneY,
vertical: curveMonotoneX
},
'natural': {
curve: curveNatural
},
'step': {
curve: curveStep
},
'step-after': {
curve: curveStepAfter
},
'step-before': {
curve: curveStepBefore
}
};
export default function curves(type, orientation, tension) {
var entry = hasOwnProperty(lookup, type) && lookup[type],
curve = null;
if (entry) {
curve = entry.curve || entry[orientation || 'vertical'];
if (entry.tension && tension != null) {
curve = curve[entry.tension](tension);
}
}
return curve;
}

49
node_modules/vega-scenegraph/src/path/parse.js generated vendored Normal file
View File

@@ -0,0 +1,49 @@
// Path parsing and rendering code adapted from fabric.js -- Thanks!
var cmdlen = { m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7 },
regexp = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\d)([-+])/g, /\s|,|###/];
export default function(pathstr) {
var result = [],
path,
curr,
chunks,
parsed, param,
cmd, len, i, j, n, m;
// First, break path into command sequence
path = pathstr
.slice()
.replace(regexp[0], '###$1')
.split(regexp[1])
.slice(1);
// Next, parse each command in turn
for (i=0, n=path.length; i<n; ++i) {
curr = path[i];
chunks = curr
.slice(1)
.trim()
.replace(regexp[2],'$1###$2')
.split(regexp[3]);
cmd = curr.charAt(0);
parsed = [cmd];
for (j=0, m=chunks.length; j<m; ++j) {
if ((param = +chunks[j]) === param) { // not NaN
parsed.push(param);
}
}
len = cmdlen[cmd.toLowerCase()];
if (parsed.length-1 > len) {
for (j=1, m=parsed.length; j<m; j+=len) {
result.push([cmd].concat(parsed.slice(j, j+len)));
}
}
else {
result.push(parsed);
}
}
return result;
}

136
node_modules/vega-scenegraph/src/path/rectangle.js generated vendored Normal file
View File

@@ -0,0 +1,136 @@
import {path} from 'd3-path';
// See http://spencermortensen.com/articles/bezier-circle/
const C = 0.448084975506; // C = 1 - c
function rectangleX(d) {
return d.x;
}
function rectangleY(d) {
return d.y;
}
function rectangleWidth(d) {
return d.width;
}
function rectangleHeight(d) {
return d.height;
}
function number(_) {
return typeof _ === 'function' ? _ : () => +_;
}
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
export default function() {
var x = rectangleX,
y = rectangleY,
width = rectangleWidth,
height = rectangleHeight,
crTL = number(0),
crTR = crTL,
crBL = crTL,
crBR = crTL,
context = null;
function rectangle(_, x0, y0) {
var buffer,
x1 = x0 != null ? x0 : +x.call(this, _),
y1 = y0 != null ? y0 : +y.call(this, _),
w = +width.call(this, _),
h = +height.call(this, _),
s = Math.min(w, h) / 2,
tl = clamp(+crTL.call(this, _), 0, s),
tr = clamp(+crTR.call(this, _), 0, s),
bl = clamp(+crBL.call(this, _), 0, s),
br = clamp(+crBR.call(this, _), 0, s);
if (!context) context = buffer = path();
if (tl <= 0 && tr <= 0 && bl <= 0 && br <= 0) {
context.rect(x1, y1, w, h);
} else {
var x2 = x1 + w,
y2 = y1 + h;
context.moveTo(x1 + tl, y1);
context.lineTo(x2 - tr, y1);
context.bezierCurveTo(x2 - C * tr, y1, x2, y1 + C * tr, x2, y1 + tr);
context.lineTo(x2, y2 - br);
context.bezierCurveTo(x2, y2 - C * br, x2 - C * br, y2, x2 - br, y2);
context.lineTo(x1 + bl, y2);
context.bezierCurveTo(x1 + C * bl, y2, x1, y2 - C * bl, x1, y2 - bl);
context.lineTo(x1, y1 + tl);
context.bezierCurveTo(x1, y1 + C * tl, x1 + C * tl, y1, x1 + tl, y1);
context.closePath();
}
if (buffer) {
context = null;
return buffer + '' || null;
}
}
rectangle.x = function(_) {
if (arguments.length) {
x = number(_);
return rectangle;
} else {
return x;
}
};
rectangle.y = function(_) {
if (arguments.length) {
y = number(_);
return rectangle;
} else {
return y;
}
};
rectangle.width = function(_) {
if (arguments.length) {
width = number(_);
return rectangle;
} else {
return width;
}
};
rectangle.height = function(_) {
if (arguments.length) {
height = number(_);
return rectangle;
} else {
return height;
}
};
rectangle.cornerRadius = function(tl, tr, br, bl) {
if (arguments.length) {
crTL = number(tl);
crTR = tr != null ? number(tr) : crTL;
crBR = br != null ? number(br) : crTL;
crBL = bl != null ? number(bl) : crTR;
return rectangle;
} else {
return crTL;
}
};
rectangle.context = function(_) {
if (arguments.length) {
context = _ == null ? null : _;
return rectangle;
} else {
return context;
}
};
return rectangle;
}

323
node_modules/vega-scenegraph/src/path/render.js generated vendored Normal file
View File

@@ -0,0 +1,323 @@
import {bezier, segments} from './arc';
var temp = ['l', 0, 0, 0, 0, 0, 0, 0];
function scale(current, sX, sY) {
var c = (temp[0] = current[0]);
if (c === 'a' || c === 'A') {
temp[1] = sX * current[1];
temp[2] = sY * current[2];
temp[3] = current[3];
temp[4] = current[4];
temp[5] = current[5];
temp[6] = sX * current[6];
temp[7] = sY * current[7];
} else if (c === 'h' || c === 'H') {
temp[1] = sX * current[1];
} else if (c === 'v' || c === 'V') {
temp[1] = sY * current[1];
} else {
for (var i=1, n=current.length; i<n; ++i) {
temp[i] = (i % 2 == 1 ? sX : sY) * current[i];
}
}
return temp;
}
export default function(context, path, l, t, sX, sY) {
var current, // current instruction
previous = null,
x = 0, // current x
y = 0, // current y
controlX = 0, // current control point x
controlY = 0, // current control point y
tempX,
tempY,
tempControlX,
tempControlY;
if (l == null) l = 0;
if (t == null) t = 0;
if (sX == null) sX = 1;
if (sY == null) sY = sX;
if (context.beginPath) context.beginPath();
for (var i=0, len=path.length; i<len; ++i) {
current = path[i];
if (sX !== 1 || sY !== 1) {
current = scale(current, sX, sY);
}
switch (current[0]) { // first letter
case 'l': // lineto, relative
x += current[1];
y += current[2];
context.lineTo(x + l, y + t);
break;
case 'L': // lineto, absolute
x = current[1];
y = current[2];
context.lineTo(x + l, y + t);
break;
case 'h': // horizontal lineto, relative
x += current[1];
context.lineTo(x + l, y + t);
break;
case 'H': // horizontal lineto, absolute
x = current[1];
context.lineTo(x + l, y + t);
break;
case 'v': // vertical lineto, relative
y += current[1];
context.lineTo(x + l, y + t);
break;
case 'V': // verical lineto, absolute
y = current[1];
context.lineTo(x + l, y + t);
break;
case 'm': // moveTo, relative
x += current[1];
y += current[2];
context.moveTo(x + l, y + t);
break;
case 'M': // moveTo, absolute
x = current[1];
y = current[2];
context.moveTo(x + l, y + t);
break;
case 'c': // bezierCurveTo, relative
tempX = x + current[5];
tempY = y + current[6];
controlX = x + current[3];
controlY = y + current[4];
context.bezierCurveTo(
x + current[1] + l, // x1
y + current[2] + t, // y1
controlX + l, // x2
controlY + t, // y2
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
break;
case 'C': // bezierCurveTo, absolute
x = current[5];
y = current[6];
controlX = current[3];
controlY = current[4];
context.bezierCurveTo(
current[1] + l,
current[2] + t,
controlX + l,
controlY + t,
x + l,
y + t
);
break;
case 's': // shorthand cubic bezierCurveTo, relative
// transform to absolute x,y
tempX = x + current[3];
tempY = y + current[4];
// calculate reflection of previous control points
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
context.bezierCurveTo(
controlX + l,
controlY + t,
x + current[1] + l,
y + current[2] + t,
tempX + l,
tempY + t
);
// set control point to 2nd one of this command
// the first control point is assumed to be the reflection of
// the second control point on the previous command relative
// to the current point.
controlX = x + current[1];
controlY = y + current[2];
x = tempX;
y = tempY;
break;
case 'S': // shorthand cubic bezierCurveTo, absolute
tempX = current[3];
tempY = current[4];
// calculate reflection of previous control points
controlX = 2*x - controlX;
controlY = 2*y - controlY;
context.bezierCurveTo(
controlX + l,
controlY + t,
current[1] + l,
current[2] + t,
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
// set control point to 2nd one of this command
// the first control point is assumed to be the reflection of
// the second control point on the previous command relative
// to the current point.
controlX = current[1];
controlY = current[2];
break;
case 'q': // quadraticCurveTo, relative
// transform to absolute x,y
tempX = x + current[3];
tempY = y + current[4];
controlX = x + current[1];
controlY = y + current[2];
context.quadraticCurveTo(
controlX + l,
controlY + t,
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
break;
case 'Q': // quadraticCurveTo, absolute
tempX = current[3];
tempY = current[4];
context.quadraticCurveTo(
current[1] + l,
current[2] + t,
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
controlX = current[1];
controlY = current[2];
break;
case 't': // shorthand quadraticCurveTo, relative
// transform to absolute x,y
tempX = x + current[1];
tempY = y + current[2];
if (previous[0].match(/[QqTt]/) === null) {
// If there is no previous command or if the previous command was not a Q, q, T or t,
// assume the control point is coincident with the current point
controlX = x;
controlY = y;
}
else if (previous[0] === 't') {
// calculate reflection of previous control points for t
controlX = 2 * x - tempControlX;
controlY = 2 * y - tempControlY;
}
else if (previous[0] === 'q') {
// calculate reflection of previous control points for q
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
tempControlX = controlX;
tempControlY = controlY;
context.quadraticCurveTo(
controlX + l,
controlY + t,
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
controlX = x + current[1];
controlY = y + current[2];
break;
case 'T':
tempX = current[1];
tempY = current[2];
// calculate reflection of previous control points
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
context.quadraticCurveTo(
controlX + l,
controlY + t,
tempX + l,
tempY + t
);
x = tempX;
y = tempY;
break;
case 'a':
drawArc(context, x + l, y + t, [
current[1],
current[2],
current[3],
current[4],
current[5],
current[6] + x + l,
current[7] + y + t
]);
x += current[6];
y += current[7];
break;
case 'A':
drawArc(context, x + l, y + t, [
current[1],
current[2],
current[3],
current[4],
current[5],
current[6] + l,
current[7] + t
]);
x = current[6];
y = current[7];
break;
case 'z':
case 'Z':
context.closePath();
break;
}
previous = current;
}
}
function drawArc(context, x, y, coords) {
var seg = segments(
coords[5], // end x
coords[6], // end y
coords[0], // radius x
coords[1], // radius y
coords[3], // large flag
coords[4], // sweep flag
coords[2], // rotation
x, y
);
for (var i=0; i<seg.length; ++i) {
var bez = bezier(seg[i]);
context.bezierCurveTo(bez[0], bez[1], bez[2], bez[3], bez[4], bez[5]);
}
}

91
node_modules/vega-scenegraph/src/path/shapes.js generated vendored Normal file
View File

@@ -0,0 +1,91 @@
import curves from './curves';
import symbols from './symbols';
import {default as vg_rect} from './rectangle';
import {default as vg_trail} from './trail';
import {
arc as d3_arc,
area as d3_area,
line as d3_line,
symbol as d3_symbol
} from 'd3-shape';
function value(a, b) {
return a != null ? a : b;
}
const x = item => item.x || 0,
y = item => item.y || 0,
w = item => item.width || 0,
h = item => item.height || 0,
xw = item => (item.x || 0) + (item.width || 0),
yh = item => (item.y || 0) + (item.height || 0),
sa = item => item.startAngle || 0,
ea = item => item.endAngle || 0,
pa = item => item.padAngle || 0,
ir = item => item.innerRadius || 0,
or = item => item.outerRadius || 0,
cr = item => item.cornerRadius || 0,
tl = item => value(item.cornerRadiusTopLeft, item.cornerRadius) || 0,
tr = item => value(item.cornerRadiusTopRight, item.cornerRadius) || 0,
br = item => value(item.cornerRadiusBottomRight, item.cornerRadius) || 0,
bl = item => value(item.cornerRadiusBottomLeft, item.cornerRadius) || 0,
sz = item => value(item.size, 64),
ts = item => item.size || 1,
def = item => !(item.defined === false),
type = item => symbols(item.shape || 'circle');
const arcShape = d3_arc().startAngle(sa).endAngle(ea).padAngle(pa)
.innerRadius(ir).outerRadius(or).cornerRadius(cr),
areavShape = d3_area().x(x).y1(y).y0(yh).defined(def),
areahShape = d3_area().y(y).x1(x).x0(xw).defined(def),
lineShape = d3_line().x(x).y(y).defined(def),
rectShape = vg_rect().x(x).y(y).width(w).height(h)
.cornerRadius(tl, tr, br, bl),
symbolShape = d3_symbol().type(type).size(sz),
trailShape = vg_trail().x(x).y(y).defined(def).size(ts);
export function hasCornerRadius(item) {
return item.cornerRadius
|| item.cornerRadiusTopLeft
|| item.cornerRadiusTopRight
|| item.cornerRadiusBottomRight
|| item.cornerRadiusBottomLeft;
}
export function arc(context, item) {
return arcShape.context(context)(item);
}
export function area(context, items) {
var item = items[0],
interp = item.interpolate || 'linear';
return (item.orient === 'horizontal' ? areahShape : areavShape)
.curve(curves(interp, item.orient, item.tension))
.context(context)(items);
}
export function line(context, items) {
var item = items[0],
interp = item.interpolate || 'linear';
return lineShape.curve(curves(interp, item.orient, item.tension))
.context(context)(items);
}
export function rectangle(context, item, x, y) {
return rectShape.context(context)(item, x, y);
}
export function shape(context, item) {
return (item.mark.shape || item.shape)
.context(context)(item);
}
export function symbol(context, item) {
return symbolShape.context(context)(item);
}
export function trail(context, items) {
return trailShape.context(context)(items);
}

156
node_modules/vega-scenegraph/src/path/symbols.js generated vendored Normal file
View File

@@ -0,0 +1,156 @@
import pathParse from './parse';
import pathRender from './render';
import {HalfSqrt3, Tau} from '../util/constants';
import {hasOwnProperty} from 'vega-util';
var Tan30 = 0.5773502691896257;
var builtins = {
'circle': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2;
context.moveTo(r, 0);
context.arc(0, 0, r, 0, Tau);
}
},
'cross': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
s = r / 2.5;
context.moveTo(-r, -s);
context.lineTo(-r, s);
context.lineTo(-s, s);
context.lineTo(-s, r);
context.lineTo(s, r);
context.lineTo(s, s);
context.lineTo(r, s);
context.lineTo(r, -s);
context.lineTo(s, -s);
context.lineTo(s, -r);
context.lineTo(-s, -r);
context.lineTo(-s, -s);
context.closePath();
}
},
'diamond': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2;
context.moveTo(-r, 0);
context.lineTo(0, -r);
context.lineTo(r, 0);
context.lineTo(0, r);
context.closePath();
}
},
'square': {
draw: function(context, size) {
var w = Math.sqrt(size),
x = -w / 2;
context.rect(x, x, w, w);
}
},
'arrow': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
s = r / 7,
t = r / 2.5,
v = r / 8;
context.moveTo(-s, r);
context.lineTo(s, r);
context.lineTo(s, -v);
context.lineTo(t, -v);
context.lineTo(0, -r);
context.lineTo(-t, -v);
context.lineTo(-s, -v);
context.closePath();
}
},
'wedge': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r,
o = (h - r * Tan30),
b = r / 4;
context.moveTo(0, -h - o);
context.lineTo(-b, h - o);
context.lineTo(b, h - o);
context.closePath();
}
},
'triangle': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r,
o = (h - r * Tan30);
context.moveTo(0, -h - o);
context.lineTo(-r, h - o);
context.lineTo(r, h - o);
context.closePath();
}
},
'triangle-up': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r;
context.moveTo(0, -h);
context.lineTo(-r, h);
context.lineTo(r, h);
context.closePath();
}
},
'triangle-down': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r;
context.moveTo(0, h);
context.lineTo(-r, -h);
context.lineTo(r, -h);
context.closePath();
}
},
'triangle-right': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r;
context.moveTo(h, 0);
context.lineTo(-h, -r);
context.lineTo(-h, r);
context.closePath();
}
},
'triangle-left': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2,
h = HalfSqrt3 * r;
context.moveTo(-h, 0);
context.lineTo(h, -r);
context.lineTo(h, r);
context.closePath();
}
},
'stroke': {
draw: function(context, size) {
var r = Math.sqrt(size) / 2;
context.moveTo(-r, 0);
context.lineTo(r, 0);
}
}
};
export default function symbols(_) {
return hasOwnProperty(builtins, _) ? builtins[_] : customSymbol(_);
}
var custom = {};
function customSymbol(path) {
if (!hasOwnProperty(custom, path)) {
var parsed = pathParse(path);
custom[path] = {
draw: function(context, size) {
pathRender(context, parsed, 0, 0, Math.sqrt(size) / 2);
}
};
}
return custom[path];
}

116
node_modules/vega-scenegraph/src/path/trail.js generated vendored Normal file
View File

@@ -0,0 +1,116 @@
import {Tau} from '../util/constants';
import {path} from 'd3-path';
export default function() {
var x,
y,
size,
defined,
context = null,
ready, x1, y1, r1;
function point(x2, y2, w2) {
var r2 = w2 / 2;
if (ready) {
var ux = y1 - y2,
uy = x2 - x1;
if (ux || uy) {
// get normal vector
var ud = Math.sqrt(ux * ux + uy * uy),
rx = (ux /= ud) * r1,
ry = (uy /= ud) * r1,
t = Math.atan2(uy, ux);
// draw segment
context.moveTo(x1 - rx, y1 - ry);
context.lineTo(x2 - ux * r2, y2 - uy * r2);
context.arc(x2, y2, r2, t - Math.PI, t);
context.lineTo(x1 + rx, y1 + ry);
context.arc(x1, y1, r1, t, t + Math.PI);
} else {
context.arc(x2, y2, r2, 0, Tau);
}
context.closePath();
} else {
ready = 1;
}
x1 = x2;
y1 = y2;
r1 = r2;
}
function trail(data) {
var i,
n = data.length,
d,
defined0 = false,
buffer;
if (context == null) context = buffer = path();
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) ready = 0;
}
if (defined0) point(+x(d, i, data), +y(d, i, data), +size(d, i, data));
}
if (buffer) {
context = null;
return buffer + '' || null;
}
}
trail.x = function(_) {
if (arguments.length) {
x = _;
return trail;
} else {
return x;
}
};
trail.y = function(_) {
if (arguments.length) {
y = _;
return trail;
} else {
return y;
}
};
trail.size = function(_) {
if (arguments.length) {
size = _;
return trail;
} else {
return size;
}
};
trail.defined = function(_) {
if (arguments.length) {
defined = _;
return trail;
} else {
return defined;
}
};
trail.context = function(_) {
if (arguments.length) {
if (_ == null) {
context = null;
} else {
context = _;
}
return trail;
} else {
return context;
}
};
return trail;
}

167
node_modules/vega-scenegraph/src/util/aria.js generated vendored Normal file
View File

@@ -0,0 +1,167 @@
import {domainCaption, isDiscrete} from 'vega-scale';
import {array, peek, toSet} from 'vega-util';
const ARIA_HIDDEN = 'aria-hidden';
const ARIA_LABEL = 'aria-label';
const ARIA_ROLE = 'role';
const ARIA_ROLEDESCRIPTION = 'aria-roledescription';
const GRAPHICS_OBJECT = 'graphics-object';
const GRAPHICS_SYMBOL = 'graphics-symbol';
const bundle = (role, roledesc, label) => ({
[ARIA_ROLE]: role,
[ARIA_ROLEDESCRIPTION]: roledesc,
[ARIA_LABEL]: label || undefined
});
// these roles are covered by related roles
// we can ignore them, no need to generate attributes
const AriaIgnore = toSet([
'axis-domain',
'axis-grid',
'axis-label',
'axis-tick',
'axis-title',
'legend-band',
'legend-entry',
'legend-gradient',
'legend-label',
'legend-title',
'legend-symbol',
'title'
]);
// aria attribute generators for guide roles
const AriaGuides = {
'axis': {desc: 'axis', caption: axisCaption},
'legend': {desc: 'legend', caption: legendCaption},
'title-text': {
desc: 'title',
caption: item => `Title text '${titleCaption(item)}'`
},
'title-subtitle': {
desc: 'subtitle',
caption: item => `Subtitle text '${titleCaption(item)}'`
}
};
// aria properties generated for mark item encoding channels
export const AriaEncode = {
ariaRole: ARIA_ROLE,
ariaRoleDescription: ARIA_ROLEDESCRIPTION,
description: ARIA_LABEL
};
export function ariaItemAttributes(emit, item) {
const hide = item.aria === false;
emit(ARIA_HIDDEN, hide || undefined);
if (hide || item.description == null) {
for (const prop in AriaEncode) {
emit(AriaEncode[prop], undefined);
}
} else {
const type = item.mark.marktype;
emit(
ARIA_LABEL,
item.description
);
emit(
ARIA_ROLE,
item.ariaRole || (type === 'group' ? GRAPHICS_OBJECT : GRAPHICS_SYMBOL)
);
emit(
ARIA_ROLEDESCRIPTION,
item.ariaRoleDescription || `${type} mark`
);
}
}
export function ariaMarkAttributes(mark) {
return mark.aria === false ? { [ARIA_HIDDEN]: true }
: AriaIgnore[mark.role] ? null
: AriaGuides[mark.role] ? ariaGuide(mark, AriaGuides[mark.role])
: ariaMark(mark);
}
function ariaMark(mark) {
const type = mark.marktype;
const recurse = (
type === 'group' ||
type === 'text' ||
mark.items.some(_ => _.description != null && _.aria !== false)
);
return bundle(
recurse ? GRAPHICS_OBJECT : GRAPHICS_SYMBOL,
`${type} mark container`,
mark.description
);
}
function ariaGuide(mark, opt) {
try {
const item = mark.items[0],
caption = opt.caption || (() => '');
return bundle(
opt.role || GRAPHICS_SYMBOL,
opt.desc,
item.description || caption(item)
);
} catch (err) {
return null;
}
}
function titleCaption(item) {
return array(item.text).join(' ');
}
function axisCaption(item) {
const datum = item.datum,
orient = item.orient,
title = datum.title ? extractTitle(item) : null,
ctx = item.context,
scale = ctx.scales[datum.scale].value,
locale = ctx.dataflow.locale(),
type = scale.type,
xy = (orient === 'left' || orient === 'right') ? 'Y' : 'X';
return `${xy}-axis`
+ (title ? ` titled '${title}'` : '')
+ ` for a ${isDiscrete(type) ? 'discrete' : type} scale`
+ ` with ${domainCaption(locale, scale, item)}`;
}
function legendCaption(item) {
const datum = item.datum,
title = datum.title ? extractTitle(item) : null,
type = `${datum.type || ''} legend`.trim(),
scales = datum.scales,
props = Object.keys(scales),
ctx = item.context,
scale = ctx.scales[scales[props[0]]].value,
locale = ctx.dataflow.locale();
return capitalize(type)
+ (title ? ` titled '${title}'` : '')
+ ` for ${channelCaption(props)}`
+ ` with ${domainCaption(locale, scale, item)}`;
}
function extractTitle(item) {
try {
return array(peek(item.items).items[0].text).join(' ');
} catch (err) {
return null;
}
}
function channelCaption(props) {
props = props.map(p => p + (p === 'fill' || p === 'stroke' ? ' color' : ''));
return props.length < 2 ? props[0]
: props.slice(0, -1).join(', ') + ' and ' + peek(props);
}
function capitalize(s) {
return s.length ? s[0].toUpperCase() + s.slice(1) : s;
}

View File

@@ -0,0 +1,3 @@
export default function(context, item) {
context.globalCompositeOperation = item.blend || 'source-over';
}

24
node_modules/vega-scenegraph/src/util/canvas/clip.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import {hasCornerRadius, rectangle} from '../../path/shapes';
import {isFunction} from 'vega-util';
export default function(context, scene) {
var clip = scene.clip;
context.save();
if (isFunction(clip)) {
context.beginPath();
clip(context);
context.clip();
} else {
clipGroup(context, scene.group);
}
}
export function clipGroup(context, group) {
context.beginPath();
hasCornerRadius(group)
? rectangle(context, group, 0, 0)
: context.rect(0, 0, group.width || 0, group.height || 0);
context.clip();
}

View File

@@ -0,0 +1,8 @@
import {isGradient} from '../../Gradient';
import gradient from './gradient';
export default function(context, item, value) {
return isGradient(value)
? gradient(context, value, item.bounds)
: value;
}

View File

@@ -0,0 +1,5 @@
import {canvas} from 'vega-canvas';
export var context = (context = canvas(1,1))
? context.getContext('2d')
: null;

39
node_modules/vega-scenegraph/src/util/canvas/draw.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
import blend from './blend';
import fill from './fill';
import stroke from './stroke';
import {visit} from '../visit';
export function drawAll(path) {
return function(context, scene, bounds) {
visit(scene, function(item) {
if (!bounds || bounds.intersects(item.bounds)) {
drawPath(path, context, item, item);
}
});
};
}
export function drawOne(path) {
return function(context, scene, bounds) {
if (scene.items.length && (!bounds || bounds.intersects(scene.bounds))) {
drawPath(path, context, scene.items[0], scene.items);
}
};
}
function drawPath(path, context, item, items) {
var opacity = item.opacity == null ? 1 : item.opacity;
if (opacity === 0) return;
if (path(context, items)) return;
blend(context, item);
if (item.fill && fill(context, item, opacity)) {
context.fill();
}
if (item.stroke && stroke(context, item, opacity)) {
context.stroke();
}
}

12
node_modules/vega-scenegraph/src/util/canvas/fill.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import color from './color';
export default function(context, item, opacity) {
opacity *= (item.fillOpacity==null ? 1 : item.fillOpacity);
if (opacity > 0) {
context.globalAlpha = opacity;
context.fillStyle = color(context, item, item.fill);
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,59 @@
import value from '../value';
import {canvas} from 'vega-canvas';
function addStops(gradient, stops) {
const n = stops.length;
for (let i=0; i<n; ++i) {
gradient.addColorStop(stops[i].offset, stops[i].color);
}
return gradient;
}
export default function(context, spec, bounds) {
const w = bounds.width(),
h = bounds.height();
let gradient;
if (spec.gradient === 'radial') {
gradient = context.createRadialGradient(
bounds.x1 + value(spec.x1, 0.5) * w,
bounds.y1 + value(spec.y1, 0.5) * h,
Math.max(w, h) * value(spec.r1, 0),
bounds.x1 + value(spec.x2, 0.5) * w,
bounds.y1 + value(spec.y2, 0.5) * h,
Math.max(w, h) * value(spec.r2, 0.5)
);
} else { // linear gradient
const x1 = value(spec.x1, 0),
y1 = value(spec.y1, 0),
x2 = value(spec.x2, 1),
y2 = value(spec.y2, 0);
if (x1 === x2 || y1 === y2 || w === h) {
// axis aligned: use normal gradient
gradient = context.createLinearGradient(
bounds.x1 + x1 * w,
bounds.y1 + y1 * h,
bounds.x1 + x2 * w,
bounds.y1 + y2 * h
);
} else {
// not axis aligned: render gradient into a pattern (#2365)
// this allows us to use normalized bounding box coordinates
const image = canvas(Math.ceil(w), Math.ceil(h)),
ictx = image.getContext('2d');
ictx.scale(w, h);
ictx.fillStyle = addStops(
ictx.createLinearGradient(x1, y1, x2, y2),
spec.stops
);
ictx.fillRect(0, 0, w, h);
return context.createPattern(image, 'no-repeat');
}
}
return addStops(gradient, spec.stops);
}

View File

@@ -0,0 +1,4 @@
import {Canvas} from './canvas';
export default typeof Image !== 'undefined' ? Image
: (Canvas && Canvas.Image || null);

42
node_modules/vega-scenegraph/src/util/canvas/pick.js generated vendored Normal file
View File

@@ -0,0 +1,42 @@
import {pickVisit} from '../visit';
import {truthy} from 'vega-util';
export function pick(test) {
test = test || truthy;
return function(context, scene, x, y, gx, gy) {
x *= context.pixelRatio;
y *= context.pixelRatio;
return pickVisit(scene, function(item) {
var b = item.bounds;
// first hit test against bounding box
if ((b && !b.contains(gx, gy)) || !b) return;
// if in bounding box, perform more careful test
if (test(context, item, x, y, gx, gy)) return item;
});
};
}
export function hitPath(path, filled) {
return function(context, o, x, y) {
var item = Array.isArray(o) ? o[0] : o,
fill = (filled == null) ? item.fill : filled,
stroke = item.stroke && context.isPointInStroke, lw, lc;
if (stroke) {
lw = item.strokeWidth;
lc = item.strokeCap;
context.lineWidth = lw != null ? lw : 1;
context.lineCap = lc != null ? lc : 'butt';
}
return path(context, o) ? false :
(fill && context.isPointInPath(x, y)) ||
(stroke && context.isPointInStroke(x, y));
};
}
export function pickPath(path) {
return pick(hitPath(path));
}

34
node_modules/vega-scenegraph/src/util/canvas/resize.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
function devicePixelRatio() {
return typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;
}
var pixelRatio = devicePixelRatio();
export default function(canvas, width, height, origin, scaleFactor, opt) {
const inDOM = typeof HTMLElement !== 'undefined'
&& canvas instanceof HTMLElement
&& canvas.parentNode != null,
context = canvas.getContext('2d'),
ratio = inDOM ? pixelRatio : scaleFactor;
canvas.width = width * ratio;
canvas.height = height * ratio;
for (const key in opt) {
context[key] = opt[key];
}
if (inDOM && ratio !== 1) {
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
}
context.pixelRatio = ratio;
context.setTransform(
ratio, 0, 0, ratio,
ratio * origin[0],
ratio * origin[1]
);
return canvas;
}

28
node_modules/vega-scenegraph/src/util/canvas/stroke.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
import color from './color';
var Empty = [];
export default function(context, item, opacity) {
var lw = (lw = item.strokeWidth) != null ? lw : 1;
if (lw <= 0) return false;
opacity *= (item.strokeOpacity==null ? 1 : item.strokeOpacity);
if (opacity > 0) {
context.globalAlpha = opacity;
context.strokeStyle = color(context, item, item.stroke);
context.lineWidth = lw;
context.lineCap = item.strokeCap || 'butt';
context.lineJoin = item.strokeJoin || 'miter';
context.miterLimit = item.strokeMiterLimit || 10;
if (context.setLineDash) {
context.setLineDash(item.strokeDash || Empty);
context.lineDashOffset = item.strokeDashOffset || 0;
}
return true;
} else {
return false;
}
}

5
node_modules/vega-scenegraph/src/util/constants.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export const DegToRad = Math.PI / 180;
export const Epsilon = 1e-14;
export const HalfPi = Math.PI / 2;
export const Tau = Math.PI * 2;
export const HalfSqrt3 = Math.sqrt(3) / 2;

45
node_modules/vega-scenegraph/src/util/dom.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
// create a new DOM element
export function domCreate(doc, tag, ns) {
if (!doc && typeof document !== 'undefined' && document.createElement) {
doc = document;
}
return doc
? (ns ? doc.createElementNS(ns, tag) : doc.createElement(tag))
: null;
}
// find first child element with matching tag
export function domFind(el, tag) {
tag = tag.toLowerCase();
var nodes = el.childNodes, i = 0, n = nodes.length;
for (; i<n; ++i) if (nodes[i].tagName.toLowerCase() === tag) {
return nodes[i];
}
}
// retrieve child element at given index
// create & insert if doesn't exist or if tags do not match
export function domChild(el, index, tag, ns) {
var a = el.childNodes[index], b;
if (!a || a.tagName.toLowerCase() !== tag.toLowerCase()) {
b = a || null;
a = domCreate(el.ownerDocument, tag, ns);
el.insertBefore(a, b);
}
return a;
}
// remove all child elements at or above the given index
export function domClear(el, index) {
var nodes = el.childNodes,
curr = nodes.length;
while (curr > index) el.removeChild(nodes[--curr]);
return el;
}
// generate css class name for mark
export function cssClass(mark) {
return 'mark-' + mark.marktype
+ (mark.role ? ' role-' + mark.role : '')
+ (mark.name ? ' ' + mark.name : '');
}

40
node_modules/vega-scenegraph/src/util/equal.js generated vendored Normal file
View File

@@ -0,0 +1,40 @@
import pathParse from '../path/parse';
import {isNumber, isObject} from 'vega-util';
var TOLERANCE = 1e-9;
export function sceneEqual(a, b, key) {
return (a === b) ? true
: (key === 'path') ? pathEqual(a, b)
: (a instanceof Date && b instanceof Date) ? +a === +b
: (isNumber(a) && isNumber(b)) ? Math.abs(a - b) <= TOLERANCE
: (!a || !b || !isObject(a) && !isObject(b)) ? a == b
: (a == null || b == null) ? false
: objectEqual(a, b);
}
export function pathEqual(a, b) {
return sceneEqual(pathParse(a), pathParse(b));
}
function objectEqual(a, b) {
var ka = Object.keys(a),
kb = Object.keys(b),
key, i;
if (ka.length !== kb.length) return false;
ka.sort();
kb.sort();
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i]) return false;
}
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!sceneEqual(a[key], b[key], key)) return false;
}
return typeof a === typeof b;
}

45
node_modules/vega-scenegraph/src/util/events.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
export const KeyDownEvent = 'keydown';
export const KeyPressEvent = 'keypress';
export const KeyUpEvent = 'keyup';
export const DragEnterEvent = 'dragenter';
export const DragLeaveEvent = 'dragleave';
export const DragOverEvent = 'dragover';
export const MouseDownEvent = 'mousedown';
export const MouseUpEvent = 'mouseup';
export const MouseMoveEvent = 'mousemove';
export const MouseOutEvent = 'mouseout';
export const MouseOverEvent = 'mouseover';
export const ClickEvent = 'click';
export const DoubleClickEvent = 'dblclick';
export const WheelEvent = 'wheel';
export const MouseWheelEvent = 'mousewheel';
export const TouchStartEvent = 'touchstart';
export const TouchMoveEvent = 'touchmove';
export const TouchEndEvent = 'touchend';
export const Events = [
KeyDownEvent,
KeyPressEvent,
KeyUpEvent,
DragEnterEvent,
DragLeaveEvent,
DragOverEvent,
MouseDownEvent,
MouseUpEvent,
MouseMoveEvent,
MouseOutEvent,
MouseOverEvent,
ClickEvent,
DoubleClickEvent,
WheelEvent,
MouseWheelEvent,
TouchStartEvent,
TouchMoveEvent,
TouchEndEvent
];
export const TooltipShowEvent = MouseMoveEvent;
export const TooltipHideEvent = MouseOutEvent;
export const HrefEvent = ClickEvent;

80
node_modules/vega-scenegraph/src/util/intersect.js generated vendored Normal file
View File

@@ -0,0 +1,80 @@
import {context} from './canvas/context';
import Bounds from '../Bounds';
const b = new Bounds();
export function intersectPath(draw) {
return function(item, brush) {
// rely on (inaccurate) bounds intersection if no context
if (!context) return true;
// add path to offscreen graphics context
draw(context, item);
// get bounds intersection region
b.clear().union(item.bounds).intersect(brush).round();
const {x1, y1, x2, y2} = b;
// iterate over intersection region
// perform fine grained inclusion test
for (let y = y1; y <= y2; ++y) {
for (let x = x1; x <= x2; ++x) {
if (context.isPointInPath(x, y)) {
return true;
}
}
}
// false if no hits in intersection region
return false;
};
}
export function intersectPoint(item, box) {
return box.contains(item.x || 0, item.y || 0);
}
export function intersectRect(item, box) {
const x = item.x || 0,
y = item.y || 0,
w = item.width || 0,
h = item.height || 0;
return box.intersects(b.set(x, y, x + w, y + h));
}
export function intersectRule(item, box) {
const x = item.x || 0,
y = item.y || 0,
x2 = item.x2 != null ? item.x2 : x,
y2 = item.y2 != null ? item.y2 : y;
return intersectBoxLine(box, x, y, x2, y2);
}
export function intersectBoxLine(box, x, y, u, v) {
const {x1, y1, x2, y2} = box,
dx = u - x,
dy = v - y;
let t0 = 0, t1 = 1, p, q, r, e;
for (e=0; e<4; ++e) {
if (e === 0) { p = -dx; q = -(x1 - x); }
if (e === 1) { p = dx; q = (x2 - x); }
if (e === 2) { p = -dy; q = -(y1 - y); }
if (e === 3) { p = dy; q = (y2 - y); }
if (Math.abs(p) < 1e-10 && q < 0) return false;
r = q / p;
if (p < 0) {
if (r > t1) return false;
else if (r > t0) t0 = r;
} else if (p > 0) {
if (r < t0) return false;
else if (r < t1) t1 = r;
}
}
return true;
}

47
node_modules/vega-scenegraph/src/util/pickPath.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
export function pickArea(a, p) {
var v = a[0].orient === 'horizontal' ? p[1] : p[0],
z = a[0].orient === 'horizontal' ? 'y' : 'x',
i = a.length,
min = +Infinity, hit, d;
while (--i >= 0) {
if (a[i].defined === false) continue;
d = Math.abs(a[i][z] - v);
if (d < min) {
min = d;
hit = a[i];
}
}
return hit;
}
export function pickLine(a, p) {
var t = Math.pow(a[0].strokeWidth || 1, 2),
i = a.length, dx, dy, dd;
while (--i >= 0) {
if (a[i].defined === false) continue;
dx = a[i].x - p[0];
dy = a[i].y - p[1];
dd = dx * dx + dy * dy;
if (dd < t) return a[i];
}
return null;
}
export function pickTrail(a, p) {
var i = a.length, dx, dy, dd;
while (--i >= 0) {
if (a[i].defined === false) continue;
dx = a[i].x - p[0];
dy = a[i].y - p[1];
dd = dx * dx + dy * dy;
dx = a[i].size || 1;
if (dd < dx*dx) return a[i];
}
return null;
}

7
node_modules/vega-scenegraph/src/util/point.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
export default function(event, el) {
var rect = el.getBoundingClientRect();
return [
event.clientX - rect.left - (el.clientLeft || 0),
event.clientY - rect.top - (el.clientTop || 0)
];
}

20
node_modules/vega-scenegraph/src/util/resolveItem.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import marks from '../marks/index';
import point from './point';
export default function(item, event, el, origin) {
var mark = item && item.mark,
mdef, p;
if (mark && (mdef = marks[mark.marktype]).tip) {
p = point(event, el);
p[0] -= origin[0];
p[1] -= origin[1];
while (item = item.mark.group) {
p[0] -= item.x || 0;
p[1] -= item.y || 0;
}
item = mdef.tip(mark.items, p);
}
return item;
}

50
node_modules/vega-scenegraph/src/util/serialize.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import boundMark from '../bound/boundMark';
var keys = [
'marktype', 'name', 'role', 'interactive', 'clip', 'items', 'zindex',
'x', 'y', 'width', 'height', 'align', 'baseline', // layout
'fill', 'fillOpacity', 'opacity', 'blend', // fill
'stroke', 'strokeOpacity', 'strokeWidth', 'strokeCap', // stroke
'strokeDash', 'strokeDashOffset', // stroke dash
'strokeForeground', 'strokeOffset', // group
'startAngle', 'endAngle', 'innerRadius', 'outerRadius', // arc
'cornerRadius', 'padAngle', // arc, rect
'cornerRadiusTopLeft', 'cornerRadiusTopRight', // rect, group
'cornerRadiusBottomLeft', 'cornerRadiusBottomRight',
'interpolate', 'tension', 'orient', 'defined', // area, line
'url', 'aspect', 'smooth', // image
'path', 'scaleX', 'scaleY', // path
'x2', 'y2', // rule
'size', 'shape', // symbol
'text', 'angle', 'theta', 'radius', 'dir', 'dx', 'dy', // text
'ellipsis', 'limit', 'lineBreak', 'lineHeight',
'font', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant', // font
'description', 'aria', 'ariaRole', 'ariaRoleDescription' // aria
];
export function sceneToJSON(scene, indent) {
return JSON.stringify(scene, keys, indent);
}
export function sceneFromJSON(json) {
var scene = (typeof json === 'string' ? JSON.parse(json) : json);
return initialize(scene);
}
function initialize(scene) {
var type = scene.marktype,
items = scene.items,
parent, i, n;
if (items) {
for (i=0, n=items.length; i<n; ++i) {
parent = type ? 'mark' : 'group';
items[i][parent] = scene;
if (items[i].zindex) items[i][parent].zdirty = true;
if ('group' === (type || parent)) initialize(items[i]);
}
}
if (type) boundMark(scene);
return scene;
}

26
node_modules/vega-scenegraph/src/util/svg/clip.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import {hasCornerRadius, rectangle} from '../../path/shapes';
import {isFunction} from 'vega-util';
var clip_id = 1;
export function resetSVGClipId() {
clip_id = 1;
}
export default function(renderer, item, size) {
var clip = item.clip,
defs = renderer._defs,
id = item.clip_id || (item.clip_id = 'clip' + clip_id++),
c = defs.clipping[id] || (defs.clipping[id] = {id: id});
if (isFunction(clip)) {
c.path = clip(null);
} else if (hasCornerRadius(size)) {
c.path = rectangle(null, size, 0, 0);
} else {
c.width = size.width || 0;
c.height = size.height || 0;
}
return 'url(#' + id + ')';
}

View File

@@ -0,0 +1,5 @@
export default {
'version': '1.1',
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink'
};

20
node_modules/vega-scenegraph/src/util/svg/styles.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
export const styles = {
fill: 'fill',
fillOpacity: 'fill-opacity',
stroke: 'stroke',
strokeOpacity: 'stroke-opacity',
strokeWidth: 'stroke-width',
strokeCap: 'stroke-linecap',
strokeJoin: 'stroke-linejoin',
strokeDash: 'stroke-dasharray',
strokeDashOffset: 'stroke-dashoffset',
strokeMiterLimit: 'stroke-miterlimit',
opacity: 'opacity',
blend: 'mix-blend-mode'
};
// ensure miter limit default is consistent with canvas (#2498)
export const rootAttributes = {
'fill': 'none',
'stroke-miterlimit': 10
};

21
node_modules/vega-scenegraph/src/util/svg/transform.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
export function translate(x, y) {
return 'translate(' + x + ',' + y + ')';
}
export function rotate(a) {
return 'rotate(' + a + ')';
}
export function scale(scaleX, scaleY){
return 'scale('+ scaleX + ',' + scaleY+')';
}
export function translateItem(item) {
return translate(item.x || 0, item.y || 0);
}
export function transformItem(item) {
return translate(item.x || 0, item.y || 0)
+ (item.angle ? ' ' + rotate(item.angle) : '')
+ (item.scaleX || item.scaleY ? ' ' + scale(item.scaleX || 1, item.scaleY || 1) : '');
}

31
node_modules/vega-scenegraph/src/util/tags.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
const attrText = val => (val + '')
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;');
/**
* Generate string for an opening xml tag.
* @param tag the name of the xml tag
* @param attr hash of attribute name-value pairs to include
* @param raw additional raw string to include in tag markup
*/
export function openTag(tag, attr, raw) {
var s = '<' + tag, key, val;
if (attr) {
for (key in attr) {
val = attr[key];
if (val != null) {
s += ' ' + key + '="' + attrText(val) + '"';
}
}
}
if (raw) s += ' ' + raw;
return s + '>';
}
/**
* Generate string for closing xml tag.
* @param tag the name of the xml tag
*/
export function closeTag(tag) {
return '</' + tag + '>';
}

149
node_modules/vega-scenegraph/src/util/text.js generated vendored Normal file
View File

@@ -0,0 +1,149 @@
import {context} from './canvas/context';
import {isArray, lruCache} from 'vega-util';
// memoize text width measurement
const widthCache = lruCache();
export var textMetrics = {
height: fontSize,
measureWidth: measureWidth,
estimateWidth: estimateWidth,
width: estimateWidth,
canvas: useCanvas
};
useCanvas(true);
function useCanvas(use) {
textMetrics.width = (use && context) ? measureWidth : estimateWidth;
}
// make dumb, simple estimate if no canvas is available
function estimateWidth(item, text) {
return _estimateWidth(textValue(item, text), fontSize(item));
}
function _estimateWidth(text, currentFontHeight) {
return ~~(0.8 * text.length * currentFontHeight);
}
// measure text width if canvas is available
function measureWidth(item, text) {
return fontSize(item) <= 0 || !(text = textValue(item, text)) ? 0
: _measureWidth(text, font(item));
}
function _measureWidth(text, currentFont) {
const key = `(${currentFont}) ${text}`;
let width = widthCache.get(key);
if (width === undefined) {
context.font = currentFont;
width = context.measureText(text).width;
widthCache.set(key, width);
}
return width;
}
export function fontSize(item) {
return item.fontSize != null ? (+item.fontSize || 0) : 11;
}
export function lineHeight(item) {
return item.lineHeight != null ? item.lineHeight : (fontSize(item) + 2);
}
function lineArray(_) {
return isArray(_) ? _.length > 1 ? _ : _[0] : _;
}
export function textLines(item) {
return lineArray(
item.lineBreak && item.text && !isArray(item.text)
? item.text.split(item.lineBreak)
: item.text
);
}
export function multiLineOffset(item) {
const tl = textLines(item);
return (isArray(tl) ? (tl.length - 1) : 0) * lineHeight(item);
}
export function textValue(item, line) {
const text = line == null ? '' : (line + '').trim();
return item.limit > 0 && text.length ? truncate(item, text) : text;
}
function widthGetter(item) {
if (textMetrics.width === measureWidth) {
// we are using canvas
const currentFont = font(item);
return text => _measureWidth(text, currentFont);
} else {
// we are relying on estimates
const currentFontHeight = fontSize(item);
return text => _estimateWidth(text, currentFontHeight);
}
}
function truncate(item, text) {
var limit = +item.limit,
width = widthGetter(item);
if (width(text) < limit) return text;
var ellipsis = item.ellipsis || '\u2026',
rtl = item.dir === 'rtl',
lo = 0,
hi = text.length, mid;
limit -= width(ellipsis);
if (rtl) {
while (lo < hi) {
mid = (lo + hi >>> 1);
if (width(text.slice(mid)) > limit) lo = mid + 1;
else hi = mid;
}
return ellipsis + text.slice(lo);
} else {
while (lo < hi) {
mid = 1 + (lo + hi >>> 1);
if (width(text.slice(0, mid)) < limit) lo = mid;
else hi = mid - 1;
}
return text.slice(0, lo) + ellipsis;
}
}
export function fontFamily(item, quote) {
var font = item.font;
return (quote && font
? String(font).replace(/"/g, '\'')
: font) || 'sans-serif';
}
export function font(item, quote) {
return '' +
(item.fontStyle ? item.fontStyle + ' ' : '') +
(item.fontVariant ? item.fontVariant + ' ' : '') +
(item.fontWeight ? item.fontWeight + ' ' : '') +
fontSize(item) + 'px ' +
fontFamily(item, quote);
}
export function offset(item) {
// perform our own font baseline calculation
// why? not all browsers support SVG 1.1 'alignment-baseline' :(
// this also ensures consistent layout across renderers
var baseline = item.baseline,
h = fontSize(item);
return Math.round(
baseline === 'top' ? 0.79 * h :
baseline === 'middle' ? 0.30 * h :
baseline === 'bottom' ? -0.21 * h :
baseline === 'line-top' ? 0.29 * h + 0.5 * lineHeight(item) :
baseline === 'line-bottom' ? 0.29 * h - 0.5 * lineHeight(item) : 0
);
}

3
node_modules/vega-scenegraph/src/util/value.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export default function(value, dflt) {
return value == null ? dflt : value;
}

59
node_modules/vega-scenegraph/src/util/visit.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
function compare(a, b) {
return a.zindex - b.zindex || a.index - b.index;
}
export function zorder(scene) {
if (!scene.zdirty) return scene.zitems;
var items = scene.items,
output = [], item, i, n;
for (i=0, n=items.length; i<n; ++i) {
item = items[i];
item.index = i;
if (item.zindex) output.push(item);
}
scene.zdirty = false;
return scene.zitems = output.sort(compare);
}
export function visit(scene, visitor) {
var items = scene.items, i, n;
if (!items || !items.length) return;
var zitems = zorder(scene);
if (zitems && zitems.length) {
for (i=0, n=items.length; i<n; ++i) {
if (!items[i].zindex) visitor(items[i]);
}
items = zitems;
}
for (i=0, n=items.length; i<n; ++i) {
visitor(items[i]);
}
}
export function pickVisit(scene, visitor) {
var items = scene.items, hit, i;
if (!items || !items.length) return null;
var zitems = zorder(scene);
if (zitems && zitems.length) items = zitems;
for (i=items.length; --i >= 0;) {
if (hit = visitor(items[i])) return hit;
}
if (items === zitems) {
for (items=scene.items, i=items.length; --i >= 0;) {
if (!items[i].zindex) {
if (hit = visitor(items[i])) return hit;
}
}
}
return null;
}