From f365e1fffeb75e8e2534f8e34cf6c3b282729d31 Mon Sep 17 00:00:00 2001 From: Arvind Satyanarayan Date: Thu, 7 Jan 2021 13:44:59 -0500 Subject: [PATCH] fix: parse field projections after encodings to prevent duplicates (#7164) --- src/compile/selection/project.ts | 17 +++++++++-------- test/compile/selection/parse.test.ts | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/compile/selection/project.ts b/src/compile/selection/project.ts index 6506edfc35..38a29ec0c6 100644 --- a/src/compile/selection/project.ts +++ b/src/compile/selection/project.ts @@ -96,14 +96,6 @@ const project: SelectionCompiler = { } } - // TODO: find a possible channel mapping for these fields. - for (const field of fields ?? []) { - const p: SelectionProjection = {type: 'E', field}; - p.signals = {...signalName(p, 'data')}; - proj.items.push(p); - proj.hasField[field] = p; - } - for (const channel of encodings ?? []) { const fieldDef = model.fieldDef(channel); if (fieldDef) { @@ -158,6 +150,15 @@ const project: SelectionCompiler = { } } + // TODO: find a possible channel mapping for these fields. + for (const field of fields ?? []) { + if (proj.hasField[field]) continue; + const p: SelectionProjection = {type: 'E', field}; + p.signals = {...signalName(p, 'data')}; + proj.items.push(p); + proj.hasField[field] = p; + } + if (init) { selCmpt.init = (init as any).map((v: SelectionInitMapping | SelectionInitIntervalMapping) => { return proj.items.map(p => (v[p.channel] !== undefined ? v[p.channel] : v[p.field])); diff --git a/test/compile/selection/parse.test.ts b/test/compile/selection/parse.test.ts index 6cca6606d7..5e61ee6160 100644 --- a/test/compile/selection/parse.test.ts +++ b/test/compile/selection/parse.test.ts @@ -282,6 +282,20 @@ describe('Selection', () => { } ]); }); + + it('does not add duplicate projections', () => { + const component = parseUnitSelection(model, [ + { + name: 'one', + select: {type: 'interval', fields: ['Horsepower', 'Miles_per_Gallon'], encodings: ['x', 'y']} + } + ]); + + expect(component['one'].project.items).toEqual([ + {field: 'Horsepower', channel: 'x', type: 'R', signals: {data: 'one_Horsepower', visual: 'one_x'}}, + {field: 'Miles_per_Gallon', channel: 'y', type: 'R', signals: {data: 'one_Miles_per_Gallon', visual: 'one_y'}} + ]); + }); }); it('materializes a selection', () => {