• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

graphty-org / graphty-element / 20514590651

26 Dec 2025 02:37AM UTC coverage: 70.559% (-0.3%) from 70.836%
20514590651

push

github

apowers313
ci: fix npm ci

9591 of 13363 branches covered (71.77%)

Branch coverage included in aggregate %.

25136 of 35854 relevant lines covered (70.11%)

6233.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.62
/src/algorithms/utils/communityUtils.ts
1
/**
2
 * @file Shared utilities for community detection algorithms
3
 */
4

5
import type {GraphLike} from "./graphUtils";
6

7
/**
8
 * Options for community utilities
9
 */
10
export interface CommunityOptions {
11
    /** Weight attribute name on edges (default: "value") */
12
    weightAttribute?: string;
13
}
14

15
/**
16
 * Options for degree calculation
17
 */
18
export interface DegreeOptions {
19
    /** Whether to treat the graph as directed (default: false for undirected) */
20
    directed?: boolean;
21
    /** For directed graphs, count "in", "out", or "both" edges (default: "both") */
22
    countType?: "in" | "out" | "both";
23
}
24

25
/**
26
 * Convert a community assignment map to an array of arrays.
27
 *
28
 * Takes a Map where keys are node IDs and values are community IDs,
29
 * and returns an array where each element is an array of node IDs in that community.
30
 * @param communities - Map of node ID to community ID
31
 * @returns Array of arrays, where each inner array contains node IDs in the same community
32
 * @example
33
 * ```typescript
34
 * const communities = new Map([["A", 0], ["B", 0], ["C", 1]]);
35
 * const result = extractCommunities(communities);
36
 * // result: [["A", "B"], ["C"]]
37
 * ```
38
 */
39
export function extractCommunities(
15✔
40
    communities: Map<number | string, number>,
5✔
41
): (number | string)[][] {
5✔
42
    const communityArrays = new Map<number, (number | string)[]>();
5✔
43

44
    for (const [nodeId, communityId] of communities) {
5✔
45
        let communityArray = communityArrays.get(communityId);
12✔
46

47
        if (communityArray === undefined) {
12✔
48
            communityArray = [];
9✔
49
            communityArrays.set(communityId, communityArray);
9✔
50
        }
9✔
51

52
        communityArray.push(nodeId);
12✔
53
    }
12✔
54

55
    return Array.from(communityArrays.values());
5✔
56
}
5✔
57

58
/**
59
 * Get the total weight of all edges in the graph.
60
 * @param graph - The graphty-element Graph instance
61
 * @param options - Configuration options
62
 * @returns Total edge weight
63
 * @example
64
 * ```typescript
65
 * const totalWeight = getTotalEdgeWeight(graph);
66
 * ```
67
 */
68
export function getTotalEdgeWeight(
15✔
69
    graph: GraphLike,
4✔
70
    options: CommunityOptions = {},
4✔
71
): number {
4✔
72
    const {weightAttribute = "value"} = options;
4✔
73
    const {edges} = graph.getDataManager();
4✔
74

75
    let totalWeight = 0;
4✔
76

77
    for (const edge of edges.values()) {
4✔
78
        const edgeData = edge.data;
5✔
79
        let rawWeight = edgeData?.[weightAttribute];
5!
80

81
        if (rawWeight === undefined) {
5✔
82
            rawWeight = edge[weightAttribute];
5✔
83
        }
5✔
84

85
        const weight: number = typeof rawWeight === "number" ? rawWeight : 1;
5✔
86
        totalWeight += weight;
5✔
87
    }
5✔
88

89
    return totalWeight;
4✔
90
}
4✔
91

92
/**
93
 * Get the degree of a specific node.
94
 *
95
 * In undirected mode (default), counts all edges incident to the node.
96
 * In directed mode, can count incoming, outgoing, or both edges.
97
 * @param graph - The graphty-element Graph instance
98
 * @param nodeId - The ID of the node
99
 * @param options - Configuration options
100
 * @returns The degree of the node
101
 * @example
102
 * ```typescript
103
 * // Undirected degree
104
 * const degree = getNodeDegree(graph, "A");
105
 *
106
 * // Directed out-degree
107
 * const outDegree = getNodeDegree(graph, "A", { directed: true, countType: "out" });
108
 * ```
109
 */
110
export function getNodeDegree(
15✔
111
    graph: GraphLike,
6✔
112
    nodeId: number | string,
6✔
113
    options: DegreeOptions = {},
6✔
114
): number {
6✔
115
    const {directed = false, countType = "both"} = options;
6✔
116
    const {edges} = graph.getDataManager();
6✔
117

118
    let degree = 0;
6✔
119
    const nodeIdStr = String(nodeId);
6✔
120

121
    for (const edge of edges.values()) {
6✔
122
        const srcIdStr = String(edge.srcId);
8✔
123
        const dstIdStr = String(edge.dstId);
8✔
124

125
        if (directed) {
8✔
126
            if (countType === "out" && srcIdStr === nodeIdStr) {
4✔
127
                degree++;
1✔
128
            } else if (countType === "in" && dstIdStr === nodeIdStr) {
4✔
129
                degree++;
2✔
130
            } else if (countType === "both") {
3!
131
                if (srcIdStr === nodeIdStr || dstIdStr === nodeIdStr) {
×
132
                    degree++;
×
133
                }
×
134
            }
×
135
        } else {
4✔
136
            // Undirected: count if node is either source or destination
137
            if (srcIdStr === nodeIdStr || dstIdStr === nodeIdStr) {
4✔
138
                degree++;
4✔
139
            }
4✔
140
        }
4✔
141
    }
8✔
142

143
    return degree;
6✔
144
}
6✔
145

146
/**
147
 * Count the number of unique communities in a community assignment map.
148
 * @param communities - Map of node ID to community ID
149
 * @returns Number of unique communities
150
 * @example
151
 * ```typescript
152
 * const communities = new Map([["A", 0], ["B", 0], ["C", 1]]);
153
 * const count = countUniqueCommunities(communities);
154
 * // count: 2
155
 * ```
156
 */
157
export function countUniqueCommunities(
15✔
158
    communities: Map<number | string, number>,
9✔
159
): number {
9✔
160
    const uniqueCommunities = new Set<number>();
9✔
161

162
    for (const communityId of communities.values()) {
9✔
163
        uniqueCommunities.add(communityId);
91✔
164
    }
91✔
165

166
    return uniqueCommunities.size;
9✔
167
}
9✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc