Closed AlmightyLks closed 1 year ago
Hello,
I see that you're clearing both nodes and links, but still working with a _originalRootNode
, is that normal?
Also, how is everything re-inserted? Are you adding the same instances again or something else?
I am re-using the same node objects All I am doing is clearing all nodes and links off the Diagram, and re-adding and re-linking nodes via (simplified)
private void RenderNode(RepositoryNodeModel current)
{
Diagram.Nodes.Add(current);
if (current.Parent is not null)
{
var link = new LinkModel(current.Parent, current)
{
TargetMarker = LinkMarker.Arrow
};
link.SetSourcePort(current.Parent.GetPort(PortAlignment.Bottom));
link.SetTargetPort(current.GetPort(PortAlignment.Top));
Diagram.Links.Add(link);
}
}
to the diagram
Will links for example ever change? Because I don't see why you would clear everything just to re-insert the same instances, all you need to do is change the node's position (SetPosition
) if the links stay the same, they will be updated automatically
As you can see at the top right, I have a filter option
I want to be able to dynamically decide which nodes (and parent-child links) to display, based on which info was specified
It makes a bit more sense, once I also show the node-whitelist check that lies within the RenderNode function 😄
private void RenderNode(RepositoryNodeModel current)
{
if (!_whitelistedNodeIds.Contains(current.Item.Id))
return;
Diagram.Nodes.Add(current);
if (current.Parent is not null)
{
var link = new LinkModel(current.Parent, current)
{
TargetMarker = LinkMarker.Arrow
};
link.SetSourcePort(current.Parent.GetPort(PortAlignment.Bottom));
link.SetTargetPort(current.GetPort(PortAlignment.Top));
Diagram.Links.Add(link);
}
}
I deemed, that first setting up a whitelist, and then go through the normal rendering process off the original dataset, with a whitelist check, would be the easiest to go about this As opposed to fiddling with the Diagram-stored nodes and links, especially if I need to re-add nodes, which I would have to find by going through the data structure (parent-children) anyways 😄
Can you give me an idea of what CalculateNodePositions does?
https://github.com/AlmightyLks/ForkHierarchy/blob/main/ForkHierarchy.Core/Helpers/TreeBuilder.cs
Essentially what it does is going up and down through the entire parent-child hierarchy to evenly place the nodes next to each other, based on things like, how many siblings a node has and all that stuff.
It sets the NodeModel-Positions for each and every node directly + at the very end, when setting each and every node's final position, it executes an Action, passing the node, which I set to be my "RenderNode" function. Every time a Node's final position was set, it is added onto the Diagram
https://github.com/AlmightyLks/ForkHierarchy/blob/main/ForkHierarchy.Core/Helpers/TreeBuilder.cs#L60 https://github.com/AlmightyLks/ForkHierarchy/blob/main/ForkHierarchy/ViewModels/HierarchyViewModel.cs#L39
Instead of (in your node)
public double X { get => Position.X; set => Position = new Point(value, Position.Y); }
public double Y { get => Position.Y; set => Position = new Point(Position.X, value); }
Use SetPosition
.
Since you're using the same instances, the ports position isn't updated. SetPosition
updates the ports position (with the delta), which should fix your issue. Basically, your links are using the same ports, but the ports have their old positions.
Please try this and tell me if it fixes the issue
God damn! Yes that did it! Thanks very much
Great !! Maybe I should make Position
private or init-only to avoid this issue in the future.
Well, can you think of a reason to have it public-settable?
As you can see in the video below, the Diagram does not update itself, unless I make it by moving stuff around, or moving the canvas. Furthermore, the links are not updated, and they stay where they are What my Render Graph Button does is:
Getting rid of previous node and link information, and re-calcuating positions (and re-adding the nodes)
A StateHasChanged call wasn't doing the trick, so I thought manually forcing the Diagram to update itself via
Diagram.Refresh()
at the end of all rendering could do do it - it didn't. Same with going through allNode
's within the Diagram, and making them refresh themselves manuallyhttps://user-images.githubusercontent.com/54688434/209883392-e0d6b963-caef-4388-be4f-95a30a47076f.mp4