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