From 4d41fb8cd88b91bd72c2869ef0c1aa7fe493a956 Mon Sep 17 00:00:00 2001 From: "mathias.chouet" <mathias.chouet@irstea.fr> Date: Wed, 11 Dec 2019 12:20:01 +0100 Subject: [PATCH] Fix jalhyd#171 - draw weirs on PAB profile --- .../fixedvar-results/results.component.ts | 16 +++ .../pab-profile-chart.component.ts | 127 +++++++++++++++++- src/app/results/y-series.ts | 4 + src/locale/messages.en.json | 1 + src/locale/messages.fr.json | 1 + 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/src/app/components/fixedvar-results/results.component.ts b/src/app/components/fixedvar-results/results.component.ts index d5282b1b1..355a28b31 100644 --- a/src/app/components/fixedvar-results/results.component.ts +++ b/src/app/components/fixedvar-results/results.component.ts @@ -68,6 +68,22 @@ export class ResultsComponent { ]; } + /** the 10 different point styles available in Chart.js, ordered in a way that seems nice to me */ + public static get distinctPointStyles(): string[] { + return [ + "circle", + "rect", + "triangle", + "cross", + "star", + "rectRot", + "crossRot", + "dash", + "rectRounded", + "line" + ]; + } + /** * Formats (rounds) the given number (or the value of the given parameter) with the * number of decimals specified in app preferences; if given number is too low and diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts index aa4e3f407..765191293 100644 --- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts +++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts @@ -9,7 +9,9 @@ import { IYSeries } from "../../results/y-series"; import { fv } from "../../util"; import { AppComponent } from "../../app.component"; -import { CloisonAval, Cloisons } from "jalhyd"; +import { CloisonAval, Cloisons, LoiDebit } from "jalhyd"; + +import { sprintf } from "sprintf-js"; @Component({ selector: "pab-profile-chart", @@ -112,6 +114,15 @@ export class PabProfileChartComponent extends ResultsComponent { } } }; + // format numbers in tooltips + this.graph_options["tooltips"] = { + displayColors: false, + callbacks: { + label: (tooltipItem, data) => { + return "(" + fv(Number(tooltipItem.xLabel)) + ", " + fv(Number(tooltipItem.yLabel)) + ")"; + } + } + }; } public set results(r: PabResults) { @@ -172,7 +183,8 @@ export class PabProfileChartComponent extends ResultsComponent { 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" + showLine: "true", + pointStyle: ys.pointStyle }); } } @@ -219,9 +231,14 @@ export class PabProfileChartComponent extends ResultsComponent { const xs = this.getXSeries(); // abscissae const pabLength = xs[xs.length - 1] - xs[0]; const pabLength5Pct = (pabLength * 5) / 100; + const dw = (this._results.cloisonAvalResults.sourceNub as CloisonAval); + const ZRAMdw = dw.prms.ZRAM.singleValue; // 1. radier (cotes amont et mi-bassin) const dataF: { x: number, y: number }[] = []; + const pointStyles: string[] = []; + // one data series for one device repeated throughout the basins + const ddSeries: { x: number, y: number }[][] = []; // extend upstream dataF.push({ x: xs[0] - pabLength5Pct, @@ -234,33 +251,99 @@ export class PabProfileChartComponent extends ResultsComponent { const ZRAM = cr.resultElement.getValue("ZRAM"); // any ResultElement will do const ZRMB = cr.resultElement.getValue("ZRMB"); // any ResultElement will do const halfLB = c.prms.LB.singleValue / 2; + // ZRAM dataF.push({ x: xs[i], y: ZRAM }); + // ZDV of each device… + for (let sti = 0; sti < c.structures.length; sti ++) { + const st = c.structures[sti]; + // init device series if it does not exist yet + if (ddSeries[sti] === undefined) { + ddSeries[sti] = []; + } + // orifices have no relevant ZDV + if (st.properties.getPropValue("loiDebit") !== LoiDebit.OrificeSubmerged) { + // 2 points, to draw a segment + ddSeries[sti].push({ + x: xs[i], + y: ZRAM + }); + ddSeries[sti].push({ + x: xs[i], + y: st.prms.ZDV.v + }); + // 1 null point, to disjoin segments + ddSeries[sti].push({ + x: xs[i], + y: null + }); + } + } + // ZRMB dataF.push({ x: xs[i] + halfLB, y: ZRMB }); } // downwall - const dw = (this._results.cloisonAvalResults.sourceNub as CloisonAval); - const ZRAMdw = dw.prms.ZRAM.singleValue; dataF.push({ x: xs[ xs.length - 1 ], y: ZRAMdw }); + // ZDV of each device… + for (let sti = 0; sti < dw.structures.length; sti ++) { + const st = dw.structures[sti]; + // init device series if it does not exist yet + if (ddSeries[sti] === undefined) { + ddSeries[sti] = []; + } + // orifices have no relevant ZDV; lift gate will be drawn later for each series + if (! [ LoiDebit.OrificeSubmerged, LoiDebit.VanLevLarinier, LoiDebit.VanLevVillemonte ] + .includes(st.properties.getPropValue("loiDebit")) + ) { + // 2 points, to draw a segment + ddSeries[sti].push({ + x: xs[ xs.length - 1 ], + y: ZRAMdw + }); + ddSeries[sti].push({ + x: xs[ xs.length - 1 ], + y: st.prms.ZDV.v + }); + // 1 null point, to disjoin segments + ddSeries[sti].push({ + x: xs[ xs.length - 1 ], + y: null + }); + } + } // extend downstream dataF.push({ x: xs[xs.length - 1] + pabLength5Pct, y: ZRAMdw }); - // add series + // add bottom series ret.push({ data: dataF, label: this.intlService.localizeText("INFO_LIB_RADIER"), color: "#808080" }); + // add devices series with a different point style for each + const psPalette = ResultsComponent.distinctPointStyles; + for (let ddi = 0; ddi < ddSeries.length; ddi++) { + const ds = ddSeries[ddi]; + // series might have no eligible device, thus no point at all + if (ds.length > 0) { + ret.push({ + data: ds, + label: sprintf(this.intlService.localizeText("INFO_LIB_PAB_CHART_SEUILS"), ddi + 1), + color: "#808080", // same as bottom line + pointStyle: psPalette[ddi] + }); + } + } // 2. séries const nbSeries = this._results.cloisonsResults[0].resultElements.length; @@ -287,6 +370,7 @@ export class PabProfileChartComponent extends ResultsComponent { for (const x of xs) { let Z1: number; let nextZ1: number; + let isLastAbscissa = false; if (i < xs.length - 2) { // regular walls Z1 = this._results.cloisonsResults[i].resultElements[n].vCalc; @@ -299,6 +383,7 @@ export class PabProfileChartComponent extends ResultsComponent { // downwall Z1 = this._results.cloisonAvalResults.resultElements[n].vCalc; nextZ1 = this._results.Z2[n]; + isLastAbscissa = true; } // 2 points for each abscissa @@ -311,6 +396,38 @@ export class PabProfileChartComponent extends ResultsComponent { y: nextZ1 }); + // draw lift gate if any + if (isLastAbscissa) { + for (const st of dw.structures) { + if ([ LoiDebit.VanLevLarinier, LoiDebit.VanLevVillemonte ].includes(st.properties.getPropValue("loiDebit"))) { + // skip a point to disjoin line + dataN.push({ + x: x, + y: null + }); + // draw gate between bottom and ZDV + dataN.push({ + x: x, + y: ZRAMdw + }); + dataN.push({ + x: x, + y: this._results.cloisonAvalResults.resultElements[n].getValue("ZDV") + }); + // skip a point to disjoin line + dataN.push({ + x: x, + y: null + }); + // back to last water line point + dataN.push({ + x: x, + y: nextZ1 + }); + } + } + } + i++; } diff --git a/src/app/results/y-series.ts b/src/app/results/y-series.ts index 1a8f4e771..4f66a9278 100644 --- a/src/app/results/y-series.ts +++ b/src/app/results/y-series.ts @@ -8,4 +8,8 @@ export interface IYSeries { label: string; /** line color */ color: string; + /** points colors, might be an array */ + pointBackgroundColor?: any; + /** points styles (shape or image), might be an array */ + pointStyle?: any; } diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 4a632d1cd..1666eb964 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -289,6 +289,7 @@ "INFO_LIB_ZRAM": "Upstream apron elevation", "INFO_LIB_ZRMB": "Downstream basin bottom elevation", "INFO_LIB_ZT": "Triangle top elevation", + "INFO_LIB_PAB_CHART_SEUILS": "Weirs (%s)", "INFO_LINKED_VALUE_CHILD": "%s (%s, %s %s)", "INFO_LINKED_VALUE_EXTRA_RESULT_OF": "%s (%s)", "INFO_LINKED_VALUE_EXTRA_RESULT": "%s (%s)", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index 4d86f3a4a..79440de70 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -288,6 +288,7 @@ "INFO_LIB_ZRAM": "Cote du radier amont", "INFO_LIB_ZRMB": "Cote de radier mi-bassin", "INFO_LIB_ZT": "Cote haute du triangle", + "INFO_LIB_PAB_CHART_SEUILS": "Seuils (%s)", "INFO_LINKED_VALUE_CHILD": "%s (%s, %s %s)", "INFO_LINKED_VALUE_EXTRA_RESULT_OF": "%s (%s)", "INFO_LINKED_VALUE_EXTRA_RESULT": "%s (%s)", -- GitLab