code: def to_json(self):
      
      res_dict = {}
  
      def gen_dep_edge(node, edge, dep_tgt, aliases):
        return {
          'target': dep_tgt.address.spec,
          'dependency_type': self._edge_type(node.concrete_target, edge, dep_tgt),
          'products_used': len(edge.products_used),
          'products_used_ratio': self._used_ratio(dep_tgt, edge),
          'aliases': [alias.address.spec for alias in aliases],
        }
  
      for node in self._nodes.values():
        res_dict[node.concrete_target.address.spec] = {
          'cost': self._cost(node.concrete_target),
          'cost_transitive': self._trans_cost(node.concrete_target),
          'products_total': node.products_total,
          'dependencies': [gen_dep_edge(node, edge, dep_tgt, node.dep_aliases.get(dep_tgt, {}))
                           for dep_tgt, edge in node.dep_edges.items()],
        }
      yield str(json.dumps(res_dict, indent=2, sort_keys=True))
docs: Outputs the entire graph.