コード例 #1
0
        /// <summary>
        /// Event handler that is triggered when a group is closed interactively.
        /// </summary>
        /// <remarks>This method performs an incremental layout on the newly collapsed group node.</remarks>
        /// <param name="source"></param>
        /// <param name="evt"></param>
        private async void NavigationInputMode_GroupCollapsed(object source, ItemEventArgs <INode> evt)
        {
            incrementalNodes.Clear();
            incrementalEdges.Clear();
            // we mark the group node and its adjacent edges as incremental
            incrementalNodes.Add(evt.Item);
            incrementalEdges.UnionWith(graphControl.Graph.EdgesAt(evt.Item));
            // rescue the original node bounds which are needed for a correct layout
            INode groupNode = evt.Item;

            fixedGroupNodeLayout.Clear();
            fixedGroupNodeLayout[groupNode] = groupNode.Layout.ToRectD();

            // retrieve the state of the view node *before* the grouping operation
            INode master = foldingView.GetMasterItem(groupNode);

            // and set these bounds so that the animation will move it to the correct location
            graphControl.Graph.SetNodeLayout(groupNode, master.Layout.ToRectD());

            // reset adjacent edge paths to get smoother layout transitions
            foreach (var edge in graphControl.Graph.EdgesAt(groupNode))
            {
                graphControl.Graph.ClearBends(edge);
            }

            await ApplyLayout();
        }
コード例 #2
0
        /// <summary>
        /// Apply the algorithm which is appropriate for the selected graph.
        /// </summary>
        /// <param name="sampleSelectedIndex">The index to use.</param>
        private async Task ApplyAlgorithmForKey(int sampleSelectedIndex)
        {
            ResetStyles();

            if (CurrentConfig != null && CurrentConfig.IncrementalElements != null &&
                CurrentConfig.IncrementalElements.Entries.Any())
            {
                incrementalElements.Clear();
                CurrentConfig.IncrementalElements = incrementalElements;
                CurrentConfig.EdgeRemoved         = false;
            }

            // run the layout if the layout combo box is already correct
            var algorithmSelectedIndex = algorithmComboBox.SelectedIndex;

            if (!mIsInitializing)
            {
                preventLayout = true;
                // otherwise, change the selection and indirectly trigger the layout
                algorithmComboBox.SelectedIndex = sampleSelectedIndex; // changing the algorithm will trigger a layout run
            }
            else
            {
                UpdateGraphInformation();
            }

            preventLayout = false;
            // run a layout from scratch (i.e. for a new graph), clear the undo queue and apply an analysis algorithm
            await RunLayout(false, true, true);
        }
コード例 #3
0
 /// <summary>
 /// Creates a mapping to specify the components which should not be modified by <see cref="ClearAreaLayout"/>.
 /// </summary>
 private void UpdateComponents()
 {
     components.Clear();
     if (subtree.NewParent != null)
     {
         foreach (var edge in Graph.OutEdgesAt(subtree.NewParent))
         {
             var siblingSubtree = new Subtree(Graph, edge.GetTargetNode());
             foreach (var node in siblingSubtree.Nodes)
             {
                 components[node] = siblingSubtree;
             }
         }
     }
 }
 public void Clear()
 {
     backingMapper.Clear();
 }
コード例 #5
0
        /// <summary>
        /// Run a layout and an analysis algorithm if wanted.
        /// </summary>
        /// <param name="incremental">Whether to run in incremental mode, i.e. only moving new items.</param>
        /// <param name="clearUndo">Whether to clear the undo queue after the layout.</param>
        /// <param name="runAlgorithm">Whether to apply the <see cref="CurrentConfig">current analysis algorithm</see>, too.</param>
        /// <returns></returns>
        private async Task RunLayout(bool incremental, bool clearUndo, bool runAlgorithm)
        {
            // the actual organic layout
            var layout = new OrganicLayout {
                Deterministic       = true,
                ConsiderNodeSizes   = true,
                Scope               = incremental ? Scope.MainlySubset : Scope.All,
                LabelingEnabled     = false,
                PreferredEdgeLength = 100,
                MinimumNodeDistance = 10
            };

            ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.None | ComponentArrangementStyles.ModifierNoOverlap;

            OrganicLayoutData layoutData = null;

            if (incremental && incrementalNodesMapper != null)
            {
                layoutData = new OrganicLayoutData();
                layoutData.AffectedNodes.Mapper = incrementalNodesMapper;
            }
            inLayout = true;
            SetUiDisabled(true);
            // run the layout in an asynchronous, animated fashion
            await graphControl.MorphLayout(layout, TimeSpan.FromSeconds(0.5), layoutData);

            // run algorithm
            if (runAlgorithm)
            {
                // apply graph algorithms after layout
                ApplyAlgorithm();
                var algorithm = algorithmComboBox.SelectedItem as Algorithm;
                if (algorithm != null && algorithm.DisplayName.EndsWith("Centrality"))
                {
                    // since centrality changes the node sizes, node overlaps need to be removed
                    await graphControl.MorphLayout(new OrganicRemoveOverlapsStage(), TimeSpan.FromSeconds(0.2));
                }
            }

            // labeling: place labels after the layout and the analysis (which might have generated or changed labels)
            var labeling = new GenericLabeling {
                PlaceEdgeLabels = true,
                PlaceNodeLabels = false,
                Deterministic   = true
            };
            var labelingData = new LabelingData {
                EdgeLabelPreferredPlacement =
                {
                    Delegate                                            = label => {
                        var preferredPlacementDescriptor                = new PreferredPlacementDescriptor();
                        if ("Centrality".Equals(label.Tag))
                        {
                            preferredPlacementDescriptor.SideOfEdge     = LabelPlacements.OnEdge;
                        }
                        else
                        {
                            preferredPlacementDescriptor.SideOfEdge     = LabelPlacements.RightOfEdge | LabelPlacements.LeftOfEdge;
                            preferredPlacementDescriptor.DistanceToEdge = 5;
                        }
                        preferredPlacementDescriptor.Freeze();
                        return(preferredPlacementDescriptor);
                    }
                }
            };
            await graphControl.MorphLayout(labeling, TimeSpan.FromSeconds(0.2), labelingData);

            // cleanup
            if (clearUndo)
            {
                graphControl.Graph.GetUndoEngine().Clear();
            }
            // clean up data provider
            incrementalNodesMapper.Clear();

            // enable the UI's buttons
            ReleaseLocks();
            SetUiDisabled(false);
            UpdateUiState();
        }