ntopng/httpdocs/js/ntop.min.js
emanuele-f f3497eb37c Graphs improvements
- Show begin and end time in the graph info table
- Show "Custom" zoom resolution when zoom is active and make it clickable to jump to it later
- Hide past time comparison series by default if too high
2018-08-17 15:00:42 +02:00

2 lines
No EOL
52 KiB
JavaScript

(function(){"use strict";var root=this;var Springy;if(typeof exports!=="undefined"){Springy=exports}else{Springy=root.Springy={}}var Graph=Springy.Graph=function(){this.nodeSet={};this.nodes=[];this.edges=[];this.adjacency={};this.nextNodeId=0;this.nextEdgeId=0;this.eventListeners=[]};var Node=Springy.Node=function(id,data){this.id=id;this.data=data!==undefined?data:{}};var Edge=Springy.Edge=function(id,source,target,data){this.id=id;this.source=source;this.target=target;this.data=data!==undefined?data:{}};Graph.prototype.addNode=function(node){if(!(node.id in this.nodeSet)){this.nodes.push(node)}this.nodeSet[node.id]=node;this.notify();return node};Graph.prototype.addNodes=function(){for(var i=0;i<arguments.length;i++){var name=arguments[i];var node=new Node(name,{label:name});this.addNode(node)}};Graph.prototype.addEdge=function(edge){var exists=false;this.edges.forEach(function(e){if(edge.id===e.id){exists=true}});if(!exists){this.edges.push(edge)}if(!(edge.source.id in this.adjacency)){this.adjacency[edge.source.id]={}}if(!(edge.target.id in this.adjacency[edge.source.id])){this.adjacency[edge.source.id][edge.target.id]=[]}exists=false;this.adjacency[edge.source.id][edge.target.id].forEach(function(e){if(edge.id===e.id){exists=true}});if(!exists){this.adjacency[edge.source.id][edge.target.id].push(edge)}this.notify();return edge};Graph.prototype.addEdges=function(){for(var i=0;i<arguments.length;i++){var e=arguments[i];var node1=this.nodeSet[e[0]];if(node1==undefined){throw new TypeError("invalid node name: "+e[0])}var node2=this.nodeSet[e[1]];if(node2==undefined){throw new TypeError("invalid node name: "+e[1])}var attr=e[2];this.newEdge(node1,node2,attr)}};Graph.prototype.addNodes2=function(){for(var i=0;i<arguments.length;i++){var data=arguments[i];var node=new Node(data.label,data);this.addNode(node)}};Graph.prototype.addEdges2=function(){for(var i=0;i<arguments.length;i++){var e=arguments[i];var node1=this.nodeSet[e.source];if(node1==undefined){throw new TypeError("invalid node name: "+e.source)}var node2=this.nodeSet[e.target];if(node2==undefined){throw new TypeError("invalid node name: "+e.target)}var attr=e.attributes;this.newEdge(node1,node2,attr)}};Graph.prototype.newNode=function(data){var node=new Node(this.nextNodeId++,data);this.addNode(node);return node};Graph.prototype.newEdge=function(source,target,data){var edge=new Edge(this.nextEdgeId++,source,target,data);this.addEdge(edge);return edge};Graph.prototype.loadJSON=function(json){if(typeof json=="string"||json instanceof String){json=JSON.parse(json)}if("nodes"in json||"edges"in json){this.addNodes2.apply(this,json["nodes"]);this.addEdges2.apply(this,json["edges"])}};Graph.prototype.getEdges=function(node1,node2){if(node1.id in this.adjacency&&node2.id in this.adjacency[node1.id]){return this.adjacency[node1.id][node2.id]}return[]};Graph.prototype.removeNode=function(node){if(node.id in this.nodeSet){delete this.nodeSet[node.id]}for(var i=this.nodes.length-1;i>=0;i--){if(this.nodes[i].id===node.id){this.nodes.splice(i,1)}}this.detachNode(node)};Graph.prototype.detachNode=function(node){var tmpEdges=this.edges.slice();tmpEdges.forEach(function(e){if(e.source.id===node.id||e.target.id===node.id){this.removeEdge(e)}},this);this.notify()};Graph.prototype.removeEdge=function(edge){for(var i=this.edges.length-1;i>=0;i--){if(this.edges[i].id===edge.id){this.edges.splice(i,1)}}for(var x in this.adjacency){for(var y in this.adjacency[x]){var edges=this.adjacency[x][y];for(var j=edges.length-1;j>=0;j--){if(this.adjacency[x][y][j].id===edge.id){this.adjacency[x][y].splice(j,1)}}if(this.adjacency[x][y].length==0){delete this.adjacency[x][y]}}if(isEmpty(this.adjacency[x])){delete this.adjacency[x]}}this.notify()};Graph.prototype.merge=function(data){var nodes=[];data.nodes.forEach(function(n){nodes.push(this.addNode(new Node(n.id,n.data)))},this);data.edges.forEach(function(e){var from=nodes[e.from];var to=nodes[e.to];var id=e.directed?id=e.type+"-"+from.id+"-"+to.id:from.id<to.id?e.type+"-"+from.id+"-"+to.id:e.type+"-"+to.id+"-"+from.id;var edge=this.addEdge(new Edge(id,from,to,e.data));edge.data.type=e.type},this)};Graph.prototype.filterNodes=function(fn){var tmpNodes=this.nodes.slice();tmpNodes.forEach(function(n){if(!fn(n)){this.removeNode(n)}},this)};Graph.prototype.filterEdges=function(fn){var tmpEdges=this.edges.slice();tmpEdges.forEach(function(e){if(!fn(e)){this.removeEdge(e)}},this)};Graph.prototype.addGraphListener=function(obj){this.eventListeners.push(obj)};Graph.prototype.notify=function(){this.eventListeners.forEach(function(obj){obj.graphChanged()})};var Layout=Springy.Layout={};Layout.ForceDirected=function(graph,stiffness,repulsion,damping){this.graph=graph;this.stiffness=stiffness;this.repulsion=repulsion;this.damping=damping;this.nodePoints={};this.edgeSprings={}};Layout.ForceDirected.prototype.point=function(node){if(!(node.id in this.nodePoints)){var mass=node.data.mass!==undefined?node.data.mass:1;this.nodePoints[node.id]=new Layout.ForceDirected.Point(Vector.random(),mass)}return this.nodePoints[node.id]};Layout.ForceDirected.prototype.spring=function(edge){if(!(edge.id in this.edgeSprings)){var length=edge.data.length!==undefined?edge.data.length:1;var existingSpring=false;var from=this.graph.getEdges(edge.source,edge.target);from.forEach(function(e){if(existingSpring===false&&e.id in this.edgeSprings){existingSpring=this.edgeSprings[e.id]}},this);if(existingSpring!==false){return new Layout.ForceDirected.Spring(existingSpring.point1,existingSpring.point2,0,0)}var to=this.graph.getEdges(edge.target,edge.source);from.forEach(function(e){if(existingSpring===false&&e.id in this.edgeSprings){existingSpring=this.edgeSprings[e.id]}},this);if(existingSpring!==false){return new Layout.ForceDirected.Spring(existingSpring.point2,existingSpring.point1,0,0)}this.edgeSprings[edge.id]=new Layout.ForceDirected.Spring(this.point(edge.source),this.point(edge.target),length,this.stiffness)}return this.edgeSprings[edge.id]};Layout.ForceDirected.prototype.eachNode=function(callback){var t=this;this.graph.nodes.forEach(function(n){callback.call(t,n,t.point(n))})};Layout.ForceDirected.prototype.eachEdge=function(callback){var t=this;this.graph.edges.forEach(function(e){callback.call(t,e,t.spring(e))})};Layout.ForceDirected.prototype.eachSpring=function(callback){var t=this;this.graph.edges.forEach(function(e){callback.call(t,t.spring(e))})};Layout.ForceDirected.prototype.applyCoulombsLaw=function(){this.eachNode(function(n1,point1){this.eachNode(function(n2,point2){if(point1!==point2){var d=point1.p.subtract(point2.p);var distance=d.magnitude()+.1;var direction=d.normalise();point1.applyForce(direction.multiply(this.repulsion).divide(distance*distance*.5));point2.applyForce(direction.multiply(this.repulsion).divide(distance*distance*-.5))}})})};Layout.ForceDirected.prototype.applyHookesLaw=function(){this.eachSpring(function(spring){var d=spring.point2.p.subtract(spring.point1.p);var displacement=spring.length-d.magnitude();var direction=d.normalise();spring.point1.applyForce(direction.multiply(spring.k*displacement*-.5));spring.point2.applyForce(direction.multiply(spring.k*displacement*.5))})};Layout.ForceDirected.prototype.attractToCentre=function(){this.eachNode(function(node,point){var direction=point.p.multiply(-1);point.applyForce(direction.multiply(this.repulsion/50))})};Layout.ForceDirected.prototype.updateVelocity=function(timestep){this.eachNode(function(node,point){point.v=point.v.add(point.a.multiply(timestep)).multiply(this.damping);point.a=new Vector(0,0)})};Layout.ForceDirected.prototype.updatePosition=function(timestep){this.eachNode(function(node,point){point.p=point.p.add(point.v.multiply(timestep))})};Layout.ForceDirected.prototype.totalEnergy=function(timestep){var energy=0;this.eachNode(function(node,point){var speed=point.v.magnitude();energy+=.5*point.m*speed*speed});return energy};var __bind=function(fn,me){return function(){return fn.apply(me,arguments)}};Springy.requestAnimationFrame=__bind(root.requestAnimationFrame||root.webkitRequestAnimationFrame||root.mozRequestAnimationFrame||root.oRequestAnimationFrame||root.msRequestAnimationFrame||function(callback,element){root.setTimeout(callback,10)},root);Layout.ForceDirected.prototype.start=function(render,onRenderStop,onRenderStart){var t=this;if(this._started)return;this._started=true;this._stop=false;if(onRenderStart!==undefined){onRenderStart()}Springy.requestAnimationFrame(function step(){t.applyCoulombsLaw();t.applyHookesLaw();t.attractToCentre();t.updateVelocity(.03);t.updatePosition(.03);if(render!==undefined){render()}if(t._stop||t.totalEnergy()<.01){t._started=false;if(onRenderStop!==undefined){onRenderStop()}}else{Springy.requestAnimationFrame(step)}})};Layout.ForceDirected.prototype.stop=function(){this._stop=true};Layout.ForceDirected.prototype.nearest=function(pos){var min={node:null,point:null,distance:null};var t=this;this.graph.nodes.forEach(function(n){var point=t.point(n);var distance=point.p.subtract(pos).magnitude();if(min.distance===null||distance<min.distance){min={node:n,point:point,distance:distance}}});return min};Layout.ForceDirected.prototype.getBoundingBox=function(){var bottomleft=new Vector(-2,-2);var topright=new Vector(2,2);this.eachNode(function(n,point){if(point.p.x<bottomleft.x){bottomleft.x=point.p.x}if(point.p.y<bottomleft.y){bottomleft.y=point.p.y}if(point.p.x>topright.x){topright.x=point.p.x}if(point.p.y>topright.y){topright.y=point.p.y}});var padding=topright.subtract(bottomleft).multiply(.07);return{bottomleft:bottomleft.subtract(padding),topright:topright.add(padding)}};var Vector=Springy.Vector=function(x,y){this.x=x;this.y=y};Vector.random=function(){return new Vector(10*(Math.random()-.5),10*(Math.random()-.5))};Vector.prototype.add=function(v2){return new Vector(this.x+v2.x,this.y+v2.y)};Vector.prototype.subtract=function(v2){return new Vector(this.x-v2.x,this.y-v2.y)};Vector.prototype.multiply=function(n){return new Vector(this.x*n,this.y*n)};Vector.prototype.divide=function(n){return new Vector(this.x/n||0,this.y/n||0)};Vector.prototype.magnitude=function(){return Math.sqrt(this.x*this.x+this.y*this.y)};Vector.prototype.normal=function(){return new Vector(-this.y,this.x)};Vector.prototype.normalise=function(){return this.divide(this.magnitude())};Layout.ForceDirected.Point=function(position,mass){this.p=position;this.m=mass;this.v=new Vector(0,0);this.a=new Vector(0,0)};Layout.ForceDirected.Point.prototype.applyForce=function(force){this.a=this.a.add(force.divide(this.m))};Layout.ForceDirected.Spring=function(point1,point2,length,k){this.point1=point1;this.point2=point2;this.length=length;this.k=k};var Renderer=Springy.Renderer=function(layout,clear,drawEdge,drawNode,onRenderStop,onRenderStart){this.layout=layout;this.clear=clear;this.drawEdge=drawEdge;this.drawNode=drawNode;this.onRenderStop=onRenderStop;this.onRenderStart=onRenderStart;this.layout.graph.addGraphListener(this)};Renderer.prototype.graphChanged=function(e){this.start()};Renderer.prototype.start=function(done){var t=this;this.layout.start(function render(){t.clear();t.layout.eachEdge(function(edge,spring){t.drawEdge(edge,spring.point1.p,spring.point2.p)});t.layout.eachNode(function(node,point){t.drawNode(node,point.p)})},this.onRenderStart,this.onRenderStop)};Renderer.prototype.stop=function(){this.layout.stop()};if(!Array.prototype.forEach){Array.prototype.forEach=function(callback,thisArg){var T,k;if(this==null){throw new TypeError(" this is null or not defined")}var O=Object(this);var len=O.length>>>0;if({}.toString.call(callback)!="[object Function]"){throw new TypeError(callback+" is not a function")}if(thisArg){T=thisArg}k=0;while(k<len){var kValue;if(k in O){kValue=O[k];callback.call(T,kValue,k,O)}k++}}}var isEmpty=function(obj){for(var k in obj){if(obj.hasOwnProperty(k)){return false}}return true}}).call(this);(function(){jQuery.fn.springy=function(params){var graph=this.graph=params.graph||new Springy.Graph;var nodeFont="16px Verdana, sans-serif";var edgeFont="8px Verdana, sans-serif";var stiffness=params.stiffness||400;var repulsion=params.repulsion||400;var damping=params.damping||.5;var nodeSelected=params.nodeSelected||null;var nodeImages={};var edgeLabelsUpright=true;var canvas=this[0];var ctx=canvas.getContext("2d");var layout=this.layout=new Springy.Layout.ForceDirected(graph,stiffness,repulsion,damping);var currentBB=layout.getBoundingBox();var targetBB={bottomleft:new Springy.Vector(-2,-2),topright:new Springy.Vector(2,2)};Springy.requestAnimationFrame(function adjust(){targetBB=layout.getBoundingBox();currentBB={bottomleft:currentBB.bottomleft.add(targetBB.bottomleft.subtract(currentBB.bottomleft).divide(10)),topright:currentBB.topright.add(targetBB.topright.subtract(currentBB.topright).divide(10))};Springy.requestAnimationFrame(adjust)});var toScreen=function(p){var size=currentBB.topright.subtract(currentBB.bottomleft);var sx=p.subtract(currentBB.bottomleft).divide(size.x).x*canvas.width;var sy=p.subtract(currentBB.bottomleft).divide(size.y).y*canvas.height;return new Springy.Vector(sx,sy)};var fromScreen=function(s){var size=currentBB.topright.subtract(currentBB.bottomleft);var px=s.x/canvas.width*size.x+currentBB.bottomleft.x;var py=s.y/canvas.height*size.y+currentBB.bottomleft.y;return new Springy.Vector(px,py)};var selected=null;var nearest=null;var dragged=null;jQuery(canvas).mousedown(function(e){var pos=jQuery(this).offset();var p=fromScreen({x:e.pageX-pos.left,y:e.pageY-pos.top});selected=nearest=dragged=layout.nearest(p);if(selected.node!==null){dragged.point.m=1e4;if(nodeSelected){nodeSelected(selected.node)}}renderer.start()});jQuery(canvas).dblclick(function(e){var pos=jQuery(this).offset();var p=fromScreen({x:e.pageX-pos.left,y:e.pageY-pos.top});selected=layout.nearest(p);node=selected.node;if(node&&node.data&&node.data.ondoubleclick){node.data.ondoubleclick(node.data)}});jQuery(canvas).mousemove(function(e){var pos=jQuery(this).offset();var p=fromScreen({x:e.pageX-pos.left,y:e.pageY-pos.top});nearest=layout.nearest(p);if(dragged!==null&&dragged.node!==null){dragged.point.p.x=p.x;dragged.point.p.y=p.y}renderer.start()});jQuery(window).bind("mouseup",function(e){dragged=null});var getTextWidth=function(node){var text=node.data.label!==undefined?node.data.label:node.id;if(node._width&&node._width[text])return node._width[text];ctx.save();ctx.font=node.data.font!==undefined?node.data.font:nodeFont;var width=ctx.measureText(text).width;ctx.restore();node._width||(node._width={});node._width[text]=width;return width};var getTextHeight=function(node){return 16};var getImageWidth=function(node){var width=node.data.image.width!==undefined?node.data.image.width:nodeImages[node.data.image.src].object.width;return width};var getImageHeight=function(node){var height=node.data.image.height!==undefined?node.data.image.height:nodeImages[node.data.image.src].object.height;return height};Springy.Node.prototype.getHeight=function(){var height;if(this.data.image==undefined){height=getTextHeight(this)}else{if(this.data.image.src in nodeImages&&nodeImages[this.data.image.src].loaded){height=getImageHeight(this)}else{height=10}}return height};Springy.Node.prototype.getWidth=function(){var width;if(this.data.image==undefined){width=getTextWidth(this)}else{if(this.data.image.src in nodeImages&&nodeImages[this.data.image.src].loaded){width=getImageWidth(this)}else{width=10}}return width};var renderer=this.renderer=new Springy.Renderer(layout,function clear(){ctx.clearRect(0,0,canvas.width,canvas.height)},function drawEdge(edge,p1,p2){var x1=toScreen(p1).x;var y1=toScreen(p1).y;var x2=toScreen(p2).x;var y2=toScreen(p2).y;var direction=new Springy.Vector(x2-x1,y2-y1);var normal=direction.normal().normalise();var from=graph.getEdges(edge.source,edge.target);var to=graph.getEdges(edge.target,edge.source);var total=from.length+to.length;var n=0;for(var i=0;i<from.length;i++){if(from[i].id===edge.id){n=i}}var spacing=12;var offset=normal.multiply(-((total-1)*spacing)/2+n*spacing);var paddingX=6;var paddingY=6;var s1=toScreen(p1).add(offset);var s2=toScreen(p2).add(offset);var boxWidth=edge.target.getWidth()+paddingX;var boxHeight=edge.target.getHeight()+paddingY;var intersection=intersect_line_box(s1,s2,{x:x2-boxWidth/2,y:y2-boxHeight/2},boxWidth,boxHeight);if(!intersection){intersection=s2}var stroke=edge.data.color!==undefined?edge.data.color:"#000000";var arrowWidth;var arrowLength;var weight=edge.data.weight!==undefined?edge.data.weight:1;ctx.lineWidth=Math.max(weight*2,.1);arrowWidth=1+ctx.lineWidth;arrowLength=8;var directional=edge.data.directional!==undefined?edge.data.directional:true;var lineEnd;if(directional){lineEnd=intersection.subtract(direction.normalise().multiply(arrowLength*.5))}else{lineEnd=s2}ctx.strokeStyle=stroke;ctx.beginPath();ctx.moveTo(s1.x,s1.y);ctx.lineTo(lineEnd.x,lineEnd.y);ctx.stroke();if(directional){ctx.save();ctx.fillStyle=stroke;ctx.translate(intersection.x,intersection.y);ctx.rotate(Math.atan2(y2-y1,x2-x1));ctx.beginPath();ctx.moveTo(-arrowLength,arrowWidth);ctx.lineTo(0,0);ctx.lineTo(-arrowLength,-arrowWidth);ctx.lineTo(-arrowLength*.8,-0);ctx.closePath();ctx.fill();ctx.restore()}if(edge.data.label!==undefined){text=edge.data.label;ctx.save();ctx.textAlign="center";ctx.textBaseline="top";ctx.font=edge.data.font!==undefined?edge.data.font:edgeFont;ctx.fillStyle=stroke;var angle=Math.atan2(s2.y-s1.y,s2.x-s1.x);var displacement=-8;if(edgeLabelsUpright&&(angle>Math.PI/2||angle<-Math.PI/2)){displacement=8;angle+=Math.PI}var textPos=s1.add(s2).divide(2).add(normal.multiply(displacement));ctx.translate(textPos.x,textPos.y);ctx.rotate(angle);ctx.fillText(text,0,-2);ctx.restore()}},function drawNode(node,p){var s=toScreen(p);ctx.save();var paddingX=6;var paddingY=6;var contentWidth=node.getWidth();var contentHeight=node.getHeight();var boxWidth=contentWidth+paddingX;var boxHeight=contentHeight+paddingY;ctx.clearRect(s.x-boxWidth/2,s.y-boxHeight/2,boxWidth,boxHeight);if(selected!==null&&selected.node!==null&&selected.node.id===node.id){ctx.fillStyle="#FFFFE0"}else if(nearest!==null&&nearest.node!==null&&nearest.node.id===node.id){ctx.fillStyle="#EEEEEE"}else{ctx.fillStyle="#FFFFFF"}ctx.fillRect(s.x-boxWidth/2,s.y-boxHeight/2,boxWidth,boxHeight);if(node.data.image==undefined){ctx.textAlign="left";ctx.textBaseline="top";ctx.font=node.data.font!==undefined?node.data.font:nodeFont;ctx.fillStyle="#000000";var text=node.data.label!==undefined?node.data.label:node.id;ctx.fillText(text,s.x-contentWidth/2,s.y-contentHeight/2);if(node.data.ip!==undefined){ctx.textBaseline="top";ctx.textAlign="center";ctx.font="8px Verdana, sans-serif";ctx.fillStyle="#000000";ctx.fillText(node.data.ip,s.x,s.y+contentHeight/2)}}else{var src=node.data.image.src;if(src in nodeImages){if(nodeImages[src].loaded){ctx.drawImage(nodeImages[src].object,s.x-contentWidth/2,s.y-contentHeight/2,contentWidth,contentHeight);if(node.data.ip!==undefined){ctx.textBaseline="top";ctx.textAlign="center";ctx.font="8px Verdana, sans-serif";ctx.fillStyle="#000000";ctx.fillText(node.data.ip,s.x,s.y+contentHeight/2)}}}else{nodeImages[src]={};var img=new Image;nodeImages[src].object=img;img.addEventListener("load",function(){nodeImages[src].loaded=true});img.src=src}}ctx.restore()});renderer.start();function intersect_line_line(p1,p2,p3,p4){var denom=(p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);if(denom===0){return false}var ua=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;var ub=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;if(ua<0||ua>1||ub<0||ub>1){return false}return new Springy.Vector(p1.x+ua*(p2.x-p1.x),p1.y+ua*(p2.y-p1.y))}function intersect_line_box(p1,p2,p3,w,h){var tl={x:p3.x,y:p3.y};var tr={x:p3.x+w,y:p3.y};var bl={x:p3.x,y:p3.y+h};var br={x:p3.x+w,y:p3.y+h};var result;if(result=intersect_line_line(p1,p2,tl,tr)){return result}if(result=intersect_line_line(p1,p2,tr,br)){return result}if(result=intersect_line_line(p1,p2,br,bl)){return result}if(result=intersect_line_line(p1,p2,bl,tl)){return result}return false}return this}})();function datatableRemoveEmptyRow(table){$("tbody tr.emptyRow",$(table)).remove()}function datatableAddEmptyRow(table,empty_str){var columns=$("thead th",$(table)).filter(function(){return $(this).css("display")!="none"}).length;$("tbody",$(table)).html('<tr class="emptyRow"><td colspan="'+columns+'"><i>'+empty_str+"</i></td></tr>")}function datatableGetNumDisplayedItems(table){return $("tr:not(.emptyRow)",$(table)).length-1}function datatableIsEmpty(table){return datatableGetNumDisplayedItems(table)==0}function datatableGetTotalItems(table){if(datatableIsEmpty(table))return 0;return $("#dt-bottom-details div.pull-left",$(table)).html().match(/of (\d+) rows/)[1]}function datatableGetByForm(form){return $("table",$("#dt-top-details",$(form)).parent())}function datatableUndoAddRow(new_row,empty_str,bt_to_enable,callback_str){if(bt_to_enable)$(bt_to_enable).removeAttr("disabled");var form=$(new_row).closest("form");$(new_row).remove();aysUpdateForm(form);var dt=datatableGetByForm(form);if(datatableIsEmpty(dt))datatableAddEmptyRow(dt,empty_str);if(callback_str)window[callback_str](new_row)}function datatableForEachRow(table,callbacks){$("tr:not(:first)",table).each(function(row_i){if(typeof callbacks==="function"){callbacks.bind(this)(row_i)}else{var i;for(i=0;i<callbacks.length;i++)callbacks[i].bind(this)(row_i)}})}function datatableAddButtonCallback(td_idx,label,bs_class,callback_str,link){$("td:nth-child("+td_idx+")",$(this)).append('<a href="'+link+'" class="add-on btn" style="padding:0.2em;" onclick="'+callback_str+'" role="button"><span class="label '+bs_class+'">'+label+"</span></a>")}function datatableAddDeleteButtonCallback(td_idx,callback_str,label){datatableAddButtonCallback.bind(this)(td_idx,label,"label-danger",callback_str,"javascript:void(0)")}function datatableAddActionButtonCallback(td_idx,callback_str,label){datatableAddButtonCallback.bind(this)(td_idx,label,"label-info",callback_str,"javascript:void(0)")}function datatableAddLinkButtonCallback(td_idx,link,label){datatableAddButtonCallback.bind(this)(td_idx,label,"label-info","",link)}function datatableMakeSelectUnique(tr_obj,added_rows_prefix,options){options=paramsExtend({on_change:$.noop,selector_fn:function(obj){return obj.find("select").first()}},options);function datatableForeachSelectOtherThan(this_select,added_rows_prefix,selector_fn,callback){$("[id^="+added_rows_prefix+"]").each(function(){var other=selector_fn($(this));if(other[0]!=this_select[0])callback(other)})}function datatableOptionChangeStatus(option_obj,enable){if(enable){option_obj.removeAttr("disabled")}else{var select_obj=option_obj.closest("select");var should_reset=select_obj.val()==option_obj.val();option_obj.attr("disabled","disabled");if(should_reset){var new_val=select_obj.find("option:not([disabled])").first().val();select_obj.val(new_val);select_obj.attr("data-old-val",new_val)}}}function datatableOnSelectEntryChange(added_rows_prefix,selector_fn,change_callback){var old_value=$(this).attr("data-old-val")||"";var new_value=$(this).val()||"";var others=[];if(old_value==new_value)old_value="";datatableForeachSelectOtherThan($(this),added_rows_prefix,selector_fn,function(other){datatableOptionChangeStatus(other.find("option[value='"+old_value+"']"),true);datatableOptionChangeStatus(other.find("option[value='"+new_value+"']"),false);others.push(other)});change_callback($(this),old_value,new_value,others,datatableOptionChangeStatus);$(this).attr("data-old-val",new_value)}function datatableOnAddSelectEntry(select_obj,added_rows_prefix,selector_fn){select_obj.val("");datatableForeachSelectOtherThan(select_obj,added_rows_prefix,selector_fn,function(other){other.trigger("change")});var new_sel=select_obj.find("option:not([disabled])").first();var new_val=new_sel.val();select_obj.val(new_val);select_obj.trigger("change")}var select=options.selector_fn(tr_obj);select.on("change",function(){datatableOnSelectEntryChange.bind(this)(added_rows_prefix,options.selector_fn,options.on_change)});select.on("remove",function(){$(this).val("").trigger("change")});datatableOnAddSelectEntry(select,added_rows_prefix,options.selector_fn)}function datatableOrderedInsert(table,td_idx,to_insert,to_insert_val,cmp_fn){var cmp_fn=cmp_fn||function(a,b){return b-a};var inserted=false;datatableForEachRow(table,function(){if(inserted)return;var tr=$(this);var cmp_val=parseInt($("td:nth-child("+td_idx+")",tr).html());if(!isNaN(cmp_val)&&cmp_fn(cmp_val,to_insert_val)<0){tr.before(to_insert);inserted=true}});if(!inserted)$(table).append(to_insert)}function datatableIsLastPage(table){var lastpage=$("#dt-bottom-details .pagination li:nth-last-child(3)",$(table));return!(lastpage.length==1&&lastpage.hasClass("active")==false)}function aysHandleForm(form_selector,options){if(!form_selector)form_selector="form";if(form_selector==="form"){form_selector='form:not([data-ays-ignore="true"])'}var default_options={submit_selector:'button[type="submit"]:not([data-ays-ignore="true"])',on_dirty_callback:$.noop,on_clean_callback:$.noop,handle_submit_buttons:true,handle_datatable:false,handle_tabs:false,disable_on_dirty:"",ays_options:{}};var o=$.extend(true,{},default_options,options);o.form_selector=form_selector;$(function(){$(o.form_selector).areYouSure(o.ays_options);if(o.handle_submit_buttons)$(o.form_selector).find(o.submit_selector).attr("disabled","disabled");$(o.form_selector).on("dirty.areYouSure",function(){if(o.handle_submit_buttons)$(this).find(o.submit_selector).removeAttr("disabled");if(o.handle_datatable){$(this).find("a.dropdown-toggle").attr("disabled","disabled");$(this).find("ul.pagination a").css("pointer-events","none").css("cursor","default")}if(o.handle_tabs){$(".nav-tabs").find("a").each(function(){if(!$(this).closest("li").hasClass("active"))$(this).removeAttr("data-toggle").closest("li").addClass("disabled")})}$(o.disable_on_dirty).addClass("disabled");o.on_dirty_callback.bind(this)()});$(o.form_selector).on("clean.areYouSure",function(){if(o.handle_submit_buttons)$(this).find(o.submit_selector).attr("disabled","disabled");if(o.handle_datatable){$(this).find("a.dropdown-toggle").removeAttr("disabled");$(this).find("ul.pagination a").css("pointer-events","").css("cursor","")}if(o.handle_tabs){$(".nav-tabs").find("a").each(function(){$(this).attr("data-toggle","tab").closest("li").removeClass("disabled")})}$(o.disable_on_dirty).removeClass("disabled");o.on_clean_callback.bind(this)()})})}function aysResetForm(form_selector){$(form_selector).trigger("reinitialize.areYouSure")}function aysUpdateForm(form_selector){$(form_selector).trigger("rescan.areYouSure")}function aysRecheckForm(form_selector){$(form_selector).trigger("checkform.areYouSure")}function aysGetDirty(form_selector,fields_selector){fields_selector=fields_selector||":input:not(input[type=submit]):not(input[type=button])";var getValue=function($field){if($field.hasClass("ays-ignore")||$field.hasClass("aysIgnore")||$field.attr("data-ays-ignore")||$field.attr("name")===undefined){return null}if($field.is(":disabled")){return"ays-disabled"}var val;var type=$field.attr("type");if($field.is("select")){type="select"}switch(type){case"checkbox":case"radio":val=$field.is(":checked");break;case"select":val="";$field.find("option").each(function(o){var $option=$(this);if($option.is(":selected")){val+=$option.val()}});break;default:val=$field.val()}return val};var isFieldDirty=function($field){var origValue=$field.data("ays-orig");var curValue=getValue($field);var dirty=undefined!==origValue&&origValue!=curValue;return{dirty:dirty,origValue:origValue,curValue:curValue}};var l=[];$(form_selector).find(fields_selector).each(function(){var dirty_status=isFieldDirty($(this));if(dirty_status.dirty){dirty_status.input=$(this);l.push(dirty_status)}});return l}function is_good_ipv4(ipv4){if(/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/.test(ipv4)){return true}else{return false}}function is_good_ipv6(ipv6){if(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\:){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ipv6)){return true}else{return false}}function isNumeric(value){return/^\d+$/.test(value)}function is_mac_address(what){return/^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$/.test(what)}function is_network_mask(what,optional_mask){var elems=what.split("/");var mask=null;var ip_addr;if(elems.length!=2){if(!optional_mask)return null;else ip_addr=what}else{ip_addr=elems[0];if(!isNumeric(elems[1]))return null;mask=parseInt(elems[1]);if(mask<0)return null}if(is_good_ipv4(ip_addr)){if(mask===null)mask=32;else if(mask>32)return null;return{type:"ipv4",address:ip_addr,mask:mask}}else if(is_good_ipv6(elems[0])){if(mask===null)mask=128;else if(mask>128)return false;return{type:"ipv6",address:ip_addr,mask:mask}}return null}function fbits(bits){var sizes=["bps","Kbit/s","Mbit/s","Gbit/s","Tbit/s"];if(bits<.005)return"0";var bits_log1000=Math.log(bits)/Math.log(1e3);var i=parseInt(Math.floor(bits_log1000));if(i<0||isNaN(i)){i=0}else if(i>=sizes.length){return"> "+sizes[sizes.length-1]}if(i<=1){return Math.round(bits/Math.pow(1e3,i)*100)/100+" "+sizes[i]}else{var ret=parseFloat(bits/Math.pow(1e3,i)).toFixed(2);if(ret%1==0)ret=Math.round(ret);return ret+" "+sizes[i]}}function fbits_from_bytes(bytes){return fbits(bytes*8)}function fpackets(pps){var sizes=["pps","Kpps","Mpps","Gpps","Tpps"];if(pps<.005)return"0";var res=scaleValue(pps,sizes,1e3);return Math.round(res[0]*100)/100+" "+res[1]}function fflows(fps){var sizes=["fps","Kfps","Mfps","Gfps","Tfps"];if(fps<.005)return"0";var res=scaleValue(fps,sizes,1e3);return Math.round(res[0]*100)/100+" "+res[1]}function fint(value){var x=Math.round(value);return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}function fdate(when){var epoch=when*1e3;var d=new Date(epoch);return d}function capitaliseFirstLetter(string){return string.charAt(0).toUpperCase()+string.slice(1)}String.prototype.startsWith=function(string){return this.indexOf(string)===0};function get_trend(actual,before){if(before===undefined||actual==before){return'<i class="fa fa-minus"></i>'}else{return'<i class="fa fa-arrow-up"></i>'}}function getOSIcon(name){var icon="";if(name.search("Linux")!=-1||name.search("Ubuntu")!=-1)icon="<i class='fa fa-linux fa-lg'></i> ";else if(name.search("Android")!=-1)icon="<i class='fa fa-android fa-lg'></i> ";else if(name.search("Windows")!=-1||name.search("Win32")!=-1||name.search("MSIE")!=-1)icon="<i class='fa fa-windows fa-lg'></i> ";else if(name.search("iPhone")!=-1||name.search("iPad")!=-1||name.search("OS X")!=-1)icon="<i class='fa fa-apple fa-lg'></i> ";return icon}function abbreviateString(str,len){if(!str)return"";if(str.length<len)return str;return str.substring(0,len)+"..."}function bytesToSize(bytes){var precision=2;var kilobyte=1024;var megabyte=kilobyte*1024;var gigabyte=megabyte*1024;var terabyte=gigabyte*1024;if(bytes>=0&&bytes<kilobyte)return bytes.toFixed(precision)+" Bytes";else if(bytes>=kilobyte&&bytes<megabyte)return(bytes/kilobyte).toFixed(precision)+" KB";else if(bytes>=megabyte&&bytes<gigabyte)return(bytes/megabyte).toFixed(precision)+" MB";else if(bytes>=gigabyte&&bytes<terabyte)return(bytes/gigabyte).toFixed(precision)+" GB";else if(bytes>=terabyte)return(bytes/terabyte).toFixed(precision)+" TB";else return bytes.toFixed(precision)+" Bytes"}String.prototype.capitalizeSingleWord=function(){var uc=this.toUpperCase();if(uc=="ASN"||uc=="OS")return uc;else return this.charAt(0).toUpperCase()+this.slice(1)};String.prototype.capitalize=function(){var res=this.split(" ");for(var i in res){res[i]=res[i].capitalizeSingleWord()}return res.join(" ")};function drawTrend(current,last,withColor){if(current==last){return'<i class="fa fa-minus"></i>'}else if(current>last){return'<i class="fa fa-arrow-up"'+withColor+"></i>"}else{return'<i class="fa fa-arrow-down"></i>'}}function toggleAllTabs(enabled){if(enabled===true)$("#historical-tabs-container").find("li").removeClass("disabled").find("a").attr("data-toggle","tab");else $("#historical-tabs-container").find("li").addClass("disabled").find("a").removeAttr("data-toggle")}function disableAllDropdownsAndTabs(){$("select").each(function(){$(this).prop("disabled",true)});toggleAllTabs(false)}function enableAllDropdownsAndTabs(){$("select").each(function(){$(this).prop("disabled",false)});toggleAllTabs(true)}function capitalize(s){return s&&s[0].toUpperCase()+s.slice(1)}function addCommas(nStr){nStr+="";var x=nStr.split(".");var x1=x[0];var x2=x.length>1?"."+x[1]:"";var rgx=/(\d+)(\d{3})/;while(rgx.test(x1)){x1=x1.replace(rgx,"$1"+","+"$2")}return x1+x2}function scaleValue(val,sizes,scale){if(val==0)return[0,sizes[0]];var i=parseInt(Math.floor(Math.log(val)/Math.log(scale)));if(i<0||isNaN(i)){i=0}else if(i>=sizes.length)i=sizes.length-1;return[val/Math.pow(scale,i),sizes[i]]}function formatValue(val){var sizes=["","K","M","G","T"];var res=scaleValue(val,sizes,1e3);return Math.round(res[0])+res[1]}function formatPackets(n){return addCommas(n.toFixed(0))+" Pkts"}function formatFlows(n){return addCommas(n.toFixed(0))+" Flows"}function fmillis(value){var x=Math.round(value);var res=scaleValue(x,["ms","s"],1e3);return res[0]+" "+res[1]}function bytesToVolume(bytes){var sizes=["Bytes","KB","MB","GB","TB"];if(bytes==0)return"0 Bytes";var res=scaleValue(bytes,sizes,1024);return res[0].toFixed(2)+" "+res[1]}function bytesToVolumeAndLabel(bytes){var sizes=["Bytes","KB","MB","GB","TB"];if(bytes==0)return"0 Bytes";var i=parseInt(Math.floor(Math.log(bytes)/Math.log(1024)));return[(bytes/Math.pow(1024,i)).toFixed(2),sizes[i]]}function bitsToSize(bits,factor){factor=factor||1e3;var sizes=["bit/s","kbit/s","Mbit/s","Gbit/s","Tbit/s"];if(bits==0)return"0 bps";var res=scaleValue(bits,sizes,factor);return res[0].toFixed(2)+" "+res[1]}function secondsToTime(seconds){if(seconds<1){return"< 1 sec"}var days=Math.floor(seconds/86400);var hours=Math.floor(seconds/3600-days*24);var minutes=Math.floor(seconds/60-days*1440-hours*60);var sec=seconds%60;var msg="",msg_array=[];if(days>0){years=Math.floor(days/365);if(years>0){days=days%365;msg=years+" year";if(years>1){msg+="s"}msg_array.push(msg);msg=""}msg=days+" day";if(days>1){msg+="s"}msg_array.push(msg);msg=""}if(hours>0){if(hours<10){msg="0"}msg+=hours+":"}if(minutes<10){msg+="0"}msg+=minutes+":";if(sec<10){msg+="0"}msg+=sec;msg_array.push(msg);return msg_array.join(", ")}Date.prototype.format=function(format){var o={"M+":this.getMonth()+1,"d+":this.getDate(),"h+":this.getHours(),"m+":this.getMinutes(),"s+":this.getSeconds(),"q+":Math.floor((this.getMonth()+3)/3),S:this.getMilliseconds()};if(/(y+)/.test(format))format=format.replace(RegExp.$1,(this.getFullYear()+"").substr(4-RegExp.$1.length));for(var k in o)if(new RegExp("("+k+")").test(format))format=format.replace(RegExp.$1,RegExp.$1.length==1?o[k]:("00"+o[k]).substr((""+o[k]).length));return format};function epoch2Seen(epoch){var d=new Date(epoch*1e3);var tdiff=Math.floor((new Date).getTime()/1e3-epoch);return d.format("dd/MM/yyyy hh:mm:ss")+" ["+secondsToTime(tdiff)+" ago]"}function graphGetXAxisTicksFormat(diff_epoch){var tickFormat;if(diff_epoch<=86400){tickFormat="%H:%M:%S"}else if(diff_epoch<=2*86400){tickFormat="%b %e, %H:%M:%S"}else{tickFormat="%b %e"}return tickFormat}function paramsExtend(defaults,override){return $.extend({},defaults,override)}function paramsToForm(form,params){form=$(form);for(var k in params){if(params.hasOwnProperty(k)){var input=$('<input type="hidden" name="'+k+'" value="'+params[k]+'">');input.appendTo(form)}}return form}function paramsPairsEncode(params){var i=0;var res={};for(var k in params){res["key_"+i]=k;res["val_"+i]=params[k];i=i+1}return res}jQuery.fn.extend({disable:function(state){return this.each(function(){var $this=$(this);if($this.is("input, button, textarea, select"))this.disabled=state;else $this.toggleClass("disabled",state)})}});function hostkey2hostInfo(host_key){var info;var hostinfo=[];host_key=host_key.replace(/____/g,":");host_key=host_key.replace(/___/g,"/");host_key=host_key.replace(/__/g,".");info=host_key.split("@");return info}function handle_tab_state(nav_object,default_tab){$("a",nav_object).click(function(e){e.preventDefault()});$(" > li > a",nav_object).on("shown.bs.tab",function(e){var id=$(e.target).attr("href").substr(1);if(history.replaceState){history.replaceState(null,null,"#"+id)}else{window.location.hash=id}});var hash=window.location.hash;if(!hash)hash="#"+default_tab;$('a[href="'+hash+'"]',nav_object).tab("show")}String.prototype.sformat=function(){var args=arguments;return this.replace(/{(\d+)}/g,function(match,number){return typeof args[number]!="undefined"?args[number]:match})};if(typeof String.prototype.contains==="undefined"){String.prototype.contains=function(s){return this.indexOf(s)!==-1}}function makeFindHostBeforeSubmitCallback(http_prefix){return function(form,data){if(data.type=="mac")form.attr("action",http_prefix+"/lua/mac_details.lua");else if(data.type=="snmp")form.attr("action",http_prefix+"/lua/pro/enterprise/snmp_device_details.lua");else form.attr("action",http_prefix+"/lua/host_details.lua");return true}}function tstampToDateString(html_tag,format,tdiff){tdiff=tdiff||0;var timestamp=parseInt(html_tag.html())+tdiff;var localized=d3.time.format(format)(new Date(timestamp*1e3));html_tag.html(localized).removeClass("hidden");return localized}var schema_2_label={};var data_2_label={};function initLabelMaps(_schema_2_label,_data_2_label){schema_2_label=_schema_2_label;data_2_label=_data_2_label}function getSerieLabel(schema,serie){var data_label=serie.label;var new_label=data_2_label[data_label];if(schema=="top:local_senders"||schema=="top:local_receivers"){return serie.tags.host}else if(schema.startsWith("top:")){if(serie.tags.protocol)return serie.tags.protocol;else if(serie.tags.category)return serie.tags.category;else if(serie.tags.device&&serie.tags.if_index){if(serie.tags.if_index!=serie.ext_label)return serie.ext_label+" ("+serie.tags.if_index+")";else return serie.ext_label}else if(serie.tags.device&&serie.tags.port)return serie.tags.port;else if(serie.tags.profile)return serie.tags.profile}else if(data_label!="bytes"){if(serie.tags.protocol)return serie.tags.protocol+" ("+new_label+")";else if(serie.tags.category)return serie.tags.category+" ("+new_label+")";else if(serie.tags.device&&serie.tags.if_index)return serie.ext_label+" ("+new_label+")";else if(serie.tags.device&&serie.tags.port)return serie.tags.port+" ("+new_label+")"}else{if(serie.tags.protocol)return serie.tags.protocol;else if(serie.tags.category)return serie.tags.category;else if(serie.tags.profile)return serie.tags.profile;else if(data_label=="bytes")return"Traffic"}if(schema_2_label[schema])return capitaliseFirstLetter(schema_2_label[schema]);if(new_label)return capitaliseFirstLetter(new_label);return capitaliseFirstLetter(data_label)}function getValueFormatter(schema,series){if(series&&series.length&&series[0].label){var label=series[0].label;if(label.contains("bytes"))return[fbits_from_bytes,bytesToSize];else if(label.contains("packets"))return[fpackets,formatPackets];else if(label.contains("flows"))return[formatValue,formatFlows,formatFlows];else if(label.contains("millis"))return[fmillis,fmillis]}return[fint,fint]}function makeFlatLineValues(tstart,tstep,num,data){var t=tstart;var values=[];for(var i=0;i<num;i++){values[i]=[t,data];t+=tstep}return values}function checkSeriesConsinstency(schema_name,count,series){var rv=true;for(var i=0;i<series.length;i++){var data=series[i].data;if(data.length>count){console.error("points mismatch: serie '"+getSerieLabel(schema_name,series[i])+"' has "+data.length+" points, expected "+count);rv=false}else if(data.length<count){series[i].data=upsampleSerie(data,count)}}return rv}function upsampleSerie(serie,num_points){if(num_points<=serie.length)return serie;var res=[];var intervals=num_points/serie.length;function lerp(v0,v1,t){return(1-t)*v0+t*v1}for(var i=0;i<num_points;i++){var index=i/intervals;var prev_i=Math.floor(index);var next_i=Math.min(Math.ceil(index),serie.length-1);var t=index%1;var v=lerp(serie[prev_i],serie[next_i],t);res.push(v)}return res.slice(0,num_points)}function buildTotalSerie(data_series){var series=[];for(var i=0;i<data_series.length;i++)series.push(data_series[i].data);return d3.transpose(series).map(function(x){return x.map(function(g){return g})}).map(function(x){return d3.sum(x)})}function arrayToNvSerie(serie_data,start,step){var values=[];var t=start;for(var i=0;i<serie_data.length;i++){values[i]=[t,serie_data[i]];t+=step}return values}function buildOtherSerie(total_serie,visual_total){if(total_serie.length!==visual_total.length){console.warn("Total/Visual length mismatch: "+total_serie.length+" vs "+visual_total.length);return}var res=[];var max_val=0;for(var i=0;i<total_serie.length;i++){var value=Math.max(0,total_serie[i]-visual_total[i]);max_val=Math.max(max_val,value);res.push(value)}if(max_val>.1)return res}function buildTimeArray(start_time,end_time,step){var arr=[];for(var t=start_time;t<end_time;t+=step)arr.push(t);return arr}function fixTimeRange(chart,params,step){var diff_epoch=params.epoch_end-params.epoch_begin;var frame,align,tick_step,resolution,fmt="%H:%M:%S";var range_params=[[15,1,"%H:%M:%S",1,1],[60,1,"%H:%M:%S",1,5],[120,5,"%H:%M:%S",10,10],[300,5,"%H:%M:%S",10,30],[600,10,"%H:%M:%S",30,60],[1200,30,"%H:%M:%S",60,120],[3600,60,"%H:%M:%S",60,300],[5400,120,"%H:%M",300,900],[10800,300,"%H:%M",300,900],[21600,300,"%H:%M",3600,1800],[43200,600,"%H:%M",3600,3600],[86400,600,"%H:%M",3600,7200],[172800,3600,"%a, %H:%M",3600,14400],[604800,3600,"%Y-%m-%d",86400,86400],[1209600,7200,"%Y-%m-%d",86400,172800],[2678400,21600,"%Y-%m-%d",86400,259200],[15768e3,175200,"%Y-%m-%d",2678400,1314e3],[31622400,175200,"%Y-%m-%d",2678400,2678400]];for(var i=0;i<range_params.length;i++){var range=range_params[i];if(diff_epoch<=range[0]){frame=range[0];resolution=range[1];fmt=range[2];align=range[3];tick_step=range[4];break}}if(align){align=Math.max(align,step);params.epoch_begin-=params.epoch_begin%align;params.epoch_end-=params.epoch_end%align;diff_epoch=params.epoch_end-params.epoch_begin;params.limit=Math.round(diff_epoch/resolution);params.epoch_end+=Math.ceil(diff_epoch/params.limit)*params.limit-diff_epoch;chart.xAxis.tickValues(buildTimeArray(params.epoch_begin,params.epoch_end,tick_step))}chart.xAxis.tickFormat(function(d){return d3.time.format(fmt)(new Date(d*1e3))})}function attachStackedChartCallback(chart,schema_name,chart_id,zoom_reset_id,flows_dt,params,step){var pending_request=null;var d3_sel=d3.select(chart_id);var $chart=$(chart_id);var $zoom_reset=$(zoom_reset_id);var $graph_zoom=$("#graph_zoom");var max_interval=step*8;var is_max_zoom=false;var zoom_stack=[];var url=http_prefix+"/lua/get_ts.lua";var first_load=true;var first_time_loaded=true;var datetime_format="dd/MM/yyyy hh:mm:ss";var max_over_total_ratio=3;var spinner=$('<i class="chart-loading-spinner fa fa-spinner fa-lg fa-spin"></i>');$chart.parent().css("position","relative");var chart_colors_full=["#69B87F","#94CFA4","#B3DEB6","#E5F1A6","#FFFCC6","#FEDEA5","#FFB97B","#FF8D6D","#E27B85"];var chart_colors_min=["#7CC28F","#FCD384","#FD977B"];var update_chart_data=function(new_data){d3_sel.datum([]).call(chart);d3_sel.datum(new_data).transition().call(chart);nv.utils.windowResize(chart.update);pending_request=null;spinner.remove()};function isLegendDisabled(key,default_val){if(typeof localStorage!=="undefined"){var val=localStorage.getItem("chart_series.disabled."+key);if(val!=null)return val==="true"}return default_val}chart.legend.dispatch.on("legendClick",function(d,i){if(typeof localStorage!=="undefined")localStorage.setItem("chart_series.disabled."+d.legend_key,!d.disabled?true:false)});chart.dispatch.on("zoom",function(e){var cur_zoom=[params.epoch_begin,params.epoch_end];var t_start=Math.floor(e.xDomain[0]);var t_end=Math.ceil(e.xDomain[1]);if(chart.updateStackedChart(t_start,t_end)){chart.is_zoomed=true;zoom_stack.push(cur_zoom);$zoom_reset.show();$graph_zoom.find(".btn-warning:not(.custom-zoom-btn)").addClass("initial-zoom-sel").removeClass("btn-warning");$graph_zoom.find(".custom-zoom-btn").show();var zoom_link=$graph_zoom.find(".custom-zoom-btn input");var link=zoom_link.val();link+="&epoch_begin="+t_start+"&epoch_end="+t_end;zoom_link.val(link)}});function updateZoom(zoom){var t_start=zoom[0];var t_end=zoom[1];chart.updateStackedChart(t_start,t_end);if(!zoom_stack.length){$zoom_reset.hide();$graph_zoom.find(".initial-zoom-sel").addClass("btn-warning");$graph_zoom.find(".custom-zoom-btn").hide()}}$chart.on("dblclick",function(){if(zoom_stack.length){var zoom=zoom_stack.pop();updateZoom(zoom)}});$zoom_reset.on("click",function(){if(zoom_stack.length){var zoom=zoom_stack[0];zoom_stack=[];updateZoom(zoom)}});var old_start,old_end;chart.updateStackedChart=function(tstart,tend,no_spinner){if(tstart)params.epoch_begin=tstart;if(tend)params.epoch_end=tend;var cur_interval=params.epoch_end-params.epoch_begin;if(cur_interval<max_interval){if(is_max_zoom)return false;if(!first_load){var epoch=params.epoch_begin+(params.epoch_end-params.epoch_begin)/2;params.epoch_begin=Math.floor(epoch-max_interval/2);params.epoch_end=Math.ceil(epoch+max_interval/2)}is_max_zoom=true;chart.zoomType(null)}else{is_max_zoom=false;chart.zoomType("x")}fixTimeRange(chart,params,step);if(old_start==params.epoch_begin&&old_end==params.epoch_end)return false;old_start=params.epoch_begin;old_end=params.epoch_end;if(pending_request)pending_request.abort();else if(!no_spinner)spinner.appendTo($chart.parent());pending_request=$.get(url,params,function(data){if(!data||!data.series||!data.series.length||!checkSeriesConsinstency(schema_name,data.count,data.series)){update_chart_data([]);return}var res=[];var series=data.series;var total_serie;var color_i=0;var chart_colors=series.length<=chart_colors_min.length?chart_colors_min:chart_colors_full;for(var j=0;j<series.length;j++){var values=[];var serie_data=series[j].data;var t=data.start;for(var i=0;i<serie_data.length;i++){values[i]=[t,serie_data[i]];t+=data.step}var label=getSerieLabel(schema_name,series[j]);var legend_key=schema_name+":"+label;res.push({key:label,yAxis:series[j].axis||1,values:values,type:series[j].type||"area",color:chart_colors[color_i++],legend_key:legend_key,disabled:isLegendDisabled(legend_key,false)})}var visual_total=buildTotalSerie(series);var has_full_data=false;if(data.additional_series&&data.additional_series.total){total_serie=data.additional_series.total;var other_serie=buildOtherSerie(total_serie,visual_total);if(other_serie){res.push({key:"Other",yAxis:1,values:arrayToNvSerie(other_serie,data.start,data.step),type:"area",color:chart_colors[color_i++],legend_key:"other",disabled:isLegendDisabled("other",false)});has_full_data=true}}else{total_serie=visual_total;has_full_data=!schema_name.startsWith("top:")}if(data.additional_series){for(var key in data.additional_series){if(key=="total"){continue}var serie_data=upsampleSerie(data.additional_series[key],data.count);var ratio_over_total=d3.max(serie_data)/d3.max(visual_total);var values=arrayToNvSerie(serie_data,data.start,data.step);var is_disabled=isLegendDisabled(key,false);if(first_time_loaded&&ratio_over_total>max_over_total_ratio)is_disabled=true;res.push({key:capitaliseFirstLetter(key),yAxis:1,values:values,type:"line",classed:"line-dashed line-animated",color:"#7E91A0",legend_key:key,disabled:is_disabled})}}if(!data.no_trend&&has_full_data&&total_serie.length){var num_smoothed_points=Math.max(Math.floor(total_serie.length/5),3);var smoothed=smooth(total_serie,num_smoothed_points);var max_val=d3.max(smoothed);if(max_val>0){var scale=d3.max(total_serie)/max_val;var scaled=$.map(smoothed,function(x){return x*scale});var aligned=upsampleSerie(scaled,data.count);res.push({key:"Trend",yAxis:1,values:arrayToNvSerie(aligned,data.start,data.step),type:"line",classed:"line-animated",color:"#62ADF6",legend_key:"trend",disabled:isLegendDisabled("trend",false)})}}var formatter1=getValueFormatter(schema_name,series.filter(function(d){return d.axis!=2}));var value_formatter=formatter1[0];var tot_formatter=formatter1[1];var stats_formatter=formatter1[2]||value_formatter;chart.yAxis1.tickFormat(value_formatter);chart.yAxis1_formatter=value_formatter;var second_axis_series=series.filter(function(d){return d.axis==2});var formatter2=getValueFormatter(schema_name,second_axis_series);var value_formatter2=formatter2[0];chart.yAxis2.tickFormat(value_formatter2);chart.yAxis2_formatter=value_formatter2;var stats_table=$chart.closest("table").find(".graph-statistics");var stats=data.statistics;stats_table.find(".graph-val-begin").show().find("span").html(new Date(data.start*1e3).format(datetime_format));stats_table.find(".graph-val-end").show().find("span").html(new Date((data.start+data.step*(data.count-1))*1e3).format(datetime_format));if(stats){if(stats.average){var values=makeFlatLineValues(data.start,data.step,data.count,stats.average);res.push({key:"Avg",yAxis:1,values:values,type:"line",classed:"line-dashed line-animated",color:"#AC9DDF",legend_key:"avg",disabled:isLegendDisabled("avg",true)})}if(stats.total)stats_table.find(".graph-val-total").show().find("span").html(tot_formatter(stats.total));if(stats.average)stats_table.find(".graph-val-average").show().find("span").html(stats_formatter(stats.average));if(stats.min_val)stats_table.find(".graph-val-min").show().find("span").html(stats_formatter(stats.min_val)+" @ "+new Date(res[0].values[stats.min_val_idx][0]*1e3).format(datetime_format));if(stats.max_val)stats_table.find(".graph-val-max").show().find("span").html(stats_formatter(stats.max_val)+" @ "+new Date(res[0].values[stats.max_val_idx][0]*1e3).format(datetime_format));if(stats["95th_percentile"]){stats_table.find(".graph-val-95percentile").show().find("span").html(stats_formatter(stats["95th_percentile"]));var values=makeFlatLineValues(data.start,data.step,data.count,stats["95th_percentile"]);res.push({key:"95th Perc",yAxis:1,values:values,type:"line",classed:"line-dashed line-animated",color:"#476DFF",legend_key:"95perc",disabled:isLegendDisabled("95perc",true)})}}stats_table.show();var enabled_series=res.filter(function(d){return d.disabled!==true});if(second_axis_series.length>0||enabled_series.length==0){for(var i=0;i<res.length;i++)res[i].disabled=false}if(second_axis_series.length>0){chart.legend.updateState(false)}update_chart_data(res);first_time_loaded=false}).fail(function(xhr,status,error){if(xhr.statusText=="abort"){return}console.error("Error while retrieving the timeseries data ["+status+"]: "+error);update_chart_data([])});if(first_load){first_load=false}else{if(flows_dt)flows_dt.render()}return true}}function makeUniqueValidator(items_function){return function(field){var cmp_name=field.val();var count=0;if(!cmp_name)return true;items_function(field).each(function(){var name=$(this).val();if(name==cmp_name)count=count+1});return count==1}}function memberValueValidator(input){var member=input.val();if(member==="")return true;return is_mac_address(member)||is_network_mask(member,true)}function makePasswordPatternValidator(pattern){return function passwordPatternValidator(input){if(!input.val())return true;return $(input).val().match(pattern)}}function passwordMatchValidator(input){var other_input=$(input).closest("form").find("[data-passwordmatch]").not(input);if(!input.val()||!other_input.val())return true;return other_input.val()===input.val()}function poolnameValidator(input){if(!input.val())return true;return $(input).val().match(/^[a-z0-9_]*$/)}function passwordMatchRecheck(form){var items=$(form).find("[data-passwordmatch]");var not_empty=0;items.each(function(){if($(this).val()!="")not_empty++});if(not_empty==items.length)items.trigger("input")}function hostOrMacValidator(input){var host=input.val();if(host==="")return true;return is_mac_address(host)||is_good_ipv4(host)||is_good_ipv6(host)}
//# sourceMappingURL=ntop.min.js.map