diff --git a/src/classes/display/box.js b/src/classes/display/box.js
index 082bff5..b25746c 100644
--- a/src/classes/display/box.js
+++ b/src/classes/display/box.js
@@ -22,8 +22,11 @@ export class Box {
}
}
- flex() {
+ flex({ center = false } = {}) {
this.addClass('flex');
+ if (center) {
+ this.addClass('flex-center');
+ }
return this;
}
diff --git a/src/classes/display/form.js b/src/classes/display/form.js
index ee794d7..1b20f6e 100644
--- a/src/classes/display/form.js
+++ b/src/classes/display/form.js
@@ -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;
}
diff --git a/src/classes/supporting/vertex.js b/src/classes/supporting/vertex.js
index 9d705f0..1137bf6 100644
--- a/src/classes/supporting/vertex.js
+++ b/src/classes/supporting/vertex.js
@@ -144,14 +144,14 @@ export class Vertex {
});
doc.remark('
New Edge
', { 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;
diff --git a/src/classes/supporting/wdg.js b/src/classes/supporting/wdg.js
index 762c050..c454279 100644
--- a/src/classes/supporting/wdg.js
+++ b/src/classes/supporting/wdg.js
@@ -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);
diff --git a/src/index.css b/src/index.css
index b41b51c..cfa67b0 100644
--- a/src/index.css
+++ b/src/index.css
@@ -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%;