summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Levy <alon@pobox.com>2015-04-05 18:08:55 +0300
committerAlon Levy <alon@pobox.com>2015-04-05 18:10:24 +0300
commit574cc751946fa0949a484ef1109682b57a53ef89 (patch)
treeb03d72f1aa4ee61b5e707f29ffc9aa788c85fb37 /src
parent18194d66ebe18a15fe2e3837f024740ffd5d146a (diff)
client: selection: enable selection of link via 0 depth selection of both nodes; resolve #393
shift selection still works, but now it's a bit not obvious when you shift select a link: - it acts as inverting the source and destination node. - an alternative could be to special case for both or single or none of the nodes already selected - a correct fix would be to track separately the nodes and links selection states. Right now we only have a nodes selection state (array of root nodes, the ones the user selected, and array of selected nodes, the ones we highlight as such).
Diffstat (limited to 'src')
-rw-r--r--src/client/view/graph_view.js10
-rw-r--r--src/client/view/selection.js63
2 files changed, 54 insertions, 19 deletions
diff --git a/src/client/view/graph_view.js b/src/client/view/graph_view.js
index 75bd8cef..f8f1c4ad 100644
--- a/src/client/view/graph_view.js
+++ b/src/client/view/graph_view.js
@@ -399,7 +399,7 @@ function GraphView(spec) {
}
if (!temporary) {
svgInput.enable(this.querySelector('text'), d, nodeTextX(d));
- (d3.event.shiftKey ? selection.invert : selection.update)([d]);
+ (d3.event.shiftKey ? selection.invert_nodes : selection.select_nodes)([d]);
showNodeInfo(graph.find_node__by_id(model_id_from_dom_id(this.id)));
}
d3.event.stopPropagation();
@@ -510,16 +510,14 @@ function GraphView(spec) {
// after this events bubbles to the svg element
return;
}
- var that = this,
- src = this.link.__src,
- dst = this.link.__dst;
+ var that = this;
view.edge_info.on_delete(function () {
view.edge_info.hide();
graph.links__delete([that.link.id]);
});
view.edge_info.show(d);
- (d3.event.shiftKey? selection.invert : selection.update)([src, dst]);
+ (d3.event.shiftKey? selection.invert_link : selection.select_link)(this.link);
});
//var selected_N = selection:
@@ -682,7 +680,7 @@ function GraphView(spec) {
return;
}
d3.event.stopPropagation();
- (d3.event.shiftKey ? selection.invert : selection.update)([d]);
+ (d3.event.shiftKey ? selection.invert_nodes : selection.select_nodes)([d]);
if(!temporary) {
showNodeInfo(d);
}
diff --git a/src/client/view/selection.js b/src/client/view/selection.js
index 2805ba44..25f8cbed 100644
--- a/src/client/view/selection.js
+++ b/src/client/view/selection.js
@@ -65,7 +65,7 @@ function listen_on_diff_bus(diffBus)
return get_main_graph().find_node__by_id(n.id) !== null;
});
// reselect based on current graph
- inner_update(root_nodes);
+ inner_select_nodes(root_nodes);
});
}
@@ -137,7 +137,7 @@ function links_to_nodes(links)
function byVisitors(node_selector, link_selector) {
var new_selection = get_main_graph().find__by_visitors(node_selector, link_selector);
- inner_update(sum_nodes(new_selection.nodes, links_to_nodes(new_selection.links)));
+ inner_select_nodes(sum_nodes(new_selection.nodes, links_to_nodes(new_selection.links)));
}
function connectedComponent(nodes) {
@@ -171,9 +171,9 @@ function connectedComponent(nodes) {
break;
};
}
+ // XXX side effect, should not be here
nodes.forEach(function (n) { n.state = 'chosen'; });
- selected_nodes = connected.nodes.map(function (d) { return d.node; }).concat(nodes.slice());
- updateSelectedNodesBus(nodes, selected_nodes);
+ return connected.nodes.map(function (d) { return d.node; }).concat(nodes.slice());
}
var node_selected = function(node) {
@@ -221,25 +221,60 @@ function arr_compare(a1, a2)
return true;
}
-var inner_update = function(nodes)
+var inner_select_nodes = function(nodes)
{
- get_main_graph_view().nodes__user_visible(nodes);
- connectedComponent(nodes);
+ inner_select(nodes, connectedComponent(nodes));
}
-var update = function(nodes)
+var select_nodes = function(nodes)
{
var new_nodes = nodes;
var not_same = !arr_compare(new_nodes, root_nodes);
if (not_same) {
- inner_update(new_nodes);
+ inner_select_nodes(new_nodes);
}
}
-var invert = function(nodes)
+var inner_select = function(new_root_nodes, new_selected_nodes)
{
- update(_.union(_.difference(root_nodes, nodes), _.difference(nodes, root_nodes)));
+ if (arr_compare(new_root_nodes, root_nodes) && arr_compare(new_selected_nodes, selected_nodes)) {
+ // no change
+ return;
+ }
+ get_main_graph_view().nodes__user_visible(new_selected_nodes);
+ updateSelectedNodesBus(new_root_nodes, new_selected_nodes);
+}
+
+function nodes_from_link(link)
+{
+ return [link.__src, link.__dst];
+}
+
+var select_link = function(link)
+{
+ var new_root_nodes = nodes_from_link(link);
+
+ inner_select(new_root_nodes, new_root_nodes);
+}
+
+function invert(initial, inverted)
+{
+ return _.union(_.difference(initial, inverted), _.difference(inverted, initial));
+}
+
+var invert_link = function(link)
+{
+ var link_nodes = nodes_from_link(link),
+ new_root_nodes = invert(root_nodes, link_nodes),
+ new_selected_nodes = invert(selected_nodes, link_nodes);
+
+ inner_select(new_root_nodes, new_selected_nodes);
+}
+
+var invert_nodes = function(nodes)
+{
+ select_nodes(invert(root_nodes, nodes));
}
var setup_toolbar = function(main_graph)
@@ -289,8 +324,10 @@ return {
connectedComponent: connectedComponent,
is_empty: is_empty,
clear: clear,
- invert: invert,
- update: update,
+ select_nodes: select_nodes,
+ invert_nodes: invert_nodes,
+ select_link: select_link,
+ invert_link: invert_link,
selected_class__node: selected_class__node,
selected_class__link: selected_class__link,
node_selected: node_selected,