// 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 += "
" + 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 += "" + l[i].replace(/\//g, ".") + "" + "
"; 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 "

" + name + "

" + description + "

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