Skip to content

Commit

Permalink
bump version to 0.0.6 in package.json and package-lock.json; refactor…
Browse files Browse the repository at this point in the history
… App, SolverGraph, and TimelinesChart classes for improved component structure and event handling
  • Loading branch information
riccardodebenedictis committed Jan 10, 2025
1 parent 3bf7f63 commit 66a5de5
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 38 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ratio-gui",
"version": "0.0.5",
"version": "0.0.6",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
52 changes: 29 additions & 23 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
class App {
class App implements AppListener {

private selected_comp: Component<any, HTMLElement> | null = null;
private app_listeners: Set<AppListener> = new Set();

constructor() { }

get_selected_component(): Component<any, HTMLElement> | null { return this.selected_comp; }

selected_component(component: Component<any, HTMLElement> | null): void {
this.selected_comp = component;
for (const listener of this.app_listeners) { listener.selected_component(component); }
}

add_app_listener(listener: AppListener): void {
this.app_listeners.add(listener);
}

remove_app_listener(listener: AppListener): void {
this.app_listeners.delete(listener);
}
}

export interface AppListener {
Expand All @@ -19,11 +37,11 @@ export abstract class Component<P, E extends HTMLElement> {
}

remove(): void {
this.unmounting();
this.element.remove();
this.unmounted();
}

unmounted(): void { }
unmounting(): void { }
}

export abstract class ListComponent<P, E extends HTMLElement, L extends HTMLElement> extends Component<Component<P, E>[], L> {
Expand Down Expand Up @@ -60,40 +78,28 @@ export abstract class ListComponent<P, E extends HTMLElement, L extends HTMLElem
} else
throw new Error('Child not found');
}

remove(): void {
for (const child of this.children)
child.remove();
super.remove();
}
}

export class AppComponent extends Component<App, HTMLDivElement> implements AppListener {
export class AppComponent extends Component<App, HTMLDivElement> {

private static instance: AppComponent;
private selected_comp: Component<any, HTMLElement> | null = null;
private app_listeners: Set<AppListener> = new Set();

private constructor() {
super(new App(), document.querySelector('#app') as HTMLDivElement);
this.element.classList.add('d-flex', 'flex-column', 'h-100');
}

static get_instance() {
if (!AppComponent.instance) {
if (!AppComponent.instance)
AppComponent.instance = new AppComponent();
}
return AppComponent.instance;
}

get_selected_component(): Component<any, HTMLElement> | null { return this.selected_comp; }

selected_component(component: Component<any, HTMLElement> | null): void {
this.selected_comp = component;
for (const listener of this.app_listeners) { listener.selected_component(component); }
}

add_app_listener(listener: AppListener): void {
this.app_listeners.add(listener);
}

remove_app_listener(listener: AppListener): void {
this.app_listeners.delete(listener);
}
}

export class AnchorComponent<P> extends Component<P, HTMLAnchorElement> {
Expand Down
76 changes: 71 additions & 5 deletions src/solver_components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { AppComponent, Component, AnchorComponent, UListComponent } from './app'
import { solver } from "./solver";
import { library, icon } from '@fortawesome/fontawesome-svg-core'
import { faBrain, faPauseCircle, faPlayCircle, faCheckCircle, faXmarkCircle } from '@fortawesome/free-solid-svg-icons'
import { TimelinesChart } from './solver_timelines';
import { SolverGraph } from './solver_graph';

library.add(faBrain, faPauseCircle, faPlayCircle, faCheckCircle, faXmarkCircle);

Expand All @@ -10,7 +12,7 @@ export class SolverAnchor extends AnchorComponent<solver.Solver> implements solv
constructor(solver: solver.Solver) {
super(solver);
solver.add_solver_listener(this);
this.element.addEventListener('click', () => { AppComponent.get_instance().selected_component(this); });
this.element.addEventListener('click', () => { AppComponent.get_instance().payload.selected_component(this); });
}

init(items: Map<string, solver.values.Value>, atoms: Map<number, solver.values.Atom>, state: solver.SolverState, flaws: Map<number, solver.graph.Flaw>, resolvers: Map<number, solver.graph.Resolver>, c_flaw: solver.graph.Flaw | null, c_resolver: solver.graph.Resolver | null): void { this.render(); }
Expand All @@ -25,10 +27,10 @@ export class SolverAnchor extends AnchorComponent<solver.Solver> implements solv
this.element.innerHTML = to_icon(this.payload.get_state()) + ' ' + this.payload.get_name();
}

unmounted(): void {
unmounting(): void {
this.payload.remove_solver_listener(this);
if (AppComponent.get_instance().get_selected_component() === this)
AppComponent.get_instance().selected_component(null);
if (AppComponent.get_instance().payload.get_selected_component() === this)
AppComponent.get_instance().payload.selected_component(null);
}
}

Expand All @@ -52,9 +54,73 @@ export class SolverListComponent extends UListComponent<solver.Solver> {

export class SolverComponent extends Component<solver.Solver, HTMLDivElement> {

private timelines_chart: TimelinesChart;
private graph_component: SolverGraph;

constructor(solver: solver.Solver) {
super(solver, document.createElement('div'));
this.element.classList.add('flex-grow-1', 'd-flex', 'flex-column');
this.element.classList.add('d-flex', 'flex-column', 'flex-grow-1');
const fragment = document.createDocumentFragment();
const pills = document.createElement('ul');
pills.classList.add('nav', 'nav-pills', 'mb-3');

const timelines_pill = document.createElement('li');
timelines_pill.role = 'presentation';
const timelines_pill_link = document.createElement('a');
timelines_pill_link.classList.add('nav-link', 'active');
timelines_pill_link.id = 'timelines-tab';
timelines_pill_link.setAttribute('data-bs-toggle', 'pill');
timelines_pill_link.setAttribute('data-bs-target', '#slv-' + solver.get_id() + '-timelines');
timelines_pill_link.setAttribute('role', 'tab');
timelines_pill_link.setAttribute('aria-controls', 'timelines');
timelines_pill_link.setAttribute('aria-selected', 'true');
timelines_pill_link.innerText = 'Timelines';
timelines_pill.appendChild(timelines_pill_link);
pills.appendChild(timelines_pill);

const graph_pill = document.createElement('li');
graph_pill.role = 'presentation';
const graph_pill_link = document.createElement('a');
graph_pill_link.classList.add('nav-link');
graph_pill_link.id = 'graph-tab';
graph_pill_link.setAttribute('data-bs-toggle', 'pill');
graph_pill_link.setAttribute('data-bs-target', '#slv-' + solver.get_id() + '-graph');
graph_pill_link.setAttribute('role', 'tab');
graph_pill_link.setAttribute('aria-controls', 'graph');
graph_pill_link.setAttribute('aria-selected', 'false');
graph_pill_link.innerText = 'Graph';
graph_pill.appendChild(graph_pill_link);
pills.appendChild(graph_pill);

fragment.appendChild(pills);

const tab_content = document.createElement('div');
tab_content.classList.add('tab-content');
tab_content.id = 'slv-' + solver.get_id() + '-tab-content';

const timelines = document.createElement('div');
timelines.classList.add('tab-pane', 'fade', 'show', 'active');
timelines.id = 'slv-' + solver.get_id() + '-timelines';
timelines.setAttribute('role', 'tabpanel');
timelines.setAttribute('aria-labelledby', 'timelines-tab');
tab_content.appendChild(timelines);

const graph = document.createElement('div');
graph.classList.add('tab-pane', 'fade');
graph.id = 'slv-' + solver.get_id() + '-graph';
graph.setAttribute('role', 'tabpanel');
graph.setAttribute('aria-labelledby', 'graph-tab');
tab_content.appendChild(graph);

fragment.appendChild(tab_content);

this.timelines_chart = new TimelinesChart(solver);
this.graph_component = new SolverGraph(solver);
}

unmounting(): void {
this.timelines_chart.remove();
this.graph_component.remove();
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/solver_graph.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Component } from "./app";
import { solver } from "./solver";
import cytoscape from 'cytoscape';
import { interpolateRgb } from 'd3-interpolate';

const costColorScale = interpolateRgb("green", "red");
const infiniteColor = "black";

export class SolverGraph implements solver.SolverListener {
export class SolverGraph extends Component<solver.Solver, HTMLDivElement> implements solver.SolverListener {

cy: cytoscape.Core;
layout = {
Expand All @@ -18,8 +19,10 @@ export class SolverGraph implements solver.SolverListener {
};

constructor(solver: solver.Solver) {
super(solver, document.querySelector('#slv-' + solver.get_id() + '-graph') as HTMLDivElement);
this.element.classList.add('d-flex', 'flex-column', 'flex-grow-1');
this.cy = cytoscape({
container: document.getElementById('slv-' + solver.get_id() + '-graph'),
container: this.element,
style: [
{
selector: 'node[type="flaw"]',
Expand Down Expand Up @@ -99,6 +102,8 @@ export class SolverGraph implements solver.SolverListener {
current_resolver(resolver: solver.graph.Resolver): void {
this.cy.layout(this.layout).run();
}

unmounting(): void { this.payload.remove_solver_listener(this); }
}

function color(flaw: solver.graph.Flaw | solver.graph.Resolver): string {
Expand Down
13 changes: 8 additions & 5 deletions src/solver_timelines.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component } from "./app";
import { solver } from "./solver";
import Plotly from 'plotly.js';

export class TimelinesChart implements solver.SolverListener {
export class TimelinesChart extends Component<solver.Solver, HTMLDivElement> implements solver.SolverListener {

private solver: solver.Solver;
private layout = {
autosize: true,
xaxis: { title: 'Time' },
Expand All @@ -27,12 +27,13 @@ export class TimelinesChart implements solver.SolverListener {
private config = { responsive: true, displaylogo: false };

constructor(solver: solver.Solver) {
this.solver = solver;
this.solver.add_solver_listener(this);
super(solver, document.querySelector('#slv-' + solver.get_id() + '-timelines') as HTMLDivElement);
this.element.classList.add('d-flex', 'flex-column', 'flex-grow-1');
solver.add_solver_listener(this);
}

init(items: Map<string, solver.values.Value>, atoms: Map<number, solver.values.Atom>, state: solver.SolverState, flaws: Map<number, solver.graph.Flaw>, resolvers: Map<number, solver.graph.Resolver>, c_flaw: solver.graph.Flaw | null, c_resolver: solver.graph.Resolver | null): void {
Plotly.react('slv-' + this.solver.get_id() + '-timelines', [], this.layout, this.config);
Plotly.react(this.element, [], this.layout, this.config);
}

state_changed(state: solver.SolverState): void { }
Expand All @@ -41,4 +42,6 @@ export class TimelinesChart implements solver.SolverListener {
current_flaw(flaw: solver.graph.Flaw): void { }
resolver_created(resolver: solver.graph.Resolver): void { }
current_resolver(resolver: solver.graph.Resolver): void { }

unmounting(): void { this.payload.remove_solver_listener(this); }
}

0 comments on commit 66a5de5

Please sign in to comment.