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

graphty-org / graphty-element / 20390753610

20 Dec 2025 06:53AM UTC coverage: 82.423% (-1.2%) from 83.666%
20390753610

push

github

apowers313
Merge branch 'master' of https://github.com/graphty-org/graphty-element

5162 of 6088 branches covered (84.79%)

Branch coverage included in aggregate %.

24775 of 30233 relevant lines covered (81.95%)

6480.4 hits per line

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

97.78
/src/algorithms/LeidenAlgorithm.ts
1
import {leiden} from "@graphty/algorithms";
3✔
2
import {z} from "zod/v4";
3✔
3

4
import {defineOptions, type OptionsSchema as ZodOptionsSchema, type SuggestedStylesConfig} from "../config";
3✔
5
import {Algorithm} from "./Algorithm";
3✔
6
import type {OptionsSchema} from "./types/OptionSchema";
7
import {countUniqueCommunities} from "./utils/communityUtils";
3✔
8
import {toAlgorithmGraph} from "./utils/graphConverter";
3✔
9

10
/**
11
 * Zod-based options schema for Leiden algorithm
12
 */
13
export const leidenOptionsSchema = defineOptions({
3✔
14
    resolution: {
3✔
15
        schema: z.number().min(0.1).max(5.0).default(1.0),
3✔
16
        meta: {
3✔
17
            label: "Resolution",
3✔
18
            description: "Controls community granularity",
3✔
19
            step: 0.1,
3✔
20
        },
3✔
21
    },
3✔
22
    randomSeed: {
3✔
23
        schema: z.number().int().min(0).max(2147483647).default(42),
3✔
24
        meta: {
3✔
25
            label: "Random Seed",
3✔
26
            description: "Seed for reproducible results",
3✔
27
            advanced: true,
3✔
28
        },
3✔
29
    },
3✔
30
    maxIterations: {
3✔
31
        schema: z.number().int().min(1).max(500).default(100),
3✔
32
        meta: {
3✔
33
            label: "Max Iterations",
3✔
34
            description: "Maximum refinement iterations",
3✔
35
            advanced: true,
3✔
36
        },
3✔
37
    },
3✔
38
    threshold: {
3✔
39
        schema: z.number().min(1e-10).max(0.01).default(1e-6),
3✔
40
        meta: {
3✔
41
            label: "Threshold",
3✔
42
            description: "Convergence threshold",
3✔
43
            advanced: true,
3✔
44
        },
3✔
45
    },
3✔
46
});
3✔
47

48
/**
49
 * Options for the Leiden community detection algorithm
50
 */
51
export interface LeidenOptions extends Record<string, unknown> {
52
    /** Controls community granularity */
53
    resolution: number;
54
    /** Seed for reproducible results */
55
    randomSeed: number;
56
    /** Maximum refinement iterations */
57
    maxIterations: number;
58
    /** Convergence threshold */
59
    threshold: number;
60
}
61

62
export class LeidenAlgorithm extends Algorithm<LeidenOptions> {
3✔
63
    static namespace = "graphty";
7✔
64
    static type = "leiden";
108✔
65

66
    static zodOptionsSchema: ZodOptionsSchema = leidenOptionsSchema;
108✔
67

68
    static optionsSchema: OptionsSchema = {
108✔
69
        resolution: {
108✔
70
            type: "number",
108✔
71
            default: 1.0,
108✔
72
            label: "Resolution",
108✔
73
            description: "Controls community granularity",
108✔
74
            min: 0.1,
108✔
75
            max: 5.0,
108✔
76
            step: 0.1,
108✔
77
        },
108✔
78
        randomSeed: {
108✔
79
            type: "integer",
108✔
80
            default: 42,
108✔
81
            label: "Random Seed",
108✔
82
            description: "Seed for reproducible results",
108✔
83
            min: 0,
108✔
84
            max: 2147483647,
108✔
85
            advanced: true,
108✔
86
        },
108✔
87
        maxIterations: {
108✔
88
            type: "integer",
108✔
89
            default: 100,
108✔
90
            label: "Max Iterations",
108✔
91
            description: "Maximum refinement iterations",
108✔
92
            min: 1,
108✔
93
            max: 500,
108✔
94
            advanced: true,
108✔
95
        },
108✔
96
        threshold: {
108✔
97
            type: "number",
108✔
98
            default: 1e-6,
108✔
99
            label: "Threshold",
108✔
100
            description: "Convergence threshold",
108✔
101
            min: 1e-10,
108✔
102
            max: 0.01,
108✔
103
            advanced: true,
108✔
104
        },
108✔
105
    };
108✔
106

107
    static suggestedStyles = (): SuggestedStylesConfig => ({
108✔
108
        layers: [
11✔
109
            {
11✔
110
                node: {
11✔
111
                    selector: "",
11✔
112
                    style: {
11✔
113
                        enabled: true,
11✔
114
                    },
11✔
115
                    calculatedStyle: {
11✔
116
                        inputs: ["algorithmResults.graphty.leiden.communityId"],
11✔
117
                        output: "style.texture.color",
11✔
118
                        expr: "{ return StyleHelpers.color.categorical.tolMuted(arguments[0] ?? 0) }",
11✔
119
                    },
11✔
120
                },
11✔
121
                metadata: {
11✔
122
                    name: "Leiden - Muted Colors",
11✔
123
                    description: "7 subdued professional community colors",
11✔
124
                },
11✔
125
            },
11✔
126
        ],
11✔
127
        description: "Visualizes communities detected via Leiden algorithm (improved Louvain)",
11✔
128
        category: "grouping",
11✔
129
    });
11✔
130

131
    // eslint-disable-next-line @typescript-eslint/require-await
132
    async run(): Promise<void> {
7✔
133
        const g = this.graph;
3✔
134
        const nodes = Array.from(g.getDataManager().nodes.keys());
3✔
135

136
        if (nodes.length === 0) {
3!
137
            return;
×
138
        }
×
139

140
        // Get options from schema
141
        const {resolution, maxIterations, threshold} = this.schemaOptions;
3✔
142

143
        // Convert to @graphty/algorithms Graph format (undirected for community detection)
144
        const graphData = toAlgorithmGraph(g, {addReverseEdges: false});
3✔
145

146
        // Run Leiden algorithm - returns {communities: Map<string, number>, modularity, iterations}
147
        const result = leiden(graphData, {
3✔
148
            resolution,
3✔
149
            maxIterations,
3✔
150
            threshold,
3✔
151
        });
3✔
152

153
        // Store results on nodes
154
        for (const nodeId of nodes) {
3✔
155
            const communityId = result.communities.get(String(nodeId)) ?? 0;
43✔
156
            this.addNodeResult(nodeId, "communityId", communityId);
43✔
157
        }
43✔
158

159
        // Store graph-level results
160
        this.addGraphResult("modularity", result.modularity);
3✔
161
        this.addGraphResult("communityCount", countUniqueCommunities(result.communities));
3✔
162
        this.addGraphResult("iterations", result.iterations);
3✔
163
    }
3✔
164
}
7✔
165

166
// Auto-register this algorithm when the module is imported
167
Algorithm.register(LeidenAlgorithm);
3✔
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