Allow editing graph name
This commit is contained in:
parent
52aacec792
commit
8fdde5aeb4
|
@ -22,8 +22,11 @@ export class Box {
|
|||
}
|
||||
}
|
||||
|
||||
flex() {
|
||||
flex({ center = false } = {}) {
|
||||
this.addClass('flex');
|
||||
if (center) {
|
||||
this.addClass('flex-center');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,10 +42,11 @@ export class Button extends FormElement {
|
|||
export class TextField extends FormElement {
|
||||
constructor(name, form, opts) {
|
||||
super(name, form, opts);
|
||||
this.flex({ center: true });
|
||||
this.label = document.createElement('label');
|
||||
this.labelDiv = document.createElement('div');
|
||||
this.label.appendChild(this.labelDiv);
|
||||
this.labelDiv.innerHTML = name;
|
||||
this.labelDiv.innerHTML = opts.label || name;
|
||||
this.input = document.createElement('input');
|
||||
this.input.disabled = !!opts.disabled;
|
||||
this.input.defaultValue = opts.defaultValue || '';
|
||||
|
@ -99,9 +100,10 @@ export class FileInput extends FormElement {
|
|||
this.input = document.createElement('input');
|
||||
this.input.type = 'file';
|
||||
this.input.accept = 'application/json';
|
||||
// this.input.classList.add('visually-hidden')
|
||||
this.input.classList.add('visually-hidden');
|
||||
this.label = document.createElement('label');
|
||||
this.label.innerHTML = name;
|
||||
this.button = form.button({ name, cb: () => this.input.click() }).lastItem;
|
||||
this.label.appendChild(this.button.el);
|
||||
this.label.appendChild(this.input);
|
||||
this.el.appendChild(this.label);
|
||||
}
|
||||
|
@ -148,7 +150,7 @@ export class Form extends Box {
|
|||
}
|
||||
|
||||
fileInput(opts) {
|
||||
this.items.push(new FileInput(opts.label || opts.name, this, opts));
|
||||
this.items.push(new FileInput(opts.name, this, opts));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,14 +144,14 @@ export class Vertex {
|
|||
});
|
||||
|
||||
doc.remark('<h3>New Edge</h3>', { parentEl: form.el });
|
||||
const { subForm } = form.subForm({ name: 'newEdge' }).lastItem;
|
||||
subForm.textField({ name: 'to' });
|
||||
subForm.textField({ name: 'type' });
|
||||
subForm.textField({ name: 'weight' });
|
||||
subForm.button({
|
||||
const newEdgeForm = doc.form({ name: 'newEdge' }).lastElement;
|
||||
newEdgeForm.textField({ name: 'to' });
|
||||
newEdgeForm.textField({ name: 'type' });
|
||||
newEdgeForm.textField({ name: 'weight' });
|
||||
newEdgeForm.submit({
|
||||
name: 'Save',
|
||||
cb: ({ form: { value: { to, type, weight } } }) => {
|
||||
graph.addEdge(type, vertex, to, weight, null);
|
||||
graph.setEdgeWeight(type, vertex, to, weight, null);
|
||||
doc.clear();
|
||||
Edge.prepareEditorDocument(graph, doc, vertex.id, to);
|
||||
},
|
||||
|
@ -162,6 +162,7 @@ export class Vertex {
|
|||
id: 'cancel',
|
||||
name: 'Cancel',
|
||||
cb: () => graph.resetEditor(),
|
||||
parentEl: doc.el,
|
||||
});
|
||||
|
||||
return doc;
|
||||
|
|
|
@ -119,22 +119,29 @@ export class WeightedDirectedGraph {
|
|||
this.scene?.withSectionFlowchart();
|
||||
this.flowchart = this.scene?.lastFlowchart;
|
||||
if (this.editable) {
|
||||
this.controlDoc = new Document('WDGControl', this.flowchart.box.el, { prepend: true });
|
||||
this.editorDoc = new Document('WDGEditor', this.flowchart.box.el);
|
||||
this.errorDoc = new Document('WDGErrors', this.flowchart.box.el);
|
||||
this.controlDoc = new Document('WDGControl', this.flowchart.box.el, { prepend: true });
|
||||
this.resetEditor();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
resetEditor() {
|
||||
this.editorDoc.clear();
|
||||
this.controlDoc.clear();
|
||||
Vertex.prepareEditorDocument(this, this.editorDoc);
|
||||
prepareControlDoc() {
|
||||
const form = this.controlDoc.form({ name: 'controlForm' }).lastElement;
|
||||
form.button({
|
||||
name: 'Download',
|
||||
label: 'Export',
|
||||
const { subForm: graphPropertiesForm } = form.subForm({ name: 'graphPropsForm' }).lastItem;
|
||||
graphPropertiesForm.flex()
|
||||
.textField({ name: 'name', label: 'Graph name', defaultValue: this.name })
|
||||
.submit({
|
||||
name: 'Save',
|
||||
cb: (({ form: { value: { name } } }) => {
|
||||
this.name = name;
|
||||
}),
|
||||
});
|
||||
const { subForm: exportImportForm } = form.subForm({ name: 'exportImportForm' }).lastItem;
|
||||
exportImportForm.flex()
|
||||
.button({
|
||||
name: 'Export',
|
||||
cb: () => {
|
||||
const a = window.document.createElement('a');
|
||||
const json = JSON.stringify(this.toJSON(), null, 2);
|
||||
|
@ -144,12 +151,14 @@ export class WeightedDirectedGraph {
|
|||
a.download = `wdg_${this.name}_${currentTime}.json`;
|
||||
a.click();
|
||||
},
|
||||
});
|
||||
form.fileInput({
|
||||
label: 'Import',
|
||||
})
|
||||
.fileInput({
|
||||
name: 'Import',
|
||||
cb: ({ input: { files: [file] } }) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = ({ target: { result: text } }) => {
|
||||
console.log('imported file', { file });
|
||||
// this.flowchart?.log(`%% Imported file ${file}`)
|
||||
const data = JSON.parse(text);
|
||||
this.fromJSON(data);
|
||||
};
|
||||
|
@ -158,6 +167,13 @@ export class WeightedDirectedGraph {
|
|||
});
|
||||
}
|
||||
|
||||
resetEditor() {
|
||||
this.editorDoc.clear();
|
||||
this.controlDoc.clear();
|
||||
this.prepareControlDoc();
|
||||
Vertex.prepareEditorDocument(this, this.editorDoc);
|
||||
}
|
||||
|
||||
addVertex(type, id, data, label, options) {
|
||||
// Supports simple case of auto-incremented numeric ids
|
||||
if (typeof id === 'object') {
|
||||
|
@ -220,10 +236,10 @@ export class WeightedDirectedGraph {
|
|||
addEdge(type, from, to, weight, data, options) {
|
||||
from = from instanceof Vertex ? from : this.getVertex(from);
|
||||
to = to instanceof Vertex ? to : this.getVertex(to);
|
||||
const existingEdges = this.getEdges(type, from, to);
|
||||
if (this.getEdge(type, from, to)) {
|
||||
throw new Error(`Edge ${type} from ${from.id} to ${to.id} already exists`);
|
||||
}
|
||||
const existingEdges = this.getEdges(null, from, to);
|
||||
const edge = this.setEdgeWeight(type, from, to, weight, data, options);
|
||||
from.edges.from.push(edge);
|
||||
to.edges.to.push(edge);
|
||||
|
|
|
@ -26,6 +26,9 @@ a:visited {
|
|||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
}
|
||||
.monospace {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
@ -44,8 +47,8 @@ a:visited {
|
|||
}
|
||||
.scene-controls {
|
||||
position: relative;
|
||||
left: 15em;
|
||||
top: -1em;
|
||||
left: 12em;
|
||||
top: -0.5em;
|
||||
}
|
||||
svg {
|
||||
width: 800px;
|
||||
|
@ -61,19 +64,20 @@ td {
|
|||
fill: #216262 !important;
|
||||
}
|
||||
button {
|
||||
margin: 5px;
|
||||
margin-top: 1em;
|
||||
background-color: #c6f4ff;
|
||||
border-color: #b6b6b6;
|
||||
border-radius: 5px;
|
||||
}
|
||||
input {
|
||||
margin: 1pt;
|
||||
}
|
||||
button, input[type=file] {
|
||||
border-radius: 4pt;
|
||||
margin: 4pt;
|
||||
}
|
||||
button:disabled {
|
||||
background-color: #2a535e;
|
||||
color: #919191;
|
||||
}
|
||||
label > input {
|
||||
margin-left: 1em;
|
||||
}
|
||||
label {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
|
@ -82,7 +86,8 @@ label {
|
|||
}
|
||||
label > div {
|
||||
display: inline-block;
|
||||
min-width: 50px;
|
||||
min-width: 5em;
|
||||
margin-right: 4pt;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
|
|
Loading…
Reference in New Issue