private boolean allShowExtent(Field[] fields) {
   // Categorical and numeric fields both show elements as extents on the axis
   for (Field field : fields) {
     if (field.isNumeric() && !field.isBinned()) return false;
   }
   return true;
 }
  private void setLocations(
      ElementDefinition.ElementDimensionDefinition dim,
      String dimName,
      Field[] fields,
      boolean categorical) {
    String scaleName = "scale_" + dimName;

    if (fields.length == 0) {
      // There are no fields -- we have a notional [0,1] extent, so use the center of that
      dim.center = "function() { return " + scaleName + "(0.5) }";
      dim.left = "function() { return " + scaleName + "(0) }";
      dim.right = "function() { return " + scaleName + "(1) }";
    } else if (fields.length == 1) {
      Field field = fields[0]; // The single field
      String dataFunction = D3Util.writeCall(field); // A call to that field using the datum 'd'

      if (isRange(field)) {
        // This is a range field, but we have not been asked to show both ends,
        // so we use the difference between the top and bottom
        dim.center = "function(d) { return " + scaleName + "(" + dataFunction + ".extent()) }";
        // Left and Right are not defined
      } else if (field.isBinned() && !categorical) {
        // A Binned value on a non-categorical axes
        dim.center = "function(d) { return " + scaleName + "(" + dataFunction + ".mid) }";
        dim.left = "function(d) { return " + scaleName + "(" + dataFunction + ".low) }";
        dim.right = "function(d) { return " + scaleName + "(" + dataFunction + ".high) }";

      } else {
        // Nothing unusual -- just define the center
        dim.center = "function(d) { return " + scaleName + "(" + dataFunction + ") }";
      }
    } else {
      // The dimension contains two fields: a range
      String lowDataFunc =
          D3Util.writeCall(fields[0]); // A call to the low field using the datum 'd'
      String highDataFunc =
          D3Util.writeCall(fields[1]); // A call to the high field using the datum 'd'

      // When one of the fields is a range, use the outermost value of that
      if (isRange(fields[0])) lowDataFunc += ".low";
      if (isRange(fields[1])) highDataFunc += ".high";

      dim.left = "function(d) { return " + scaleName + "(" + lowDataFunc + ") }";
      dim.right = "function(d) { return " + scaleName + "(" + highDataFunc + ") }";
      dim.center =
          "function(d) { return "
              + scaleName
              + "( ("
              + highDataFunc
              + " + "
              + lowDataFunc
              + " )/2) }";
    }
  }