//////////////////////////////////////////////////// //////////////// New in this sample //////////////// //////////////////////////////////////////////////// /// <summary> /// Draws the edge-like connectors from a node to its labels /// </summary> private void RenderLabelEdges(IRenderContext context, INode node, VisualGroup container) { int count = 0; if (node.Labels.Count > 0) { // Create a SimpleEdge which will be used as a dummy for the rendering SimpleEdge simpleEdge = new SimpleEdge(null, null); // Assign the style simpleEdge.Style = new PolylineEdgeStyle(); // Create a SimpleNode which provides the sourceport for the edge but won't be drawn itself SimpleNode sourceDummyNode = new SimpleNode { Layout = new RectD(0, 0, node.Layout.Width, node.Layout.Height), Style = node.Style }; // Set sourceport to the port of the node using a dummy node that is located at the origin. simpleEdge.SourcePort = new SimplePort(sourceDummyNode, FreeNodePortLocationModel.NodeCenterAnchored); // Create a SimpleNode which provides the targetport for the edge but won't be drawn itself SimpleNode targetDummyNode = new SimpleNode(); // Create port on targetDummynode for the label target targetDummyNode.Ports = new ListEnumerable <IPort>(new[] { new SimplePort(targetDummyNode, FreeNodePortLocationModel.NodeCenterAnchored) }); simpleEdge.TargetPort = new SimplePort(targetDummyNode, FreeNodePortLocationModel.NodeCenterAnchored); var topLeft = node.Layout.GetTopLeft(); var labelLocations = node.Labels.Select(l => l.GetLayout().GetCenter() - topLeft); // Render one edge for each label foreach (PointD labelLocation in labelLocations) { // move the dummy node to the location of the label targetDummyNode.Layout = new MutableRectangle(labelLocation, SizeD.Zero); // now create the visual using the style interface: IEdgeStyleRenderer renderer = simpleEdge.Style.Renderer; IVisualCreator creator = renderer.GetVisualCreator(simpleEdge, simpleEdge.Style); if (container.Children.Count > count) { container.Children[count] = creator.UpdateVisual(context, container.Children[count]); } else { container.Children.Add(creator.CreateVisual(context)); } count++; } } // remove superfluous visuals while (container.Children.Count > count) { container.Children.RemoveAt(container.Children.Count - 1); } }
// clone constructor private BpmnEdgeStyle(BpmnEdgeStyle other) { renderer = other.renderer; innerPen = other.innerPen; // We need to clone the wrapped style since our properties just delegate there delegateStyle = (PolylineEdgeStyle)other.delegateStyle.Clone(); // setting the type updates all read-only properties Type = other.Type; innerPen = other.innerPen; }
protected DynamicArrowEdgeStyleBase() { sourceArrow = new Arrow() { Type = ArrowType.None }; targetArrow = new Arrow() { Type = ArrowType.Default }; Pen = Pens.Black; renderer = new DynamicArrowEdgeStyleRenderer(); }
/// <summary> /// Draws the edge-like connectors from a node to its labels /// </summary> private void RenderLabelEdges(IRenderContext context, INode node, VisualGroup container, RenderDataCache cache) { if (node.Labels.Count > 0) { // Create a SimpleEdge which will be used as a dummy for the rendering SimpleEdge simpleEdge = new SimpleEdge(null, null); // Assign the style simpleEdge.Style = new MySimpleEdgeStyle { PathThickness = 2 }; // Create a SimpleNode which provides the source port for the edge but won't be drawn itself SimpleNode sourceDummyNode = new SimpleNode { Layout = new RectD(0, 0, node.Layout.Width, node.Layout.Height), Style = node.Style }; // Set source port to the port of the node using a dummy node that is located at the origin. simpleEdge.SourcePort = new SimplePort(sourceDummyNode, FreeNodePortLocationModel.NodeCenterAnchored); // Create a SimpleNode which provides the target port for the edge but won't be drawn itself SimpleNode targetDummyNode = new SimpleNode(); // Create port on targetDummynode for the label target targetDummyNode.Ports = new ListEnumerable <IPort>(new[] { new SimplePort(targetDummyNode, FreeNodePortLocationModel.NodeCenterAnchored) }); simpleEdge.TargetPort = new SimplePort(targetDummyNode, FreeNodePortLocationModel.NodeCenterAnchored); // Render one edge for each label foreach (PointD labelLocation in cache.LabelLocations) { // move the dummy node to the location of the label targetDummyNode.Layout = new MutableRectangle(labelLocation, SizeD.Zero);; // now create the visual using the style interface: IEdgeStyleRenderer renderer = simpleEdge.Style.Renderer; IVisualCreator creator = renderer.GetVisualCreator(simpleEdge, simpleEdge.Style); Visual element = creator.CreateVisual(context); if (element != null) { container.Add(element); } } } }
private bool FindAnchorTangent(IEdge edge, out double upX, out double upY, out double cx, out double cy) { IEdgeStyle style = edge.Style; if (style != null) { IEdgeStyleRenderer renderer = style.Renderer; IPathGeometry geometry = renderer.GetPathGeometry(edge, style); if (geometry != null) { var t = geometry.GetTangent(ratio); if (t != null) { var tangent = t.Value; upX = -tangent.Vector.Y; upY = tangent.Vector.X; cx = tangent.Point.X; cy = tangent.Point.Y; return(true); } } } double l = 0; var spl = edge.SourcePort.GetLocation(); double x1 = spl.X; double y1 = spl.Y; var tpl = edge.TargetPort.GetLocation(); double x2 = tpl.X; double y2 = tpl.Y; { double lx = x1; double ly = y1; var bends = edge.Bends; for (int i = 0; i < bends.Count; i++) { IBend bend = bends[i]; double bx = bend.Location.X; double by = bend.Location.Y; double dx = bx - lx; double dy = by - ly; l += Math.Sqrt(dx * dx + dy * dy); lx = bx; ly = by; } { double dx = x2 - lx; double dy = y2 - ly; l += Math.Sqrt(dx * dx + dy * dy); } } double tl = ratio * l; if (l == 0) { // no length, no path, no label upX = 0; upY = -1; cx = x1; cy = y1; return(false); } l = 0; { double lx = x1; double ly = y1; var bends = edge.Bends; for (int i = 0; i < bends.Count; i++) { IBend bend = bends[i]; double bx = bend.Location.X; double by = bend.Location.Y; double dx = bx - lx; double dy = by - ly; double sl = Math.Sqrt(dx * dx + dy * dy); if (sl > 0 && l + sl >= tl) { tl -= l; cx = lx + tl * dx / sl; cy = ly + tl * dy / sl; upX = -dy; upY = dx; return(true); } l += sl; lx = bx; ly = by; } { double dx = x2 - lx; double dy = y2 - ly; double sl = Math.Sqrt(dx * dx + dy * dy); if (sl > 0) { tl -= l; cx = lx + tl * dx / sl; cy = ly + tl * dy / sl; upX = -dy; upY = dx; return(true); } else { upX = 0; upY = -1; cx = x1; cy = y1; return(false); } } } }