/// <summary> /// Initializes the graph instance, setting default styles /// and creating a small sample graph. /// </summary> protected virtual void InitializeGraph() { // Create the graph instance that will hold the complete graph. fullGraph = new DefaultGraph(); // Create a nice default style for the nodes fullGraph.NodeDefaults.Style = new NodeControlNodeStyle("InnerNodeStyleTemplate"); fullGraph.NodeDefaults.Size = new SizeD(60, 30); fullGraph.NodeDefaults.ShareStyleInstance = false; // and a style for the labels DefaultLabelStyle labelStyle = new DefaultLabelStyle(); fullGraph.NodeDefaults.Labels.Style = labelStyle; // now build a simple sample tree BuildTree(fullGraph, 3, 3, 3); // create a view of the graph that contains only non-collapsed subtrees. // use a predicate method to decide what nodes should be part of the graph. filteredGraph = new FilteredGraphWrapper(fullGraph, NodePredicate); // display the filtered graph in our control. graphControl.Graph = filteredGraph; // center the graph to prevent the initial layout fading in from the top left corner graphControl.FitGraphBounds(); // create layout algorithms SetupLayouts(); }
/// <summary> /// Creates a new <see cref="FilteredGraphWrapper"/> that shows the currently visible original nodes. /// </summary> /// <remarks> /// Nodes without currently visible edges are also filtered out. /// </remarks> private FilteredGraphWrapper CreateFilteredView() { // create a new FilteredGraphWrapper that filters the original graph and shows only the currently visible nodes var filteredGraph = new FilteredGraphWrapper(OriginalGraph, node => { node = aggregationHelper.GetPlaceholder(node); if (!AggregateGraph.Contains(node)) { return(false); } // also filter nodes without edges return(AggregateGraph.EdgesAt(node).Count(edge => !aggregationHelper.IsHierarchyEdge(edge)) > 0); }); // set the node layouts for a smooth transition foreach (var node in filteredGraph.Nodes) { filteredGraph.SetNodeLayout(node, aggregationHelper.GetPlaceholder(node).Layout.ToRectD()); } // reset any rotated labels foreach (var label in filteredGraph.Labels) { filteredGraph.SetLabelLayoutParameter(label, FreeNodeLabelModel.Instance.CreateDefaultParameter()); } return(filteredGraph); }
private void OnLoaded(object src, EventArgs eventArgs) { InitializeGraph(); // register command bindings graphControl.CommandBindings.Add(new CommandBinding(HideChildrenCommand, HideChildrenExecuted, CanExecuteHideChildren)); graphControl.CommandBindings.Add(new CommandBinding(ShowChildrenCommand, ShowChildrenExecuted, CanExecuteShowChildren)); graphControl.CommandBindings.Add(new CommandBinding(HideParentCommand, HideParentExecuted, CanExecuteHideParent)); graphControl.CommandBindings.Add(new CommandBinding(ShowParentCommand, ShowParentExecuted, CanExecuteShowParent)); graphControl.CommandBindings.Add(new CommandBinding(ShowAllCommand, ShowAllExecuted, CanExecuteShowAll)); // disable selection, focus and highlight painting GraphControl.SelectionIndicatorManager.Enabled = false; GraphControl.FocusIndicatorManager.Enabled = false; GraphControl.HighlightIndicatorManager.Enabled = false; // we wrap the graph instance by a filtered graph wrapper filteredGraphWrapper = new FilteredGraphWrapper(GraphControl.Graph, ShouldShowNode); GraphControl.Graph = filteredGraphWrapper; // now calculate the initial layout DoLayout(); GraphControl.FitGraphBounds(); LimitViewport(); }
private void FormLoaded() { // load description description.LoadFile(new MemoryStream(Resources.description), RichTextBoxStreamType.RichText); InitializeGraph(); // build the object model from the XML var employeeRoots = TreeBuilder.BuildEmployeesFromXml(); BuildGraph(employeeRoots); BuildTree(employeeRoots); InitializeInputModes(); InitializeToolTips(); graphControl.CurrentItemChanged += graphControl_CurrentItemChanged; // disable selection, focus and highlight painting GraphControl.SelectionIndicatorManager.Enabled = false; GraphControl.FocusIndicatorManager.Enabled = false; GraphControl.HighlightIndicatorManager.Enabled = false; // we wrap the graph instance by a filtered graph wrapper filteredGraphWrapper = new FilteredGraphWrapper(GraphControl.Graph, ShouldShowNode); GraphControl.Graph = filteredGraphWrapper; graphOverviewControl.GraphControl = graphControl; // now calculate the initial layout DoLayout(); GraphControl.FitGraphBounds(); LimitViewport(); }
/// <summary> /// Initializes the graph instance setting default styles, /// load the sample graph and route its edges. /// </summary> protected virtual void InitializeGraph() { // setting styles for maze nodes Graph.NodeDefaults.Style = new ShapeNodeStyle { Pen = null, Brush = new SolidColorBrush(Color.FromRgb(102, 153, 204)) }; // add maze nodes to graph and store in a list graphControl.GraphMLIOHandler.Read(Graph, "Resources/mazeOnly.graphml"); var mazeNodes = Graph.Nodes.ToList(); // update styles for normal nodes Graph.NodeDefaults.Style = new ShinyPlateNodeStyle { Brush = Brushes.Orange }; graphControl.GraphMLIOHandler.ClearGraphBeforeRead = false; graphControl.GraphMLIOHandler.Read(Graph, "Resources/normalNodesOnly.graphml"); // store the full graph to use for layout configuration fullGraph = Graph; // add the visual of the maze to the graph foreach (var node in mazeNodes) { graphControl.BackgroundGroup.AddChild(node, CanvasObjectDescriptors.AlwaysDirtyLookup); } // route the edges according to the configured polylineEdgeRouter Graph.ApplyLayout(GetLayoutAlgorithm()); // remove the maze after successfully applying the layout for the first time var filteredGraph = new FilteredGraphWrapper( Graph, // if the node has a tag, its a maze and needs to be removed node => node.Tag == null ); // set the filtered graph without mazes Graph = filteredGraph; // enable undo engine and clear for first start Graph.SetUndoEngineEnabled(true); Graph.GetUndoEngine().Clear(); }
/// <summary> /// Marks the cycle nodes and edges. /// </summary> private void MarkCycles(IGraph graph, CycleEdges.Result cycleResult) { // hides all non-cycle edges to be able to find independent cycles var cycleEdgeSet = new HashSet <IEdge>(cycleResult.Edges); var filteredGraph = new FilteredGraphWrapper(graph, node => true, edge => cycleEdgeSet.Contains(edge)); // now find independent cycles var result = new ConnectedComponents().Run(filteredGraph); // find the components that are affected by the user's move, if any var affectedComponents = GetAffectedNodeComponents(result.NodeComponents); // find the component with the larger number of elements var largestComponent = GetLargestComponent(affectedComponents); // hold a color for each affected components var color2AffectedComponent = new Dictionary <Component, Color>(); // generate the colors for the components var colors = GenerateColors(false); for (var i = 0; i < result.Components.Count; i++) { var component = result.Components[i]; foreach (var edge in component.InducedEdges) { // the source and target node get the same color, depending on their connecting edge var color = DetermineElementColor(colors, component, affectedComponents, color2AffectedComponent, largestComponent, result.Components, graph, edge); edge.Tag = new Tag { CurrentColor = color, Directed = Directed }; var source = edge.GetSourceNode(); source.Tag = new Tag { CurrentColor = color }; var target = edge.GetTargetNode(); target.Tag = new Tag { CurrentColor = color }; } } }
/// <summary> /// A <see cref="LayoutExecutor"/> that is used when dragging the subtree starts. /// </summary> /// <remarks> /// When the drag begins, the <see cref="FillAreaLayout"/> fills up the space that was covered by the subtree. /// This state is the initial layout for the <see cref="ClearAreaLayout"/> during the drag. /// </remarks> private LayoutExecutor CreateInitializingLayoutExecutor() { var layout = new FillAreaLayout { LayoutOrientation = LayoutOrientation.TopToBottom, ComponentAssignmentStrategy = ComponentAssignmentStrategy.Customized, Spacing = 50 }; layout.ConfigureAreaOutline(subtree.Nodes); var layoutData = new FillAreaLayoutData { ComponentIds = { Mapper = components }, }; // the FillAreaLayout is only applied to the part of the tree that does not belong to the subtree IGraph filteredGraph = new FilteredGraphWrapper(graphControl.Graph, n => !subtree.Nodes.Contains(n)); return(new LayoutExecutor(graphControl, filteredGraph, layout) { LayoutData = layoutData, RunInThread = true, Duration = TimeSpan.FromMilliseconds(150) }); }
public DraggingLayoutExecutor(GraphControl graphControl, ILayoutAlgorithm layout, ICollection <INode> nodes) : base(graphControl, layout) { filteredGraph = new FilteredGraphWrapper(graphControl.Graph, n => !nodes.Contains(n)); }