code: public Graph<String> requiresTransitiveGraph(Configuration cf,
                                                   Set<String> roots)
      {
          Deque<String> deque = new ArrayDeque<>(roots);
          Set<String> visited = new HashSet<>();
          Graph.Builder<String> builder = new Graph.Builder<>();
  
          while (deque.peek() != null) {
              String mn = deque.pop();
              if (visited.contains(mn))
                  continue;
  
              visited.add(mn);
              builder.addNode(mn);
              cf.findModule(mn).get()
                .reference().descriptor().requires().stream()
                .filter(d -> d.modifiers().contains(TRANSITIVE)
                                  || d.name().equals("java.base"))
                .map(Requires::name)
                .forEach(d -> {
                    deque.add(d);
                    builder.addEdge(mn, d);
                });
          }
  
          return builder.build().reduce();
      }
docs: Returns a Graph containing only requires transitive edges
  with transitive reduction.