Repository: vega/vega-lite
Pull request #624 (2015-10-07 20:02:55)

Correct refactor


Patch:
diff --git a/gallery/gallery.js b/gallery/gallery.js
index fa5ea6a71..bcd5c4199 100644
--- a/gallery/gallery.js
+++ b/gallery/gallery.js
@@ -74,22 +74,6 @@ var EXAMPLES = [
       },
       'data': {'url': 'data/barley.json'}
     }
-  },{
-    title: 'Grouped bar chart',
-    spec: {
-      marktype: 'bar',
-      encoding: {
-        x: {name: 'Origin', type: 'N'},
-        y: {name: 'Acceleration',type: 'Q', aggregate: 'mean'},
-        col: { axis: {maxLabelLength: 25}, name: 'Cylinders',type: 'O'},
-        color: {
-          scale: {quantitativeRange: ['#AFC6A3','#09622A']},
-          name: 'Origin',
-          type: 'N'
-        }
-      },
-      data: {url: 'data/cars.json'}
-    }
   },{
     title: 'Barleys',
     spec: {
diff --git a/package.json b/package.json
index 5da05fc0a..baef42ef0 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
     "release": "gulp release",
     "start": "gulp serve",
     "test": "gulp test",
-    "watch": "gulp bundle watch-schema watch-test"
+    "watch": "gulp watch-schema watch-test"
   },
   "repository": {
     "type": "git",
diff --git a/src/Encoding.js b/src/Encoding.js
index 0df50dd7f..d056b0062 100644
--- a/src/Encoding.js
+++ b/src/Encoding.js
@@ -4,7 +4,7 @@ require('./globals');
 
 var consts = require('./consts'),
   util = require('./util'),
-  vlfield = require('./field'),
+  vlEncDef = require('./encdef'),
   vlenc = require('./enc'),
   schema = require('./schema/schema');
 
@@ -94,7 +94,7 @@ module.exports = (function() {
     return this._enc[encType].name !== undefined;
   };
 
-  proto.field = function(et) {
+  proto.encDef = function(et) {
     return this._enc[et];
   };
 
@@ -105,11 +105,7 @@ module.exports = (function() {
   // get "field" reference for vega
   proto.fieldRef = function(et, opt) {
     opt = opt || {};
-    return vlfield.fieldRef(this._enc[et], opt);
-  };
-
-  proto.fieldName = function(et) {
-    return this._enc[et].name;
+    return vlEncDef.fieldRef(this._enc[et], opt);
   };
 
   /*
@@ -120,8 +116,8 @@ module.exports = (function() {
   };
 
   proto.fieldTitle = function(et) {
-    if (vlfield.isCount(this._enc[et])) {
-      return vlfield.count.displayName;
+    if (vlEncDef.isCount(this._enc[et])) {
+      return vlEncDef.count.displayName;
     }
     var fn = this._enc[et].aggregate || this._enc[et].timeUnit || (this._enc[et].bin && 'bin');
     if (fn) {
@@ -146,7 +142,7 @@ module.exports = (function() {
       (encType === X && this.has(COL) && this.has(X));
 
     // if band.size is explicitly specified, follow the specification, otherwise draw value from config.
-    return this.field(encType).band.size ||
+    return this.encDef(encType).band.size ||
       this.config(useSmallBand ? 'smallBandSize' : 'largeBandSize');
   };
 
@@ -179,7 +175,7 @@ module.exports = (function() {
   proto.sort = function(et, stats) {
     var sort = this._enc[et].sort,
       enc = this._enc,
-      isTypes = vlfield.isTypes;
+      isTypes = vlEncDef.isTypes;
 
     if ((!sort || sort.length===0) &&
         // FIXME
@@ -218,26 +214,26 @@ module.exports = (function() {
   };
 
   proto.isType = function(et, type) {
-    var field = this.field(et);
-    return field && vlfield.isType(field, type);
+    var encDef = this.encDef(et);
+    return encDef && vlEncDef.isType(encDef, type);
   };
 
 
   proto.isTypes = function(et, type) {
-    var field = this.field(et);
-    return field && vlfield.isTypes(field, type);
+    var encDef = this.encDef(et);
+    return encDef && vlEncDef.isTypes(encDef, type);
   };
 
   Encoding.isOrdinalScale = function(encoding, encType) {
-    return vlfield.isOrdinalScale(encoding.field(encType));
+    return vlEncDef.isOrdinalScale(encoding.encDef(encType));
   };
 
   Encoding.isDimension = function(encoding, encType) {
-    return vlfield.isDimension(encoding.field(encType));
+    return vlEncDef.isDimension(encoding.encDef(encType));
   };
 
   Encoding.isMeasure = function(encoding, encType) {
-    return vlfield.isMeasure(encoding.field(encType));
+    return vlEncDef.isMeasure(encoding.encDef(encType));
   };
 
   proto.isOrdinalScale = function(encType) {
@@ -301,7 +297,7 @@ module.exports = (function() {
   };
 
   proto.cardinality = function(encType, stats) {
-    return vlfield.cardinality(this.field(encType), stats, this.config('filterNull'));
+    return vlEncDef.cardinality(this.encDef(encType), stats, this.config('filterNull'));
   };
 
   proto.isRaw = function() {
@@ -354,7 +350,7 @@ module.exports = (function() {
 
   Encoding.toggleSort.support = function(spec, stats) {
     var enc = spec.encoding,
-      isTypes = vlfield.isTypes;
+      isTypes = vlEncDef.isTypes;
 
     if (vlenc.has(enc, ROW) || vlenc.has(enc, COL) ||
       !vlenc.has(enc, X) || !vlenc.has(enc, Y) ||
@@ -362,8 +358,8 @@ module.exports = (function() {
       return false;
     }
 
-    return ( isTypes(enc.x, [N,O]) && vlfield.isMeasure(enc.y)) ? 'x' :
-      ( isTypes(enc.y, [N,O]) && vlfield.isMeasure(enc.x)) ? 'y' : false;
+    return ( isTypes(enc.x, [N,O]) && vlEncDef.isMeasure(enc.y)) ? 'x' :
+      ( isTypes(enc.y, [N,O]) && vlEncDef.isMeasure(enc.x)) ? 'y' : false;
   };
 
   Encoding.toggleFilterNullO = function(spec) {
diff --git a/src/compiler/axis.js b/src/compiler/axis.js
index f542cec2a..66e6b0d21 100644
--- a/src/compiler/axis.js
+++ b/src/compiler/axis.js
@@ -18,7 +18,7 @@ axis.def = function(name, encoding, layout, stats, opt) {
     type: type,
     scale: name,
     properties: {},
-    layer: encoding.field(name).axis.layer,
+    layer: encoding.encDef(name).axis.layer,
     orient: axis.orient(name, encoding, stats)
   };
 
@@ -34,7 +34,7 @@ axis.def = function(name, encoding, layout, stats, opt) {
       // TODO(kanitw): Jul 19, 2015 - #506 add condition for rotation
       def = axis.labels.rotate(def);
     } else { // Q
-      def.ticks = encoding.field(name).axis.ticks;
+      def.ticks = encoding.encDef(name).axis.ticks;
     }
   }
 
@@ -54,7 +54,7 @@ axis.def = function(name, encoding, layout, stats, opt) {
 };
 
 axis.orient = function(name, encoding, stats) {
-  var orient = encoding.field(name).axis.orient;
+  var orient = encoding.encDef(name).axis.orient;
   if (orient) return orient;
 
   if (name === COL) return 'top';
@@ -127,7 +127,7 @@ axis.hideTicks = function(def) {
 };
 
 axis.title = function (def, name, encoding, layout) {
-  var ax = encoding.field(name).axis;
+  var ax = encoding.encDef(name).axis;
 
   if (ax.title) {
     def.title = ax.title;
@@ -164,7 +164,7 @@ axis.labels = {};
 /** add custom label for time type and bin */
 axis.labels.scale = function(def, encoding, name) {
   // time
-  var timeUnit = encoding.field(name).timeUnit;
+  var timeUnit = encoding.encDef(name).timeUnit;
   if (encoding.isType(name, T) && timeUnit && (time.hasScale(timeUnit))) {
     setter(def, ['properties','labels','text','scale'], 'time-'+ timeUnit);
   }
@@ -176,14 +176,14 @@ axis.labels.scale = function(def, encoding, name) {
  * Determine number format or truncate if maxLabel length is presented.
  */
 axis.labels.format = function (def, name, encoding, stats) {
-  var fieldStats = stats[encoding.field(name).name];
+  var fieldStats = stats[encoding.encDef(name).name];
 
   if (encoding.axis(name).format) {
     def.format = encoding.axis(name).format;
   } else if (encoding.isType(name, Q) || fieldStats.type === 'number') {
     def.format = encoding.numberFormat(fieldStats);
   } else if (encoding.isType(name, T)) {
-    var timeUnit = encoding.field(name).timeUnit;
+    var timeUnit = encoding.encDef(name).timeUnit;
     if (!timeUnit) {
       def.format = encoding.config('timeFormat');
     } else if (timeUnit === 'year') {
diff --git a/src/compiler/data.js b/src/compiler/data.js
index 928b4f195..51d65e2c9 100644
--- a/src/compiler/data.js
+++ b/src/compiler/data.js
@@ -4,7 +4,7 @@ require('../globals');
 
 module.exports = data;
 
-var vlfield = require('../field'),
+var vlEncDef = require('../encdef'),
   util = require('../util'),
   time = require('./time');
 
@@ -58,14 +58,14 @@ data.raw = function(encoding, stats) {
 data.raw.formatParse = function(encoding) {
   var parse;
 
-  encoding.forEach(function(field) {
-    if (field.type == T) {
+  encoding.forEach(function(encDef) {
+    if (encDef.type == T) {
       parse = parse || {};
-      parse[field.name] = 'date';
-    } else if (field.type == Q) {
-      if (vlfield.isCount(field)) return;
+      parse[encDef.name] = 'date';
+    } else if (encDef.type == Q) {
+      if (vlEncDef.isCount(encDef)) return;
       parse = parse || {};
-      parse[field.name] = 'number';
+      parse[encDef.name] = 'number';
     }
   });
 
@@ -88,14 +88,14 @@ data.raw.transform = function(encoding, stats) {
 };
 
 data.raw.transform.time = function(encoding) {
-  return encoding.reduce(function(transform, field, encType) {
-    if (field.type === T && field.timeUnit) {
+  return encoding.reduce(function(transform, encDef, encType) {
+    if (encDef.type === T && encDef.timeUnit) {
       var fieldRef = encoding.fieldRef(encType, {nofn: true, datum: true});
 
       transform.push({
         type: 'formula',
         field: encoding.fieldRef(encType),
-        expr: time.formula(field.timeUnit, fieldRef)
+        expr: time.formula(encDef.timeUnit, fieldRef)
       });
     }
     return transform;
@@ -104,15 +104,15 @@ data.raw.transform.time = function(encoding) {
 
 // FIXME(#514): eliminate stats
 data.raw.transform.bin = function(encoding, stats) {
-  return encoding.reduce(function(transform, field, encType) {
+  return encoding.reduce(function(transform, encDef, encType) {
     if (encoding.bin(encType)) {
       transform.push({
         type: 'bin',
-        field: field.name,
+        field: encDef.name,
         output: {bin: encoding.fieldRef(encType)},
         maxbins: encoding.bin(encType).maxbins,
-        min: stats[field.name].min,
-        max: stats[field.name].max
+        min: stats[encDef.name].min,
+        max: stats[encDef.name].max
       });
     }
     return transform;
@@ -163,18 +163,18 @@ data.aggregate = function(encoding) {
 
   var hasAggregate = false;
 
-  encoding.forEach(function(field, encType) {
-    if (field.aggregate) {
+  encoding.forEach(function(encDef, encType) {
+    if (encDef.aggregate) {
       hasAggregate = true;
-      if (field.aggregate === 'count') {
+      if (encDef.aggregate === 'count') {
         meas['*'] = meas['*'] || {};
         meas['*'].count = true;
       } else {
-        meas[field.name] = meas[field.name] || {};
-        meas[field.name][field.aggregate] = true;
+        meas[encDef.name] = meas[encDef.name] || {};
+        meas[encDef.name][encDef.aggregate] = true;
       }
     } else {
-      dims[field.name] = encoding.fieldRef(encType);
+      dims[encDef.name] = encoding.fieldRef(encType);
     }
   });
 
@@ -182,8 +182,8 @@ data.aggregate = function(encoding) {
 
   // short-format summarize object for Vega's aggregate transform
   // https://github.com/vega/vega/wiki/Data-Transforms#-aggregate
-  var summarize = util.reduce(meas, function(summarize, fnDictSet, fieldName) {
-    summarize[fieldName] = util.keys(fnDictSet);
+  var summarize = util.reduce(meas, function(summarize, fnDictSet, field) {
+    summarize[field] = util.keys(fnDictSet);
     return summarize;
   }, {});
 
@@ -203,7 +203,7 @@ data.aggregate = function(encoding) {
 };
 
 data.filterNonPositive = function(dataTable, encoding) {
-  encoding.forEach(function(field, encType) {
+  encoding.forEach(function(encDef, encType) {
     if (encoding.scale(encType).type === 'log') {
       dataTable.transform.push({
         type: 'filter',
diff --git a/src/compiler/facet.js b/src/compiler/facet.js
index 2a2d7d6bd..249ba15d3 100644
--- a/src/compiler/facet.js
+++ b/src/compiler/facet.js
@@ -54,7 +54,7 @@ function faceting(group, encoding, layout, spec, singleScaleNames, stack, stats)
     if (!encoding.isDimension(ROW)) {
       util.error('Row encoding should be ordinal.');
     }
-    enter.y = {scale: ROW, field: encoding.fieldName(ROW)};
+    enter.y = {scale: ROW, field: encoding.encDef(ROW).name};
     enter.height = {'value': layout.cellHeight}; // HACK
 
     facetKeys.push(encoding.fieldRef(ROW));
@@ -86,7 +86,7 @@ function faceting(group, encoding, layout, spec, singleScaleNames, stack, stats)
     if (!encoding.isDimension(COL)) {
       util.error('Col encoding should be ordinal.');
     }
-    enter.x = {scale: COL, field: encoding.fieldName(COL)};
+    enter.x = {scale: COL, field: encoding.encDef(COL).name};
     enter.width = {'value': layout.cellWidth}; // HACK
 
     facetKeys.push(encoding.fieldRef(COL));
diff --git a/src/compiler/layout.js b/src/compiler/layout.js
index 8290c0044..e57858ce6 100644
--- a/src/compiler/layout.js
+++ b/src/compiler/layout.js
@@ -41,9 +41,9 @@ function box(encoding, stats) {
   if (hasX) {
     if (encoding.isOrdinalScale(X)) {
       // for ordinal, hasCol or not doesn't matter -- we scale based on cardinality
-      cellWidth = (xCardinality + encoding.field(X).band.padding) * encoding.bandSize(X, useSmallBand);
+      cellWidth = (xCardinality + encoding.encDef(X).band.padding) * encoding.bandSize(X, useSmallBand);
     } else {
-      cellWidth = hasCol || hasRow ? encoding.field(COL).width :  encoding.config('singleWidth');
+      cellWidth = hasCol || hasRow ? encoding.encDef(COL).width :  encoding.config('singleWidth');
     }
   } else {
     if (marktype === TEXT) {
@@ -57,9 +57,9 @@ function box(encoding, stats) {
   if (hasY) {
     if (encoding.isOrdinalScale(Y)) {
       // for ordinal, hasCol or not doesn't matter -- we scale based on cardinality
-      cellHeight = (yCardinality + encoding.field(Y).band.padding) * encoding.bandSize(Y, useSmallBand);
+      cellHeight = (yCardinality + encoding.encDef(Y).band.padding) * encoding.bandSize(Y, useSmallBand);
     } else {
-      cellHeight = hasCol || hasRow ? encoding.field(ROW).height :  encoding.config('singleHeight');
+      cellHeight = hasCol || hasRow ? encoding.encDef(ROW).height :  encoding.config('singleHeight');
     }
   } else {
     cellHeight = encoding.bandSize(Y);
@@ -101,16 +101,16 @@ function getMaxNumberLength(encoding, et, fieldStats) {
 
 // TODO(#600) revise this
 function getMaxLength(encoding, stats, et) {
-  var field = encoding.field(et),
-    fieldStats = stats[field.name];
+  var encDef = encoding.encDef(et),
+    fieldStats = stats[encDef.name];
 
-  if (field.bin) {
+  if (encDef.bin) {
     // TODO once bin support range, need to update this
     return getMaxNumberLength(encoding, et, fieldStats);
   } if (encoding.isType(et, Q)) {
     return getMaxNumberLength(encoding, et, fieldStats);
   } else if (encoding.isType(et, T)) {
-    return time.maxLength(encoding.field(et).timeUnit, encoding);
+    return time.maxLength(encoding.encDef(et).timeUnit, encoding);
   } else if (encoding.isTypes(et, [N, O])) {
     if(fieldStats.type === 'number') {
       return getMaxNumberLength(encoding, et, fieldStats);
diff --git a/src/compiler/legend.js b/src/compiler/legend.js
index 2443d5a59..4eb5c6315 100644
--- a/src/compiler/legend.js
+++ b/src/compiler/legend.js
@@ -12,19 +12,19 @@ var legend = module.exports = {};
 legend.defs = function(encoding, style) {
   var defs = [];
 
-  if (encoding.has(COLOR) && encoding.field(COLOR).legend) {
+  if (encoding.has(COLOR) && encoding.encDef(COLOR).legend) {
     defs.push(legend.def(COLOR, encoding, {
       fill: COLOR
     }, style));
   }
 
-  if (encoding.has(SIZE) && encoding.field(SIZE).legend) {
+  if (encoding.has(SIZE) && encoding.encDef(SIZE).legend) {
     defs.push(legend.def(SIZE, encoding, {
       size: SIZE
     }, style));
   }
 
-  if (encoding.has(SHAPE) && encoding.field(SHAPE).legend) {
+  if (encoding.has(SHAPE) && encoding.encDef(SHAPE).legend) {
     defs.push(legend.def(SHAPE, encoding, {
       shape: SHAPE
     }, style));
@@ -33,10 +33,10 @@ legend.defs = function(encoding, style) {
 };
 
 legend.def = function(name, encoding, def, style) {
-  var timeUnit = encoding.field(name).timeUnit;
+  var timeUnit = encoding.encDef(name).timeUnit;
 
   def.title = legend.title(name, encoding);
-  def.orient = encoding.field(name).legend.orient;
+  def.orient = encoding.encDef(name).legend.orient;
 
   def = legend.style(name, encoding, def, style);
 
@@ -68,7 +68,7 @@ legend.style = function(name, e, def, style) {
       /* fall through */
     case 'point':
       // fill or stroke
-      if (e.field(SHAPE).filled) {
+      if (e.encDef(SHAPE).filled) {
         if (e.has(COLOR) && name === COLOR) {
           symbols.fill = {scale: COLOR, field: 'data'};
         } else {
@@ -92,7 +92,7 @@ legend.style = function(name, e, def, style) {
       break;
   }
 
-  var opacity = e.field(COLOR).opacity || style.opacity;
+  var opacity = e.encDef(COLOR).opacity || style.opacity;
   if (opacity) {
     symbols.opacity = {value: opacity};
   }
@@ -100,7 +100,7 @@ legend.style = function(name, e, def, style) {
 };
 
 legend.title = function(name, encoding) {
-  var leg = encoding.field(name).legend;
+  var leg = encoding.encDef(name).legend;
 
   if (leg.title) return leg.title;
 
diff --git a/src/compiler/marks.js b/src/compiler/marks.js
index f6b97c1eb..55fe2f140 100644
--- a/src/compiler/marks.js
+++ b/src/compiler/marks.js
@@ -159,7 +159,7 @@ function bar_props(e, layout, style) {
   }
 
   // opacity
-  var opacity = e.field(COLOR).opacity;
+  var opacity = e.encDef(COLOR).opacity;
   if (opacity) p.opacity = {value: opacity};
 
   return p;
@@ -197,7 +197,7 @@ function point_props(e, layout, style) {
   }
 
   // fill or stroke
-  if (e.field(SHAPE).filled) {
+  if (e.encDef(SHAPE).filled) {
     if (e.has(COLOR)) {
       p.fill = {scale: COLOR, field: e.fieldRef(COLOR)};
     } else if (!e.has(COLOR)) {
@@ -213,7 +213,7 @@ function point_props(e, layout, style) {
   }
 
   // opacity
-  var opacity = e.field(COLOR).opacity || style.opacity;
+  var opacity = e.encDef(COLOR).opacity || style.opacity;
   if (opacity) p.opacity = {value: opacity};
 
   return p;
@@ -244,7 +244,7 @@ function line_props(e,layout, style) {
     p.stroke = {value: e.value(COLOR)};
   }
 
-  var opacity = e.field(COLOR).opacity;
+  var opacity = e.encDef(COLOR).opacity;
   if (opacity) p.opacity = {value: opacity};
 
   p.strokeWidth = {value: e.config('strokeWidth')};
@@ -286,7 +286,7 @@ function area_props(e, layout, style) {
     p.fill = {value: e.value(COLOR)};
   }
 
-  var opacity = e.field(COLOR).opacity;
+  var opacity = e.encDef(COLOR).opacity;
   if (opacity) p.opacity = {value: opacity};
 
   return p;
@@ -336,7 +336,7 @@ function tick_props(e, layout, style) {
     p.fill = {value: e.value(COLOR)};
   }
 
-  var opacity = e.field(COLOR).opacity  || style.opacity;
+  var opacity = e.encDef(COLOR).opacity  || style.opacity;
   if(opacity) p.opacity = {value: opacity};
 
   return p;
@@ -377,7 +377,7 @@ function filled_point_props(shape) {
       p.fill = {value: e.value(COLOR)};
     }
 
-    var opacity = e.field(COLOR).opacity  || style.opacity;
+    var opacity = e.encDef(COLOR).opacity  || style.opacity;
     if(opacity) p.opacity = {value: opacity};
 
     return p;
@@ -386,7 +386,7 @@ function filled_point_props(shape) {
 
 function text_props(e, layout, style, stats) {
   var p = {},
-    field = e.field(TEXT);
+    encDef = e.encDef(TEXT);
 
   // x
   if (e.has(X)) {
@@ -410,36 +410,36 @@ function text_props(e, layout, style, stats) {
   if (e.has(SIZE)) {
     p.fontSize = {scale: SIZE, field: e.fieldRef(SIZE)};
   } else if (!e.has(SIZE)) {
-    p.fontSize = {value: field.font.size};
+    p.fontSize = {value: encDef.font.size};
   }
 
   // fill
   // color should be set to background
-  p.fill = {value: field.color};
+  p.fill = {value: encDef.color};
 
-  var opacity = e.field(COLOR).opacity  || style.opacity;
+  var opacity = e.encDef(COLOR).opacity  || style.opacity;
   if(opacity) p.opacity = {value: opacity};
 
   // text
   if (e.has(TEXT)) {
     if (e.isType(TEXT, Q)) {
-      var fieldStats = stats[e.fieldName(TEXT)],
-        numberFormat = field.format || e.numberFormat(fieldStats);
+      var fieldStats = stats[e.encDef(TEXT).name],
+        numberFormat = encDef.format || e.numberFormat(fieldStats);
 
       p.text = {template: '{{' + e.fieldRef(TEXT) + ' | number:\'' +
         numberFormat +'\'}}'};
-      p.align = {value: field.align};
+      p.align = {value: encDef.align};
     } else {
       p.text = {field: e.fieldRef(TEXT)};
     }
   } else {
-    p.text = {value: field.placeholder};
+    p.text = {value: encDef.placeholder};
   }
 
-  p.font = {value: field.font.family};
-  p.fontWeight = {value: field.font.weight};
-  p.fontStyle = {value: field.font.style};
-  p.baseline = {value: field.baseline};
+  p.font = {value: encDef.font.family};
+  p.fontWeight = {value: encDef.font.weight};
+  p.fontStyle = {value: encDef.font.style};
+  p.baseline = {value: encDef.baseline};
 
   return p;
 }
diff --git a/src/compiler/scale.js b/src/compiler/scale.js
index 359d8f38f..4c66a8e3d 100644
--- a/src/compiler/scale.js
+++ b/src/compiler/scale.js
@@ -37,7 +37,7 @@ scale.type = function(name, encoding) {
     case N: //fall through
     case O: return 'ordinal';
     case T:
-      var timeUnit = encoding.field(name).timeUnit;
+      var timeUnit = encoding.encDef(name).timeUnit;
       return timeUnit ? time.scale.type(timeUnit, name) : 'time';
     case Q:
       if (encoding.bin(name)) {
@@ -53,20 +53,20 @@ scale.domain = function (scaleDef, encoding, stats, opt) {
 
   var name = scaleDef.name;
 
-  var field = encoding.field(name);
+  var encDef = encoding.encDef(name);
 
   // special case for temporal scale
   if (encoding.isType(name, T)) {
-    var range = time.scale.domain(field.timeUnit, name);
+    var range = time.scale.domain(encDef.timeUnit, name);
     if (range) return range;
   }
 
   // For binned, produce fixed stepped domain.
   // TODO(#614): this must be changed in vg2
-  if (field.bin) {
+  if (encDef.bin) {
 
-    var fieldStat = stats[field.name],
-      bins = util.getbins(fieldStat, field.bin.maxbins || schema.MAXBINS_DEFAULT),
+    var fieldStat = stats[encDef.name],
+      bins = util.getbins(fieldStat, encDef.bin.maxbins || schema.MAXBINS_DEFAULT),
       numbins = (bins.stop - bins.start) / bins.step;
     return util.range(numbins).map(function(i) {
       return bins.start + bins.step * i;
@@ -85,7 +85,7 @@ scale.domain = function (scaleDef, encoding, stats, opt) {
   }
 
   var aggregate = encoding.aggregate(name),
-    timeUnit = field.timeUnit;
+    timeUnit = encDef.timeUnit;
 
   // determine useRawDomain value
   var scaleUseRawDomain = encoding.scale(name).useRawDomain,
@@ -96,7 +96,7 @@ scale.domain = function (scaleDef, encoding, stats, opt) {
   var dataTable = encoding.dataTable();
   if ( useRawDomain && notCountOrSum && (
       // Q always uses non-ordinal scale except when it's binned and thus uses ordinal scale.
-      (encoding.isType(name, Q) && !field.bin) ||
+      (encoding.isType(name, Q) && !encDef.bin) ||
       // T uses non-ordinal scale when there's no unit or when the unit is not ordinal.
       (encoding.isType(name, T) && (!timeUnit || !time.isOrdinalFn(timeUnit)))
     )
@@ -119,8 +119,8 @@ scale.domain = function (scaleDef, encoding, stats, opt) {
 
 scale.range = function (scaleDef, encoding, layout, stats) {
   var spec = encoding.scale(scaleDef.name),
-    field = encoding.field(scaleDef.name),
-    timeUnit = field.timeUnit;
+    encDef = encoding.encDef(scaleDef.name),
+    timeUnit = encDef.timeUnit;
 
   switch (scaleDef.name) {
     case X:
@@ -146,7 +146,7 @@ scale.range = function (scaleDef, encoding, layout, stats) {
     case Y:
       if (scaleDef.type === 'ordinal') {
         scaleDef.range = layout.cellHeight ?
-          (field.bin ? [layout.cellHeight, 0] : [0, layout.cellHeight]) :
+          (encDef.bin ? [layout.cellHeight, 0] : [0, layout.cellHeight]) :
           'height';
         scaleDef.bandWidth = encoding.bandSize(Y, layout.y.useSmallBand);
       } else {
@@ -214,7 +214,7 @@ scale.range = function (scaleDef, encoding, layout, stats) {
     case Y:
       if (scaleDef.type === 'ordinal') { //&& !s.bandWidth
         scaleDef.points = true;
-        scaleDef.padding = encoding.field(scaleDef.name).band.padding;
+        scaleDef.padding = encoding.encDef(scaleDef.name).band.padding;
       }
   }
 
diff --git a/src/compiler/stack.js b/src/compiler/stack.js
index a577406e1..c6d7cfb36 100644
--- a/src/compiler/stack.js
+++ b/src/compiler/stack.js
@@ -46,14 +46,14 @@ function stacking(data, encoding, mdef) {
       groupby: facets,
       summarize: [{
         ops: ['max'],
-        field: encoding.fieldName(val, {fn: 'sum'})
+        field: encoding.fieldRef(val, {prefn: 'sum_'})
       }]
     });
   }
 
   data.push(stacked);
 
-  var valName = encoding.fieldName(val);
+  var valName = encoding.encDef(val).name;
   var startField = valName + '_start';
   var endField = valName + '_end';
 
diff --git a/src/compiler/style.js b/src/compiler/style.js
index 28d54128b..e4d699c9c 100644
--- a/src/compiler/style.js
+++ b/src/compiler/style.js
@@ -2,7 +2,7 @@
 
 require('../globals');
 
-var vlfield = require('../field');
+var vlEncDef = require('../encdef');
 
 module.exports = function(encoding, stats) {
   return {
@@ -25,11 +25,11 @@ function estimateOpacity(encoding,stats) {
     //  for each non faceting and non-ordinal X / Y fields
     //  note that ordinal x,y are not include since we can
     //  consider that ordinal x are subdividing the cell into subcells anyway
-    encoding.forEach(function(field, encType) {
+    encoding.forEach(function(encDef, encType) {
 
       if (encType !== ROW && encType !== COL &&
           !((encType === X || encType === Y) &&
-          vlfield.isOrdinalScale(field))
+          vlEncDef.isOrdinalScale(encDef))
         ) {
         numPoints *= encoding.cardinality(encType, stats);
       }
diff --git a/src/compiler/time.js b/src/compiler/time.js
index f0d2d4936..ebd840359 100644
--- a/src/compiler/time.js
+++ b/src/compiler/time.js
@@ -10,8 +10,8 @@ var time = module.exports = {};
 // September is the longest month (8 in javascript as it is zero-indexed).
 var LONG_DATE = new Date(Date.UTC(2014, 8, 17));
 
-time.cardinality = function(field, stats, filterNull, type) {
-  var timeUnit = field.timeUnit;
+time.cardinality = function(encDef, stats, filterNull, type) {
+  var timeUnit = encDef.timeUnit;
   switch (timeUnit) {
     case 'seconds': return 60;
     case 'minutes': return 60;
@@ -20,8 +20,8 @@ time.cardinality = function(field, stats, filterNull, type) {
     case 'date': return 31;
     case 'month': return 12;
     case 'year':
-      var stat = stats[field.name],
-        yearstat = stats['year_'+field.name];
+      var stat = stats[encDef.name],
+        yearstat = stats['year_' + encDef.name];
 
       if (!yearstat) { return null; }
 
@@ -87,10 +87,10 @@ time.range = function(timeUnit, encoding) {
  * @return {Array}  scales for time unit names
  */
 time.scales = function(encoding) {
-  var scales = encoding.reduce(function(scales, field) {
-    var timeUnit = field.timeUnit;
-    if (field.type === T && timeUnit && !scales[timeUnit]) {
-      var scale = time.scale.def(field.timeUnit, encoding);
+  var scales = encoding.reduce(function(scales, encDef) {
+    var timeUnit = encDef.timeUnit;
+    if (encDef.type === T && timeUnit && !scales[timeUnit]) {
+      var scale = time.scale.def(encDef.timeUnit, encoding);
       if (scale) scales[timeUnit] = scale;
     }
     return scales;
diff --git a/src/enc.js b/src/enc.js
index f8ab8ea8f..ac68b3afc 100644
--- a/src/enc.js
+++ b/src/enc.js
@@ -4,7 +4,7 @@
 
 var consts = require('./consts'),
   c = consts.shorthand,
-  vlfield = require('./field'),
+  vlEncDef = require('./encdef'),
   util = require('./util'),
   schema = require('./schema/schema'),
   encTypes = schema.encTypes;
@@ -81,7 +81,7 @@ vlenc.fields = function(enc) {
 
 vlenc.shorthand = function(enc) {
   return vlenc.map(enc, function(field, et) {
-    return et + c.assign + vlfield.shorthand(field);
+    return et + c.assign + vlEncDef.shorthand(field);
   }).join(c.delim);
 };
 
@@ -92,7 +92,7 @@ vlenc.fromShorthand = function(shorthand) {
         enctype = split[0].trim(),
         field = split[1];
 
-    m[enctype] = vlfield.fromShorthand(field);
+    m[enctype] = vlEncDef.fromShorthand(field);
     return m;
   }, {});
 };
diff --git a/src/field.js b/src/encdef.js
similarity index 100%
rename from src/field.js
rename to src/encdef.js
diff --git a/src/vl.js b/src/vl.js
index 020008705..f1aba3556 100644
--- a/src/vl.js
+++ b/src/vl.js
@@ -14,7 +14,7 @@ vl.compiler = require('./compiler/compiler');
 vl.compile = vl.compiler.compile;
 vl.data = require('./data');
 vl.enc = require('./enc');
-vl.field = require('./field');
+vl.encDef = require('./encdef');
 vl.schema = require('./schema/schema');
 vl.toShorthand = vl.Encoding.shorthand;
 vl.format = require('d3-format').format;


Test patch:
diff --git a/test/field.spec.js b/test/field.spec.js
index 8804ddc4f..15f928f82 100644
--- a/test/field.spec.js
+++ b/test/field.spec.js
@@ -3,23 +3,23 @@
 require('../src/globals');
 
 var expect = require('chai').expect;
-var vlfield = require('../src/field');
+var vlEncDef = require('../src/encdef');
 
 describe('vl.field.cardinality()', function () {
   describe('for Q', function () {
     it('should return cardinality', function() {
-      var field = {name:2, type:'Q'};
+      var encDef = {name:2, type:'Q'};
       var stats = {2:{distinct: 10, min:0, max:150}};
-      var cardinality = vlfield.cardinality(field, stats);
+      var cardinality = vlEncDef.cardinality(encDef, stats);
       expect(cardinality).to.equal(10);
     });
   });
 
   describe('for B(Q)', function(){
     it('should return cardinality', function() {
-      var field = {name:2, type:'Q', bin: {maxbins: 15}};
+      var encDef = {name:2, type:'Q', bin: {maxbins: 15}};
       var stats = {2:{distinct: 10, min:0, max:150}};
-      var cardinality = vlfield.cardinality(field, stats);
+      var cardinality = vlEncDef.cardinality(encDef, stats);
       expect(cardinality).to.equal(15);
     });
   });
@@ -27,20 +27,20 @@ describe('vl.field.cardinality()', function () {
 
 describe('vl.field.isType', function () {
   it('should return correct type checking', function() {
-    var qField = {name: 'number', type:'Q'};
-    expect(vlfield.isType(qField, Q)).to.eql(true);
-    expect(vlfield.isTypes(qField, N)).to.eql(false);
+    var qDef = {name: 'number', type:'Q'};
+    expect(vlEncDef.isType(qDef, Q)).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, N)).to.eql(false);
   });
 });
 
 describe('vl.field.isTypes', function () {
   it('should return correct type checking', function() {
-    var qField = {name: 'number', type:'Q'};
-    expect(vlfield.isType(qField, Q)).to.eql(true);
-    expect(vlfield.isTypes(qField, [Q])).to.eql(true);
-    expect(vlfield.isTypes(qField, [Q, O])).to.eql(true);
-    expect(vlfield.isTypes(qField, [O, Q])).to.eql(true);
-    expect(vlfield.isTypes(qField, [Q, N])).to.eql(true);
-    expect(vlfield.isTypes(qField, [N])).to.eql(false);
+    var qDef = {name: 'number', type:'Q'};
+    expect(vlEncDef.isType(qDef, Q)).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, [Q])).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, [Q, O])).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, [O, Q])).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, [Q, N])).to.eql(true);
+    expect(vlEncDef.isTypes(qDef, [N])).to.eql(false);
   });
 });
\ No newline at end of file