in packages/sanddance-specs/src/specBuilder.ts [109:273]
public build(): SpecResult {
const { specContext } = this;
const { facetLayout, specCapabilities } = this.props;
const { insight, specColumns, specViewOptions } = specContext;
const dataName = 'data_source';
const { vegaSpec, groupMark } = this.initSpec(dataName);
const { topColorField, colorDataName } = addColor({
scope: vegaSpec,
dataName,
specContext,
scaleName: ScaleNames.Color,
legendDataName: 'data_legend',
topLookupName: 'data_topcolorlookup',
colorReverseSignalName: SignalNames.ColorReverse
});
const globalScope = new GlobalScope({
dataName: colorDataName,
markGroup: groupMark,
scope: vegaSpec,
signals: this.globalSignals
});
if (facetLayout) {
addSignals(vegaSpec,
{
name: SignalNames.FacetPaddingBottom,
update: `${facetLayout.facetPadding.bottom}`
},
{
name: SignalNames.FacetPaddingLeft,
update: `${facetLayout.facetPadding.left}`
},
{
name: SignalNames.FacetPaddingTop,
update: `${facetLayout.facetPadding.top}`
}
);
this.globalSignals.plotOffsetTop.update = `${facetLayout.plotPadding.y}`;
this.globalSignals.plotOffsetRight.update = `${facetLayout.plotPadding.x}`;
}
const {
firstScope,
finalScope,
specResult,
allGlobalScales,
allEncodingRules
} = this.iterateLayouts(globalScope, (i, innerScope) => {
if (facetLayout && i === 0) {
globalScope.zSize = innerScope.offsets.h;
}
});
if (specResult) {
return specResult;
}
if (allGlobalScales.length > 0) {
const plotHeightOut = this.globalSignals.plotHeightOut.name;
const plotWidthOut = this.globalSignals.plotWidthOut.name;
const colTitleScale: LinearScale = {
type: 'linear',
name: 'scale_facet_col_title',
domain: [0, 1],
range: [0, { signal: plotWidthOut }]
};
const rowTitleScale: LinearScale = {
type: 'linear',
name: 'scale_facet_row_title',
domain: [0, 1],
range: [{ signal: plotHeightOut }, 0]
};
let axesScopes: AxesScopeMap = facetLayout ?
addFacetAxesGroupMarks({
globalScope: globalScope.scope,
plotScope: groupMark,
facetScope: firstScope,
colTitleScale,
rowTitleScale,
colSeqName: 'data_FacetCellColTitles',
rowSeqName: 'data_FacetCellRowTitles'
})
:
{
main: [{
scope: groupMark,
lines: true,
labels: true,
title: true
}]
};
addGlobalAxes({
globalScope,
allGlobalScales,
axisScales: this.props.axisScales,
plotOffsetSignals: { x: this.globalSignals.plotOffsetLeft, y: this.globalSignals.plotOffsetBottom },
axesOffsets: { x: axesOffsetX, y: axesOffsetY },
axesTitlePadding: facetLayout ? { x: axesTitlePaddingFacetX, y: axesTitlePaddingFacetY } : { x: axesTitlePaddingX, y: axesTitlePaddingY },
labelBaseline: { x: 'top', y: 'middle' },
specColumns,
specViewOptions,
axesScopes,
faceted: !!facetLayout,
view: insight.view
});
}
//add mark to the final scope
if (finalScope.mark) {
const { update } = finalScope.mark.encode;
const outputDataName = 'output';
finalScope.mark.from.data = outputDataName;
addData(globalScope.markGroup,
{
name: outputDataName,
source: globalScope.markDataName,
transform: [
{
type: 'formula',
expr: finalScope.offsets.x,
as: FieldNames.OffsetX
},
{
type: 'formula',
expr: finalScope.offsets.y,
as: FieldNames.OffsetY
}
]
}
);
update.x = {
field: FieldNames.OffsetX
};
update.y = {
field: FieldNames.OffsetY
};
allEncodingRules.forEach(map => {
for (let key in map) {
if (update[key]) {
let arrIn = map[key];
if (!Array.isArray(update[key])) {
let value = update[key];
let arrOut = [];
update[key] = arrOut;
arrIn.forEach(rule => arrOut.push(rule));
arrOut.push(value);
} else {
let arrOut = update[key] as {}[];
arrIn.forEach(rule => arrOut.unshift(rule));
}
}
}
});
update.fill = fill(specContext, topColorField, ScaleNames.Color);
update.opacity = opacity(specContext);
}
return {
specCapabilities,
vegaSpec
};
}