link curviness

hello ,

i need to set my curviness propert on linktemplate to 90 in order to break the line closer to the right node so far so good. but when the curviness property is not set to 0 the line (link)
between to two nodes does not get shorter if i bring thom closer , instead it keeps its length and curves back . im adding a picture for you to understand what im saying .

note how the green link between the upper left to nodes (the red and the orange) in your sample goes back instead of getting shorter . now maby this was the intention , but i realy need help making the link not do that behavior on curviness not set to 0 , because it makes my diagram look messy when it comes to larger diagram with a lot of links and nodes (plus some people bug me about it hard…)
thanks ,


The default value for Route.Curviness is NaN, not zero. This allows the route computation to figure out the distance, which is normally mid-way between the two endpoints.

Specifying a number will always cause the break to happen at that distance.

But if your links are Orthogonal you could override Route.GetMidOrthoPosition to figure out what value you want to use. Here’s the default definition:

protected virtual double GetMidOrthoPosition(double fromPosition, double toPosition, bool vertical) { if (HasCurviness()) { double c = ComputeCurviness(); return (fromPosition + toPosition)/2 + c; } return (fromPosition + toPosition)/2; }
You could instead override Route.ComputeCurviness if you preferred.

but if you look at the sample , when you set curviness to 0 (not nan) it shortens the link perfectly when you bring them closer !

not sure i get how to override GetMidOrthoPosition to get what i need , i dont think i should change how it gets the mid position am i ? how will it help ?
im not sure what computecurviness does , and what to change in it also , it seems a bit complicated to interfere with
ComputeCurviness without making something else not work , any suggestions where to start , for making the link shorter when the nodes are closed even if curviness has a value of 90 ?


Trying to be clear about one thing , i dont need the line to break in the middle thats why im changing the curviness property , but i the behavior i need is for the line to get shorter so it will not start to circle it self when the nodes are brought closer

i wating for your reply on the former topic called
link curviness, just need to know you noticed im asking some more questions there .

As you may have heard, we have been busy releasing new versions of our products to accompany the release of Visual Studio 2012. We still aren’t quite done with that process.

Most of our messages come by e-mail rather than this forum, and we have been very busy answering those too.

The purpose of Route.GetMidOrthoPosition is to determine the point at which the standard orthogonal link turns between two ports. Isn’t that exactly what you want to control? This gives you more control by allowing you to decide what value to use instead of depending on a fixed property like Route.Curviness.

Sorry, i dont get it, to my understanding you enable me to control the middle position by code. but i already do that from the xaml with curviness property , this is already achieved and not what i need.

changing the middle point by code , or using ComputePoints to return the middle point is not helping me , it is not making the link stop circling it self when i bring the two nodes closer to each other.

what i need is the link stop circling it self when i bring the nodes closer to each other and do the same thing that it does (try it) when the curviness equals 0 , which is - the link gets shorter while maintainig the same middle point (when curviness is 0 it is right in the middle ,but i dont want it in the middle so i set the curviness to 90 and hoping to see the line gets shorter from the left side of the middle point but it just stays there and does not get any shorter ).
so i need the line to get shorter on whatever middle point (curviness , whatever) i may set by the curviness property , or by code in GetOrthoMidPoint() .

you see if i set curviness to 0 the green line between red and orange gets very short when the nodes are close :

while it does not get short here when curviness is 90 :

Realy hope you can help , and thank you


Another emphasis about my last reply - note i’ve deleted curviness property from xaml so it should be NaN,and im doing this in Route.cs :

protected virtual double GetMidOrthoPosition(double fromPosition, double toPosition, bool vertical)
return (fromPosition + toPosition) / 2 + 90;

and still ,changing only the middle point by code and avoid using curviness has not worked. the line circles it self.

If you are setting Curviness=“90”, then as you can see in the code I listed above, the bend is going to be 90 units away from the middle, no matter where the nodes are.

If you want it to be smarter about deciding where to turn, you cannot use a constant value. That’s why you should override the method to return the value that you want depending on the circumstances.

Re your last post: yes, exactly – that shows you how the “90” value affects the turning point.

So how can i calculate the middle point while the nodes are getting closer ? do i have info about the length of the line or distance between nodes inside route.cs that i cac use so can i determine that the nodes are getting closer so i can lower the mid point ?
does this chunck of code thats already in the computecurviness is doing that ?

Link link = this.Link;
int bundleindex = link.BundleIndex;
if (bundleindex != 0)
LinkBundle bundle = link.Bundle;
double spacing = (bundle != null ? bundle.Spacing : 10);
int i = Math.Abs(bundleindex);
c = spacing / 2 + (i - 1) / 2 * spacing; // i.e. +/- 5/15/25/etc from center
if (i % 2 == 0) c = -c; // alternate sides
if (bundleindex < 0) c = -c; // other direction
i realy dont understand this code , what is bundleindex , link.bundle?
how deep will i need to investigate to understand how to override this function ?

This returns the midpoint:

return (fromPosition + toPosition) / 2;

This calculates the distance between them:

Math.Abs(fromPosition - toPosition)

You also can examine the ports (or Nodes) that the Link connects by looking at the Route.Link’s properties.

thank you for your answer , i succeeded in this taks !

however ,and this problem is even before my change, im finding it difficult to understand why the line suddenly breaks on several places (and not
in one place like i managed to do with your help) , if i change the linktemplate in runtime .

see , i need to show the diagram with different template (colors , behavior) sometimes , and that is y i need the template to swich on a user command .

i managed to realise that the template changing itself forces a complete re-calculation in the Route class. i also noticed that the line starts breaking in odd places when it crosses one another it breaks like in two places instead of one and not on the point returned from the
GetMidOrthoPosition function .
i figured it has to do with ComputeCurviness function that is called independently throghout the route.cs code so i’ve overriden it as follows:

protected virtual double ComputeCurviness()
return MiddleOrthogonalPoint;

while MiddleOrthogonalPoint is a new class property which is the result of my new calculations in
GetMidOrthoPosition as follows :

protected virtual double GetMidOrthoPosition(double fromPosition, double toPosition, bool vertical)
double routeLength = Math.Abs(fromPosition - toPosition);
MiddleOrthogonalPoint =(fromPosition + toPosition) / 2 + (routeLength * 0.4);
return MiddleOrthogonalPoint;
private double MiddleOrthogonalPoint {get;set;}

still no luck , a linktemplate change messes my links mid point and draws the link differently.
route.cs is very complicated and full of algorithms which some of the code is only calculated on some conditions , lots of if else that preety much makes me mixed up about the purpose of a function. any way you can direct me to the cause of this link behavior ?

thank you ,

As you say, link routing can be rather complicated. If you could be more specific about exactly the cases you care about and what conditions they are in, perhaps I could give you a specific answer.

in this code i change the template to show a different visual on a print preview i made :

private void LoadDiagramForPrint()
DiagramForPrint.Model = this.Diagram.Model;
DiagramForPrint.IsReadOnly = true;

        DataTemplateDictionary printingNodeTemplateDictionary = FindResource("PrintNodeTemplates") as DataTemplateDictionary;
        DiagramForPrint.NodeTemplateDictionary = printingNodeTemplateDictionary ?? this.Diagram.NodeTemplateDictionary;

        DataTemplate printingLinkTemplate = FindResource("PrintLinkTemplate") as DataTemplate;
        DiagramForPrint.LinkTemplate = printingLinkTemplate ?? this.Diagram.LinkTemplate;

        DataTemplate printingParentEntityTemplate = FindResource("PrintParentEntityView") as DataTemplate;
        DiagramForPrint.GroupTemplate = printingParentEntityTemplate ?? this.Diagram.GroupTemplate;

        if (IsPoligon && PrintAreaNode != null)
            PrintAreaNode.ContentTemplate = FindResource("PrintPreviewPoligonTemplate") as DataTemplate;
            DiagramForPrint.PartsModel = new Northwoods.GoXam.Model.PartsModel();
            DiagramForPrint.PartsModel.SkipsUndoManager = true;
            PrintAreaNode.DataContext = this.DataContext;
            PrintAreaNode.Move(PrintAreaNodeLocation, false);

this line of code inside the function :
DataTemplate printingLinkTemplate = FindResource(“PrintLinkTemplate”) as DataTemplate;

goes to the Route.cs constructor

call stack shows the origin is from here :

OnModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

and the function diagram.Rebuild();

that runs inside it .

if i want to disable the rebuild all the links disappear .

i’ve added a picture that shows the link middle point and shape change ,
just because i’ve changed the template of the link:

thanks ,


Instead of replacing the Link’s DataTemplate it might be easier to change the bindings or styles. That way you would not need to worry about the recomputation of the link route.

not working with DataTemplates will require full refactoring of my code , because not only the linktemplate is changed but also the node template , DiagramForPrint is a different diagram :

        <go:Diagram x:Name="DiagramForPrint"

without defining its linktemplate , a default link template will be selected , which has different properties and layout.

i ment to say that the RaiseTemplatesChanged is running when the

DiagramForPrint.LinkTemplate = printingLinkTemplate ?? this.Diagram.LinkTemplate; 

or the

DiagramForPrint.GroupTemplate = printingParentEntityTemplate ?? this.Diagram.GroupTemplate;

is running , and the

OnModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 

runs when this runs :

DiagramForPrint.Model = this.Diagram.Model;

i don’t know what messes the link though

Are you using the Route class for both (or all) Link DataTemplates?
If so I do not know why you wouldn’t get the same result with either template.

If you are expecting transient (i.e. FrameworkElement) state to be copied to the new template, you’ll need to save that in the model data. If that transient state is the route (i.e. the sequence of Points), you can do what some of the sample apps do to save and restore the Route.Points to/from a link data property.

which sample
apps does this saving ?