vega-selections
Advanced tools
Comparing version 5.2.0 to 5.3.0
@@ -7,2 +7,58 @@ (function (global, factory) { | ||
function ascending (a, b) { | ||
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | ||
} | ||
function bisector (f) { | ||
let delta = f; | ||
let compare = f; | ||
if (f.length === 1) { | ||
delta = (d, x) => f(d) - x; | ||
compare = ascendingComparator(f); | ||
} | ||
function left(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
const mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; | ||
} | ||
return lo; | ||
} | ||
function right(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
const mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; | ||
} | ||
return lo; | ||
} | ||
function center(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
const i = left(a, x, lo, hi - 1); | ||
return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; | ||
} | ||
return { | ||
left, | ||
center, | ||
right | ||
}; | ||
} | ||
function ascendingComparator(f) { | ||
return (d, x) => ascending(f(d), x); | ||
} | ||
const Intersect = 'intersect'; | ||
@@ -15,8 +71,9 @@ const Union = 'union'; | ||
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? | ||
const SELECTION_ID = '_vgsid_', | ||
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? | ||
@@ -119,4 +176,39 @@ function testPoint(datum, entry) { | ||
} | ||
const selectionId = vegaUtil.field(SELECTION_ID), | ||
bisect = bisector(selectionId), | ||
bisectLeft = bisect.left, | ||
bisectRight = bisect.right; | ||
function selectionIdTest(name, datum, op) { | ||
const data = this.context.data[name], | ||
entries = data ? data.values.value : [], | ||
unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined, | ||
intersect = op === Intersect, | ||
value = selectionId(datum), | ||
index = bisectLeft(entries, value); | ||
if (index === entries.length) return false; | ||
if (selectionId(entries[index]) !== value) return false; | ||
if (unitIdx && intersect) { | ||
if (unitIdx.size === 1) return true; | ||
if (bisectRight(entries, value) - index < unitIdx.size) return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Maps an array of scene graph items to an array of selection tuples. | ||
* @param {string} name - The name of the dataset representing the selection. | ||
* @param {string} unit - The name of the unit view. | ||
* | ||
* @returns {array} An array of selection entries for the given unit. | ||
*/ | ||
function selectionTuples(array, base) { | ||
return array.map(x => vegaUtil.extend({ | ||
values: base.fields.map(f => (f.getter || (f.getter = vegaUtil.field(f.field)))(x.datum)) | ||
}, base)); | ||
} | ||
/** | ||
* Resolves selection for use as a scale domain or reads via the API. | ||
@@ -271,4 +363,6 @@ * @param {string} name - The name of the dataset representing the selection | ||
exports.selectionIdTest = selectionIdTest; | ||
exports.selectionResolve = selectionResolve; | ||
exports.selectionTest = selectionTest; | ||
exports.selectionTuples = selectionTuples; | ||
exports.selectionVisitor = selectionVisitor; | ||
@@ -275,0 +369,0 @@ |
@@ -1,2 +0,2 @@ | ||
!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="undefined"!=typeof globalThis?globalThis:e||self).vega={},e.vega,e.vega)}(this,(function(e,t,n){"use strict";const r="intersect",i="union";var u="index:unit";function o(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 a={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((e=>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,u){for(var o,f,l,s,c,d,g,v,p,h,y,b=this.context.data[e],m=b?b.values.value:[],x={},R={},O={},_=m.length,E=0;E<_;++E){for(s=(o=m[E]).unit,f=o.fields,l=o.values,h=0,y=f.length;h<y;++h)c=f[h],g=(d=x[c.field]||(x[c.field]={}))[s]||(d[s]=[]),O[c.field]=v=c.type.charAt(0),p=a[v+"_union"],d[s]=p(g,t.array(l[h]));r&&(g=R[s]||(R[s]=[])).push(t.array(l).reduce(((e,t,n)=>(e[f[n].field]=t,e)),{}))}if(n=n||i,Object.keys(x).forEach((e=>{x[e]=Object.keys(x[e]).map((t=>x[e][t])).reduce(((t,r)=>void 0===t?r:a[O[e]+"_"+n](t,r)))})),m=Object.keys(R),r&&m.length){x[u?"vlPoint":"vlMulti"]=n===i?{or:m.reduce(((e,t)=>(e.push(...R[t]),e)),[])}:{and:m.map((e=>({or:R[e]})))}}return x},e.selectionTest=function(e,t,n){for(var i,a,f,l,s,c=this.context.data[e],d=c?c.values.value:[],g=c?c[u]&&c[u].value:void 0,v=n===r,p=d.length,h=0;h<p;++h)if(i=d[h],g&&v){if(-1===(f=(a=a||{})[l=i.unit]||0))continue;if(s=o(t,i),a[l]=s?-1:++f,s&&1===g.size)return!0;if(!s&&f===g.get(l).count)return!1}else if(v^(s=o(t,i)))return s;return p&&v},e.selectionVisitor=function(e,i,u,o){i[0].type!==n.Literal&&t.error("First argument to selection functions must be a string literal.");const a=i[0].value,f="unit",l="@unit",s=":"+a;(i.length>=2&&t.peek(i).value)!==r||t.hasOwnProperty(o,l)||(o["@unit"]=u.getData(a).indataRef(u,f)),t.hasOwnProperty(o,s)||(o[s]=u.getData(a).tuplesRef())},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!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="undefined"!=typeof globalThis?globalThis:e||self).vega={},e.vega,e.vega)}(this,(function(e,t,n){"use strict";const r="intersect",i="union",u="index:unit";function l(e,n){for(var r,i,u=n.fields,l=n.values,o=u.length,f=0;f<o;++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(l[f])&&(l[f]=t.toNumber(l[f])),t.isDate(l[f][0])&&(l[f]=l[f].map(t.toNumber)),"E"===i.type){if(t.isArray(l[f])?l[f].indexOf(r)<0:r!==l[f])return!1}else if("R"===i.type){if(!t.inrange(r,l[f]))return!1}else if("R-RE"===i.type){if(!t.inrange(r,l[f],!0,!1))return!1}else if("R-E"===i.type){if(!t.inrange(r,l[f],!1,!1))return!1}else if("R-LE"===i.type&&!t.inrange(r,l[f],!1,!0))return!1;return!0}const o=t.field("_vgsid_"),f=function(e){let t=e,n=e;function r(e,t,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r<i;){const u=r+i>>>1;n(e[u],t)<0?r=u+1:i=u}return r}return 1===e.length&&(t=(t,n)=>e(t)-n,n=function(e){return(t,n)=>{return(r=e(t))<(i=n)?-1:r>i?1:r>=i?0:NaN;var r,i}}(e)),{left:r,center:function(e,n,i,u){null==i&&(i=0),null==u&&(u=e.length);const l=r(e,n,i,u-1);return l>i&&t(e[l-1],n)>-t(e[l],n)?l-1:l},right:function(e,t,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r<i;){const u=r+i>>>1;n(e[u],t)>0?i=u:r=u+1}return r}}}(o),s=f.left,a=f.right;var c={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((e=>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.selectionIdTest=function(e,t,n){const i=this.context.data[e],l=i?i.values.value:[],f=i?i[u]&&i[u].value:void 0,c=n===r,d=o(t),g=s(l,d);if(g===l.length)return!1;if(o(l[g])!==d)return!1;if(f&&c){if(1===f.size)return!0;if(a(l,d)-g<f.size)return!1}return!0},e.selectionResolve=function(e,n,r,u){for(var l,o,f,s,a,d,g,v,h,p,y,m=this.context.data[e],b=m?m.values.value:[],x={},R={},_={},N=b.length,O=0;O<N;++O){for(s=(l=b[O]).unit,o=l.fields,f=l.values,p=0,y=o.length;p<y;++p)a=o[p],g=(d=x[a.field]||(x[a.field]={}))[s]||(d[s]=[]),_[a.field]=v=a.type.charAt(0),h=c[v+"_union"],d[s]=h(g,t.array(f[p]));r&&(g=R[s]||(R[s]=[])).push(t.array(f).reduce(((e,t,n)=>(e[o[n].field]=t,e)),{}))}if(n=n||i,Object.keys(x).forEach((e=>{x[e]=Object.keys(x[e]).map((t=>x[e][t])).reduce(((t,r)=>void 0===t?r:c[_[e]+"_"+n](t,r)))})),b=Object.keys(R),r&&b.length){x[u?"vlPoint":"vlMulti"]=n===i?{or:b.reduce(((e,t)=>(e.push(...R[t]),e)),[])}:{and:b.map((e=>({or:R[e]})))}}return x},e.selectionTest=function(e,t,n){for(var i,o,f,s,a,c=this.context.data[e],d=c?c.values.value:[],g=c?c[u]&&c[u].value:void 0,v=n===r,h=d.length,p=0;p<h;++p)if(i=d[p],g&&v){if(-1===(f=(o=o||{})[s=i.unit]||0))continue;if(a=l(t,i),o[s]=a?-1:++f,a&&1===g.size)return!0;if(!a&&f===g.get(s).count)return!1}else if(v^(a=l(t,i)))return a;return h&&v},e.selectionTuples=function(e,n){return e.map((e=>t.extend({values:n.fields.map((n=>(n.getter||(n.getter=t.field(n.field)))(e.datum)))},n)))},e.selectionVisitor=function(e,i,u,l){i[0].type!==n.Literal&&t.error("First argument to selection functions must be a string literal.");const o=i[0].value,f="unit",s="@unit",a=":"+o;(i.length>=2&&t.peek(i).value)!==r||t.hasOwnProperty(l,s)||(l["@unit"]=u.getData(o).indataRef(u,f)),t.hasOwnProperty(l,a)||(l[a]=u.getData(o).tuplesRef())},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=vega-selection.min.js.map |
@@ -1,4 +0,60 @@ | ||
import { field, isDate, toNumber, isArray, inrange, array, error, peek, hasOwnProperty } from 'vega-util'; | ||
import { field, isDate, toNumber, isArray, inrange, extend, array, error, peek, hasOwnProperty } from 'vega-util'; | ||
import { Literal } from 'vega-expression'; | ||
function ascending (a, b) { | ||
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | ||
} | ||
function bisector (f) { | ||
let delta = f; | ||
let compare = f; | ||
if (f.length === 1) { | ||
delta = (d, x) => f(d) - x; | ||
compare = ascendingComparator(f); | ||
} | ||
function left(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
const mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; | ||
} | ||
return lo; | ||
} | ||
function right(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
const mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; | ||
} | ||
return lo; | ||
} | ||
function center(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
const i = left(a, x, lo, hi - 1); | ||
return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; | ||
} | ||
return { | ||
left, | ||
center, | ||
right | ||
}; | ||
} | ||
function ascendingComparator(f) { | ||
return (d, x) => ascending(f(d), x); | ||
} | ||
const Intersect = 'intersect'; | ||
@@ -11,8 +67,9 @@ const Union = 'union'; | ||
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? | ||
const SELECTION_ID = '_vgsid_', | ||
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? | ||
@@ -115,4 +172,39 @@ function testPoint(datum, entry) { | ||
} | ||
const selectionId = field(SELECTION_ID), | ||
bisect = bisector(selectionId), | ||
bisectLeft = bisect.left, | ||
bisectRight = bisect.right; | ||
function selectionIdTest(name, datum, op) { | ||
const data = this.context.data[name], | ||
entries = data ? data.values.value : [], | ||
unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined, | ||
intersect = op === Intersect, | ||
value = selectionId(datum), | ||
index = bisectLeft(entries, value); | ||
if (index === entries.length) return false; | ||
if (selectionId(entries[index]) !== value) return false; | ||
if (unitIdx && intersect) { | ||
if (unitIdx.size === 1) return true; | ||
if (bisectRight(entries, value) - index < unitIdx.size) return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Maps an array of scene graph items to an array of selection tuples. | ||
* @param {string} name - The name of the dataset representing the selection. | ||
* @param {string} unit - The name of the unit view. | ||
* | ||
* @returns {array} An array of selection entries for the given unit. | ||
*/ | ||
function selectionTuples(array, base) { | ||
return array.map(x => extend({ | ||
values: base.fields.map(f => (f.getter || (f.getter = field(f.field)))(x.datum)) | ||
}, base)); | ||
} | ||
/** | ||
* Resolves selection for use as a scale domain or reads via the API. | ||
@@ -267,2 +359,2 @@ * @param {string} name - The name of the dataset representing the selection | ||
export { selectionResolve, selectionTest, selectionVisitor }; | ||
export { selectionIdTest, selectionResolve, selectionTest, selectionTuples, selectionVisitor }; |
@@ -1,3 +0,4 @@ | ||
export {selectionTest} from './src/selectionTest'; | ||
export {selectionTest, selectionIdTest} from './src/selectionTest'; | ||
export {selectionTuples} from './src/selectionTuples'; | ||
export {selectionResolve} from './src/selectionResolve'; | ||
export {selectionVisitor} from './src/selectionVisitor'; |
{ | ||
"name": "vega-selections", | ||
"version": "5.2.0", | ||
"version": "5.3.0", | ||
"description": "Vega expression functions for Vega-Lite selections.", | ||
@@ -27,3 +27,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "0f8859294bb83eb637da209d952faf65eebcf908" | ||
"gitHead": "b88cd747158cb91dbbe0c55141604eb6e4fedae4" | ||
} |
@@ -0,5 +1,7 @@ | ||
import {bisector} from 'd3-array'; | ||
import {Intersect} from './constants'; | ||
import {field, inrange, isArray, isDate, toNumber} from 'vega-util'; | ||
var TYPE_ENUM = 'E', | ||
const SELECTION_ID = '_vgsid_', | ||
TYPE_ENUM = 'E', | ||
TYPE_RANGE_INC = 'R', | ||
@@ -104,2 +106,26 @@ TYPE_RANGE_EXC = 'R-E', | ||
return n && intersect; | ||
} | ||
} | ||
const selectionId = field(SELECTION_ID), | ||
bisect = bisector(selectionId), | ||
bisectLeft = bisect.left, | ||
bisectRight = bisect.right; | ||
export function selectionIdTest(name, datum, op) { | ||
const data = this.context.data[name], | ||
entries = data ? data.values.value : [], | ||
unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined, | ||
intersect = op === Intersect, | ||
value = selectionId(datum), | ||
index = bisectLeft(entries, value); | ||
if (index === entries.length) return false; | ||
if (selectionId(entries[index]) !== value) return false; | ||
if (unitIdx && intersect) { | ||
if (unitIdx.size === 1) return true; | ||
if (bisectRight(entries, value) - index < unitIdx.size) return false; | ||
} | ||
return true; | ||
} |
Sorry, the diff of this file is not supported yet
58004
14
883