139 lines
3.8 KiB
JavaScript
139 lines
3.8 KiB
JavaScript
export class Edge {
|
|
constructor(graph, type, from, to, weight, data, options = {}) {
|
|
this.graph = graph;
|
|
this.from = from;
|
|
this.to = to;
|
|
this.type = type;
|
|
this.weight = weight;
|
|
this.data = data;
|
|
this.options = options;
|
|
this.installedClickCallback = false;
|
|
}
|
|
|
|
reset() {
|
|
this.installedClickCallback = false;
|
|
}
|
|
|
|
static getKey({
|
|
from, to, type,
|
|
}) {
|
|
return ['edge', from.id, to.id, type].join(':');
|
|
}
|
|
|
|
static getCombinedKey({ from, to }) {
|
|
return ['edge', from.id, to.id].join(':');
|
|
}
|
|
|
|
getComorphicEdges() {
|
|
return this.graph.getEdges(null, this.from, this.to);
|
|
}
|
|
|
|
getHtml() {
|
|
const edges = this.getComorphicEdges();
|
|
let html = '';
|
|
html += '<table>';
|
|
for (const { type, weight } of edges) {
|
|
html += `<tr><td>${type}</td><td>${weight}</td></tr>`;
|
|
}
|
|
html += '</table>';
|
|
|
|
return html;
|
|
}
|
|
|
|
getFlowchartNode() {
|
|
return `${Edge.getCombinedKey(this)}("${this.getHtml()}")`;
|
|
}
|
|
|
|
displayEdgeNode() {
|
|
if (this.options.hide) {
|
|
return;
|
|
}
|
|
this.graph.flowchart?.log(this.getFlowchartNode());
|
|
}
|
|
|
|
displayEdge() {
|
|
if (this.options.hide) {
|
|
return;
|
|
}
|
|
this.graph.flowchart?.log(`${this.from.id} --- ${this.getFlowchartNode()} --> ${this.to.id}`);
|
|
this.graph.flowchart?.log(`class ${Edge.getCombinedKey(this)} edge`);
|
|
if (this.graph.editable && !this.installedClickCallback) {
|
|
this.graph.flowchart?.log(`click ${Edge.getCombinedKey(this)} WDGHandler${this.graph.index} \
|
|
"Edit Edge ${this.from.id} -> ${this.to.id}"`);
|
|
this.installedClickCallback = true;
|
|
}
|
|
}
|
|
|
|
static prepareEditorDocument(graph, doc, from, to) {
|
|
const form = doc.form({ name: 'editorForm' }).lastElement;
|
|
doc.remark('<h3>Edit Edge</h3>', { parentEl: form.el });
|
|
form
|
|
.textField({
|
|
id: 'from', name: 'from', defaultValue: from, disabled: true,
|
|
})
|
|
.textField({
|
|
id: 'to', name: 'to', defaultValue: to, disabled: true,
|
|
});
|
|
|
|
doc.remark('<h4>Edge Types</h4>', { parentEl: form.el });
|
|
const subFormArray = form.subFormArray({ id: 'edges', name: 'edges' }).lastItem;
|
|
|
|
const addEdgeForm = (edge) => {
|
|
const { subForm } = form.subForm({ name: 'subform', subFormArray }).lastItem;
|
|
subForm.textField({
|
|
id: 'type', name: 'type', defaultValue: edge.type, required: true,
|
|
})
|
|
.textField({
|
|
id: 'weight', name: 'weight', defaultValue: edge.weight, required: true,
|
|
})
|
|
.button({
|
|
id: 'remove',
|
|
name: 'Remove Edge Type',
|
|
cb: () => subFormArray.remove(subForm),
|
|
});
|
|
doc.remark('<br>', { parentEl: subForm.el });
|
|
};
|
|
|
|
for (const edge of graph.getEdges(null, from, to)) {
|
|
addEdgeForm(edge);
|
|
}
|
|
|
|
form.button({
|
|
id: 'add',
|
|
name: 'Add Edge Type',
|
|
cb: () => addEdgeForm(new Edge(graph, null, graph.getVertex(from), graph.getVertex(to))),
|
|
})
|
|
.button({
|
|
id: 'save',
|
|
name: 'Save',
|
|
type: 'submit',
|
|
cb: ({ form: { value: { edges } } }) => {
|
|
// Do validation
|
|
for (const { type, weight } of edges) {
|
|
if (type === null || weight === null) {
|
|
graph.errorDoc.remark('<pre>type and weight are required</pre>');
|
|
return;
|
|
}
|
|
}
|
|
// Handle additions and updates
|
|
for (const { type, weight } of edges) {
|
|
graph.setEdgeWeight(type, from, to, weight);
|
|
}
|
|
// Handle removals
|
|
for (const edge of graph.getEdges(null, from, to)) {
|
|
if (!edges.find(({ type }) => type === edge.type)) {
|
|
graph.deleteEdge(edge.type, from, to);
|
|
}
|
|
}
|
|
graph.redraw();
|
|
graph.errorDoc.clear();
|
|
},
|
|
})
|
|
.button({
|
|
id: 'cancel',
|
|
name: 'Cancel',
|
|
cb: () => graph.resetEditorDocument(),
|
|
});
|
|
}
|
|
}
|