pab-profile-graph.component.ts 11.07 KiB
import { Component } from "@angular/core";
import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
import { I18nService } from "../../services/internationalisation/internationalisation.service";
import { ResultsComponent } from "../fixedvar-results/results.component";
import { PabResults } from "../../results/pab-results";
@Component({
    selector: "pab-profile-graph",
    templateUrl: "./pab-profile-graph.component.html",
    styleUrls: [
        "./pab-profile-graph.component.scss"
export class PabProfileGraphComponent extends ResultsComponent {
    private _results: PabResults;
    /** size of the longest variable value */
    private size = 0;
    /** inferred extended values list for each variating parameter */
    private varValues = [];
     * config du graphe
    public graph_data: { datasets: any[] };
    public graph_options = {
        responsive: true,
        maintainAspectRatio: true,
        animation: {
            duration: 0
        legend: {
            display: true,
            position: "bottom",
            reverse: false
        title: {
            display: true,
            text: "Profil en long de la passe"
        elements: {
            line: {
                tension: 0
    public constructor(
        private appSetupService: ApplicationSetupService,
        private intlService: I18nService
    ) {
        super();
        const nDigits = this.appSetupService.displayDigits;
        // do not move following block out of constructor or scale labels won't be rendered
        this.graph_options["scales"] = {
            xAxes: [{
                type: "linear",
                position: "bottom",
                ticks: {
                    precision: nDigits
                scaleLabel: {
                    display: true,
                    labelString: this.intlService.localizeText("INFO_LIB_DISTANCE_AMONT")
            }],
            yAxes: [{
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
type: "linear", position: "left", ticks: { precision: nDigits }, scaleLabel: { display: true, labelString: this.intlService.localizeText("INFO_LIB_COTE") } }] }; } public set results(r: PabResults) { this._results = r; // pre-extract variable parameters values if (this._results) { this.varValues = []; const nDigits = this.appSetupService.displayDigits; // find longest list this.size = 0; for (let i = 0; i < this._results.variatedParameters.length; i++) { const vs = this._results.variatedParameters[i].valuesIterator.count(); if (vs > this.size) { this.size = vs; } } // get extended values lists for each variable parameter for (const v of this._results.variatedParameters) { const vv = []; const iter = v.getExtendedValuesIterator(this.size); while (iter.hasNext) { const nv = iter.next(); vv.push(nv.value.toFixed(nDigits)); } this.varValues.push(vv); } } } public updateView() { console.log("PPG => updateView() !"); this.generateScatterGraph(); } /** * génère les données d'un graphe de type "scatter" */ private generateScatterGraph() { const ySeries = this.getYSeries(); this.graph_data = { datasets: [] }; // build Y data series for (const ys of ySeries) { // push series config this.graph_data.datasets.push({ label: ys.label, data: ys.data, borderColor: ys.color, // couleur de la ligne backgroundColor: "rgba(0,0,0,0)", // couleur de remplissage sous la courbe : transparent showLine: "true" }); } /* const that = this; this.graph_options["tooltips"] = {
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
displayColors: false, callbacks: { title: (tooltipItems, data) => { return this.chartY + " = " + Number(tooltipItems[0].yLabel).toFixed(nDigits); }, label: (tooltipItem, data) => { const lines: string[] = []; const nbLines = that._results.getVariatingParametersSymbols().length; for (const v of that._results.getVariatingParametersSymbols()) { const series = that._results.getValuesSeries(v); const line = v + " = " + series[tooltipItem.index].toFixed(nDigits); if (v === this.chartX) { if (nbLines > 1) { lines.unshift(""); } lines.unshift(line); } else { lines.push(line); } } return lines; } } }; */ } public exportAsImage(element: HTMLDivElement) { const canvas: HTMLCanvasElement = element.querySelector("canvas"); canvas.toBlob((blob) => { saveAs(blob, "chart.png"); }); // defaults to image/png } private getXSeries(): string[] { const data: string[] = []; const nDigits = this.appSetupService.displayDigits; // X is always wall abscissa for (const cr of this._results.cloisonsResults) { const x = cr.resultElement.getExtraResult("x"); // any resultElement will do data.push(x.toFixed(nDigits)); } const xdw = this._results.cloisonAvalResults.resultElement.getExtraResult("x"); data.push(xdw.toFixed(nDigits)); return data; } private getYSeries(): { data: { x: string, y: string }[], label: string, color: string }[] { const ret: { data: { x: string, y: string }[], label: string, color: string }[] = []; const xs = this.getXSeries(); // abscissae const pabLength = Number(xs[xs.length - 1]) - Number(xs[0]); const pabLength5Pct = (pabLength * 5) / 100; // 1. fond du machin const dataF: { x: string, y: string }[] = []; const nDigits = this.appSetupService.displayDigits; // extend upstrem dataF.push({ x: (Number(xs[0]) - pabLength5Pct).toFixed(nDigits), y: this._results.cloisonsResults[0].resultElement.getExtraResult("ZRAM").toFixed(nDigits) }); // regular walls for (let i = 0; i < this._results.cloisonsResults.length; i++) { const cr = this._results.cloisonsResults[i]; const ZRAM = cr.resultElement.getExtraResult("ZRAM"); // any ResultElement will do dataF.push({ x: xs[i], y: ZRAM.toFixed(nDigits) }); } // downwall
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
const ZRAMdw = this._results.cloisonAvalResults.resultElement.getExtraResult("ZRAM"); dataF.push({ x: xs[ xs.length - 1 ], y: ZRAMdw.toFixed(nDigits) }); // extend downstream dataF.push({ x: (Number(xs[xs.length - 1]) + pabLength5Pct).toFixed(nDigits), y: ZRAMdw.toFixed(nDigits) }); // add series ret.push({ data: dataF, label: this.intlService.localizeText("INFO_LIB_RADIER"), color: "#808080" }); // 2. séries const nbSeries = this._results.cloisonsResults[0].resultElements.length; const palette = this.distinctColors; for (let n = 0; n < nbSeries; n++) { // --------- build nth series --------- const dataN: { x: string, y: string }[] = []; let i = 0; // abscissa index // extend upstream dataN.push({ x: (Number(xs[0]) - pabLength5Pct).toFixed(nDigits), y: this._results.cloisonsResults[0].resultElements[n].vCalc.toFixed(nDigits) }); // walls for (const x of xs) { let Z1: number; let nextZ1: number; if (i < xs.length - 2) { // regular walls Z1 = this._results.cloisonsResults[i].resultElements[n].vCalc; nextZ1 = this._results.cloisonsResults[i + 1].resultElements[n].vCalc; } else if (i === xs.length - 2) { // last regular wall Z1 = this._results.cloisonsResults[i].resultElements[n].vCalc; nextZ1 = this._results.cloisonAvalResults.resultElements[n].vCalc; } else { // downwall Z1 = this._results.cloisonAvalResults.resultElements[n].vCalc; nextZ1 = this._results.Z2[n]; } // 2 points for each abscissa dataN.push({ x: x, y: Z1.toFixed(nDigits) }); dataN.push({ x: x, y: nextZ1.toFixed(nDigits) }); i++; } // extend downstream dataN.push({ x: (Number(xs[xs.length - 1]) + pabLength5Pct).toFixed(nDigits), y: this._results.Z2[n].toFixed(nDigits) }); ret.push({
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
data: dataN, label: ( this._results.variatedParameters.length > 0 ? this.getLegendForSeries(n) : this.intlService.localizeText("INFO_LIB_LIGNE_D_EAU") ), color: palette[ n % palette.length ] }); } return ret; } /** * Returns a label showing the boundary conditions values for * the given iteration * @param n index of the variating parameter(s) iteration */ private getLegendForSeries(n: number): string { let i = 0; return this.varValues.map((vv) => { const vp = this._results.variatedParameters[i]; i++; let value = "0"; value = vv[n]; return `${vp.symbol} = ${value}`; }).join(", "); } /** * 14 distinct colors @see https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors */ private get distinctColors(): string[] { return [ "#4363d8", // blue "#f58231", // orange "#3cb44b", // green "#e6194B", // red "#911eb4", // purple "#ffe119", // yellow "#f032e6", // magenta "#9A6324", // brown "#000075", // navy "#808000", // olive "#42d4f4", // cyan "#a9a9a9", // grey "#bfef45", // lime "#469990", // teal ]; } }