| Index: tools/turbolizer/graph-view.js
|
| diff --git a/tools/turbolizer/graph-view.js b/tools/turbolizer/graph-view.js
|
| index aa1b638f57ba248de205754882c872ff48231405..efddc90a7d8b771f4134aa8ebf1fca8edf952d52 100644
|
| --- a/tools/turbolizer/graph-view.js
|
| +++ b/tools/turbolizer/graph-view.js
|
| @@ -173,16 +173,30 @@ class GraphView extends View {
|
| if (d3.event.keyCode == 13) {
|
| graph.state.selection.clear();
|
| var reg = new RegExp(this.value);
|
| + var filterFunction = function(n) {
|
| + return (reg.exec(n.getDisplayLabel()) != null ||
|
| + (graph.state.showTypes && reg.exec(n.getDisplayType())) ||
|
| + reg.exec(n.opcode) != null);
|
| + };
|
| + if (d3.event.ctrlKey) {
|
| + graph.nodes.forEach(function(n, i) {
|
| + if (filterFunction(n)) {
|
| + n.visible = true;
|
| + }
|
| + });
|
| + graph.updateGraphVisibility();
|
| + }
|
| var selected = graph.visibleNodes.each(function(n) {
|
| - if (reg.exec(n.getDisplayLabel()) != null ||
|
| - (graph.state.showTypes && reg.exec(n.getDisplayType())) ||
|
| - reg.exec(n.opcode) != null) {
|
| + if (filterFunction(n)) {
|
| graph.state.selection.select(this, true);
|
| }
|
| });
|
| + graph.connectVisibleSelectedNodes();
|
| + graph.updateGraphVisibility();
|
| this.blur();
|
| graph.viewSelection();
|
| }
|
| + d3.event.stopPropagation();
|
| });
|
|
|
| // listen for key events
|
| @@ -243,9 +257,10 @@ class GraphView extends View {
|
| }
|
|
|
| initializeContent(data, rememberedSelection) {
|
| - this.createGraph(data);
|
| + this.createGraph(data, rememberedSelection);
|
| if (rememberedSelection != null) {
|
| this.attachSelection(rememberedSelection);
|
| + this.connectVisibleSelectedNodes();
|
| }
|
| this.updateGraphVisibility();
|
| }
|
| @@ -259,7 +274,7 @@ class GraphView extends View {
|
| }
|
| };
|
|
|
| - createGraph(data) {
|
| + createGraph(data, initiallyVisibileIds) {
|
| var g = this;
|
| g.nodes = data.nodes;
|
| g.nodeMap = [];
|
| @@ -298,6 +313,11 @@ class GraphView extends View {
|
| });
|
| g.nodes.forEach(function(n, i) {
|
| n.visible = isNodeInitiallyVisible(n);
|
| + if (initiallyVisibileIds != undefined) {
|
| + if (initiallyVisibileIds.has(n.id)) {
|
| + n.visible = true;
|
| + }
|
| + }
|
| });
|
| g.fitGraphViewToWindow();
|
| g.updateGraphVisibility();
|
| @@ -306,6 +326,23 @@ class GraphView extends View {
|
| g.viewWholeGraph();
|
| }
|
|
|
| + connectVisibleSelectedNodes() {
|
| + var graph = this;
|
| + graph.state.selection.selection.forEach(function(element) {
|
| + var edgeNumber = 0;
|
| + element.__data__.inputs.forEach(function(edge) {
|
| + if (edge.source.visible && edge.target.visible) {
|
| + edge.visible = true;
|
| + }
|
| + });
|
| + element.__data__.outputs.forEach(function(edge) {
|
| + if (edge.source.visible && edge.target.visible) {
|
| + edge.visible = true;
|
| + }
|
| + });
|
| + });
|
| + }
|
| +
|
| updateInputAndOutputBubbles() {
|
| var g = this;
|
| var s = g.visibleBubbles;
|
| @@ -359,11 +396,11 @@ class GraphView extends View {
|
|
|
| detachSelection() {
|
| var selection = this.state.selection.detachSelection();
|
| - var result = new Set();
|
| + var s = new Set();
|
| for (var i of selection) {
|
| - result.add(i.__data__.id);
|
| + s.add(i.__data__.id);
|
| };
|
| - return result;
|
| + return s;
|
| }
|
|
|
| pathMouseDown(path, d) {
|
| @@ -436,6 +473,17 @@ class GraphView extends View {
|
| });
|
| }
|
|
|
| + selectAllNodes(inEdges, filter) {
|
| + var graph = this;
|
| + if (!d3.event.shiftKey) {
|
| + graph.state.selection.clear();
|
| + }
|
| + graph.visibleNodes.each(function(n) {
|
| + graph.state.selection.select(this, true);
|
| + });
|
| + graph.updateGraphVisibility();
|
| + }
|
| +
|
| svgMouseDown() {
|
| this.state.graphMouseDown = true;
|
| }
|
| @@ -463,36 +511,109 @@ class GraphView extends View {
|
| // Don't handle key press repetition
|
| if(state.lastKeyDown !== -1) return;
|
|
|
| - var getEdgeFrontier = function(inEdges) {
|
| + var getEdgeFrontier = function(inEdges, edgeFilter) {
|
| var frontierSet = new Set();
|
| + var newState = true;
|
| + if (d3.event.ctrlKey) {
|
| + state.selection.selection.forEach(function(element) {
|
| + var edges = inEdges ? element.__data__.inputs : element.__data__.outputs;
|
| + var edgeNumber = 0;
|
| + // Control key toggles edges rather than just turning them on
|
| + edges.forEach(function(i) {
|
| + if (edgeFilter == undefined || edgeFilter(i, edgeNumber)) {
|
| + if (i.visible) {
|
| + newState = false;
|
| + }
|
| + }
|
| + ++edgeNumber;
|
| + });
|
| + });
|
| + }
|
| state.selection.selection.forEach(function(element) {
|
| - var nodes = inEdges ? element.__data__.inputs : element.__data__.outputs;
|
| - nodes.forEach(function(i) {
|
| - i.visible = true;
|
| - var candidate = inEdges ? i.source : i.target;
|
| - candidate.visible = true;
|
| - frontierSet.add(candidate);
|
| + var edges = inEdges ? element.__data__.inputs : element.__data__.outputs;
|
| + var edgeNumber = 0;
|
| + edges.forEach(function(i) {
|
| + if (edgeFilter == undefined || edgeFilter(i, edgeNumber)) {
|
| + i.visible = newState;
|
| + if (newState) {
|
| + var candidate = inEdges ? i.source : i.target;
|
| + candidate.visible = true;
|
| + frontierSet.add(candidate);
|
| + }
|
| + }
|
| + ++edgeNumber;
|
| });
|
| });
|
| graph.updateGraphVisibility();
|
| - return graph.visibleNodes.filter(function(n) {
|
| - return frontierSet.has(n);
|
| - });
|
| + if (newState) {
|
| + return graph.visibleNodes.filter(function(n) {
|
| + return frontierSet.has(n);
|
| + });
|
| + } else {
|
| + return undefined;
|
| + }
|
| + }
|
| +
|
| + var selectNodesThroughEdges = function(inEdges, filter, reselect) {
|
| + var frontier = getEdgeFrontier(inEdges, filter);
|
| + if (frontier != undefined) {
|
| + if (reselect) {
|
| + if (!d3.event.shiftKey) {
|
| + state.selection.clear();
|
| + }
|
| + frontier.each(function(n) {
|
| + state.selection.select(this, true);
|
| + });
|
| + }
|
| + graph.updateGraphVisibility();
|
| + }
|
| + allowRepetition = false;
|
| }
|
|
|
| var allowRepetition = true;
|
| switch(d3.event.keyCode) {
|
| + case 49:
|
| + case 50:
|
| + case 51:
|
| + case 52:
|
| + case 53:
|
| + case 54:
|
| + case 55:
|
| + case 56:
|
| + case 57:
|
| + // '1'-'9'
|
| + selectNodesThroughEdges(true,
|
| + (edge, index) => { return index == (d3.event.keyCode - 49); },
|
| + false);
|
| + break;
|
| + case 67:
|
| + // 'c'
|
| + selectNodesThroughEdges(true,
|
| + (edge, index) => { return edge.type == 'control'; },
|
| + false);
|
| + break;
|
| + case 69:
|
| + // 'e'
|
| + selectNodesThroughEdges(true,
|
| + (edge, index) => { return edge.type == 'effect'; },
|
| + false);
|
| + break;
|
| + case 79:
|
| + // 'o'
|
| + selectNodesThroughEdges(false, undefined, false);
|
| + break;
|
| + case 73:
|
| + // 'i'
|
| + selectNodesThroughEdges(true, undefined, false);
|
| + break;
|
| + case 65:
|
| + // 'a'
|
| + graph.selectAllNodes();
|
| + allowRepetition = false;
|
| + break;
|
| case 38:
|
| case 40: {
|
| - var frontier = getEdgeFrontier(d3.event.keyCode == 38);
|
| - if (!d3.event.shiftKey) {
|
| - state.selection.clear();
|
| - }
|
| - frontier.each(function(n) {
|
| - state.selection.select(this, true);
|
| - });
|
| - graph.updateGraphVisibility();
|
| - allowRepetition = false;
|
| + selectNodesThroughEdges(d3.event.keyCode == 38, undefined, true);
|
| break;
|
| }
|
| }
|
|
|