- static css and javascript libs added Change-Id: I4d46b9736fc5c04c9d7d55d484b647741fc2eafechanges/01/18201/54
parent
c81ca69b70
commit
3c6a7ff9f0
@ -0,0 +1,96 @@
|
||||
.class-rect {
|
||||
fill: white;
|
||||
stroke-width: 1px;
|
||||
stroke: black;
|
||||
}
|
||||
|
||||
.class-rect:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.class-label {
|
||||
font-size: 10px;
|
||||
font-family: Courier
|
||||
}
|
||||
|
||||
.class-label:hover {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.class-message {
|
||||
font-size: x-small;
|
||||
font-family: Courier
|
||||
}
|
||||
|
||||
.class-message:hover {
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.class-title {
|
||||
font-size: big;
|
||||
font-family: Courier
|
||||
}
|
||||
|
||||
.message-number {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.class-vertical-line {
|
||||
stroke: #888;
|
||||
}
|
||||
|
||||
#editorDiv {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
position:absolute;
|
||||
background-color: white;
|
||||
z-index: 1001;
|
||||
border: solid 1px black;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: none;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
#controls {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#diagram_header {
|
||||
height: 30px;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
#diagram_wrapper {
|
||||
height: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#diagram {
|
||||
height: 70%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#message-frame {
|
||||
height: 30%;
|
||||
width: 100%;
|
||||
font-family: Courier;
|
||||
}
|
||||
|
||||
/* overrides*/
|
||||
#content {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#masthead {
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
var dictedit = {
|
||||
value: function(id){
|
||||
var res = {};
|
||||
var ta = document.getElementById(id);
|
||||
var rows = ta.value.split(ta.dataset["dictedit_delim"]);
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var x = rows[i].split(ta.dataset["dictedit_sep"]);
|
||||
if (x[0] != "")
|
||||
{
|
||||
res[x[0]] = x[1];
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
init: function(id, opts, initKeys, initValues) {
|
||||
opts = opts || {};
|
||||
var ta = document.getElementById(id);
|
||||
var newNode = document.createElement("div");
|
||||
newNode.id = id + "_dictedit" //+ new Date().getTime();
|
||||
newNode.className = "dictedit-wrapper " + id + "_dictedit";
|
||||
ta.parentNode.insertBefore(newNode,ta);
|
||||
ta.style.display = "none";
|
||||
var delim = opts.delim || ";";
|
||||
var sep = opts.sep || " : ";
|
||||
ta.dataset["dictedit_sep"] = sep;
|
||||
ta.dataset["dictedit_delim"] = delim;
|
||||
for(var i = 0; i < initKeys.length; i++){
|
||||
if (initKeys[i].length > 0){
|
||||
dictedit.addRow(id, initKeys[i], initValues[i]);
|
||||
}
|
||||
}
|
||||
dictedit.updateRows(id.split("_dictedit")[0]);
|
||||
},
|
||||
addRow: function(taID, a, b){
|
||||
var id = taID + "_dictedit";
|
||||
this.__handleRowAdd(id, a, b);
|
||||
},
|
||||
__handleKeyPress: function(e){
|
||||
var id = e.target.parentNode.id;
|
||||
var y = function(){
|
||||
dictedit.updateRows(id.split("_dictedit")[0]);
|
||||
}
|
||||
setTimeout(y, 100);
|
||||
},
|
||||
__handleRowAdd: function(id, a, b) {
|
||||
var taID = id.split("_dictedit")[0];
|
||||
var dataset = document.getElementById(taID).dataset;
|
||||
var sep = dataset.dictedit_sep || ": ";
|
||||
var delim = dataset.dictedit_delim || "; ";
|
||||
var temp = new Date().getTime().toString();
|
||||
var outS = "<input onkeydown='dictedit.__handleKeyPress(event)' class='" + temp + " left' value='" + a + "' readonly>"
|
||||
+ "<input onkeydown='dictedit.__handleKeyPress(event)' class='" + temp + " right' value='" + b + "'>"
|
||||
+ "<br class='" + temp + "'>";
|
||||
$("#" + id).append(outS);
|
||||
},
|
||||
updateRows(taID)
|
||||
{
|
||||
var id = taID + "_dictedit";
|
||||
var ret = "";
|
||||
var dataset = document.getElementById(taID).dataset;
|
||||
var sep = dataset.dictedit_sep || ": ";
|
||||
var delim = dataset.dictedit_delim || "; ";
|
||||
var list = document.getElementById(id).getElementsByTagName("input");
|
||||
for(var i = 0; i < list.length/2; i++){
|
||||
ret += list[i*2].value + sep + list[i*2+1].value + delim;
|
||||
}
|
||||
document.getElementById(taID).value = ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,385 @@
|
||||
var colors=["green", "red", "sienna", "orange", "black", "purple", "chocolate", "olivedrab", "darkred", "darkslategrey", "midnightblue", "maroon", "teal", "goldenrod", "gray", "darkolivegreen", "darkcyan", "brown", "peru", "mediumorchild", "navy", "saddlebrown", "coral"];
|
||||
|
||||
function line_color(d)
|
||||
{
|
||||
return colors[d];
|
||||
}
|
||||
|
||||
var aliases = { };
|
||||
|
||||
function classToAlias(c)
|
||||
{
|
||||
var alias = aliases[c];
|
||||
|
||||
if (alias == undefined)
|
||||
{
|
||||
alias = c;
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
function receiver(d, considerports)
|
||||
{
|
||||
var rc = d.dst_ip;
|
||||
|
||||
if (considerports)
|
||||
{
|
||||
rc += ":" + d.dst_port;
|
||||
}
|
||||
|
||||
return classToAlias(rc);
|
||||
}
|
||||
|
||||
function sender(d, considerports)
|
||||
{
|
||||
var rc = d.src_ip;
|
||||
|
||||
if (considerports)
|
||||
{
|
||||
rc += ":" + d.src_port;
|
||||
}
|
||||
|
||||
return classToAlias(rc);
|
||||
}
|
||||
|
||||
function prepareData(data, considerports)
|
||||
{
|
||||
console.log("prepare data");
|
||||
|
||||
data.frames.forEach(function(m, i) {
|
||||
m.hidden = false;
|
||||
m.drawable = true;
|
||||
});
|
||||
|
||||
data.frames.forEach(function(m, i) {
|
||||
|
||||
var i = (sender(m, considerports) == receiver(m, considerports))
|
||||
|
||||
m.internal = i;
|
||||
m.drawable = !i;
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
function hostPortToClass(c)
|
||||
{
|
||||
return "class-" + classToAlias(c).replace(/\./g, "_").replace(":", "_");
|
||||
}
|
||||
|
||||
function toggleSVG(node)
|
||||
{
|
||||
console.log(node);
|
||||
var x = document.getElementsByClassName(node);
|
||||
|
||||
console.log(x.length);
|
||||
var i; for (i = 0; i < x.length; i++)
|
||||
{
|
||||
x[i].style.display = (x[i].style.display == 'none') ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function createSvg(container)
|
||||
{
|
||||
var width = parseInt(d3.select(container).style("width"), 10);
|
||||
|
||||
return d3.select(container).append("svg").attr("width", width );
|
||||
}
|
||||
|
||||
function redraw(data, considerports)
|
||||
{
|
||||
var svg = d3.selectAll("svg");
|
||||
svg.remove();
|
||||
draw_sequence_diagram(data, considerports);
|
||||
}
|
||||
|
||||
function hidePackets(rawdata, pattern, considerports)
|
||||
{
|
||||
console.log("hide packets", pattern);
|
||||
|
||||
rawdata.frames.forEach(function(item, i)
|
||||
{
|
||||
if (sender(item, considerports) == pattern || receiver(item, considerports) == pattern)
|
||||
{
|
||||
item.hidden = !item.hidden;
|
||||
}
|
||||
});
|
||||
|
||||
redraw(rawdata, considerports);
|
||||
}
|
||||
|
||||
function getNodes(data, considerports)
|
||||
{
|
||||
var senders = d3.set(data.map(function(d){ return sender(d, considerports); })).values();
|
||||
var receivers = d3.set(data.map(function(d){ return receiver(d, considerports); })).values();
|
||||
return _.union(senders, receivers);
|
||||
}
|
||||
|
||||
function considerPortsClick(rawdata, considerports)
|
||||
{
|
||||
console.log("consider ports click");
|
||||
prepareData(rawdata, !considerports);
|
||||
redraw(rawdata, !considerports);
|
||||
}
|
||||
|
||||
function draw_sequence_diagram(rawdata, considerports)
|
||||
{
|
||||
var chartName = rawdata.call;
|
||||
var data = rawdata.frames;
|
||||
|
||||
function considerPorts()
|
||||
{
|
||||
considerPortsClick(rawdata, considerports);
|
||||
}
|
||||
|
||||
var message_frame = d3.select("#message-frame");
|
||||
|
||||
function showMessageBody(m)
|
||||
{
|
||||
message_frame.html("<textarea>" + "packet# " + m.id + "\n" + m.payload + "</textarea>");
|
||||
}
|
||||
|
||||
function listClasses(m, considerports)
|
||||
{
|
||||
return hostPortToClass(sender(m, considerports)) + " " +
|
||||
hostPortToClass(receiver(m, considerports)) + " " +
|
||||
"class-message";
|
||||
}
|
||||
|
||||
function classClick(node)
|
||||
{
|
||||
console.log("class click", node);
|
||||
|
||||
// FIXME reimplement with d3
|
||||
// toggleSVG(hostPortToClass(node));
|
||||
hidePackets(rawdata, node, considerports);
|
||||
|
||||
}
|
||||
|
||||
function initAliases(nodes, preAliases)
|
||||
{
|
||||
if (_.isEmpty(aliases))
|
||||
{
|
||||
var nodes1 = nodes.slice();
|
||||
|
||||
if (typeof preAliases !== 'undefined')
|
||||
{
|
||||
for (var key in preAliases)
|
||||
{
|
||||
var index = nodes1.indexOf(key);
|
||||
if (index != -1)
|
||||
{
|
||||
nodes1[index] = preAliases[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dictedit.init("nodeEditor", null, nodes, nodes1);
|
||||
aliases = dictedit.value("nodeEditor");
|
||||
applyNodeEdit();
|
||||
}
|
||||
}
|
||||
|
||||
var button1 = d3.select("#considerPortsButton").on("click", considerPorts);
|
||||
var expand = d3.select("#expandEditor").on("click", expandEditor);
|
||||
var apply = d3.select("#applyNodeEdit").on("click", applyNodeEdit);
|
||||
|
||||
function applyNodeEdit() {
|
||||
aliases = dictedit.value("nodeEditor");
|
||||
redraw(rawdata, considerports);
|
||||
};
|
||||
|
||||
function expandEditor() {
|
||||
$("#editorDiv").slideToggle(200);
|
||||
};
|
||||
|
||||
var header = createSvg("#diagram_header");
|
||||
var svg = createSvg("#diagram");
|
||||
|
||||
var margin = { top: 20, right: 20, bottom: 20, left: 20 },
|
||||
width = +svg.attr('width') - margin.left - margin.right,
|
||||
height = +svg.attr('height') - margin.top - margin.bottom,
|
||||
g = header.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
||||
|
||||
// Graph title
|
||||
g.append('text')
|
||||
.attr('x', (width / 2))
|
||||
.attr('y', 0 - (margin.top / 4))
|
||||
.attr('class', 'class-title')
|
||||
.text(chartName);
|
||||
|
||||
var nodes = getNodes(data, considerports);
|
||||
|
||||
initAliases(nodes, rawdata.aliases);
|
||||
|
||||
var XPAD = 200; // horizontal padding for vertical lines/messages/labels
|
||||
var YPAD = 3;
|
||||
var VERT_SPACE = parseInt(width/nodes.length);
|
||||
|
||||
var MESSAGE_SPACE = 25;
|
||||
svg.attr("height", (data.length+2)*MESSAGE_SPACE);
|
||||
|
||||
var MESSAGE_LABEL_X_OFFSET = -50;
|
||||
var MESSAGE_LABEL_Y_OFFSET = 10;
|
||||
var MESSAGE_ARROW_Y_OFFSET = 15;
|
||||
|
||||
var CLASS_WIDTH = 120;
|
||||
var CLASS_LABEL_X_OFFSET = -30;
|
||||
var CLASS_LABEL_Y_OFFSET = 25;
|
||||
|
||||
// Draw vertical lines
|
||||
nodes.forEach(function(c, i) {
|
||||
var line = svg.append("line")
|
||||
.attr("class", "class-vertical-line")
|
||||
.attr("x1", XPAD + i * VERT_SPACE)
|
||||
.attr("y1", 0) // YPAD + MESSAGE_SPACE)
|
||||
.attr("x2", XPAD + i * VERT_SPACE)
|
||||
.attr("y2", YPAD + data.length * (MESSAGE_SPACE + 5))
|
||||
});
|
||||
|
||||
// Draw class labels
|
||||
nodes.forEach(function(c, i) {
|
||||
var x = XPAD + i * VERT_SPACE;
|
||||
var g1 = header.append("g")
|
||||
.attr("transform", "translate(" + x + "," + YPAD + ")")
|
||||
.attr("class", "class-rect")
|
||||
.append("rect")
|
||||
.attr("x", -CLASS_WIDTH/2)
|
||||
.attr("y", "0")
|
||||
.attr("width", CLASS_WIDTH)
|
||||
.attr("height", "24px")
|
||||
.on("click", function() { classClick(c) })
|
||||
|
||||
var g2 = header.append("g")
|
||||
.attr("transform", "translate(" + x + "," + YPAD + ")")
|
||||
.append("text")
|
||||
.attr("class", "class-label")
|
||||
.attr("text-anchor", "middle")
|
||||
.text(function (d) { return classToAlias(c); })
|
||||
.attr("dy", "16px")
|
||||
.on("click", function() { classClick(c) })
|
||||
});
|
||||
|
||||
var i = -1;
|
||||
var message_number = 0;
|
||||
|
||||
data.forEach(function(m, c) {
|
||||
|
||||
// FIXME var lcolor = line_color(m.session_id);
|
||||
var lcolor = line_color(0);
|
||||
var tcolor = "black";
|
||||
|
||||
if (!m.drawable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (m.hidden)
|
||||
{
|
||||
lcolor = "lightgrey";
|
||||
tcolor = "lightgrey";
|
||||
}
|
||||
|
||||
// draw packet number
|
||||
var xPos = 0;
|
||||
var yPos = MESSAGE_LABEL_Y_OFFSET + i * MESSAGE_SPACE;
|
||||
var classes = listClasses(m, considerports);
|
||||
|
||||
var g1 = svg.append("g")
|
||||
.attr("transform", "translate(" + xPos + "," + yPos + ")")
|
||||
.attr("text-anchor", "left")
|
||||
.attr("class", classes)
|
||||
.attr("class", "message-number")
|
||||
.append("text")
|
||||
.style("fill", tcolor)
|
||||
.text(message_number++);
|
||||
|
||||
|
||||
// draw timestamp
|
||||
var xPos = XPAD/2;
|
||||
var yPos = MESSAGE_LABEL_Y_OFFSET + i * MESSAGE_SPACE;
|
||||
|
||||
g1 = svg.append("g")
|
||||
.attr("transform", "translate(" + xPos + "," + yPos + ")")
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("class", classes)
|
||||
.append("text")
|
||||
.style("fill", tcolor)
|
||||
.style("font-size", "10px")
|
||||
.text(m.timestamp);
|
||||
|
||||
// draw message labels
|
||||
xPos = XPAD + MESSAGE_LABEL_X_OFFSET + (((nodes.indexOf(receiver(m, considerports)) - nodes.indexOf(sender(m, considerports))) * VERT_SPACE) / 2) + (nodes.indexOf(sender(m, considerports)) * VERT_SPACE);
|
||||
yPos = MESSAGE_LABEL_Y_OFFSET + i * MESSAGE_SPACE;
|
||||
|
||||
// draw message labels
|
||||
g1 = svg.append("g")
|
||||
.attr("transform", "translate(" + xPos + "," + yPos + ")")
|
||||
.append("text")
|
||||
.attr("dx", "5px")
|
||||
.attr("dy", "-2px")
|
||||
.attr("text-anchor", "begin")
|
||||
.style("fill", tcolor)
|
||||
.attr("class", classes)
|
||||
.on("click", function() { showMessageBody(m) })
|
||||
.text(m.method + " " + m.request_uri);
|
||||
|
||||
// draw line
|
||||
var y = MESSAGE_ARROW_Y_OFFSET + (i) * MESSAGE_SPACE;
|
||||
var line = svg.append("line")
|
||||
.style("stroke", lcolor)
|
||||
.attr("x1", XPAD + nodes.indexOf(sender(m, considerports)) * VERT_SPACE)
|
||||
.attr("y1", y)
|
||||
.attr("x2", XPAD + nodes.indexOf(receiver(m, considerports)) * VERT_SPACE)
|
||||
.attr("y2", y)
|
||||
.attr("marker-end", "url(#end)")
|
||||
.on("click", function() { showMessageBody(m) })
|
||||
|
||||
if (m.hidden)
|
||||
{
|
||||
line.attr("marker-end", "url(#hidden)");
|
||||
}
|
||||
else
|
||||
{
|
||||
line.attr("marker-end", "url(#end)");
|
||||
}
|
||||
});
|
||||
|
||||
// Arrow style
|
||||
svg.append("svg:defs").selectAll("marker")
|
||||
.data(["end"])
|
||||
.enter().append("svg:marker")
|
||||
.attr("id", String)
|
||||
.attr("viewBox", "0 -5 10 10")
|
||||
.attr("refX", 10)
|
||||
.attr("refY", 0)
|
||||
.attr("markerWidth", 10)
|
||||
.attr("markerHeight", 10)
|
||||
.attr("orient", "auto")
|
||||
.attr("fill", "blue")
|
||||
.append("svg:path")
|
||||
.style("stroke", "blue")
|
||||
.attr("d", "M0,-3L10,0L0,3");
|
||||
|
||||
// Arrow style
|
||||
svg.append("svg:defs").selectAll("marker")
|
||||
.data(["hidden"])
|
||||
.enter().append("svg:marker")
|
||||
.attr("id", String)
|
||||
.attr("viewBox", "0 -5 10 10")
|
||||
.attr("refX", 10)
|
||||
.attr("refY", 0)
|
||||
.attr("markerWidth", 10)
|
||||
.attr("markerHeight", 10)
|
||||
.attr("orient", "auto")
|
||||
.attr("fill", "lightgrey")
|
||||
.append("svg:path")
|
||||
.style("stroke", "lightgrey")
|
||||
.attr("d", "M0,-3L10,0L0,3");
|
||||
|
||||
showMessageBody(data[0]);
|
||||
}
|
@ -1,37 +1,61 @@
|
||||
[% site_config.title = c.loc('Call Flow for Call-ID [_1]', callid) -%]
|
||||
<link rel="stylesheet" href="/css/callflow.css">
|
||||
<link rel="stylesheet" href="/css/ui-lightness/jquery-ui-1.10.3.custom.min.css">
|
||||
|
||||
<script type="text/javascript" src="/js/libs/jquery.popup.js"></script>
|
||||
<script type="text/javascript">
|
||||
function pkgPopup(pkgid) {
|
||||
// http://www.jquerypopup.com/documentation.php
|
||||
modalPopup("center", 100, 640, 10, "#666666", 40, "#FFFFFF", "#000000", 4, 5, 300,
|
||||
"[% c.uri_for_action('/subscriber/get_packet', c.req.captures) %]/"+pkgid,
|
||||
"/img/loader.gif");
|
||||
}
|
||||
</script>
|
||||
<script src="https://d3js.org/d3.v4.js"></script>
|
||||
<script src="https://d3js.org/d3-dsv.v1.min.js"></script>
|
||||
<script src="/js/libs/aliaseditor.js"></script>
|
||||
<script src="/js/libs/diagram.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
|
||||
<script src="/js/libs/jquery-1.7.2.min.js"></script>
|
||||
|
||||
<div class="row">
|
||||
<span class="pull-left" style="margin:0 5px 0 5px;">
|
||||
<a class="btn btn-primary btn-large" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
|
||||
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('/subscriber/get_pcap', c.req.captures) %]"><i class="icon-file"></i> [% c.loc('Download PCAP') %]</a>
|
||||
</span>
|
||||
<div id="controls">
|
||||
<a class="btn btn-primary btn-small" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
|
||||
<a class="btn btn-primary btn-small" href="[% c.uri_for_action('/subscriber/get_pcap', c.req.captures) %]"><i class="icon-file"></i> [% c.loc('Download PCAP') %]</a>
|
||||
<input id="considerPortsButton" type="button" class="btn-primary btn-small" value="Consider Ports"/>
|
||||
<input id="expandEditor" type="button" class="btn-primary btn-small" value="Node Editor"/>
|
||||
<div id="editorDiv">
|
||||
node|alias
|
||||
<textarea id="nodeEditor"></textarea>
|
||||
<input id="applyNodeEdit" type="button" value="Apply"/>
|
||||
</div>
|
||||
</div>
|
||||
[% back_created = 1 -%]
|
||||
|
||||
<div class="row">
|
||||
[% FOREACH m IN messages -%]
|
||||
<div class="alert alert-[% m.type %]">[% m.text %]</div>
|
||||
[% END -%]
|
||||
<div id="diagram_wrapper">
|
||||
<div id="diagram_header">
|
||||
</div>
|
||||
<div id="diagram">
|
||||
</div>
|
||||
<div id="message-frame">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ngcp-separator"></div>
|
||||
<script>
|
||||
$(document).mouseup(function(e) {
|
||||
var container = $("#editorDiv");
|
||||
|
||||
// if the target of the click isn't the container nor a descendant of the container
|
||||
if (!container.is(e.target) && container.has(e.target).length === 0)
|
||||
{
|
||||
container.hide();
|
||||
}
|
||||
});
|
||||
|
||||
$( document ).ready(function() {
|
||||
$.getJSON("[% c.uri_for_action('/subscriber/get_uas_json', c.req.captures) %]", function(aliases) {
|
||||
|
||||
<img src="[% c.uri_for_action('/subscriber/get_png', c.req.captures) %]"
|
||||
width="[% canvas.width %]" height="[% canvas.height %]" usemap="#diamap" style="min-width:[% canvas.width %]px !important" />
|
||||
<map name="diamap">
|
||||
[% FOREACH area IN canvas.areas -%]
|
||||
<area shape="rect" coords="[% area.coords %]" href="javascript:pkgPopup([% area.id %])" />
|
||||
[% END -%]
|
||||
</map>
|
||||
$.getJSON("[% c.uri_for_action('/subscriber/get_json', c.req.captures) %]", function(frames) {
|
||||
var considerports = true;
|
||||
var data = {};
|
||||
data.frames = frames;
|
||||
data.aliases = aliases;
|
||||
data = prepareData(data, considerports);
|
||||
redraw(data, considerports);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
[% back_created = 1 -%]
|
||||
|
||||
[% # vim: set tabstop=4 syntax=html expandtab: -%]
|
||||
|
Loading…
Reference in new issue