@zenfg/inspector 0.1.0-beta.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GUIDE.md +182 -0
- package/README.md +61 -89
- package/THEMING.md +124 -0
- package/dist/FrameGraphInspector.d.ts +23 -4
- package/dist/FrameGraphInspector.d.ts.map +1 -1
- package/dist/FrameGraphInspector.js +137 -29
- package/dist/FrameGraphInspector.js.map +1 -1
- package/dist/capture.d.ts +5 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +2 -0
- package/dist/capture.js.map +1 -0
- package/dist/debugCaptureModel.d.ts +19 -0
- package/dist/debugCaptureModel.d.ts.map +1 -1
- package/dist/debugCaptureModel.js +36 -2
- package/dist/debugCaptureModel.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/panelAliasAnalysis.d.ts +1 -0
- package/dist/panelAliasAnalysis.d.ts.map +1 -1
- package/dist/panelAliasAnalysis.js +23 -54
- package/dist/panelAliasAnalysis.js.map +1 -1
- package/dist/panelCytoscapeGraphRenderer.d.ts +15 -2
- package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
- package/dist/panelCytoscapeGraphRenderer.js +145 -23
- package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
- package/dist/panelDetailLayout.d.ts +27 -0
- package/dist/panelDetailLayout.d.ts.map +1 -0
- package/dist/panelDetailLayout.js +174 -0
- package/dist/panelDetailLayout.js.map +1 -0
- package/dist/panelDetailStyles.d.ts +2 -0
- package/dist/panelDetailStyles.d.ts.map +1 -0
- package/dist/panelDetailStyles.js +57 -0
- package/dist/panelDetailStyles.js.map +1 -0
- package/dist/panelDiagnosticsView.d.ts +10 -1
- package/dist/panelDiagnosticsView.d.ts.map +1 -1
- package/dist/panelDiagnosticsView.js +166 -57
- package/dist/panelDiagnosticsView.js.map +1 -1
- package/dist/panelDomHelpers.d.ts.map +1 -1
- package/dist/panelDomHelpers.js +6 -5
- package/dist/panelDomHelpers.js.map +1 -1
- package/dist/panelGraphLayout.d.ts +3 -2
- package/dist/panelGraphLayout.d.ts.map +1 -1
- package/dist/panelGraphLayout.js +6 -5
- package/dist/panelGraphLayout.js.map +1 -1
- package/dist/panelGraphRenderer.d.ts +10 -0
- package/dist/panelGraphRenderer.d.ts.map +1 -1
- package/dist/panelGraphRenderer.js.map +1 -1
- package/dist/panelGraphScene.d.ts +1 -0
- package/dist/panelGraphScene.d.ts.map +1 -1
- package/dist/panelGraphScene.js +69 -32
- package/dist/panelGraphScene.js.map +1 -1
- package/dist/panelGraphSearch.d.ts +16 -0
- package/dist/panelGraphSearch.d.ts.map +1 -0
- package/dist/panelGraphSearch.js +93 -0
- package/dist/panelGraphSearch.js.map +1 -0
- package/dist/panelGraphView.d.ts +82 -0
- package/dist/panelGraphView.d.ts.map +1 -1
- package/dist/panelGraphView.js +15 -4
- package/dist/panelGraphView.js.map +1 -1
- package/dist/panelGraphVisuals.d.ts +14 -6
- package/dist/panelGraphVisuals.d.ts.map +1 -1
- package/dist/panelGraphVisuals.js +126 -51
- package/dist/panelGraphVisuals.js.map +1 -1
- package/dist/panelInspectorView.d.ts +8 -0
- package/dist/panelInspectorView.d.ts.map +1 -1
- package/dist/panelInspectorView.js +242 -48
- package/dist/panelInspectorView.js.map +1 -1
- package/dist/panelListStyles.d.ts +3 -0
- package/dist/panelListStyles.d.ts.map +1 -0
- package/dist/panelListStyles.js +155 -0
- package/dist/panelListStyles.js.map +1 -0
- package/dist/panelMemoryStyles.d.ts +3 -0
- package/dist/panelMemoryStyles.d.ts.map +1 -0
- package/dist/panelMemoryStyles.js +42 -0
- package/dist/panelMemoryStyles.js.map +1 -0
- package/dist/panelMemoryView.d.ts +13 -1
- package/dist/panelMemoryView.d.ts.map +1 -1
- package/dist/panelMemoryView.js +161 -41
- package/dist/panelMemoryView.js.map +1 -1
- package/dist/panelPassesView.d.ts +15 -0
- package/dist/panelPassesView.d.ts.map +1 -1
- package/dist/panelPassesView.js +202 -72
- package/dist/panelPassesView.js.map +1 -1
- package/dist/panelRawView.d.ts +15 -0
- package/dist/panelRawView.d.ts.map +1 -0
- package/dist/panelRawView.js +105 -0
- package/dist/panelRawView.js.map +1 -0
- package/dist/panelResourcesView.d.ts +8 -0
- package/dist/panelResourcesView.d.ts.map +1 -1
- package/dist/panelResourcesView.js +62 -31
- package/dist/panelResourcesView.js.map +1 -1
- package/dist/panelSelection.d.ts +9 -1
- package/dist/panelSelection.d.ts.map +1 -1
- package/dist/panelSelection.js +34 -4
- package/dist/panelSelection.js.map +1 -1
- package/dist/panelTheme.d.ts +13 -0
- package/dist/panelTheme.d.ts.map +1 -0
- package/dist/panelTheme.js +104 -0
- package/dist/panelTheme.js.map +1 -0
- package/dist/panelTypes.d.ts +10 -1
- package/dist/panelTypes.d.ts.map +1 -1
- package/dist/panelTypes.js.map +1 -1
- package/dist/panelVisualTheme.d.ts +147 -50
- package/dist/panelVisualTheme.d.ts.map +1 -1
- package/dist/panelVisualTheme.js +34 -44
- package/dist/panelVisualTheme.js.map +1 -1
- package/dist/panelWorkbenchHelpers.d.ts +12 -1
- package/dist/panelWorkbenchHelpers.d.ts.map +1 -1
- package/dist/panelWorkbenchHelpers.js +62 -1
- package/dist/panelWorkbenchHelpers.js.map +1 -1
- package/dist/panelWorkbenchStyles.d.ts +2 -0
- package/dist/panelWorkbenchStyles.d.ts.map +1 -0
- package/dist/panelWorkbenchStyles.js +101 -0
- package/dist/panelWorkbenchStyles.js.map +1 -0
- package/dist/panelWorkbenchView.d.ts +16 -0
- package/dist/panelWorkbenchView.d.ts.map +1 -1
- package/dist/panelWorkbenchView.js +228 -50
- package/dist/panelWorkbenchView.js.map +1 -1
- package/dist/query.js.map +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +147 -195
- package/dist/styles.js.map +1 -1
- package/dist/theme.d.ts +22 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +10 -0
- package/dist/theme.js.map +1 -0
- package/dist/themeDefinitions.d.ts +251 -0
- package/dist/themeDefinitions.d.ts.map +1 -0
- package/dist/themeDefinitions.js +96 -0
- package/dist/themeDefinitions.js.map +1 -0
- package/dist/themePalette.d.ts +66 -0
- package/dist/themePalette.d.ts.map +1 -0
- package/dist/themePalette.js +37 -0
- package/dist/themePalette.js.map +1 -0
- package/dist/themes.css +165 -0
- package/package.json +44 -10
- package/src/FrameGraphInspector.ts +130 -31
- package/src/capture.ts +4 -0
- package/src/debugCaptureModel.ts +53 -2
- package/src/index.ts +6 -2
- package/src/panelAliasAnalysis.ts +24 -70
- package/src/panelCytoscapeGraphRenderer.ts +140 -23
- package/src/panelDetailLayout.ts +155 -0
- package/src/panelDetailStyles.ts +56 -0
- package/src/panelDiagnosticsView.ts +166 -85
- package/src/panelDomHelpers.ts +4 -5
- package/src/panelGraphLayout.ts +6 -5
- package/src/panelGraphRenderer.ts +7 -0
- package/src/panelGraphScene.ts +68 -30
- package/src/panelGraphSearch.ts +96 -0
- package/src/panelGraphView.ts +14 -4
- package/src/panelGraphVisuals.ts +122 -52
- package/src/panelInspectorView.ts +227 -48
- package/src/panelListStyles.ts +154 -0
- package/src/panelMemoryStyles.ts +41 -0
- package/src/panelMemoryView.ts +178 -53
- package/src/panelPassesView.ts +190 -137
- package/src/panelRawView.ts +99 -0
- package/src/panelResourcesView.ts +69 -56
- package/src/panelSelection.ts +37 -5
- package/src/panelTheme.ts +85 -0
- package/src/panelTypes.ts +7 -1
- package/src/panelVisualTheme.ts +38 -49
- package/src/panelWorkbenchHelpers.ts +60 -2
- package/src/panelWorkbenchStyles.ts +100 -0
- package/src/panelWorkbenchView.ts +201 -52
- package/src/query.ts +11 -11
- package/src/styles.ts +148 -195
- package/src/theme.ts +24 -0
- package/src/themeDefinitions.ts +103 -0
- package/src/themePalette.ts +44 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type GraphVisualTheme } from './panelVisualTheme.ts';
|
|
1
2
|
import type cytoscape from 'cytoscape';
|
|
2
3
|
import type { ELK } from 'elkjs/lib/elk-api';
|
|
3
4
|
import type { GraphRenderer, GraphRenderRequest } from './panelGraphRenderer.ts';
|
|
@@ -13,7 +14,7 @@ export type GraphResizeSubscription = {
|
|
|
13
14
|
export type GraphRendererEnvironment = {
|
|
14
15
|
readonly createElement: (tagName: string) => HTMLElement;
|
|
15
16
|
readonly loadRuntime: () => Promise<GraphRendererRuntime>;
|
|
16
|
-
readonly layoutScene: (elk: ELK, scene: GraphScene) => Promise<GraphLayoutResult>;
|
|
17
|
+
readonly layoutScene: (elk: ELK, scene: GraphScene, theme?: GraphVisualTheme) => Promise<GraphLayoutResult>;
|
|
17
18
|
readonly observeResize?: (element: HTMLElement, onResize: () => void) => GraphResizeSubscription;
|
|
18
19
|
};
|
|
19
20
|
export declare class CytoscapeGraphRenderer implements GraphRenderer {
|
|
@@ -25,6 +26,9 @@ export declare class CytoscapeGraphRenderer implements GraphRenderer {
|
|
|
25
26
|
private readonly statusMessage;
|
|
26
27
|
private readonly retryButton;
|
|
27
28
|
private readonly resizeSubscription;
|
|
29
|
+
private theme;
|
|
30
|
+
private geometryRevision;
|
|
31
|
+
private wasVisible;
|
|
28
32
|
private core;
|
|
29
33
|
private elk;
|
|
30
34
|
private loading;
|
|
@@ -40,10 +44,17 @@ export declare class CytoscapeGraphRenderer implements GraphRenderer {
|
|
|
40
44
|
private anchorTargetContentKey;
|
|
41
45
|
private failedSceneContentKey;
|
|
42
46
|
private overview;
|
|
47
|
+
private dragPanning;
|
|
48
|
+
private pointerInside;
|
|
49
|
+
private pointerOverElement;
|
|
50
|
+
private readonly cancelPointerInteraction;
|
|
51
|
+
private pendingReveal;
|
|
43
52
|
private pendingGroupTap;
|
|
44
53
|
constructor(host: HTMLElement, environment?: GraphRendererEnvironment);
|
|
45
54
|
render(request: GraphRenderRequest): void;
|
|
55
|
+
setTheme(theme: GraphVisualTheme): void;
|
|
46
56
|
resize(): void;
|
|
57
|
+
cancelReveal(): void;
|
|
47
58
|
fit(): void;
|
|
48
59
|
relayout(): void;
|
|
49
60
|
destroy(): void;
|
|
@@ -56,17 +67,19 @@ export declare class CytoscapeGraphRenderer implements GraphRenderer {
|
|
|
56
67
|
private syncInteraction;
|
|
57
68
|
private consumeFitIfCurrentTarget;
|
|
58
69
|
private consumeAnchorIfCurrentTarget;
|
|
70
|
+
private consumeReveal;
|
|
59
71
|
private targetNeedsApply;
|
|
60
72
|
private updateSemanticZoom;
|
|
61
73
|
private positionTooltip;
|
|
62
74
|
private hideTooltip;
|
|
63
75
|
private cancelGroupTap;
|
|
64
76
|
private clearHover;
|
|
77
|
+
private updateCursor;
|
|
65
78
|
private showStatus;
|
|
66
79
|
private hideStatus;
|
|
67
80
|
private resolveCurrentRequest;
|
|
68
81
|
}
|
|
69
|
-
export declare function updateElementData(core: cytoscape.Core, scene: GraphScene): void;
|
|
82
|
+
export declare function updateElementData(core: cytoscape.Core, scene: GraphScene, theme?: GraphVisualTheme): void;
|
|
70
83
|
export { createCytoscapeEdgeRouteData, createElkLayoutGraph, layoutGraphScene, } from './panelGraphLayout.ts';
|
|
71
84
|
export type { CytoscapeEdgeRouteData, GraphEdgeRoute, GraphLayoutResult, GraphPosition, } from './panelGraphLayout.ts';
|
|
72
85
|
export { createGraphStyles, expandedGroupLabelMaxWidth, graphEdgeDisplayLabel, graphLayoutGeometryKey, isOverviewGraphScale, } from './panelGraphVisuals.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panelCytoscapeGraphRenderer.d.ts","sourceRoot":"","sources":["../src/panelCytoscapeGraphRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAIH,KAAK,iBAAiB,EAEzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEH,KAAK,UAAU,EAIlB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"panelCytoscapeGraphRenderer.d.ts","sourceRoot":"","sources":["../src/panelCytoscapeGraphRenderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { GRAPH_VISUAL_THEME } from "./panelVisualTheme.js";
|
|
1
2
|
import { applyGraphLayout, layoutGraphScene, syncExpandedGroupLabelGeometry, } from "./panelGraphLayout.js";
|
|
2
3
|
import { selectionKey, } from "./panelGraphScene.js";
|
|
3
|
-
import { createGraphStyles, expandedGroupLabelMaxWidth, GRAPH_GEOMETRY, graphEdgeDisplayLabel, graphLayoutGeometryKey, isOverviewGraphScale, nodeDimensions, } from "./panelGraphVisuals.js";
|
|
4
|
+
import { createGraphStyles, fitGraphLabel, fitCollapsedGroupLabel, graphLabelFontSize, expandedGroupLabelMaxWidth, GRAPH_GEOMETRY, graphEdgeDisplayLabel, graphLayoutGeometryKey, isOverviewGraphScale, nodeDimensions, } from "./panelGraphVisuals.js";
|
|
4
5
|
export class CytoscapeGraphRenderer {
|
|
5
6
|
host;
|
|
6
7
|
environment;
|
|
@@ -10,6 +11,9 @@ export class CytoscapeGraphRenderer {
|
|
|
10
11
|
statusMessage;
|
|
11
12
|
retryButton;
|
|
12
13
|
resizeSubscription;
|
|
14
|
+
theme = GRAPH_VISUAL_THEME;
|
|
15
|
+
geometryRevision = 0;
|
|
16
|
+
wasVisible = false;
|
|
13
17
|
core;
|
|
14
18
|
elk;
|
|
15
19
|
loading;
|
|
@@ -25,17 +29,30 @@ export class CytoscapeGraphRenderer {
|
|
|
25
29
|
anchorTargetContentKey;
|
|
26
30
|
failedSceneContentKey;
|
|
27
31
|
overview = false;
|
|
32
|
+
dragPanning = false;
|
|
33
|
+
pointerInside = false;
|
|
34
|
+
pointerOverElement = false;
|
|
35
|
+
cancelPointerInteraction = () => {
|
|
36
|
+
this.dragPanning = false;
|
|
37
|
+
this.cancelGroupTap();
|
|
38
|
+
this.clearHover();
|
|
39
|
+
};
|
|
40
|
+
pendingReveal;
|
|
28
41
|
pendingGroupTap;
|
|
29
42
|
constructor(host, environment = browserGraphRendererEnvironment) {
|
|
30
43
|
this.host = host;
|
|
31
44
|
this.environment = environment;
|
|
32
45
|
this.canvasHost = environment.createElement('div');
|
|
33
46
|
this.canvasHost.className = 'zenfg-inspector-graph-canvas';
|
|
47
|
+
this.updateCursor();
|
|
34
48
|
this.tooltip = environment.createElement('div');
|
|
35
49
|
this.tooltip.className = 'zenfg-inspector-graph-tooltip';
|
|
36
50
|
this.tooltip.hidden = true;
|
|
37
51
|
// Cytoscape's node mouseout is not guaranteed when leaving its canvas directly.
|
|
38
|
-
this.canvasHost.addEventListener('
|
|
52
|
+
this.canvasHost.addEventListener('pointerenter', () => { this.pointerInside = true; });
|
|
53
|
+
this.canvasHost.addEventListener('pointerleave', () => { this.pointerInside = false; this.clearHover(); });
|
|
54
|
+
this.canvasHost.addEventListener('pointercancel', this.cancelPointerInteraction);
|
|
55
|
+
this.canvasHost.ownerDocument?.defaultView?.addEventListener('blur', this.cancelPointerInteraction);
|
|
39
56
|
this.status = environment.createElement('div');
|
|
40
57
|
this.status.className = 'zenfg-inspector-graph-status';
|
|
41
58
|
this.status.hidden = true;
|
|
@@ -49,11 +66,19 @@ export class CytoscapeGraphRenderer {
|
|
|
49
66
|
this.retryButton.addEventListener('click', () => this.relayout());
|
|
50
67
|
this.status.append(this.statusMessage, this.retryButton);
|
|
51
68
|
this.host.replaceChildren(this.canvasHost, this.status, this.tooltip);
|
|
52
|
-
this.resizeSubscription = environment.observeResize?.(host, () =>
|
|
69
|
+
this.resizeSubscription = environment.observeResize?.(host, () => {
|
|
70
|
+
const visible = host.clientWidth > 0 && host.clientHeight > 0;
|
|
71
|
+
if (visible && !this.wasVisible)
|
|
72
|
+
this.latestRequest?.onVisible?.();
|
|
73
|
+
this.wasVisible = visible;
|
|
74
|
+
this.core?.resize();
|
|
75
|
+
});
|
|
53
76
|
}
|
|
54
77
|
render(request) {
|
|
55
78
|
if (this.destroyed)
|
|
56
79
|
return;
|
|
80
|
+
if (request.theme)
|
|
81
|
+
this.setTheme(request.theme);
|
|
57
82
|
if (this.latestRequest?.scene !== request.scene
|
|
58
83
|
|| (this.latestRequest?.selected && selectionKey(this.latestRequest.selected)) !== (request.selected && selectionKey(request.selected))) {
|
|
59
84
|
this.cancelGroupTap();
|
|
@@ -63,6 +88,14 @@ export class CytoscapeGraphRenderer {
|
|
|
63
88
|
this.core?.elements().removeClass('semantic-hover');
|
|
64
89
|
}
|
|
65
90
|
this.latestRequest = request;
|
|
91
|
+
if (request.reveal) {
|
|
92
|
+
this.pendingReveal = { request: request.reveal, contentKey: request.scene.contentKey, captureRevision: request.captureRevision };
|
|
93
|
+
}
|
|
94
|
+
else if (this.pendingReveal && (this.pendingReveal.captureRevision !== request.captureRevision
|
|
95
|
+
|| this.pendingReveal.contentKey !== request.scene.contentKey
|
|
96
|
+
|| !request.selected || selectionKey(request.selected) !== selectionKey(this.pendingReveal.request.selection))) {
|
|
97
|
+
this.pendingReveal = undefined;
|
|
98
|
+
}
|
|
66
99
|
if (request.fit) {
|
|
67
100
|
this.fitTargetContentKey = request.scene.contentKey;
|
|
68
101
|
}
|
|
@@ -92,14 +125,46 @@ export class CytoscapeGraphRenderer {
|
|
|
92
125
|
this.syncInteraction(request);
|
|
93
126
|
this.consumeFitIfCurrentTarget();
|
|
94
127
|
this.consumeAnchorIfCurrentTarget();
|
|
128
|
+
this.consumeReveal();
|
|
95
129
|
this.processedVersion = version;
|
|
96
130
|
return;
|
|
97
131
|
}
|
|
98
132
|
this.scheduleProcessing();
|
|
99
133
|
}
|
|
134
|
+
setTheme(theme) {
|
|
135
|
+
if (this.destroyed || JSON.stringify(theme) === JSON.stringify(this.theme))
|
|
136
|
+
return;
|
|
137
|
+
const typographyChanged = theme.fontFamily !== this.theme.fontFamily || theme.fontSize !== this.theme.fontSize;
|
|
138
|
+
this.theme = theme;
|
|
139
|
+
this.core?.style().fromJson(createGraphStyles(theme)).update();
|
|
140
|
+
if (!typographyChanged)
|
|
141
|
+
return;
|
|
142
|
+
this.geometryRevision++;
|
|
143
|
+
if (this.core && this.latestRequest && this.appliedScene) {
|
|
144
|
+
const selected = this.core.nodes('.semantic-selected').first();
|
|
145
|
+
const center = this.core.extent();
|
|
146
|
+
const target = selected.nonempty() ? selected : this.core.nodes().filter(node => !node.isParent()).sort((a, b) => {
|
|
147
|
+
const distance = (node) => Math.hypot(node.position('x') - center.x1 - center.w / 2, node.position('y') - center.y1 - center.h / 2);
|
|
148
|
+
return distance(a) - distance(b);
|
|
149
|
+
}).first();
|
|
150
|
+
if (target.nonempty()) {
|
|
151
|
+
this.anchorElementId = target.id();
|
|
152
|
+
this.anchorTargetContentKey = this.latestRequest.scene.contentKey;
|
|
153
|
+
}
|
|
154
|
+
this.forceRelayout = true;
|
|
155
|
+
++this.requestVersion;
|
|
156
|
+
this.scheduleProcessing();
|
|
157
|
+
}
|
|
158
|
+
this.updateSemanticZoom(true);
|
|
159
|
+
}
|
|
100
160
|
resize() {
|
|
101
161
|
this.core?.resize();
|
|
102
162
|
}
|
|
163
|
+
cancelReveal() {
|
|
164
|
+
this.pendingReveal = undefined;
|
|
165
|
+
this.cancelGroupTap();
|
|
166
|
+
this.clearHover();
|
|
167
|
+
}
|
|
103
168
|
fit() {
|
|
104
169
|
const targetContentKey = this.latestRequest?.scene.contentKey;
|
|
105
170
|
if (targetContentKey)
|
|
@@ -132,6 +197,7 @@ export class CytoscapeGraphRenderer {
|
|
|
132
197
|
this.cancelGroupTap();
|
|
133
198
|
this.requestVersion++;
|
|
134
199
|
this.resizeSubscription?.disconnect();
|
|
200
|
+
this.canvasHost.ownerDocument?.defaultView?.removeEventListener('blur', this.cancelPointerInteraction);
|
|
135
201
|
this.hideTooltip();
|
|
136
202
|
this.core?.destroy();
|
|
137
203
|
this.core = undefined;
|
|
@@ -165,7 +231,7 @@ export class CytoscapeGraphRenderer {
|
|
|
165
231
|
if (request.scene.nodes.length === 0) {
|
|
166
232
|
this.hideTooltip();
|
|
167
233
|
if (this.core)
|
|
168
|
-
replaceElements(this.core, request.scene);
|
|
234
|
+
replaceElements(this.core, request.scene, this.theme);
|
|
169
235
|
this.appliedScene = request.scene;
|
|
170
236
|
this.forceRelayout = false;
|
|
171
237
|
if (this.fitTargetContentKey === request.scene.contentKey)
|
|
@@ -190,6 +256,7 @@ export class CytoscapeGraphRenderer {
|
|
|
190
256
|
this.syncInteraction(request);
|
|
191
257
|
this.consumeFitIfCurrentTarget();
|
|
192
258
|
this.consumeAnchorIfCurrentTarget();
|
|
259
|
+
this.consumeReveal();
|
|
193
260
|
this.hideStatus();
|
|
194
261
|
this.processedVersion = version;
|
|
195
262
|
continue;
|
|
@@ -208,20 +275,23 @@ export class CytoscapeGraphRenderer {
|
|
|
208
275
|
let laidOut = false;
|
|
209
276
|
if (geometryChanged || this.forceRelayout) {
|
|
210
277
|
this.showStatus('layout', 'Laying out graph…');
|
|
211
|
-
const
|
|
278
|
+
const geometryRevision = this.geometryRevision;
|
|
279
|
+
const result = await this.environment.layoutScene(this.elk, request.scene, this.theme);
|
|
280
|
+
if (geometryRevision !== this.geometryRevision)
|
|
281
|
+
continue;
|
|
212
282
|
const layoutRequest = this.resolveCurrentRequest(version, request.scene.contentKey);
|
|
213
283
|
if (!layoutRequest)
|
|
214
284
|
continue;
|
|
215
285
|
({ version, request } = layoutRequest);
|
|
216
286
|
if (topologyChanged || !this.appliedScene)
|
|
217
|
-
replaceElements(core, request.scene);
|
|
287
|
+
replaceElements(core, request.scene, this.theme);
|
|
218
288
|
else
|
|
219
|
-
updateElementData(core, request.scene);
|
|
289
|
+
updateElementData(core, request.scene, this.theme);
|
|
220
290
|
applyGraphLayout(core, request.scene, result);
|
|
221
291
|
laidOut = true;
|
|
222
292
|
}
|
|
223
293
|
else {
|
|
224
|
-
updateElementData(core, request.scene);
|
|
294
|
+
updateElementData(core, request.scene, this.theme);
|
|
225
295
|
}
|
|
226
296
|
syncExpandedGroupLabelGeometry(core);
|
|
227
297
|
this.appliedScene = request.scene;
|
|
@@ -243,6 +313,7 @@ export class CytoscapeGraphRenderer {
|
|
|
243
313
|
restoreViewport(core, previousViewport);
|
|
244
314
|
}
|
|
245
315
|
this.consumeAnchorIfCurrentTarget();
|
|
316
|
+
this.consumeReveal();
|
|
246
317
|
this.updateSemanticZoom(true);
|
|
247
318
|
this.hideStatus();
|
|
248
319
|
this.processedVersion = version;
|
|
@@ -278,7 +349,7 @@ export class CytoscapeGraphRenderer {
|
|
|
278
349
|
this.core = runtime.createCore({
|
|
279
350
|
container: this.canvasHost,
|
|
280
351
|
elements: [],
|
|
281
|
-
style: createGraphStyles(),
|
|
352
|
+
style: createGraphStyles(this.theme),
|
|
282
353
|
layout: { name: 'preset' },
|
|
283
354
|
minZoom: 0.03,
|
|
284
355
|
maxZoom: 4,
|
|
@@ -321,10 +392,13 @@ export class CytoscapeGraphRenderer {
|
|
|
321
392
|
});
|
|
322
393
|
const hoverElement = (event) => {
|
|
323
394
|
const request = this.interactiveRequest();
|
|
324
|
-
if (!request)
|
|
395
|
+
if (!request || this.dragPanning)
|
|
325
396
|
return;
|
|
326
397
|
const id = event.target.id();
|
|
327
398
|
const selection = request.scene.interaction.selectionByElementId.get(id);
|
|
399
|
+
this.pointerInside = true;
|
|
400
|
+
this.pointerOverElement = !!selection;
|
|
401
|
+
this.updateCursor();
|
|
328
402
|
if (selection)
|
|
329
403
|
request.onHover(selection);
|
|
330
404
|
const title = event.target.data('tooltip');
|
|
@@ -342,6 +416,19 @@ export class CytoscapeGraphRenderer {
|
|
|
342
416
|
const clearHover = () => this.clearHover();
|
|
343
417
|
core.on('mouseout', 'node', clearHover);
|
|
344
418
|
core.on('mouseout', 'edge', clearHover);
|
|
419
|
+
core.on('dragpan', () => {
|
|
420
|
+
if (this.dragPanning)
|
|
421
|
+
return;
|
|
422
|
+
this.dragPanning = true;
|
|
423
|
+
this.cancelGroupTap();
|
|
424
|
+
this.clearHover();
|
|
425
|
+
});
|
|
426
|
+
core.on('tapend', (event) => {
|
|
427
|
+
this.dragPanning = false;
|
|
428
|
+
this.pointerOverElement = this.pointerInside && event.target !== core
|
|
429
|
+
&& !!this.interactiveRequest()?.scene.interaction.selectionByElementId.get(event.target.id());
|
|
430
|
+
this.updateCursor();
|
|
431
|
+
});
|
|
345
432
|
core.on('zoom', () => this.updateSemanticZoom());
|
|
346
433
|
}
|
|
347
434
|
interactiveRequest() {
|
|
@@ -385,6 +472,27 @@ export class CytoscapeGraphRenderer {
|
|
|
385
472
|
this.anchorElementId = undefined;
|
|
386
473
|
this.anchorTargetContentKey = undefined;
|
|
387
474
|
}
|
|
475
|
+
consumeReveal() {
|
|
476
|
+
const pending = this.pendingReveal;
|
|
477
|
+
const request = this.latestRequest;
|
|
478
|
+
if (!pending || !request || !this.core || this.targetNeedsApply())
|
|
479
|
+
return;
|
|
480
|
+
this.pendingReveal = undefined;
|
|
481
|
+
if (pending.captureRevision !== request.captureRevision || pending.contentKey !== request.scene.contentKey)
|
|
482
|
+
return;
|
|
483
|
+
const ids = request.scene.interaction.primaryElementIdsBySelection.get(selectionKey(pending.request.selection)) ?? [];
|
|
484
|
+
const targets = this.core.collection();
|
|
485
|
+
for (const id of ids)
|
|
486
|
+
targets.merge(this.core.getElementById(id));
|
|
487
|
+
if (!targets.length)
|
|
488
|
+
return;
|
|
489
|
+
this.core.resize();
|
|
490
|
+
this.core.fit(targets, 64);
|
|
491
|
+
if (this.core.zoom() > 1.2)
|
|
492
|
+
this.core.zoom(1.2);
|
|
493
|
+
this.core.center(targets);
|
|
494
|
+
this.updateSemanticZoom();
|
|
495
|
+
}
|
|
388
496
|
targetNeedsApply() {
|
|
389
497
|
const target = this.latestRequest?.scene;
|
|
390
498
|
if (!target || !this.appliedScene)
|
|
@@ -395,7 +503,7 @@ export class CytoscapeGraphRenderer {
|
|
|
395
503
|
const core = this.core;
|
|
396
504
|
if (!core)
|
|
397
505
|
return;
|
|
398
|
-
const overview = isOverviewGraphScale(core.zoom());
|
|
506
|
+
const overview = isOverviewGraphScale(core.zoom(), this.theme);
|
|
399
507
|
if (!force && overview === this.overview)
|
|
400
508
|
return;
|
|
401
509
|
this.overview = overview;
|
|
@@ -424,9 +532,14 @@ export class CytoscapeGraphRenderer {
|
|
|
424
532
|
this.pendingGroupTap = undefined;
|
|
425
533
|
}
|
|
426
534
|
clearHover() {
|
|
535
|
+
this.pointerOverElement = false;
|
|
536
|
+
this.updateCursor();
|
|
427
537
|
this.hideTooltip();
|
|
428
538
|
this.latestRequest?.onHover(undefined);
|
|
429
539
|
}
|
|
540
|
+
updateCursor() {
|
|
541
|
+
this.canvasHost.style.cursor = this.dragPanning ? 'grabbing' : this.pointerOverElement ? 'pointer' : 'grab';
|
|
542
|
+
}
|
|
430
543
|
showStatus(kind, message, retry = false) {
|
|
431
544
|
this.status.dataset.state = kind;
|
|
432
545
|
this.statusMessage.textContent = message;
|
|
@@ -489,9 +602,9 @@ const browserGraphRendererEnvironment = {
|
|
|
489
602
|
};
|
|
490
603
|
},
|
|
491
604
|
};
|
|
492
|
-
function replaceElements(core, scene) {
|
|
605
|
+
function replaceElements(core, scene, theme = GRAPH_VISUAL_THEME) {
|
|
493
606
|
const definitions = [
|
|
494
|
-
...scene.nodes.map(nodeDefinition),
|
|
607
|
+
...scene.nodes.map(node => nodeDefinition(node, theme)),
|
|
495
608
|
...scene.edges.map(edgeDefinition),
|
|
496
609
|
];
|
|
497
610
|
core.startBatch();
|
|
@@ -499,12 +612,12 @@ function replaceElements(core, scene) {
|
|
|
499
612
|
core.add(definitions);
|
|
500
613
|
core.endBatch();
|
|
501
614
|
}
|
|
502
|
-
export function updateElementData(core, scene) {
|
|
615
|
+
export function updateElementData(core, scene, theme = GRAPH_VISUAL_THEME) {
|
|
503
616
|
core.batch(() => {
|
|
504
617
|
for (const node of scene.nodes) {
|
|
505
618
|
const element = core.getElementById(node.id);
|
|
506
619
|
if (element.nonempty())
|
|
507
|
-
element.data(nodeRenderableData(node));
|
|
620
|
+
element.data(nodeRenderableData(node, theme));
|
|
508
621
|
}
|
|
509
622
|
for (const edge of scene.edges) {
|
|
510
623
|
const element = core.getElementById(edge.id);
|
|
@@ -513,21 +626,29 @@ export function updateElementData(core, scene) {
|
|
|
513
626
|
}
|
|
514
627
|
});
|
|
515
628
|
}
|
|
516
|
-
function nodeDefinition(node) {
|
|
629
|
+
function nodeDefinition(node, theme) {
|
|
517
630
|
return {
|
|
518
631
|
group: 'nodes',
|
|
632
|
+
pannable: true,
|
|
519
633
|
data: {
|
|
520
634
|
id: node.id,
|
|
521
635
|
parent: node.parentId,
|
|
522
|
-
...nodeRenderableData(node),
|
|
636
|
+
...nodeRenderableData(node, theme),
|
|
523
637
|
},
|
|
524
638
|
};
|
|
525
639
|
}
|
|
526
|
-
function nodeRenderableData(node) {
|
|
527
|
-
const dimensions = nodeDimensions(node);
|
|
640
|
+
function nodeRenderableData(node, theme) {
|
|
641
|
+
const dimensions = nodeDimensions(node, theme);
|
|
528
642
|
const labelMaxWidth = node.kind === 'group' && node.collapsed
|
|
529
643
|
? expandedGroupLabelMaxWidth(dimensions.width)
|
|
530
|
-
: 160;
|
|
644
|
+
: 160 * theme.fontSize / GRAPH_GEOMETRY.baseFontSize;
|
|
645
|
+
const fitLabel = (label) => node.kind !== 'group'
|
|
646
|
+
? fitGraphLabel(label, labelMaxWidth, theme)
|
|
647
|
+
: node.collapsed ? fitCollapsedGroupLabel(label, labelMaxWidth, theme) : label;
|
|
648
|
+
const detailLabel = fitLabel(node.label);
|
|
649
|
+
const labelFontSize = node.kind === 'group' && !node.collapsed
|
|
650
|
+
? theme.fontSize * 1.2
|
|
651
|
+
: graphLabelFontSize(detailLabel, labelMaxWidth, dimensions.height - 12 * theme.fontSize / GRAPH_GEOMETRY.baseFontSize, theme);
|
|
531
652
|
return {
|
|
532
653
|
kind: node.kind,
|
|
533
654
|
passKind: node.kind === 'pass' ? node.passKind : undefined,
|
|
@@ -535,9 +656,10 @@ function nodeRenderableData(node) {
|
|
|
535
656
|
collapsed: node.kind === 'group' && node.collapsed ? 1 : 0,
|
|
536
657
|
hasCulled: node.kind === 'group' && node.culledNodeCount > 0 ? 1 : 0,
|
|
537
658
|
depthBand: node.kind === 'group' ? node.depthBand : undefined,
|
|
538
|
-
detailLabel
|
|
539
|
-
|
|
540
|
-
|
|
659
|
+
detailLabel,
|
|
660
|
+
labelFontSize,
|
|
661
|
+
overviewLabel: fitLabel(node.overviewLabel),
|
|
662
|
+
displayLabel: detailLabel,
|
|
541
663
|
tooltip: node.title,
|
|
542
664
|
labelMaxWidth,
|
|
543
665
|
width: dimensions.width,
|