@receptron/graphai_vue_cytoscape 0.0.17 → 0.3.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/README.md +4 -3
- package/lib/cytoscape.d.ts +2 -2
- package/lib/cytoscape.js +156 -233
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -23,9 +23,7 @@ export default defineComponent({
|
|
|
23
23
|
|
|
24
24
|
const run = async () => {
|
|
25
25
|
const graphai = new GraphAI(selectdGraph.value, agents);
|
|
26
|
-
graphai.
|
|
27
|
-
updateCytoscape(nodeId, state);
|
|
28
|
-
};
|
|
26
|
+
graphai.registerCallback(updateCytoscape);
|
|
29
27
|
await graphai.run();
|
|
30
28
|
}
|
|
31
29
|
run();
|
|
@@ -37,3 +35,6 @@ export default defineComponent({
|
|
|
37
35
|
});
|
|
38
36
|
```
|
|
39
37
|
|
|
38
|
+
### requirement
|
|
39
|
+
|
|
40
|
+
GraphAI 0.6.23 or above
|
package/lib/cytoscape.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Ref, ComputedRef } from "vue";
|
|
2
|
-
import { GraphData,
|
|
2
|
+
import { GraphData, TransactionLog } from "graphai";
|
|
3
3
|
import { DataSource } from "graphai/lib/type";
|
|
4
4
|
export declare const inputs2dataSources: (inputs: any) => string[];
|
|
5
5
|
export declare const dataSourceNodeIds: (sources: DataSource[]) => string[];
|
|
6
6
|
export declare const useCytoscape: (selectedGraph: ComputedRef<GraphData> | Ref<GraphData>) => {
|
|
7
7
|
cytoscapeRef: Ref<any, any>;
|
|
8
|
-
updateCytoscape: (
|
|
8
|
+
updateCytoscape: (log: TransactionLog) => Promise<void>;
|
|
9
9
|
resetCytoscape: () => void;
|
|
10
10
|
layoutCytoscape: (key: string) => void;
|
|
11
11
|
loadLayout: (key: string) => void;
|
package/lib/cytoscape.js
CHANGED
|
@@ -1,79 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
-
};
|
|
52
|
-
var _a;
|
|
53
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
-
exports.useCytoscape = exports.dataSourceNodeIds = exports.inputs2dataSources = void 0;
|
|
55
|
-
var vue_1 = require("vue");
|
|
56
|
-
var graphai_1 = require("graphai");
|
|
57
|
-
var cytoscape_1 = __importDefault(require("cytoscape"));
|
|
58
|
-
var cytoscape_klay_1 = __importDefault(require("cytoscape-klay"));
|
|
59
|
-
cytoscape_1.default.use(cytoscape_klay_1.default);
|
|
60
|
-
var layout = "klay";
|
|
61
|
-
var colorPriority = "#f80";
|
|
62
|
-
var colorStatic = "#88f";
|
|
63
|
-
var calcNodeWidth = function (label) {
|
|
1
|
+
import { ref, onMounted, watch } from "vue";
|
|
2
|
+
import { NodeState, sleep, isObject } from "graphai";
|
|
3
|
+
import cytoscape from "cytoscape";
|
|
4
|
+
import klay from "cytoscape-klay";
|
|
5
|
+
cytoscape.use(klay);
|
|
6
|
+
const layout = "klay";
|
|
7
|
+
const colorPriority = "#f80";
|
|
8
|
+
const colorStatic = "#88f";
|
|
9
|
+
const calcNodeWidth = (label) => {
|
|
64
10
|
if (label === null || label === undefined) {
|
|
65
11
|
return "50px";
|
|
66
12
|
}
|
|
67
13
|
return Math.max(50, label.length * 8) + "px";
|
|
68
14
|
};
|
|
69
|
-
|
|
15
|
+
const cyStyle = [
|
|
70
16
|
{
|
|
71
17
|
selector: "node",
|
|
72
18
|
style: {
|
|
73
19
|
"background-color": "data(color)",
|
|
74
20
|
label: "data(id)",
|
|
75
|
-
shape:
|
|
76
|
-
width:
|
|
21
|
+
shape: (ele) => (ele.data("isStatic") ? "rectangle" : "roundrectangle"),
|
|
22
|
+
width: (ele) => calcNodeWidth(ele.data("id")),
|
|
77
23
|
color: "#fff",
|
|
78
24
|
height: "30px",
|
|
79
25
|
"text-valign": "center",
|
|
@@ -122,69 +68,67 @@ var cyStyle = [
|
|
|
122
68
|
},
|
|
123
69
|
},
|
|
124
70
|
];
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
71
|
+
const colorMap = {
|
|
72
|
+
[NodeState.Waiting]: "#888",
|
|
73
|
+
[NodeState.Completed]: "#000",
|
|
74
|
+
[NodeState.Executing]: "#0f0",
|
|
75
|
+
["executing-server"]: "#FFC0CB",
|
|
76
|
+
[NodeState.Queued]: "#ff0",
|
|
77
|
+
[NodeState.Injected]: "#00f",
|
|
78
|
+
[NodeState.TimedOut]: "#f0f",
|
|
79
|
+
[NodeState.Failed]: "#f00",
|
|
80
|
+
[NodeState.Skipped]: "#0ff",
|
|
81
|
+
};
|
|
82
|
+
const parseInput = (input) => {
|
|
137
83
|
// WARNING: Assuming the first character is always ":"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return { source
|
|
84
|
+
const ids = input.slice(1).split(".");
|
|
85
|
+
const source = ids.shift() || "";
|
|
86
|
+
const label = ids.length ? ids.join(".") : undefined;
|
|
87
|
+
return { source, label };
|
|
142
88
|
};
|
|
143
|
-
|
|
89
|
+
export const inputs2dataSources = (inputs) => {
|
|
144
90
|
if (Array.isArray(inputs)) {
|
|
145
|
-
return inputs.map(
|
|
91
|
+
return inputs.map((inp) => inputs2dataSources(inp)).flat();
|
|
146
92
|
}
|
|
147
|
-
if (
|
|
93
|
+
if (isObject(inputs)) {
|
|
148
94
|
return Object.values(inputs)
|
|
149
|
-
.map(
|
|
95
|
+
.map((input) => inputs2dataSources(input))
|
|
150
96
|
.flat();
|
|
151
97
|
}
|
|
152
98
|
if (typeof inputs === "string") {
|
|
153
|
-
|
|
99
|
+
const templateMatch = Array.from(inputs.matchAll(/\${(:[^}]+)}/g)).map((m) => m[1]);
|
|
154
100
|
if (templateMatch.length > 0) {
|
|
155
|
-
return
|
|
101
|
+
return inputs2dataSources(templateMatch);
|
|
156
102
|
}
|
|
157
103
|
}
|
|
158
104
|
return inputs;
|
|
159
105
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return sources.filter(function (source) { return source.nodeId; }).map(function (source) { return source.nodeId; });
|
|
106
|
+
export const dataSourceNodeIds = (sources) => {
|
|
107
|
+
return sources.filter((source) => source.nodeId).map((source) => source.nodeId);
|
|
163
108
|
};
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
var cyNode = {
|
|
109
|
+
const node2cyNode = (node, nodeId) => {
|
|
110
|
+
const isStatic = "value" in node;
|
|
111
|
+
const cyNode = {
|
|
168
112
|
data: {
|
|
169
113
|
id: nodeId,
|
|
170
|
-
color: isStatic ? colorStatic : colorMap[
|
|
171
|
-
isStatic
|
|
114
|
+
color: isStatic ? colorStatic : colorMap[NodeState.Waiting],
|
|
115
|
+
isStatic,
|
|
172
116
|
},
|
|
173
117
|
};
|
|
174
118
|
return cyNode;
|
|
175
119
|
};
|
|
176
|
-
|
|
177
|
-
|
|
120
|
+
const node2cyEdge = (node, nodeId) => {
|
|
121
|
+
const edges = [];
|
|
178
122
|
if ("inputs" in node) {
|
|
179
123
|
// computed node
|
|
180
|
-
|
|
124
|
+
inputs2dataSources(node.inputs).forEach((input) => {
|
|
181
125
|
if (input[0] === ":") {
|
|
182
|
-
|
|
126
|
+
const { source, label } = parseInput(input);
|
|
183
127
|
edges.push({
|
|
184
128
|
data: {
|
|
185
|
-
source
|
|
129
|
+
source,
|
|
186
130
|
target: nodeId,
|
|
187
|
-
label
|
|
131
|
+
label,
|
|
188
132
|
},
|
|
189
133
|
});
|
|
190
134
|
}
|
|
@@ -192,15 +136,15 @@ var node2cyEdge = function (node, nodeId) {
|
|
|
192
136
|
}
|
|
193
137
|
if ("update" in node && node.update) {
|
|
194
138
|
// static node
|
|
195
|
-
|
|
139
|
+
inputs2dataSources([node.update]).forEach((input) => {
|
|
196
140
|
if (input[0] === ":") {
|
|
197
|
-
|
|
141
|
+
const { source, label } = parseInput(input);
|
|
198
142
|
edges.push({
|
|
199
143
|
data: {
|
|
200
|
-
source
|
|
144
|
+
source,
|
|
201
145
|
target: nodeId,
|
|
202
146
|
isUpdate: true,
|
|
203
|
-
label
|
|
147
|
+
label,
|
|
204
148
|
},
|
|
205
149
|
});
|
|
206
150
|
}
|
|
@@ -208,28 +152,28 @@ var node2cyEdge = function (node, nodeId) {
|
|
|
208
152
|
}
|
|
209
153
|
return edges;
|
|
210
154
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
elements.edges.push({ data
|
|
155
|
+
const cytoscapeFromGraph = (_graph_data) => {
|
|
156
|
+
const elements = { nodes: [], edges: [], map: {} };
|
|
157
|
+
const pushEdge = (data) => {
|
|
158
|
+
elements.edges.push({ data });
|
|
215
159
|
};
|
|
216
|
-
|
|
217
|
-
Object.keys(graph_data.nodes || {}).forEach(
|
|
218
|
-
|
|
219
|
-
|
|
160
|
+
const toGraph = (graph_data) => {
|
|
161
|
+
Object.keys(graph_data.nodes || {}).forEach((nodeId) => {
|
|
162
|
+
const node = graph_data.nodes[nodeId];
|
|
163
|
+
const cyNode = node2cyNode(node, nodeId);
|
|
220
164
|
elements.nodes.push(cyNode);
|
|
221
165
|
elements.map[nodeId] = cyNode;
|
|
222
|
-
node2cyEdge(node, nodeId).forEach(
|
|
166
|
+
node2cyEdge(node, nodeId).forEach((edge) => {
|
|
223
167
|
elements.edges.push(edge);
|
|
224
168
|
});
|
|
225
169
|
// nested
|
|
226
170
|
if ("agent" in node && node.agent === "nestedAgent") {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
.filter(
|
|
230
|
-
.reduce(
|
|
231
|
-
if (
|
|
232
|
-
|
|
171
|
+
const graph = typeof node.graph === "string" ? JSON.parse(node.graph) : { ...node.graph };
|
|
172
|
+
const staticInputs = Object.keys(graph.nodes)
|
|
173
|
+
.filter((key) => "value" in graph.nodes[key])
|
|
174
|
+
.reduce((tmp, key) => {
|
|
175
|
+
if (graph.nodes[key].value[0] === ":") {
|
|
176
|
+
const { source } = parseInput(graph.nodes[key].value);
|
|
233
177
|
if (!tmp[source]) {
|
|
234
178
|
tmp[source] = [];
|
|
235
179
|
}
|
|
@@ -237,23 +181,23 @@ var cytoscapeFromGraph = function (_graph_data) {
|
|
|
237
181
|
}
|
|
238
182
|
return tmp;
|
|
239
183
|
}, {});
|
|
240
|
-
Object.keys(node.inputs).forEach(
|
|
241
|
-
if (!
|
|
242
|
-
|
|
184
|
+
Object.keys(node.inputs).forEach((parentInputNodeId) => {
|
|
185
|
+
if (!graph.nodes[parentInputNodeId]) {
|
|
186
|
+
graph.nodes[parentInputNodeId] = { value: "dummy" };
|
|
243
187
|
}
|
|
244
|
-
|
|
245
|
-
|
|
188
|
+
inputs2dataSources([node.inputs[parentInputNodeId]]).forEach((input) => {
|
|
189
|
+
const { source } = parseInput(input);
|
|
246
190
|
pushEdge({ source: nodeId, target: parentInputNodeId, label: source });
|
|
247
|
-
if (
|
|
248
|
-
|
|
191
|
+
if (staticInputs[parentInputNodeId]) {
|
|
192
|
+
staticInputs[parentInputNodeId].forEach((id) => {
|
|
249
193
|
pushEdge({ source: nodeId, target: id, label: parentInputNodeId });
|
|
250
194
|
});
|
|
251
195
|
}
|
|
252
196
|
});
|
|
253
197
|
});
|
|
254
|
-
toGraph(
|
|
255
|
-
Object.keys(
|
|
256
|
-
|
|
198
|
+
toGraph(graph);
|
|
199
|
+
Object.keys(graph.nodes).forEach((key) => {
|
|
200
|
+
const childNode = graph.nodes[key];
|
|
257
201
|
if ("agent" in childNode && childNode.isResult) {
|
|
258
202
|
pushEdge({ source: key, target: nodeId, label: "result", isResult: true });
|
|
259
203
|
}
|
|
@@ -262,54 +206,42 @@ var cytoscapeFromGraph = function (_graph_data) {
|
|
|
262
206
|
});
|
|
263
207
|
};
|
|
264
208
|
toGraph(_graph_data);
|
|
265
|
-
return { elements
|
|
209
|
+
return { elements };
|
|
266
210
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
elements = cytoscapeData.value.elements;
|
|
286
|
-
if (!elements.map[nodeId]) return [3 /*break*/, 4];
|
|
287
|
-
elements.map[nodeId].data.color = colorMap[state];
|
|
288
|
-
graph = selectedGraph.value;
|
|
289
|
-
nodeData = (_b = ((_a = graph === null || graph === void 0 ? void 0 : graph.nodes) !== null && _a !== void 0 ? _a : {})[nodeId]) !== null && _b !== void 0 ? _b : {};
|
|
290
|
-
if ("agent" in nodeData && state === graphai_1.NodeState.Queued && ((_c = nodeData.priority) !== null && _c !== void 0 ? _c : 0) > 0) {
|
|
291
|
-
// computed node
|
|
292
|
-
elements.map[nodeId].data.color = colorPriority;
|
|
293
|
-
}
|
|
294
|
-
else if ("value" in nodeData && state === graphai_1.NodeState.Waiting) {
|
|
295
|
-
// static node
|
|
296
|
-
elements.map[nodeId].data.color = colorStatic;
|
|
297
|
-
}
|
|
298
|
-
cytoscapeData.value = { elements: elements };
|
|
299
|
-
if (!(state === graphai_1.NodeState.Injected)) return [3 /*break*/, 4];
|
|
300
|
-
return [4 /*yield*/, (0, graphai_1.sleep)(100)];
|
|
301
|
-
case 3:
|
|
302
|
-
_d.sent();
|
|
303
|
-
elements.map[nodeId].data.color = colorStatic;
|
|
304
|
-
cytoscapeData.value = { elements: elements };
|
|
305
|
-
_d.label = 4;
|
|
306
|
-
case 4: return [2 /*return*/];
|
|
211
|
+
export const useCytoscape = (selectedGraph) => {
|
|
212
|
+
let cy = null;
|
|
213
|
+
const cytoscapeData = ref(cytoscapeFromGraph(selectedGraph.value ?? { nodes: {} }));
|
|
214
|
+
const cytoscapeRef = ref();
|
|
215
|
+
const zoomingEnabled = ref(true);
|
|
216
|
+
const updateCytoscape = async (log) => {
|
|
217
|
+
const { nodeId, state } = log;
|
|
218
|
+
if ([NodeState.Completed, NodeState.Waiting].includes(state)) {
|
|
219
|
+
await sleep(100);
|
|
220
|
+
}
|
|
221
|
+
const elements = cytoscapeData.value.elements;
|
|
222
|
+
if (elements.map[nodeId]) {
|
|
223
|
+
elements.map[nodeId].data.color = colorMap[state];
|
|
224
|
+
const graph = selectedGraph.value;
|
|
225
|
+
const nodeData = (graph?.nodes ?? {})[nodeId] ?? {};
|
|
226
|
+
if ("agent" in nodeData && state === NodeState.Queued && (nodeData.priority ?? 0) > 0) {
|
|
227
|
+
// computed node
|
|
228
|
+
elements.map[nodeId].data.color = colorPriority;
|
|
307
229
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
230
|
+
else if ("value" in nodeData && state === NodeState.Waiting) {
|
|
231
|
+
// static node
|
|
232
|
+
elements.map[nodeId].data.color = colorStatic;
|
|
233
|
+
}
|
|
234
|
+
cytoscapeData.value = { elements };
|
|
235
|
+
if (state === NodeState.Injected) {
|
|
236
|
+
await sleep(100);
|
|
237
|
+
elements.map[nodeId].data.color = colorStatic;
|
|
238
|
+
cytoscapeData.value = { elements };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const createCytoscape = () => {
|
|
311
243
|
try {
|
|
312
|
-
cy = (
|
|
244
|
+
cy = cytoscape({
|
|
313
245
|
container: cytoscapeRef.value,
|
|
314
246
|
style: cyStyle,
|
|
315
247
|
layout: {
|
|
@@ -331,67 +263,59 @@ var useCytoscape = function (selectedGraph) {
|
|
|
331
263
|
// error_msg.value = `${error}`;
|
|
332
264
|
}
|
|
333
265
|
};
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
cy.fit();
|
|
351
|
-
if (!(name_1 === layout)) return [3 /*break*/, 2];
|
|
352
|
-
return [4 /*yield*/, (0, graphai_1.sleep)(400)];
|
|
353
|
-
case 1:
|
|
354
|
-
_a.sent();
|
|
355
|
-
storePositions();
|
|
356
|
-
_a.label = 2;
|
|
357
|
-
case 2: return [2 /*return*/];
|
|
266
|
+
const updateGraphData = async () => {
|
|
267
|
+
if (cy) {
|
|
268
|
+
cy.elements().remove();
|
|
269
|
+
cy.add(cytoscapeData.value.elements);
|
|
270
|
+
const name = cytoscapeData.value.elements.nodes.reduce((prevName, node) => {
|
|
271
|
+
if (node.position) {
|
|
272
|
+
return "preset";
|
|
273
|
+
}
|
|
274
|
+
return prevName;
|
|
275
|
+
}, layout);
|
|
276
|
+
// console.log("layout", name);
|
|
277
|
+
cy.layout({ name }).run();
|
|
278
|
+
cy.fit();
|
|
279
|
+
if (name === layout) {
|
|
280
|
+
await sleep(400);
|
|
281
|
+
storePositions();
|
|
358
282
|
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const storePositions = () => {
|
|
362
286
|
// console.log("storePositions");
|
|
363
287
|
if (cy) {
|
|
364
|
-
cy.nodes().forEach(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
288
|
+
cy.nodes().forEach((cynode) => {
|
|
289
|
+
const id = cynode.id();
|
|
290
|
+
const pos = cynode.position();
|
|
291
|
+
const node = cytoscapeData.value.elements.map[id];
|
|
368
292
|
node.position = pos;
|
|
369
293
|
});
|
|
370
294
|
}
|
|
371
295
|
};
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
Object.keys(elements.map).forEach(
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
elements.map[nodeId].data.color = "value" in nodeData ? colorStatic : colorMap[
|
|
296
|
+
const resetCytoscape = () => {
|
|
297
|
+
const elements = cytoscapeData.value.elements;
|
|
298
|
+
Object.keys(elements.map).forEach((nodeId) => {
|
|
299
|
+
const graph = selectedGraph.value;
|
|
300
|
+
const nodeData = graph.nodes[nodeId];
|
|
301
|
+
elements.map[nodeId].data.color = "value" in nodeData ? colorStatic : colorMap[NodeState.Waiting];
|
|
378
302
|
});
|
|
379
|
-
cytoscapeData.value = { elements
|
|
303
|
+
cytoscapeData.value = { elements };
|
|
380
304
|
};
|
|
381
|
-
|
|
305
|
+
watch(cytoscapeData, () => {
|
|
382
306
|
console.log("updated");
|
|
383
307
|
updateGraphData();
|
|
384
308
|
});
|
|
385
|
-
|
|
309
|
+
watch(selectedGraph, () => {
|
|
386
310
|
cytoscapeData.value = cytoscapeFromGraph(selectedGraph.value);
|
|
387
311
|
});
|
|
388
|
-
|
|
312
|
+
onMounted(() => {
|
|
389
313
|
createCytoscape();
|
|
390
314
|
updateGraphData();
|
|
391
315
|
});
|
|
392
|
-
|
|
316
|
+
const layoutCytoscape = (key) => {
|
|
393
317
|
if (cy) {
|
|
394
|
-
|
|
318
|
+
const positions = cy.nodes().map((node) => {
|
|
395
319
|
return {
|
|
396
320
|
id: node.id(),
|
|
397
321
|
position: node.position(),
|
|
@@ -401,13 +325,13 @@ var useCytoscape = function (selectedGraph) {
|
|
|
401
325
|
localStorage.setItem("layoutData-" + key, JSON.stringify(positions));
|
|
402
326
|
}
|
|
403
327
|
};
|
|
404
|
-
|
|
405
|
-
|
|
328
|
+
const loadLayout = (key) => {
|
|
329
|
+
const savedLayoutData = localStorage.getItem("layoutData-" + key);
|
|
406
330
|
if (savedLayoutData) {
|
|
407
|
-
|
|
408
|
-
positions.forEach(
|
|
331
|
+
const positions = JSON.parse(savedLayoutData);
|
|
332
|
+
positions.forEach((data) => {
|
|
409
333
|
if (cy) {
|
|
410
|
-
|
|
334
|
+
const node = cy.getElementById(data.id);
|
|
411
335
|
if (node) {
|
|
412
336
|
node.position(data.position);
|
|
413
337
|
}
|
|
@@ -415,18 +339,17 @@ var useCytoscape = function (selectedGraph) {
|
|
|
415
339
|
});
|
|
416
340
|
}
|
|
417
341
|
};
|
|
418
|
-
|
|
342
|
+
watch(zoomingEnabled, (value) => {
|
|
419
343
|
if (cy) {
|
|
420
344
|
cy.zoomingEnabled(value);
|
|
421
345
|
}
|
|
422
346
|
});
|
|
423
347
|
return {
|
|
424
|
-
cytoscapeRef
|
|
425
|
-
updateCytoscape
|
|
426
|
-
resetCytoscape
|
|
427
|
-
layoutCytoscape
|
|
428
|
-
loadLayout
|
|
429
|
-
zoomingEnabled
|
|
348
|
+
cytoscapeRef,
|
|
349
|
+
updateCytoscape,
|
|
350
|
+
resetCytoscape,
|
|
351
|
+
layoutCytoscape,
|
|
352
|
+
loadLayout,
|
|
353
|
+
zoomingEnabled,
|
|
430
354
|
};
|
|
431
355
|
};
|
|
432
|
-
exports.useCytoscape = useCytoscape;
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@receptron/graphai_vue_cytoscape",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "lib/cytoscape.js",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"files": [
|
|
6
7
|
"./lib"
|
|
7
8
|
],
|
|
8
9
|
"scripts": {
|
|
9
10
|
"dev": "vite",
|
|
10
|
-
"build": "tsc
|
|
11
|
+
"build": "tsc -p tsconfig.build.json",
|
|
11
12
|
"preview": "vite preview",
|
|
12
13
|
"build-only": "vite build",
|
|
13
14
|
"type-check": "vue-tsc --build --force",
|
|
@@ -26,15 +27,15 @@
|
|
|
26
27
|
},
|
|
27
28
|
"homepage": "https://github.com/receptron/graphai_utils/tree/main/packages/vue-cytoscape#readme",
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"cytoscape": "^3.
|
|
30
|
+
"cytoscape": "^3.34.3",
|
|
30
31
|
"cytoscape-klay": "^3.1.4"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
|
-
"@types/cytoscape-klay": "^3.1.
|
|
34
|
-
"@vitejs/plugin-vue": "^
|
|
35
|
-
"@vue/tsconfig": "^0.
|
|
36
|
-
"vue": "^3.5.
|
|
37
|
-
"vue-tsc": "^
|
|
34
|
+
"@types/cytoscape-klay": "^3.1.5",
|
|
35
|
+
"@vitejs/plugin-vue": "^6.0.9",
|
|
36
|
+
"@vue/tsconfig": "^0.9.1",
|
|
37
|
+
"vue": "^3.5.43",
|
|
38
|
+
"vue-tsc": "^3.3.11"
|
|
38
39
|
},
|
|
39
40
|
"types": "./lib/cytoscape.d.ts",
|
|
40
41
|
"directories": {
|