6
Vote

Index out of range in .EfficientSugiyamaLayoutAlgorithm.Sweeping

description

I have a few checkboxes in the gui, controlling which objects to show. When changing a checkbox a new graph is created and set through a call to GraphViewModel.Graph. It works a few times before crashing. The animation is awesome :-).

This is the stack trace:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at GraphSharp.Algorithms.Layout.Simple.Hierarchical.EfficientSugiyamaLayoutAlgorithm3.Sweeping(Int32 startLayerIndex, Int32 endLayerIndex, Int32 step, Boolean enableSameMeasureOptimization, Boolean& changed, Int32& phase) in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#\Algorithms\Layout\Simple\Hierarchical\EfficientSugiyamaAlgorithm.DoCrossingMinimizations.cs:line 87
at GraphSharp.Algorithms.Layout.Simple.Hierarchical.EfficientSugiyamaLayoutAlgorithm
3.DoCrossingMinimizations() in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#\Algorithms\Layout\Simple\Hierarchical\EfficientSugiyamaAlgorithm.DoCrossingMinimizations.cs:line 58
at GraphSharp.Algorithms.Layout.Simple.Hierarchical.EfficientSugiyamaLayoutAlgorithm3.InternalCompute() in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#\Algorithms\Layout\Simple\Hierarchical\EfficientSugiyamaLayoutAlgorithm.cs:line 111
at GraphSharp.Algorithms.AlgorithmBase.Compute() in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#\Algorithms\AlgorithmBase.cs:line 36
at GraphSharp.Controls.GraphLayout
3.Layout(Boolean continueLayout) in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#.Controls\Controls\GraphLayout.cs:line 301
at GraphSharp.Controls.GraphLayout3.Relayout() in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#.Controls\Controls\GraphLayout.cs:line 128
at GraphSharp.Controls.GraphLayout
3.OnRelayoutInduction(Boolean tryKeepControls) in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#.Controls\Controls\GraphLayout.DependencyProperties.cs:line 396
at GraphSharp.Controls.GraphLayout`3.Graph_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) in d:\projects\graphsharp-6e1f3e1fd045\Source\Graph#.Controls\Controls\GraphLayout.DependencyProperties.cs:line 384
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp)
at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.ScheduleTransfer(Boolean isASubPropertyChange)
at MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean dependencySourcesChanged, Boolean initialValue, Boolean isASubPropertyChange)
at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
at MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(Object o, String propName)
at MS.Internal.Data.PropertyPathWorker.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
at System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(Object sender, PropertyChangedEventArgs args)
at CmdbScriptEditor.GraphViewModel.NotifyPropertyChanged(String info) in d:\projects\CMDB\CmdbScriptEditor\GraphViewModel.cs:line 184
at CmdbScriptEditor.GraphViewModel.set_Graph(GraphModel value) in d:\projects\CMDB\CmdbScriptEditor\GraphViewModel.cs:line 160
at CmdbScriptEditor.GraphViewModel.CreateGraphToVisualize() in d:\projects\CMDB\CmdbScriptEditor\GraphViewModel.cs:line 259
at CmdbScriptEditor.GraphViewModel.RemoveScriptStatus(String status) in d:\projects\CMDB\CmdbScriptEditor\GraphViewModel.cs:line 131
at CmdbScriptEditor.MainWindow.RibbonCheckBox_Unchecked(Object sender, RoutedEventArgs e) in d:\projects\CMDB\CmdbScriptEditor\MainWindow.xaml.cs:line 70
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ToggleButton.OnUnchecked(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ToggleButton.OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)
at System.Windows.Controls.Primitives.ToggleButton.OnToggle()
at Microsoft.Windows.Controls.Ribbon.RibbonCheckBox.OnClick() in e:\dd\WPFOOB\src\wpfoob\Ribbon\RibbonControlsLibrary\Microsoft\Windows\Controls\Ribbon\RibbonCheckBox.cs:line 509
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at CmdbScriptEditor.App.Main() in d:\projects\CMDB\CmdbScriptEditor\obj\Debug\App.g.cs:line 0

comments

more10 wrote Nov 14, 2011 at 9:19 PM

I am using graphsharp-6e1f3e1fd045

more10 wrote Nov 15, 2011 at 8:28 AM

Same as #8276

mrdix wrote Apr 30, 2012 at 9:04 AM

the exception also occurs when creating a graph with only 1 vertex and no edges.

method "Sweeping" is then called with startLayerIndex = 0 and endLayerIndex = -1.

adamcarmi wrote Oct 3, 2012 at 9:37 AM

Here is how I worked around this issue:
    private void ConfigureLayout_(ModelGraphViewerGraph graph)
    {
        if (graph == null || graph.VertexCount == 0)
        {
            graphLayout_.LayoutAlgorithmType = null;
            return;
        }

        if (graph.EdgeCount == 0 || graph.VertexCount <= 1)
        {
            graphLayout_.LayoutAlgorithmType = "CompoundFDP";
        }
        else
        {
            graphLayout_.LayoutAlgorithmType = "EfficientSugiyama";
        }
    }
The idea is to use a different graph layout when the graph is problematic. Fortunately, the problematic graphs are trivial so the layout change is smooth. You should call the method right after the graph is modified to refresh the layout. When setting the EfficientSugiyama layout you may want to set the layout parameters. For example:
var layoutParams = graphLayout_.LayoutParameters as 
    GraphSharp.Algorithms.Layout.Simple.Hierarchical.EfficientSugiyamaLayoutParameters;
layoutParams.LayerDistance = 25;
layoutParams.VertexDistance = 25;
layoutParams.MinimizeEdgeLength = false;

vasa911 wrote Feb 5, 2015 at 8:55 PM

@adamcarmi, thank you. Your suggestion fixes this bug.