Enable wdg import
This commit is contained in:
parent
b610484e49
commit
496c132b82
|
@ -26,7 +26,14 @@ 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;
|
||||||
this.el.appendChild(this.button);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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', () => {
|
||||||
|
|
Loading…
Reference in New Issue