123 lines
3.0 KiB
JavaScript
123 lines
3.0 KiB
JavaScript
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs';
|
|
import { debounce } from '../util.js';
|
|
|
|
export class Vertex {
|
|
constructor(data) {
|
|
this.data = data;
|
|
this.edges = {
|
|
from: [],
|
|
to: [],
|
|
};
|
|
}
|
|
|
|
getEdges(label, away) {
|
|
return this.edges[away ? 'from' : 'to'].filter(
|
|
(edge) => edge.label === label,
|
|
);
|
|
}
|
|
}
|
|
|
|
export class Edge {
|
|
constructor(label, from, to, data) {
|
|
this.from = from;
|
|
this.to = to;
|
|
this.label = label;
|
|
this.data = data;
|
|
}
|
|
}
|
|
|
|
export class CategorizedEdges {}
|
|
|
|
export class Graph {
|
|
constructor() {
|
|
this.vertices = new Map();
|
|
this.edgeLabels = new Map();
|
|
this.nextVertexId = 0;
|
|
}
|
|
|
|
addVertex(id, data) {
|
|
// Support simple case of auto-incremented numeric ids
|
|
if (typeof id === 'object') {
|
|
data = id;
|
|
id = this.nextVertexId++;
|
|
}
|
|
if (this.vertices.has(id)) {
|
|
throw new Error(`Vertex already exists with id: ${id}`);
|
|
}
|
|
const vertex = new Vertex(data);
|
|
console.log('addVertex', vertex);
|
|
this.vertices.set(id, vertex);
|
|
return this;
|
|
}
|
|
|
|
getVertex(id) {
|
|
return this.vertices.get(id);
|
|
}
|
|
|
|
getVertexData(id) {
|
|
return this.getVertex(id)?.data;
|
|
}
|
|
|
|
getVertices() {
|
|
return Array.from(this.vertices.values()).map(({ data }) => data);
|
|
}
|
|
|
|
getEdge(label, from, to) {
|
|
const edges = this.edgeLabels.get(label);
|
|
return edges?.get(JSON.stringify({ from, to }));
|
|
}
|
|
|
|
setEdge(label, from, to, edge) {
|
|
let edges = this.edgeLabels.get(label);
|
|
if (!edges) {
|
|
edges = new Map();
|
|
this.edgeLabels.set(label, edges);
|
|
}
|
|
edges.set(JSON.stringify({ from, to }), edge);
|
|
}
|
|
|
|
addEdge(label, from, to, data) {
|
|
console.log('addEdge', { from, to });
|
|
if (this.getEdge(label, from, to)) {
|
|
throw new Error(`Edge ${label} from ${from} to ${to} already exists`);
|
|
}
|
|
const edge = new Edge(label, from, to, data);
|
|
this.setEdge(label, from, to, edge);
|
|
this.getVertex(from).edges.from.push(edge);
|
|
this.getVertex(to).edges.to.push(edge);
|
|
return this;
|
|
}
|
|
|
|
getEdges(label, from, to) {
|
|
const edgeLabels = label ? [label] : Array.from(this.edgeLabels.keys());
|
|
return edgeLabels.flatMap((edgeLabel) => {
|
|
const edges = this.edgeLabels.get(edgeLabel);
|
|
return Array.from(edges?.values() || []).filter((edge) => {
|
|
const matchFrom = from === null || from === undefined || from === edge.from;
|
|
const matchTo = to === null || to === undefined || to === edge.to;
|
|
return matchFrom && matchTo;
|
|
});
|
|
});
|
|
}
|
|
|
|
countVertices() {
|
|
return this.vertices.size;
|
|
}
|
|
|
|
async renderGraph() {
|
|
const render = async () => {
|
|
const dateStart = new Date();
|
|
const graph = await mermaid.mermaidAPI.render(
|
|
this.seqDiagramElement.getId(),
|
|
this.logBox.getInnerText(),
|
|
);
|
|
this.seqDiagramBox.setInnerHTML(graph);
|
|
if (!this.dateLastRender) {
|
|
this.dateLastRender = new Date();
|
|
}
|
|
this.dateLastRender = dateStart;
|
|
};
|
|
debounce(render, 100);
|
|
}
|
|
}
|