Adding edges to graph throws error

Nov 7, 2012 at 1:43 PM
Edited Nov 7, 2012 at 1:44 PM

Hi there!

Let me say in the beginning: Awesome library! Exactly what I was looking for to have custom WPF controls layouted by GraphViz.

I'm trying to visually represent call relations meaning the user will be able to select methods which then will be layouted using GraphViz. This basically works so far, unfortunately I get the following error at runtime:

System.InvalidOperationException was unhandled by user code  HResult=-2146233079  Message=LayoutDirector: the RunDot method must be invoked before call to BuildGraph  Source=Graphviz4Net  StackTrace:       at Graphviz4Net.LayoutDirector.BuildGraph()       at Graphviz4Net.WPF.GraphLayout.BuildGraph()  InnerException: 

Do you have any suggestion about what could be wrong? I'm using the latest version from VCS and did not change anything in the source code.

Any help would be appreciated! ;-) Thanks in advance!

Here is what I did:

// constructor        
public ExplorationToolViewModel()
{
       _relationGraph = new Graph<Method>();
       _relationGraph.Changed += _relationGraph_Changed;

       RelationGraph = _relationGraph;
}        

// methods
private IEnumerable<Guid> MethodIds
{
    get { return _relationGraph.AllVertices.Select(m => m.Id); }
}        

public void AddMethodToGraph(Method method)
{
    // check if method is already in graph
    if (MethodIds.Any(i => i.Equals(method.Id)))
    {
        Logger.WriteToPluginPane(String.Format("Graph contains already method '{0}'", method.Name));
        return;
     }

     // add method to the graph
     _relationGraph.AddVertex(method);

     // update the call relations between drawn methods
     UpdateCallRelations(method);
}

private void UpdateCallRelations(Method newMethod)
{
     foreach (var methodVertex in _relationGraph.AllVertices)
     {
        // check if new method is called by an existing one
        if (newMethod.Callers.Contains(methodVertex))
        {
            var edge = new Edge<Method>(methodVertex, newMethod, new Arrow());
            _relationGraph.AddEdge(edge);
        }
     }
}
Coordinator
Nov 11, 2012 at 9:16 PM

Hi there,

are you using the WPF component, or directly LayoutDirector? LayoutDirector is internally used by the WPF component, and one must stick to a specific sequence of invocation of its methods. This sequence is described in its API documentation I believe.

Can you compile and run the example, does it throw any exception?

Steves

Nov 17, 2012 at 9:44 AM

Hi Steve

Thanks for your input and sorry for my long absence. I was very busy with my thesis, but things are going great! I actually managed to come around with my problem. I guess that the background process which runs the dot.exe somehow does not comply with loops that add elements to the graph. I introduced some kind of "lock" around the RaiseChanged method of the graph such that it does not recalculate the whole graph for each edge/vertice/subgraph I'm adding to it in my loop. When the element adding loop has finished, I force the graph to relayout.

Doing it like that, everything works and no more errors are thrown. On the other hand I'm also gaining some performance improvements.

I ran into some other issues for which I will create a separate discussion thread now. So feel free to give me advise there ;-)

Thanks again!

Chris

Feb 11, 2014 at 9:17 AM
Hey Biocoder

I have the same problem like you but I don’t get it how you "lock" the graph. Could you maybe send me the code snip or an example of the solution?

Thanks

Adam
Feb 14, 2014 at 10:19 AM
skadir wrote:
Hey Biocoder

I have the same problem like you but I don’t get it how you "lock" the graph. Could you maybe send me the code snip or an example of the solution?

Thanks

Adam
Hey,
I found the part you mean. Thanks for the clue.

Thanks

Adam
 public void AddVertex(TVertex vertex)
        {
            Contract.Requires(vertex != null);
            Contract.Requires(this.AllVertices.Contains(vertex) == false, "Vertex is already in the graph.");
            this.vertices.Add(vertex);
            this.RaiseChanged();
        }