| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 "use strict"; | 5 "use strict"; |
| 6 | 6 |
| 7 class GraphView extends View { | 7 class GraphView extends View { |
| 8 constructor (d3, id, nodes, edges, broker) { | 8 constructor (d3, id, nodes, edges, broker) { |
| 9 super(id, broker); | 9 super(id, broker); |
| 10 var graph = this; | 10 var graph = this; |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 static get rectClass() { | 167 static get rectClass() { |
| 168 return "nodeStyle"; | 168 return "nodeStyle"; |
| 169 } | 169 } |
| 170 static get activeEditId() { | 170 static get activeEditId() { |
| 171 return "active-editing"; | 171 return "active-editing"; |
| 172 } | 172 } |
| 173 static get nodeRadius() { | 173 static get nodeRadius() { |
| 174 return 50; | 174 return 50; |
| 175 } | 175 } |
| 176 | 176 |
| 177 getNodeHeight(graph) { | 177 getNodeHeight(d) { |
| 178 if (this.state.showTypes) { | 178 if (this.state.showTypes) { |
| 179 return DEFAULT_NODE_HEIGHT + TYPE_HEIGHT; | 179 return d.normalheight + d.labelbbox.height; |
| 180 } else { | 180 } else { |
| 181 return DEFAULT_NODE_HEIGHT; | 181 return d.normalheight; |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 getEdgeFrontier(nodes, inEdges, edgeFilter) { | 185 getEdgeFrontier(nodes, inEdges, edgeFilter) { |
| 186 let frontier = new Set(); | 186 let frontier = new Set(); |
| 187 nodes.forEach(function(element) { | 187 nodes.forEach(function(element) { |
| 188 var edges = inEdges ? element.__data__.inputs : element.__data__.outputs; | 188 var edges = inEdges ? element.__data__.inputs : element.__data__.outputs; |
| 189 var edgeNumber = 0; | 189 var edgeNumber = 0; |
| 190 edges.forEach(function(edge) { | 190 edges.forEach(function(edge) { |
| 191 if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) { | 191 if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 | 247 |
| 248 deleteContent() { | 248 deleteContent() { |
| 249 if (this.visibleNodes) { | 249 if (this.visibleNodes) { |
| 250 this.nodes = []; | 250 this.nodes = []; |
| 251 this.edges = []; | 251 this.edges = []; |
| 252 this.nodeMap = []; | 252 this.nodeMap = []; |
| 253 this.updateGraphVisibility(); | 253 this.updateGraphVisibility(); |
| 254 } | 254 } |
| 255 }; | 255 }; |
| 256 | 256 |
| 257 measureText(text) { |
| 258 var textMeasure = document.getElementById('text-measure'); |
| 259 textMeasure.textContent = text; |
| 260 return { |
| 261 width: textMeasure.getBBox().width, |
| 262 height: textMeasure.getBBox().height, |
| 263 }; |
| 264 } |
| 265 |
| 257 createGraph(data, initiallyVisibileIds) { | 266 createGraph(data, initiallyVisibileIds) { |
| 258 var g = this; | 267 var g = this; |
| 259 g.nodes = data.nodes; | 268 g.nodes = data.nodes; |
| 260 g.nodeMap = []; | 269 g.nodeMap = []; |
| 261 var textMeasure = document.getElementById('text-measure'); | |
| 262 g.nodes.forEach(function(n, i){ | 270 g.nodes.forEach(function(n, i){ |
| 263 n.__proto__ = Node; | 271 n.__proto__ = Node; |
| 264 n.visible = false; | 272 n.visible = false; |
| 265 n.x = 0; | 273 n.x = 0; |
| 266 n.y = 0; | 274 n.y = 0; |
| 267 n.rank = MAX_RANK_SENTINEL; | 275 n.rank = MAX_RANK_SENTINEL; |
| 268 n.inputs = []; | 276 n.inputs = []; |
| 269 n.outputs = []; | 277 n.outputs = []; |
| 270 n.rpo = -1; | 278 n.rpo = -1; |
| 271 n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; | 279 n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH; |
| 272 n.cfg = n.control; | 280 n.cfg = n.control; |
| 273 g.nodeMap[n.id] = n; | 281 g.nodeMap[n.id] = n; |
| 274 n.displayLabel = n.getDisplayLabel(); | 282 n.displayLabel = n.getDisplayLabel(); |
| 275 textMeasure.textContent = n.getDisplayLabel(); | 283 n.labelbbox = g.measureText(n.displayLabel); |
| 276 var width = textMeasure.getComputedTextLength(); | 284 n.typebbox = g.measureText(n.getDisplayType()); |
| 277 textMeasure.textContent = n.getDisplayType(); | 285 var innerwidth = Math.max(n.labelbbox.width, n.typebbox.width); |
| 278 width = Math.max(width, textMeasure.getComputedTextLength()); | 286 n.width = Math.alignUp(innerwidth + NODE_INPUT_WIDTH * 2, |
| 279 n.width = Math.alignUp(width + NODE_INPUT_WIDTH * 2, | |
| 280 NODE_INPUT_WIDTH); | 287 NODE_INPUT_WIDTH); |
| 288 var innerheight = Math.max(n.labelbbox.height, n.typebbox.height); |
| 289 n.normalheight = innerheight + 20; |
| 281 }); | 290 }); |
| 282 g.edges = []; | 291 g.edges = []; |
| 283 data.edges.forEach(function(e, i){ | 292 data.edges.forEach(function(e, i){ |
| 284 var t = g.nodeMap[e.target]; | 293 var t = g.nodeMap[e.target]; |
| 285 var s = g.nodeMap[e.source]; | 294 var s = g.nodeMap[e.source]; |
| 286 var newEdge = new Edge(t, e.index, s, e.type); | 295 var newEdge = new Edge(t, e.index, s, e.type); |
| 287 t.inputs.push(newEdge); | 296 t.inputs.push(newEdge); |
| 288 s.outputs.push(newEdge); | 297 s.outputs.push(newEdge); |
| 289 g.edges.push(newEdge); | 298 g.edges.push(newEdge); |
| 290 if (e.type == 'control') { | 299 if (e.type == 'control') { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 return !edge.isVisible(); | 358 return !edge.isVisible(); |
| 350 } else { | 359 } else { |
| 351 return g.nodeMap[components[1]].areAnyOutputsVisible() == 0; | 360 return g.nodeMap[components[1]].areAnyOutputsVisible() == 0; |
| 352 } | 361 } |
| 353 }); | 362 }); |
| 354 s.each(function(c) { | 363 s.each(function(c) { |
| 355 var components = this.id.split(','); | 364 var components = this.id.split(','); |
| 356 if (components[0] == "ob") { | 365 if (components[0] == "ob") { |
| 357 var from = g.nodeMap[components[1]]; | 366 var from = g.nodeMap[components[1]]; |
| 358 var x = from.getOutputX(); | 367 var x = from.getOutputX(); |
| 359 var y = g.getNodeHeight() + DEFAULT_NODE_BUBBLE_RADIUS / 2 + 4; | 368 var y = g.getNodeHeight(from) + DEFAULT_NODE_BUBBLE_RADIUS; |
| 360 var transform = "translate(" + x + "," + y + ")"; | 369 var transform = "translate(" + x + "," + y + ")"; |
| 361 this.setAttribute('transform', transform); | 370 this.setAttribute('transform', transform); |
| 362 } | 371 } |
| 363 }); | 372 }); |
| 364 } | 373 } |
| 365 | 374 |
| 366 attachSelection(s) { | 375 attachSelection(s) { |
| 367 var graph = this; | 376 var graph = this; |
| 368 if (s.size != 0) { | 377 if (s.size != 0) { |
| 369 this.visibleNodes.each(function(n) { | 378 this.visibleNodes.each(function(n) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 468 } |
| 460 | 469 |
| 461 showAllAction(graph) { | 470 showAllAction(graph) { |
| 462 graph.nodes.filter(function(n) { n.visible = true; }) | 471 graph.nodes.filter(function(n) { n.visible = true; }) |
| 463 graph.edges.filter(function(e) { e.visible = true; }) | 472 graph.edges.filter(function(e) { e.visible = true; }) |
| 464 graph.updateGraphVisibility(); | 473 graph.updateGraphVisibility(); |
| 465 graph.viewWholeGraph(); | 474 graph.viewWholeGraph(); |
| 466 } | 475 } |
| 467 | 476 |
| 468 hideDeadAction(graph) { | 477 hideDeadAction(graph) { |
| 469 graph.nodes.filter(function(n) { if (!n.live) n.visible = false; }) | 478 graph.nodes.filter(function(n) { if (!n.isLive()) n.visible = false; }) |
| 470 graph.updateGraphVisibility(); | 479 graph.updateGraphVisibility(); |
| 471 } | 480 } |
| 472 | 481 |
| 473 hideUnselectedAction(graph) { | 482 hideUnselectedAction(graph) { |
| 474 var unselected = graph.visibleNodes.filter(function(n) { | 483 var unselected = graph.visibleNodes.filter(function(n) { |
| 475 return !this.classList.contains("selected"); | 484 return !this.classList.contains("selected"); |
| 476 }); | 485 }); |
| 477 unselected.each(function(n) { | 486 unselected.each(function(n) { |
| 478 n.visible = false; | 487 n.visible = false; |
| 479 }); | 488 }); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 graph.visibleEdges = visibleEdges; | 727 graph.visibleEdges = visibleEdges; |
| 719 | 728 |
| 720 // update existing nodes | 729 // update existing nodes |
| 721 var filteredNodes = graph.nodes.filter(function(n) { return n.visible; }); | 730 var filteredNodes = graph.nodes.filter(function(n) { return n.visible; }); |
| 722 graph.visibleNodes = graph.visibleNodes.data(filteredNodes, function(d) { | 731 graph.visibleNodes = graph.visibleNodes.data(filteredNodes, function(d) { |
| 723 return d.id; | 732 return d.id; |
| 724 }); | 733 }); |
| 725 graph.visibleNodes.attr("transform", function(n){ | 734 graph.visibleNodes.attr("transform", function(n){ |
| 726 return "translate(" + n.x + "," + n.y + ")"; | 735 return "translate(" + n.x + "," + n.y + ")"; |
| 727 }).select('rect'). | 736 }).select('rect'). |
| 728 attr(HEIGHT, function(d) { return graph.getNodeHeight(); }); | 737 attr(HEIGHT, function(d) { return graph.getNodeHeight(d); }); |
| 729 | 738 |
| 730 // add new nodes | 739 // add new nodes |
| 731 var newGs = graph.visibleNodes.enter() | 740 var newGs = graph.visibleNodes.enter() |
| 732 .append("g"); | 741 .append("g"); |
| 733 | 742 |
| 734 newGs.classed("control", function(n) { return n.isControl(); }) | 743 newGs.classed("control", function(n) { return n.isControl(); }) |
| 735 .classed("live", function(n) { return n.isLive(); }) | 744 .classed("live", function(n) { return n.isLive(); }) |
| 736 .classed("dead", function(n) { return !n.isLive(); }) | 745 .classed("dead", function(n) { return !n.isLive(); }) |
| 737 .classed("javascript", function(n) { return n.isJavaScript(); }) | 746 .classed("javascript", function(n) { return n.isJavaScript(); }) |
| 738 .classed("input", function(n) { return n.isInput(); }) | 747 .classed("input", function(n) { return n.isInput(); }) |
| 739 .classed("simplified", function(n) { return n.isSimplified(); }) | 748 .classed("simplified", function(n) { return n.isSimplified(); }) |
| 740 .classed("machine", function(n) { return n.isMachine(); }) | 749 .classed("machine", function(n) { return n.isMachine(); }) |
| 741 .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")
";}) | 750 .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")
";}) |
| 742 .on("mousedown", function(d){ | 751 .on("mousedown", function(d){ |
| 743 graph.nodeMouseDown.call(graph, d3.select(this), d); | 752 graph.nodeMouseDown.call(graph, d3.select(this), d); |
| 744 }) | 753 }) |
| 745 .on("mouseup", function(d){ | 754 .on("mouseup", function(d){ |
| 746 graph.nodeMouseUp.call(graph, d3.select(this), d); | 755 graph.nodeMouseUp.call(graph, d3.select(this), d); |
| 747 }) | 756 }) |
| 748 .call(graph.drag); | 757 .call(graph.drag); |
| 749 | 758 |
| 750 newGs.append("rect") | 759 newGs.append("rect") |
| 751 .attr("rx", 10) | 760 .attr("rx", 10) |
| 752 .attr("ry", 10) | 761 .attr("ry", 10) |
| 753 .attr(WIDTH, function(d) { return d.getTotalNodeWidth(); }) | 762 .attr(WIDTH, function(d) { |
| 754 .attr(HEIGHT, function(d) { return graph.getNodeHeight(); }) | 763 return d.getTotalNodeWidth(); |
| 764 }) |
| 765 .attr(HEIGHT, function(d) { |
| 766 return graph.getNodeHeight(d); |
| 767 }) |
| 755 | 768 |
| 756 function appendInputAndOutputBubbles(g, d) { | 769 function appendInputAndOutputBubbles(g, d) { |
| 757 for (var i = 0; i < d.inputs.length; ++i) { | 770 for (var i = 0; i < d.inputs.length; ++i) { |
| 758 var x = d.getInputX(i); | 771 var x = d.getInputX(i); |
| 759 var y = -DEFAULT_NODE_BUBBLE_RADIUS / 2 - 4; | 772 var y = -DEFAULT_NODE_BUBBLE_RADIUS; |
| 760 var s = g.append('circle') | 773 var s = g.append('circle') |
| 761 .classed("filledBubbleStyle", function(c) { | 774 .classed("filledBubbleStyle", function(c) { |
| 762 return d.inputs[i].isVisible(); | 775 return d.inputs[i].isVisible(); |
| 763 } ) | 776 } ) |
| 764 .classed("bubbleStyle", function(c) { | 777 .classed("bubbleStyle", function(c) { |
| 765 return !d.inputs[i].isVisible(); | 778 return !d.inputs[i].isVisible(); |
| 766 } ) | 779 } ) |
| 767 .attr("id", "ib," + d.inputs[i].stringID()) | 780 .attr("id", "ib," + d.inputs[i].stringID()) |
| 768 .attr("r", DEFAULT_NODE_BUBBLE_RADIUS) | 781 .attr("r", DEFAULT_NODE_BUBBLE_RADIUS) |
| 769 .attr("transform", function(d) { | 782 .attr("transform", function(d) { |
| 770 return "translate(" + x + "," + y + ")"; | 783 return "translate(" + x + "," + y + ")"; |
| 771 }) | 784 }) |
| 772 .on("mousedown", function(d){ | 785 .on("mousedown", function(d){ |
| 773 var components = this.id.split(','); | 786 var components = this.id.split(','); |
| 774 var node = graph.nodeMap[components[3]]; | 787 var node = graph.nodeMap[components[3]]; |
| 775 var edge = node.inputs[components[2]]; | 788 var edge = node.inputs[components[2]]; |
| 776 var visible = !edge.isVisible(); | 789 var visible = !edge.isVisible(); |
| 777 node.setInputVisibility(components[2], visible); | 790 node.setInputVisibility(components[2], visible); |
| 778 d3.event.stopPropagation(); | 791 d3.event.stopPropagation(); |
| 779 graph.updateGraphVisibility(); | 792 graph.updateGraphVisibility(); |
| 780 }); | 793 }); |
| 781 } | 794 } |
| 782 if (d.outputs.length != 0) { | 795 if (d.outputs.length != 0) { |
| 783 var x = d.getOutputX(); | 796 var x = d.getOutputX(); |
| 784 var y = graph.getNodeHeight() + DEFAULT_NODE_BUBBLE_RADIUS / 2 + 4; | 797 var y = graph.getNodeHeight(d) + DEFAULT_NODE_BUBBLE_RADIUS; |
| 785 var s = g.append('circle') | 798 var s = g.append('circle') |
| 786 .classed("filledBubbleStyle", function(c) { | 799 .classed("filledBubbleStyle", function(c) { |
| 787 return d.areAnyOutputsVisible() == 2; | 800 return d.areAnyOutputsVisible() == 2; |
| 788 } ) | 801 } ) |
| 789 .classed("halFilledBubbleStyle", function(c) { | 802 .classed("halFilledBubbleStyle", function(c) { |
| 790 return d.areAnyOutputsVisible() == 1; | 803 return d.areAnyOutputsVisible() == 1; |
| 791 } ) | 804 } ) |
| 792 .classed("bubbleStyle", function(c) { | 805 .classed("bubbleStyle", function(c) { |
| 793 return d.areAnyOutputsVisible() == 0; | 806 return d.areAnyOutputsVisible() == 0; |
| 794 } ) | 807 } ) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 806 } | 819 } |
| 807 | 820 |
| 808 newGs.each(function(d){ | 821 newGs.each(function(d){ |
| 809 appendInputAndOutputBubbles(d3.select(this), d); | 822 appendInputAndOutputBubbles(d3.select(this), d); |
| 810 }); | 823 }); |
| 811 | 824 |
| 812 newGs.each(function(d){ | 825 newGs.each(function(d){ |
| 813 d3.select(this).append("text") | 826 d3.select(this).append("text") |
| 814 .classed("label", true) | 827 .classed("label", true) |
| 815 .attr("text-anchor","right") | 828 .attr("text-anchor","right") |
| 816 .attr("dx", "5") | 829 .attr("dx", 5) |
| 817 .attr("dy", DEFAULT_NODE_HEIGHT / 2 + 5) | 830 .attr("dy", 5) |
| 818 .append('tspan') | 831 .append('tspan') |
| 819 .text(function(l) { | 832 .text(function(l) { |
| 820 return d.getDisplayLabel(); | 833 return d.getDisplayLabel(); |
| 821 }) | 834 }) |
| 822 .append("title") | 835 .append("title") |
| 823 .text(function(l) { | 836 .text(function(l) { |
| 824 return d.getTitle(); | 837 return d.getTitle(); |
| 825 }) | 838 }) |
| 826 if (d.type != undefined) { | 839 if (d.type != undefined) { |
| 827 d3.select(this).append("text") | 840 d3.select(this).append("text") |
| 828 .classed("label", true) | 841 .classed("label", true) |
| 829 .classed("type", true) | 842 .classed("type", true) |
| 830 .attr("text-anchor","right") | 843 .attr("text-anchor","right") |
| 831 .attr("dx", "5") | 844 .attr("dx", 5) |
| 832 .attr("dy", DEFAULT_NODE_HEIGHT / 2 + TYPE_HEIGHT + 5) | 845 .attr("dy", d.labelbbox.height + 5) |
| 833 .append('tspan') | 846 .append('tspan') |
| 834 .text(function(l) { | 847 .text(function(l) { |
| 835 return d.getDisplayType(); | 848 return d.getDisplayType(); |
| 836 }) | 849 }) |
| 837 .append("title") | 850 .append("title") |
| 838 .text(function(l) { | 851 .text(function(l) { |
| 839 return d.getType(); | 852 return d.getType(); |
| 840 }) | 853 }) |
| 841 } | 854 } |
| 842 }); | 855 }); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 var graph = this; | 992 var graph = this; |
| 980 var minX, maxX, minY, maxY; | 993 var minX, maxX, minY, maxY; |
| 981 var hasSelection = false; | 994 var hasSelection = false; |
| 982 graph.visibleNodes.each(function(n) { | 995 graph.visibleNodes.each(function(n) { |
| 983 if (this.classList.contains("selected")) { | 996 if (this.classList.contains("selected")) { |
| 984 hasSelection = true; | 997 hasSelection = true; |
| 985 minX = minX ? Math.min(minX, n.x) : n.x; | 998 minX = minX ? Math.min(minX, n.x) : n.x; |
| 986 maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) : | 999 maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) : |
| 987 n.x + n.getTotalNodeWidth(); | 1000 n.x + n.getTotalNodeWidth(); |
| 988 minY = minY ? Math.min(minY, n.y) : n.y; | 1001 minY = minY ? Math.min(minY, n.y) : n.y; |
| 989 maxY = maxY ? Math.max(maxY, n.y + DEFAULT_NODE_HEIGHT) : | 1002 maxY = maxY ? Math.max(maxY, n.y + graph.getNodeHeight(n)) : |
| 990 n.y + DEFAULT_NODE_HEIGHT; | 1003 n.y + graph.getNodeHeight(n); |
| 991 } | 1004 } |
| 992 }); | 1005 }); |
| 993 if (hasSelection) { | 1006 if (hasSelection) { |
| 994 graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, | 1007 graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60, |
| 995 maxX + NODE_INPUT_WIDTH, maxY + 60, | 1008 maxX + NODE_INPUT_WIDTH, maxY + 60, |
| 996 true); | 1009 true); |
| 997 } | 1010 } |
| 998 } | 1011 } |
| 999 | 1012 |
| 1000 viewGraphRegion(minX, minY, maxX, maxY, transition) { | 1013 viewGraphRegion(minX, minY, maxX, maxY, transition) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1011 } | 1024 } |
| 1012 | 1025 |
| 1013 viewWholeGraph() { | 1026 viewWholeGraph() { |
| 1014 var graph = this; | 1027 var graph = this; |
| 1015 var minScale = graph.minScale(); | 1028 var minScale = graph.minScale(); |
| 1016 var translation = [0, 0]; | 1029 var translation = [0, 0]; |
| 1017 translation = graph.getVisibleTranslation(translation, minScale); | 1030 translation = graph.getVisibleTranslation(translation, minScale); |
| 1018 graph.translateClipped(translation, minScale); | 1031 graph.translateClipped(translation, minScale); |
| 1019 } | 1032 } |
| 1020 } | 1033 } |
| OLD | NEW |