def group_people_js(request, mode="egograph", output="full"):
    """Return Belfast Group network graph data as JSON, for use with
    :meth:`group_people`.

    Optionally filter
    the data by minimum degree, if min_degree is specified as a url parameter.
    When generating the node and link data, nodes are annotated with
    degree, in degree, out degree, betweenness centrality, and eigenvector
    centrality if available.  (In/out degree is only available for directed
    graphs.)

    :param mode: egograph: network information for a one- or two-degree
        egograph centered around the Belfast Group; groupsheet-model:
        alternate network graph based on the Group sheets themselves
    :param output: full: node and link data; adjacency: adjacency matrix,
        used for generating chord diagram
    """

    if mode == "egograph":
        degree = request.GET.get("degree", 1)
        extra_opts = {}
        try:
            degree = int(degree)
            # currently only support 1 or 2 degree
            degree = max(1, min(degree, 2))
            # NOTE: degree 2 graph is large enough that it *must* be filtered
            # to be sensible and usable on the webpage;
            # by trial & error, I found a minimum degree of 5 to be reasonable
            if degree == 2:
                extra_opts["min_degree"] = 5
        except ValueError:
            # if a value is passed that can't be converted to int, fallback to 1
            degree = 1

        belfast_group = RdfOrganization(network_data().copy(), BELFAST_GROUP_URI)
        graph = belfast_group.ego_graph(radius=degree, types=["Person", "Organization"], **extra_opts)

        # annotate nodes in graph with degree
        # FIXME: not a directional graph; in/out degree not available
        graph = annotate_graph(
            graph, fields=["degree", "in_degree", "out_degree", "betweenness_centrality", "eigenvector_centrality"]
        )

    elif mode == "groupsheet-model":
        graph = gexf.read_gexf(settings.GEXF_DATA["bg1"])
        graph = annotate_graph(
            graph, fields=["degree", "betweenness_centrality", "eigenvector_centrality"]  #'in_degree', 'out_degree',
        )

    if output == "full":
        data = json_graph.node_link_data(graph)
    if output == "adjacency":
        # adjacency matrix for generating chord diagram
        matrix = nx.convert_matrix.to_numpy_matrix(graph)

        # NOTE: this also works, but as of networx 1.9 requires scipy
        # matrix = nx.linalg.graphmatrix.adjacency_matrix(graph)
        data = matrix.tolist()

    return HttpResponse(json.dumps(data), content_type="application/json")
def egograph_js(request, id):
    "Egograph information as JSON for a single person."
    uri = local_uri(reverse("people:profile", args=[id]), request)
    g = rdf_data()
    person = RdfPerson(g, rdflib.URIRef(uri))
    graph = person.ego_graph(radius=1, types=["Person", "Organization", "Place"])
    # annotate nodes in graph with degree
    #  NOTE: not a directional graph, so in/out degree not available

    graph = annotate_graph(
        graph, fields=["degree", "in_degree", "out_degree", "betweenness_centrality", "eigenvector_centrality"]
    )

    data = json_graph.node_link_data(graph)
    return HttpResponse(json.dumps(data), content_type="application/json")
def full_js(request, mode):
    """Return full network graph data as JSON.  Optionally filter
    the data by minimum degree, if min_degree is specified as a url parameter.
    When generating the node and link data, nodes are annotated with
    degree, in degree, out degree, betweenness centrality, and eigenvector
    centrality if available.  (In/out degree is only available for directed
    graphs.)


    :param mode: full - node and link data; adjacency - adjacency matrix,
        used to construct a chord diagram

    .. deprecated:: 1.0

       This network graph is too large to be usable or viewable in a
       browser/javascript display environment, and should not be used;
       :meth:`group_people` should be used instead.
    """

    # optionally filter by minimum degree
    min_degree = request.GET.get("min_degree", None)
    filter = {}
    if min_degree:
        filter["min_degree"] = int(min_degree)

    graph = _network_graph(**filter)
    if mode == "full":
        graph = annotate_graph(
            graph, fields=["degree", "in_degree", "out_degree", "betweenness_centrality", "eigenvector_centrality"]
        )
        # standard nodes & links data
        data = json_graph.node_link_data(graph)

    if mode == "adjacency":
        # adjacency matrix for generating chord diagram
        matrix = nx.linalg.graphmatrix.adjacency_matrix(graph)
        data = matrix.tolist()
    return HttpResponse(json.dumps(data), content_type="application/json")