Able to add new vertices
This commit is contained in:
parent
07370be4fa
commit
a743a81218
|
@ -1,10 +1,11 @@
|
|||
import { MermaidDiagram } from './mermaid.js';
|
||||
|
||||
export class Flowchart extends MermaidDiagram {
|
||||
constructor(box, logBox, direction = 'BT') {
|
||||
constructor(box, logBox, { direction = 'BT' } = {}) {
|
||||
super(box, logBox);
|
||||
this.direction = direction;
|
||||
this.init();
|
||||
this.controlBox = this.box.addBox('Controls');
|
||||
}
|
||||
|
||||
init() {
|
||||
|
|
|
@ -9,7 +9,6 @@ export class MermaidDiagram {
|
|||
this.renderBox = this.box.addBox('Render');
|
||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.logBoxPre = logBox.el.appendChild(document.createElement('pre'));
|
||||
this.inSection = 0;
|
||||
}
|
||||
|
||||
static initializeAPI() {
|
||||
|
@ -20,10 +19,8 @@ export class MermaidDiagram {
|
|||
darkMode: true,
|
||||
primaryColor: '#2a5b6c',
|
||||
primaryTextColor: '#b6b6b6',
|
||||
// lineColor: '#349cbd',
|
||||
lineColor: '#57747d',
|
||||
signalColor: '#57747d',
|
||||
// signalColor: '#349cbd',
|
||||
noteBkgColor: '#516f77',
|
||||
noteTextColor: '#cecece',
|
||||
activationBkgColor: '#1d3f49',
|
||||
|
|
|
@ -47,26 +47,27 @@ export class Scene {
|
|||
}
|
||||
|
||||
withFlowchart({ direction = 'BT' } = {}) {
|
||||
const box = this.topSection.addBox('Flowchart').addClass('padded');
|
||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
const logBox = this.box.addBox('Flowchart text').addClass('dim');
|
||||
this.flowchart = new Flowchart(box, logBox, direction);
|
||||
this.withSectionFlowchart({ direction, section: this.topSection });
|
||||
this.flowchart = this.lastFlowchart;
|
||||
return this;
|
||||
}
|
||||
|
||||
withAdditionalFlowchart({ id, name, direction = 'BT' } = {}) {
|
||||
withSectionFlowchart({
|
||||
id, name, direction = 'BT', section,
|
||||
} = {}) {
|
||||
section = section ?? this.middleSection;
|
||||
const index = this.flowcharts.size;
|
||||
name = name ?? `Flowchart ${index}`;
|
||||
id = id ?? `flowchart_${CryptoUtil.randomUUID().slice(0, 4)}`;
|
||||
const container = this.middleSection.addBox(name).flex();
|
||||
const container = section.addBox(name).flex();
|
||||
const box = container.addBox('Flowchart').addClass('padded');
|
||||
const logBox = container.addBox('Flowchart text').addClass('dim');
|
||||
const flowchart = new Flowchart(box, logBox, direction);
|
||||
const flowchart = new Flowchart(box, logBox, { direction });
|
||||
this.flowcharts.set(id, flowchart);
|
||||
return this;
|
||||
}
|
||||
|
||||
lastFlowchart() {
|
||||
get lastFlowchart() {
|
||||
if (!this.flowcharts.size) {
|
||||
if (this.flowchart) {
|
||||
return this.flowchart;
|
||||
|
|
|
@ -117,7 +117,7 @@ export class Edge {
|
|||
.button({
|
||||
id: 'cancel',
|
||||
name: 'Cancel',
|
||||
cb: () => doc.clear(),
|
||||
cb: () => graph.resetEditorDocument(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,18 +54,15 @@ export class Vertex {
|
|||
|
||||
static prepareEditorDocument(graph, doc, vertexId) {
|
||||
doc.clear();
|
||||
const vertex = graph.getVertex(vertexId);
|
||||
if (!vertex) {
|
||||
throw new Error(`Could not find WDG Vertex ${vertexId}`);
|
||||
}
|
||||
const vertex = vertexId ? graph.getVertex(vertexId) : undefined;
|
||||
const form = doc.form().lastElement;
|
||||
doc.remark('<h3>Edit Vertex</h3>', { parentEl: form.el });
|
||||
doc.remark(`<h3>${vertex ? 'Edit' : 'Add'} Vertex</h3>`, { parentEl: form.el });
|
||||
form
|
||||
.textField({
|
||||
id: 'id', name: 'id', defaultValue: vertex.id,
|
||||
id: 'id', name: 'id', defaultValue: vertex?.id,
|
||||
})
|
||||
.textField({ id: 'type', name: 'type', defaultValue: vertex.type })
|
||||
.textField({ id: 'label', name: 'label', defaultValue: vertex.label });
|
||||
.textField({ id: 'type', name: 'type', defaultValue: vertex?.type })
|
||||
.textField({ id: 'label', name: 'label', defaultValue: vertex?.label });
|
||||
|
||||
doc.remark('<h4>Properties</h4>', { parentEl: form.el });
|
||||
const subFormArray = form.subFormArray({ id: 'properties', name: 'properties' }).lastItem;
|
||||
|
@ -81,8 +78,10 @@ export class Vertex {
|
|||
doc.remark('<br>', { parentEl: subForm.el });
|
||||
};
|
||||
|
||||
for (const [key, value] of vertex.properties.entries()) {
|
||||
addPropertyForm(key, value);
|
||||
if (vertex) {
|
||||
for (const [key, value] of vertex.properties.entries()) {
|
||||
addPropertyForm(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
form.button({
|
||||
|
@ -92,26 +91,34 @@ export class Vertex {
|
|||
})
|
||||
.button({
|
||||
id: 'save',
|
||||
name: 'Save',
|
||||
name: this.id ? 'Save' : 'Add',
|
||||
type: 'submit',
|
||||
cb: ({ form: { value: formValue } }) => {
|
||||
let fullRedraw = false;
|
||||
if (formValue.id !== vertex.id) {
|
||||
if (vertex && formValue.id !== vertex.id) {
|
||||
fullRedraw = true;
|
||||
}
|
||||
// TODO: preserve data types of properties
|
||||
formValue.properties = new Map(formValue.properties.map(({ key, value }) => [key, value]));
|
||||
Object.assign(vertex, formValue);
|
||||
vertex.displayVertex();
|
||||
if (vertex) {
|
||||
Object.assign(vertex, formValue);
|
||||
vertex.displayVertex();
|
||||
} else {
|
||||
graph.addVertex(formValue.type, formValue.id, null, formValue.label);
|
||||
}
|
||||
if (fullRedraw) {
|
||||
graph.redraw();
|
||||
}
|
||||
if (!vertex) {
|
||||
// This was a new vertex. Now let's edit.
|
||||
Vertex.prepareEditorDocument(graph, doc, formValue.id);
|
||||
}
|
||||
},
|
||||
})
|
||||
.button({
|
||||
id: 'cancel',
|
||||
name: 'Cancel',
|
||||
cb: () => doc.clear(),
|
||||
cb: () => graph.resetEditorDocument(),
|
||||
});
|
||||
return doc;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Vertex } from './vertex.js';
|
||||
import { Edge } from './edge.js';
|
||||
import { Document } from '../display/document.js';
|
||||
|
||||
const graphs = [];
|
||||
const allGraphs = [];
|
||||
|
||||
const makeWDGHandler = (graphIndex) => (vertexId) => {
|
||||
const graph = graphs[graphIndex];
|
||||
const graph = allGraphs[graphIndex];
|
||||
// We want a document for editing this node, which may be a vertex or an edge
|
||||
const editorDoc = graph.scene.getDocument('editorDocument')
|
||||
?? graph.scene.withDocument('editorDocument').lastDocument;
|
||||
const { editorDoc } = graph;
|
||||
if (vertexId.startsWith('edge:')) {
|
||||
const [, from, to] = vertexId.split(':');
|
||||
Edge.prepareEditorDocument(graph, editorDoc, from, to);
|
||||
|
@ -22,14 +22,17 @@ export class WeightedDirectedGraph {
|
|||
this.vertices = new Map();
|
||||
this.edgeTypes = new Map();
|
||||
this.nextVertexId = 0;
|
||||
this.flowchart = scene?.flowchart;
|
||||
this.flowchart = undefined;
|
||||
this.editable = options.editable;
|
||||
this.index = graphs.length;
|
||||
graphs.push(this);
|
||||
|
||||
// Mermaid supports a click callback, but we can't customize arguments; we just get the vertex ID.
|
||||
// In order to provide the appropriate graph context for each callback, we create a separate callback
|
||||
// function for each graph.
|
||||
this.index = allGraphs.length;
|
||||
allGraphs.push(this);
|
||||
window[`WDGHandler${this.index}`] = makeWDGHandler(this.index);
|
||||
|
||||
// TODO: Populate history
|
||||
this.history = {};
|
||||
}
|
||||
|
||||
|
@ -88,11 +91,19 @@ export class WeightedDirectedGraph {
|
|||
}
|
||||
|
||||
withFlowchart() {
|
||||
this.scene?.withAdditionalFlowchart();
|
||||
this.flowchart = this.scene?.lastFlowchart();
|
||||
this.scene?.withSectionFlowchart();
|
||||
this.flowchart = this.scene?.lastFlowchart;
|
||||
if (this.editable) {
|
||||
this.editorDoc = new Document('Controls', this.flowchart.controlBox.el);
|
||||
this.resetEditorDocument();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
resetEditorDocument() {
|
||||
Vertex.prepareEditorDocument(this, this.editorDoc);
|
||||
}
|
||||
|
||||
addVertex(type, id, data, label, options) {
|
||||
// Supports simple case of auto-incremented numeric ids
|
||||
if (typeof id === 'object') {
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('Document > Form > TextField', () => {
|
|||
doc.remark('Hmm...!');
|
||||
});
|
||||
// it('can exist within a graph', () => {
|
||||
// scene.withAdditionalFlowchart({ id: 'flowchart', name: 'Graph' });
|
||||
// scene.withSectionFlowchart({ id: 'flowchart', name: 'Graph' });
|
||||
// const graph = scene.lastFlowchart();
|
||||
// });
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue