• 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

90.7
/src/managers/StyleManager.ts
1
import type {CalculatedValue} from "../CalculatedValue";
2
import type {AdHocData, EdgeStyleConfig, NodeStyleConfig, StyleLayerType} from "../config";
3
import {type EdgeStyleId, type NodeStyleId, Styles} from "../Styles";
3✔
4
import type {EventManager} from "./EventManager";
5
import type {Manager} from "./interfaces";
6

7
/**
8
 * Manages graph styling, wrapping the Styles class with additional caching
9
 * and event-driven updates.
10
 */
11
export class StyleManager implements Manager {
3✔
12
    private styles: Styles;
13
    private nodeStyleCache = new Map<string, NodeStyleId>();
3✔
14
    private edgeStyleCache = new Map<string, EdgeStyleId>();
3✔
15
    private cacheEnabled = true;
3✔
16

17
    constructor(
3✔
18
        private eventManager: EventManager,
599✔
19
        styles?: Styles,
599✔
20
    ) {
599✔
21
        // Initialize with provided styles or create default
22
        this.styles = styles ?? Styles.default();
599✔
23

24
        // Listen for style change events
25
        // TODO: "style-changed" is a custom event type, not in the standard EventType enum
26
        // We use the graph observable directly for now
27
        // TODO: Add proper event type when EventManager is extended
28
    }
599✔
29

30
    async init(): Promise<void> {
3✔
31
        // No async initialization needed
32
    }
510✔
33

34
    dispose(): void {
3✔
35
        this.clearCache();
469✔
36
    }
469✔
37

38
    /**
39
     * Get the underlying Styles instance
40
     */
41
    getStyles(): Styles {
3✔
42
        return this.styles;
17,819✔
43
    }
17,819✔
44

45
    /**
46
     * Get style ID for a node, with caching
47
     */
48
    getStyleForNode(data: AdHocData, algorithmResults?: AdHocData): NodeStyleId {
3✔
49
        if (!this.cacheEnabled) {
8✔
50
            return this.styles.getStyleForNode(data, algorithmResults);
2✔
51
        }
2✔
52

53
        const cacheKey = this.createCacheKey(data, algorithmResults);
6✔
54
        const cached = this.nodeStyleCache.get(cacheKey);
6✔
55
        if (cached !== undefined) {
8✔
56
            return cached;
1✔
57
        }
1✔
58

59
        const styleId = this.styles.getStyleForNode(data, algorithmResults);
5✔
60
        this.nodeStyleCache.set(cacheKey, styleId);
5✔
61
        return styleId;
5✔
62
    }
8✔
63

64
    /**
65
     * Get calculated styles for a node
66
     */
67
    getCalculatedStylesForNode(data: AdHocData): CalculatedValue[] {
3✔
68
        // No caching for calculated styles as they may change frequently
69
        return this.styles.getCalculatedStylesForNode(data);
1✔
70
    }
1✔
71

72
    /**
73
     * Get style ID for an edge, with caching
74
     */
75
    getStyleForEdge(data: AdHocData, algorithmResults?: AdHocData): EdgeStyleId {
3✔
76
        if (!this.cacheEnabled) {
3!
77
            return this.styles.getStyleForEdge(data, algorithmResults);
×
78
        }
×
79

80
        const cacheKey = this.createCacheKey(data, algorithmResults);
3✔
81
        const cached = this.edgeStyleCache.get(cacheKey);
3✔
82
        if (cached !== undefined) {
3✔
83
            return cached;
1✔
84
        }
1✔
85

86
        const styleId = this.styles.getStyleForEdge(data, algorithmResults);
2✔
87
        this.edgeStyleCache.set(cacheKey, styleId);
2✔
88
        return styleId;
2✔
89
    }
3✔
90

91
    /**
92
     * Get node style configuration by ID
93
     */
94
    static getStyleForNodeStyleId(id: NodeStyleId): NodeStyleConfig {
3✔
95
        return Styles.getStyleForNodeStyleId(id);
1✔
96
    }
1✔
97

98
    /**
99
     * Get edge style configuration by ID
100
     */
101
    static getStyleForEdgeStyleId(id: EdgeStyleId): EdgeStyleConfig {
3✔
102
        return Styles.getStyleForEdgeStyleId(id);
1✔
103
    }
1✔
104

105
    /**
106
     * Add a new style layer
107
     */
108
    addLayer(layer: StyleLayerType): void {
3✔
109
        this.styles.addLayer(layer);
45✔
110
        this.clearCache();
45✔
111
        this.eventManager.emitGraphEvent("style-changed", {});
45✔
112
    }
45✔
113

114
    /**
115
     * Insert a style layer at a specific position
116
     */
117
    insertLayer(position: number, layer: StyleLayerType): void {
3✔
118
        this.styles.insertLayer(position, layer);
1✔
119
        this.clearCache();
1✔
120
        this.eventManager.emitGraphEvent("style-changed", {});
1✔
121
    }
1✔
122

123
    /**
124
     * Remove style layers matching a metadata predicate
125
     */
126
    removeLayersByMetadata(predicate: (metadata: unknown) => boolean): void {
3✔
UNCOV
127
        const removed = this.styles.removeLayersByMetadata(predicate);
×
UNCOV
128
        if (removed) {
×
UNCOV
129
            this.clearCache();
×
UNCOV
130
            this.eventManager.emitGraphEvent("style-changed", {});
×
UNCOV
131
        }
×
UNCOV
132
    }
×
133

134
    /**
135
     * Load styles from an object
136
     */
137
    loadStylesFromObject(obj: object): void {
3✔
138
        this.styles = Styles.fromObject(obj);
327✔
139
        this.clearCache();
327✔
140
        this.eventManager.emitGraphEvent("style-changed", {});
327✔
141
    }
327✔
142

143
    /**
144
     * Load styles from a URL
145
     */
146
    async loadStylesFromUrl(url: string): Promise<void> {
3✔
147
        this.styles = await Styles.fromUrl(url);
1✔
148
        this.clearCache();
1✔
149
        this.eventManager.emitGraphEvent("style-changed", {});
1✔
150
    }
1✔
151

152
    /**
153
     * Update the styles configuration
154
     */
155
    updateStyles(newStyles: Styles): void {
3✔
156
        this.styles = newStyles;
1✔
157
        this.clearCache();
1✔
158
        this.eventManager.emitGraphEvent("style-changed", {});
1✔
159
    }
1✔
160

161
    /**
162
     * Clear the style cache
163
     */
164
    clearCache(): void {
3✔
165
        this.nodeStyleCache.clear();
846✔
166
        this.edgeStyleCache.clear();
846✔
167
    }
846✔
168

169
    /**
170
     * Enable or disable caching
171
     */
172
    setCacheEnabled(enabled: boolean): void {
3✔
173
        this.cacheEnabled = enabled;
1✔
174
        if (!enabled) {
1✔
175
            this.clearCache();
1✔
176
        }
1✔
177
    }
1✔
178

179
    /**
180
     * Create a cache key from node/edge data and algorithmResults
181
     * This is a simple implementation - could be optimized
182
     */
183
    private createCacheKey(data: AdHocData, algorithmResults?: AdHocData): string {
3✔
184
        // Use JSON stringify for now - could be optimized with a hash function
185
        if (algorithmResults) {
9!
UNCOV
186
            return JSON.stringify({data, algorithmResults});
×
UNCOV
187
        }
×
188

189
        return JSON.stringify(data);
9✔
190
    }
9✔
191
}
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