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);
this.dao = dao;
this.id = this.reputationPublicKey;
this.graph = new WeightedDirectedGraph(scene);
this.graph = new WeightedDirectedGraph('forum', scene);
this.actions = {
propagate: new Action('propagate', scene),
confirm: new Action('confirm', scene),

View File

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

View File

@ -18,6 +18,18 @@ export class Vertex {
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() {
this.installedClickCallback = false;
}
@ -129,7 +141,7 @@ export class Vertex {
cb: () => {
graph.deleteVertex(vertex.id);
graph.redraw();
graph.resetEditorDocument();
graph.resetEditor();
},
});
@ -151,7 +163,7 @@ export class Vertex {
form.button({
id: 'cancel',
name: 'Cancel',
cb: () => graph.resetEditorDocument(),
cb: () => graph.resetEditor(),
});
return doc;

View File

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

View File

@ -7,13 +7,13 @@ const rootElement = document.getElementById('scene');
const rootBox = new Box('rootBox', rootElement).flex();
window.scene = new Scene('WDG test', rootBox);
describe('Weighted Directed Acyclic Graph', function tests() {
describe('Weighted Directed Graph', function tests() {
this.timeout(0);
let graph;
before(() => {
graph = (window.graph = new WeightedDirectedGraph(window.scene)).withFlowchart();
graph = (window.graph = new WeightedDirectedGraph('test1', window.scene)).withFlowchart();
graph.addVertex('v1', {});
graph.addVertex('v1', {});
@ -47,13 +47,64 @@ describe('Weighted Directed Acyclic Graph', function tests() {
['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;
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('v2', {});