Adding new Element to diagram without redrawing/refreshing

Hello, I don’t want to refresh the whole diagram every time I add a new node to it. I’m using LayeredDigraphLayout and to avoid refreshing I thought it would be enough to set the Conditions to “None”.

    <go:Diagram.Layout>
            <go:LayeredDigraphLayout Direction="90" LayerSpacing="{Binding ChartOptions.LayerSpacing}" 
                                     ColumnSpacing="{Binding ChartOptions.ColumnSpacing}" Iterations="10" Conditions="None"
                                     />
        </go:Diagram.Layout>

It worked fine when I copy/paste an Element. The new pasted Element is added to the Diagram and the refreshing won’t be carried out.
But when I try to add an Element to the Diagram (I have a button that adds Elements to the Diagram) using:

 networkDiagram.StartTransaction("Adding new Element");
 networkDiagram.Model.AddNode(myNode);
 networkDiagram.CommitTransaction("Added new Element");

The diagram won’t be refreshed (that’s ok).
It adds the new node to the networkDiagram, but the new node WON’T be added to the Diagram(Chart), the new node cannot be seen in the Diagram although it has been added to the networkDiagram.
Has that something to do with the LayeredDigraphLayout --> Conditions that I set?

LoadFromXML method will be called and its input xmlContainer is the transformed object to XML (where the new node was correctly added)

  public void LoadFromXML(XContainer xmlContainer)
    {
        var model = networkDiagram.Model as GraphLinksModel<MyNodeData, String, String, MyLinkData>;

        try
        {
            networkDiagram.LayoutCompleted += LoadLinkRoutes;
            networkDiagram.PartManager.UpdatesRouteDataPoints = false;
            model.Load<MyNodeData, MyLinkData>(xmlContainer, "MyNodeData", "MyLinkData");
            model.Modifiable = true;
            model.HasUndoManager = true;
            model.Changed += DiagramModelChangedHandler;
            
            networkDiagram.Model = model;
        }
        catch (Exception e)
        {
            log.Warn("Loading of XML Failed", e);
        }
       
    }

If I don’t set any Conditions to the LayeredDigraphLayout, the Diagram (Chart) will be refreshed and the new node will be added to the Chart, the new node can be seen in the diagram. But I don’t want to refresh the whole Diagram every time i add a new node because all the changes done by the user will be gone. Is there any way to do that?
Thanks

You could try temporarily setting DiagramLayout.Conditions to “InitialOnly” when you add nodes programmatically but do not want the layout to be invalidated.

But I’m not sure if doing so wouldn’t invalidate the layout anyway. If that’s the case, then afterwards you need to explicitly set DiagramLayout.ValidLayout to true.

Thank you so much for the quick reply.
But I think the DiagramLayout.Conditions= “None” works fine (with “InitialOnly” I got the same effect) since the diagram does not get refreshed( it’s what I want). The problem is that the new Element (Node) that I want to add it’s not displayed in the diagram at all. Am I missing something in the LoadFromXML method?? the model.Load method should work fine since the xmlContainer has the new added node…

Hi Walter, I just found out the problem. It turns out everything was implemented fine, the only reason why the new node wasn’t displayed at all in the diagram was that actually it was somewhere (some invisible position) displayed, but I couldn`t see it, and then I set the Position of the new node to some random position that I know:
myNode.Location = new Point(100.0, 90.0);
and I could see the new node in my diagram!!
Thanks anyway!!

Hi, I got another similar problem, but I have no idea how to solve it.

The problem now is that I want to add a new Link to the Diagram without refreshing/redrawing. The new Link is properly displayed in the Diagram, but its LABEL not, although I set the “Text” property of the MyLinkData to some name.
Since I’m using LayeredDigraphLayout with Conditions = “None” I think maybe the problem is that the label is being displayed, but in some invisible position (like it happened with the Nodes), but the thing is that I don’t know how to manually set the Position of the Label of a Link. Any ideas??

After adding the Link to the network, the method OnChartDataChanged get called:

private static void OnChartDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FameNetworkChart chart = d as FameNetworkChart;
        XContainer data = e.NewValue as XContainer;
       
        chart.networkDiagram.IsReadOnly = true;
        chart.networkDiagram.Stretch = StretchPolicy.Uniform;
        chart.networkDiagram.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
        chart.networkDiagram.VerticalAlignment = System.Windows.VerticalAlignment.Center;
        chart.networkDiagram.IsManipulationEnabled = false;

        if (data != null)
        {
            chart.LoadFromXML(data);
        }
        else
        {
            chart.networkDiagram.Model = null;
            chart.networkDiagram.UpdateLayout();
        }
    }

in data was the new Link correctly added, also with the proper Text
LoadFromXML(XContainer xmlContainer)
xmlContainer has the new added Link wiht its Label
but then when the Diagram is displayed, the label of the Link cannot be seen, it`s not displayed!!

What is your Link DataTemplate? Does it include a TextBlock with an appropriate data Binding to the “Text” property of the link data?

Yeah, it does:

  <DataTemplate x:Key="LinkTemplate">
        <go:LinkPanel go:Part.Reshapable="True" MouseDown="LinkPanel_MouseDown" go:Part.SelectionElementName="Path" go:Part.SelectionAdorned="True">
            <go:Link.Route>
                <go:Route Routing="AvoidsNodes" Curve="JumpOver" Curviness="10"
                RelinkableFrom="True" RelinkableTo="True" />
            </go:Link.Route>
            <go:LinkShape x:Name="Path" Stroke="{Binding Path=Link.ToData.Category,
                       Converter={StaticResource theLinkBrushConverter}}" StrokeDashArray="{Binding Path=Link.ToData.Category,
                       Converter={StaticResource theLinkDashConverter}}" StrokeThickness="{Binding Path=Link.ToData.Category,
                       Converter={StaticResource theLinkStrokeThicknessConverter}}" />
            <Path Stroke="{Binding Path=Link.ToData.Category,
                Converter={StaticResource theLinkBrushConverter}}" StrokeThickness="1" go:LinkPanel.ToArrow="Standard" />
            <TextBlock Text="{Binding Path=Data.Text, Mode=TwoWay}"
               TextWrapping="WrapWithOverflow" go:Part.TextEditable="True"
               go:LinkPanel.Index="-2" go:LinkPanel.Offset="-10 -30" go:LinkPanel.Orientation="None"                  
               />
        </go:LinkPanel>
    </DataTemplate>

I’m still trying to figure out what I’m missing but I have no idea, I think this time it has nothing to do with the Position of the Link Label. The label will be displayed as an empty string even though in the xmlContainer the label String of the MyLinkData has the proper name and it’s not empty.
LoadFromXML(XContainer xmlContainer)

btw I’m not adding the new Link within a Transaction…should I do that?

I don’t know what to say – your XAML looks OK to me. What else is different from those samples that display text labels on their links?

Yes, all changes should occur within a transaction. This is important not only for undo/redo, but also to ensure everything else is updated consistently.

Thanks again for quick reply! The problem got solved as soon as I added the change within a transaction. Thanks!!