Enable wdg export

This commit is contained in:
Ladd Hoffman 2023-07-11 11:27:15 -05:00
parent f27ebaf0a4
commit b610484e49
5 changed files with 107 additions and 17 deletions

View File

@ -44,7 +44,7 @@ export class Forum extends ReputationHolder {
super(name, scene); super(name, scene);
this.dao = dao; this.dao = dao;
this.id = this.reputationPublicKey; this.id = this.reputationPublicKey;
this.graph = new WeightedDirectedGraph(scene); this.graph = new WeightedDirectedGraph('forum', scene);
this.actions = { this.actions = {
propagate: new Action('propagate', scene), propagate: new Action('propagate', scene),
confirm: new Action('confirm', scene), confirm: new Action('confirm', scene),

View File

@ -10,6 +10,15 @@ export class Edge {
this.installedClickCallback = false; this.installedClickCallback = false;
} }
toJSON() {
return {
from: this.from.id,
to: this.to.id,
type: this.type,
weight: this.weight,
};
}
reset() { reset() {
this.installedClickCallback = false; this.installedClickCallback = false;
} }
@ -132,7 +141,7 @@ export class Edge {
.button({ .button({
id: 'cancel', id: 'cancel',
name: 'Cancel', name: 'Cancel',
cb: () => graph.resetEditorDocument(), cb: () => graph.resetEditor(),
}); });
} }
} }

View File

@ -18,6 +18,18 @@ export class Vertex {
this.properties = new Map(); this.properties = new Map();
} }
toJSON() {
return {
id: this.id,
type: this.type,
label: this.label,
properties: Array.from(this.properties.entries()).reduce((props, [key, value]) => {
props[key] = value;
return props;
}, {}),
};
}
reset() { reset() {
this.installedClickCallback = false; this.installedClickCallback = false;
} }
@ -129,7 +141,7 @@ export class Vertex {
cb: () => { cb: () => {
graph.deleteVertex(vertex.id); graph.deleteVertex(vertex.id);
graph.redraw(); graph.redraw();
graph.resetEditorDocument(); graph.resetEditor();
}, },
}); });
@ -151,7 +163,7 @@ export class Vertex {
form.button({ form.button({
id: 'cancel', id: 'cancel',
name: 'Cancel', name: 'Cancel',
cb: () => graph.resetEditorDocument(), cb: () => graph.resetEditor(),
}); });
return doc; return doc;

View File

@ -18,7 +18,8 @@ const makeWDGHandler = (graphIndex) => (vertexId) => {
}; };
export class WeightedDirectedGraph { export class WeightedDirectedGraph {
constructor(scene, options = {}) { constructor(name, scene, options = {}) {
this.name = name;
this.scene = scene; this.scene = scene;
this.vertices = new Map(); this.vertices = new Map();
this.edgeTypes = new Map(); this.edgeTypes = new Map();
@ -34,7 +35,7 @@ export class WeightedDirectedGraph {
window[`WDGHandler${this.index}`] = makeWDGHandler(this.index); window[`WDGHandler${this.index}`] = makeWDGHandler(this.index);
// TODO: Populate history // TODO: Populate history
this.history = {}; this.history = [];
} }
getHistory() { getHistory() {
@ -44,9 +45,11 @@ export class WeightedDirectedGraph {
toJSON() { toJSON() {
return { return {
vertices: Array.from(this.vertices.values()), vertices: Array.from(this.vertices.values())
edgeTypes: Array.from(this.edgeTypes.keys()), .map((vertex) => vertex.toJSON()),
edges: Array.from(this.edgeTypes.values()).flatMap((edges) => Array.from(edges.values())), edges: Array.from(this.edgeTypes.values())
.flatMap((edges) => Array.from(edges.values()))
.map((edge) => edge.toJSON()),
history: this.getHistory(), history: this.getHistory(),
}; };
} }
@ -95,16 +98,31 @@ 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.editorDoc = new Document('WDGControls', this.flowchart.box.el); this.editorDoc = new Document('WDGEditor', this.flowchart.box.el);
this.resetEditorDocument();
}
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();
}
return this; return this;
} }
resetEditorDocument() { resetEditor() {
this.editorDoc.clear(); this.editorDoc.clear();
Vertex.prepareEditorDocument(this, this.editorDoc); Vertex.prepareEditorDocument(this, this.editorDoc);
const form = this.controlDoc.form({ name: 'controlForm' }).lastElement;
form.button({
id: 'export',
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();
},
});
} }
addVertex(type, id, data, label, options) { addVertex(type, id, data, label, options) {

View File

@ -7,13 +7,13 @@ const rootElement = document.getElementById('scene');
const rootBox = new Box('rootBox', rootElement).flex(); const rootBox = new Box('rootBox', rootElement).flex();
window.scene = new Scene('WDG test', rootBox); window.scene = new Scene('WDG test', rootBox);
describe('Weighted Directed Acyclic Graph', function tests() { describe('Weighted Directed Graph', function tests() {
this.timeout(0); this.timeout(0);
let graph; let graph;
before(() => { before(() => {
graph = (window.graph = new WeightedDirectedGraph(window.scene)).withFlowchart(); graph = (window.graph = new WeightedDirectedGraph('test1', window.scene)).withFlowchart();
graph.addVertex('v1', {}); graph.addVertex('v1', {});
graph.addVertex('v1', {}); graph.addVertex('v1', {});
@ -47,13 +47,64 @@ describe('Weighted Directed Acyclic Graph', function tests() {
['3', '1', 0.25], ['3', '1', 0.25],
]); ]);
}); });
it('can export to JSON', () => {
const result = graph.toJSON();
console.log('export to JSON, result', result);
result.should.eql({
vertices: [
{
id: '0', type: 'v1', label: '0', properties: {},
},
{
id: '1', type: 'v1', label: '1', properties: {},
},
{
id: '2', type: 'v1', label: '2', properties: {},
},
{
id: '3', type: 'v1', label: '3', properties: {},
},
{
id: '4', type: 'v1', label: '4', properties: {},
},
],
edges: [
{
from: '0',
to: '1',
type: 'e1',
weight: 1,
},
{
from: '2',
to: '1',
type: 'e1',
weight: 0.5,
},
{
from: '3',
to: '1',
type: 'e1',
weight: 0.25,
},
{
from: '1',
to: '4',
type: 'e1',
weight: 0.125,
},
],
history: [],
});
});
}); });
describe('editable', () => { describe('Editable', () => {
let graph; let graph;
it('should be editable', () => { it('should be editable', () => {
graph = (window.graph2 = new WeightedDirectedGraph(window.scene, { editable: true })).withFlowchart(); graph = (window.graph2 = new WeightedDirectedGraph('test2', window.scene, { editable: true })).withFlowchart();
graph.addVertex('v1', {}); graph.addVertex('v1', {});
graph.addVertex('v2', {}); graph.addVertex('v2', {});