template/html/d3-graph.js
function bootstrap()
   {
      // Hook up controllers
      $('.control-zoom button').on('click', onControlZoomClicked);
      $('.control-level input').on('change', onControlLevelChanged);
      $('.control-deps input').on('click', onControlDepsClicked);
      $('.control-links input').on('click', onControlLinksClicked);
      $('.control-menu li').on('click', onControlMenuClicked);

      $('#contextpopup li[data-action]').on('click', onNodeContextMenuClick);

      // Gather current level and scope from template values.
      appOptions.currentLevel = parseInt($('.control-level input').val());
      appOptions.currentScope = $('.control-deps input:radio[name=dep]:checked').val();

      zoom = d3.behavior.zoom();

      zoom.scaleExtent([minScaleExtent, maxScaleExtent]);
      zoom.on('zoom', onZoomChanged);

      graphWidth = window.innerWidth;
      graphHeight = window.innerHeight;

      d3.select(window).on('resize', onResize);

      // Setup layout
      layout = d3.layout.force()
       .gravity(.05)
       .charge(-300)
       .linkDistance(80)
       .size([graphWidth, graphHeight])
       .on('tick', onTick);

      // Setup drag callbacks for nodes. If a node is clicked and dragged it becomes fixed.
      layout.drag()
       .on('dragstart', function(targetNode)
       {
          d3.event.sourceEvent.stopPropagation();
          d3.select(this).classed('dragging', true).classed('fixed', targetNode.fixed = true);
          detectAllNodesFixed();
       })
       .on('drag', function(targetNode)
       {
          d3.select(this).attr('cx', targetNode.x = d3.event.x).attr('cy', targetNode.y = d3.event.y);
       })
       .on('dragend', function()
       {
          d3.select(this).classed('dragging', false);
       });

      // Setup graph
      d3.select('.graph')
       .append('svg')
       .attr('transform', 'rotate(0)')
       .on('contextmenu', function() { d3.event.preventDefault(); })
       .attr('pointer-events', 'all')
       .call(zoom).on('dblclick.zoom', null);

      // Markers Def
      d3.select('.graph svg')
       .append('defs').selectAll('marker')
       .data(['regular'])
       .enter().append('marker')
       .attr('id', String)
       .attr('viewBox', '0 -5 10 10')
       .attr('refX', 15)
       .attr('refY', -1.5)
       .attr('markerWidth', 6)
       .attr('markerHeight', 6)
       .attr('orient', 'auto')
       .append('path')
       .attr('d', 'M0,-5L10,0L0,5');

      // Top level SVGGElement for dragging / centering graph
      graph = d3.select('.graph svg')
       .append(getSVG('g'))
       .attr('width', graphWidth)
       .attr('height', graphHeight)
       .attr('transform', 'translate(' + zoom.translate() + ')' + ' scale(' + zoom.scale() + ')');

      // Initialize tablesorter
      $('#nodeTable').tablesorter(
      {
         widgets: ['stickyHeaders'],
         widgetOptions:
         {
            stickyHeaders_filteredToTop: true,
            stickyHeaders_cloneId : '-sticky',
            stickyHeaders_attachTo : '.control-table-inner'
         },
         sortMultiSortKey: ''
      });

      updateAll();

      // Center graph w/ zoom fit w/ 1 second transition applied after 4 seconds delay for debounce.
      centerGraph(zoomFit, 1000, 4000);
   }
function bootstrap()
   {
      // Hook up controllers
      $('.control-zoom button').on('click', onControlZoomClicked);
      $('.control-level input').on('change', onControlLevelChanged);
      $('.control-deps input').on('click', onControlDepsClicked);
      $('.control-links input').on('click', onControlLinksClicked);
      $('.control-menu li').on('click', onControlMenuClicked);

      $('#contextpopup li[data-action]').on('click', onNodeContextMenuClick);

      // Gather current level and scope from template values.
      appOptions.currentLevel = parseInt($('.control-level input').val());
      appOptions.currentScope = $('.control-deps input:radio[name=dep]:checked').val();

      zoom = d3.behavior.zoom();

      zoom.scaleExtent([minScaleExtent, maxScaleExtent]);
      zoom.on('zoom', onZoomChanged);

      graphWidth = window.innerWidth;
      graphHeight = window.innerHeight;

      d3.select(window).on('resize', onResize);

      // Setup layout
      layout = d3.layout.force()
       .gravity(.05)
       .charge(-300)
       .linkDistance(80)
       .size([graphWidth, graphHeight])
       .on('tick', onTick);

      // Setup drag callbacks for nodes. If a node is clicked and dragged it becomes fixed.
      layout.drag()
       .on('dragstart', function(targetNode)
       {
          d3.event.sourceEvent.stopPropagation();
          d3.select(this).classed('dragging', true).classed('fixed', targetNode.fixed = true);
          detectAllNodesFixed();
       })
       .on('drag', function(targetNode)
       {
          d3.select(this).attr('cx', targetNode.x = d3.event.x).attr('cy', targetNode.y = d3.event.y);
       })
       .on('dragend', function()
       {
          d3.select(this).classed('dragging', false);
       });

      // Setup graph
      d3.select('.graph')
       .append('svg')
       .attr('transform', 'rotate(0)')
       .on('contextmenu', function() { d3.event.preventDefault(); })
       .attr('pointer-events', 'all')
       .call(zoom).on('dblclick.zoom', null);

      // Markers Def
      d3.select('.graph svg')
       .append('defs').selectAll('marker')
       .data(['regular'])
       .enter().append('marker')
       .attr('id', String)
       .attr('viewBox', '0 -5 10 10')
       .attr('refX', 15)
       .attr('refY', -1.5)
       .attr('markerWidth', 6)
       .attr('markerHeight', 6)
       .attr('orient', 'auto')
       .append('path')
       .attr('d', 'M0,-5L10,0L0,5');

      // Top level SVGGElement for dragging / centering graph
      graph = d3.select('.graph svg')
       .append(getSVG('g'))
       .attr('width', graphWidth)
       .attr('height', graphHeight)
       .attr('transform', 'translate(' + zoom.translate() + ')' + ' scale(' + zoom.scale() + ')');

      // Initialize tablesorter
      $('#nodeTable').tablesorter(
      {
         widgets: ['stickyHeaders'],
         widgetOptions:
         {
            stickyHeaders_filteredToTop: true,
            stickyHeaders_cloneId : '-sticky',
            stickyHeaders_attachTo : '.control-table-inner'
         },
         sortMultiSortKey: ''
      });

      updateAll();

      // Center graph w/ zoom fit w/ 1 second transition applied after 4 seconds delay for debounce.
      centerGraph(zoomFit, 1000, 4000);
   }
Bootstraps the setup of the graph.