using System.Collections.Generic; using Microsoft.Msagl.Core.Geometry; using Microsoft.Msagl.Core.Layout; namespace Microsoft.Msagl.Layout.Incremental { /// /// A vertical separation constraint requires a minimum separation between y coordinates of two nodes, /// i.e. u.Y + separation less or equal v.Y /// public class VerticalSeparationConstraint : IConstraint { bool equality; /// /// /// public bool IsEquality { get { return equality; } } private Node u; /// /// Constrained to be vertically above the BottomNode /// public Node TopNode { get { return u; } } private Node v; /// /// Constrained to be vertically below the TopNode /// public Node BottomNode { get { return v; } } private double separation; /// /// We allow the separation of existing constraints to be modified by the user. /// public double Separation { get { return separation; } set { separation = value; } } /// /// /// /// /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704")] public VerticalSeparationConstraint(Node u, Node v, double separation) { this.u = u; this.v = v; this.separation = separation; } /// /// /// /// /// /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704")] public VerticalSeparationConstraint(Node u, Node v, double separation, bool equality) { this.equality = equality; this.u = u; this.v = v; this.separation = separation; } /// /// /// public virtual double Project() { double uv = v.Center.Y - u.Center.Y; double d = separation - uv; if (d > 0) { double wu = ((FiNode)u.AlgorithmData).stayWeight, wv = ((FiNode)v.AlgorithmData).stayWeight; double f = d/(wu+wv); u.Center = new Point(u.Center.X, u.Center.Y - wv*f); v.Center = new Point(v.Center.X, v.Center.Y + wu*f); return d; } else { return 0; } } /// /// VerticalSeparationConstraint are usually structural and therefore default to level 0 /// /// 0 public int Level { get { return 0; } } /// /// Get the list of nodes involved in the constraint /// public IEnumerable Nodes { get { return new Node[] { u, v }; } } } }