@receptron/graphai_vue_cytoscape 0.0.13 → 0.0.14
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/lib/cytoscape.js +27 -19
- package/package.json +9 -9
- package/lib/bundle.umd.js~ +0 -293
package/lib/cytoscape.js
CHANGED
|
@@ -192,14 +192,18 @@ var node2cyEdge = function (node, nodeId) {
|
|
|
192
192
|
}
|
|
193
193
|
if ("update" in node && node.update) {
|
|
194
194
|
// static node
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
(0, exports.inputs2dataSources)([node.update]).forEach(function (input) {
|
|
196
|
+
if (input[0] === ":") {
|
|
197
|
+
var _a = parseInput(input), source = _a.source, label = _a.label;
|
|
198
|
+
edges.push({
|
|
199
|
+
data: {
|
|
200
|
+
source: source,
|
|
201
|
+
target: nodeId,
|
|
202
|
+
isUpdate: true,
|
|
203
|
+
label: label,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
203
207
|
});
|
|
204
208
|
}
|
|
205
209
|
return edges;
|
|
@@ -224,22 +228,26 @@ var cytoscapeFromGraph = function (_graph_data) {
|
|
|
224
228
|
var staticInputs_1 = Object.keys(graph_1.nodes)
|
|
225
229
|
.filter(function (key) { return "value" in graph_1.nodes[key]; })
|
|
226
230
|
.reduce(function (tmp, key) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
tmp[source]
|
|
231
|
+
if (graph_1.nodes[key].value[0] === ":") {
|
|
232
|
+
var source = parseInput(graph_1.nodes[key].value).source;
|
|
233
|
+
if (!tmp[source]) {
|
|
234
|
+
tmp[source] = [];
|
|
235
|
+
}
|
|
236
|
+
tmp[source].push(key);
|
|
230
237
|
}
|
|
231
|
-
tmp[source].push(key);
|
|
232
238
|
return tmp;
|
|
233
239
|
}, {});
|
|
234
240
|
Object.keys(node.inputs).forEach(function (parentInputNodeId) {
|
|
235
241
|
graph_1.nodes[parentInputNodeId] = { value: "dummy" };
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
staticInputs_1[parentInputNodeId]
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
242
|
+
(0, exports.inputs2dataSources)([node.inputs[parentInputNodeId]]).forEach(function (input) {
|
|
243
|
+
var source = parseInput(input).source;
|
|
244
|
+
pushEdge({ source: nodeId, target: parentInputNodeId, label: source });
|
|
245
|
+
if (staticInputs_1[parentInputNodeId]) {
|
|
246
|
+
staticInputs_1[parentInputNodeId].forEach(function (id) {
|
|
247
|
+
pushEdge({ source: nodeId, target: id, label: parentInputNodeId });
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
});
|
|
243
251
|
});
|
|
244
252
|
toGraph(graph_1);
|
|
245
253
|
Object.keys(graph_1.nodes).forEach(function (key) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@receptron/graphai_vue_cytoscape",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"main": "lib/cytoscape.js",
|
|
5
5
|
"module": "lib/bundle.esm.js",
|
|
6
6
|
"browser": "lib/bundle.umd.js",
|
|
@@ -29,22 +29,22 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/receptron/graphai_utils/tree/main/packages/vue-cytoscape#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"cytoscape": "^3.30.
|
|
32
|
+
"cytoscape": "^3.30.4",
|
|
33
33
|
"cytoscape-klay": "^3.1.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@babel/types": "^7.26.
|
|
36
|
+
"@babel/types": "^7.26.3",
|
|
37
37
|
"@rushstack/eslint-patch": "^1.8.0",
|
|
38
38
|
"@tsconfig/node20": "^20.1.4",
|
|
39
39
|
"@types/cytoscape-klay": "^3.1.4",
|
|
40
|
-
"@vitejs/plugin-vue": "^5.1
|
|
41
|
-
"@vue/tsconfig": "^0.
|
|
40
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
41
|
+
"@vue/tsconfig": "^0.7.0",
|
|
42
42
|
"autoprefixer": "^10.4.19",
|
|
43
43
|
"npm-run-all2": "^7.0.1",
|
|
44
|
-
"postcss": "^8.4.
|
|
45
|
-
"tailwindcss": "^3.4.
|
|
46
|
-
"vite": "^
|
|
47
|
-
"vue": "^3.5.
|
|
44
|
+
"postcss": "^8.4.49",
|
|
45
|
+
"tailwindcss": "^3.4.16",
|
|
46
|
+
"vite": "^6.0.3",
|
|
47
|
+
"vue": "^3.5.13",
|
|
48
48
|
"vue-tsc": "^2.1.10"
|
|
49
49
|
},
|
|
50
50
|
"types": "./lib/cytoscape.d.ts",
|
package/lib/bundle.umd.js~
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('graphai'), require('cytoscape'), require('cytoscape-klay')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'vue', 'graphai', 'cytoscape', 'cytoscape-klay'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vue_cytoscape = {}, global.vue, global.graphai, global.cytoscape, global["cytoscape-klay"]));
|
|
5
|
-
})(this, (function (exports, vue, graphai, cytoscape, klay) { 'use strict';
|
|
6
|
-
|
|
7
|
-
cytoscape.use(klay);
|
|
8
|
-
const layout = "klay";
|
|
9
|
-
const colorPriority = "#f80";
|
|
10
|
-
const colorStatic = "#88f";
|
|
11
|
-
const calcNodeWidth = (label) => {
|
|
12
|
-
if (label === null || label === undefined) {
|
|
13
|
-
return "50px";
|
|
14
|
-
}
|
|
15
|
-
return Math.max(50, label.length * 8) + "px";
|
|
16
|
-
};
|
|
17
|
-
const cyStyle = [
|
|
18
|
-
{
|
|
19
|
-
selector: "node",
|
|
20
|
-
style: {
|
|
21
|
-
"background-color": "data(color)",
|
|
22
|
-
label: "data(id)",
|
|
23
|
-
shape: (ele) => (ele.data("isStatic") ? "rectangle" : "roundrectangle"),
|
|
24
|
-
width: (ele) => calcNodeWidth(ele.data("id")),
|
|
25
|
-
color: "#fff",
|
|
26
|
-
height: "30px",
|
|
27
|
-
"text-valign": "center",
|
|
28
|
-
"text-halign": "center",
|
|
29
|
-
"font-size": "12px",
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
selector: "edge",
|
|
34
|
-
style: {
|
|
35
|
-
width: 3,
|
|
36
|
-
"line-color": "#888",
|
|
37
|
-
"target-arrow-color": "#888",
|
|
38
|
-
"target-arrow-shape": "triangle",
|
|
39
|
-
"curve-style": "straight",
|
|
40
|
-
"text-background-color": "#ffffff",
|
|
41
|
-
"text-background-opacity": 0.8,
|
|
42
|
-
"text-background-shape": "rectangle",
|
|
43
|
-
"font-size": "10px",
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
selector: "edge[label]",
|
|
48
|
-
style: {
|
|
49
|
-
label: "data(label)",
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
selector: "edge[isUpdate]",
|
|
54
|
-
style: {
|
|
55
|
-
color: "#ddd",
|
|
56
|
-
"line-color": "#ddd",
|
|
57
|
-
"line-style": "dashed",
|
|
58
|
-
"curve-style": "unbundled-bezier",
|
|
59
|
-
"target-arrow-color": "#ddd",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
const colorMap = {
|
|
64
|
-
[graphai.NodeState.Waiting]: "#888",
|
|
65
|
-
[graphai.NodeState.Completed]: "#000",
|
|
66
|
-
[graphai.NodeState.Executing]: "#0f0",
|
|
67
|
-
["executing-server"]: "#FFC0CB",
|
|
68
|
-
[graphai.NodeState.Queued]: "#ff0",
|
|
69
|
-
[graphai.NodeState.Injected]: "#00f",
|
|
70
|
-
[graphai.NodeState.TimedOut]: "#f0f",
|
|
71
|
-
[graphai.NodeState.Failed]: "#f00",
|
|
72
|
-
[graphai.NodeState.Skipped]: "#0ff",
|
|
73
|
-
};
|
|
74
|
-
const parseInput = (input) => {
|
|
75
|
-
// WARNING: Assuming the first character is always ":"
|
|
76
|
-
const ids = input.slice(1).split(".");
|
|
77
|
-
const source = ids.shift() || "";
|
|
78
|
-
const label = ids.length ? ids.join(".") : undefined;
|
|
79
|
-
return { source, label };
|
|
80
|
-
};
|
|
81
|
-
const inputs2dataSources = (inputs) => {
|
|
82
|
-
if (Array.isArray(inputs)) {
|
|
83
|
-
return inputs.map((inp) => inputs2dataSources(inp)).flat();
|
|
84
|
-
}
|
|
85
|
-
if (graphai.isObject(inputs)) {
|
|
86
|
-
return Object.values(inputs)
|
|
87
|
-
.map((input) => inputs2dataSources(input))
|
|
88
|
-
.flat();
|
|
89
|
-
}
|
|
90
|
-
if (typeof inputs === "string") {
|
|
91
|
-
const templateMatch = Array.from(inputs.matchAll(/\${(:[^}]+)}/g)).map((m) => m[1]);
|
|
92
|
-
if (templateMatch.length > 0) {
|
|
93
|
-
return inputs2dataSources(templateMatch);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return inputs;
|
|
97
|
-
};
|
|
98
|
-
const dataSourceNodeIds = (sources) => {
|
|
99
|
-
return sources.filter((source) => source.nodeId).map((source) => source.nodeId);
|
|
100
|
-
};
|
|
101
|
-
const cytoscapeFromGraph = (graph_data) => {
|
|
102
|
-
const elements = Object.keys(graph_data.nodes || {}).reduce((tmp, nodeId) => {
|
|
103
|
-
const node = graph_data.nodes[nodeId];
|
|
104
|
-
const isStatic = "value" in node;
|
|
105
|
-
const cyNode = {
|
|
106
|
-
data: {
|
|
107
|
-
id: nodeId,
|
|
108
|
-
color: isStatic ? colorStatic : colorMap[graphai.NodeState.Waiting],
|
|
109
|
-
isStatic,
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
tmp.nodes.push(cyNode);
|
|
113
|
-
tmp.map[nodeId] = cyNode;
|
|
114
|
-
if ("inputs" in node) {
|
|
115
|
-
// computed node
|
|
116
|
-
inputs2dataSources(node.inputs).forEach((input) => {
|
|
117
|
-
if (input[0] === ":") {
|
|
118
|
-
const { source, label } = parseInput(input);
|
|
119
|
-
tmp.edges.push({
|
|
120
|
-
data: {
|
|
121
|
-
source,
|
|
122
|
-
target: nodeId,
|
|
123
|
-
label,
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
if ("update" in node && node.update) {
|
|
130
|
-
// static node
|
|
131
|
-
const { source, label } = parseInput(node.update);
|
|
132
|
-
tmp.edges.push({
|
|
133
|
-
data: {
|
|
134
|
-
source,
|
|
135
|
-
target: nodeId,
|
|
136
|
-
isUpdate: true,
|
|
137
|
-
label,
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
return tmp;
|
|
142
|
-
}, { nodes: [], edges: [], map: {} });
|
|
143
|
-
return { elements };
|
|
144
|
-
};
|
|
145
|
-
const useCytoscape = (selectedGraph) => {
|
|
146
|
-
let cy = null;
|
|
147
|
-
const cytoscapeData = vue.ref(cytoscapeFromGraph(selectedGraph.value ?? { nodes: {} }));
|
|
148
|
-
const cytoscapeRef = vue.ref();
|
|
149
|
-
const zoomingEnabled = vue.ref(true);
|
|
150
|
-
const updateCytoscape = async (nodeId, state) => {
|
|
151
|
-
if ([graphai.NodeState.Completed, graphai.NodeState.Waiting].includes(state)) {
|
|
152
|
-
await graphai.sleep(100);
|
|
153
|
-
}
|
|
154
|
-
const elements = cytoscapeData.value.elements;
|
|
155
|
-
elements.map[nodeId].data.color = colorMap[state];
|
|
156
|
-
const graph = selectedGraph.value;
|
|
157
|
-
const nodeData = (graph?.nodes ?? {})[nodeId] ?? [];
|
|
158
|
-
if ("agent" in nodeData && state === graphai.NodeState.Queued && (nodeData.priority ?? 0) > 0) {
|
|
159
|
-
// computed node
|
|
160
|
-
elements.map[nodeId].data.color = colorPriority;
|
|
161
|
-
}
|
|
162
|
-
else if ("value" in nodeData && state === graphai.NodeState.Waiting) {
|
|
163
|
-
// static node
|
|
164
|
-
elements.map[nodeId].data.color = colorStatic;
|
|
165
|
-
}
|
|
166
|
-
cytoscapeData.value = { elements };
|
|
167
|
-
if (state === graphai.NodeState.Injected) {
|
|
168
|
-
await graphai.sleep(100);
|
|
169
|
-
elements.map[nodeId].data.color = colorStatic;
|
|
170
|
-
cytoscapeData.value = { elements };
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
const createCytoscape = () => {
|
|
174
|
-
try {
|
|
175
|
-
cy = cytoscape({
|
|
176
|
-
container: cytoscapeRef.value,
|
|
177
|
-
style: cyStyle,
|
|
178
|
-
layout: {
|
|
179
|
-
name: layout,
|
|
180
|
-
// fit: true,
|
|
181
|
-
// padding: 30,
|
|
182
|
-
// avoidOverlap: true,
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
cy.on("mouseup", storePositions);
|
|
186
|
-
cy.on("touchend", storePositions);
|
|
187
|
-
// cy.on("select", "node", callback);
|
|
188
|
-
// cy.on("select", "edge", callback);
|
|
189
|
-
//store.commit("setCytoscape", cy);
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
console.error(error);
|
|
193
|
-
// store.commit("setCytoscape", null);
|
|
194
|
-
// error_msg.value = `${error}`;
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
const updateGraphData = async () => {
|
|
198
|
-
if (cy) {
|
|
199
|
-
cy.elements().remove();
|
|
200
|
-
cy.add(cytoscapeData.value.elements);
|
|
201
|
-
const name = cytoscapeData.value.elements.nodes.reduce((prevName, node) => {
|
|
202
|
-
if (node.position) {
|
|
203
|
-
return "preset";
|
|
204
|
-
}
|
|
205
|
-
return prevName;
|
|
206
|
-
}, layout);
|
|
207
|
-
console.log("layout", name);
|
|
208
|
-
cy.layout({ name }).run();
|
|
209
|
-
cy.fit();
|
|
210
|
-
if (name === layout) {
|
|
211
|
-
await graphai.sleep(400);
|
|
212
|
-
storePositions();
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
const storePositions = () => {
|
|
217
|
-
console.log("storePositions");
|
|
218
|
-
if (cy) {
|
|
219
|
-
cy.nodes().forEach((cynode) => {
|
|
220
|
-
const id = cynode.id();
|
|
221
|
-
const pos = cynode.position();
|
|
222
|
-
const node = cytoscapeData.value.elements.map[id];
|
|
223
|
-
node.position = pos;
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
const resetCytoscape = () => {
|
|
228
|
-
const elements = cytoscapeData.value.elements;
|
|
229
|
-
Object.keys(elements.map).forEach((nodeId) => {
|
|
230
|
-
const graph = selectedGraph.value;
|
|
231
|
-
const nodeData = graph.nodes[nodeId];
|
|
232
|
-
elements.map[nodeId].data.color = "value" in nodeData ? colorStatic : colorMap[graphai.NodeState.Waiting];
|
|
233
|
-
});
|
|
234
|
-
cytoscapeData.value = { elements };
|
|
235
|
-
};
|
|
236
|
-
vue.watch(cytoscapeData, () => {
|
|
237
|
-
console.log("updated");
|
|
238
|
-
updateGraphData();
|
|
239
|
-
});
|
|
240
|
-
vue.watch(selectedGraph, () => {
|
|
241
|
-
cytoscapeData.value = cytoscapeFromGraph(selectedGraph.value);
|
|
242
|
-
});
|
|
243
|
-
vue.onMounted(() => {
|
|
244
|
-
createCytoscape();
|
|
245
|
-
updateGraphData();
|
|
246
|
-
});
|
|
247
|
-
const layoutCytoscape = (key) => {
|
|
248
|
-
if (cy) {
|
|
249
|
-
const positions = cy.nodes().map((node) => {
|
|
250
|
-
return {
|
|
251
|
-
id: node.id(),
|
|
252
|
-
position: node.position(),
|
|
253
|
-
};
|
|
254
|
-
});
|
|
255
|
-
console.log(JSON.stringify(positions));
|
|
256
|
-
localStorage.setItem("layoutData-" + key, JSON.stringify(positions));
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
const loadLayout = (key) => {
|
|
260
|
-
const savedLayoutData = localStorage.getItem("layoutData-" + key);
|
|
261
|
-
if (savedLayoutData) {
|
|
262
|
-
const positions = JSON.parse(savedLayoutData);
|
|
263
|
-
positions.forEach((data) => {
|
|
264
|
-
if (cy) {
|
|
265
|
-
const node = cy.getElementById(data.id);
|
|
266
|
-
if (node) {
|
|
267
|
-
node.position(data.position);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
vue.watch(zoomingEnabled, (value) => {
|
|
274
|
-
if (cy) {
|
|
275
|
-
cy.zoomingEnabled(value);
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
return {
|
|
279
|
-
cytoscapeRef,
|
|
280
|
-
updateCytoscape,
|
|
281
|
-
resetCytoscape,
|
|
282
|
-
layoutCytoscape,
|
|
283
|
-
loadLayout,
|
|
284
|
-
zoomingEnabled,
|
|
285
|
-
};
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
exports.dataSourceNodeIds = dataSourceNodeIds;
|
|
289
|
-
exports.inputs2dataSources = inputs2dataSources;
|
|
290
|
-
exports.useCytoscape = useCytoscape;
|
|
291
|
-
|
|
292
|
-
}));
|
|
293
|
-
//# sourceMappingURL=bundle.umd.js.map
|