LayOutGraph ( IGraph graph, LayoutContext layoutContext ) { AssertValid(); const String MethodName = "LayOutGraph"; this.ArgumentChecker.CheckArgumentNotNull(MethodName, "graph", graph); this.ArgumentChecker.CheckArgumentNotNull(MethodName, "layoutContext", layoutContext); LayoutContext oAdjustedLayoutContext; if (!GetAdjustedLayoutContext(graph, layoutContext, out oAdjustedLayoutContext)) { return; } // Honor the optional LayOutTheseVerticesOnly key on the graph. ICollection <IVertex> oVerticesToLayOut = GetVerticesToLayOut(graph); if (oVerticesToLayOut.Count > 0) { LayOutGraphCore(graph, oVerticesToLayOut, oAdjustedLayoutContext); LayoutMetadataUtil.MarkGraphAsLaidOut(graph); } }
LayOutGraphOnBackgroundWorker ( BackgroundWorker oBackgroundWorker, DoWorkEventArgs oDoWorkEventArgs ) { Debug.Assert(oBackgroundWorker != null); Debug.Assert(oDoWorkEventArgs != null); AssertValid(); Debug.Assert(oDoWorkEventArgs.Argument is LayOutGraphAsyncArguments); LayOutGraphAsyncArguments oLayOutGraphAsyncArguments = (LayOutGraphAsyncArguments)oDoWorkEventArgs.Argument; IGraph oGraph = oLayOutGraphAsyncArguments.Graph; LayoutContext oLayoutContext = oLayOutGraphAsyncArguments.LayoutContext; LayoutContext oAdjustedLayoutContext; if (!GetAdjustedLayoutContext(oGraph, oLayoutContext, out oAdjustedLayoutContext)) { return; } // Honor the optional LayOutTheseVerticesOnly key on the graph. ICollection <IVertex> oVerticesToLayOut = GetVerticesToLayOut(oGraph); Int32 iVerticesToLayOut = oVerticesToLayOut.Count; if (iVerticesToLayOut == 0) { return; } // Binning is supported only if the entire graph is being laid out. if (this.SupportsBinning && m_bUseBinning && iVerticesToLayOut == oGraph.Vertices.Count) { // Lay out the graph's smaller components in bins. GraphBinner oGraphBinner = new GraphBinner(); oGraphBinner.MaximumVerticesPerBin = m_iMaximumVerticesPerBin; oGraphBinner.BinLength = m_iBinLength; ICollection <IVertex> oRemainingVertices; Rectangle oRemainingRectangle; if (oGraphBinner.LayOutSmallerComponentsInBins(oGraph, oVerticesToLayOut, oAdjustedLayoutContext, out oRemainingVertices, out oRemainingRectangle)) { // The remaining vertices need to be laid out in the remaining // rectangle. oVerticesToLayOut = oRemainingVertices; oAdjustedLayoutContext = new LayoutContext(oRemainingRectangle); } else { // There are no remaining vertices, or there is no space // left. oVerticesToLayOut = new IVertex[0]; } } if (oVerticesToLayOut.Count > 0) { // Let the derived class do the work. if (!LayOutGraphCore(oGraph, oVerticesToLayOut, oAdjustedLayoutContext, oBackgroundWorker)) { // LayOutGraphAsyncCancel() was called. oDoWorkEventArgs.Cancel = true; return; } LayoutMetadataUtil.MarkGraphAsLaidOut(oGraph); } }
LayOutSmallerComponentsInBins ( IGraph graph, ICollection <IVertex> verticesToLayOut, LayoutContext layoutContext, out ICollection <IVertex> remainingVertices, out Rectangle remainingRectangle ) { AssertValid(); remainingVertices = null; remainingRectangle = Rectangle.Empty; // This method modifies some of the graph's metadata. Save the // original metadata. Boolean bOriginalGraphHasBeenLaidOut = LayoutMetadataUtil.GraphHasBeenLaidOut(graph); ICollection <IVertex> oOriginalLayOutTheseVerticesOnly = (ICollection <IVertex>)graph.GetValue( ReservedMetadataKeys.LayOutTheseVerticesOnly, typeof(ICollection <IVertex>)); // Split the vertices into strongly connected components, sorted in // increasing order of vertex count. ConnectedComponentCalculator oConnectedComponentCalculator = new ConnectedComponentCalculator(); IList <LinkedList <IVertex> > oComponents = oConnectedComponentCalculator.CalculateStronglyConnectedComponents( verticesToLayOut, graph, true); Int32 iComponents = oComponents.Count; // This object will split the graph rectangle into bin rectangles. RectangleBinner oRectangleBinner = new RectangleBinner( layoutContext.GraphRectangle, m_iBinLength); Int32 iComponent = 0; for (iComponent = 0; iComponent < iComponents; iComponent++) { LinkedList <IVertex> oComponent = oComponents[iComponent]; Int32 iVerticesInComponent = oComponent.Count; if (iVerticesInComponent > m_iMaximumVerticesPerBin) { // The vertices in the remaining components should not be // binned. break; } Rectangle oBinRectangle; if (!oRectangleBinner.TryGetNextBin(out oBinRectangle)) { // There is no room for an additional bin rectangle. break; } // Lay out the component within the bin rectangle. LayOutComponentInBin(graph, oComponent, oBinRectangle); } // Restore the original metadata on the graph. if (bOriginalGraphHasBeenLaidOut) { LayoutMetadataUtil.MarkGraphAsLaidOut(graph); } else { LayoutMetadataUtil.MarkGraphAsNotLaidOut(graph); } if (oOriginalLayOutTheseVerticesOnly != null) { graph.SetValue(ReservedMetadataKeys.LayOutTheseVerticesOnly, oOriginalLayOutTheseVerticesOnly); } else { graph.RemoveKey(ReservedMetadataKeys.LayOutTheseVerticesOnly); } if (oRectangleBinner.TryGetRemainingRectangle( out remainingRectangle)) { remainingVertices = GetRemainingVertices(oComponents, iComponent); return(remainingVertices.Count > 0); } return(false); }