Redraw Issue with Diagram

I'm having a problem clearing and redrawing a diagram. When I first setup the diagram, it is using auto-layout to render an Org Chart from Left-to-Right

        protected DiagramLayout LayoutValue = new DiagramLayout()
        {
            Type = LayoutType.OrganizationalChart,
            VerticalSpacing = 50,
            HorizontalSpacing = 25,
            EnableAnimation = true,
            Orientation = LayoutOrientation.LeftToRight,
            LayoutInfo = new TreeInfo()
            {
                CanEnableSubTree = true
                //Orientation = SubTreeOrientation.Vertical
            }
        };

Here is the markup:
    <SfDiagram @ref="Diagram"
               ID="diagram"
               Height="100%"
               Nodes="@NodeCollection"
               Connectors="@ConnectorCollection"
               NodeDefaults="@NodeDefaults"
               ConnectorDefaults="@ConnectorDefaults"
               Constraints="@DiagramConstraints"
               SelectedItems="@SelectedItems"
               Tool="@Tool" 
               Layout="@LayoutValue">
        <DiagramSnapSettings Constraints="@SnapConstraints.None"></DiagramSnapSettings>
        <DiagramEvents SelectionChanged="@SelectionChanged"></DiagramEvents>
    </SfDiagram>


When the diagram first loads. it looks like this (which is what I want)


However, the user can select a different element to render, which is supposed to clear the diagram and redraw it. This is done by 
  • calling await Diagram.Clear();
  • removing all the nodes from ConnectorCollection and NodeCollection
  • adding new nodes to ConnectorCollection and NodeCollection
The problem is that this results in a diagram that  renders the leaf nodes from top to bottom, instead of left to right, example here:


In order to "force" the rendering to be correct, I explicitly force the layout to be LayoutOrientation.LeftToRight again, wait for it to render, and then reapply the node orientations, as follows: 

        internal async Task Reload(LearningElement deepElement)
        {
            DeepElement = deepElement;
            await LoadData();

            // --------------------------------
            // Inexplicably necessary code 
            // (but not 100% reliable)
            // --------------------------------
            // do not delete this, or the flowchart will not render correctly.
            Diagram.Layout.Orientation = LayoutOrientation.LeftToRight;
            await Diagram.DoLayout();
            await InvokeAsync(() => StateHasChanged());
            // --------------------------------
            // Inexplicably necessary code 
            // --------------------------------            

            await SetLayoutColor();
            await InvokeAsync(() => StateHasChanged());
        }

However, this is not always reliable - sometimes the end result is what I want, but sometimes it does not render the leaf nodes from left to right. 

You can see that in this video:  https://drive.google.com/file/d/1EJIShvCBXatuTxCF1xmImchxRUlVOnXB/view?usp=sharing

Is there a way to correctly do this? 



3 Replies

AR Aravind Ravi Syncfusion Team November 11, 2020 12:43 PM UTC

Hi Joseph, 
 
In the diagram, when we call the diagram clear method we have cleared all the nodes and connectors collection. We does not need to again clear the nodes and connectors collection. After clear the nodes , again add the nodes in the existing nodes collection instead of creating new observable collection of nodes. In our side after add new nodes, nodes all add properly. We suspect that the issue occurs due to you have reset the layout settings so it takes the default orientation type of TopToBottom. So please do not reset the layout settings. 
 
In case if the issue still replicates, please share us a code snippet of after add new nodes how do you refresh the layout or simple sample replicating issue. This would help us to serve you better.  
 
Regards 
Aravind Ravi 



JT Joseph Tan November 12, 2020 02:16 AM UTC

The problem seems to be that the "defaults" do not apply until after the diagram is rendered. 

I was able to fix the redraw problem as follows:
  • Take out NodeDefaults="@NodeDefaults" and ConnectorDefaults="@ConnectorDefaults" from the SfDiagram declaration
  • Define the layout orientation and type when I add the nodes to the NodeCollection, e.g.
            if (element.ChildrenCount > 0) // leaf nodes
            {
                n.LayoutInfo.Orientation = Orientation.Vertical;
                n.LayoutInfo.Type = SubTreeAlignments.Right;
            }
            else
            {
                n.LayoutInfo.Orientation = Orientation.Horizontal;
                n.LayoutInfo.Type = SubTreeAlignments.Balanced;
            }

By doing that, the redraw is reliably producing the left-to-right behaviour for the leaf nodes. 
However, there remains a slight issue  : 

When adding nodes to the NodeCollection, there is a momentary flicker on the screen, while the nodes are added 

                foreach (var a in NodeStagingCollection)
                    NodeCollection.Add(a);



Then, when I call await Diagram.DoLayout(), the diagram "expands" into its final form.



Is there a way to prevent the flicker?

I have tried to surround the code with BeginUpdate/EndUpdate

Diagram.BeginUpdate()
    foreach (var a in NodeStagingCollection) 
                 NodeCollection.Add(a);
Diagram.EndUpdate()


But that does not help. The flicker is still there.



AR Aravind Ravi Syncfusion Team November 13, 2020 04:10 AM UTC

Hi Joseph, 
 
Currently, in the blazor, we have support to clear the nodes collection and able to add the new nodes in the existing node collection. On adding the new nodes in the diagram it gets added one by one. At the time of node added in the diagram, it gets added one by one and it looks like flickering. We do not able to restrict it, as this is the behavior of the diagram. 
 
Regards 
Aravind Ravi 


Loader.
Up arrow icon