Skip to content

Commit

Permalink
add expr functions for extensional selection predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
arvind authored and jheer committed Jan 21, 2021
1 parent c725029 commit 5350881
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 3 deletions.
4 changes: 4 additions & 0 deletions packages/vega-functions/src/codegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {
} from 'vega-dataflow';

import {
selectionIdTest,
selectionResolve,
selectionTest,
selectionTuples,
selectionVisitor
} from 'vega-selections';

Expand Down Expand Up @@ -351,4 +353,6 @@ expressionFunction('treeAncestors', treeAncestors, dataVisitor);

// register Vega-Lite selection functions
expressionFunction('vlSelectionTest', selectionTest, selectionVisitor);
expressionFunction('vlSelectionIdTest', selectionIdTest, selectionVisitor);
expressionFunction('vlSelectionResolve', selectionResolve, selectionVisitor);
expressionFunction('vlSelectionTuples', selectionTuples);
3 changes: 2 additions & 1 deletion packages/vega-selections/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,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';
30 changes: 28 additions & 2 deletions packages/vega-selections/src/selectionTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
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',
TYPE_RANGE_EXC = 'R-E',
TYPE_RANGE_LE = 'R-LE',
Expand Down Expand Up @@ -101,4 +103,28 @@ export function selectionTest(name, datum, op) {
// if not intersecting, then we saw no matches
// if no active selections, return false
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;
}
14 changes: 14 additions & 0 deletions packages/vega-selections/src/selectionTuples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {extend, field} from 'vega-util';

/**
* 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.
*/
export function selectionTuples(array, base) {
return array.map(x => extend({
values: base.fields.map(f => (f.getter || (f.getter = field(f.field)))(x.datum))
}, base));
}

0 comments on commit 5350881

Please sign in to comment.