<div id="netmap_pane_tooltip" class="net_gobrechts_d3_force_tooltip" style="top: 0px; left: 0px;"></div> <script> // *********************************************** // ************ retrieve network map ************* // *********************************************** $.getJSON('[% uri_for('/ajax/data/device/netmap') | none %]?[% my_query | none %]', function(mapdata) { jQuery(document).ready(function() { window.graph = netGobrechtsD3Force('netmap_pane') // .debug(true) .width( parseInt(jQuery('#netmap_pane').parent().css('width')) ) .height( window.innerHeight - 100 ) .showSelfLinks(true) .wrapLabels(true) .lassoMode(true) .dragMode(true) .zoomMode(true) .pinMode(true) [% '.showLegend(false)' UNLESS (params.colorby == 'hgroup' OR params.colorby == 'lgroup') %] .showLinkDirection(false) .colorScheme('color10') //.preventLabelOverlappingOnForceEnd( // (mapdata['newnodes'] && ('[% params.mapshow | html_entity %]' == 'neighbors')) // ? true : false //) .nodeEventToStopPinMode('none') .showTooltips(true) .tooltipPosition('svgTopLeft') .nodeEventToOpenLink('dblclick') .nodeLinkTarget('none') .minNodeRadius(4) .maxNodeRadius(4 + (mapdata['numsizes'] || 0)) .minZoomFactor(0.1) .maxZoomFactor(10) .labelDistance(2) .linkDistance(120) .charge(-550) .gravity(0.3); graph['nd2'] = {}; graph['nd2']['centernode'] = mapdata['centernode']; graph['nd2']['dragging'] = false; // *************************************** // *********** fullscreen icon *********** // *************************************** graph.inspect().dom.svg .append("g") .attr("id", "nd2_netmap-fullscreen-container") .attr("transform", "translate(" + (graph.width() - 17) + ",17)") .append("svg:text") .attr("id", "nd2_netmap-fullscreen") .attr("class", "link") .attr("text-anchor", "start") .attr("font-family", "FontAwesome") .text('\uf065') .on("click", function() { requestFullScreen(document.getElementById('netmap_pane')); }); // ************************************************** // *********** force running spinner icon *********** // ************************************************** graph.inspect().dom.svg .append("g") .attr("id", "nd2_netmap-spinner-container") .attr("transform", "translate(" + (graph.width() - 15) + "," + (graph.height() - 15) + ")") .append("path") .attr("id", "nd2_netmap-spinner"); graph.inspect().main.force.on('start.nd2spinner', function() { d3.select("#nd2_netmap-spinner").call(spin); }); // **************************************************** // *********** link labels that track links *********** // **************************************************** graph.inspect().main.force.on('tick.movelinklabel', function() { graph.inspect().dom.svg.selectAll('text.nd_netmap-linklabel') .attr('x', function(d) { var sx = graph.nodeDataById($(this).attr('data-source')); var tx = graph.nodeDataById($(this).attr('data-target')); if (!(sx && tx)) { return 0 } return ((sx.x + tx.x) / 2); }) .attr('y', function(d) { var sy = graph.nodeDataById($(this).attr('data-source')); var ty = graph.nodeDataById($(this).attr('data-target')); if (!(sy && ty)) { return 0 } return ((sy.y + ty.y) / 2); }); }); graph.inspect().main.force.on('start.movelinklabel', function() { mapdata['data']['links'].forEach(function(link) { graph.inspect().dom.svg.select('g.graph') .append('svg:text') .attr('class', 'nd_netmap-linklabel') .attr('data-source', link['FROMID']) .attr('data-target', link['TOID']) .attr('text-anchor', 'middle') [% ".attr('fill', 'black')" IF params.showspeed %] .text(link['SPEED']); }); graph.inspect().main.force.on('start.movelinklabel', null); }); // ********************************************************** // ********* node lasso and group-dragging support ********** // ********************************************************** graph.inspect().main.force.on('start.draggednode', function() { graph.inspect().main.nodes.on('mousedown.dragall', function(n) { if (this.nodeName !== 'circle') { return } graph['nd2']['dragging'] = true; graph['nd2']['dragStartX'] = n.x; graph['nd2']['dragStartY'] = n.y; graph['nd2']['draggedNode'] = n.index; console.log(graph['nd2']); }); graph.inspect().main.nodes.on('mousemove.dragall', function(draggedNode) { var evt = window.event; if (!("buttons" in evt) || (evt.buttons !== 1)) { return } if (!(graph['nd2']['dragging']) || !(graph['nd2']['draggedNode'])) { return } if (draggedNode.index !== graph['nd2']['draggedNode']) { return } var dx = (draggedNode.x - graph['nd2']['dragStartX']), dy = (draggedNode.y - graph['nd2']['dragStartY']); graph['nd2']['dragStartX'] += dx; graph['nd2']['dragStartY'] += dy; graph.inspect().main.nodes .filter(function(n) { return (n.selected && (n.index !== draggedNode.index)) }) .each(function(n) { n.x += dx; n.y += dy; n.px += dx; n.py += dy; }); }); graph.inspect().main.nodes.on('mouseup.dragall', function(n) { graph['nd2']['dragging'] = false; }); graph.inspect().main.force.on('start.draggednode', null); }); // ***************************** // ********* DO IT!! *********** // ***************************** graph.start(mapdata); // about a second after render starts, zoom in a bit if ('[% params.mapshow | html_entity %]' == 'neighbors') { setTimeout(function() { //if ('[% params.dynamicsize | html_entity %]' == 'on') { // graph.zoomToFit(); //} else { var node = graph.nodeDataById( graph['nd2']['centernode'] ); graph.zoomSmooth(node.x, node.y, node.radius * 125); //} }, 1500); } }); // document.onReady }); // getJSON // *********************************************** // ******** force engine status spinner ********* // *********************************************** var radius = 12; var tau = 2 * Math.PI; var arc = d3.svg.arc() .innerRadius(radius * 0.5) .outerRadius(radius * 0.8) .startAngle(0) .endAngle(0.33 * tau); var circle = d3.svg.arc() .innerRadius(radius * 0.5) .outerRadius(radius * 0.8) .startAngle(0) .endAngle(tau); function spin(selection, duration) { duration = duration || 1500; if (! graph.inspect().status.forceRunning) { d3.select('#nd2_netmap-spinner').style('fill', '#CCFFCC').attr('d', circle); saveMapPositions(); return; } d3.select('#nd2_netmap-spinner').style('fill', '#FFE4B5').attr('d', arc); selection.transition() .ease("linear") .duration(duration) .attrTween("transform", function() { return d3.interpolateString("rotate(0)", "rotate(360)"); }); setTimeout(function() { spin(selection, duration); }, duration); } // ******************************************************** // ********* save new node positions back to DB *********** // ******************************************************** function saveMapPositions() { graph.inspect().main.nodes.each(function(n) { n.fixed = true }); $.post( '[% uri_for('/ajax/data/device/netmappositions') | none %]' ,$("#nd_vlan-entry, #nd_mapshow-hops, #nd_hgroup-select, #nd_lgroup-select, #nq, input[name='mapshow']").serialize() + '&positions=' + JSON.stringify(graph.positions()) ); // toastr.success('Saved map positions.'); } // *********************************************** // ************ full screen handling ************* // *********************************************** function isFullScreen() { return (document.webkitFullscreenElement || document.mozFullScreenElement || document.fullscreenElement); } function requestFullScreen(elt) { if (isFullScreen()) { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } } else { if (elt.requestFullscreen) { elt.requestFullscreen(); } else if (elt.msRequestFullscreen) { elt.msRequestFullscreen(); } else if (elt.mozRequestFullScreen) { elt.mozRequestFullScreen(); } else if (elt.webkitRequestFullscreen) { elt.webkitRequestFullscreen(); } } } $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() { resizeGraphContainer(); $('#nd2_netmap-fullscreen').text(function() { return (isFullScreen() ? '\uf066' : '\uf065'); }); }); // ************************************************** // ************ react to sidebar in/out ************* // ************************************************** // custom resize function as there is no event to fire and we need // to react to the sidebar. function resizeGraphContainer() { setTimeout(function(){ var netmap_pane = jQuery('#netmap_pane'); graph.width( parseInt(netmap_pane.parent().css('width')) ).resume(); graph.height( window.innerHeight - 100 ).resume(); d3.select("#nd2_netmap-spinner-container").attr("transform", "translate(" + (graph.width() - 15) + "," + (graph.height() - 15) + ")"); d3.select("#nd2_netmap-fullscreen-container").attr("transform", "translate(" + (graph.width() - 17) + ",17)"); }, 500) } $('#nd_sidebar-toggle-img-in').on("click", resizeGraphContainer); $('#nd_sidebar-toggle-img-out').on("click", resizeGraphContainer); $(window).on("resize", resizeGraphContainer); // vim: ft=javascript </script>