/// <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 MySimpleEdgeStyle { PathThickness = 2 }; // 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); } }
private static void UpdateChildVisual(IRenderContext context, VisualGroup container, int index, IVisualCreator icon) { var oldPathVisual = container.Children[index]; var newPathVisual = icon.UpdateVisual(context, oldPathVisual); if (!oldPathVisual.Equals(newPathVisual)) { newPathVisual = newPathVisual ?? new VisualGroup(); container.Children.Remove(oldPathVisual); container.Children.Insert(index, newPathVisual); } }