/// <summary> /// constructor /// </summary> /// <param name="layeredGraph"></param> /// <param name="la"></param> /// <param name="database"></param> /// <param name="intGraphP"></param> LayerInserter( ProperLayeredGraph layeredGraph, LayerArrays la, Database database, BasicGraph<Node, IntEdge> intGraphP) { this.la = la; this.database = database; this.layeredGraph = layeredGraph; this.intGraph = intGraphP; }
MetroMapOrdering(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays, Dictionary <int, Point> nodePositions) { this.properLayeredGraph = properLayeredGraph; this.layerArrays = layerArrays; this.nodePositions = nodePositions; }
static Dictionary <int, Point> BuildInitialNodePositions(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { var result = new Dictionary <int, Point>(); for (int i = 0; i < layerArrays.Layers.Length; i++) { int prev = 0, curr = 0; while (curr < layerArrays.Layers[i].Length) { while (curr < layerArrays.Layers[i].Length && properLayeredGraph.IsVirtualNode(layerArrays.Layers[i][curr])) { curr++; } for (int j = prev; j < curr; j++) { result[layerArrays.Layers[i][j]] = new Point(i, prev); } if (curr < layerArrays.Layers[i].Length) { result[layerArrays.Layers[i][curr]] = new Point(i, curr); } curr++; prev = curr; } } return(result); }
/// <summary> /// Creating buckets for multi edges and allocating the graph. /// </summary> private void CreateFullLayeredGraph() { totalNodes = this.intGraph.NodeCount; foreach (List <IntEdge> list in database.RegularMultiedges) { int span = 0; bool first = true; foreach (IntEdge e in list) { if (first) { first = false; span = e.LayerSpan * 2; } if (span > 0) { e.LayerEdges = new LayerEdge[span]; for (int i = 0; i < span; i++) { int source = EdgePathsInserter.GetSource(ref totalNodes, e, i); int target = EdgePathsInserter.GetTarget(ref totalNodes, e, i, span); e.LayerEdges[i] = new LayerEdge(source, target, e.CrossingWeight); } LayerInserter.RegisterDontStepOnVertex(this.database, e); } } } this.nLayeredGraph = new ProperLayeredGraph(this.intGraph); }
static LayerEdge[] EdgesOfStrip(int[] bottomVerts, ProperLayeredGraph properLayeredGraph) { LayerEdge[] edges = (from v in bottomVerts from e in properLayeredGraph.InEdges(v) select e).ToArray(); return(edges); }
static internal void InsertPaths( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph<Node, IntEdge> intGraphP) { EdgePathsInserter li = new EdgePathsInserter(layeredGraph, la, db, intGraphP); li.InsertPaths(); layeredGraph = li.NLayeredGraph; la = li.Nla; }
///// <summary> ///// the entry point of the class ///// </summary> ///// <param name="layeredGraph"></param> ///// <param name="la"></param> ///// <param name="db"></param> static internal void InsertLayers( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph<Node, IntEdge> intGraphP) { LayerInserter li = new LayerInserter(layeredGraph, la, db, intGraphP); li.InsertLayers(); layeredGraph = li.NLayeredGraph; la = li.Nla.DropEmptyLayers(); }
static internal void InsertPaths( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph <Node, IntEdge> intGraphP) { EdgePathsInserter li = new EdgePathsInserter(layeredGraph, la, db, intGraphP); li.InsertPaths(); layeredGraph = li.NLayeredGraph; la = li.Nla; }
/// <summary> /// Creates a smoothed polyline /// </summary> internal SmoothedPolylineCalculator(IntEdge edgePathPar, Anchor[] anchorsP, GeometryGraph origGraph, SugiyamaLayoutSettings settings, LayerArrays la, ProperLayeredGraph layerGraph, Database databaseP) { this.database = databaseP; edgePath = edgePathPar; anchors = anchorsP; this.layerArrays = la; this.originalGraph = origGraph; this.settings = settings; this.layeredGraph = layerGraph; rightHierarchy = BuildRightHierarchy(); leftHierarchy = BuildLeftHierarchy(); }
internal static int GetCrossingsTotal(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { int x = 0; for (int i = 0; i < layerArrays.Layers.Length - 1; i++) { x += GetCrossingCountFromStrip(i, properLayeredGraph, layerArrays); } return(x); }
void CreateProperLayeredGraph() { IEnumerable <IntEdge> edges = CreatePathEdgesOnIntGraph(); var nodeCount = Math.Max(intGraph.NodeCount, BasicGraph <Node, IntEdge> .VertexCount(edges)); var baseGraph = new BasicGraph <Node, IntEdge>(edges, nodeCount) { Nodes = intGraph.Nodes }; ProperLayeredGraph = new ProperLayeredGraph(baseGraph); }
internal AdjacentSwapsWithConstraints(LayerArrays layerArray, bool hasCrossWeights, ProperLayeredGraph properLayeredGraph, LayerInfo[] layerInfos) { X = layerArray.X; layering = layerArray.Y; layers = layerArray.Layers; this.properLayeredGraph = properLayeredGraph; this.hasCrossWeights = hasCrossWeights; this.layerInfos = layerInfos; }
internal Routing(SugiyamaLayoutSettings settings, GeometryGraph originalGraph, Database dbP, LayerArrays yLayerArrays, ProperLayeredGraph properLayeredGraph, BasicGraph<Node, IntEdge> intGraph ) { this.settings = settings; OriginalGraph = originalGraph; Database = dbP; ProperLayeredGraph = properLayeredGraph; LayerArrays = yLayerArrays; IntGraph = intGraph; }
int weightMultiplierOfTwoVirtual = 8; //weight multiplier for edges with two virtual nodes internal XLayoutGraph(BasicGraph <IntEdge> graph, //DAG of the original graph with no multiple edges ProperLayeredGraph layeredGraph, LayerArrays layerArrays, List <IntEdge> edges, int nov) { this.SetEdges(edges, nov); this.virtualVerticesStart = graph.NodeCount; this.virtualVerticesEnd = layeredGraph.NodeCount - 1; this.layeredGraph = layeredGraph; this.layerArrays = layerArrays; }
internal Routing(SugiyamaLayoutSettings settings, GeometryGraph originalGraph, Database dbP, LayerArrays yLayerArrays, ProperLayeredGraph properLayeredGraph, BasicGraph<Node, PolyIntEdge> intGraph ) { this.settings = settings; OriginalGraph = originalGraph; Database = dbP; ProperLayeredGraph = properLayeredGraph; LayerArrays = yLayerArrays; IntGraph = intGraph; }
Ordering(ProperLayeredGraph graphPar, bool tryReverse, LayerArrays layerArraysParam, int startOfVirtualNodes, bool balanceVirtualAndOrigNodes, bool hasCrossWeights, SugiyamaLayoutSettings settings) { this.tryReverse = tryReverse; startOfVirtNodes = startOfVirtualNodes; layerArrays = layerArraysParam; layering = layerArraysParam.Y; nOfLayers = layerArraysParam.Layers.Length; layers = layerArraysParam.Layers; balanceVirtAndOrigNodes = balanceVirtualAndOrigNodes; properLayeredGraph = graphPar; this.hasCrossWeights = hasCrossWeights; this.settings = settings; random = new Random(SeedOfRandom); }
Ordering(ProperLayeredGraph graphPar, bool tryReverse, LayerArrays layerArraysParam, int startOfVirtualNodes, bool hasCrossWeights, SugiyamaLayoutSettings settings) { this.tryReverse = tryReverse; startOfVirtNodes = startOfVirtualNodes; layerArrays = layerArraysParam; layering = layerArraysParam.Y; nOfLayers = layerArraysParam.Layers.Length; layers = layerArraysParam.Layers; properLayeredGraph = graphPar; this.hasCrossWeights = hasCrossWeights; this.settings = settings; random = new Random(SeedOfRandom); }
///// <summary> ///// This method can be improved: see the paper Simple And Efficient ... ///// </summary> ///// <param name="graph"></param> ///// <param name="layerArrays"></param> ///// <param name="bottom">bottom of the strip</param> ///// <returns></returns> static int GetCrossingCountFromStrip(int bottom, ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { int[] topVerts = layerArrays.Layers[bottom + 1]; int[] bottomVerts = layerArrays.Layers[bottom]; if (bottomVerts.Length <= topVerts.Length) { return(GetCrossingCountFromStripWhenBottomLayerIsShorter(bottomVerts, properLayeredGraph, layerArrays)); } else { return(GetCrossingCountFromStripWhenTopLayerIsShorter(topVerts, bottomVerts, properLayeredGraph, layerArrays)); } }
internal static void OrderLayers(ProperLayeredGraph graph, LayerArrays layerArrays, int startOfVirtualNodes, bool balanceVirtualAndOriginalNodes, SugiyamaLayoutSettings settings, CancelToken cancelToken) { bool hasCrossWeight = false; foreach (LayerEdge le in graph.Edges) if (le.CrossingWeight != 1) { hasCrossWeight = true; break; } var o = new Ordering(graph, true, layerArrays, startOfVirtualNodes, balanceVirtualAndOriginalNodes, hasCrossWeight, settings); o.Run(cancelToken); }
///// <summary> ///// private constructor ///// </summary> ///// <param name="layerArrays"></param> ///// <param name="anchs"></param> ///// <param name="layeredGraph"></param> ///// <param name="nOfOriginalVs"></param> XCoordsWithAlignment(LayerArrays layerArrays, ProperLayeredGraph layeredGraph, int nOfOriginalVs, Anchor[] anchorsP, double ns) { this.la = layerArrays; this.graph = layeredGraph; this.nOfOriginalVertices = nOfOriginalVs; this.nOfVertices = graph.NodeCount; this.h = la.Layers.Length; this.root = new int[nOfVertices]; this.align = new int[nOfVertices]; // this.sink = new int[nOfVertices]; // this.shift = new double[nOfVertices]; this.anchors = anchorsP; this.nodeSep = ns; }
internal static void Refine( int topNodeP, int bottomNode, Site topSiteP, Anchor[] anchors, LayerArrays layerArraysP, ProperLayeredGraph layeredGraph, GeometryGraph originalGraph, double layerSeparation) { RefinerBetweenTwoLayers refiner = new RefinerBetweenTwoLayers(topNodeP, bottomNode, topSiteP, layerArraysP, layeredGraph, originalGraph, anchors, layerSeparation); refiner.Refine(); }
/// <summary> /// it is a special recovery constructor to recreate the engine from the recovery engine /// </summary> internal LayeredLayoutEngine(LayerArrays engineLayerArrays, GeometryGraph originalGraph, ProperLayeredGraph properLayeredGraph, SugiyamaLayoutSettings sugiyamaSettings, Database database, BasicGraph<Node, IntEdge> intGraph, Dictionary<Node, int> nodeIdToIndex, BasicGraph<Node, IntEdge> gluedDagSkeletonForLayering, bool layersAreDoubled, ConstrainedOrdering constrainedOrdering, bool brandes, XLayoutGraph xLayoutGraph) { this.engineLayerArrays = engineLayerArrays; this.originalGraph = originalGraph; this.properLayeredGraph = properLayeredGraph; this.sugiyamaSettings = sugiyamaSettings; this.database = database; IntGraph = intGraph; this.nodeIdToIndex = nodeIdToIndex; GluedDagSkeletonForLayering = gluedDagSkeletonForLayering; LayersAreDoubled = layersAreDoubled; this.constrainedOrdering = constrainedOrdering; Brandes = brandes; anchors = database.anchors; this.xLayoutGraph = xLayoutGraph; }
RefinerBetweenTwoLayers( int topNodeP, int bottomNodeP, Site topSiteP, LayerArrays layerArraysP, ProperLayeredGraph layeredGraphP, GeometryGraph originalGraphP, Anchor[] anchorsP, double layerSeparation) { this.topNode = topNodeP; this.bottomNode = bottomNodeP; this.topSite = topSiteP; this.bottomSite = topSiteP.Next; this.currentTopSite = topSiteP; this.currentBottomSite = topSiteP.Next; this.layerArrays = layerArraysP; this.layeredGraph = layeredGraphP; this.originalGraph = originalGraphP; this.anchors = anchorsP; this.layerSeparation = layerSeparation; }
private void CreateFullLayeredGraph() { int currentVV = this.layeredGraph.NodeCount; foreach (KeyValuePair <IntPair, List <IntEdge> > kv in database.Multiedges) { if (kv.Key.x != kv.Key.y) //not a self edge { List <IntEdge> list = kv.Value; bool first = true; int span = 0; foreach (IntEdge e in list) { if (first) { first = false; span = e.LayerSpan; } else { e.LayerEdges = new LayerEdge[span]; if (span == 1) { e.LayerEdges[0] = new LayerEdge(e.Source, e.Target, e.CrossingWeight); } else { for (int i = 0; i < span; i++) { int source = GetSource(ref currentVV, e, i); int target = GetTarget(ref currentVV, e, i, span); e.LayerEdges[i] = new LayerEdge(source, target, e.CrossingWeight); } } } LayerInserter.RegisterDontStepOnVertex(this.database, e); } } } this.nLayeredGraph = new ProperLayeredGraph(this.intGraph); }
internal static void OrderLayers(ProperLayeredGraph graph, LayerArrays layerArrays, int startOfVirtualNodes, SugiyamaLayoutSettings settings, CancelToken cancelToken) { bool hasCrossWeight = false; foreach (LayerEdge le in graph.Edges) { if (le.CrossingWeight != 1) { hasCrossWeight = true; break; } } var o = new Ordering(graph, true, layerArrays, startOfVirtualNodes, hasCrossWeight, settings); o.Run(cancelToken); }
static Dictionary<int, Point> BuildInitialNodePositions(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { var result = new Dictionary<int, Point>(); for (int i = 0; i < layerArrays.Layers.Length; i++) { int prev = 0, curr = 0; while (curr < layerArrays.Layers[i].Length) { while (curr < layerArrays.Layers[i].Length && properLayeredGraph.IsVirtualNode(layerArrays.Layers[i][curr])) curr++; for (int j = prev; j < curr; j++) result[layerArrays.Layers[i][j]] = new Point(i, prev); if (curr < layerArrays.Layers[i].Length) result[layerArrays.Layers[i][curr]] = new Point(i, curr); curr++; prev = curr; } } return result; }
static int GetCrossingCountFromStripWhenBottomLayerIsShorter(int[] bottomVerts, ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { LayerEdge[] edges = EdgesOfStrip(bottomVerts, properLayeredGraph); Array.Sort(edges, new EdgeComparerBySource(layerArrays.X)); //find first n such that 2^n >=bottomVerts.Length int n = 1; while (n < bottomVerts.Length) { n *= 2; } //init accumulator var tree = new int[2 * n - 1]; n--; // the first bottom node starts from n now int cc = 0; //number of crossings foreach (LayerEdge edge in edges) { int index = n + layerArrays.X[edge.Target]; int ew = edge.CrossingWeight; tree[index] += ew; while (index > 0) { if (index % 2 != 0) { cc += ew * tree[index + 1]; //intersect everything accumulated in the right sibling } index = (index - 1) / 2; tree[index] += ew; } } return(cc); }
/// <summary> /// Creating buckets for multi edges and allocating the graph. /// </summary> private void CreateFullLayeredGraph() { totalNodes = this.intGraph.NodeCount; foreach (List<IntEdge> list in database.RegularMultiedges) { int span = 0; bool first = true; foreach (IntEdge e in list) { if (first) { first = false; span = e.LayerSpan * 2; } if (span > 0) { e.LayerEdges = new LayerEdge[span]; for (int i = 0; i < span; i++) { int source = EdgePathsInserter.GetSource(ref totalNodes, e, i); int target = EdgePathsInserter.GetTarget(ref totalNodes, e, i, span); e.LayerEdges[i] = new LayerEdge(source, target, e.CrossingWeight); } LayerInserter.RegisterDontStepOnVertex(this.database, e); } } } this.nLayeredGraph = new ProperLayeredGraph(this.intGraph); }
private void CreateLayerArraysAndProperLayeredGraph() { int numberOfLayers = this.gridLayerOffsets.Count; this.layerOffsets=new double[numberOfLayers]; int i = numberOfLayers-1; foreach (KeyValuePair<int, double> kv in this.gridLayerOffsets) { layerOffsets[i] = kv.Value; gridLayerToLayer[kv.Key] = i--; } int nOfNodes=CountTotalNodesIncludingVirtual(nodesToIndices[tree.Root]); ////debugging !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //int tt = 0; //foreach (IntEdge ie in this.intGraph.Edges) // tt += this.OriginalNodeLayer(ie.Source) - this.OriginalNodeLayer(ie.Target) - 1; //if (tt + this.intGraph.Nodes.Count != nOfNodes) // throw new Exception(); int[] layering = new int[nOfNodes]; List<int>[] layers = new List<int>[numberOfLayers]; for (i = 0; i < numberOfLayers; i++) layers[i] = new List<int>(); WalkTreeAndInsertLayerEdges(layering, layers); this.layerArrays = new LayerArrays(layering); int[][]ll=layerArrays.Layers=new int[numberOfLayers][]; i = 0; foreach (List<int> layer in layers) { ll[i++] = layer.ToArray(); } this.properLayeredGraph = new ProperLayeredGraph(intGraph); }
/// <summary> /// /// </summary> static internal void CalculateXCoordinates(LayerArrays layerArrays, ProperLayeredGraph layeredGraph, int nOfOriginalVs, Anchor[] anchors, double nodeSeparation) { XCoordsWithAlignment x = new XCoordsWithAlignment(layerArrays, layeredGraph, nOfOriginalVs, anchors, nodeSeparation); x.Calculate(); }
/// <summary> /// Reorder virtual nodes between the same pair of real nodes /// </summary> internal static void UpdateLayerArrays(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { Dictionary<int, Point> nodePositions = BuildInitialNodePositions(properLayeredGraph, layerArrays); UpdateLayerArrays(properLayeredGraph, layerArrays, nodePositions); }
/// <summary> /// Reorder only points having identical nodePositions /// </summary> internal static void UpdateLayerArrays(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays, Dictionary<int, Point> nodePositions) { new MetroMapOrdering(properLayeredGraph, layerArrays, nodePositions).UpdateLayerArrays(); }
void CreateProperLayeredGraph() { IEnumerable<IntEdge> edges = CreatePathEdgesOnIntGraph(); var nodeCount = Math.Max(intGraph.NodeCount, BasicGraph<Node, IntEdge>.VertexCount(edges)); var baseGraph = new BasicGraph<Node, IntEdge>(edges, nodeCount) { Nodes = intGraph.Nodes }; ProperLayeredGraph = new ProperLayeredGraph(baseGraph); }
/// <summary> /// Reorder only points having identical nodePositions /// </summary> internal static void UpdateLayerArrays(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays, Dictionary <int, Point> nodePositions) { new MetroMapOrdering(properLayeredGraph, layerArrays, nodePositions).UpdateLayerArrays(); }
/// <summary> /// Reorder virtual nodes between the same pair of real nodes /// </summary> internal static void UpdateLayerArrays(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { Dictionary <int, Point> nodePositions = BuildInitialNodePositions(properLayeredGraph, layerArrays); UpdateLayerArrays(properLayeredGraph, layerArrays, nodePositions); }
internal static int GetCrossingsTotal(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { int x = 0; for (int i = 0; i < layerArrays.Layers.Length - 1; i++) x += GetCrossingCountFromStrip(i, properLayeredGraph, layerArrays); return x; }
///// <summary> ///// This method can be improved: see the paper Simple And Efficient ... ///// </summary> ///// <param name="graph"></param> ///// <param name="layerArrays"></param> ///// <param name="bottom">bottom of the strip</param> ///// <returns></returns> static int GetCrossingCountFromStrip(int bottom, ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { int[] topVerts = layerArrays.Layers[bottom + 1]; int[] bottomVerts = layerArrays.Layers[bottom]; if (bottomVerts.Length <= topVerts.Length) return GetCrossingCountFromStripWhenBottomLayerIsShorter(bottomVerts, properLayeredGraph, layerArrays); else return GetCrossingCountFromStripWhenTopLayerIsShorter(topVerts, bottomVerts, properLayeredGraph, layerArrays); }
LayerArrays YLayeringAndOrdering(LayerCalculator layering) { #region reporting #if REPORTING Timer t = null; if (sugiyamaSettings.Reporting) { t = new Timer(); Report("ylayering ... "); t.Start(); } #endif #endregion int[] yLayers = layering.GetLayers(); Balancing.Balance(GluedDagSkeletonForLayering, yLayers, GetNodeCountsOfGluedDag(), null); yLayers = ExtendLayeringToUngluedSameLayerVertices(yLayers); #region reporting #if REPORTING if (sugiyamaSettings.Reporting) { t.Stop(); Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration)); Report("ordering ... "); t.Start(); } #endif #endregion var layerArrays = new LayerArrays(yLayers); //if (!SugiyamaSettings.UseEdgeBundling && (HorizontalConstraints == null || HorizontalConstraints.IsEmpty)) { if (HorizontalConstraints == null || HorizontalConstraints.IsEmpty) { layerArrays = YLayeringAndOrderingWithoutHorizontalConstraints(layerArrays); #region reporting #if REPORTING if (sugiyamaSettings.Reporting) { t.Stop(); Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration)); } #endif #endregion return layerArrays; } constrainedOrdering = new ConstrainedOrdering(originalGraph, IntGraph, layerArrays.Y, nodeIdToIndex, database, sugiyamaSettings); constrainedOrdering.Calculate(); properLayeredGraph = constrainedOrdering.ProperLayeredGraph; #region reporting #if REPORTING if (sugiyamaSettings.Reporting) { t.Stop(); Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration)); } #endif #endregion // SugiyamaLayoutSettings.ShowDatabase(this.database); return constrainedOrdering.LayerArrays; }
MetroMapOrdering(ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays, Dictionary<int, Point> nodePositions) { this.properLayeredGraph = properLayeredGraph; this.layerArrays = layerArrays; this.nodePositions = nodePositions; }
internal static void CalculateAnchorSizes(Database database, out Anchor[] anchors, ProperLayeredGraph properLayeredGraph, GeometryGraph originalGraph, BasicGraph<Node, IntEdge> intGraph, SugiyamaLayoutSettings settings) { database.Anchors = anchors = new Anchor[properLayeredGraph.NodeCount]; for (int i = 0; i < anchors.Length; i++) anchors[i] = new Anchor(settings.LabelCornersPreserveCoefficient); //go over the old vertices for (int i = 0; i < originalGraph.Nodes.Count; i++) CalcAnchorsForOriginalNode(i, intGraph, anchors, database, settings); //go over virtual vertices foreach (IntEdge intEdge in database.AllIntEdges) if (intEdge.LayerEdges != null) { foreach (LayerEdge layerEdge in intEdge.LayerEdges) { int v = layerEdge.Target; if (v != intEdge.Target) { Anchor anchor = anchors[v]; if (!database.MultipleMiddles.Contains(v)) { anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth/2.0f; anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f; } else { anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth*4; anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f; } } } //fix label vertices if (intEdge.HasLabel) { int lj = intEdge.LayerEdges[intEdge.LayerEdges.Count/2].Source; Anchor a = anchors[lj]; double w = intEdge.LabelWidth, h = intEdge.LabelHeight; a.RightAnchor = w; a.LeftAnchor = VirtualNodeWidth*8; if (a.TopAnchor < h/2.0) a.TopAnchor = a.BottomAnchor = h/2.0; a.LabelToTheRightOfAnchorCenter = true; } } }
static LayerEdge[] EdgesOfStrip(int[] bottomVerts, ProperLayeredGraph properLayeredGraph) { LayerEdge[] edges = (from v in bottomVerts from e in properLayeredGraph.InEdges(v) select e).ToArray(); return edges; }
//[System.Diagnostics.Conditional("DEBUGGLEE")] //private void TestYXLayers(LayerArrays layerArrays, int[] xLayers) { // foreach (IntEdge e in this.xLayoutGraph.Edges) { // int s = e.Source; int targ = e.Target; // if (e.Source >= layeredGraph.Nodes.Count) { // if (xLayoutGraph.OutEdges(s).Count != 2 || xLayoutGraph.InEdges(s).Count != 0) // Report("must be two out edges and none incoming"); // if (targ >= layeredGraph.Nodes.Count) // Report("an illegal edge"); // } else { // if (layerArrays.Y[s] != layerArrays.Y[targ]) // Report("layers don't coincide"); // if (layerArrays.X[s] - 1 != layerArrays.X[targ]) // Report("wrong input"); // if (xLayers[s] <= xLayers[targ]) // Report("wrong xlayering"); // } // } //} /// <summary> /// Creating a proper layered graph, a graph where each /// edge goes only one layer down from the i+1-th layer to the i-th layer. /// </summary> /// <param name="layering"></param> /// <param name="layerArrays"></param> void CreaeteProperLayeredGraph(int[] layering, out LayerArrays layerArrays) { int n = layering.Length; int nOfVV = 0; foreach (IntEdge e in database.SkeletonEdges()) { int span = EdgeSpan(layering, e); Debug.Assert(span >= 0); if (span > 0) e.LayerEdges = new LayerEdge[span]; int pe = 0; //offset in the string if (span > 1) { //we create span-2 dummy nodes and span new edges int d0 = n + nOfVV++; var layerEdge = new LayerEdge(e.Source, d0, e.CrossingWeight,e.Weight); e.LayerEdges[pe++] = layerEdge; //create span-2 internal edges all from dummy nodes for (int j = 0; j < span - 2; j++) { d0++; nOfVV++; layerEdge = new LayerEdge(d0 - 1, d0, e.CrossingWeight,e.Weight); e.LayerEdges[pe++] = layerEdge; } layerEdge = new LayerEdge(d0, e.Target, e.CrossingWeight, e.Weight); e.LayerEdges[pe] = layerEdge; } else if (span == 1) { var layerEdge = new LayerEdge(e.Source, e.Target, e.CrossingWeight, e.Weight); e.LayerEdges[pe] = layerEdge; } } var extendedVertexLayering = new int[originalGraph.Nodes.Count + nOfVV]; foreach (IntEdge e in database.SkeletonEdges()) if (e.LayerEdges != null) { int l = layering[e.Source]; extendedVertexLayering[e.Source] = l--; foreach (LayerEdge le in e.LayerEdges) extendedVertexLayering[le.Target] = l--; } else { extendedVertexLayering[e.Source] = layering[e.Source]; extendedVertexLayering[e.Target] = layering[e.Target]; } properLayeredGraph = new ProperLayeredGraph(new BasicGraph<Node, IntEdge>(database.SkeletonEdges(), layering.Length)); properLayeredGraph.BaseGraph.Nodes = IntGraph.Nodes; layerArrays = new LayerArrays(extendedVertexLayering); }
static int GetCrossingCountFromStripWhenBottomLayerIsShorter(int[] bottomVerts, ProperLayeredGraph properLayeredGraph, LayerArrays layerArrays) { LayerEdge[] edges = EdgesOfStrip(bottomVerts, properLayeredGraph); Array.Sort(edges, new EdgeComparerBySource(layerArrays.X)); //find first n such that 2^n >=bottomVerts.Length int n = 1; while (n < bottomVerts.Length) n *= 2; //init accumulator var tree = new int[2*n - 1]; n--; // the first bottom node starts from n now int cc = 0; //number of crossings foreach (LayerEdge edge in edges) { int index = n + layerArrays.X[edge.Target]; int ew = edge.CrossingWeight; tree[index] += ew; while (index > 0) { if (index%2 != 0) cc += ew*tree[index + 1]; //intersect everything accumulated in the right sibling index = (index - 1)/2; tree[index] += ew; } } return cc; }
LayerArrays YLayeringAndOrdering(LayerCalculator layering) { int[] yLayers = layering.GetLayers(); yLayers = ExtendLayeringToUngluedSameLayerVertices(yLayers); var layerArrays = new LayerArrays(yLayers); //if (!SugiyamaSettings.UseEdgeBundling && (HorizontalConstraints == null || HorizontalConstraints.IsEmpty)) { if (HorizontalConstraints == null || HorizontalConstraints.IsEmpty) { layerArrays = YLayeringAndOrderingWithoutHorizontalConstraints(layerArrays); return layerArrays; } constrainedOrdering = new ConstrainedOrdering(originalGraph, IntGraph, layerArrays.Y, nodeIdToIndex, database, sugiyamaSettings); constrainedOrdering.Calculate(); properLayeredGraph = constrainedOrdering.ProperLayeredGraph; // SugiyamaLayoutSettings.ShowDatabase(this.database); return constrainedOrdering.LayerArrays; }
private void CreateFullLayeredGraph() { int currentVV = this.layeredGraph.NodeCount; foreach (KeyValuePair<IntPair, List<IntEdge>> kv in database.Multiedges) { if (kv.Key.x != kv.Key.y) { //not a self edge List<IntEdge> list = kv.Value; bool first = true; int span = 0; foreach (IntEdge e in list) { if (first) { first = false; span = e.LayerSpan; } else { e.LayerEdges = new LayerEdge[span]; if (span == 1) e.LayerEdges[0] = new LayerEdge(e.Source, e.Target, e.CrossingWeight); else { for (int i = 0; i < span; i++) { int source = GetSource(ref currentVV, e, i); int target = GetTarget(ref currentVV, e, i, span); e.LayerEdges[i] = new LayerEdge(source, target, e.CrossingWeight); } } } LayerInserter.RegisterDontStepOnVertex(this.database, e); } } } this.nLayeredGraph = new ProperLayeredGraph(this.intGraph); }