Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
while (level-- > 0) {
object += '.mark.group';
}
if (ref.parent) {
field = ref.parent;
object += '.datum';
} else {
field = ref.group;
}
} else if (ref.datum) {
object = 'datum';
field = ref.datum;
} else {
error('Invalid field reference: ' + stringValue(ref));
}
if (!ref.signal) {
if (isString(field)) {
fields[field] = 1; // TODO review field tracking?
field = splitAccessPath(field).map(stringValue).join('][');
} else {
field = resolve(field, scope, params, fields);
}
}
return object + '[' + field + ']';
}
function channelSignals(model, selCmpt, proj, init) {
const channel = proj.channel;
const vname = proj.signals.visual;
const dname = proj.signals.data;
const hasScales = scales.has(selCmpt);
const scaleName = stringValue(model.scaleName(channel));
const scale = model.getScaleComponent(channel);
const scaleType = scale ? scale.get('type') : undefined;
const scaled = (str) => `scale(${scaleName}, ${str})`;
const size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal;
const coord = `${channel}(unit)`;
const on = events(selCmpt, (def, evt) => {
return [
...def,
{ events: evt.between[0], update: `[${coord}, ${coord}]` },
{ events: evt, update: `[${vname}[0], clamp(${coord}, 0, ${size})]` } // Brush End
];
});
// React to pan/zooms of continuous scales. Non-continuous scales
// (band, point) cannot be pan/zoomed and any other changes
// to their domains (e.g., filtering) should clear the brushes.
on.push({
}
else {
selCmpt = model.getSelectionComponent(name, selDomain.selection);
if (!encoding && !field) {
field = selCmpt.project[0].field;
if (selCmpt.project.length > 1) {
warn('A "field" or "encoding" must be specified when using a selection as a scale domain. ' +
`Using "field": ${stringValue(field)}.`);
}
}
else if (encoding && !field) {
const encodings = selCmpt.project.filter(p => p.channel === encoding);
if (!encodings.length || encodings.length > 1) {
field = selCmpt.project[0].field;
warn((!encodings.length ? 'No ' : 'Multiple ') +
`matching ${stringValue(encoding)} encoding found for selection ${stringValue(selDomain.selection)}. ` +
`Using "field": ${stringValue(field)}.`);
}
else {
field = encodings[0].field;
}
}
return { signal: accessPathWithDatum(field, name) };
}
return { signal: 'null' };
}
// Utility functions
function parseSubParameter(def, value, scope) {
var params, pdef, k, i, n;
// loop over defs to find matching key
for (i=0, n=def.params.length; i
.map(p => {
const fieldDef = model.fieldDef(p.channel);
// Binned fields should capture extents, for a range test against the raw field.
return fieldDef && fieldDef.bin
? `[${datum}[${stringValue(model.vgField(p.channel, {}))}], ` +
`${datum}[${stringValue(model.vgField(p.channel, {binSuffix: 'end'}))}]]`
: `${datum}[${stringValue(p.field)}]`;
})
.join(', ');
.map(name => {
const store = stringValue(varName(name) + STORE);
return `(!length(data(${store})) || (${name}[${field}] && indexof(${name}[${field}], datum.value) >= 0))`;
})
.join(' || ');
function selectedCondition(model: UnitModel, legendCmp: LegendComponent, fieldDef: TypedFieldDef) {
const selections = legendCmp.get('selections');
if (!selections?.length) return undefined;
const field = stringValue(fieldDef.field);
return selections
.map(name => {
const store = stringValue(varName(name) + STORE);
return `(!length(data(${store})) || (${name}[${field}] && indexof(${name}[${field}], datum.value) >= 0))`;
})
.join(' || ');
}
globalvar: function(id) { return '_[' + stringValue('$' + id) + ']'; },
functions: expressionFunctions,
function dataLookupError(name) {
error('Can not find data set: ' + stringValue(name));
}