• 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

61.67
/src/algorithms/utils/graphConverter.ts
1
/**
2
 * @file Utility for converting graphty-element Graph to @graphty/algorithms Graph format
3
 */
4

5
import {Graph as AlgorithmGraph} from "@graphty/algorithms";
15✔
6

7
import type {Graph} from "../../Graph";
8

9
/**
10
 * Options for graph conversion
11
 */
12
export interface GraphConverterOptions {
13
    /** Whether to treat the graph as directed (default: false for undirected) */
14
    directed?: boolean;
15
    /** Weight attribute name on edges (default: "value") */
16
    weightAttribute?: string;
17
    /** Whether to allow parallel edges (default: true to handle real-world datasets) */
18
    allowParallelEdges?: boolean;
19
    /**
20
     * Whether to add reverse edges for bidirectional traversal in undirected mode.
21
     * When true (default), creates a directed graph internally with edges in both directions.
22
     * When false, creates a truly undirected graph (required for MST algorithms).
23
     * Only applies when directed=false.
24
     */
25
    addReverseEdges?: boolean;
26
}
27

28
/**
29
 * Convert a graphty-element Graph to @graphty/algorithms Graph format
30
 * @param g - The graphty-element Graph instance
31
 * @param options - Conversion options
32
 * @returns A new AlgorithmGraph instance
33
 */
34
export function toAlgorithmGraph(g: Graph, options: GraphConverterOptions = {}): AlgorithmGraph {
15✔
35
    const {directed = false, weightAttribute = "value", allowParallelEdges = true, addReverseEdges = true} = options;
125✔
36

37
    // Determine the actual directedness of the created graph:
38
    // - If directed=true, create a directed graph (no reverse edges needed)
39
    // - If directed=false and addReverseEdges=true (default), create a directed graph internally
40
    //   with edges in both directions for algorithms that need bidirectional traversal
41
    // - If directed=false and addReverseEdges=false, create a truly undirected graph
42
    //   (required for MST algorithms like kruskal/prim)
43
    const useDirectedInternally = directed || addReverseEdges;
125✔
44
    const graph = new AlgorithmGraph({directed: useDirectedInternally, allowParallelEdges});
125✔
45

46
    // Add all nodes
47
    for (const node of g.getDataManager().nodes.values()) {
125✔
48
        graph.addNode(node.id);
3,839✔
49
    }
3,839✔
50

51
    // Add all edges with weights
52
    for (const edge of g.getDataManager().edges.values()) {
125✔
53
        // Get weight from edge data (weightAttribute already defaults to "value")
54
        // edge.data might be undefined in mock graphs used during testing
55
        // First try edge.data[weightAttribute], then fall back to edge[weightAttribute]
56
        const edgeData = edge.data as Record<string, unknown> | undefined;
9,712✔
57
        const edgeObject = edge as unknown as Record<string, unknown>;
9,712✔
58
        let rawWeight = edgeData?.[weightAttribute];
9,712!
59

60
        if (rawWeight === undefined) {
9,712!
61
            rawWeight = edgeObject[weightAttribute];
8,784✔
62
        }
8,784✔
63

64
        const weight: number = typeof rawWeight === "number" ? rawWeight : 1;
9,712!
65

66
        graph.addEdge(edge.srcId, edge.dstId, weight);
9,712✔
67

68
        // For undirected graphs with reverse edges enabled, add reverse edge as well
69
        // This ensures algorithms like bellmanFord work correctly in both directions
70
        if (!directed && addReverseEdges) {
9,712✔
71
            graph.addEdge(edge.dstId, edge.srcId, weight);
7,480✔
72
        }
7,480✔
73
    }
9,712✔
74

75
    return graph;
125✔
76
}
125✔
77

78
/**
79
 * Convert a graphty-element Graph to adjacency map format
80
 * Used by algorithms like labelPropagation and leiden that expect Map<string, Map<string, number>>
81
 * @param g - The graphty-element Graph instance
82
 * @param options - Conversion options
83
 * @returns An adjacency map where outer map keys are node IDs, inner maps are neighbor -> weight
84
 */
85
export function toAdjacencyMap(g: Graph, options: GraphConverterOptions = {}): Map<string, Map<string, number>> {
15✔
86
    const {weightAttribute = "value"} = options;
×
87

88
    const adjacencyMap = new Map<string, Map<string, number>>();
×
89

90
    // Initialize all nodes with empty neighbor maps
91
    for (const node of g.getDataManager().nodes.values()) {
×
92
        adjacencyMap.set(String(node.id), new Map<string, number>());
×
93
    }
×
94

95
    // Add edges (both directions for undirected graph)
96
    for (const edge of g.getDataManager().edges.values()) {
×
97
        const srcId = String(edge.srcId);
×
98
        const dstId = String(edge.dstId);
×
99

100
        // Get weight from edge data
101
        const edgeData = edge.data as Record<string, unknown> | undefined;
×
102
        const edgeObject = edge as unknown as Record<string, unknown>;
×
103
        let rawWeight = edgeData?.[weightAttribute];
×
104

105
        if (rawWeight === undefined) {
×
106
            rawWeight = edgeObject[weightAttribute];
×
107
        }
×
108

109
        const weight: number = typeof rawWeight === "number" ? rawWeight : 1;
×
110

111
        // Add edge in both directions (undirected)
112
        adjacencyMap.get(srcId)?.set(dstId, weight);
×
113
        adjacencyMap.get(dstId)?.set(srcId, weight);
×
114
    }
×
115

116
    return adjacencyMap;
×
117
}
×
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