Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export default function(spec, scope, target) {
var events = spec.events,
update = spec.update,
encode = spec.encode,
sources = [],
entry = {target: target};
if (!events) {
error('Signal update missing events specification.');
}
// interpret as an event selector string
if (isString(events)) {
events = selector(events, scope.isSubscope() ? Scope : View);
}
// separate event streams from signal updates
events = array(events)
.filter(s => s.signal || s.scale ? (sources.push(s), 0) : 1);
// merge internal operator listeners
if (sources.length > 1) {
sources = [mergeSources(sources)];
}
// merge event streams, include as source
if (events.length) {
sources.push(events.length > 1 ? {merge: events} : events[0]);
}
// a property (e.g., "nearest": true).
for (const key in cfg) {
// A selection should contain either `encodings` or `fields`, only use
// default values for these two values if neither of them is specified.
if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {
continue;
}
if (key === 'mark') {
selDef[key] = Object.assign({}, cfg[key], selDef[key]);
}
if (selDef[key] === undefined || selDef[key] === true) {
selDef[key] = cfg[key] || selDef[key];
}
}
name = varName(name);
const selCmpt = (selCmpts[name] = Object.assign({}, selDef, { name: name, events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on }));
forEachTransform(selCmpt, txCompiler => {
if (txCompiler.parse) {
txCompiler.parse(model, selDef, selCmpt);
}
});
}
return selCmpts;
}
export function assembleUnitSelectionSignals(model, signals) {
}
if (key === 'mark') {
selDef[key] = {...cfg[key], ...selDef[key]};
}
if (selDef[key] === undefined || selDef[key] === true) {
selDef[key] = cfg[key] ?? selDef[key];
}
}
const safeName = varName(name);
const selCmpt = (selCmpts[safeName] = {
...selDef,
name: safeName,
events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : duplicate(selDef.on)
} as any);
forEachTransform(selCmpt, txCompiler => {
if (txCompiler.has(selCmpt) && txCompiler.parse) {
txCompiler.parse(model, selCmpt, selDef, selDefs[name]);
}
});
}
return selCmpts;
}
signals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const hasScales = scalesCompiler.has(selCmpt);
const delta = name + DELTA;
const { x, y } = selCmpt.project.has;
const sx = stringValue(model.scaleName(X));
const sy = stringValue(model.scaleName(Y));
let events = parseSelector(selCmpt.zoom, 'scope');
if (!hasScales) {
events = events.map(e => ((e.markname = name + INTERVAL_BRUSH), e));
}
signals.push({
name: name + ANCHOR,
on: [
{
events: events,
update: !hasScales
? `{x: x(unit), y: y(unit)}`
: '{' +
[sx ? `x: invert(${sx}, x(unit))` : '', sy ? `y: invert(${sy}, y(unit))` : '']
.filter(expr => !!expr)
.join(', ') +
'}'
}
export function assembleFacetSignals(model: FacetModel, signals: Signal[]) {
if (model.component.selection && keys(model.component.selection).length) {
const name = stringValue(model.getName('cell'));
signals.unshift({
name: 'facet',
value: {},
on: [
{
events: parseSelector('mousemove', 'scope'),
update: `isTuple(facet) ? facet : group(${name}).datum`
}
]
});
}
return cleanupEmptyOnArray(signals);
}
parse: (model, selDef, selCmpt) => {
if (selDef.clear) {
selCmpt.clear = parseSelector(selDef.clear, 'scope');
}
},
signals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const hasScales = scalesCompiler.has(selCmpt);
const anchor = name + ANCHOR;
const {x, y} = selCmpt.project.hasChannel;
let events = parseSelector(selCmpt.translate, 'scope');
if (!hasScales) {
events = events.map(e => ((e.between[0].markname = name + INTERVAL_BRUSH), e));
}
signals.push(
{
name: anchor,
value: {},
on: [
{
events: events.map(e => e.between[0]),
update:
'{x: x(unit), y: y(unit)' +
(x !== undefined ? ', extent_x: ' + (hasScales ? domain(model, X) : `slice(${x.signals.visual})`) : '') +
(y !== undefined ? ', extent_y: ' + (hasScales ? domain(model, Y) : `slice(${y.signals.visual})`) : '') +
signals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const hasScales = scalesCompiler.has(selCmpt);
const anchor = name + ANCHOR;
const { x, y } = selCmpt.project.has;
let events = parseSelector(selCmpt.translate, 'scope');
if (!hasScales) {
events = events.map(e => ((e.between[0].markname = name + INTERVAL_BRUSH), e));
}
signals.push({
name: anchor,
value: {},
on: [
{
events: events.map(e => e.between[0]),
update: '{x: x(unit), y: y(unit)' +
(x !== undefined ? ', extent_x: ' + (hasScales ? domain(model, X) : `slice(${x.signals.visual})`) : '') +
(y !== undefined ? ', extent_y: ' + (hasScales ? domain(model, Y) : `slice(${y.signals.visual})`) : '') +
'}'
}
]
}, {
export function assembleFacetSignals(model, signals) {
if (model.component.selection && keys(model.component.selection).length) {
const name = stringValue(model.getName('cell'));
signals.unshift({
name: 'facet',
value: {},
on: [
{
events: parseSelector('mousemove', 'scope'),
update: `isTuple(facet) ? facet : group(${name}).datum`
}
]
});
}
return signals;
}
export function assembleTopLevelSignals(model, signals) {
signals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const hasScales = scalesCompiler.has(selCmpt);
const delta = name + DELTA;
const {x, y} = selCmpt.project.hasChannel;
const sx = stringValue(model.scaleName(X));
const sy = stringValue(model.scaleName(Y));
let events = parseSelector(selCmpt.zoom, 'scope');
if (!hasScales) {
events = events.map(e => ((e.markname = name + INTERVAL_BRUSH), e));
}
signals.push(
{
name: name + ANCHOR,
on: [
{
events: events,
update: !hasScales
? `{x: x(unit), y: y(unit)}`
: '{' +
[sx ? `x: invert(${sx}, x(unit))` : '', sy ? `y: invert(${sy}, y(unit))` : '']
.filter(expr => !!expr)