Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeat #1262

Merged
merged 24 commits into from
Mar 25, 2016
Merged

Repeat #1262

Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "0.1.0",
"command": "npm",
"isShellCommand": true,
"args": [
"run"
],
"showOutput": "silent",
"tasks": [
{
// "npm run build"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. JSON shouldn't have JS comment?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix in on master

"taskName": "build",
"isBuildCommand": true,
"problemMatcher": "$tsc"
},
{
// Test task, Ctrl+Shift+T
// "npm test"
"taskName": "test",
"isTestCommand": true
}
]
}
4 changes: 2 additions & 2 deletions src/compile/axis.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {AxisOrient} from '../axis';
import {COLUMN, ROW, X, Y, Channel} from '../channel';
import {title as fieldDefTitle, isDimension} from '../fielddef';
import {isDimension} from '../fielddef';
import {NOMINAL, ORDINAL, TEMPORAL} from '../type';
import {contains, keys, extend, truncate, Dict} from '../util';
import {VgAxis} from '../vega.schema';
Expand Down Expand Up @@ -203,7 +203,7 @@ export function title(model: Model, channel: Channel) {
}

// if not defined, automatically determine axis title from field def
const fieldTitle = fieldDefTitle(model.fieldDef(channel));
const fieldTitle = model.title(channel);

let maxLength;
if (axis.titleMaxLength) {
Expand Down
15 changes: 10 additions & 5 deletions src/compile/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@ import {QUANTITATIVE, ORDINAL, TEMPORAL} from '../type';
import {contains, union} from '../util';

import {FacetModel} from './facet';
import {RepeatModel, RepeatValues} from './repeat';
import {LayerModel} from './layer';
import {Model} from './model';
import {format as timeFormatExpr} from './time';
import {UnitModel} from './unit';
import {Spec, isUnitSpec, isFacetSpec, isLayerSpec} from '../spec';
import {Spec, isUnitSpec, isFacetSpec, isRepeatSpec, isLayerSpec} from '../spec';


export function buildModel(spec: Spec, parent: Model, parentGivenName: string): Model {
export function buildModel(spec: Spec, parent: Model, parentGivenName: string, repeatValues: RepeatValues): Model {
if (isFacetSpec(spec)) {
return new FacetModel(spec, parent, parentGivenName);
return new FacetModel(spec, parent, parentGivenName, repeatValues);
}

if (isRepeatSpec(spec)) {
return new RepeatModel(spec, parent, parentGivenName, repeatValues);
}

if (isLayerSpec(spec)) {
return new LayerModel(spec, parent, parentGivenName);
return new LayerModel(spec, parent, parentGivenName, repeatValues);
}

if (isUnitSpec(spec)) {
return new UnitModel(spec, parent, parentGivenName);
return new UnitModel(spec, parent, parentGivenName, repeatValues);
}

console.error('Invalid spec.');
Expand Down
2 changes: 1 addition & 1 deletion src/compile/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function compile(inputSpec: ExtendedSpec) {
const spec = normalize(inputSpec);

// 2. Instantiate the model with default properties
const model = buildModel(spec, null, '');
const model = buildModel(spec, null, '', null);

// 3. Parse each part of the model to produce components that will be assembled later
// We traverse the whole tree to parse once for each type of components
Expand Down
23 changes: 20 additions & 3 deletions src/compile/data/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import {field, FieldDef} from '../../fielddef';
import {extend, vals, flatten, hash, Dict} from '../../util';
import {VgTransform} from '../../vega.schema';

import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {Model} from './../model';
import {FacetModel} from '../facet';
import {LayerModel} from '../layer';
import {RepeatModel} from './../repeat';
import {Model} from '../model';

import {DataComponent} from './data';

Expand Down Expand Up @@ -85,6 +86,22 @@ export namespace bin {
return binComponent;
}

export function parseRepeat(model: RepeatModel) {
let binComponent = parse(model);

model.children().forEach((child) => {
const childDataComponent = child.component.data;

// If child doesn't have its own data source, then merge
if (!childDataComponent.source) {
extend(binComponent, childDataComponent.bin);
delete childDataComponent.bin;
}
});

return binComponent;
}

export function assemble(component: DataComponent) {
return flatten(vals(component.bin));
}
Expand Down
28 changes: 23 additions & 5 deletions src/compile/data/colorrank.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {COLOR} from '../../channel';
import {ORDINAL} from '../../type';
import {extend, vals, flatten, Dict} from '../../util';
import {extend, vals, flatten, hash, Dict} from '../../util';
import {VgTransform} from '../../vega.schema';

import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {Model} from './../model';
import {FacetModel} from '../facet';
import {LayerModel} from '../layer';
import {RepeatModel} from './../repeat';
import {Model} from '../model';

import {DataComponent} from './data';

Expand All @@ -21,7 +22,8 @@ export namespace colorRank {
export function parseUnit(model: Model) {
let colorRankComponent: Dict<VgTransform[]> = {};
if (model.has(COLOR) && model.fieldDef(COLOR).type === ORDINAL) {
colorRankComponent[model.field(COLOR)] = [{
// TODO: what is the right thing?
colorRankComponent[hash(model.field(COLOR))] = [{
type: 'sort',
by: model.field(COLOR)
}, {
Expand Down Expand Up @@ -66,6 +68,22 @@ export namespace colorRank {
return colorRankComponent;
}

export function parseRepeat(model: RepeatModel) {
let colorRankComponent = {} as Dict<VgTransform[]>;

model.children().forEach((child) => {
const childDataComponent = child.component.data;

// If child doesn't have its own data source, then merge
if (!childDataComponent.source) {
extend(colorRankComponent, childDataComponent.colorRank);
delete childDataComponent.colorRank;
}
});

return colorRankComponent;
}

export function assemble(component: DataComponent) {
return flatten(vals(component.colorRank));
}
Expand Down
33 changes: 26 additions & 7 deletions src/compile/data/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import {Formula} from '../../transform';
import {keys, Dict, StringSet} from '../../util';
import {VgData, VgTransform} from '../../vega.schema';

import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {Model} from './../model';
import {UnitModel} from './../unit';
import {FacetModel} from '../facet';
import {RepeatModel} from '../repeat';
import {LayerModel} from '../layer';
import {Model} from '../model';
import {UnitModel} from '../unit';

import {source} from './source';
import {formatParse} from './formatparse';
Expand Down Expand Up @@ -83,8 +84,8 @@ export function parseUnitData(model: UnitModel): DataComponent {
return {
formatParse: formatParse.parseUnit(model),
nullFilter: nullFilter.parseUnit(model),
filter: filter.parseUnit(model),
nonPositiveFilter: nonPositiveFilter.parseUnit(model),
filter: filter.parseUnit(model),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you swapping the order here? (Just curious why?)


source: source.parseUnit(model),
bin: bin.parseUnit(model),
Expand All @@ -101,8 +102,8 @@ export function parseFacetData(model: FacetModel): DataComponent {
return {
formatParse: formatParse.parseFacet(model),
nullFilter: nullFilter.parseFacet(model),
filter: filter.parseFacet(model),
nonPositiveFilter: nonPositiveFilter.parseFacet(model),
filter: filter.parseFacet(model),

source: source.parseFacet(model),
bin: bin.parseFacet(model),
Expand All @@ -119,10 +120,10 @@ export function parseLayerData(model: LayerModel): DataComponent {
return {
// filter and formatParse could cause us to not be able to merge into parent
// so let's parse them first
filter: filter.parseLayer(model),
formatParse: formatParse.parseLayer(model),
nullFilter: nullFilter.parseLayer(model),
nonPositiveFilter: nonPositiveFilter.parseLayer(model),
filter: filter.parseLayer(model),

// everything after here does not affect whether we can merge child data into parent or not
source: source.parseLayer(model),
Expand All @@ -136,6 +137,24 @@ export function parseLayerData(model: LayerModel): DataComponent {
};
}

export function parseRepeatData(model: RepeatModel): DataComponent {
return {
formatParse: formatParse.parseRepeat(model),
nullFilter: nullFilter.parseRepeat(model),
nonPositiveFilter: nonPositiveFilter.parseRepeat(model),
filter: filter.parseRepeat(model),

source: source.parseRepeat(model),
bin: bin.parseRepeat(model),
calculate: formula.parseRepeat(model),
timeUnit: timeUnit.parseRepeat(model),
timeUnitDomain: timeUnitDomain.parseRepeat(model),
summary: summary.parseRepeat(model),
stackScale: stackScale.parseRepeat(model),
colorRank: colorRank.parseRepeat(model)
};
}


/* tslint:enable:no-use-before-declare */

Expand Down
21 changes: 17 additions & 4 deletions src/compile/data/filter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {Model} from './../model';
import {FacetModel} from '../facet';
import {LayerModel} from '../layer';
import {RepeatModel} from '../repeat';
import {Model} from '../model';

import {DataComponent} from './data';

Expand Down Expand Up @@ -41,11 +42,23 @@ export namespace filter {
return filterComponent;
}

export function parseRepeat(model: RepeatModel) {
// Note that this `filter.parseLayer` method is called before `source.parseLayer`
let filterComponent = parse(model);
model.children().forEach((child) => {
const childDataComponent = child.component.data;
if (childDataComponent.filter) {
delete childDataComponent.filter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why always delete without even merging?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 018f662

}
});
return filterComponent;
}

export function assemble(component: DataComponent) {
const filter = component.filter;
return filter ? [{
type: 'filter',
test: filter
}] : [];
}
}
}
26 changes: 21 additions & 5 deletions src/compile/data/formatparse.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {FieldDef, isCount} from '../../fielddef';
import {Channel} from '../../channel';
import {QUANTITATIVE, TEMPORAL} from '../../type';
import {extend, differ, Dict} from '../../util';

import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {RepeatModel} from './../repeat';
import {Model} from './../model';

export namespace formatParse {
Expand All @@ -17,14 +19,15 @@ export namespace formatParse {
let parseComponent: Dict<string> = {};
// use forEach rather than reduce so that it can return undefined
// if there is no parse needed
model.forEach(function(fieldDef: FieldDef) {
model.forEach(function(fieldDef: FieldDef, channel: Channel) {
const field = model.fieldOrig(channel);
if (fieldDef.type === TEMPORAL) {
parseComponent[fieldDef.field] = 'date';
parseComponent[field] = 'date';
} else if (fieldDef.type === QUANTITATIVE) {
if (isCount(fieldDef) || calcFieldMap[fieldDef.field]) {
if (isCount(fieldDef) || calcFieldMap[field]) {
return;
}
parseComponent[fieldDef.field] = 'number';
parseComponent[field] = 'number';
}
});
return parseComponent;
Expand Down Expand Up @@ -58,5 +61,18 @@ export namespace formatParse {
return parseComponent;
}

export function parseRepeat(model: RepeatModel) {
let parseComponent = parse(model);
model.children().forEach((child) => {
const childDataComponent = child.component.data;
if (!differ(childDataComponent.formatParse, parseComponent)) {
// merge parse up if the child does not have an incompatible parse
extend(parseComponent, childDataComponent.formatParse);
delete childDataComponent.formatParse;
}
});
return parseComponent;
}

// Assemble for formatParse is an identity function, no need to declare
}
}
17 changes: 15 additions & 2 deletions src/compile/data/formula.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {extend, vals, hash, Dict} from '../../util';

import {FacetModel} from './../facet';
import {LayerModel} from './../layer';
import {RepeatModel} from './../repeat';
import {Model} from './../model';

import {DataComponent} from './data';
Expand Down Expand Up @@ -35,8 +36,20 @@ export namespace formula {
let formulaComponent = parse(model);
model.children().forEach((child) => {
const childDataComponent = child.component.data;
if (!childDataComponent.source && childDataComponent.calculate) {
extend(formulaComponent || {}, childDataComponent.calculate);
if (!childDataComponent.source) {
extend(formulaComponent, childDataComponent.calculate);
delete childDataComponent.calculate;
}
});
return formulaComponent;
}

export function parseRepeat(model: RepeatModel) {
let formulaComponent = parse(model);
model.children().forEach((child) => {
const childDataComponent = child.component.data;
if (!childDataComponent.source) {
extend(formulaComponent, childDataComponent.calculate);
delete childDataComponent.calculate;
}
});
Expand Down
Loading