GraphComponent ComposeRendering(GraphComponent component, Strand strand, double y0 = 0) // We render a strand as a linear sequence of spring-separated particles. // We initially lay things out in a linear line, either to the right (for // normally oriented strands) or left (for reverse oriented strands). { if (null==component) component = new GraphComponent(this); // // Compose edges for domains along the strand backbone // List<GraphVertex> strandVertices = new List<GraphVertex>(); List<GraphEdge> strandEdges = new List<GraphEdge>(); // double count = strand.AllDomains().Count(); double length = strand.AllDomains().Sum(d => this.EdgeFromDomain(component, d).PreferredLength); double radius = length / 2.0 / Math.PI; // radius /= 3; // hack -> otherwise the forces pulling the circle together overshoot // int i = 0; foreach (Domain d in strand.AllDomains()) { GraphEdge edge = this.EdgeFromDomain(component, d); strandEdges.Add(edge); // // The first vertex in the strand needs to be explicitly positioned // double x,y; // if (strandVertices.IsEmpty()) { strandVertices.Add(edge.A); if (strand.IsCircular) x = strand.Orientation==Strand.Direction.FiveToThree ? -radius : radius; else x = 0; edge.A.SetLocation(x,y0); } // // Position the B vertex of the edge // if (strand.IsCircular) { double theta = i / count * 2 * Math.PI; x = radius * Math.Cos(theta); y = radius * Math.Sin(theta); if (strand.Orientation==Strand.Direction.FiveToThree) { x = -x; y = -y; } } else { y = y0; x = edge.PreferredLength; if (strand.Orientation == Strand.Direction.ThreeToFive) x = -x; x += strandVertices.Last().Location.X; } // edge.B.SetLocation(x, y); strandVertices.Add(edge.B); // i++; } // // Make a spline for the strand as a whole // if (strandVertices.NotEmpty()) { VisualStrand vStrand = new VisualStrand(strand, component, strandEdges, strandVertices); this.mpStrandVisualization[strand] = vStrand; // // Place ticks at the ends of each of the interior domains in the strand // for (i = strand.IsCircular ? 0 : 1; i < strandVertices.Count-1; i++) { new VisualDomainEndTick(component, vStrand, i, Constants.DomainEndLength); } // // Add domain labels and nucleotides // foreach (Domain d in strand.AllDomains()) { i = d.StrandIndex; // VisualStrandLabel label = new VisualStrandLabel(component, vStrand, i, i+1, d.FullDisplayName, Constants.StyleDomainLabel); label.LabelType = VisualStrandLabel.LABELTYPE.DOMAIN; vStrand.NoteDomainLabel(i, label); // if (d.Nucleotides.Length > 0 && true) { label = new VisualStrandLabel(component, vStrand, i, i+1, d.Nucleotides, Constants.StyleNucleotides); label.LabelType = VisualStrandLabel.LABELTYPE.NUCLEOTIDE; label.FontVerticallyCentered = true; label.AutoReverseText = true; } } } // if (strandVertices.NotEmpty()) { // Help a bit with initial placement: left align if we moved leftward // from zero due to strand direction. // if (!strand.IsCircular && strand.Orientation == Strand.Direction.ThreeToFive) { double dx = -strandVertices.Last().Location.X; foreach (GraphVertex v in strandVertices) { v.TranslateBy(dx, 0); } } } // // Put in stiffness along the strand // foreach (Domain d in strand.AllDomains()) { if (d.CircularNextTo5 != null) { GraphEdge curEdge = this.EdgeFromDomain(component, d); GraphEdge prevEdge = this.EdgeFromDomain(component, d.CircularNextTo5); // new StraighteningForce(component, prevEdge.A, curEdge.A, curEdge.B, Constants.StraighteningStrength); } } // return component; }
public VisualDomainEndTick(GraphComponent component, VisualStrand strand, int iControlPoint, double length) : base(component) { this.strand = strand; this.iControlPoint = iControlPoint; this.length = length; this.SetStyleName(Constants.StyleDomainEnd); component.AddRenderable(this); }
// //---------------------------------------------------------------------------------------- // Construction //---------------------------------------------------------------------------------------- public VisualDoubleStrandedRegion(GraphComponent component, VisualStrand vStrandTop, int iTopControlFirst, int iTopControlLast, VisualStrand vStrandBottom, int iBottomControlFirst, int iBottomControlLast, int cNt ) : base(component) { Debug.Assert(iTopControlFirst < iTopControlLast); Debug.Assert(iBottomControlFirst < iBottomControlLast); // this.vStrandTop = vStrandTop; this.vStrandBottom = vStrandBottom; // this.iTopControlFirst = iTopControlFirst; this.iTopControlLast = iTopControlLast; this.iBottomControlFirst = iBottomControlFirst; this.iBottomControlLast = iBottomControlLast; // this.cNt = cNt; // this.SetStyleName(Constants.StyleDoubleStranded); // default component.AddRenderable(this); }
//---------------------------------------------------------------------------------------- // Construction //---------------------------------------------------------------------------------------- public VisualStrandLabel(GraphComponent component, VisualStrand vStrand, int iControlFirst, int iControlLast, string text, string style ) : base(component) { this.vStrand = vStrand; this.iControlFirst = iControlFirst; this.iControlLast = iControlLast; this.text = text; // Debug.Assert(iControlFirst < iControlLast); // this.SetStyleName(style); // default component.AddRenderable(this); }