ERM with Dagre

Rendering ERM with Dagre-D3

HTML

<script src="//cpettitt.github.io/project/dagre-d3/latest/dagre-d3.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<body>
<div class="background"></div>
<div class="container">
<svg></svg>
</div>

CSS

div.container {
            /*font-family: "Courier New", Courier, monospace;*/
            font-family: "Helvetic Neue", Helvetica, Arial, sans-serif;
            font-size: small;
        }
        .node rect,
        .node circle,
        .node ellipse {
            stroke: #333;
            opacity: 0.8;
            fill-opacity: 0;
        }

        .edgePath path {
            stroke: #333;
            fill: #333;
            fill-opacity: 1;
            stroke-opacity: 1;
        }

        .cluster {
            stroke: #999;
            /*fill: #222;*/
            fill-opacity: 0;
            stroke-opacity: 0.6;
        }

        .entity-name rect {

            fill: #222;
            fill-opacity: 0.3;
        }

JavaScript

var width = window.innerWidth,
        initialHeight = window.innerHeight,

        svg = d3.select("body div.container svg"),
        inner = svg.append("g");

    svg
            .attr('width', width)
            .attr('height', initialHeight);

    // Set up zoom support
    var zoom = d3.behavior.zoom().on("zoom", function() {
        inner.attr("transform", "translate(" + d3.event.translate + ")" +
        "scale(" + d3.event.scale + ")");
    });
    svg.call(zoom);

    // create graph
    var g = new dagreD3.graphlib.Graph({
        multigraph: false,
        compound: true
    }).setGraph({
        rankdir: "LR",
        edgesep: 25,
        nodesep: 0
    });

    // customer entity
    g.setNode('customer',       {label:'customer', class: 'entity-name', labelStyle: 'font-weight:bold;', width: 80});
    g.setNode('customer_parent',{label:'customer_par', width: 80});
    // customer attributes
    g.setNode('cust_id',        {label: 'id', width: 80});
    g.setNode('cust_first_name',{label: 'first_name', width: 80});
    g.setNode('cust_last_name', {label: 'last_name', width: 80});
    g.setNode('cust_city',      {label: 'city', width: 80});
    g.setNode('cust_country',   {label: 'country', width: 80});
    // assign parent
    g.setParent('customer','customer_parent');
    g.setParent('cust_id','customer_parent');
    g.setParent('cust_first_name','customer_parent');
    g.setParent('cust_last_name','customer_parent');
    g.setParent('cust_city','customer_parent');
    g.setParent('cust_country','customer_parent');

    // city entity
    g.setNode('city',       {label:'city', class: 'entity-name', labelStyle: 'font-weight:bold;', width: 80});
    g.setNode('city_parent',{label:'city_parent'});
    // city attributes
    g.setNode('city_id',    {label: 'id', width: 80});
    g.setNode('city_name',  {label: 'name', width: 80});
    g.setNode('city_country',{label: 'country', width: 80});
    // assign parent
    g.setParent('city','city_parent');
   ...