vega-lite
Version:
Vega-Lite is a concise high-level language for interactive visualization.
74 lines (62 loc) • 2.37 kB
text/typescript
import {stringValue} from 'vega-util';
import {disableDirectManipulation, TUPLE, SelectionCompiler} from './index.js';
import {varName} from '../../util.js';
import {assembleInit} from './assemble.js';
import nearest from './nearest.js';
import {TUPLE_FIELDS} from './project.js';
import {isLegendBinding} from '../../selection.js';
import {NewSignal} from 'vega';
const inputBindings: SelectionCompiler<'point'> = {
defined: (selCmpt) => {
return (
selCmpt.type === 'point' &&
selCmpt.resolve === 'global' &&
selCmpt.bind &&
selCmpt.bind !== 'scales' &&
!isLegendBinding(selCmpt.bind)
);
},
parse: (model, selCmpt, selDef) => disableDirectManipulation(selCmpt, selDef),
topLevelSignals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const proj = selCmpt.project;
const bind = selCmpt.bind;
const init = selCmpt.init?.[0]; // Can only exist on single selections (one initial value).
const datum = nearest.defined(selCmpt) ? '(item().isVoronoi ? datum.datum : datum)' : 'datum';
proj.items.forEach((p, i) => {
const sgname = varName(`${name}_${p.field}`);
const hasSignal = signals.filter((s) => s.name === sgname);
if (!hasSignal.length) {
signals.unshift({
name: sgname,
...(init ? {init: assembleInit(init[i])} : {value: null}),
on: selCmpt.events
? [
{
events: selCmpt.events,
update: `datum && item().mark.marktype !== 'group' ? ${datum}[${stringValue(p.field)}] : null`,
},
]
: [],
bind: (bind as any)[p.field] ?? (bind as any)[p.channel] ?? bind,
});
}
});
return signals;
},
signals: (model, selCmpt, signals) => {
const name = selCmpt.name;
const proj = selCmpt.project;
const signal: NewSignal = signals.find((s) => s.name === name + TUPLE);
const fields = name + TUPLE_FIELDS;
const values = proj.items.map((p) => varName(`${name}_${p.field}`));
const valid = values.map((v) => `${v} !== null`).join(' && ');
if (values.length) {
signal.update = `${valid} ? {fields: ${fields}, values: [${values.join(', ')}]} : null`;
}
delete signal.value;
delete signal.on;
return signals;
},
};
export default inputBindings;