protected override VisualGroup UpdateVisual(IRenderContext context, VisualGroup group, INode node) { if (group == null) { return(CreateVisual(context, node)); } // update the node visualization group.Children[0] = NodeStyle.Renderer.GetVisualCreator(node, NodeStyle).UpdateVisual(context, group.Children[0]); // update the "visual" ports int count = 1; foreach (var portDescriptor in PortDescriptor.CreatePortDescriptors(FlowChartType)) { if (portDescriptor.X != int.MaxValue) { var parameter = FreeNodePortLocationModel.Instance.CreateParameter(PointD.Origin, new PointD(portDescriptor.X, portDescriptor.Y)); var port = new SimplePort(node, parameter) { LookupImplementation = Lookups.Empty }; // see if we have a visual to update... if (count < group.Children.Count) { var oldPortVisual = group.Children[count]; group.Children[count] = PortStyle.Renderer.GetVisualCreator(port, PortStyle).UpdateVisual(context, oldPortVisual); } else { // no - add a new one var portVisual = PortStyle.Renderer.GetVisualCreator(port, PortStyle).CreateVisual(context); group.Children.Add(portVisual); } } count++; } // see if the number of ports decreased while (count < group.Children.Count) { // yes, remove the old visual var index = group.Children.Count - 1; group.Children.RemoveAt(index); } return(group); }
/// <summary> /// Actually creates the visual appearance of a node. /// </summary> /// <remarks> /// This renders the node and the edges to the labels and adds the visuals to the <paramref name="container"/>. /// All items are arranged as if the node was located at (0,0). <see cref="CreateVisual"/> and <see cref="UpdateVisual"/> /// finally arrange the container so that the drawing is translated into the final position. /// </remarks> private void Render(IRenderContext context, INode node, VisualGroup container) { var innerVisual = NodeStyle.Renderer.GetVisualCreator(node, NodeStyle).CreateVisual(context); container.Add(innerVisual); // draw "visual" ports foreach (var portDescriptor in PortDescriptor.CreatePortDescriptors(FlowChartType)) { if (portDescriptor.X != int.MaxValue) { var parameter = FreeNodePortLocationModel.Instance.CreateParameter(PointD.Origin, new PointD(portDescriptor.X, portDescriptor.Y)); var port = new SimplePort(node, parameter) { LookupImplementation = Lookups.Empty }; var portVisual = PortStyle.Renderer.GetVisualCreator(port, PortStyle).CreateVisual(context); container.Children.Add(portVisual); } } }
/// <summary> /// Perform the layout operation /// </summary> private async Task ApplyLayout() { // layout starting, disable button layoutButton.IsEnabled = false; // create the layout algorithm var layout = new HierarchicLayout { OrthogonalRouting = true, LayoutOrientation = LayoutOrientation.TopToBottom }; // do the layout await graphControl.MorphLayout(layout, TimeSpan.FromSeconds(1), new HierarchicLayoutData { //Automatically determine port constraints for source and target NodePortCandidateSets = { Delegate = node => { var candidateSet = new PortCandidateSet(); // iterate the port descriptors var descriptors = PortDescriptor.CreatePortDescriptors(((FlowChartNodeStyle)node.Style).FlowChartType); foreach (var portDescriptor in descriptors) { PortCandidate candidate; // isn't a fixed port candidate (location is variable) if (portDescriptor.X == int.MaxValue) { // create a port candidate at the specified side (east, west, north, south) and apply a cost to it candidate = PortCandidate.CreateCandidate(portDescriptor.Side, portDescriptor.Cost); } else { // create a candidate at a fixed location and side var x = portDescriptor.X - node.Layout.Width / 2; var y = portDescriptor.Y - node.Layout.Height / 2; candidate = PortCandidate.CreateCandidate(x, y, portDescriptor.Side, portDescriptor.Cost); } candidateSet.Add(candidate, portDescriptor.Capacity); } return(candidateSet); } }, SourceGroupIds = { Delegate = edge => { // create bus-like edge groups for outgoing edges at Start nodes var sourceNode = edge.SourcePort.Owner as INode; if (sourceNode != null && ((((FlowChartNodeStyle)sourceNode.Style).FlowChartType)) == FlowChartType.Start) { return(sourceNode); } return(null); } }, TargetGroupIds = { Delegate = edge => { // create bus-like edge groups for incoming edges at Branch nodes var targetNode = edge.TargetPort.Owner as INode; if (targetNode != null && (((FlowChartNodeStyle)targetNode.Style).FlowChartType) == FlowChartType.Branch) { return(targetNode); } return(null); } } }); // enable button again layoutButton.IsEnabled = true; }