bdcontract-web-ide/js/controlflow.js

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