private void GenerateSeparateSubgraphs(HashSet<GraphLayout.Node> nodes)
{
int processed = 0;
var combinedGraph = LayoutSubgraphs.First();
GraphLayout.Graph graph = new GraphLayout.Graph();
Queue<GraphLayout.Node> queue = new Queue<GraphLayout.Node>();
while (nodes.Count(n => n.IsSelected) > 0)
{
GraphLayout.Node currentNode;
if (queue.Count == 0)
{
if (graph.Nodes.Count > 0)
{
// Save the subgraph and subtract these nodes from the combined graph
LayoutSubgraphs.Add(graph);
nodes.ExceptWith(graph.Nodes);
combinedGraph.Nodes.ExceptWith(graph.Nodes);
graph = new GraphLayout.Graph();
}
if (nodes.Count(n => n.IsSelected) == 0) break;
currentNode = nodes.FirstOrDefault(n => n.IsSelected);
graph.Nodes.Add(currentNode);
}
else
{
currentNode = queue.Dequeue();
}
// Find all nodes in the selection which are connected directly
// to the left or to the right to the currentNode
var selectedNodes = currentNode.RightEdges.Select(e => e.EndNode)
.Union(currentNode.LeftEdges.Select(e => e.StartNode))
.Where(x => nodes.Contains(x) && x.IsSelected)
.Except(graph.Nodes).ToList();
graph.Nodes.UnionWith(selectedNodes);
graph.Edges.UnionWith(currentNode.RightEdges);
graph.Edges.UnionWith(currentNode.LeftEdges);
// If any of the incident edges are connected to unselected (outside) nodes
// then mark these edges as anchors.
graph.AnchorRightEdges.UnionWith(currentNode.RightEdges.Where(e => !e.EndNode.IsSelected));
graph.AnchorLeftEdges.UnionWith(currentNode.LeftEdges.Where(e => !e.StartNode.IsSelected));
foreach (var node in selectedNodes)
{
queue.Enqueue(node);
processed++;
}
}
}