Slow drawing with many connections outgoing the same node

13 posts, 0 answers
  1. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 12 Feb 2015 Link to this post

    Hello,

    when I populate the graph with so many connections outgoing from a specific node, it takes so so so much time!

    Here is my graph source

    class GraphSource : GraphSourceBase<Node, Link>
            {
                List<Cluster> clusters = new List<Cluster>();
                public GraphSource()
                {
                     Cluster c1 = new Cluster("Cluster1");
                    Cluster c2 = new Cluster("Cluster2");
                    Cluster c3 = new Cluster("Cluster3");
                    Cluster c4 = new Cluster("Cluster4");
                    Cluster c5 = new Cluster("Cluster5");
                    Cluster c6 = new Cluster("Cluster6");
     
                 
                    ECU eCU1 = new ECU("ECU1");
                    ECU eCU2= new ECU("ECU2");
                    ECU eCU3 = new ECU("ECU3");
                    ECU eCU4 = new ECU("ECU4");
                    ECU eCU5 = new ECU("ECU5");
                    ECU eCU6 = new ECU("ECU6");
                    ECU eCU7 = new ECU("ECU7");
                    ECU eCU8 = new ECU("ECU8");
                    ECU eCU9 = new ECU("ECU9");
                    ECU eCU10 = new ECU("ECU10");
                    ECU eCU11 = new ECU("ECU11");
                    ECU eCU12 = new ECU("ECU12");
                    ECU eCU13 = new ECU("ECU13");
                    ECU eCU14 = new ECU("ECU14");
                    ECU eCU15 = new ECU("ECU15");
                    ECU eCU16 = new ECU("ECU16");
                    ECU eCU17 = new ECU("ECU17");
                    ECU eCU18 = new ECU("ECU18");
                    ECU eCU19 = new ECU("ECU19");
                    ECU eCU20 = new ECU("ECU20");
     
                    c1.AddECU(eCU1);
                    c1.AddECU(eCU2);
                    c1.AddECU(eCU3);
                    c1.AddECU(eCU4);
                    c1.AddECU(eCU5);
     
                    c2.AddECU(eCU1);
                    c2.AddECU(eCU6);
                    c2.AddECU(eCU7);
                    c2.AddECU(eCU8);
                    c2.AddECU(eCU9);
                    c2.AddECU(eCU10);
                    c2.AddECU(eCU11);
                    c2.AddECU(eCU12);
                    c2.AddECU(eCU13);
     
                    c3.AddECU(eCU13);
                    c3.AddECU(eCU17);
                    c3.AddECU(eCU18);
                    c3.AddECU(eCU19);
     
                    c4.AddECU(eCU11);
                    c4.AddECU(eCU12);
                    c4.AddECU(eCU13);
                    c4.AddECU(eCU14);
     
                    c5.AddECU(eCU15);
                    c5.AddECU(eCU16);
                    c5.AddECU(eCU17);
                    c5.AddECU(eCU18);
     
                    c6.AddECU(eCU19);
                    c6.AddECU(eCU20);
     
                    clusters.Add(c1);
                    clusters.Add(c2);
                    clusters.Add(c3);
                    clusters.Add(c4);
                    clusters.Add(c5);
                    clusters.Add(c6);
                }
     
     
                public void PopulateGraph()
                {
                    foreach (Cluster cluster in clusters)
                    {
     
                        Node vNode = new Node() { Width=10,Height=10};
     
                        this.AddNode(vNode);
                        foreach (ECU eCU in cluster.GetECUs())
                        {
     
                            IEnumerable<Node> res = from Node nn in this.Items where eCU.Name.Equals(nn.Content) select nn;
     
                            if (res.Count() == 0)
                            {
                                Node eNode = new Node() { Content = eCU.Name };
                                this.AddNode(eNode);
                                this.AddLink(new Link(vNode, eNode));
                            }
                            else
                            {
                                this.AddLink(new Link(vNode, res.First()));
                            }
     
                        }
                    }
     
                }
     
            }


    Thanks in advance,
    Hassan
              
  2. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 12 Feb 2015 in reply to Hassan Link to this post

    I forgot to mention that I am using default layout and AStar router.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Shawn
    Shawn avatar
    39 posts
    Member since:
    Jul 2012

    Posted 13 Feb 2015 Link to this post

    Assuming your GraphSource is directly bound to your diagram, you are basically adding each object/link one at a time instead of all at once. Try adding your data to a temporary GraphSource that is not bound to your diagram, populate it and then assign it to the diagram's GraphSource. This will force the diagram to layout everything at once and perform one set up updates instead of one each time you make a change.
  5. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 16 Feb 2015 in reply to Shawn Link to this post

    My GraphSource is not bound to the diagram. I just create GraphSource object and populate it and then assign it to the diagram's GraphSource.
  6. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 16 Feb 2015 in reply to Shawn Link to this post

    The binding of the Node properties (Visibility, Height, Width and Content) was the reason
    <Style x:Key="NodeStyle" TargetType="telerik:RadDiagramShape">
          <Setter Property="Visibility" Value="{Binding Visibility }" />
          <Setter Property="Height" Value="{Binding Height}" />
          <Setter Property="Width" Value="{Binding Width}" />
          <Setter Property="ContentTemplate">
              <Setter.Value>
                  <DataTemplate >
                      <TextBlock  Text="{Binding Content}" />
                  </DataTemplate>
              </Setter.Value>
          </Setter>
      </Style>
    But how to achieve the same results without such binding?
  7. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 16 Feb 2015 in reply to Shawn Link to this post

    But the same binding does not cause any problems when I remove the code lines adding the links to the diagram. So I think it may be related to the links not the nodes.
  8. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 16 Feb 2015 Link to this post

    Hi Hassan,

    What's the number of Connections and could you please try setting RouteConnections =  False to check whether this improves the performance ? Also, is there any change in performance if you do not set the AStarRouter ? Is it possible for you to open a new support thread with an isolated project that we can investigate ? Possible you may have hit a corner case which we are not aware of. If sending a project is not an option we can also prepare a sample that can serve as a base for our discussions here or in new support thread. 
    Thank you in advance for your cooperation. We are looking forward to your reply since performance in Diagram is with priority for us.

    Regards,
    Petar Mladenov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  9. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 16 Feb 2015 in reply to Petar Mladenov Link to this post

    Hi Petar,

    I tried to set RouteConnections to false and not to use the A* router but the performance seems to be the same as before.
    Is it possible to attach compressed files so that I can upload the project? It is 4.0 MB zip file?


    Thanks in advance,
    Hassan
  10. Shawn
    Shawn avatar
    39 posts
    Member since:
    Jul 2012

    Posted 16 Feb 2015 Link to this post

    One issue we had with the AStar implementation is there is no limit on the number of attempts to route a connection. In the Route function, there is a while loop that runs until it finds the optimal route but there are cases where it can never find it. This occurs regularly on diagrams where there is a large number of shapes and the distance between your source and target are large and/or there is a lot of other objects between the two. Containers also seem to cause problems as well.

    Because the offending function is private, we had to bring out all the code into a new router type, LocalAStarRouter and add in a property called MaxItterations which set the maximum number of times to attempt to route before giving up. We used 500 as a default. We then added in a check inside the while loop inside the Route function which checked if we had past the number of attempts and if so, return the failurePath. I don't know if I'm allowed to paste the whole routine but here is a snippet of the modification:
    public int MaxIterations { get; set; }
     
    /// <summary>
    /// Initializes a new instance of the <see cref="AStarRouter"/> class.
    /// </summary>
    /// <param name="diagram">The related diagram.</param>
    public LocalAStarRouter(IGraphInternal diagram)
    {
        if (diagram == null)
        {
            throw new ArgumentNullException("diagram");
        }
     
        this.diagram = diagram;
        this.cameFrom = new Dictionary<AStarNode, AStarNode>();
        this.orderedOpenSet = new PriorityQueue<AStarNode, double>(OrderType.Ascending);
        MaxIterations = 500;
    }

    private IList<Point> Route(Orientation startOrientation, Point startPoint, Point endPoint, Rect endWall, double gridSize)
    {
        var failurePath = new List<Point>() { startPoint, endPoint };
        var iterations = 0;
        this.cameFrom.Clear();
        this.orderedOpenSet.Clear();
     
        var startNode = this.stepGenerator.GenerateNode(startPoint);
        var endNode = this.stepGenerator.GenerateNode(endPoint);
     
        startNode.G = 0;
        startNode.H = Heuristic(startNode, endNode);
        startNode.F = startNode.G + startNode.H;
        this.orderedOpenSet.Push(startNode, startNode.F);
     
        //// If start and end are close to each other.
        if (IsInSquare(startPoint, endPoint, gridSize))
        {
            return failurePath;
        }
        try
        {
            while (true)
            {
                var node = this.orderedOpenSet.Pop();
                node.IsOpen = false;
                if (iterations > MaxIterations) //Perform check to see if we have past the max attempts
                    return failurePath;         //Return the failurePath which was already created
                iterations += 1;
                if (IsPathDivergent(node, startNode, gridSize))
                {
                    return failurePath;
                }

    The rest of the code for the router is the unmodified.

    Hope this helps,
    Shawn
  11. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 19 Feb 2015 Link to this post

    Hi,

    @Hassan
    You can submit a new support ticket in which you are able attach zip files up to 20 mb. We are looking forward to investigating this scenario.

    @Shawn
    Thanks for the sample code, it might be useful for other users. Also we appreciate your feedback for the AStarRouter and we will have it in mind when we work on future versions of RadDiagram.


    Regards,
    Petar Mladenov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  12. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 19 Feb 2015 Link to this post

    Hi All,

    @Shawn
    Thank you very much for your time and assistance. But even if I disable the AStar router, I still have the problem.


    @Petar
    I will submit a support ticket as soon as possible.

    Sincerely,
    Hassan
  13. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 23 Feb 2015 Link to this post

    Hi,

    I will post a follow up on the Hassan's performance issue in RadDiagram. It appeared that it is related to the use of ConenctionBridges. This is known one, it is already logged in our system. The good news is that it is fixed and the Q1 2015, which is right at the door, includes this fix.

    Regards,
    Petar Mladenov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  14. Hassan
    Hassan avatar
    13 posts
    Member since:
    Jan 2015

    Posted 25 Feb 2015 in reply to Petar Mladenov Link to this post

    Hi Petar,

    Thanks

    Sincerely,
    Hassan
Back to Top
UI for WPF is Visual Studio 2017 Ready