202 lines
5.1 KiB
JavaScript
202 lines
5.1 KiB
JavaScript
// Create a new directed graph
|
|
global = {};
|
|
var init = function() {
|
|
initFile();
|
|
$.ajax({
|
|
url : "./CMManager",
|
|
data : {
|
|
"action" : "getControlFlowByFileName",
|
|
"path" : "A2.yjs"
|
|
},
|
|
dataType : "jsonp"
|
|
}).done(function(result) {
|
|
// console.log(result);
|
|
global.r = result;
|
|
drawMethod(global.r.sub);
|
|
});
|
|
$('#tabdiv').editableSelect({
|
|
filter : false
|
|
});
|
|
$("#tabdiv").on('select.editable-select', function(e) {
|
|
switchProject();
|
|
});
|
|
$('#tabdiv').addClass("ui-selectmenu-button");
|
|
$('#tabdiv').addClass("ui-selectmenu-button-closedn");
|
|
$('#tabdiv').addClass("ui-corner-all");
|
|
$('#tabdiv').addClass("ui-button");
|
|
$('#tabdiv').addClass("ui-widget");
|
|
};
|
|
var initFile = function() {
|
|
var prefix = "ws://";
|
|
if (document.location.href.startsWith("https"))
|
|
prefix = "wss://";
|
|
url = prefix
|
|
+ document.location.host
|
|
+ (document.location.pathname.replace("contractflowchart.html",
|
|
"SCExecutor"));
|
|
|
|
var wssocket = new WebSocket(url);
|
|
// console.log("[ideapi.js] wssocket的url = " + url);
|
|
global.filewssocket = wssocket;
|
|
wssocket.onerror = function(error) {
|
|
console.log(error);
|
|
};
|
|
wssocket.onopen = function(error) {
|
|
var pingObj = {};
|
|
pingObj.action = "ping";
|
|
wssocket.send(JSON.stringify(pingObj));
|
|
listProjects();
|
|
};
|
|
wssocket.onmessage = FileHandler;
|
|
};
|
|
var listProjects = function(off) {
|
|
console.log("[ideapi.js] listProjects : ");
|
|
var pingObj = {};
|
|
pingObj.action = "listProjects";
|
|
global.filewssocket.send(JSON.stringify(pingObj));
|
|
}
|
|
|
|
var FileHandler = function(event) {
|
|
console.log("[ideapi.js] FileHandler : ");
|
|
// console.log(event);
|
|
data = event.data;
|
|
// console.log(" -->" + data);
|
|
try {
|
|
var obj = JSON.parse(data);
|
|
switch (obj.action) {
|
|
case 'ping':
|
|
// console.log("[ideapi.js] FileHandler case 'ping' : ");
|
|
case 'poing':
|
|
break;
|
|
case 'onListProjects':
|
|
onListProjects(obj);
|
|
break;
|
|
default:
|
|
logComm(obj);
|
|
break;
|
|
}
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
|
|
};
|
|
var logComm = function(obj) {
|
|
console.log(obj);
|
|
};
|
|
var switchProject = function() {
|
|
var fileName = $("#tabdiv")[0].value;
|
|
if (fileName != global.lastProject) {
|
|
global.lastProject = fileName;
|
|
} else
|
|
return;
|
|
// console.log("[FileName, switch] " + fileName);
|
|
$.ajax({
|
|
url : "./CMManager",
|
|
data : {
|
|
"action" : "getControlFlowByFileName",
|
|
"path" : fileName
|
|
},
|
|
dataType : "jsonp"
|
|
}).done(function(result) {
|
|
// console.log(result);
|
|
global.r = result;
|
|
for ( var k in global.r) {
|
|
drawMethod(global.r[k]);
|
|
break;
|
|
}
|
|
});
|
|
$("#tabdiv").on('select.editable-select', function(e) {
|
|
switchProject();
|
|
});
|
|
}
|
|
var onListProjects = function(obj) {
|
|
var data = JSON.parse(obj.data);
|
|
global.projects = data;
|
|
$("#tabdiv").editableSelect('clear');
|
|
// $("#tabdiv").html("");
|
|
global.contractName2ID = {};
|
|
for (var i = 0; i < data.length; i++) {
|
|
$("#tabdiv").editableSelect('add', data[i]);
|
|
}
|
|
if (data.length > 0)
|
|
$("#tabdiv").editableSelect()[0].value = data[0];
|
|
};
|
|
var drawMethod = function(method) {
|
|
var states = {};
|
|
for (var i = 0; i < method.blocks.length; i++) {
|
|
var block = method.blocks[i];
|
|
var desp = {};
|
|
desp.description = stmt2Str(block.stmts);
|
|
desp.description += "<br/>" + block.original;
|
|
// console.log(desp.description);
|
|
if (block.type != "Continuous")
|
|
desp.fill = "#f77";
|
|
states[block.name] = desp;
|
|
}
|
|
drawCFGraph(states, method.edges);
|
|
};
|
|
var stmt2Str = function(l) {
|
|
var str = "";
|
|
for (var i = 0; i < l.length; i++)
|
|
str += "<span style='text-overflow:ellipsis'>"
|
|
+ l[i].replace(/\//g, ".") + "</span>" + "<br/>";
|
|
return str;
|
|
}
|
|
|
|
var drawCFGraph = function(states, edges) {
|
|
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
// Add states to the graph, set labels, and style
|
|
Object.keys(states).forEach(function(state) {
|
|
var value = states[state];
|
|
value.label = state;
|
|
value.rx = value.ry = 5;
|
|
g.setNode(state, value);
|
|
});
|
|
for (var i = 0; i < edges.length; i++)
|
|
g.setEdge(edges[i].from, edges[i].to, edges[i].label);
|
|
// Set up the edges
|
|
|
|
// Create the renderer
|
|
var render = new dagreD3.render();
|
|
$("svg").html("");
|
|
// var width = $("svg").width();
|
|
// $("svg").css("width", width);
|
|
|
|
// Set up an SVG group so that we can translate the final graph.
|
|
var svg = d3.select("svg"), inner = svg.append("g");
|
|
|
|
// Set up zoom support
|
|
var zoom = d3.zoom().on("zoom", function() {
|
|
inner.attr("transform", d3.event.transform);
|
|
});
|
|
svg.call(zoom);
|
|
|
|
// Simple function to style the tooltip for the given node.
|
|
var styleTooltip = function(name, description) {
|
|
return "<p class='name'>" + name + "</p><p class='description'>"
|
|
+ description + "</p>";
|
|
};
|
|
|
|
// Run the renderer. This is what draws the final graph.
|
|
render(inner, g);
|
|
|
|
inner.selectAll("g.node").attr("title", function(v) {
|
|
return styleTooltip(v, g.node(v).description)
|
|
}).each(function(v) {
|
|
$(this).tipsy({
|
|
gravity : "w",
|
|
opacity : 1,
|
|
html : true
|
|
});
|
|
});
|
|
var initialScale = 0.75;
|
|
|
|
var tWidth = (svg._groups[0][0].clientWidth - g.graph().width * initialScale) / 2; //水平居中
|
|
|
|
// Center the graph
|
|
svg.call(zoom.transform, d3.zoomIdentity.translate(tWidth, 20)
|
|
.scale(initialScale));
|
|
|
|
svg.attr('height', g.graph().height * initialScale + 40);
|
|
}
|