Allow editing graph name

This commit is contained in:
Ladd Hoffman 2023-07-11 22:44:05 -05:00
parent 52aacec792
commit 8fdde5aeb4
5 changed files with 74 additions and 47 deletions

View File

@ -22,8 +22,11 @@ export class Box {
}
}
flex() {
flex({ center = false } = {}) {
this.addClass('flex');
if (center) {
this.addClass('flex-center');
}
return this;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -119,43 +119,59 @@ 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;
}
prepareControlDoc() {
const form = this.controlDoc.form({ name: 'controlForm' }).lastElement;
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);
const currentTime = Math.floor(new Date().getTime() / 1000);
a.href = `data:attachment/text,${encodeURI(json)}`;
a.target = '_blank';
a.download = `wdg_${this.name}_${currentTime}.json`;
a.click();
},
})
.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);
};
reader.readAsText(file);
},
});
}
resetEditor() {
this.editorDoc.clear();
this.controlDoc.clear();
this.prepareControlDoc();
Vertex.prepareEditorDocument(this, this.editorDoc);
const form = this.controlDoc.form({ name: 'controlForm' }).lastElement;
form.button({
name: 'Download',
label: 'Export',
cb: () => {
const a = window.document.createElement('a');
const json = JSON.stringify(this.toJSON(), null, 2);
const currentTime = Math.floor(new Date().getTime() / 1000);
a.href = `data:attachment/text,${encodeURI(json)}`;
a.target = '_blank';
a.download = `wdg_${this.name}_${currentTime}.json`;
a.click();
},
});
form.fileInput({
label: 'Import',
cb: ({ input: { files: [file] } }) => {
const reader = new FileReader();
reader.onload = ({ target: { result: text } }) => {
const data = JSON.parse(text);
this.fromJSON(data);
};
reader.readAsText(file);
},
});
}
addVertex(type, id, data, label, options) {
@ -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);

View File

@ -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%;