dao-governance-framework/forum-network/src/classes/display/scene.js

132 lines
4.2 KiB
JavaScript

import { Action } from './action.js';
import { CryptoUtil } from '../supporting/crypto.js';
import { MermaidDiagram } from './mermaid.js';
import { SequenceDiagram } from './sequence.js';
import { Table } from './table.js';
import { Flowchart } from './flowchart.js';
import { Controls } from './controls.js';
import { Box } from './box.js';
export class Scene {
constructor(name, rootBox) {
this.name = name;
this.box = rootBox.addBox(name);
this.titleBox = this.box.addBox('Title').setInnerHTML(name);
this.box.addBox('Spacer').setInnerHTML(' ');
this.topSection = this.box.addBox('Top section').flex();
this.displayValuesBox = this.topSection.addBox('Values');
this.middleSection = this.box.addBox('Middle section');
this.box.addBox('Spacer').setInnerHTML(' ');
this.actors = new Set();
this.dateStart = new Date();
this.flowcharts = new Map();
MermaidDiagram.initializeAPI();
this.options = {
edgeNodeColor: '#4d585c',
};
window.autoPlay = new URL(window.location.href).searchParams.get('auto') !== 'false';
if (!window.disableSceneControls) {
this.topRail = new Box('Top rail', document.body, { prepend: true }).addClass('top-rail');
this.controlsBox = this.topRail.addBox('Controls').addClass('controls');
this.controls = new Controls(this.controlsBox);
}
}
withSequenceDiagram() {
const box = this.box.addBox('Sequence diagram');
this.box.addBox('Spacer').setInnerHTML(' ');
const logBox = this.box.addBox('Sequence diagram text').addClass('dim');
this.sequence = new SequenceDiagram(box, logBox);
return this;
}
withFlowchart({ direction = 'BT' } = {}) {
const box = this.topSection.addBox('Flowchart').addClass('padded');
this.box.addBox('Spacer').setInnerHTML(' ');
const logBox = this.box.addBox('Flowchart text').addClass('dim');
this.flowchart = new Flowchart(box, logBox, direction);
return this;
}
withAdditionalFlowchart({ id, name, direction = 'BT' } = {}) {
const index = this.flowcharts.size;
name = name ?? `Flowchart ${index}`;
id = id ?? `flowchart_${CryptoUtil.randomUUID().slice(0, 4)}`;
const container = this.middleSection.addBox(name).flex();
const box = container.addBox('Flowchart').addClass('padded');
const logBox = container.addBox('Flowchart text').addClass('dim');
const flowchart = new MermaidDiagram(box, logBox);
flowchart.log(`graph ${direction}`, false);
this.flowcharts.set(id, flowchart);
return this;
}
lastFlowchart() {
if (!this.flowcharts.size) {
if (this.flowchart) {
return this.flowchart;
}
throw new Error('lastFlowchart: No additional flowcharts have been added.');
}
const flowcharts = Array.from(this.flowcharts.values());
return flowcharts[flowcharts.length - 1];
}
withTable() {
if (this.table) {
return this;
}
const box = this.middleSection.addBox('Table').addClass('padded');
this.box.addBox('Spacer').setInnerHTML(' ');
this.table = new Table(box);
return this;
}
registerActor(actor) {
this.actors.add(actor);
if (actor.options.announce) {
this.sequence?.log(`participant ${actor.name}`);
}
}
findActor(fn) {
return Array.from(this.actors.values()).find(fn);
}
addAction(name) {
const action = new Action(name, this);
return action;
}
addDisplayValue(name) {
const dv = this.displayValuesBox.addDisplayValue(name);
return dv;
}
stateToTable(label) {
const row = new Map();
const columns = [];
columns.push({ key: 'seqNum', title: '#' });
columns.push({ key: 'elapsedMs', title: 'Time (ms)' });
row.set('seqNum', this.table.rows.length + 1);
row.set('elapsedMs', new Date() - this.dateStart);
row.set('label', label);
for (const actor of this.actors) {
if (!actor.options.hide) {
for (const [aKey, { name, value }] of actor.getValuesMap()) {
const key = `${actor.name}:${aKey}`;
columns.push({ key, title: name });
row.set(key, value);
}
}
}
columns.push({ key: 'label', title: '' });
this.table.setColumns(columns);
this.table.addRow(row);
}
}