You've already forked wakapi-readme-stats
Bar graph added.
This commit is contained in:
27
node_modules/vega-selections/LICENSE
generated
vendored
Normal file
27
node_modules/vega-selections/LICENSE
generated
vendored
Normal 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.
|
||||
3
node_modules/vega-selections/README.md
generated
vendored
Normal file
3
node_modules/vega-selections/README.md
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# vega-selections
|
||||
|
||||
[Vega expression language](https://vega.github.io/vega/docs/expressions/) functions for implementing Vega-Lite selections.
|
||||
249
node_modules/vega-selections/build/vega-selections.js
generated
vendored
Normal file
249
node_modules/vega-selections/build/vega-selections.js
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vega-util'), require('vega-expression')) :
|
||||
typeof define === 'function' && define.amd ? define(['exports', 'vega-util', 'vega-expression'], factory) :
|
||||
(global = global || self, factory(global.vega = {}, global.vega, global.vega));
|
||||
}(this, (function (exports, vegaUtil, vegaExpression) { 'use strict';
|
||||
|
||||
const Intersect = 'intersect';
|
||||
const Union = 'union';
|
||||
const VlMulti = 'vlMulti';
|
||||
const Or = 'or';
|
||||
const And = 'and';
|
||||
|
||||
var TYPE_ENUM = 'E',
|
||||
TYPE_RANGE_INC = 'R',
|
||||
TYPE_RANGE_EXC = 'R-E',
|
||||
TYPE_RANGE_LE = 'R-LE',
|
||||
TYPE_RANGE_RE = 'R-RE',
|
||||
UNIT_INDEX = 'index:unit';
|
||||
|
||||
// TODO: revisit date coercion?
|
||||
function testPoint(datum, entry) {
|
||||
var fields = entry.fields,
|
||||
values = entry.values,
|
||||
n = fields.length,
|
||||
i = 0, dval, f;
|
||||
|
||||
for (; i<n; ++i) {
|
||||
f = fields[i];
|
||||
f.getter = vegaUtil.field.getter || vegaUtil.field(f.field);
|
||||
dval = f.getter(datum);
|
||||
|
||||
if (vegaUtil.isDate(dval)) dval = vegaUtil.toNumber(dval);
|
||||
if (vegaUtil.isDate(values[i])) values[i] = vegaUtil.toNumber(values[i]);
|
||||
if (vegaUtil.isDate(values[i][0])) values[i] = values[i].map(vegaUtil.toNumber);
|
||||
|
||||
if (f.type === TYPE_ENUM) {
|
||||
// Enumerated fields can either specify individual values (single/multi selections)
|
||||
// or an array of values (interval selections).
|
||||
if(vegaUtil.isArray(values[i]) ? values[i].indexOf(dval) < 0 : dval !== values[i]) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (f.type === TYPE_RANGE_INC) {
|
||||
if (!vegaUtil.inrange(dval, values[i])) return false;
|
||||
} else if (f.type === TYPE_RANGE_RE) {
|
||||
// Discrete selection of bins test within the range [bin_start, bin_end).
|
||||
if (!vegaUtil.inrange(dval, values[i], true, false)) return false;
|
||||
} else if (f.type === TYPE_RANGE_EXC) { // 'R-E'/'R-LE' included for completeness.
|
||||
if (!vegaUtil.inrange(dval, values[i], false, false)) return false;
|
||||
} else if (f.type === TYPE_RANGE_LE) {
|
||||
if (!vegaUtil.inrange(dval, values[i], false, true)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a tuple is contained within an interactive selection.
|
||||
* @param {string} name - The name of the data set representing the selection.
|
||||
* Tuples in the dataset are of the form
|
||||
* {unit: string, fields: array<fielddef>, values: array<*>}.
|
||||
* Fielddef is of the form
|
||||
* {field: string, channel: string, type: 'E' | 'R'} where
|
||||
* 'type' identifies whether tuples in the dataset enumerate
|
||||
* values for the field, or specify a continuous range.
|
||||
* @param {object} datum - The tuple to test for inclusion.
|
||||
* @param {string} op - The set operation for combining selections.
|
||||
* One of 'intersect' or 'union' (default).
|
||||
* @return {boolean} - True if the datum is in the selection, false otherwise.
|
||||
*/
|
||||
function selectionTest(name, datum, op) {
|
||||
var data = this.context.data[name],
|
||||
entries = data ? data.values.value : [],
|
||||
unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined,
|
||||
intersect = op === Intersect,
|
||||
n = entries.length,
|
||||
i = 0,
|
||||
entry, miss, count, unit, b;
|
||||
|
||||
for (; i<n; ++i) {
|
||||
entry = entries[i];
|
||||
|
||||
if (unitIdx && intersect) {
|
||||
// multi selections union within the same unit and intersect across units.
|
||||
miss = miss || {};
|
||||
count = miss[unit=entry.unit] || 0;
|
||||
|
||||
// if we've already matched this unit, skip.
|
||||
if (count === -1) continue;
|
||||
|
||||
b = testPoint(datum, entry);
|
||||
miss[unit] = b ? -1 : ++count;
|
||||
|
||||
// if we match and there are no other units return true
|
||||
// if we've missed against all tuples in this unit return false
|
||||
if (b && unitIdx.size === 1) return true;
|
||||
if (!b && count === unitIdx.get(unit).count) return false;
|
||||
} else {
|
||||
b = testPoint(datum, entry);
|
||||
|
||||
// if we find a miss and we do require intersection return false
|
||||
// if we find a match and we don't require intersection return true
|
||||
if (intersect ^ b) return b;
|
||||
}
|
||||
}
|
||||
|
||||
// if intersecting and we made it here, then we saw no misses
|
||||
// if not intersecting, then we saw no matches
|
||||
// if no active selections, return false
|
||||
return n && intersect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves selection for use as a scale domain or reads via the API.
|
||||
* @param {string} name - The name of the dataset representing the selection
|
||||
* @param {string} [op='union'] - The set operation for combining selections.
|
||||
* One of 'intersect' or 'union' (default).
|
||||
* @returns {object} An object of selected fields and values.
|
||||
*/
|
||||
function selectionResolve(name, op, isMulti) {
|
||||
var data = this.context.data[name],
|
||||
entries = data ? data.values.value : [],
|
||||
resolved = {}, multiRes = {}, types = {},
|
||||
entry, fields, values, unit, field, res, resUnit, type, union,
|
||||
n = entries.length, i = 0, j, m;
|
||||
|
||||
// First union all entries within the same unit.
|
||||
for (; i < n; ++i) {
|
||||
entry = entries[i];
|
||||
unit = entry.unit;
|
||||
fields = entry.fields;
|
||||
values = entry.values;
|
||||
|
||||
for (j = 0, m = fields.length; j < m; ++j) {
|
||||
field = fields[j];
|
||||
res = resolved[field.field] || (resolved[field.field] = {});
|
||||
resUnit = res[unit] || (res[unit] = []);
|
||||
types[field.field] = type = field.type.charAt(0);
|
||||
union = ops[type + '_union'];
|
||||
res[unit] = union(resUnit, vegaUtil.array(values[j]));
|
||||
}
|
||||
|
||||
// If the same multi-selection is repeated over views and projected over
|
||||
// an encoding, it may operate over different fields making it especially
|
||||
// tricky to reliably resolve it. At best, we can de-dupe identical entries
|
||||
// but doing so may be more computationally expensive than it is worth.
|
||||
// Instead, for now, we simply transform our store representation into
|
||||
// a more human-friendly one.
|
||||
if (isMulti) {
|
||||
resUnit = multiRes[unit] || (multiRes[unit] = []);
|
||||
resUnit.push(vegaUtil.array(values).reduce((obj, curr, j) => (obj[fields[j].field] = curr, obj), {}));
|
||||
}
|
||||
}
|
||||
|
||||
// Then resolve fields across units as per the op.
|
||||
op = op || Union;
|
||||
Object.keys(resolved).forEach(function (field) {
|
||||
resolved[field] = Object.keys(resolved[field])
|
||||
.map(unit => resolved[field][unit])
|
||||
.reduce((acc, curr) => acc === undefined ? curr : ops[types[field] + '_' + op](acc, curr));
|
||||
});
|
||||
|
||||
entries = Object.keys(multiRes);
|
||||
if (isMulti && entries.length) {
|
||||
resolved[VlMulti] = op === Union
|
||||
? {[Or]: entries.reduce((acc, k) => (acc.push.apply(acc, multiRes[k]), acc), [])}
|
||||
: {[And]: entries.map(k => ({[Or]: multiRes[k]}))};
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
var ops = {
|
||||
E_union: function(base, value) {
|
||||
if (!base.length) return value;
|
||||
|
||||
var i = 0, n = value.length;
|
||||
for (; i<n; ++i) if (base.indexOf(value[i]) < 0) base.push(value[i]);
|
||||
return base;
|
||||
},
|
||||
|
||||
E_intersect: function(base, value) {
|
||||
return !base.length ? value :
|
||||
base.filter(function (v) { return value.indexOf(v) >= 0; });
|
||||
},
|
||||
|
||||
R_union: function(base, value) {
|
||||
var lo = vegaUtil.toNumber(value[0]), hi = vegaUtil.toNumber(value[1]);
|
||||
if (lo > hi) {
|
||||
lo = value[1];
|
||||
hi = value[0];
|
||||
}
|
||||
|
||||
if (!base.length) return [lo, hi];
|
||||
if (base[0] > lo) base[0] = lo;
|
||||
if (base[1] < hi) base[1] = hi;
|
||||
return base;
|
||||
},
|
||||
|
||||
R_intersect: function(base, value) {
|
||||
var lo = vegaUtil.toNumber(value[0]), hi = vegaUtil.toNumber(value[1]);
|
||||
if (lo > hi) {
|
||||
lo = value[1];
|
||||
hi = value[0];
|
||||
}
|
||||
|
||||
if (!base.length) return [lo, hi];
|
||||
if (hi < base[0] || base[1] < lo) {
|
||||
return [];
|
||||
} else {
|
||||
if (base[0] < lo) base[0] = lo;
|
||||
if (base[1] > hi) base[1] = hi;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
};
|
||||
|
||||
const DataPrefix = ':',
|
||||
IndexPrefix = '@';
|
||||
|
||||
function selectionVisitor(name, args, scope, params) {
|
||||
if (args[0].type !== vegaExpression.Literal) vegaUtil.error('First argument to selection functions must be a string literal.');
|
||||
|
||||
const data = args[0].value,
|
||||
op = args.length >= 2 && vegaUtil.peek(args).value,
|
||||
field = 'unit',
|
||||
indexName = IndexPrefix + field,
|
||||
dataName = DataPrefix + data;
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (op === Intersect && !vegaUtil.hasOwnProperty(params, indexName)) {
|
||||
params[indexName] = scope.getData(data).indataRef(scope, field);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (!vegaUtil.hasOwnProperty(params, dataName)) {
|
||||
params[dataName] = scope.getData(data).tuplesRef();
|
||||
}
|
||||
}
|
||||
|
||||
exports.selectionResolve = selectionResolve;
|
||||
exports.selectionTest = selectionTest;
|
||||
exports.selectionVisitor = selectionVisitor;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
})));
|
||||
1
node_modules/vega-selections/build/vega-selections.min.js
generated
vendored
Normal file
1
node_modules/vega-selections/build/vega-selections.min.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vega-util"),require("vega-expression")):"function"==typeof define&&define.amd?define(["exports","vega-util","vega-expression"],t):t((e=e||self).vega={},e.vega,e.vega)}(this,(function(e,t,n){"use strict";function r(e,n){for(var r,i,u=n.fields,o=n.values,a=u.length,f=0;f<a;++f)if((i=u[f]).getter=t.field.getter||t.field(i.field),r=i.getter(e),t.isDate(r)&&(r=t.toNumber(r)),t.isDate(o[f])&&(o[f]=t.toNumber(o[f])),t.isDate(o[f][0])&&(o[f]=o[f].map(t.toNumber)),"E"===i.type){if(t.isArray(o[f])?o[f].indexOf(r)<0:r!==o[f])return!1}else if("R"===i.type){if(!t.inrange(r,o[f]))return!1}else if("R-RE"===i.type){if(!t.inrange(r,o[f],!0,!1))return!1}else if("R-E"===i.type){if(!t.inrange(r,o[f],!1,!1))return!1}else if("R-LE"===i.type&&!t.inrange(r,o[f],!1,!0))return!1;return!0}var i={E_union:function(e,t){if(!e.length)return t;for(var n=0,r=t.length;n<r;++n)e.indexOf(t[n])<0&&e.push(t[n]);return e},E_intersect:function(e,t){return e.length?e.filter((function(e){return t.indexOf(e)>=0})):t},R_union:function(e,n){var r=t.toNumber(n[0]),i=t.toNumber(n[1]);return r>i&&(r=n[1],i=n[0]),e.length?(e[0]>r&&(e[0]=r),e[1]<i&&(e[1]=i),e):[r,i]},R_intersect:function(e,n){var r=t.toNumber(n[0]),i=t.toNumber(n[1]);return r>i&&(r=n[1],i=n[0]),e.length?i<e[0]||e[1]<r?[]:(e[0]<r&&(e[0]=r),e[1]>i&&(e[1]=i),e):[r,i]}};e.selectionResolve=function(e,n,r){for(var u,o,a,f,s,l,c,d,g,p,v,h=this.context.data[e],y=h?h.values.value:[],m={},b={},x={},R=y.length,O=0;O<R;++O){for(f=(u=y[O]).unit,o=u.fields,a=u.values,p=0,v=o.length;p<v;++p)s=o[p],c=(l=m[s.field]||(m[s.field]={}))[f]||(l[f]=[]),x[s.field]=d=s.type.charAt(0),g=i[d+"_union"],l[f]=g(c,t.array(a[p]));r&&(c=b[f]||(b[f]=[])).push(t.array(a).reduce((e,t,n)=>(e[o[n].field]=t,e),{}))}return n=n||"union",Object.keys(m).forEach((function(e){m[e]=Object.keys(m[e]).map(t=>m[e][t]).reduce((t,r)=>void 0===t?r:i[x[e]+"_"+n](t,r))})),y=Object.keys(b),r&&y.length&&(m.vlMulti="union"===n?{or:y.reduce((e,t)=>(e.push.apply(e,b[t]),e),[])}:{and:y.map(e=>({or:b[e]}))}),m},e.selectionTest=function(e,t,n){for(var i,u,o,a,f,s=this.context.data[e],l=s?s.values.value:[],c=s?s["index:unit"]&&s["index:unit"].value:void 0,d="intersect"===n,g=l.length,p=0;p<g;++p)if(i=l[p],c&&d){if(-1===(o=(u=u||{})[a=i.unit]||0))continue;if(f=r(t,i),u[a]=f?-1:++o,f&&1===c.size)return!0;if(!f&&o===c.get(a).count)return!1}else if(d^(f=r(t,i)))return f;return g&&d},e.selectionVisitor=function(e,r,i,u){r[0].type!==n.Literal&&t.error("First argument to selection functions must be a string literal.");const o=r[0].value,a=":"+o;"intersect"!==(r.length>=2&&t.peek(r).value)||t.hasOwnProperty(u,"@unit")||(u["@unit"]=i.getData(o).indataRef(i,"unit")),t.hasOwnProperty(u,a)||(u[a]=i.getData(o).tuplesRef())},Object.defineProperty(e,"__esModule",{value:!0})}));
|
||||
3
node_modules/vega-selections/index.js
generated
vendored
Normal file
3
node_modules/vega-selections/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export {selectionTest} from './src/selectionTest';
|
||||
export {selectionResolve} from './src/selectionResolve';
|
||||
export {selectionVisitor} from './src/selectionVisitor';
|
||||
65
node_modules/vega-selections/package.json
generated
vendored
Normal file
65
node_modules/vega-selections/package.json
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"_from": "vega-selections@^5.1.1",
|
||||
"_id": "vega-selections@5.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-ztZUMfDicuIGJHZimSdVvMGzMvaa37ICzUHHvwxS51OhYv096dzKgoSypjx+tsmR7wnhY7ZL+iQgpT1/O29jlA==",
|
||||
"_location": "/vega-selections",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "vega-selections@^5.1.1",
|
||||
"name": "vega-selections",
|
||||
"escapedName": "vega-selections",
|
||||
"rawSpec": "^5.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/vega-functions"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/vega-selections/-/vega-selections-5.1.1.tgz",
|
||||
"_shasum": "5ea3931bbf7bc13f2ab7c5c5ebf39aed98e4c114",
|
||||
"_spec": "vega-selections@^5.1.1",
|
||||
"_where": "/home/prabhatdev/Documents/opensource/gitHubStats/waka-readme-stats/node_modules/vega-functions",
|
||||
"author": {
|
||||
"name": "Arvind Satyanarayan",
|
||||
"url": "http://arvindsatya.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vega/vega/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"vega-expression": "^2.6.4",
|
||||
"vega-util": "^1.13.2"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Vega expression functions for Vega-Lite selections.",
|
||||
"gitHead": "35e31c5c6b54db9dc3a577b5adad8d15ec274d32",
|
||||
"homepage": "https://github.com/vega/vega#readme",
|
||||
"keywords": [
|
||||
"vega",
|
||||
"expression",
|
||||
"selections"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "build/vega-selections.js",
|
||||
"module": "index",
|
||||
"name": "vega-selections",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vega/vega.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn rollup",
|
||||
"postbuild": "terser build/vega-selections.js -c -m -o build/vega-selections.min.js",
|
||||
"postpublish": "git push && git push --tags",
|
||||
"prebuild": "rimraf build && mkdir build",
|
||||
"prepublishOnly": "yarn test && yarn build",
|
||||
"pretest": "yarn prebuild && yarn rollup",
|
||||
"rollup": "rollup -g vega-expression:vega,vega-util:vega -f umd -n vega -o build/vega-selections.js -- index.js",
|
||||
"test": "tape 'test/**/*-test.js'"
|
||||
},
|
||||
"version": "5.1.1"
|
||||
}
|
||||
5
node_modules/vega-selections/src/constants.js
generated
vendored
Normal file
5
node_modules/vega-selections/src/constants.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export const Intersect = 'intersect';
|
||||
export const Union = 'union';
|
||||
export const VlMulti = 'vlMulti';
|
||||
export const Or = 'or';
|
||||
export const And = 'and';
|
||||
107
node_modules/vega-selections/src/selectionResolve.js
generated
vendored
Normal file
107
node_modules/vega-selections/src/selectionResolve.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
import {And, Or, Union, VlMulti} from './constants';
|
||||
import {array, toNumber} from 'vega-util';
|
||||
|
||||
/**
|
||||
* Resolves selection for use as a scale domain or reads via the API.
|
||||
* @param {string} name - The name of the dataset representing the selection
|
||||
* @param {string} [op='union'] - The set operation for combining selections.
|
||||
* One of 'intersect' or 'union' (default).
|
||||
* @returns {object} An object of selected fields and values.
|
||||
*/
|
||||
export function selectionResolve(name, op, isMulti) {
|
||||
var data = this.context.data[name],
|
||||
entries = data ? data.values.value : [],
|
||||
resolved = {}, multiRes = {}, types = {},
|
||||
entry, fields, values, unit, field, res, resUnit, type, union,
|
||||
n = entries.length, i = 0, j, m;
|
||||
|
||||
// First union all entries within the same unit.
|
||||
for (; i < n; ++i) {
|
||||
entry = entries[i];
|
||||
unit = entry.unit;
|
||||
fields = entry.fields;
|
||||
values = entry.values;
|
||||
|
||||
for (j = 0, m = fields.length; j < m; ++j) {
|
||||
field = fields[j];
|
||||
res = resolved[field.field] || (resolved[field.field] = {});
|
||||
resUnit = res[unit] || (res[unit] = []);
|
||||
types[field.field] = type = field.type.charAt(0);
|
||||
union = ops[type + '_union'];
|
||||
res[unit] = union(resUnit, array(values[j]));
|
||||
}
|
||||
|
||||
// If the same multi-selection is repeated over views and projected over
|
||||
// an encoding, it may operate over different fields making it especially
|
||||
// tricky to reliably resolve it. At best, we can de-dupe identical entries
|
||||
// but doing so may be more computationally expensive than it is worth.
|
||||
// Instead, for now, we simply transform our store representation into
|
||||
// a more human-friendly one.
|
||||
if (isMulti) {
|
||||
resUnit = multiRes[unit] || (multiRes[unit] = []);
|
||||
resUnit.push(array(values).reduce((obj, curr, j) => (obj[fields[j].field] = curr, obj), {}));
|
||||
}
|
||||
}
|
||||
|
||||
// Then resolve fields across units as per the op.
|
||||
op = op || Union;
|
||||
Object.keys(resolved).forEach(function (field) {
|
||||
resolved[field] = Object.keys(resolved[field])
|
||||
.map(unit => resolved[field][unit])
|
||||
.reduce((acc, curr) => acc === undefined ? curr : ops[types[field] + '_' + op](acc, curr));
|
||||
});
|
||||
|
||||
entries = Object.keys(multiRes);
|
||||
if (isMulti && entries.length) {
|
||||
resolved[VlMulti] = op === Union
|
||||
? {[Or]: entries.reduce((acc, k) => (acc.push.apply(acc, multiRes[k]), acc), [])}
|
||||
: {[And]: entries.map(k => ({[Or]: multiRes[k]}))};
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
var ops = {
|
||||
E_union: function(base, value) {
|
||||
if (!base.length) return value;
|
||||
|
||||
var i = 0, n = value.length;
|
||||
for (; i<n; ++i) if (base.indexOf(value[i]) < 0) base.push(value[i]);
|
||||
return base;
|
||||
},
|
||||
|
||||
E_intersect: function(base, value) {
|
||||
return !base.length ? value :
|
||||
base.filter(function (v) { return value.indexOf(v) >= 0; });
|
||||
},
|
||||
|
||||
R_union: function(base, value) {
|
||||
var lo = toNumber(value[0]), hi = toNumber(value[1]);
|
||||
if (lo > hi) {
|
||||
lo = value[1];
|
||||
hi = value[0];
|
||||
}
|
||||
|
||||
if (!base.length) return [lo, hi];
|
||||
if (base[0] > lo) base[0] = lo;
|
||||
if (base[1] < hi) base[1] = hi;
|
||||
return base;
|
||||
},
|
||||
|
||||
R_intersect: function(base, value) {
|
||||
var lo = toNumber(value[0]), hi = toNumber(value[1]);
|
||||
if (lo > hi) {
|
||||
lo = value[1];
|
||||
hi = value[0];
|
||||
}
|
||||
|
||||
if (!base.length) return [lo, hi];
|
||||
if (hi < base[0] || base[1] < lo) {
|
||||
return [];
|
||||
} else {
|
||||
if (base[0] < lo) base[0] = lo;
|
||||
if (base[1] > hi) base[1] = hi;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
};
|
||||
104
node_modules/vega-selections/src/selectionTest.js
generated
vendored
Normal file
104
node_modules/vega-selections/src/selectionTest.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
import {Intersect} from './constants';
|
||||
import {field, inrange, isArray, isDate, toNumber} from 'vega-util';
|
||||
|
||||
var TYPE_ENUM = 'E',
|
||||
TYPE_RANGE_INC = 'R',
|
||||
TYPE_RANGE_EXC = 'R-E',
|
||||
TYPE_RANGE_LE = 'R-LE',
|
||||
TYPE_RANGE_RE = 'R-RE',
|
||||
UNIT_INDEX = 'index:unit';
|
||||
|
||||
// TODO: revisit date coercion?
|
||||
function testPoint(datum, entry) {
|
||||
var fields = entry.fields,
|
||||
values = entry.values,
|
||||
n = fields.length,
|
||||
i = 0, dval, f;
|
||||
|
||||
for (; i<n; ++i) {
|
||||
f = fields[i];
|
||||
f.getter = field.getter || field(f.field);
|
||||
dval = f.getter(datum);
|
||||
|
||||
if (isDate(dval)) dval = toNumber(dval);
|
||||
if (isDate(values[i])) values[i] = toNumber(values[i]);
|
||||
if (isDate(values[i][0])) values[i] = values[i].map(toNumber);
|
||||
|
||||
if (f.type === TYPE_ENUM) {
|
||||
// Enumerated fields can either specify individual values (single/multi selections)
|
||||
// or an array of values (interval selections).
|
||||
if(isArray(values[i]) ? values[i].indexOf(dval) < 0 : dval !== values[i]) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (f.type === TYPE_RANGE_INC) {
|
||||
if (!inrange(dval, values[i])) return false;
|
||||
} else if (f.type === TYPE_RANGE_RE) {
|
||||
// Discrete selection of bins test within the range [bin_start, bin_end).
|
||||
if (!inrange(dval, values[i], true, false)) return false;
|
||||
} else if (f.type === TYPE_RANGE_EXC) { // 'R-E'/'R-LE' included for completeness.
|
||||
if (!inrange(dval, values[i], false, false)) return false;
|
||||
} else if (f.type === TYPE_RANGE_LE) {
|
||||
if (!inrange(dval, values[i], false, true)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a tuple is contained within an interactive selection.
|
||||
* @param {string} name - The name of the data set representing the selection.
|
||||
* Tuples in the dataset are of the form
|
||||
* {unit: string, fields: array<fielddef>, values: array<*>}.
|
||||
* Fielddef is of the form
|
||||
* {field: string, channel: string, type: 'E' | 'R'} where
|
||||
* 'type' identifies whether tuples in the dataset enumerate
|
||||
* values for the field, or specify a continuous range.
|
||||
* @param {object} datum - The tuple to test for inclusion.
|
||||
* @param {string} op - The set operation for combining selections.
|
||||
* One of 'intersect' or 'union' (default).
|
||||
* @return {boolean} - True if the datum is in the selection, false otherwise.
|
||||
*/
|
||||
export function selectionTest(name, datum, op) {
|
||||
var data = this.context.data[name],
|
||||
entries = data ? data.values.value : [],
|
||||
unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined,
|
||||
intersect = op === Intersect,
|
||||
n = entries.length,
|
||||
i = 0,
|
||||
entry, miss, count, unit, b;
|
||||
|
||||
for (; i<n; ++i) {
|
||||
entry = entries[i];
|
||||
|
||||
if (unitIdx && intersect) {
|
||||
// multi selections union within the same unit and intersect across units.
|
||||
miss = miss || {};
|
||||
count = miss[unit=entry.unit] || 0;
|
||||
|
||||
// if we've already matched this unit, skip.
|
||||
if (count === -1) continue;
|
||||
|
||||
b = testPoint(datum, entry);
|
||||
miss[unit] = b ? -1 : ++count;
|
||||
|
||||
// if we match and there are no other units return true
|
||||
// if we've missed against all tuples in this unit return false
|
||||
if (b && unitIdx.size === 1) return true;
|
||||
if (!b && count === unitIdx.get(unit).count) return false;
|
||||
} else {
|
||||
b = testPoint(datum, entry);
|
||||
|
||||
// if we find a miss and we do require intersection return false
|
||||
// if we find a match and we don't require intersection return true
|
||||
if (intersect ^ b) return b;
|
||||
}
|
||||
}
|
||||
|
||||
// if intersecting and we made it here, then we saw no misses
|
||||
// if not intersecting, then we saw no matches
|
||||
// if no active selections, return false
|
||||
return n && intersect;
|
||||
}
|
||||
26
node_modules/vega-selections/src/selectionVisitor.js
generated
vendored
Normal file
26
node_modules/vega-selections/src/selectionVisitor.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import {Intersect} from './constants';
|
||||
import {Literal} from 'vega-expression';
|
||||
import {error, hasOwnProperty, peek} from 'vega-util';
|
||||
|
||||
const DataPrefix = ':',
|
||||
IndexPrefix = '@';
|
||||
|
||||
export function selectionVisitor(name, args, scope, params) {
|
||||
if (args[0].type !== Literal) error('First argument to selection functions must be a string literal.');
|
||||
|
||||
const data = args[0].value,
|
||||
op = args.length >= 2 && peek(args).value,
|
||||
field = 'unit',
|
||||
indexName = IndexPrefix + field,
|
||||
dataName = DataPrefix + data;
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (op === Intersect && !hasOwnProperty(params, indexName)) {
|
||||
params[indexName] = scope.getData(data).indataRef(scope, field);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (!hasOwnProperty(params, dataName)) {
|
||||
params[dataName] = scope.getData(data).tuplesRef();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user