This is a migrated thread and some comments may be shown as answers.

TreeLayout does not work for custom connectors

12 Answers 190 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Kristoffer
Top achievements
Rank 1
Kristoffer asked on 14 Jan 2013, 06:24 PM

I have a custom connection class as shown below. I have removed the 5 connectors of my nodes ("Auto", "Left", "Right", "Top", "Bottom") and added my own connectors "In" and "Out".

public class MyChartConnection : RadDiagramConnection
{
    public MyChartConnection(MyLink link)
        : base()
    {
        SourceConnectorPosition = /*ConnectorPosition.Auto*/ "in";
        SourceCapType = link.SourceCapType;

        TargetConnectorPosition = /*ConnectorPosition.Auto*/ "out";
        TargetCapType = link.TargetCapType;
    }
}

This crashes when I try to apply your TreeLayout(). Apparently, it cannot find the "Bottom" connector... Should I use another layout class? Do I have to implement my own layout class?

12 Answers, 1 is accepted

Sort by
0
Francois
Telerik team
answered on 15 Jan 2013, 02:56 PM
Kristoffer,

this is the same bug as the one which was recorded in PITS and has been resolved on January 9th.
I have a working example with the current codebase but I reckon you'll have to wait till Q1.2013 is out.

Sorry for this.

All the best,
Francois
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Kristoffer
Top achievements
Rank 1
answered on 28 Jan 2013, 09:56 AM
Just replaced my Telerik binaries with files from RadControls_for_WPF_2012_3_1314_DEV_hotfix.zip
Same problem!


---------------------------

---------------------------
System.Exception: Connector 'Bottom' does not exist.

   at Telerik.Windows.Controls.RadDiagramConnection.ResolveSourceConnector() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 955

   at Telerik.Windows.Controls.RadDiagramConnection.OnSourceConnectorPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 902

   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.SetValue(DependencyProperty dp, Object value)

   at Telerik.Windows.Controls.RadDiagramConnection.set_SourceConnectorPosition(String value) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 352

   at Telerik.Windows.Diagrams.Core.OrgTreeRouter.DirectionalRouter.SetSourceAndTargetConnectors() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 93

   at Telerik.Windows.Diagrams.Core.OrgTreeRouter.TreeRouterBase.GetRoute(IConnection connection, Double connectionSpacing) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 332

   at Telerik.Windows.Diagrams.Core.OrgTreeRouter.GetRoutePoints(IConnection connection, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 66

   at Telerik.Windows.Diagrams.Core.RoutingService.BuildRoute(IConnection connection) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Services\RoutingService.cs:line 46

   at Telerik.Windows.Controls.Diagrams.GeometryFactory.CreateConnectionGeometry(IConnection connection, RoutingService routingService) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Utilities\GeometryFactory.cs:line 346

   at Telerik.Windows.Controls.RadDiagramConnection.UpdateGeometryOverride() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 852

   at Telerik.Windows.Controls.RadDiagramConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 805

   at Telerik.Windows.Controls.RadDiagramConnection.Telerik.Windows.Diagrams.Core.IConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 525

   at Telerik.Windows.Diagrams.Core.GraphController.UpdateConnectionsAndCheckForSelection(IShape shape) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.cs:line 707

   at Telerik.Windows.Diagrams.Core.GraphController.OnShapePropertyChanged(Object sender, PropertyEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.Services.cs:line 422

   at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnPropertyChanged(String propertyName) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 902

   at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnSizeChanged(Size newSize, Size oldSize) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 992

   at Telerik.Windows.Controls.Diagrams.RadDiagramItem.DiagramItemSizeChanged(Object sender, SizeChangedEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 1188

   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)

   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)

   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)

   at System.Windows.FrameworkElement.OnRenderSizeChanged(SizeChangedInfo sizeInfo)

   at System.Windows.ContextLayoutManager.fireSizeChangedEvents()

   at System.Windows.ContextLayoutManager.UpdateLayout()

   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)

   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()

   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)

   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)

   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)
---------------------------
OK  
---------------------------



And when trying to create a manual connection I now get the error below. The only way to get rid of the errors is to leave the original connectors... 

---------------------------

---------------------------
System.ArgumentException: No neighour corners found!

   at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetNeighborCorners(String orientation, Rect rect, Point& n1, Point& n2) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 521

   at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, Boolean& flag) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 355

   at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetRoutePoints(ConnectorInfo source, ConnectorInfo target, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 64

   at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetRoutePoints(IConnection connection, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 271

   at Telerik.Windows.Diagrams.Core.RoutingService.BuildRoute(IConnection connection) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Services\RoutingService.cs:line 50

   at Telerik.Windows.Controls.Diagrams.GeometryFactory.CreateConnectionGeometry(IConnection connection, RoutingService routingService) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Utilities\GeometryFactory.cs:line 346

   at Telerik.Windows.Controls.RadDiagramConnection.UpdateGeometryOverride() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 852

   at Telerik.Windows.Controls.RadDiagramConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 805

   at Telerik.Windows.Controls.RadDiagramConnection.Telerik.Windows.Diagrams.Core.IConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 525

   at Telerik.Windows.Diagrams.Core.GraphController.OnConnectionPropertyChanged(Object sender, PropertyEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.Services.cs:line 349

   at System.EventHandler`1.Invoke(Object sender, TEventArgs e)

   at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnPropertyChanged(String propertyName) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 902

   at Telerik.Windows.Controls.RadDiagramConnection.set_EndPoint(Point value) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 340

   at Telerik.Windows.Diagrams.Core.ConnectionTool.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ConnectionTool.cs:line 89

   at Telerik.Windows.Diagrams.Core.ToolService.<>c__DisplayClassc.<MouseMove>b__b(IMouseListener tool) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ToolService.cs:line 142

   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)

   at Telerik.Windows.Diagrams.Core.ToolService.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ToolService.cs:line 142

   at Telerik.Windows.Diagrams.Core.GraphController.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.cs:line 198

   at Telerik.Windows.Controls.RadDiagram.OnMouseMove(MouseEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\RadDiagram.cs:line 381

   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)

   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.Input.InputManager.ProcessStagingArea()

   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)
---------------------------
OK  
---------------------------

0
Kristoffer
Top achievements
Rank 1
answered on 28 Jan 2013, 04:27 PM
RadControls_for_WPF_2012_3_1321_DEV_hotfix.zip - same problem.

Please fix this as soon as possible! This is pretty much a blocker for us.
0
Petar Mladenov
Telerik team
answered on 31 Jan 2013, 07:02 AM
Hi Kristoffer,

 This bug is fixed but it won't be included in our internal builds. It will be included in the upcoming Official Q1 Release is mid-February. This mainly because it must go through our testing procedures successfully. On the other hand, we have missed to schedule it for Q1 in PITS, please excuse us for the inconvenience caused.

Kind regards,
Petar Mladenov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Kristoffer
Top achievements
Rank 1
answered on 02 Sep 2013, 02:47 PM
Though this particular issue was solved, the TreeLayout algorithm still suffers when using custom connectors. More specifically, it often swaps the y-position of the parent with its child. This always fails:

1) Add node A.
2) Add node B.
3) Not needed, but here for clarity: Rearrange the nodes so that B is above A.
4) Connect from B's bottom connector to A's top connector.
5) The nodes exchange positions, resulting in the attached image. (A is above B.)

Do you rely on ZIndex or some other weird variable when arranging the nodes? I believe this bug is the root of all problems we see when laying out our nodes.
0
Petar Mladenov
Telerik team
answered on 04 Sep 2013, 10:52 AM
Hi Kristoffer,

Could you please confirm that these provided steps are independent from scenarios where some shapes have multiple parents ? Several months ago you needed some kind of topological sorting and we explained that this currently cannot be achieved out of the box with TreeLayout and you will need custom Layout method or at least a method that works after the work of the TreeLayout (to arrange the additional parent nodes).
If this is not the case could you please check out our test project where we are unable to reproduce similar issue. We delete a connection, then create manually new connections with mouse connecting custom connectors and the Layout does not replace the source and target shapes. Please let us know if we are missing anything in the attached sample.
We do not rely on ZIndex when arranging the nodes. We use Position, Width, Height. And we also determine which node of the given two is the father, in tree with root - this is the one closer to the root.

Regards,
Petar Mladenov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Kristoffer
Top achievements
Rank 1
answered on 04 Sep 2013, 11:14 AM
Thanks for your response. No, this error has nothing to do with multiple root nodes. The five steps were performed on a diagram with no shapes - hence no other root nodes.

I'll try your sample project right away.
0
Kristoffer
Top achievements
Rank 1
answered on 04 Sep 2013, 11:19 AM
Yes, I can reproduce the error in your sample. Hooray!! :D

1) Copy a node (Ctrl+C).
2) Remove all nodes (Ctrl+A, Del).
3) Paste node #1 (Ctrl+V).
4) Paste node #2 (Ctrl+V).
5) Move node #2 above node #1.
6) Connect them.
7) Press "Layout".

Voilà!
0
Accepted
Petar Mladenov
Telerik team
answered on 04 Sep 2013, 11:32 AM
Hello Kristoffer,

 The Layout Button invokes the function PrepareAndLayout:

private void PrepareAndLayout()
{          
    TreeLayoutSettings settings = new TreeLayoutSettings()
    {
        TreeLayoutType = TreeLayoutType.TreeDown,
        VerticalDistance = 100,
        UnderneathHorizontalOffset = 50,
        UnderneathVerticalTopOffset = 50,
        UnderneathVerticalSeparation = 60
    };
    settings.Roots.Add(this.diagram.Shapes[0]);
    OrgTreeRouter router = new OrgTreeRouter()
    {
        TreeLayoutType = TreeLayoutType.TreeDown,
        ConnectionOuterSpacing = 20,
    };
    this.diagram.RoutingService.Router = router;
    this.diagram.Layout(LayoutType.Tree, settings);
}
You can see the green line sets the first shape in the Diagram.Shapes collection as the root of the tree which will be arranged. So it is entirely expected that the first pasted node will be set on top of the second pasted after layout. The first pasted becomes the first in the Shapes colelction.

Regards,
Petar Mladenov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Kristoffer
Top achievements
Rank 1
answered on 04 Sep 2013, 11:36 AM
We don't add any shapes to the Roots collection. Does it pick an arbitrary (e.g. first created) node in that case?
0
Petar Mladenov
Telerik team
answered on 04 Sep 2013, 12:06 PM
Hello Kristoffer,

 No, when there is no root set, the algorithm finds a root on the basis of longest paths in the graph:

/// <summary>
    /// Attempts to find a tree root by looking at the longest paths in the graph.
    /// </summary>
    /// <remarks>The algorithms looks for all shortest paths between all vertices, which means it will also function for disconnected graphs but will return the root
    /// of the tree with longest path.</remarks>
    /// <returns>A tree root or <c>null</c> is none was found.
    /// </returns>
    public TNode FindTreeRoot()
    {
However, in order to avoid roots you do not wish, simply set the Roots in the TreeViewSettings.

Regards,
Petar Mladenov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Kristoffer
Top achievements
Rank 1
answered on 04 Sep 2013, 12:08 PM
Thanks!

Adding all nodes that have no connections from above (i.e. input connectors are either not present or have no connections) solved the issue.
Tags
Diagram
Asked by
Kristoffer
Top achievements
Rank 1
Answers by
Francois
Telerik team
Kristoffer
Top achievements
Rank 1
Petar Mladenov
Telerik team
Share this question
or