Node and link overlap

Hi,
My application is an advanced system (in Arabic Language) that produces a natural-tree-like family tree. The attached picture explains what I want to achieve. I got very close to my goal. In fact I am satisfied with GoXam and proud of what I have done so far. I have very sofisticated node and link templates with lots of bindings for properties, and what is shown in the picture is only a simple family tree diagram.


The issue here is node and link overlap. Here is my diagram xaml:

<go:Diagram x:Name="myWholeView" LinkTemplateDictionary="{StaticResource LinkTemplateDictionary}"
NodeTemplateDictionary="{StaticResource NodeTemplateDictionary}" Foreground="Transparent"
ContextMenuEnabled="True" Margin="0,20,0,0"
InitialStretch="Uniform" Stretch="Uniform" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" AllowDrop="True">










<golayout:TreeLayout x:Name="WVlayouter" Angle="270" TreeStyle="Layered" Alignment="Bus"
LayerSpacing="{Binding ElementName=LayerSpacingSlider, Path=Value, Mode=TwoWay}"
NodeSpacing="{Binding ElementName=NodeSpacingSlider, Path=Value, Mode=TwoWay}" />


Can you suggest the easiest and best way to avoid node and link overlapping. Changing node and layer spacing did not fix the issue. I have included all layout, link and node control properties as part of my user interface, and I can adjust them interactively, but none of them fixed the issue. After exhausting all possibilities of making a resolution, I suspect that the sequence of linking the nodes might cause this effect. When I change the layout sorting, nodes are placed differently in the tree, but it did not change the link and node overlap. Also, my process of linking the nodes is very complicated and requires complete re-writing in order to change, and I am not sure even if it will solve the issue. Am I correct in this presumption?
Please advice. Thanks in advance.

GoXam version 1.2.2.4

Note:

No Groups (SubGraphs) is implemented, only nodes and links.

This should get you close without any programming. You will need to fiddle with the actual …Spacing properties.

<DataTemplate x:Key="NormalLinkTemplate">
  <go:LinkShape Stroke="Brown" StrokeThickness="10">
    <go:Link.Route>
      <go:Route Routing="Orthogonal" Corner="200" />
    </go:Link.Route>
  </go:LinkShape>
</DataTemplate>

<go:Diagram x:Name="myDiagram" Padding="10"
            NodeTemplate= . . .
            LinkTemplate="{StaticResource NormalLinkTemplate}">
  <go:Diagram.Layout>
    <go:TreeLayout TreeStyle="LastParents" 
                   Alignment="Bus" AlternateAlignment="Bus"
                   Angle="270" AlternateAngle="270"
                   LayerSpacing="100" AlternateLayerSpacing="100"
                   NodeSpacing="100" AlternateNodeSpacing="100"
                   RowSpacing="200" AlternateRowSpacing="20" />
  </go:Diagram.Layout>
</go:Diagram>

If you want to have a different curve, like that in your picture, that’s possible but might require some programming to make sure the curve avoids crossing over any nodes.

Thanks Walter, I will give it a try.

I made the changes you suggested and still had node and link overlap. In fact I already made all possible variations and combinations of layout and link properties. The following picture is the result of your suggestion

My original parameters for the first diagram picture were:
TreeStyle="Layered" , Alignment="Bus"
LayerSpacing="80" , NodeSpacing="120"
Which produced a better tree.
I am interested in the last statement of your reply talking about
"some programming to make sure the curve avoids crossing over any nodes"
Kindly assist me in How would I do that. What is the nearest Sample that gives me a base to start with?
Also, if I implement Groups, would the Groups and links overlap in the same way, or they would not intersect? What is the closest Example that would give me a base to implement Grouping?
Finally, does the linking sequence affects where nodes and links are placed in the tree? If so, I would resort to re-writing my linking process to sequence the links in a way that I have to infer from the first diagram picture - I mean who to link first and who to link last.
Thanks.

I suggested using Links that were Orthogonal and had a large Corner.

I also suggested using TreeStyle=“LastParents” so that you could specify different spacing values for the main tree and for the subtrees holding only leaf nodes. (Those are green in your screenshot – I assume you are using a different Node DataTemplate for them, just as you are using a different Link DataTemplate for the thin green links connecting to those leaf nodes.)

If you use TreeStyle=“LastParents”, the “Alternate…” properties control the tree layout for those “last parent” nodes with the green links coming out of them. For example, I believe setting AlternateRowSpacing=“20” or something smaller than the regular RowSpacing would be appropriate.

Anyway, my main point was using a different Link DataTemplate to reduce the node crossings.

Customizing the link routing is more complicated – it would be wise to try the simpler, easier things first.

My link properties are bined to sliders in the user interface. I did actually change the link to Orthogonal with a corner value of 200 interactively thru the sliders. And yes, I have three Link Templates with their properties bined to UI. I did also change tree style to last parents and added row spacing.

In order to make sure I followed your suggestion, I will remove bindings from the link templates and hard code their properties as you stated. This will take sometime as I have three rich Link templates.
I have not previously used Row Spacing, but after your explanation about the Alternate values, I will keep them after some experimentation.
Thanks.

I actually have five link templates. I changed them all based on your suggestion. Now their routing is

<go:Link.Route >
<go:Route RelinkableTo="True" RelinkableFrom="True" Routing="Orthogonal" Corner="200" />
</go:Link.Route>
And Diagram Layout is
<go:Diagram.Layout>
<golayout:TreeLayout x:Name="WVlayouter" TreeStyle="LastParents"
Alignment="Bus" AlternateAlignment="Bus"
Angle="270" AlternateAngle="270"
LayerSpacing="100" AlternateLayerSpacing="100"
NodeSpacing="100" AlternateNodeSpacing="100"
RowSpacing="200" AlternateRowSpacing="20" />
</go:Diagram.Layout>
The result is in following picture:
I am thinking of the LayeredDiagraphLayout. Since it has a ColumnSpacing property that I can adjust. Would it give me desired result - not forgetting the natural-tree-like appearance I am targetting?
Thanks.

I don’t understand how those links could be Orthogonal, since they clearly have sloping segments.

This is the xaml for one of the links and others are similar. I don’t think that the link template components have an effect on the Routing. But I include this xaml for your review in case.

<DataTemplate x:Key="LeafBranchLink" ><?: prefix = o ns = "urn:schemas-microsoft-com:office:office" />

<go:LinkPanel go:Part.SelectionElementName="Path1" go:Part.SelectionAdorned="True" go:Part.Reshapable="True" >

<go:Link.Route>

<go:Route RelinkableTo="True" RelinkableFrom="True" Routing="Orthogonal" Corner="200" />

</go:Link.Route>

<Path Name="Path1" go:LinkPanel.IsLinkShape="True"

Stroke="{Binding ElementName=ChildLinkColorComboBox, Path=SelectedIndex, Mode=TwoWay, Converter={StaticResource SBCC}}"

StrokeThickness="{Binding ElementName=LeafThicknessSlider, Path=Value, Mode=TwoWay}" Stretch="None" />

<Path x:Name="Icon1"

Data="m …. z"

Width="25" Height="16" StrokeThickness="1" Stretch="Fill" go:LinkPanel.Index="-1" go:LinkPanel.Offset="-25 0"

Fill="YellowGreen" Stroke="Green"

Visibility="{Binding ElementName=ChildLinkDecorCheckBox, Path=IsChecked, Mode=OneWay, Converter={StaticResource Bool2Vis}}" >

<Path.RenderTransform>

<TransformGroup>

<RotateTransform Angle="35" CenterX="10" CenterY="0" />

<TranslateTransform X="-8" Y="0" />

</TransformGroup>

</Path.RenderTransform>

</Path>

<Path x:Name="Icon2"

Data="m … z"

Width="25" Height="16" StrokeThickness="1" Stretch="Fill" go:LinkPanel.Index="0" go:LinkPanel.Offset="20 0"

Fill="LimeGreen" Stroke="Green"

Visibility="{Binding ElementName=ChildLinkDecorCheckBox, Path=IsChecked, Mode=OneWay, Converter={StaticResource Bool2Vis}}" >

<Path.RenderTransform>

<TransformGroup>

<RotateTransform Angle="145" CenterX="10" CenterY="0" />

<TranslateTransform X="23" Y="0" />

</TransformGroup>

</Path.RenderTransform>

</Path>

<Path x:Name="Icon3"

Data="m …. z"

Width="25" Height="25" StrokeThickness="1" Stretch="Fill" go:LinkPanel.Index="-1" go:LinkPanel.Offset="-35 -2" Stroke="#FFF866B5"

Visibility="{Binding ElementName=ChildLinkDecorCheckBox, Path=IsChecked, Mode=OneWay, Converter={StaticResource Bool2Vis}}" >

<Path.Fill>

<RadialGradientBrush>

<GradientStop Color="#FFFC51AD" Offset="0.388" />

<GradientStop Color="#FFFFFF83" Offset="0.433" />

</RadialGradientBrush>

</Path.Fill>

</Path>

<Path x:Name="Icon4"

Data="m …. z"

Width="25" Height="25" StrokeThickness="1" Stretch="Fill" go:LinkPanel.Index="0" go:LinkPanel.Offset="40 0" Stroke="#FFD86FB0"

Visibility="{Binding ElementName=ChildLinkDecorCheckBox, Path=IsChecked, Mode=OneWay, Converter={StaticResource Bool2Vis}}" >

<Path.Fill>

<RadialGradientBrush>

<GradientStop Color="#FFFCC5FC" Offset="0.403" />

<GradientStop Color="#FFDB57AA" Offset="0.373" />

</RadialGradientBrush>

</Path.Fill>

</Path>

<ToolTipService.ToolTip >

<ToolTip Content="{Binding Path=Data.ToolTip}" HorizontalOffset="5" VerticalOffset="5" FontSize="12" FontWeight="Bold" ></ToolTip>

</ToolTipService.ToolTip>

</go:LinkPanel>

</DataTemplate>

note: I removed the Path binary definition data between m and z.

What are you suggesting?

That looks fine – what I expected. But I cannot reconcile that XAML with the thin green curved links I see in your last screenshot. When I use:
go:Link.Route
<go:Route Routing=“Orthogonal” Corner=“200” />
</go:Link.Route>
the segments of the link shape Path are actually orthgonal.

Actually, I wonder if you can get the results you want with your original app (for the first screenshot) just by shifting the lower children farther away from the vertical spine of the tree.

You could do that by overriding the TreeLayout.ComputeBusNodeSpacing method. For vertexes corresponding to the bottom children (the first and second ones), return a large value. For the 3rd and 4th vertexes, return a somewhat smaller value. Etc, until it returns a small value (20?) for the last two vertexes. You can look to see where a TreeVertex is in its parent’s TreeVertex.Children array.

This might be something that has an effect. In order to achieve my goal, I have the top most structure of the node template as a SpotPanel with the following

Green nodes (tree leaf) have these properties set:
go:Node.FromSpot="RightSide" go:Node.ToSpot="LeftSide"
while Brown nodes (those nodes that have other nodes i.e. parents) have these properties set:
go:Node.FromSpot="TopSide" go:Node.ToSpot="BottomSide"
And for both I also have this set
go:Node.LocationSpot="Center"
My nodes template' SpotPanel and NodePanel properties are not very optimized, but I think they do the purpose. I have a NodePanel inside a SpotPanel, I don't know if this is optimal or not.
Regarding TreeLayout.ComputeBusNodeSpacing method modifications, I am not sure I would get into that. I am not sure if I am capable of doing it. If you think it would be achievable with your assistance, I would.
I might spend sometime experimenting with Grouping which I think may provide a better appearance since they have their own layout and alignment. And I am afraid that eventually I would face the same overlapping issue.
Regards and thanks for your time.