/// <summary> /// Helper method that increases the heat of the neighbors of a given node by a given value. /// </summary> /// <remarks> /// This will make the layout move the neighbor nodes more quickly. /// </remarks> private static void IncreaseHeat(Node copiedNode, InteractiveOrganicLayout layout, double delta) { //Increase Heat of neighbors foreach (Node neighbor in copiedNode.Neighbors) { double oldStress = layout.GetStress(neighbor); layout.SetStress(neighbor, Math.Min(1, oldStress + delta)); } }
/// <summary> /// Create a new layout instance and start it in a new thread /// </summary> /// <returns></returns> private InteractiveOrganicLayout StartLayout() { // create the layout InteractiveOrganicLayout organicLayout = new InteractiveOrganicLayout { MaximumDuration = 2000 }; // use an animator that animates an infinite animation var animator = new Animator(GraphControl) { AutoInvalidation = false, AnimationPriority = DispatcherPriority.Input }; animator.Animate(delegate { if (!organicLayout.Running) { animator.Stop(); return; } if (organicLayout.CommitPositionsSmoothly(50, 0.05) > 0) { GraphControl.UpdateVisual(); } }, TimeSpan.MaxValue); // run the layout in a separate thread Thread thread = new Thread(new ThreadStart(delegate { // we run the real interactive version of the organic layout // previously we only calculated the initial layout using OrganicLayout organicLayout.ApplyLayout(copiedLayoutGraph); // stop the animator when the layout returns (does not normally happen at all) graphControl.Dispatcher.Invoke(new Action <Animator>(animator1 => animator1.Stop()), animator); })); thread.IsBackground = true; thread.Start(); return(organicLayout); }