code: function buildLayoutGraph(inputGraph) {
    var g = new Graph({ multigraph: true, compound: true });
    var graph = canonicalize(inputGraph.graph());
  
    g.setGraph(_.merge({},
      graphDefaults,
      selectNumberAttrs(graph, graphNumAttrs),
      _.pick(graph, graphAttrs)));
  
    _.forEach(inputGraph.nodes(), function(v) {
      var node = canonicalize(inputGraph.node(v));
      g.setNode(v, _.defaults(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults));
      g.setParent(v, inputGraph.parent(v));
    });
  
    _.forEach(inputGraph.edges(), function(e) {
      var edge = canonicalize(inputGraph.edge(e));
      g.setEdge(e, _.merge({},
        edgeDefaults,
        selectNumberAttrs(edge, edgeNumAttrs),
        _.pick(edge, edgeAttrs)));
    });
  
    return g;
  }
docs: /*
  Constructs a new graph from the input graph, which can be used for layout.
  This process copies only whitelisted attributes from the input graph to the
  layout graph. Thus this function serves as a good place to determine what
  attributes can influence layout.