Skip to content
Snippets Groups Projects
Commit 64262c05 authored by mathias.chouet's avatar mathias.chouet
Browse files

Modules diagram: parent Nub nodes are clickable

parent c0cdbeec
No related branches found
No related tags found
1 merge request!56Resolve "Proposer une représentation graphique de l'enchaînement de modules de calcul (paramètres liés), si possible éditable"
......@@ -12,9 +12,10 @@
<div id="diagram" #diagram></div>
<a class="show-debug" (click)="initSvgPanZoom()">init zoom </a>
<!-- <a class="show-debug" (click)="initSvgPanZoom()">init zoom </a> -->
<!-- <a class="show-debug" (click)="showDebug = ! showDebug"> debug</a> -->
<a class="show-debug" (click)="showDebug = ! showDebug"> debug</a>
<div *ngIf="showDebug">
<pre>{{ graphDef }}</pre>
</div>
......
......@@ -3,14 +3,22 @@ import {
ViewChild,
AfterContentInit,
OnInit,
AfterViewChecked
AfterViewChecked,
AfterViewInit
} from "@angular/core";
import { Router } from "@angular/router";
import {
Session,
ParamValueMode,
CalculatorType,
ComputeNodeType,
LoiDebit,
Nub
} from "jalhyd";
import { I18nService } from "../../services/internationalisation/internationalisation.service";
import { BaseComponent } from "../base/base.component";
import { Session, ParamValueMode } from "jalhyd";
import { FormulaireService } from "../../services/formulaire/formulaire.service";
import * as mermaid from "mermaid";
......@@ -22,13 +30,14 @@ import * as SvgPanZoom from "svg-pan-zoom";
templateUrl: "./modules-diagram.component.html",
styleUrls: ["./modules-diagram.component.scss"]
})
export class ModulesDiagramComponent extends BaseComponent implements AfterContentInit, AfterViewChecked, OnInit {
export class ModulesDiagramComponent extends BaseComponent implements AfterContentInit, AfterViewChecked, AfterViewInit, OnInit {
private svgPanZoom: SvgPanZoom.Instance = null;
private needsToInitSvgPanZoom = false;
// private readonly externalFunctionName: string = "functionToCallIntoAngular";
/** handle on SVG container */
private nativeElement: any;
@ViewChild("diagram", { static: true })
public diagram;
......@@ -40,32 +49,12 @@ export class ModulesDiagramComponent extends BaseComponent implements AfterConte
constructor(
private intlService: I18nService,
private router: Router,
private formulaireService: FormulaireService/* ,
zone: NgZone */
private formulaireService: FormulaireService
) {
super();
this.error = false;
// create a new global variable in the page
// window[this.externalFunctionName] = this.buildPublicCall(zone, this);
}
/* ngOnDestroy() {
window[this.externalFunctionName] = null;
} */
// generate a function that has the zone and "this"
// captured in a closure.
/* private buildPublicCall(zone: NgZone, diagramComponent: ModulesDiagramComponent): any {
return function angularAppGlobalMethod( nodeId ) {
// you can't call "this.increment( nodeId)" because
// when the code is run on a click, "this" won't be
// the right entity. When the function is constructed
// "this" is the right entity, but it needs to captured
// at the point of construction
zone.run(() => { diagramComponent.openCalc( nodeId ); });
};
} */
public get uitextTitle(): string {
return this.intlService.localizeText("INFO_DIAGRAM_TITLE");
}
......@@ -100,16 +89,28 @@ export class ModulesDiagramComponent extends BaseComponent implements AfterConte
}
}
public ngAfterViewInit(): void {
// add click listener on every calculator node in the graph, that
// corresponds to an open module
this.nativeElement.querySelectorAll("g.node").forEach(item => {
if (item.id && this.formIsOpen(item.id)) {
item.style.cursor = "pointer";
item.addEventListener("click", () => {
this.openCalc(item.id);
});
}
});
}
public ngAfterContentInit(): void {
this.error = false;
mermaid.initialize({
// theme: "forest", // @TODO thème Irstea !
securityLevel: false, // or "loose" ?
flowchart: {
curve: "basis" // default: "linear"
curve: "basis"
}
});
const element: any = this.diagram.nativeElement;
this.nativeElement = this.diagram.nativeElement;
if (this.hasModules) {
// generate graph description
......@@ -117,7 +118,7 @@ export class ModulesDiagramComponent extends BaseComponent implements AfterConte
// draw
try {
mermaid.render("graphDiv", graphDefinition, (svgCode, bindFunctions) => {
element.innerHTML = svgCode;
this.nativeElement.innerHTML = svgCode;
});
} catch (e) {
console.error(e);
......@@ -154,14 +155,13 @@ export class ModulesDiagramComponent extends BaseComponent implements AfterConte
def.push("subgraph \"" + f.calculatorName + "\"");
def.push(f.uid + "(\"" + f.calculatorName + "\")");
for (const c of children) {
def.push(c.uid + "[\"" + c.constructor.name + "\"]");
def.push(c.uid + "[\"" + this.describe(c) + "\"]");
def.push(f.uid + " --- " + c.uid);
}
def.push("end");
} else {
// simple Nub (no children)
def.push(f.uid + "(\"" + f.calculatorName + "\")");
def.push("click " + f.uid + " openCalc \"open module\"");
}
// fnid all linked parameters
for (const p of nub.parameterIterator) {
......@@ -184,6 +184,37 @@ export class ModulesDiagramComponent extends BaseComponent implements AfterConte
}
public openCalc(uid: string) {
console.log("Opening calc", uid);
this.router.navigate(["/calculator", uid]);
}
/**
* Returns a very short "description" of the given Nub,
* based on the most specific of its properties
*/
private describe(n: Nub) {
let type = CalculatorType[n.calcType];
const nt = n.properties.getPropValue("nodeType");
if (nt) {
type = ComputeNodeType[nt];
} else {
const ld = n.properties.getPropValue("loiDebit");
if (ld !== undefined) {
type = LoiDebit[ld];
}
}
return type;
}
/**
* Returns true if uid is the id of the main Nub of any
* of the open modules
*/
private formIsOpen(uid: string) {
for (const f of this.formulaireService.formulaires) {
if (f.currentNub.uid === uid) {
return true;
}
}
return false;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment