示例#1
0
        /// <summary>
        /// An edge can define a cluster as logical head.
        /// This is used to fake edges to and from clusters by clipping the edge on the borders of the logical head.
        /// </summary>
        public void SetLogicalHead(SubGraph lhead)
        {
            if (!lhead.IsCluster())
            {
                throw new InvalidOperationException("ltail must be a cluster");
            }
            if (!MyRootGraph.IsCompound())
            {
                throw new InvalidOperationException("rootgraph must be compound for lheads/ltails to be used");
            }
            string lheadname = lhead.GetName();

            SafeSetAttribute("lhead", lheadname, "");
        }
 /// <summary>
 /// FIXME: use an actual subg equivalent to agsubedge and agsubnode
 /// https://github.com/ellson/graphviz/issues/1206
 /// This might cause a new subgraph creation.
 /// </summary>
 public void AddExisting(SubGraph subgraph)
 {
     Agsubg(_ptr, subgraph.GetName(), 1);
 }
示例#3
0
 public SubGraph OppositeLogicalEndpoint(SubGraph s)
 {
     Debug.Assert(s == LogicalTail() || s == LogicalHead());
     return(s == LogicalTail() ? LogicalHead() : LogicalTail());
 }
示例#4
0
        public void CloneInto(RootGraph target)
        {
            // Copy all nodes and edges
            foreach (var node in Nodes())
            {
                string nodename = node.GetName();
                Node   newnode  = target.GetOrAddNode(nodename);

                foreach (var edge in node.EdgesOut(this))
                {
                    Node head = edge.Head();
                    Debug.Assert(Contains(head));
                    Node tail = edge.Tail();
                    Debug.Assert(node.Equals(tail));
                    string headname = head.GetName();
                    Node   newhead  = target.GetOrAddNode(headname);
                    string tailname = tail.GetName();
                    Node   newtail  = target.GetNode(tailname);

                    string edgename = edge.GetName();
                    Edge   newedge  = target.GetOrAddEdge(newtail, newhead, edgename);
                    edge.CopyAttributesTo(newedge);
                }
                node.CopyAttributesTo(newnode);
            }

            // Copy all subgraphs
            foreach (var subgraph in Descendants())
            {
                string subgraphname = subgraph.GetName();
                Graph  parent       = subgraph.Parent();
                Graph  newparent;
                if (parent.Equals(this))
                {
                    newparent = target;
                }
                else
                {
                    string parentname = parent.GetName();
                    newparent = target.GetDescendantByName(parentname);
                    Debug.Assert(newparent != null);
                }
                SubGraph newsubgraph = newparent.GetOrAddSubgraph(subgraphname);
                subgraph.CopyAttributesTo(newsubgraph);

                // Add the (already created) nodes and edges to newly created subgraph
                foreach (var node in subgraph.Nodes())
                {
                    string nodename = node.GetName();
                    Node   newnode  = target.GetNode(nodename);
                    Debug.Assert(newnode != null);
                    newsubgraph.AddExisting(newnode);

                    foreach (var edge in node.EdgesOut(subgraph))
                    {
                        Node head = edge.Head();
                        Node tail = edge.Tail();
                        Debug.Assert(node.Equals(tail));

                        string headname = head.GetName();
                        Node   newhead  = target.GetNode(headname);
                        string tailname = tail.GetName();
                        Node   newtail  = target.GetNode(tailname);

                        string edgename = edge.GetName();
                        Edge   newedge  = target.GetEdge(newtail, newhead, edgename);
                        newsubgraph.AddExisting(newedge);
                    }
                    node.CopyAttributesTo(newnode);
                }
            }
        }
示例#5
0
        /// <summary>
        /// Create a subgraph consisting of nodes from the given nodes.
        /// Edges are added to the result if both endpoints are among the nodes.
        /// Subgraphs are added to the result if they have nodes in the given nodelist.
        /// The names of the Subgraphs are of the form "name:subgraphname".
        ///
        /// Side effect: adds the returned subgraph (and its children) to self.
        /// </summary>
        public SubGraph AddSubgraphFromNodes(string name, IEnumerable <Node> nodes)
        {
            // Freeze the list of descendants,
            // since we are going to add subgraphs while iterating over existing subgraphs
            List <SubGraph> descendants = Descendants().ToList();

            SubGraph result = GetOrAddSubgraph(name);

            foreach (var node in nodes)
            {
                result.AddExisting(node);
            }

            Debug.Assert(result.Nodes().Count() == nodes.Count());

            // All that remains to do is to patch up the result by adding edges and subgraphs
            foreach (var node in result.Nodes())
            {
                foreach (var edge in node.EdgesOut(this))
                {
                    if (result.Contains(edge.Head()))
                    {
                        result.AddExisting(edge);
                    }
                }
            }

            Debug.Assert(result.Nodes().Count() == nodes.Count());

            // Iterate over the (frozen) existing subgraphs and add new filtered subgraphs
            // in the same hierarchical position as their unfiltered counterparts.
            foreach (var subgraph in descendants)
            {
                string filteredsubgraphname = name + ":" + subgraph.GetName();
                Debug.WriteLine("Adding filtered subgraph {0}", filteredsubgraphname);
                Graph parent = subgraph.Parent();
                Graph filteredparent;
                if (parent.Equals(this))
                {
                    filteredparent = result;
                }
                else
                {
                    string parentname = name + ":" + parent.GetName();
                    filteredparent = result.GetDescendantByName(parentname);
                    Debug.Assert(filteredparent != null);
                }

                filteredparent.AddSubgraphFilteredByNodes(filteredsubgraphname, subgraph, nodes);
            }

            Debug.Assert(result.Nodes().Count() == nodes.Count());

            // Remove subgraphs again if they are empty
            // Again, we have to freeze the descendants we are enumerating, since we are disposing on the fly
            result.SafeDeleteSubgraphs(s => !s.Nodes().Any());

            Debug.Assert(result.Nodes().Count() == nodes.Count());

            return(result);
        }
示例#6
0
 public SubGraph GetSubgraph(string name)
 {
     return(SubGraph.Get(this, name));
 }
示例#7
0
 public SubGraph GetOrAddSubgraph(string name)
 {
     return(SubGraph.GetOrCreate(this, name));
 }