You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-panel/share/static/js/libs/diagram.js

386 lines
10 KiB

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]);
}