import {AggregateOp} from 'vega'; import {vgField} from '../../channeldef'; import {JoinAggregateTransform} from '../../transform'; import {duplicate, hash} from '../../util'; import {VgJoinAggregateTransform} from '../../vega.schema'; import {JoinAggregateFieldDef} from '../../transform'; import {unique} from '../../util'; import {DataFlowNode} from './dataflow'; /** * A class for the join aggregate transform nodes. */ export class JoinAggregateTransformNode extends DataFlowNode { public clone() { return new JoinAggregateTransformNode(null, duplicate(this.transform)); } constructor( parent: DataFlowNode, private readonly transform: JoinAggregateTransform ) { super(parent); } public addDimensions(fields: string[]) { this.transform.groupby = unique(this.transform.groupby.concat(fields), d => d); } public dependentFields() { const out = new Set(); if (this.transform.groupby) { this.transform.groupby.forEach(out.add, out); } this.transform.joinaggregate .map(w => w.field) .filter(f => f !== undefined) .forEach(out.add, out); return out; } public producedFields() { return new Set(this.transform.joinaggregate.map(this.getDefaultName)); } private getDefaultName(joinAggregateFieldDef: JoinAggregateFieldDef): string { return joinAggregateFieldDef.as ?? vgField(joinAggregateFieldDef); } public hash() { return `JoinAggregateTransform ${hash(this.transform)}`; } public assemble(): VgJoinAggregateTransform { const fields: string[] = []; const ops: AggregateOp[] = []; const as: string[] = []; for (const joinaggregate of this.transform.joinaggregate) { ops.push(joinaggregate.op); as.push(this.getDefaultName(joinaggregate)); fields.push(joinaggregate.field === undefined ? null : joinaggregate.field); } const groupby = this.transform.groupby; return { type: 'joinaggregate', as, ops, fields, ...(groupby !== undefined ? {groupby} : {}) }; } }