# GVPR question - Select nodes, then filter a graph for all related nodes

**URL:** <https://forum.graphviz.org/t/gvpr-question-select-nodes-then-filter-a-graph-for-all-related-nodes/2314>\
**Category:** Dev\
**Created:** [July 4, 2024, 12:47pm UTC](https://forum.graphviz.org/t/gvpr-question-select-nodes-then-filter-a-graph-for-all-related-nodes/2314 "2024-07-04T12:47:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![kobia](https://avatars.discourse-cdn.com/v4/letter/k/f1d935/32.png) [@kobia](https://forum.graphviz.org/u/kobia)\
**Post date:** [July 4, 2024, 12:47pm UTC](https://forum.graphviz.org/t/gvpr-question-select-nodes-then-filter-a-graph-for-all-related-nodes/2314/1 "2024-07-04T12:47:41Z")

</div>

I am trying to create a gvpr script to get a collection of node names as parameter and returns a graph with all nodes that are directly or remotely connected to these tables.

Is there a good example for it. Tried to ask chat gpt and got a non running code 🙂

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 4, 2024, 3:22pm UTC](https://forum.graphviz.org/t/gvpr-question-select-nodes-then-filter-a-graph-for-all-related-nodes/2314/2 "2024-07-04T15:22:38Z")

</div>

Here is a similar program - only lightly tested.

- allow multiple node names
- mark all for deletion
- unmark connected nodes & edges
- do not delete until the final END\_G

```auto
/*
  given the name of a node (via the command line -a argument)
    color that node yellow
    color all descendents and connecting edges green
    color all other nodes grey
*/
BEGIN{
  node_t aNode, Start;
  graph_t aGraph, Root;
  int seenE[], seenN[];
  int Ecnt=0;
  string start;

  /////////////////////////////////////////////////////////////////////
  // the anEdge argument is a local argument, never part of calling the function
  // each call creates a new instance
  // so the nxtedge call does not over-write
  void nodeTraverse(node_t thisNode, edge_t anEdge){
    print("// NODE: ", thisNode.name, " seen: ", seenN[thisNode]);
    if (seenN[thisNode]!=1){
      seenN[thisNode]=1;
      thisNode.fillcolor="green";
      thisNode.style="filled";      
      for (anEdge = fstedge(thisNode); anEdge; anEdge = nxtedge(anEdge,thisNode)){
        print("// edge: ", anEdge.name, " ", anEdge.tail, " ", anEdge.head, " seen: ", seenE[anEdge]);
        if (seenE[anEdge]==0){
	  anEdge.color="green";
          seenE[anEdge]=1;
          print("// recurse: ", anEdge.head);
          nodeTraverse(anEdge.head, anEdge);
          nodeTraverse(anEdge.tail, anEdge);	  
        }
      }
    }
    print ("// DONE: ", thisNode.name);
  } // end of nodeTraverse
  //////////////////////////////////////////////
}
BEG_G{
  Root=$G;
  start=ARGV[0];
  print ("// start: ", start);
  Start=isNode($G, start);
  if (Start==NULL){
    printf(2, "Error: unknown node >%s<\n", start);
    exit(9);
  }
}
//
// grey out all nodes & edges
// we will color the ones we want later
//
N{
  $.style="filled";
  $.fillcolor="lightgrey";
}
E{
  $.color="lightgrey";
}
// now find all the children & color them & their edges
END_G{
  nodeTraverse(Start); // no edge parameter on this call
  print("// Start: ", Start.name,Start.color);
  Start.fillcolor="yellow";
}

```

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 8, 2024, 4:37pm UTC](https://forum.graphviz.org/t/gvpr-question-select-nodes-then-filter-a-graph-for-all-related-nodes/2314/3 "2024-07-08T16:37:53Z")

</div>

Here is a different method of achieving the goal.  
I have not tested either solution on graphs w/ clusters and expect problems there.

```auto
BEGIN{
  int i, maxN, maxSG, Node[], Delete[];
  graph_t aG, subG[] ;
}
BEG_G{
  i=0;
  maxN=0;
  while (i<ARGC) {
    Node[ARGV[i]]=1;
    print("// node: ", ARGV[i]);
    if (isNode($G, ARGV[i])==NULL)
      printf(2, "Node \"%s\" not found\n", ARGV[i]);
    i++;
  }
}
N{
  int skip;
  Delete[$]=1; // mark all for deletion, we will fix later
  if (Node[$.name]) {
    print("// BINGO: ", $.name);
    skip=0;
    for (subG[i]) {
      if (isNode(subG[i], $.name)) {
        skip=1; // already have this subgraph
      }
    }
    if (skip==0) {
      aG=compOf($G,$);
      subG[++maxSG]=aG;
      induce(aG);
    }
  }
}
END_G{
  node_t aNode;
  for (subG[i]) {
    for (aNode=fstnode(subG[i]); aNode; aNode = nxtnode_sg(subG[i], aNode)) {
      unset(Delete, aNode);
    }
  }
  for (Delete[aNode])
    delete($G, aNode);
}

```
