/// <summary> /// Create variables, generate non-overlap constraints. /// </summary> /// <param name="hPad">horizontal node padding</param> /// <param name="vPad">vertical node padding</param> /// <param name="cHPad">horizontal cluster padding</param> /// <param name="cVPad">vertical cluster padding</param> /// <param name="nodeCenter"></param> internal void Initialize(double hPad, double vPad, double cHPad, double cVPad, InitialCenterDelegateType nodeCenter) { // For the Vertical ConstraintGenerator, Padding is vPad and PadddingP(erpendicular) is hPad. cg = new ConstraintGenerator(IsHorizontal , IsHorizontal ? hPad : vPad , IsHorizontal ? vPad : hPad , IsHorizontal ? cHPad : cVPad , IsHorizontal ? cVPad : cHPad); solver = new Solver(); foreach (var filNode in nodes) { filNode.SetOlapNode(IsHorizontal,null); } // Calculate horizontal non-Overlap constraints. if (avoidOverlaps && clusterHierarchies != null) { foreach (var c in clusterHierarchies) { AddOlapClusters(cg, null /* OlapParentCluster */, c, nodeCenter); } } foreach (var filNode in nodes) { if (filNode.getOlapNode(IsHorizontal) == null) { AddOlapNode(cg, cg.DefaultClusterHierarchy /* olapParentCluster */, filNode, nodeCenter); } filNode.getOlapNode(IsHorizontal).CreateVariable(solver); } if (avoidOverlaps && this.ConstraintLevel >= 2) { cg.Generate(solver, OverlapRemovalParameters); } AddStructuralConstraints(); }
private void AddOlapNode(ConstraintGenerator generator, OverlapRemovalCluster olapParentCluster, FiNode filNode, InitialCenterDelegateType nodeCenter) { // If the node already has an mOlapNode, it's already in a cluster (in a different // hierarchy); we just add it to the new cluster. if (null != filNode.getOlapNode(IsHorizontal)) { generator.AddNodeToCluster(olapParentCluster, filNode.getOlapNode(IsHorizontal)); return; } var center = nodeCenter(filNode); // We need to create a new Node in the Generator. if (IsHorizontal) { // Add the Generator node with the X-axis coords primary, Y-axis secondary. filNode.mOlapNodeX = generator.AddNode(olapParentCluster, filNode /* userData */ , center.X, center.Y , filNode.Width, filNode.Height, filNode.stayWeight); } else { // Add the Generator node with the Y-axis coords primary, X-axis secondary. filNode.mOlapNodeY = generator.AddNode(olapParentCluster, filNode /* userData */ , center.Y, center.X , filNode.Height, filNode.Width, filNode.stayWeight); } }
private void AddOlapClusters(ConstraintGenerator generator, OverlapRemovalCluster olapParentCluster, Cluster incClus, InitialCenterDelegateType nodeCenter) { LayoutAlgorithmSettings settings = clusterSettings(incClus); double nodeSeparationH = settings.NodeSeparation; double nodeSeparationV = settings.NodeSeparation + 1e-4; double innerPaddingH = settings.ClusterMargin; double innerPaddingV = settings.ClusterMargin + 1e-4; // Creates the OverlapRemoval (Olap) Cluster/Node objects for our FastIncrementalLayout (FIL) objects. // If !isHorizontal this overwrites the Olap members of the Incremental.Clusters and Msagl.Nodes. // First create the olapCluster for the current incCluster. If olapParentCluster is null, then // incCluster is the root of a new hierarchy. RectangularClusterBoundary rb = incClus.RectangularBoundary; if (IsHorizontal) { rb.olapCluster = generator.AddCluster( olapParentCluster, incClus /* userData */, rb.MinWidth, rb.MinHeight, rb.LeftBorderInfo, rb.RightBorderInfo, rb.BottomBorderInfo, rb.TopBorderInfo); rb.olapCluster.NodePadding = nodeSeparationH; rb.olapCluster.NodePaddingP = nodeSeparationV; rb.olapCluster.ClusterPadding = innerPaddingH; rb.olapCluster.ClusterPaddingP = innerPaddingV; } else { var postXLeftBorderInfo = new BorderInfo(rb.LeftBorderInfo.InnerMargin, rb.Rect.Left, rb.LeftBorderInfo.Weight); var postXRightBorderInfo = new BorderInfo(rb.RightBorderInfo.InnerMargin, rb.Rect.Right, rb.RightBorderInfo.Weight); rb.olapCluster = generator.AddCluster( olapParentCluster, incClus /* userData */, rb.MinHeight, rb.MinWidth, rb.BottomBorderInfo, rb.TopBorderInfo, postXLeftBorderInfo, postXRightBorderInfo); rb.olapCluster.NodePadding = nodeSeparationV; rb.olapCluster.NodePaddingP = nodeSeparationH; rb.olapCluster.ClusterPadding = innerPaddingV; rb.olapCluster.ClusterPaddingP = innerPaddingH; } rb.olapCluster.TranslateChildren = rb.GenerateFixedConstraints; // Note: Incremental.Cluster always creates child List<Cluster|Node> so we don't have to check for null here. // Add our child nodes. foreach (var filNode in incClus.Nodes) { AddOlapNode(generator, rb.olapCluster, (FiNode)filNode.AlgorithmData, nodeCenter); } // Now recurse through all child clusters. foreach (var incChildClus in incClus.Clusters) { AddOlapClusters(generator, rb.olapCluster, incChildClus, nodeCenter); } }
/// <summary> /// Create variables, generate non-overlap constraints. /// </summary> /// <param name="hPad">horizontal node padding</param> /// <param name="vPad">vertical node padding</param> /// <param name="cHPad">horizontal cluster padding</param> /// <param name="cVPad">vertical cluster padding</param> /// <param name="nodeCenter"></param> internal void Initialize(double hPad, double vPad, double cHPad, double cVPad, InitialCenterDelegateType nodeCenter) { // For the Vertical ConstraintGenerator, Padding is vPad and PadddingP(erpendicular) is hPad. cg = new ConstraintGenerator(IsHorizontal , IsHorizontal ? hPad : vPad , IsHorizontal ? vPad : hPad , IsHorizontal ? cHPad : cVPad , IsHorizontal ? cVPad : cHPad); solver = new Solver(); foreach (var filNode in nodes) { filNode.SetOlapNode(IsHorizontal, null); } // Calculate horizontal non-Overlap constraints. if (avoidOverlaps && clusterHierarchies != null) { foreach (var c in clusterHierarchies) { AddOlapClusters(cg, null /* OlapParentCluster */, c, nodeCenter); } } foreach (var filNode in nodes) { if (filNode.getOlapNode(IsHorizontal) == null) { AddOlapNode(cg, cg.DefaultClusterHierarchy /* olapParentCluster */, filNode, nodeCenter); } filNode.getOlapNode(IsHorizontal).CreateVariable(solver); } if (avoidOverlaps && this.ConstraintLevel >= 2) { cg.Generate(solver, OverlapRemovalParameters); } AddStructuralConstraints(); }