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

graphty-org / graphty-element / 19792929756

30 Nov 2025 02:57AM UTC coverage: 86.308% (+3.9%) from 82.377%
19792929756

push

github

apowers313
docs: fix stories for chromatic

3676 of 4303 branches covered (85.43%)

Branch coverage included in aggregate %.

17 of 17 new or added lines in 2 files covered. (100.0%)

1093 existing lines in 30 files now uncovered.

17371 of 20083 relevant lines covered (86.5%)

7075.46 hits per line

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

74.85
/src/layout/NGraphLayoutEngine.ts
1
import ngraphCreateLayout, {Layout as NGraphLayout} from "ngraph.forcelayout";
2!
2
import createGraph, {Graph as NGraph, Link as NGraphLink, Node as NGraphNode} from "ngraph.graph";
2!
3
import random from "ngraph.random";
2!
4

5
import type {Edge} from "../Edge";
6
import type {Node} from "../Node";
7
import {EdgePosition, LayoutEngine, Position} from "./LayoutEngine";
2✔
8

9
export class NGraphEngine extends LayoutEngine {
2✔
10
    static type = "ngraph";
2✔
11
    static maxDimensions = 3;
2✔
12
    ngraph: NGraph;
13
    ngraphLayout: NGraphLayout<NGraph>;
14

15
    static getOptionsForDimension(dimension: 2 | 3): object {
2✔
16
        return {dim: dimension};
1,778✔
17
    }
1,778✔
18
    nodeMapping = new Map<Node, NGraphNode>();
2✔
19
    edgeMapping = new Map<Edge, NGraphLink>();
2✔
20
    _settled = true;
2✔
21
    _stepCount = 0;
2✔
22
    _lastMoves: number[] = [];
2✔
23

24
    constructor(config: object = {}) {
2✔
25
        super();
968✔
26
        this.ngraph = createGraph();
968✔
27

28
        // Cast config to a more specific type for property access
29
        const typedConfig = config as Record<string, unknown>;
968✔
30

31
        // Build ngraph configuration from provided config
32
        const ngraphConfig: Record<string, unknown> = {
968✔
33
            dimensions: typedConfig.dim !== undefined ? typedConfig.dim : 3,
968!
34
        };
968✔
35

36
        // Map from layout config to ngraph parameters
37
        if (typedConfig.springLength !== undefined) {
968!
38
            ngraphConfig.springLength = typedConfig.springLength;
×
39
        }
×
40

41
        if (typedConfig.springCoefficient !== undefined) {
968!
42
            ngraphConfig.springCoefficient = typedConfig.springCoefficient;
×
43
        }
×
44

45
        if (typedConfig.gravity !== undefined) {
968!
46
            ngraphConfig.gravity = typedConfig.gravity;
×
47
        }
×
48

49
        if (typedConfig.theta !== undefined) {
968!
50
            ngraphConfig.theta = typedConfig.theta;
×
51
        }
×
52

53
        if (typedConfig.dragCoefficient !== undefined) {
968!
54
            ngraphConfig.dragCoefficient = typedConfig.dragCoefficient;
×
55
        }
×
56

57
        if (typedConfig.timeStep !== undefined) {
968!
UNCOV
58
            ngraphConfig.timeStep = typedConfig.timeStep;
×
UNCOV
59
        }
×
60

61
        // Add random number generator with seed if provided
62
        if (typedConfig.seed !== undefined && typeof typedConfig.seed === "number") {
968✔
63
            ngraphConfig.random = random(typedConfig.seed);
69✔
64
        }
69✔
65

66
        this.ngraphLayout = ngraphCreateLayout(this.ngraph, ngraphConfig);
968✔
67
    }
968✔
68

69
    // eslint-disable-next-line @typescript-eslint/no-empty-function
70
    async init(): Promise<void> {}
2✔
71

72
    step(): void {
2✔
73
        const ngraphSettled = this.ngraphLayout.step();
2,280✔
74
        const {lastMove} = this.ngraphLayout;
2,280✔
75
        const nodeCount = this.nodeMapping.size;
2,280✔
76
        const ratio = nodeCount > 0 ? lastMove / nodeCount : 0;
2,280!
77

78
        this._stepCount++;
2,280✔
79

80
        // Keep track of last 10 moves for averaging
81
        this._lastMoves.push(ratio);
2,280✔
82
        if (this._lastMoves.length > 10) {
2,280✔
83
            this._lastMoves.shift();
1,077✔
84
        }
1,077✔
85

86
        // Calculate average movement over last 10 steps
87
        const avgMovement = this._lastMoves.length > 0 ?
2,280✔
88
            this._lastMoves.reduce((a, b) => a + b, 0) / this._lastMoves.length :
2,280!
UNCOV
89
            0;
×
90

91
        // Use a more forgiving threshold or force settling after many steps
92
        const customThreshold = 0.05; // More forgiving than ngraph's 0.01
2,280✔
93
        const maxSteps = 1000; // Force settling after 1000 steps
2,280✔
94

95
        this._settled = ngraphSettled ||
2,280✔
96
                       avgMovement <= customThreshold ||
2,237✔
97
                       this._stepCount >= maxSteps;
2,208✔
98
    }
2,280✔
99

100
    get isSettled(): boolean {
2✔
101
        return this._settled;
8,813✔
102
    }
8,813✔
103

104
    addNode(n: Node): void {
2✔
105
        const ngraphNode: NGraphNode = this.ngraph.addNode(n.id, {parentNode: n});
3,471✔
106
        this.nodeMapping.set(n, ngraphNode);
3,471✔
107
        this._settled = false;
3,471✔
108
        this._stepCount = 0;
3,471✔
109
        this._lastMoves = [];
3,471✔
110
    }
3,471✔
111

112
    addEdge(e: Edge): void {
2✔
113
        const ngraphEdge = this.ngraph.addLink(e.srcId, e.dstId, {parentEdge: this});
5,591✔
114
        this.edgeMapping.set(e, ngraphEdge);
5,591✔
115
        this._settled = false;
5,591✔
116
        this._stepCount = 0;
5,591✔
117
        this._lastMoves = [];
5,591✔
118
    }
5,591✔
119

120
    getNodePosition(n: Node): Position {
2✔
121
        const ngraphNode = this._getMappedNode(n);
41,080✔
122
        return this.ngraphLayout.getNodePosition(ngraphNode.id);
41,080✔
123
    }
41,080✔
124

125
    setNodePosition(n: Node, newPos: Position): void {
2✔
126
        const ngraphNode = this._getMappedNode(n);
×
127
        const currPos = this.ngraphLayout.getNodePosition(ngraphNode.id);
×
UNCOV
128
        currPos.x = newPos.x;
×
UNCOV
129
        currPos.y = newPos.y;
×
UNCOV
130
        currPos.z = newPos.z;
×
UNCOV
131
    }
×
132

133
    getEdgePosition(e: Edge): EdgePosition {
2✔
134
        const ngraphEdge = this._getMappedEdge(e);
69,465✔
135
        const pos = this.ngraphLayout.getLinkPosition(ngraphEdge.id);
69,465✔
136
        return {
69,465✔
137
            src: {
69,465✔
138
                x: pos.from.x,
69,465✔
139
                y: pos.from.y,
69,465✔
140
                z: pos.from.z,
69,465✔
141
            },
69,465✔
142
            dst: {
69,465✔
143
                x: pos.to.x,
69,465✔
144
                y: pos.to.y,
69,465✔
145
                z: pos.to.z,
69,465✔
146
            },
69,465✔
147
        };
69,465✔
148
    }
69,465✔
149

150
    get nodes(): Iterable<Node> {
2✔
151
        // ...is this cheating?
152
        return this.nodeMapping.keys();
2,594✔
153
    }
2,594✔
154

155
    get edges(): Iterable<Edge> {
2✔
156
        return this.edgeMapping.keys();
3,254✔
157
    }
3,254✔
158

159
    pin(n: Node): void {
2✔
UNCOV
160
        const ngraphNode = this._getMappedNode(n);
×
161
        this.ngraphLayout.pinNode(ngraphNode, true);
×
162
    }
×
163

164
    unpin(n: Node): void {
2✔
UNCOV
165
        const ngraphNode = this._getMappedNode(n);
×
UNCOV
166
        this.ngraphLayout.pinNode(ngraphNode, false);
×
UNCOV
167
    }
×
168

169
    private _getMappedNode(n: Node): NGraphNode {
2✔
170
        const ngraphNode = this.nodeMapping.get(n);
41,080✔
171
        if (!ngraphNode) {
41,080!
UNCOV
172
            throw new Error("Internal error: Node not found in NGraphEngine");
×
UNCOV
173
        }
×
174

175
        return ngraphNode;
41,080✔
176
    }
41,080✔
177

178
    private _getMappedEdge(e: Edge): NGraphLink {
2✔
179
        const ngraphNode = this.edgeMapping.get(e);
69,465✔
180
        if (!ngraphNode) {
69,465!
UNCOV
181
            throw new Error("Internal error: Edge not found in NGraphEngine");
×
UNCOV
182
        }
×
183

184
        return ngraphNode;
69,465✔
185
    }
69,465✔
186
}
2✔
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