Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add expr functions for extensional selection predicates #3009

Merged
merged 1 commit into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -336,4 +338,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));
}