117 lines
3.3 KiB
JavaScript
117 lines
3.3 KiB
JavaScript
// The Lucia project.
|
|
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
|
// Authors:
|
|
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
|
// imacat.yang@dsp.im (imacat), 2023/9/23
|
|
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
|
/**
|
|
* @module cytoscapeMapTrace Cytoscape.js process map rendering for
|
|
* individual trace visualization.
|
|
*/
|
|
|
|
import cytoscape from "cytoscape";
|
|
import dagre from "cytoscape-dagre";
|
|
import tippy from "tippy.js";
|
|
import "tippy.js/dist/tippy.css";
|
|
import { createTooltipContent } from "@/module/tooltipContent.js";
|
|
|
|
cytoscape.use(dagre);
|
|
|
|
/**
|
|
* Creates a Cytoscape.js instance for rendering a single trace's
|
|
* process map with left-to-right dagre layout and tooltips.
|
|
*
|
|
* @param {Array<Object>} nodes - Array of node data objects with
|
|
* backgroundColor, bordercolor, height, id, label, shape, and width.
|
|
* @param {Array<Object>} edges - Array of edge data objects.
|
|
* @param {HTMLElement} graphId - The DOM container element for Cytoscape.
|
|
*/
|
|
export default function cytoscapeMapTrace(nodes, edges, graphId) {
|
|
// create Cytoscape
|
|
let cy = cytoscape({
|
|
container: graphId,
|
|
elements: {
|
|
nodes: nodes, // Node data
|
|
edges: edges, // Edge data
|
|
},
|
|
layout: {
|
|
name: "dagre",
|
|
rankDir: "LR", // Vertical TB | Horizontal LR, variable from 'cytoscape-dagre' plugin
|
|
},
|
|
style: [
|
|
// Node styling
|
|
{
|
|
selector: "node",
|
|
style: {
|
|
label: function (node) {
|
|
// Text to display on the node
|
|
let text = "";
|
|
|
|
// node.data('label') accesses the original array value at node.data.label
|
|
text =
|
|
node.data("label").length > 18
|
|
? `${node.data("label").substr(0, 15)}...`
|
|
: `${node.data("label")}`;
|
|
|
|
return text;
|
|
},
|
|
"text-opacity": 0.7,
|
|
"background-color": "data(backgroundColor)",
|
|
"border-color": "data(bordercolor)",
|
|
"border-width": "1",
|
|
shape: "data(shape)",
|
|
"text-wrap": "wrap",
|
|
"text-max-width": 75,
|
|
"text-halign": "center",
|
|
"text-valign": "center",
|
|
height: "data(height)",
|
|
width: "data(width)",
|
|
color: "#001933",
|
|
"font-size": 14,
|
|
},
|
|
},
|
|
// Edge styling
|
|
{
|
|
selector: "edge",
|
|
style: {
|
|
"curve-style": "taxi", // unbundled-bezier | taxi
|
|
"target-arrow-shape": "triangle", // Arrow shape pointing to target: triangle
|
|
color: "gray", //#0066cc
|
|
width: "data(lineWidth)",
|
|
"line-style": "data(style)",
|
|
},
|
|
},
|
|
// Style changes when a node is selected
|
|
{
|
|
selector: "node:selected",
|
|
style: {
|
|
"border-color": "red",
|
|
"border-width": "3",
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
// creat tippy.js
|
|
let tip;
|
|
cy.on("mouseover", "node", function (event) {
|
|
tip?.destroy();
|
|
const node = event.target;
|
|
let ref = node.popperRef();
|
|
let dummyDomEle = document.createElement("div");
|
|
let content = createTooltipContent(node.data("label"));
|
|
tip = new tippy(dummyDomEle, {
|
|
// tippy props:
|
|
getReferenceClientRect: ref.getBoundingClientRect,
|
|
trigger: "manual",
|
|
content: content,
|
|
});
|
|
tip.show();
|
|
});
|
|
cy.on("mouseout", "node", function (event) {
|
|
tip?.destroy();
|
|
tip = null;
|
|
});
|
|
return cy;
|
|
}
|