Enable wdg import

This commit is contained in:
Ladd Hoffman 2023-07-11 12:53:40 -05:00
parent b610484e49
commit 496c132b82
5 changed files with 122 additions and 10 deletions

View File

@ -26,9 +26,16 @@ export class Button extends FormElement {
this.button.setAttribute('type', opts.type ?? 'button'); this.button.setAttribute('type', opts.type ?? 'button');
this.button.innerHTML = name; this.button.innerHTML = name;
this.button.disabled = !!opts.disabled; this.button.disabled = !!opts.disabled;
if (opts.label) {
this.label = document.createElement('label');
this.label.innerHTML = opts.label;
this.label.appendChild(this.button);
this.el.appendChild(this.label);
} else {
this.el.appendChild(this.button); this.el.appendChild(this.button);
} }
} }
}
export class TextField extends FormElement { export class TextField extends FormElement {
constructor(name, form, opts) { constructor(name, form, opts) {
@ -84,6 +91,20 @@ export class SubForm extends FormElement {
} }
} }
export class FileInput extends FormElement {
constructor(name, form, opts) {
super(name, form, opts);
this.input = document.createElement('input');
this.input.type = 'file';
this.input.accept = 'application/json';
// this.input.classList.add('visually-hidden')
this.label = document.createElement('label');
this.label.innerHTML = name;
this.label.appendChild(this.input);
this.el.appendChild(this.label);
}
}
export class Form extends Box { export class Form extends Box {
constructor(document, opts = {}) { constructor(document, opts = {}) {
super(opts.name, opts.parentEl || document.el, { tagName: 'form', ...opts }); super(opts.name, opts.parentEl || document.el, { tagName: 'form', ...opts });
@ -99,6 +120,11 @@ export class Form extends Box {
return this; return this;
} }
submit(opts) {
this.items.push(new Button(opts.name, this, { ...opts, type: 'submit' }));
return this;
}
textField(opts) { textField(opts) {
this.items.push(new TextField(opts.name, this, opts)); this.items.push(new TextField(opts.name, this, opts));
return this; return this;
@ -119,6 +145,11 @@ export class Form extends Box {
return this; return this;
} }
fileInput(opts) {
this.items.push(new FileInput(opts.label || opts.name, this, opts));
return this;
}
get lastItem() { get lastItem() {
return this.items[this.items.length - 1]; return this.items[this.items.length - 1];
} }

View File

@ -112,10 +112,9 @@ export class Edge {
name: 'Add Edge Type', name: 'Add Edge Type',
cb: () => addEdgeForm(new Edge(graph, null, graph.getVertex(from), graph.getVertex(to))), cb: () => addEdgeForm(new Edge(graph, null, graph.getVertex(from), graph.getVertex(to))),
}) })
.button({ .submit({
id: 'save', id: 'save',
name: 'Save', name: 'Save',
type: 'submit',
cb: ({ form: { value: { edges } } }) => { cb: ({ form: { value: { edges } } }) => {
// Do validation // Do validation
for (const { type, weight } of edges) { for (const { type, weight } of edges) {

View File

@ -108,10 +108,9 @@ export class Vertex {
cb: () => addPropertyForm('', ''), cb: () => addPropertyForm('', ''),
}); });
form.button({ form.submit({
id: 'save', id: 'save',
name: 'Save', name: 'Save',
type: 'submit',
cb: ({ form: { value: formValue } }) => { cb: ({ form: { value: formValue } }) => {
let fullRedraw = false; let fullRedraw = false;
if (vertex && formValue.id !== vertex.id) { if (vertex && formValue.id !== vertex.id) {

View File

@ -45,15 +45,36 @@ export class WeightedDirectedGraph {
toJSON() { toJSON() {
return { return {
name: this.name,
vertices: Array.from(this.vertices.values()) vertices: Array.from(this.vertices.values())
.map((vertex) => vertex.toJSON()), .map((vertex) => vertex.toJSON()),
edges: Array.from(this.edgeTypes.values()) edges: Array.from(this.edgeTypes.values())
.flatMap((edges) => Array.from(edges.values())) .flatMap((edges) => Array.from(edges.values()))
.map((edge) => edge.toJSON()), .map((edge) => edge.toJSON()),
history: this.getHistory(), // history: this.getHistory(),
}; };
} }
fromJSON({ name, vertices, edges }) {
this.name = name;
this.vertices.clear();
this.edgeTypes.clear();
for (const {
id, type, label, properties,
} of vertices) {
const vertex = this.addVertex(type, id, null, label);
for (const [key, value] of Object.entries(properties)) {
vertex.setProperty(key, value);
}
}
for (const {
from, to, type, weight,
} of edges) {
this.addEdge(type, from, to, weight);
}
this.redraw();
}
redraw() { redraw() {
// Call .reset() on all vertices and edges // Call .reset() on all vertices and edges
for (const vertex of this.vertices.values()) { for (const vertex of this.vertices.values()) {
@ -108,11 +129,12 @@ export class WeightedDirectedGraph {
resetEditor() { resetEditor() {
this.editorDoc.clear(); this.editorDoc.clear();
this.controlDoc.clear();
Vertex.prepareEditorDocument(this, this.editorDoc); Vertex.prepareEditorDocument(this, this.editorDoc);
const form = this.controlDoc.form({ name: 'controlForm' }).lastElement; const form = this.controlDoc.form({ name: 'controlForm' }).lastElement;
form.button({ form.button({
id: 'export', name: 'Download',
name: 'Export', label: '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);
@ -123,6 +145,17 @@ export class WeightedDirectedGraph {
a.click(); 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) { addVertex(type, id, data, label, options) {

View File

@ -50,8 +50,8 @@ describe('Weighted Directed Graph', function tests() {
it('can export to JSON', () => { it('can export to JSON', () => {
const result = graph.toJSON(); const result = graph.toJSON();
console.log('export to JSON, result', result);
result.should.eql({ result.should.eql({
name: 'test1',
vertices: [ vertices: [
{ {
id: '0', type: 'v1', label: '0', properties: {}, id: '0', type: 'v1', label: '0', properties: {},
@ -95,9 +95,59 @@ describe('Weighted Directed Graph', function tests() {
weight: 0.125, weight: 0.125,
}, },
], ],
history: [], // history: [],
}); });
}); });
it('can import from JSON', () => {
const graph2 = new WeightedDirectedGraph('hidden1');
graph2.fromJSON({
name: 'hidden1import',
vertices: [{
id: '1',
label: '1',
type: 'v1',
properties: {
color: 'green',
},
}, {
id: '2',
label: '2',
type: 'v1',
properties: {
color: 'blue',
},
}],
edges: [{
from: '1',
to: '2',
type: 'e1',
weight: 0.5,
}],
});
graph2.vertices.size.should.equal(2);
graph2.edgeTypes.size.should.equal(1);
graph2.edgeTypes.get('e1').size.should.equal(1);
const v1 = graph2.getVertex('1');
v1.id.should.equal('1');
v1.label.should.equal('1');
v1.type.should.equal('v1');
v1.properties.size.should.equal(1);
v1.properties.get('color').should.equal('green');
const v2 = graph2.getVertex('2');
v2.id.should.equal('2');
v2.label.should.equal('2');
v2.type.should.equal('v1');
v2.properties.size.should.equal(1);
v2.properties.get('color').should.equal('blue');
const e1 = graph2.getEdge('e1', '1', '2');
v1.edges.from[0].should.equal(e1);
v2.edges.to[0].should.equal(e1);
});
}); });
describe('Editable', () => { describe('Editable', () => {